pip install transformers accelerate peft bitsandbytes datasets torch
# 可选:Flash Attention 2(加速训练)
pip install flash-attn --no-build-isolation需转换为 JSONL 格式,每条数据包含 instruction、input、output(或 text 字段):
{"instruction": "解释量子纠缠", "input": "", "output": "量子纠缠是..."}或使用对话格式(适配 Llama 3 的 Chat Template):
{"text": "[INST] 解释量子纠缠 [/INST] 量子纠缠是..."}from datasets import load_dataset
dataset = load_dataset("json", data_files="train.jsonl", split="train")使用 BitsAndBytes 进行 4-bit 量化,降低显存占用:
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
# 量化配置
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype="bfloat16"
)
# 加载模型(需先申请 Hugging Face 访问权限)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Meta-Llama-3-8B-Instruct", # 或 base 模型
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True
)
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")
tokenizer.pad_token = tokenizer.eos_token # 设置填充符仅微调少量参数(约 0.1%~1% 原模型参数):
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
# 准备模型(启用梯度检查点等)
model = prepare_model_for_kbit_training(model)
# LoRA 配置
lora_config = LoraConfig(
r=16, # 秩(常用 8~64)
lora_alpha=32, # 缩放因子(通常 2*r)
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"], # Llama 3 注意力层
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
# 应用 LoRA
model = get_peft_model(model, lora_config)
model.print_trainable_parameters() # 输出可训练参数比例使用 Trainer 或自定义训练循环:
from transformers import TrainingArguments, Trainer
training_args = TrainingArguments(
output_dir="./llama3-lora",
per_device_train_batch_size=1, # 根据显存调整
gradient_accumulation_steps=4, # 模拟更大 batch size
num_train_epochs=3,
learning_rate=2e-4,
fp16=True, # 或 bf16(A100/H100)
logging_steps=10,
save_steps=100,
save_total_limit=2,
optim="paged_adamw_8bit", # 8-bit Adam 优化器
report_to="none" # 关闭 WandB 等
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dataset,
tokenizer=tokenizer
)
trainer.train()model.save_pretrained("./llama3-lora-final") # 仅保存适配器权重from peft import PeftModel
# 加载基础模型(4-bit 量化)
base_model = AutoModelForCausalLM.from_pretrained(...)
model = PeftModel.from_pretrained(base_model, "./llama3-lora-final")
# 推理
inputs = tokenizer("解释量子纠缠", return_tensors="pt").to("cuda")
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0]))model = model.merge_and_unload() # 合并后保存r、降低 batch_size 或使用更激进量化(如 3-bit)。通过以上步骤,可在消费级 GPU 上高效微调 Llama 3。如需完整代码示例,可参考 Hugging Face PEFT 文档。