pip install unsloth
初始化 需要安装peft trl transformer
1. 加载模型 + 分词器
from unsloth import FastLanguageModel
#导入FastLanguageModel模型 然后载入模型
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=”unsloth/Meta-Llama-3.1-8B-bnb-4bit”,
max_seq_length=2048,
dtype=None,
load_in_4bit=True,
)
#model_name 为Q4量化的模型位置 最大长度2048 是4bit量化
#dtype设置为None ?
2. 加 LoRA 适配器
model = FastLanguageModel.get_peft_model(
model,
r=16, lora_alpha=32, lora_dropout=0.05,
target_modules=[“q_proj”, “k_proj”, “v_proj”, “o_proj”,
“gate_proj”, “up_proj”, “down_proj”],
use_gradient_checkpointing=”unsloth”,
)
#r=16 Lora的rank为16 可以拆封原始矩阵的权重,r越大训练和显存变大
#8b 16-64 1.5b 8 70b 128
#lora_aplha=32 缩放因子 lora后对原始权重影响 与r比较是2倍可以提升训练速度,但是越大可能会过拟合
#lora_dropout 0.05 防止上面过拟合 在上面AB 矩阵上加上Dropout
#target_modules 其中 qwen3 8b也可以all-linear把所有的nn.Linear都插入Lora但是也可以使用和llama一样的[“q_proj”, “k_proj”, “v_proj”, “o_proj”,
“gate_proj”, “up_proj”, “down_proj”]
#前面的[“q_proj”, “k_proj”, “v_proj”, “o_proj”, 是注意力
#”gate_proj”, “up_proj”, “down_proj”] FNN SwiGLU
#use_gradient_checkpointing unsloth 梯度检查点。用时间换空间unsolth用这个即可。显存小就靠他
3. 构造「ChatML」格式数据
chat = [
{“role”: “user”, “content”: “介绍一下光合作用”},
{“role”: “assistant”, “content”: “光合作用 🌱 是植物把阳光 → 化学能的过程。”},
]
text = tokenizer.apply_chat_template(chat, tokenize=False)
dataset = [{“text”: text}] * 200 # 快速演示:复制 200 条
#对话格式
4. 训练
from trl import SFTTrainer
from transformers import TrainingArguments
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
dataset_text_field=”text”,
max_seq_length=2048,
args=TrainingArguments(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
warmup_steps=10,
max_steps=300,
learning_rate=2e-4,
fp16=not torch.cuda.is_bf16_supported(),
bf16=torch.cuda.is_bf16_supported(),
logging_steps=1,
output_dir=”outputs”,
optim=”adamw_8bit”,
),
)
trainer.train()
#其中V100 只能FP16
#改成下面的args参数: args=TrainingArguments(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
warmup_steps=10,
max_steps=300,
learning_rate=2e-4,
fp16=True, # V100 只用 FP16
bf16=False, # 显式关闭 BF16
logging_steps=1,
output_dir=”outputs”,
optim=”adamw_8bit”,
)
5. 保存 & 本地推理
model.save_pretrained(“lora_llama31_emoji”) # 只存 LoRA
tokenizer.save_pretrained(“lora_llama31_emoji”)
推理
FastLanguageModel.for_inference(model)
inputs = tokenizer(“用一句话+Emoji 介绍黑洞”, return_tensors=”pt”).to(“cuda”)
print(tokenizer.decode(model.generate(**inputs, max_new_tokens=64)[0]))