LLM微调(五)| 使用LLaMA-Factory框架基于DPO微调大模型

大模型机器学习算法

Agent 在调用工具(Function-Calling)时,可能会遇到以下问题:
❌ 选择错误的工具
❌ 参数拼接错误
❌ 多轮对话中遗漏关键信息
❌ 明明需要工具却回答“我不知道”

❌ 工具调用格式不符合 API Schema

 本文教你,使用 llama factory 通过 强化学习(RL)中的 DPO算法 进行微调,提升 Agent 工具调用(Function-Calling)能力,解决上述问题。

一、LLaMA-Factory 微调

  数据内容可以使用Agent生成,也可以使用其他方法进行生成或者人工标注,这里不做介绍。LLaMA-Factory对微调数据格式有严格的要求,具体看如下内容:

数据准备的核心要点

要点 1:文件格式必须是 JSONL

LLaMA-Factory 的所有数据加载(SFT、DPO、RM)底层都使用 datasets.load_dataset("json") 逐行解析。

严格要求 :

  • ✅ 每行是一个合法的 JSON 对象
  • ✅ 每行之间无逗号分隔
  • ❌ 不能有数组包裹符号 [ ]
  • ❌ 文件末尾不能有空行

要点 2:每条数据结构必须一致

所有 JSON 对象必须具有 相同的键集合 ,无论字段是否为空。

示例 :

  
{"system": "...", "tools": "...", "messages": [...], "chosen": "...", "rejected": "..."}

注意 :即使某条数据的 tools 为空,也要保留该字段并写为 "tools": "" ,不能省略。

要点 3:避免使用转义换行符 \n

LLaMA-Factory UI 在前端直接展示字符串内容。如果使用 \n ,会按字面意义显示而非换行。

最佳实践 :

  • ✅ 在生成数据时写入真实换行符(实际回车)
  • ❌ 避免使用转义序列 \n

要点 4:避免非法 JSON 字符

常见错误 :

  • 结尾多余逗号
  • 非 UTF-8 编码
  • 字符串中未转义的双引号 "
  • 中文全角符号(如 ,:; )混入英文环境导致转义失败

数据集注册的关键点

要点 1:dataset_info.json 必须是标准 JSON

错误示例 (缺少外层大括号):

  
"my\_dataset": {...}  
"another": {...}

正确示例 :

  
{  
  "my\_dataset": {...},  
  "another": {...}  
}

要点 2:字段映射 columns 必须对齐实际数据

dataset_info.json 中的 columns 字段必须与实际数据的键名完全一致,否则会导致加载错误或预览为空。

示例 : 如果数据包含 tools 、 chosen 、 rejected 字段,则需配置:

  
"columns": {  
  "system": "system",  
  "tools": "tools",  
  "messages": "messages",  
  "chosen": "chosen",  
  "rejected": "rejected"  
}

要点 3:DPO 数据集必须添加 "ranking": true

通过该标志告知 LLaMA-Factory 这是偏好学习格式,包含 chosen 和 rejected 字段。

配置示例 :

  
"RL\_data\_dpo": {  
  "file\_name": "RL\_data\_dpo.jsonl",  
  "ranking": true,  
  "formatting": "sharegpt",  
  "columns": {...}  
}

要点 4:注册目录与启动命令保持一致

启动 WebUI 或 CLI 时, --dataset_dir 必须指向包含 dataset_info.json 的目录。

启动命令示例 :

  
llamafactory-cli webui --dataset\_dir ./datasets/RL\_data\_dpo

推荐目录结构 :

  
datasets/  
└── RL\_data\_dpo/  
    ├── dataset\_info.json  
    └── RL\_data\_dpo.jsonl

数据二次转换

为确保数据格式符合 LLaMA-Factory 格式要求,使用以下转换脚本 convert_to_jsonl.py :

执行命令 :

  
python convert\_to\_jsonl.py --input RL\_data\_dpo.jsonl --output RL\_data\_dpo\_fixed.jsonl

对应的 dataset_info.json 配置 :

  
{  
  "RL\_data\_dpo": {  
    "file\_name": "RL\_data\_dpo\_fixed.jsonl",  
    "ranking": true,  
    "formatting": "sharegpt",  
    "columns": {  
      "system": "system",  
      "tools": "tools",  
      "messages": "messages",  
      "chosen": "chosen",  
      "rejected": "rejected"  
    }  
  }  
}

注意 :需要在 LLaMA-Factory 微调界面验证数据集是否能正常加载和预览。

微调配置与使用

模型下载

使用 ModelScope 下载基座模型:

  
modelscope download --model Qwen/Qwen3-4B-Instruct-2507 --local\_dir /home/ubuntu/Qwen3-4B

picture.image

启动 DPO 微调

完整的训练命令如下:

  
llamafactory-cli train \  
    --stage dpo \  
    --do\_train True \  
    --model\_name\_or\_path /home/ubuntu/Qwen3-4B \  
    --preprocessing\_num\_workers 16 \  
    --finetuning\_type lora \  
    --template qwen3\_nothink \  
    --flash\_attn auto \  
    --dataset\_dir data \  
    --dataset RL\_data\_dpo \  
    --cutoff\_len 4096 \  
    --learning\_rate 1e-05 \  
    --num\_train\_epochs 2.0 \  
    --max\_samples 100000 \  
    --per\_device\_train\_batch\_size 4 \  
    --gradient\_accumulation\_steps 8 \  
    --lr\_scheduler\_type cosine \  
    --max\_grad\_norm 1.0 \  
    --logging\_steps 5 \  
    --save\_steps 100 \  
    --warmup\_steps 0 \  
    --packing False \  
    --enable\_thinking True \  
    --report\_to none \  
    --output\_dir saves/Qwen3-4B-Instruct-2507/lora/train\_2025-11-12-20-09-23 \  
    --bf16 True \  
    --plot\_loss True \  
    --trust\_remote\_code True \  
    --ddp\_timeout 180000000 \  
    --include\_num\_input\_tokens\_seen True \  
    --optim adamw\_torch \  
    --lora\_rank 8 \  
    --lora\_alpha 16 \  
    --lora\_dropout 0 \  
    --lora\_target all \  
    --pref\_beta 0.1 \  
    --pref\_ftx 0 \  
    --pref\_loss sigmoid

参数说明

总体目标 :

  
使用 LoRA 低秩微调方式,基于 DPO 偏好数据集对 Qwen3-4B 进行偏好优化  
(Direct Preference Optimization,强化学习阶段的无奖励模型替代方案)

核心参数详解 :

参数
说明
--stage dpo
指定训练阶段为
DPO (Direct Preference Optimization)
,一种无需奖励模型的强化学习对齐方法,通过偏好对比直接优化模型。
--do_train True
启动训练模式(而非推理或验证)。
--model_name_or_path /home/ubuntu/Qwen3-4B
预训练基座模型的本地路径。
--preprocessing_num_workers 16
数据预处理的并行线程数,加速数据加载。
--finetuning_type lora
采用
LoRA(低秩适配)
微调,仅训练部分参数,大幅降低显存消耗。
--template qwen3_nothink
使用 Qwen3 系列的无思维链模板格式。
--flash_attn auto
自动启用 FlashAttention,节省显存并提升速度。
--dataset_dir data
数据集所在目录。
--dataset RL_data_dpo
指定使用的数据集名称,包含 chosen(正样本)和 rejected(负样本)。
--cutoff_len 4096
最大序列长度,超出部分截断。
--learning_rate 1e-05
学习率(DPO 阶段通常较低,防止过拟合)。
--num_train_epochs 2.0
训练轮数(完整遍历数据集 2 次)。
--max_samples 100000
最大样本数量限制。
--per_device_train_batch_size 4
每张 GPU 的 batch size。
--gradient_accumulation_steps 8
梯度累积步数,实际 batch size = 4×8 = 32。
--lr_scheduler_type cosine
学习率调度策略(余弦衰减)。
--max_grad_norm 1.0
梯度裁剪上限,防止梯度爆炸。
--logging_steps 5
每 5 步打印一次训练日志。
--save_steps 100
每 100 步保存一次模型检查点。
--warmup_steps 0
学习率预热步数(0 表示无预热)。
--packing False
禁用样本打包(每条样本独立处理)。
--enable_thinking True
启用思维过程记录功能(兼容 Qwen3 思维链模式)。
--report_to none
不上报日志到 wandb / tensorboard。
--output_dir saves/...
模型输出目录。
--bf16 True
使用 bfloat16 混合精度训练。
--plot_loss True
训练过程中绘制损失曲线。
--trust_remote_code True
允许加载模型自定义代码。
--ddp_timeout 180000000
分布式训练超时设置。
--include_num_input_tokens_seen True
在日志中统计累计输入 token 数。
--optim adamw_torch
优化器(AdamW PyTorch 实现)。
--lora_rank 8
LoRA 秩(低秩矩阵维度)。
--lora_alpha 16
LoRA 缩放因子,影响权重更新幅度。
--lora_dropout 0
LoRA dropout(0 表示不使用)。
--lora_target all
对所有可训练层应用 LoRA。

DPO 特有参数详解 :

参数
说明
--pref_beta 0.1
β
是 DPO 损失函数中的温度/强度系数,控制"奖励差距"对梯度的影响。β 越小,优化越温和。常见范围:0.1~0.5。
--pref_ftx 0
是否混合监督损失(FTX)。
0
表示纯 DPO 损失;
1
表示在 DPO 中加入部分 SFT loss(混合训练)。
--pref_loss sigmoid
DPO 损失函数形式。
sigmoid
使用 logistic sigmoid 计算偏好概率(原论文形式);也可设为
hinge

训练结果分析

picture.image

损失曲线解读

坐标轴说明 :

  • 横轴(X) :训练步数(step)
  • 纵轴(Y) :损失值(loss)

曲线说明 :

  • 浅蓝线(original) :原始训练 loss(每步)
  • 深蓝线(smoothed) :平滑后的 loss 曲线(移动平均)

曲线特征 :

  • 初始 loss ≈ 0.68(接近 log(2),DPO 随机输出的典型水平)
  • 前 40 步迅速下降至 0.1 以下
  • 80 步后趋于平稳
  • 100 步后基本收敛在 0.05 左右波动

训练质量评估

  1. 收敛性优秀

Loss 从 ~0.7 平稳降至接近 0,无震荡或爆炸,说明:

  • ✅ 学习率设置合理( 1e-5 适中稳定)
  • ✅ 数据质量良好
  • ✅ 梯度累积/batch 配置平衡
  • ✅ 无梯度爆炸或欠拟合问题

结论 :模型成功学习了偏好方向,DPO 损失优化顺利。

  1. 收敛速度适中

前 40 步下降最快,属于正常现象:

  • DPO 损失在早期快速下降,表明模型快速区分 preferred 与 rejected
  • 后期趋稳表明已掌握偏好趋势,继续训练收益递减

结论 :模型进入稳定对齐阶段。

  1. 后期低波动,训练稳定

曲线后半段震荡极小(0.05 左右浮动),表示:

  • ✅ 训练进入收敛区
  • ✅ 无过拟合迹象(过拟合时 loss 会反复上升或剧烈波动)

结论 :稳定良性收敛。

DPO 训练阶段 Loss 参考值

训练阶段
典型 Loss 区间
含义
初始阶段
0.65~0.7
模型随机偏好(未区分)
中期(20–50 步)
0.2~0.1
模型逐渐学会区分 preferred / rejected
收敛期(100 步后)
0.05~0.1 以下
模型稳定对齐,可停止训练
震荡或上升

0.2 回弹 | 学习率过高或过拟合问题 |

参数配置合理性分析

结合本次训练配置:

  • learning_rate=1e-5 → 温和,不易震荡
  • pref_beta=0.1 → β 较小,梯度平滑,损失曲线下降平稳
  • pref_loss=sigmoid → 损失函数平滑,数值变化连续
  • num_train_epochs=2 → 对偏好任务通常足够

picture.image

picture.image

picture.image

picture.image

结论 :从配置到结果,整体设计科学合理。

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
VikingDB:大规模云原生向量数据库的前沿实践与应用
本次演讲将重点介绍 VikingDB 解决各类应用中极限性能、规模、精度问题上的探索实践,并通过落地的案例向听众介绍如何在多模态信息检索、RAG 与知识库等领域进行合理的技术选型和规划。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论