1. 大模型训练流程概述
大语言模型(LLM)的训练通常遵循"预训练-有监督微调-偏好对齐"的三阶段流程。这种分阶段训练方式能够逐步赋予模型语言理解、任务执行和人类偏好对齐的能力。本章将重点介绍使用Transformers框架结合Deepspeed和PEFT工具链实现这一完整流程的技术细节。
在预训练阶段,模型通过海量无标注文本学习语言规律和世界知识;有监督微调阶段则使用指令数据教会模型遵循人类指令;最后的偏好对齐阶段通过强化学习或直接偏好优化方法,使模型输出更符合人类价值观。每个阶段都有其独特的技术挑战和解决方案。
2. 预训练阶段核心技术
2.1 Transformers框架基础
Hugging Face的Transformers框架已成为LLM训练的事实标准。其核心优势在于:
- 模块化设计支持BERT、GPT、LLaMA等主流架构
- 内置Trainer类封装分布式训练逻辑
- 庞大的模型社区(25万+数据集,数亿预训练参数)
- 与Deepspeed、WandB等工具的无缝集成
python复制from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-1.5B")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-1.5B")
2.2 数据处理关键步骤
预训练数据处理需要特别注意:
- 文本拼接:将多个样本拼接为固定长度(如2048 tokens)的文本块
- 内存优化:使用内存映射和流式加载处理大规模数据
- 并行处理:利用多进程加速tokenize过程
python复制def group_texts(examples):
# 拼接文本并分块
concatenated = {k: list(chain(*examples[k])) for k in examples.keys()}
total_length = len(concatenated[list(examples.keys())[0]])
total_length = (total_length // block_size) * block_size
return {
k: [t[i:i+block_size] for i in range(0, total_length, block_size)]
for k, t in concatenated.items()
}
2.3 分布式训练配置
使用Deepspeed的Zero-2阶段配置可显著降低显存占用:
json复制{
"fp16": {"enabled": "auto"},
"optimizer": {
"type": "AdamW",
"params": {"lr": "auto"}
},
"zero_optimization": {
"stage": 2,
"offload_optimizer": {"device": "none"},
"allgather_partitions": true,
"reduce_scatter": true,
"contiguous_gradients": true
}
}
启动训练时建议使用梯度检查点技术:
bash复制deepspeed pretrain.py \
--per_device_train_batch_size 16 \
--gradient_accumulation_steps 4 \
--gradient_checkpointing \
--deepspeed ds_config_zero2.json
3. 有监督微调实践
3.1 SFT与Pretrain的核心差异
- 数据格式:使用指令对数据而非纯文本
- Loss计算:仅对回答部分计算损失
- 学习目标:指令跟随能力而非语言建模
典型的多轮对话数据处理逻辑:
python复制def process_conversation(conversation):
input_ids = []
labels = []
# 添加系统提示
system_prompt = "<|im_start|>system\nYou are helpful assistant.<|im_end|>\n"
input_ids.extend(tokenizer.encode(system_prompt))
labels.extend([-100]*len(input_ids)) # 忽略系统提示的loss
# 处理每轮对话
for turn in conversation:
role = "human" if turn["from"]=="user" else "assistant"
text = f"<|im_start|>{role}\n{turn['value']}<|im_end|>\n"
turn_ids = tokenizer.encode(text)
input_ids.extend(turn_ids)
if role == "assistant":
labels.extend(turn_ids) # 只计算assistant部分的loss
else:
labels.extend([-100]*len(turn_ids))
return {"input_ids": input_ids, "labels": labels}
3.2 微调中的关键技巧
- 学习率设置:通常为预训练的1/10(如1e-5 vs 1e-4)
- Batch Size:可适当增大以提高训练稳定性
- 序列长度:根据任务需求调整,对话任务通常需要更长上下文
提示:SFT阶段建议使用WandB或TensorBoard监控训练过程,特别关注验证集上的损失曲线。
4. 高效微调技术解析
4.1 LoRA原理与实现
LoRA(Low-Rank Adaptation)通过在原始权重矩阵旁添加低秩分解矩阵来实现高效微调:
code复制ΔW = BA 其中 B∈ℝ^(d×r), A∈ℝ^(r×k), r << min(d,k)
PEFT库中的关键配置参数:
python复制peft_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
inference_mode=False,
r=8, # 秩
lora_alpha=32, # 缩放系数
target_modules=["q_proj", "v_proj"], # 作用模块
lora_dropout=0.1,
)
4.2 不同场景下的参数选择
| 场景类型 | 推荐秩(r) | α值 | 适用模块 |
|---|---|---|---|
| 简单指令跟随 | 4-8 | 16-32 | q_proj,v_proj |
| 复杂推理任务 | 8-16 | 32-64 | q_proj,k_proj,v_proj |
| 知识注入 | 16-32 | 64-128 | 全连接层 |
4.3 训练注意事项
- 初始化策略:矩阵A用随机高斯初始化,矩阵B初始化为零
- 混合精度训练:建议使用bf16格式
- 参数合并:训练完成后可通过
merge_and_unload()将LoRA权重合并到基础模型
python复制model = get_peft_model(base_model, peft_config)
# 训练过程...
model.save_pretrained("./lora_weights")
merged_model = model.merge_and_unload()
5. 偏好对齐进阶技术
5.1 三大主流方法对比
| 方法 | 需要奖励模型 | 训练复杂度 | 典型数据需求 |
|---|---|---|---|
| RLHF | 是 | 高 | 10万+对比数据 |
| DPO | 否 | 中 | 1万+对比数据 |
| KTO | 否 | 低 | 5万+单回答数据 |
5.2 DPO实现要点
DPO(Direct Preference Optimization)的核心是直接优化偏好损失:
python复制class DPOTrainer(Trainer):
def compute_loss(self, model, inputs, return_outputs=False):
# 获取chosen和rejected的logits
chosen_logits = model(inputs["chosen_input_ids"]).logits
rejected_logits = model(inputs["rejected_input_ids"]).logits
# 计算log-sigmoid差值
log_ratio = chosen_logits - rejected_logits
loss = -F.logsigmoid(self.beta * log_ratio)
return (loss, outputs) if return_outputs else loss
关键参数β控制偏好强度,通常取值0.1-0.5。
5.3 数据构建建议
- 多样性:覆盖模型可能出现的各类错误模式
- 一致性:标注标准需统一
- 质量把控:至少经过双重校验
- 负样本:包含典型错误类型(幻觉、不安全内容等)
6. 工程实践中的经验总结
- 显存优化组合:梯度检查点+LoRA+Deepspeed Zero-2可将百亿模型微调显存需求从320GB降至24GB
- 学习率预热:SFT阶段建议设置200-500步的warmup
- 早停策略:当验证集loss连续3个epoch不下降时终止训练
- 评估指标:除了loss外,应设计任务相关的评估指标(如回答质量评分)
典型的多卡训练启动命令:
bash复制CUDA_VISIBLE_DEVICES=0,1,2,3 torchrun \
--nproc_per_node=4 \
--master_port=29500 \
train.py \
--model_name_or_path Qwen-1.5B \
--use_peft \
--peft_config lora_config.json \
--deepspeed ds_config.json
在实际项目中,建议先在小规模数据上验证流程,再扩展到全量数据。同时要注意不同框架版本的兼容性问题,特别是Transformers与Deepspeed的版本匹配。
