外观
LLaMA2 中文适配训练全流程实战
内容整理自学习笔记,仅供面试备考参考;不构成录用、培训或考试承诺。
1. 为什么需要对 LLaMA2 做基于 LoRA 的二次预训练?
加入中文训练语料进行 LLaMA2 的二次预训练,使模型增加支持中文输出的能力。
2. 二次预训练的目标
在保持预训练模型权重不变的情况下,通过添加额外的网络层并仅训练这些新增的网络层参数,实现大模型的高效微调(PEFT)。
3. 核心思想:本征维度(Intrinsic Dimension)
3.1 理论基础
Aghajanyan 研究发现,预训练模型的本征维度实际上非常小——只有一小部分参数对模型输出有显著影响:
存在一个极低维度的参数子空间,微调它和在全参数空间中微调能起到相同的效果。
3.2 LoRA 的数学表达
LoRA 假设模型在任务适配过程中权重的改变量是低秩的:
参数更新范围:只训练新增的网络层参数。
4. 语料构建思路
以中文书籍作为训练语料,来自中文书籍收录整理项目。
4.1 数据集格式
- 文件格式:
.txt - 示例数据:《红楼梦》等经典中文书籍
txt
《红楼梦》
曹雪芹 高鄂 著
第一回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀
列位看官:你道此书从何而来?...5. 基于 LoRA 的 LLaMA2 二次预训练参数配置
5.1 核心参数
python
######## 参数设置 ########
lr = 2e-4 # 学习率
lora_rank = 64 # LoRA 低秩矩阵维数
lora_alpha = 128 # LoRA 缩放系数(调整 Alpha ≈ 调整 LR)
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 比率
pretrained_model = "/root/llama/all_transformer" # 预训练模型路径
chinese_tokenizer_path = "/root/llama/all_transformer" # 分词器路径
dataset_dir = "/root/llama/data" # 数据集路径
per_device_train_batch_size = 1 # 每设备批次大小
gradient_accumulation_steps = 1 # 梯度累积步数
block_size = 512 # 最大序列长度
training_steps = 25000 # 训练步数5.2 可训练模块说明
| 模块 | 说明 |
|---|---|
q_proj / k_proj / v_proj | 多头注意力机制中的三个线性变换,将输入映射到高维向量空间 |
o_proj | 多头注意力输出层,将模型输出映射到概率分布 |
gate_proj / down_proj / up_proj | FFN 中的三个线性变换 |
embed_tokens | 将输入 Token 映射到高维向量空间 |
lm_head | 预测下一个 Token 的输出层 |
5.3 启动命令
bash
torchrun --nnodes 1 --nproc_per_node 1 scripts/training/run_clm_pt_with_peft.py \
--deepspeed ${deepspeed_config_file} \
--model_name_or_path ${pretrained_model} \
--tokenizer_name_or_path ${chinese_tokenizer_path} \
--dataset_dir ${dataset_dir} \
--data_cache_dir ${data_cache} \
--validation_split_percentage 0.001 \
--per_device_train_batch_size ${per_device_train_batch_size} \
--do_train \
--seed $RANDOM \
--fp16 \
--max_steps ${training_steps} \
--num_train_epochs 1 \
--lr_scheduler_type cosine \
--learning_rate ${lr} \
--warmup_ratio 0.05 \
--weight_decay 0.01 \
--logging_strategy steps \
--logging_steps 10 \
--save_strategy steps \
--save_total_limit 3 \
--save_steps 500 \
--gradient_accumulation_steps ${gradient_accumulation_steps} \
--preprocessing_num_workers 8 \
--block_size ${block_size} \
--output_dir ${output_dir} \
--overwrite_output_dir \
--ddp_timeout 30000 \
--logging_first_step True \
--lora_rank ${lora_rank} \
--lora_alpha ${lora_alpha} \
--trainable ${lora_trainable} \
--modules_to_save ${modules_to_save} \
--lora_dropout ${lora_dropout} \
--torch_dtype float16 \
--gradient_checkpointing \
--ddp_find_unused_parameters False6. 基于 LoRA 的 LLaMA2 微调(SFT)
6.1 训练数据
使用 Chinese-LLaMA-Alpaca 开源的中文 Alpaca 数据,包含约 51K 条从 ChatGPT(GPT-3.5-Turbo)爬取的指令数据。
数据格式:
json
{
"instruction": "我们如何在日常生活中减少用水?",
"input": "",
"output": "1. 使用节水装置,如节水淋浴喷头和水龙头..."
}对于包含
input字段的数据,采用f"{instruction}+\n+{input}"进行拼接。
6.2 微调参数
python
lr = 1e-4 # 微调 LR 比预训练小
lora_rank = 64
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
per_device_train_batch_size = 1
gradient_accumulation_steps = 8
max_seq_length = 512
training_steps = 6000
validation_file = "data_pt/alpaca_data_zh_51k.json"7. 推理加载
bash
python scripts/inference/inference_hf.py \
--base_model correspond_output_dir \ # 基础模型
--lora_model sft_output_dir2/sft_lora_model \ # LoRA 模型(可选)
--tokenizer_path correspond_output_dir \ # 分词器路径
--with_prompt # 自动用提示符包装输入推理时也支持:
- 仅加载基础模型(不指定
--lora_model) - 加载 LoRA 权重后进行推理
- 将 LoRA 合并后以标准格式加载
8. DeepSpeed 配置
使用 ds_zero2_no_offload.json 配置 ZeRO-2(无 Offload)进行分布式训练。
9. 显存占用参考
基于 LoRA 的二次预训练相比全参数训练,显存占用显著降低。具体占用取决于:
- Rank 大小
- Target Modules 选择
- Batch Size
- Sequence Length(block_size)
- 是否启用 Gradient Checkpointing
10. 关键经验总结
| 要点 | 建议 |
|---|---|
| Rank | 二次预训练用 64(比普通 LoRA 的 4-8 大得多) |
| Alpha | 默认 = 2 × Rank(128),调节 Alpha ≈ 调节 LR |
| Target Modules | 全打满(q/k/v/o + gate/down/up) |
| Modules to Save | embed_tokens + lm_head(保留词表和输出能力) |
| LR | 预训练 2e-4 → 微调 1e-4 |
| 数据格式 | 预训练用纯文本 .txt,微调用 Alpaca JSON 格式 |
| DeepSpeed | ZeRO-2(无 Offload)配 FP16 |
| 梯度累积 | 预训练不累积(step=1),微调可累积(step=8) |