微信扫码
添加专属顾问
我要投稿
我们通常会看到XX大厂又发布base模型和chat模型时,这两种模型的有什么区别呢?
其实,所有的大语言模型(LLM)的工作方式都是接收一些文本,然后预测最有可能出现在其后面的文本。
base模型,也称为基础模型,是在大量各种文本上训练出来的预测后续文本的模型。这意味着生成的后续文本不一定是对指令或对话的响应。
chat模型,又称为对话模型,是在base模型的基础上,通过对话记录(指令-响应)进行进一步的微调和强化学习。这使得它能够在接收指令和用户对话时,生成符合指令和人类预期的assistant响应内容。简单来说,chat模型更关注对话生成和交互场景,能更好地模拟人类对话。
微调,简单说就是给我们的开源 LLM 的 CKPT 增加更多数据,让它多掌握一些知识,或者改变它的一些初始生成结果。
微调会调整模型的权重,并能更好地控制模型的生成输出。与 few-shot prompting 方式相比,微调也能解决因 token 消费过多、模型响应速度慢以及上下文窗口不够带来的问题。
大模型通常是针对通用任务进行训练的,可能并不总是适合特定任务。
微调是调整大模型参数的过程,以使其在特定任务上的性能更好。
微调可以显着提高大模型在特定任务上的准确性。例如,在对新闻文章数据集进行微调后,大模型可能能够更准确地识别文章的情感。
可以使大模型在特定任务.上更有效。例如,在对问答数据集进行微调后,大模型可能能够更快、更准确地回答问题。
可以提高大模型的泛化能力,这意味着它们可以更好地执行与训练数据中数据不同的任务。例如,在对不同类型的创意文本格式(如诗歌、代码、脚本、音乐作品、电子邮件、信件等)的数据集进行微调后,大模型可能能够生成我们用看件下微调大模型的优可以减少训练大模型所需的数据量。
当大模型如GPT、BERT等在预训练阶段并不完全适应特定领域或任务,比如法律文档分析、医疗信息处理,微调可以帮助模型学习特定领域的专业术语和知识。
尽管大模型可能具有丰富的知识,但针对特定任务的训练数据可能较少。微调可以帮助模型更好地适应这些小规模数据,避免过拟合。
新数据或新需求出现时,对模型进行微调可以确保模型始终是最新的。
如果数据敏感,内部组织可能更愿意使用微调而不是公开模型,以保护数据隐私。
模型量化是一种优化技术,它通过减少模型中权重和激活值的表示精度来降低模型的存储需求和计算复杂度。
在深度学习中,量化通常指的是将浮点数(如32位浮点数)转换为较低精度的表示(如16位、8位甚至更低的整数)。
这种转换可以在不显著牺牲模型性能的情况下,大幅减少模型的内存占用和推理时间
。
1、线性量化:这是最常见的量化方法,它将浮点数线性映射到整数范围。例如,一个8位量化会将浮点数映射到0到255或-128到127的整数范围。
2、非线性量化:这种方法使用非线性函数来映射浮点数到整数,通常用于特定类型的数据或模型。
3、对称量化:在对称量化中,量化范围是对称的,例如-127到127,适用于数据分布相对均匀的情况。
4、非对称量化:非对称量化允许量化范围是非对称的,例如0到255,适用于数据分布偏斜的情况。
1、减少内存占用:量化后的模型权重和激活值占用更少的内存,使得模型可以在内存受限的设备上运行。
2、加速推理:低精度计算通常比高精度计算更快,可以在硬件加速器(如GPU、FPGA、ASIC)上实现更快的推理速度。
3、降低功耗:减少计算精度可以降低能耗,对于移动设备和嵌入式系统尤其重要。
4、提高吞吐量:在服务器端,量化可以提高处理请求的速率,从而提高服务质量。
你将学习如何进行数据预处理、训练、运行模型和保存模型(例如,为 Llama.cpp)。
Llama-3 8b 是在令牌数量为15万亿(trillion tokens)的数据集上训练的,而Llama-2只使用了2万亿令牌。
# 安装 Unsloth、Xformers(Flash Attention)和所有其他软件包
!pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
!pip install --no-deps "xformers<0.0.26" trl peft accelerate bitsandbytes
• 支持 Llama、Mistral、CodeLlama、TinyLlama、Vicuna、Open Hermes 等模型。 还有 Yi、Qwen(llamafied)、Deepseek,以及所有基于 Llama、Mistral 的架构。
• unsloth支持16位LoRA或4位QLoRA,速度提升两倍。
• max_seq_length可以设置为任何值,因为unsloth通过kaiokendev的方法进行自动RoPE缩放。
• [NEW] 通过PR 26037,unsloth支持下载4位模型的速度提升4倍!
from unsloth import FastLanguageModel
import torch
max_seq_length = 2048 # 选择想要的任意方法!内部已经实现了对RoPE(Reachable Policy Optimization for Efficient Exploration)缩放的自动支持。
dtype = None # 对于自动检测,请使用 "None";如果使用 Tesla T4 或 V100 加速器,请使用 Float16;如果使用 Ampere 架构的加速器,请使用 Bfloat16。
load_in_4bit = True # 使用 4 位量化(quantization)技术来减少内存使用。这可以是一个可选项
# unsloth支持 4 位预量化模型,这可以使得下载速度提高 4 倍,并且不会出现内存不足(Out of Memory,简称 OOM)的问题。
fourbit_models = [
"unsloth/mistral-7b-bnb-4bit",
"unsloth/mistral-7b-instruct-v0.2-bnb-4bit",
"unsloth/llama-2-7b-bnb-4bit",
"unsloth/gemma-7b-bnb-4bit",
"unsloth/gemma-7b-it-bnb-4bit", # Instruct version of Gemma 7b
"unsloth/gemma-2b-bnb-4bit",
"unsloth/gemma-2b-it-bnb-4bit", # Instruct version of Gemma 2b
"unsloth/llama-3-8b-bnb-4bit", # [NEW] 15 Trillion token Llama-3
] # More models at https://huggingface.co/unsloth
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/llama-3-8b-bnb-4bit",
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
)
我们现在添加了 LoRA(Layer-wise Relevance Analysis,即层次相关性分析)适配器,使得只需更新模型中的 1% 到 10% 的参数!
model = FastLanguageModel.get_peft_model(
model,
r = 16, # Choose any number > 0 ! Suggested 8, 16, 32, 64, 128
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",],
lora_alpha = 16,
lora_dropout = 0, # Supports any, but = 0 is optimized
bias = "none", # Supports any, but = "none" is optimized
# [NEW] "unsloth" uses 30% less VRAM, fits 2x larger batch sizes!
use_gradient_checkpointing = "unsloth", # True or "unsloth" for very long context
random_state = 3407,
use_rslora = False, # We support rank stabilized LoRA
loftq_config = None, # And LoftQ
)
我们现在使用 yahma 的 Alpaca 数据集,共包含 52K 条数据。
数据集如下:
alpaca_prompt = """Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
### Instruction:
{}
### Input:
{}
### Response:
{}"""
EOS_TOKEN = tokenizer.eos_token # tokenized 输出中必须添加 EOS\_TOKEN(结束标记)。这是一个特殊的标记,用于告诉模型一个序列已结束
def formatting_prompts_func(examples):
instructions = examples["instruction"]
inputs = examples["input"]
outputs = examples["output"]
texts = []
for instruction, input, output in zip(instructions, inputs, outputs):
# 表示必须添加 EOS\_TOKEN(结束标记),否则生成的序列会无限延续下去
text = alpaca_prompt.format(instruction, input, output) + EOS_TOKEN
texts.append(text)
return { "text" : texts, }
pass
from datasets import load_dataset
dataset = load_dataset("yahma/alpaca-cleaned", split = "train")
dataset = dataset.map(formatting_prompts_func, batched = True,)
这里使用 60 步进行训练,加速处理,也可以设置 num_train_epochs=1 以进行完整的运行,并将 max_steps=None 关闭。
from trl import SFTTrainer
from transformers import TrainingArguments
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = dataset,
dataset_text_field = "text",
max_seq_length = max_seq_length,
dataset_num_proc = 2,
packing = False, # 在短序列情况下,可以将训练速度提高 5 倍。
args = TrainingArguments(
per_device_train_batch_size = 2,
gradient_accumulation_steps = 4,
warmup_steps = 5,
max_steps = 60,
learning_rate = 2e-4,
fp16 = not torch.cuda.is_bf16_supported(),
bf16 = torch.cuda.is_bf16_supported(),
logging_steps = 1,
optim = "adamw_8bit",
weight_decay = 0.01,
lr_scheduler_type = "linear",
seed = 3407,
output_dir = "outputs",
),
)
# 显示当前GPU的内存信息
gpu_stats = torch.cuda.get_device_properties(0)
start_gpu_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
max_memory = round(gpu_stats.total_memory / 1024 / 1024 / 1024, 3)
print(f"GPU = {gpu_stats.name}. Max memory = {max_memory} GB.")
print(f"已预留{start_gpu_memory}GB的内存")
trainer_stats = trainer.train()
60 步进行训练。
#@title 显示最终的内存和时间统计数据
used_memory = round(torch.cuda.max_memory_reserved() / 1024 / 1024 / 1024, 3)
used_memory_for_lora = round(used_memory - start_gpu_memory, 3)
used_percentage = round(used_memory /max_memory*100, 3)
lora_percentage = round(used_memory_for_lora/max_memory*100, 3)
print(f"{trainer_stats.metrics['train_runtime']} seconds used for training.")
print(f"{round(trainer_stats.metrics['train_runtime']/60, 2)} minutes used for training.")
print(f"Peak reserved memory = {used_memory} GB.")
print(f"Peak reserved memory for training = {used_memory_for_lora} GB.")
print(f"Peak reserved memory % of max memory = {used_percentage} %.")
print(f"Peak reserved memory for training % of max memory = {lora_percentage} %.")
让我们运行模型!您可以更改指令和输入 - 输出留空!
# alpaca_prompt = Copied from above
FastLanguageModel.for_inference(model) # Enable native 2x faster inference
inputs = tokenizer(
[
alpaca_prompt.format(
"Continue the fibonnaci sequence.", # instruction
"1, 1, 2, 3, 5, 8", # input
"", # output - leave this blank for generation!
)
], return_tensors = "pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens = 64, use_cache = True)
tokenizer.batch_decode(outputs)
输出:
['<|begin_of_text|>Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n\n### Instruction:\nContinue the fibonnaci sequence.\n\n### Input:\n1, 1, 2, 3, 5, 8\n\n### Response:\n13, 21, 34, 55, 89, 144, 233, 377, 610, 987<|end_of_text|>']
您也可以使用TextStreamer
进行连续推理 - 这样您可以看到每个词的生成,而不是等待整个过程结束!
# alpaca_prompt = Copied from above
FastLanguageModel.for_inference(model) # Enable native 2x faster inference
inputs = tokenizer(
[
alpaca_prompt.format(
"Continue the fibonnaci sequence.", # instruction
"1, 1, 2, 3, 5, 8", # input
"", # output - leave this blank for generation!
)
], return_tensors = "pt").to("cuda")
from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128)
输出:
# alpaca_prompt = Copied from above
FastLanguageModel.for_inference(model) # Enable native 2x faster inference
inputs = tokenizer(
[
alpaca_prompt.format(
"Continue the fibonnaci sequence.", # instruction
"1, 1, 2, 3, 5, 8", # input
"", # output - leave this blank for generation!
)
], return_tensors = "pt").to("cuda")
from transformers import TextStreamer
text_streamer = TextStreamer(tokenizer)
_ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128)
要将最终模型保存为LoRA适配器,可以使用Huggingface的push_to_hub
进行在线保存或save_pretrained
进行本地保存。
[注意] 这只保存LoRA适配器,而不是完整模型。要保存为16位或GGUF,请向下滚动!
model.save_pretrained("lora_model") # Local saving
tokenizer.save_pretrained("lora_model")
# model.push_to_hub("your_name/lora_model", token = "...") # Online saving
# tokenizer.push_to_hub("your_name/lora_model", token = "...") # Online saving
输出:
('lora_model/tokenizer_config.json',
'lora_model/special_tokens_map.json',
'lora_model/tokenizer.json')
现在,如果你想加载我们刚刚保存的LoRA适配器用于推理,请将False
设置为True
:
if False:
from unsloth import FastLanguageModel
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "lora_model", # YOUR MODEL YOU USED FOR TRAINING
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
)
FastLanguageModel.for_inference(model) # Enable native 2x faster inference
# alpaca_prompt = You MUST copy from above!
inputs = tokenizer(
[
alpaca_prompt.format(
"What is a famous tall tower in Paris?", # instruction
"", # input
"", # output - leave this blank for generation!
)
], return_tensors = "pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens = 64, use_cache = True)
tokenizer.batch_decode(outputs)
输出:
["<|begin_of_text|>Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n\n### Instruction:\nWhat is a famous tall tower in Paris?\n\n### Input:\n\n\n### Response:\nThe Eiffel Tower is a famous landmark in Paris, France. It is a wrought iron tower that was built in 1889 for the World's Fair. Standing at 324 meters tall, it is the tallest building in Paris and one of the most recognizable landmarks in the world.<|end_of_text|>"]
你也可以使用 Hugging Face 的 AutoModelForPeftCausalLM
。只有在你没有安装 unsloth
的情况下,才应该使用它。因为 4bit
模型下载不支持,Unsloth 的 推理速度是 2 倍以上。
if False:
# I highly do NOT suggest - use Unsloth if possible
from peft import AutoPeftModelForCausalLM
from transformers import AutoTokenizer
model = AutoPeftModelForCausalLM.from_pretrained(
"lora_model", # YOUR MODEL YOU USED FOR TRAINING
load_in_4bit = load_in_4bit,
)
tokenizer = AutoTokenizer.from_pretrained("lora_model")
也支持直接保存为 float16
。选择 merged_16bit
以保存为 float16,或选择 merged_4bit
以保存为 int4。
另外还支持 lora
适配器作为备用。使用 push_to_hub_merged
将模型上传至你的 Hugging Face 账户!
# Merge to 16bit
if False: model.save_pretrained_merged("model", tokenizer, save_method = "merged_16bit",)
if False: model.push_to_hub_merged("hf/model", tokenizer, save_method = "merged_16bit", token = "")
# Merge to 4bit
if False: model.save_pretrained_merged("model", tokenizer, save_method = "merged_4bit",)
if False: model.push_to_hub_merged("hf/model", tokenizer, save_method = "merged_4bit", token = "")
# Just LoRA adapters
if False: model.save_pretrained_merged("model", tokenizer, save_method = "lora",)
if False: model.push_to_hub_merged("hf/model", tokenizer, save_method = "lora", token = "")
为了将文件保存为 GGUF
/ llama.cpp
格式,unsloth现在原生支持这一功能!
克隆了 llama.cpp
,并且默认将其保存为 q8_0
格式。unsloth支持所有方法,例如 q4_k_m
。
使用 save_pretrained_gguf
进行本地保存,使用 push_to_hub_gguf
进行上传到 Hugging Face。
一些受支持的量化方法(完整列表请参阅unsloth的 Wiki 页面):
• q8_0
- 快速转换。资源消耗较高,但通常可以接受。
• q4_k_m
- 推荐使用。对于一半的 attention.wv 和 feed_forward.w2 张量使用 Q6_K,其他情况使用 Q4_K。
• q5_k_m
- 推荐使用。对于一半的 attention.wv 和 feed_forward.w2 张量使用 Q6_K,其他情况使用 Q5_K。
# Save to 8bit Q8_0
if False: model.save_pretrained_gguf("model", tokenizer,)
if False: model.push_to_hub_gguf("hf/model", tokenizer, token = "")
# Save to 16bit GGUF
if False: model.save_pretrained_gguf("model", tokenizer, quantization_method = "f16")
if False: model.push_to_hub_gguf("hf/model", tokenizer, quantization_method = "f16", token = "")
# Save to q4_k_m GGUF
if False: model.save_pretrained_gguf("model", tokenizer, quantization_method = "q4_k_m")
if False: model.push_to_hub_gguf("hf/model", tokenizer, quantization_method = "q4_k_m", token = "")
现在,在 llama.cpp
或基于 UI 的系统如 GPT4All
中使用 model-unsloth.gguf
文件或 model-unsloth-Q4_K_M.gguf
文件。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-04-20
我对扣子空间与Manus的产品的思考
2025-04-20
MCP很好,但安全问题不容忽视,智能体安全框架可以解决
2025-04-20
赛博中医大师已经开始为你把脉了
2025-04-20
OpenAI 官方定义:到底什么是 AI Agent?
2025-04-20
AIGC应用必坑指南与落地实战方法论
2025-04-20
「合成用户」进化:基于访谈生成的 1000 个 虚拟用户,能产出洞察吗
2025-04-20
扣子空间火了,是国产通用 agent 一个好的开始,比 manus 还差不少
2025-04-20
微软偷偷上线一款MCP神器,可让Office文件秒变Markdown!
2024-08-13
2024-06-13
2024-08-21
2024-09-23
2024-07-31
2024-05-28
2024-08-04
2024-04-26
2024-07-09
2024-09-17
2025-04-20
2025-04-18
2025-04-16
2025-04-13
2025-04-13
2025-04-13
2025-04-12
2025-04-12