☰
DeepSpeed-Chat 第二步 DPO 微调训练脚本实战:从 OPT-350m 到 Llama-2-7b 的模型替换与参数全解
2026/10/5 1:57:09 网站建设 项目流程
  • 示例工程

【免费下载链接】DeepSpeedExamples

Example models using DeepSpeed

项目地址:https://gitcode.com/gh_mirrors/de/DeepSpeedExamples
点击查看免费下载

本指南聚焦 DeepSpeed-Chat 训练流水线第二步——Direct Preference Optimization(DPO)偏好对齐微调中training_scripts/目录下的全部训练脚本:你将学会如何用一条命令在单卡、单机多卡、多节点场景下启动 DPO 训练,如何通过--model_name_or_path一键切换facebook/opt、EleutherAI/gpt-neo、meta-llama/Llama-2等模型家族,理解 ZeRO 阶段、CPU 卸载、LoRA、梯度检查点等关键参数的作用,并深入 DPO 损失函数的源码实现原理。

一、训练脚本目录总览

在 applications/DeepSpeed-Chat/training/step2_dpo_finetuning/ 下,training_scripts/目录按模型家族与运行规模组织脚本,其结构为:

training_scripts/ ├── llama2/ │ ├── run_llama2_7b.sh # Llama-2-7B 全参数 DPO │ └── run_llama2_7b_lora.sh # Llama-2-7B LoRA 高效 DPO └── opt/ ├── multi_node/ │ └── run_350m.sh # 多节点分布式 ├── single_gpu/ │ └── run_350m.sh # 单 GPU └── single_node/ ├── run_350m.sh # 单机多卡 └── sweep/ ├── run_step2_sweep.sh # 超参扫描入口 ├── run_single.sh # 单次运行封装 └── README.md

如 training_scripts/README.md 所述:每个文件夹中的 bash 脚本默认都以 "facebook/opt" 家族为示例。所有脚本最终都调用同一个入口 main.py,区别仅在于传入的命令行参数组合,因此理解一个脚本即可掌握整套脚本的用法。

二、DPO 微调简介:为什么训练参数与 Reward Model 微调几乎相同

DPO(Direct Preference Optimization)是一种直接偏好学习算法:它不再显式训练奖励模型、再用强化学习(RLHF 第三步)优化策略,而是利用奖励模型的特定参数化形式,在闭式解中提取对应的最优策略,通过一个简单的分类损失让语言模型直接与人类偏好对齐,避开了 RLHF 的复杂性与不稳定性。

正如 DPO 论文标题所言"Your Language Model is Secretly a Reward Model"——由于语言模型本身就蕴含奖励建模能力,DPO 的训练参数与训练流程绝大部分与 step2 "Reward Model (RM) finetuning" 相同(这也是两个 step 目录脚本结构几乎一致的原因)。训练完成后,你会得到一个已经与人类偏好对齐的语言模型。这一背景在 step2 DPO README 中有完整说明。

三、快速上手:OPT-350m 单机训练

training_scripts/opt/single_node/run_350m.sh 是官方推荐的入门脚本,在 step2 目录下直接执行:

bash training_scripts/opt/single_node/run_350m.sh

脚本接受两个位置参数:OUTPUT(输出目录,默认./output)与ZERO_STAGE(默认0)。脚本核心命令如下:

deepspeed main.py \ --data_path Dahoas/rm-static Dahoas/full-hh-rlhf Dahoas/synthetic-instruct-gptj-pairwise yitingxie/rlhf-reward-datasets \ --data_split 2,4,4 \ --model_name_or_path facebook/opt-350m \ --per_device_train_batch_size 4 \ --per_device_eval_batch_size 4 \ --max_seq_len 512 \ --learning_rate 5e-5 \ --weight_decay 0.1 \ --num_train_epochs 1 \ --dropout 0.0 \ --gradient_accumulation_steps 1 \ --lr_scheduler_type cosine \ --num_warmup_steps 0 \ --seed 1234 \ --zero_stage $ZERO_STAGE \ --deepspeed \ --output_dir $OUTPUT \ &> $OUTPUT/training.log

要点解读:

  • 数据:--data_path可同时传入多个偏好数据集(Dahoas/rm-static、Dahoas/full-hh-rlhf、Dahoas/synthetic-instruct-gptj-pairwise、yitingxie/rlhf-reward-datasets),多个数据集会被混合拼接;--data_split 2,4,4表示三个训练阶段(SFT/RM/PPO)按 2:4:4 划分同一份数据,DPO 使用其中的 phase 2 部分,与 main.py 中train_phase = 2的设定 对应。
  • 精度与硬件:默认 ZeRO Stage 0(--zero_stage 0),OPT-350m 规模下单机即可训练;--dtype默认fp16(可切bf16)。
  • 日志:所有输出重定向到$OUTPUT/training.log,便于后台观察训练进度。

四、切换模型:--model_name_or_path 就是唯一开关

这是 training_scripts/README.md 的核心指导:所有脚本都默认使用facebook/opt-350m,想换成其他模型,只需替换--model_name_or_path参数。例如把 OPT-350m 换成 EleutherAI 的 GPT-Neo 系列:

# 原命令 --model_name_or_path facebook/opt-350m # 替换为 --model_name_or_path EleutherAI/gpt-neo-125m

由于脚本内部通过 Transformers 的AutoModelForCausalLM与load_hf_tokenizer自动加载模型和分词器(见 main.py 中模型创建与分词器加载),因此任何 Hugging Face 上的因果语言模型(causal LM)原则上都可以通过这一个参数接入,例如将EleutherAI/gpt-j-6b作为目标模型。关于项目完整支持(含 llama2 7B/13B、llama2-70b 等)的模型清单,请查阅 DeepSpeed-Chat 支持的模型列表(即训练脚本 README 中所指 "our landing page")。

更换模型时需要同步考虑两点:一是显存规模,二是学习率——大模型通常需要更小的学习率(见下文 Llama-2 脚本中9.65e-6的取值)。

五、Llama-2-7B:全参数训练与 LoRA 高效微调

5.1 全参数训练

training_scripts/llama2/run_llama2_7b.sh 展示了 7B 级模型的配置思路,默认输出目录为./output_step2_llama_7b_epoch1_lr9.65e-6,默认ZERO_STAGE=3:

deepspeed main.py \ --data_path Dahoas/rm-static \ --data_split 2,4,4 \ --model_name_or_path meta-llama/Llama-2-7b-hf \ --per_device_train_batch_size 8 \ --per_device_eval_batch_size 8 \ --max_seq_len 512 \ --learning_rate 9.65e-6 \ --weight_decay 0.1 \ --num_train_epochs 1 \ --gradient_accumulation_steps 1 \ --lr_scheduler_type cosine \ --num_warmup_steps 0 \ --seed 1234 \ --gradient_checkpointing \ --zero_stage $ZERO_STAGE \ --deepspeed \ --offload \ --output_dir $OUTPUT \ &> $OUTPUT/training.log

与 OPT-350m 脚本相比,Llama-2 脚本的关键差异:

  • --zero_stage 3+--offload:ZeRO-3 将模型参数、梯度、优化器状态分片到所有 GPU,--offload再把优化器状态等卸载到 CPU(对应DeepSpeedCPUAdam优化器路径,见 main.py 优化器选择),使 7B 模型在有限显存下可训练。
  • --gradient_checkpointing:以少量计算换取显存,进一步降低激活值占用。
  • --learning_rate 9.65e-6:远低于 OPT-350m 的5e-5,符合大模型 DPO 微调常见做法。

5.2 LoRA 高效微调

training_scripts/llama2/run_llama2_7b_lora.sh 在上一脚本基础上叠加 LoRA 参数:

--lora_dim 128 \ --lora_module_name "layers." \

对应 main.py 的 LoRA 分支:当--lora_dim > 0时,调用convert_linear_layer_to_lora将指定模块范围内的线性层替换为 LoRA 低秩分解结构;配合--only_optimize_lora可以只优化 LoRA 参数(冻结基座模型),配合--lora_learning_rate(默认5e-4)单独设置 LoRA 学习率。训练结束保存时,main.py 会调用convert_lora_to_linear_layer将 LoRA 权重合并回原模型,再以标准 HF 格式保存。

六、多节点与单卡场景

多节点:training_scripts/opt/multi_node/run_350m.sh 与单节点脚本参数一致,仅将per_device_train_batch_size降到2(多卡场景下总 batch 由 world size 放大),配合 DeepSpeed 的分布式启动方式运行。

单卡:training_scripts/opt/single_gpu/run_350m.sh 是最精简的示例,通过deepspeed --num_gpus 1 main.py显式限定单 GPU,并将--gradient_accumulation_steps提升到4以模拟较大 batch,同时开启 TensorBoard 记录:

deepspeed --num_gpus 1 main.py --model_name_or_path facebook/opt-350m \ --weight_decay 0.1 --dropout 0.0 --gradient_accumulation_steps 4 --zero_stage $ZERO_STAGE \ --enable_tensorboard \ --tensorboard_path $OUTPUT \ --deepspeed --output_dir $OUTPUT &> $OUTPUT/training.log

其中--enable_tensorboard/--tensorboard_path对应 main.py 的 TensorBoard 日志参数,默认路径为step2_tensorboard,供后续用 TensorBoard 观察损失曲线。

七、超参扫描:sweep 脚本自动化跑批

DPO 脚本还内置了一套超参扫描工具,见 training_scripts/opt/single_node/sweep/。其 README.md 说明:当前扫描覆盖ZeRO Stage ∈ {2, 3}与Offload ∈ {True, False}共 4 种组合。

入口脚本 run_step2_sweep.sh 双层循环生成 4 个组合,逐个调用 run_single.sh:

for z in {2..3} do for offload in true false do cmd="bash training_scripts/opt/single_node/sweep/run_single.sh \ ${z} ${offload} z${z}_offload_${offload}" $cmd pkill -9 python sleep 60 done done

每次跑完一组后脚本会pkill -9 python并休眠 60 秒清理显存,run_single.sh则把 ZeRO 阶段与 Offload 开关拼进deepspeed main.py命令(Offload 为 true 时追加--offload)。该框架可以很容易地扩展扫描维度(学习率、weight decay 等),只需在run_single.sh中追加参数变量即可。运行扫描只需一条命令(在 step2 目录下):

bash training_scripts/opt/single_node/sweep/run_step2_sweep.sh

八、main.py 核心参数全解

所有脚本共享 main.py 的parse_args中定义的参数体系,下表按功能分组整理关键参数:

类别参数默认值说明
数据--data_pathDahoas/rm-static训练数据路径,支持多个数据集混合
数据--data_split2,4,4三阶段数据划分比例,DPO 取 phase 2
数据--data_output_path/tmp/data_files/预处理缓存(shuffle index、tokenized .pt 文件)存放位置,建议放在节点本地存储
模型--model_name_or_path必填预训练模型路径或 HF 模型 ID
模型--max_seq_len512最大序列长度
模型--dropoutNone覆盖模型默认 dropout,脚本中常用0.0
训练--per_device_train_batch_size16每设备训练 batch
训练--per_device_eval_batch_size16每设备评估 batch
训练--num_train_epochs1训练轮数
训练--gradient_accumulation_steps1梯度累积步数
优化--learning_rate1e-3初始学习率(OPT 脚本用5e-5,Llama-2 用9.65e-6)
优化--weight_decay0.0权重衰减,脚本常用0.1
优化--lr_scheduler_typecosine调度器类型:linear/cosine/cosine_with_restarts/polynomial/constant/constant_with_warmup
优化--num_warmup_steps0预热步数
DPO 损失--beta1e-1DPO 损失温度参数,典型取值 0.1~0.5;beta 趋近 0 时等价于忽略参考模型
DPO 损失--label_smoothing0.0标签平滑,假设偏好存在噪声(以该概率翻转)
DeepSpeed--zero_stage0ZeRO 优化阶段(Actor 模型)
DeepSpeed--offload关闭启用 ZeRO CPU Offload
DeepSpeed--offload_reference_model关闭为参考模型单独启用 Offload
DeepSpeed--dtypefp16训练精度,可选fp16/bf16
显存--gradient_checkpointing关闭梯度检查点
LoRA--lora_dim0大于 0 时启用 LoRA 高效训练
LoRA--lora_module_namedecoder.layers.LoRA 作用模块范围
LoRA--only_optimize_lora关闭只优化 LoRA 参数
LoRA--lora_learning_rate5e-4LoRA 学习率
精度--compute_fp32_loss关闭低精度(fp16/bf16)下用 fp32 计算损失
日志--enable_tensorboard关闭开启 TensorBoard
日志--tensorboard_pathstep2_tensorboardTensorBoard 日志目录
其他--seed1234随机种子,保证可复现
其他--local_rank-1分布式训练 local_rank,-1 表示单机

两个需要展开的 DPO 专属参数(其含义直接对应损失函数源码):

  • --beta(温度参数):控制对参考模型(未对齐的初始策略)偏离的惩罚强度。beta越大,模型越不偏离参考模型;beta -> 0时损失退化为仅最大化 chosen 与 rejected 的对数概率差,等价于忽略参考模型。
  • --label_smoothing:用于处理偏好标签噪声——假设偏好以该概率被翻转,对应损失中logsigmoid(logits) * (1 - label_smoothing)与logsigmoid(-logits) * label_smoothing两项的加权。

此外注意:main.py会通过deepspeed.add_config_arguments(parser)挂接 DeepSpeed 的通用配置参数,因此还可在命令行直接传入--deepspeed_config等标准 DeepSpeed 参数。

九、源码层面:DPO 损失是如何计算的

理解训练脚本背后的计算逻辑,能帮助你正确调参。DPO 训练需要同时前向两个模型——被训练的策略模型与冻结的参考模型,main.py 中的ref_model构建逻辑 显示:参考模型与 Actor 使用同一权重初始化,且当zero_stage != 3时参考模型以 ZeRO-0 加载(假设显存足够容纳),只有 ZeRO-3 场景才为参考模型复用分片配置,并支持--offload_reference_model将参考模型卸载到 CPU。

每次训练 step 的核心流程(main.py 训练循环):

  1. DataCollatorReward(见 dschat/utils/data/data_utils.py 中的实现)将每个样本的 chosen 与 rejected 序列拼接到同一 batch,input_ids前半为 chosen、后半为 rejected;
  2. 对每条样本计算 chosen 与 rejected 首个分叉 token 位置divergence_ind,将该位置之前的label_mask置 0(只对分歧之后的部分计算对数概率,避免 prompt 前缀抵消);
  3. get_batch_logps(main.py L219-L229)通过torch.gather从 logits 的 log_softmax 中取出每个真实 token 的对数概率并按 label_mask 求和,得到序列级对数概率;
  4. 分别对策略模型(model)与参考模型(ref_model,torch.no_grad())计算chosen_logps、rejected_logps、ref_chosen_logps、ref_rejected_logps;
  5. 按如下公式计算 DPO 损失:
logits = beta * ((chosen_logps - ref_chosen_logps) - (rejected_logps - ref_rejected_logps)) loss = -logsigmoid(logits) * (1 - label_smoothing) - logsigmoid(-logits) * label_smoothing

其中beta * (logps - ref_logps)正是隐式奖励的估计,logsigmoid项则让 chosen 隐式奖励高于 rejected,从而驱动策略对齐人类偏好。main.py 注释表明该实现参考了 DPO 开源实现与 Hugging Face TRL 的dpo_trainer。

评估阶段(main.pyevaluation函数)以同样的方式计算验证集损失,并额外输出chosen_rewards与rejected_rewards(即隐式奖励均值),供训练前后对比模型对齐程度。

十、数据集格式:每个样本一对 chosen / rejected

由于 DPO 把语言模型当作奖励模型使用,其数据集格式与 Reward Model 微调完全一致(见 step2 DPO README 的 Datasets 小节):同一输入 prompt 对应两条输出——一条 "chosen"(被人类偏好)与一条 "rejected"(被拒绝)。训练时模型的目标就是增大 chosen 序列的相对概率、压低 rejected 序列的相对概率。仓库默认使用的Dahoas/rm-static、Dahoas/full-hh-rlhf等开源偏好数据集均符合该格式。

十一、训练后评估与模型输出

DPO 训练产出的 checkpoint本质上就是一个对齐后的语言模型,因此可以像 step1 "Supervised Finetuning" 那样直接评估(如做生成测试、下游任务评测)。模型保存逻辑见 main.py 保存部分:默认以标准 HF 格式保存(save_hf_format),而当--zero_stage 3时因每个 GPU 只持有模型分片,会额外调用save_zero_three_model完成 ZeRO-3 的权重聚合保存。

总结:如何选择训练脚本

你的场景推荐脚本
入门验证 / 单机多卡training_scripts/opt/single_node/run_350m.sh
单 GPU 显存受限training_scripts/opt/single_gpu/run_350m.sh(配合--gradient_accumulation_steps)
多节点集群training_scripts/opt/multi_node/run_350m.sh
7B 级模型全参数training_scripts/llama2/run_llama2_7b.sh(ZeRO-3 + offload)
7B 级模型显存紧张training_scripts/llama2/run_llama2_7b_lora.sh(LoRA)
自动跑多组配置training_scripts/opt/single_node/sweep/run_step2_sweep.sh

所有脚本只需修改--model_name_or_path即可切换到其他因果语言模型;动手前记得同步评估显存规模并相应调整 ZeRO 阶段、Offload、batch size 与学习率。

  • 示例工程

【免费下载链接】DeepSpeedExamples

Example models using DeepSpeed

项目地址:https://gitcode.com/gh_mirrors/de/DeepSpeedExamples
点击查看免费下载
上一篇:Mac美剧播放器终极指南:爱美剧客户端的完整使用教程
下一篇:Tabliss性能优化技巧:提升新标签页加载速度的7个方法

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询