外观
增量预训练(Continue Pre-Training)
内容整理自学习笔记,仅供面试备考参考;不构成录用、培训或考试承诺。
一、为什么需要增量预训练?
预训练学知识,指令微调学格式,强化学习对齐人类偏好——LIMA 等论文为这一观点提供了证据。因此,要让大模型具备领域知识,必须进行增量预训练,仅靠指令微调记忆知识不可靠(不是几十万条数据能做到的)。
二、准备工作
2.1 模型底座选型
| 模型 | 评价 |
|---|---|
| LLaMA | 主流选择,因 Scaling Law 做了充分预训练(有版权问题) |
| BLOOM | 备选,基座比 LLaMA 差,有 7B 版本 |
| Falcon | License 友好,但训练语料无中文,生态欠佳 |
| ChatGLM | 有说法在 SFT 模型上增量预训练效果较差(未证实) |
建议:刚开始实践不需要太多样本,先收集 GB 量级的领域文本跑通流程即可。
2.2 数据准备
- 经典开源预训练数据:WuDao 200G 和 The Pile,加起来约 1T 文本量
- 数据治理是最终效果最关键的部分,基础工作是清理网页爬取数据中的广告
- Falcon 论文中介绍了详细的数据清洗手段,可供参考
三、训练框架选择
大规模训练
使用 Megatron-DeepSpeed 进行 3D 并行训练。炼 LLaMA 可参考开源实现,炼 BLOOM 可直接使用 BigScience 的仓库。
小规模训练
少量节点训练:
- 单节点或多节点(通信快):直接 DeepSpeed ZeRO
- 多节点(通信慢):考虑流水线并行
少量卡训练:
- 显存不够:上 LoRA(如 MedicalGPT 项目)
四、训练流程
- 数据预处理:参考 LLaMA 预训练长度,处理成 2048 长度
- 分词器:先用原版 500K 的 tokenizer.model(加中文词表尚未有定论)
- 原始模型:可使用中文增量预训练后的版本(注意框架间模型层名可能不同)
- 训练参数:显存不够用 ZeRO-3 + offload;多机配 DeepSpeed hostfile
- 观测训练:使用 wandb 记录 loss、FLOPS、吞吐速度、消耗 token 数、测试 PPL
- 模型转换:ZeRO → fp32 → fp16 → HuggingFace 格式
- 模型测试:简单测试续写能力验证模型是否正常
五、关键训练参数
5.1 数据量
至少需要 几 B 的 token;数据量不足几十条时更推荐模型微调。
5.2 Loss 变化
增量预训练开始阶段通常会出现一段时间的 loss 上升,随后慢慢收敛——这是正常现象。
5.3 学习率设置
- 数据集较小时(<100B):使用预训练阶段最大学习率的 10%(如 7B 模型预训练 lr≈3e-4,则 CPT 用 3e-5)
- 需根据 batch size 缩放:lr 缩放倍数 ≈ √(batch_size 倍数)
- lr 过大 → loss 收敛困难,旧能力损失大;lr 过小 → 难以学到新知识
5.4 Warmup 设置
- LLM 训练 warmup_ratio 通常为 epoch × 1% 左右
- CPT 建议调大 warmup_ratio,让模型过渡更平滑
- lr 和 warmup_ratio 相辅相成,通常成正比关系
5.5 Warmup 步数实验结论
- 充分训练后:不管多长预热步数,最终性能差不多
- 训练前期:更长预热步数下,上游和下游 loss 都更低(下游学得快,上游忘得慢)
- 资源不允许充分训练时:较小学习率 + 较长 warmup 是较好选择
5.6 学习率实验结论
- 充分训练后:学习率越大 → 下游性能越好,上游性能越差(忘得最多)
- 未预训练的模型效果不如预训练过的模型
5.7 Rewarmup 实验结论
在原数据集上使用 warmup 继续训练会造成性能损伤,学习率越大损伤越大,且损伤无法在后续训练中找回。因此预训练中断后应恢复到中断前的学习率状态。
六、Pretrain 样本拼接策略
为什么需要拼接?
提高预训练效率、拓展 LLM 最大长度,将若干条短文本随机拼接是预训练阶段常见手段。
拼接方式对比
| 方式 | 描述 | 优缺点 |
|---|---|---|
| Random Concatenate | 随机拼接短文本打满 maxLen | 降低 padding 占比,提高训练效率,但无关文本可能引入噪音 |
| Random Concat + NoiseMask | 添加自定义 attentionMask 使 LLM 仅关注当前 example | ICL few-shot 提升约 1.6%,但相对位置编码信息被掩盖 |
| Random Concat + Cluster | 按实体/语义维度聚类后再拼接 | 理论更优,但存在信息重复和泄露风险 |
| In-Context Pretraining (ICLM) | 利用语义相似度优先拼接最相似的文本 | 语义聚合 + 数据去重,效果显著 |
ICLM 流程
- 将文本 embedding 化(使用 Contriever)
- 基于余弦距离进行数据去重
- 基于旅行商思想串联最相关的文本(用完即扔,不重复)
- 基于拼接后的文本进行预训练
七、基于 LoRA 的 LLaMA2 二次预训练
核心思想
- 本征维度(Intrinsic Dimension):预训练模型内在维度实际上非常小,只有一小部分参数对输出有显著影响
- 存在一个极低维度的参数空间,微调它和在全参数空间中微调效果相同
- LORA 假设权重改变量是低秩的:W = W0 + ΔW, ΔW = BA
关键参数
| 参数 | 推荐值 | 说明 |
|---|---|---|
| lora_rank | 64 | LoRA 低秩矩阵维数 |
| lora_alpha | 128 | 缩放系数,调整效果类似调整学习率 |
| lora_trainable | q_proj,v_proj,k_proj,o_proj,gate_proj,down_proj,up_proj | 可训练模块 |
| modules_to_save | embed_tokens,lm_head | 需保存的模块 |
| lora_dropout | 0.05 | Dropout 率 |
| learning_rate | 2e-4 | 学习率 |
| block_size | 512 | 最大序列长度 |
典型训练命令
bash
torchrun --nnodes 1 --nproc_per_node 1 run_clm_pt_with_peft.py \
--deepspeed ds_zero2_no_offload.json \
--model_name_or_path ${pretrained_model} \
--lr_scheduler_type cosine \
--learning_rate 2e-4 \
--warmup_ratio 0.05 \
--lora_rank 64 \
--lora_alpha 128 \
--fp16 --gradient_checkpointing