KL 驱动下的 SFT 与 DPO
通过调节参数,在不降低通用能力的前提下,引导LLM通过微调达到较好表现:**在有监督微调(SFT)**期间添加少量的 **KL 散度(KL-divergence)**惩罚,以保持策略贴近基座模型;**在直接偏好优化(DPO)**中扫描 $\beta$ 参数,以控制偏好数据塑造策略的激进程度。
SFT 期间的 KL: 经典的 RLHF 使用 KL 来防止 PPO 偏离太远。在 SFT 中使用KL,就能在学习你的格式/风格的同时,保持和基座模型对齐。
DPO 期间的 $\beta$: DPO 通过与参考策略(Reference Policy)的对比来比较“选中(chosen)”与“拒绝(rejected)”的响应。$\beta$ 是**逆温度(inverse-temperature)**系数,缩放了偏离参考模型的强度。
为什么选择 Qwen3 + LoRA?
- Qwen3 是一个强大的开源家族(包含 Dense 和 MoE 版本),支持长上下文。Dense非常适合适配器微调。
- LoRA 仅训练低秩矩阵 $\rightarrow$ 可训练参数极少 $\rightarrow$ 与全量微调相比,优化器状态极小(优化器状态随可训练权重数量扩展)。获得更低的显存占用、更快的迭代速度,以及更少的遗忘。
使用Qwen3,注意力投影层上添加 LoRA 。
基于 QLoRA 论文及后续大量实验:
A. 仅加在 Attenti5on 层 (
q_proj,v_proj等)
- 配置:
target_modules=["q_proj", "v_proj"](最早期 LoRA 的默认做法)- 效果:
- 优点: 训练参数量最小,速度快,显存占用最低。
- 擅长: 学习格式、风格、指令遵循(例如:学会输出 JSON,学会用海盗语气说话)。 * 缺点: 很难学会新的“知识”或“事实”。
- 原理: 你改变了模型“看”信息的方式,但没有改变模型脑子里的“存货”。
B. 仅加在 MLP 层 (
gate_proj,up_proj,down_proj)
- 效果:
- 擅长: 研究表明,Transformer 的 MLP 层更像是键值对存储器(Key-Value Memory),存储了模型的世界知识。 * 用途: 如果你想注入特定的领域知识(比如医疗知识、法律条文),微调这些层很重要。
C. 加在所有线性层 (All Linear Layers) —— 推荐做法
- 配置:
target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]- 效果:
- 优点: 效果最好,泛化能力最强。 这是目前的 SOTA(State-of-the-Art)做法。Qwen 和 Llama 的官方微调脚本通常都默认开启这个。
- 性能: 最接近全量微调(Full Fine-Tuning)的效果。
- 代价: 可训练参数量变大(大约是仅微调 Attention 的 2-3 倍),稍微多占一点显存,但通常是值得的。
D. 极其特殊的位置:Embeddings 和 LM Head
embed_tokens(输入层) 和lm_head(输出层)- 效果:
- 通常不建议加 LoRA,除非你在做词表扩充(比如给 Qwen 增加它原来不认识的泰语词汇)。
- 如果是常规微调,加上这两层往往会导致训练不稳定或显存暴涨,收益很小。
训练分为两个阶段:
- 有监督微调(SFT): 带有少量的 KL 散度惩罚,以稳定风格/格式并限制偏离基座模型。
- 直接偏好优化(DPO): 对 $\beta$ 进行扫描(Sweep),以控制偏好对策略的塑造强度。
数据集采用了用于 SFT 的 JSONL 指令数据和用于 DPO 的成对(选中/拒绝)JSONL 数据。
1) 基于KL 限制的 SFT
- 作用: 在 SFT 期间,在你的当前策略和参考模型(通常是基座模型)之间添加一个小的 KL 项。
- 益处: 防止适配器过拟合 SFT 数据集中的格式或伪影。可以将其理解为:“除非你非常确定,否则保持在基座附近”。
- 起始设置: KL $\approx$ 0.03–0.10。如果你发现学习不足(under-learning),在去掉 KL 之前先稍微调高学习率(LR)。
2) 基于$\beta$ 调优的 DPO
$$ \mathcal{L}_{\text{DPO}}(\pi_\theta; \pi_{\text{ref}}) = -\mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ \log \sigma \left( \beta \log \frac{\pi_\theta(y_w \mid x)}{\pi_{\text{ref}}(y_w \mid x)} - \beta \log \frac{\pi_\theta(y_l \mid x)}{\pi_{\text{ref}}(y_l \mid x)} \right) \right] $$- 作用: 相对于参考策略,最大化对“选中”响应的偏好,压制“拒绝”响应。$\beta$ 用于缩放这种偏好强度。
- 益处: 让你将对齐力度从 “轻微助推” 调节到 “强力推动”。
- 起始设置: $\beta \approx$ 0.05–0.10。小幅度的加大进行扫描。太高的话,模型会过度向你的数据对弯曲。
使用的数据集
- T-Wix (t-tech/T-Wix): 俄语混合通用/推理聊天数据,用于 SFT。在教授格式的同时保持基座风格。
- TAT-QA: 基于表格+段落的金融问答;我们为每个问题构建 DPO 数据对(标准答案 vs. 似是而非的答案)。
- Reddit Finance 43 (winddude/reddit_finance_43_250k): 帖子 $\rightarrow$ 评论;通过评论分数构建偏好对。
- Finance-Instruct-500k: 金融指令遵循数据;基于参考模型构建数据对(将参考模型的输出作为“选中”)。
- 通用 DPO 数据对 (例如 Intel/orca_dpo_pairs): 用于 DPO 流程中。
指标
使用奖励模型 Skywork/Skywork-Reward-V2-Qwen3–0.6 进行评分。这保持了跨运行评估的一致性,避免了与被测模型的循环验证陷入 “自卖自夸”。
特征 Bradley-Terry (BT) 模型 Generative (生成式) 模型 代表模型 Skywork-Reward, Llama-3-RM, ArmoRM GPT-4o, DeepSeek-GRM, Claude 核心任务 打分 (Regression/Ranking) 生成 (Next Token Prediction) 模型结构 Base Model + Scalar Head (去掉了语言头) 完整的 Base Model (保留语言头) 输出形式 一个具体的数字 (e.g., 0.95) 一段文本或 Token (e.g., “5”, “Good”) 训练目标 让好答案的分数 > 坏答案的分数 让模型学会像人类评审员一样说话/评价 优点 计算极快,显存占用略低,适合作为 PPO/DPO 的训练信号 解释性强(能说出为什么),利用了 LLM 强大的推理能力 缺点 只能给分,不知道它为什么给这个分(黑盒) 速度慢(要生成很多词),推理成本高
- SFT 验证损失 & 困惑度 (Perplexity): SFT 期间基本的过拟合/漂移警报。越低越好。“基础警报器”。
- TAT-QA “类 EM” 准确率: 带有数值容忍度的精确匹配(Exact-match),用于算术;反映有依据的、分步骤的回答能力。 “智商测试”(逻辑与事实落地)。
- MT-Bench 平均分 (1–10): 分数越高 = 在固定裁判下的通用帮助性/连贯性越好。 “综合素质测试”。
- 指令成功率 (Instruction success-rate): 评分 $\ge$ 目标值(如 7/10)的提示占比;快速了解对约束的遵循情况。“听话程度测试”。
- Reddit 奖励分 (Reward score): 裁判对回复的平均评分;对话质量的粗略信号。 “聊天水平/情商测试”。
带有 KL 锚点的 SFT
- 目标: 学习任务格式、系统语气和护栏,而不发生漂移。
- 方法: 运行
sft_train.py并设置非零的--kl_coef(例如 0.03–0.10),使用 SFT JSONL 数据保持适度的 LoRA 参数(例如 r=16, $\alpha$=16)和 8k–16k 的上下文。 - 良好迹象: 格式被锁定;通用聊天能力未改变。
- 如果欠拟合: 稍微提高 LR 或降低 KL。
- 如果漂移: 在将 KL 归零之前,先降低 LR。
使用 KLSFTTrainer 来添加针对冻结参考模型的 KL 项,sft_train.py已经使用了它;只需设置–kl_coef (> 0)` 即可。
带有 $\beta$ 扫描的单任务 DPO
- 目标: 专注于一个领域(如金融问答)并找到“$\beta$ 拐点”。
- 方法: 使用你的成对数据运行
dpo_train.py并扫描参数——在小 LR(例如 2e-5)下测试 $\beta$ 为 0.05, 0.10, 0.15, 0.20。使用你的 SFT 检查点作为策略模型,并保持基座模型作为参考模型以保留通用性。 - 选择 $\beta$: 选择那个能明显帮助你的领域但没有降低通用聊天能力的最低 $\beta$ 值。
参数
- SFT + KL (Qwen3–1.7B-Instruct): 数据=精选指令 WIX-T 数据集;LoRA r/$\alpha$=16/16;LR $\approx$ 1–2e-4 训练 1 epoch;上下文=8k–16k;KL=0.03–0.10 —— 格式稳定,无明显退化。
- DPO (单任务): 数据=金融成对数据;LoRA r/$\alpha$=16/16;LR $\approx$ 2e-5 训练 ~1 epoch;上下文=8k–16k;$\beta$=0.05–0.20 —— 更清晰、更有依据的金融回复。
- DPO (分阶段): 数据=通用偏好 $\rightarrow$ 金融 $\rightarrow$ 社交金融;LoRA r/$\alpha$=16/16;LR $\approx$ 2e-5 (分阶段);上下文=8k–16k;$\beta$=低$\rightarrow$中 —— 保留了金融方面的增益,增加了对话的细微差别。
注意
在 SFT 期间保持 KL > 0。
“Do-no-harm”(不造成伤害): SFT 数据集通常很小、很偏。如果让模型完全放飞自我去拟合这些数据,它会为了降低 Loss 而修改很多不该修改的权重,导致“灾难性遗忘”(变笨)。
“Anchor”(锚点): KL 就像船锚。它允许船(模型)在水面上随波逐流(学习新格式),但限制它不能飘离港口(Base 模型的基础能力)太远。
操作建议: 即使是很小的系数(比如 0.03),也要开着 KL,不要设为 0。
如何调节
- 先用锚稳住,再转向。 SFT 期间的 KL 减少了早期漂移;然后 DPO 的 $\beta$ 安全地调节偏好强度。
- 实施小范围、控制变量的参数扫描。 第一次扫描只针对 KL (SFT) 和 $\beta$ (DPO)。如果稳定,再微调 LR、LoRA r/$\alpha$ 和上下文。
- 保持合理的参考模型。 为了最大化通用性,保持基座作为参考。为了最终结果,将参考模型设置为你上一个训练好的好的模型。
出现的问题
- SFT 后通用聊天感觉变生硬 $\rightarrow$ 降低 LR 或稍微提高 KL(不要先移除 KL)。
- DPO($\beta$=0.05) 后领域能力仍然较弱 $\rightarrow$ 在提高 LR 之前尝试 $\beta$=0.10。
- DPO 后出现过度拒绝 $\rightarrow$ 降低 $\beta$,或将参考模型切换回基座模型。
- 长上下文出现 OOM(显存溢出) $\rightarrow$ 降低 LoRA rank 或序列长度;记住优化器状态随可训练参数扩展,所以 LoRA 在这里帮助很大。
- 如果 DPO 数据有噪声怎么办? $\rightarrow$宁愿选择更多但更柔和(低 $\beta$)的数据,也不要选择更少但更严厉的数据。高 $\beta$ 值配合垃圾数据会扭曲你的模型。
策略 A:Less but Harsher(少而精,但力度大 - 假设你试图清洗数据但用了高 $\beta$)
- 如果你用了高 $\beta$,模型会试图死记硬背每一个偏好对。
- 当模型遇到那 10% 的错误标记数据时,高 $\beta$ 会强迫模型去学习这个错误逻辑(因为惩罚太重,模型不敢不学)。
- 结果:“Garbage with high $\beta$ can warp your model”(高 $\beta$ 配合垃圾数据会扭曲/毁坏你的模型)。模型逻辑崩溃,开始胡言乱语。
策略 B:More but Softer(多而杂,但力度小 - 作者推荐)
- 你使用海量数据(比如 10万条),里面虽然有 10% 的噪声,但有 90% 是正确的趋势。
- 使用 低 $\beta$(Softer)。
- 原理: 因为力度小,单条错误数据不足以把模型带偏。模型在学习过程中,错误数据的梯度会被大量正确数据的梯度平均掉(Average out)。
- 模型学到的是“大多数时候什么是好的”,而不是“某一条特定数据必须是对的”。这叫做鲁棒性(Robustness)。
应该在调整 $\beta$ 之前更改 LoRA rank 吗?
$\beta$ 是最重要的,在找到稳定的 $\beta$ 之后再调整 LoRA r/$\alpha$。
实验:
SFT:
Exp1:
subset=general, sample_ratio=0.25, max_seq_length=768, epochs=1
uv run python sft_train.py --model Qwen/Qwen3-1.7B --output_dir qwen3_1p7b_exp1_aggressive --subset general --sample_ratio 0.25 --epochs 1 --batch 8 --grad_acc 16 --max_seq_length 768 --learning_rate 5e-5 --lora_r 16 --lora_alpha 32 --kl_coef 0.0 --mtbench_ru auto --mtbench_questions_limit 0 --mtbench_temperature 0.0 --baseline_eval_samples 40 --num_proc 4
{'loss': 26.107, 'grad_norm': 6.992496013641357, 'learning_rate': 2.951807228915663e-05, 'epoch': 0.06} {'loss': 21.9336, 'grad_norm': 1.5803261995315552, 'learning_rate': 4.994311831930032e-05, 'epoch': 0.12} {'loss': 20.3146, 'grad_norm': 1.4649460315704346, 'learning_rate': 4.903798926803701e-05, 'epoch': 0.18} {'loss': 19.9871, 'grad_norm': 1.6117888689041138, 'learning_rate': 4.706818818762558e-05, 'epoch': 0.24} {'loss': 19.8475, 'grad_norm': 1.6960031986236572, 'learning_rate': 4.4120959984031976e-05, 'epoch': 0.3} {'loss': 19.7899, 'grad_norm': 1.717342734336853, 'learning_rate': 4.032684100939835e-05, 'epoch': 0.36} {'loss': 19.5126, 'grad_norm': 1.8326685428619385, 'learning_rate': 3.58538774468938e-05, 'epoch': 0.42} {'loss': 19.42, 'grad_norm': 1.8379029035568237, 'learning_rate': 3.0900182339139954e-05, 'epoch': 0.48} {'loss': 19.4443, 'grad_norm': 1.9687762260437012, 'learning_rate': 2.5685160918552242e-05, 'epoch': 0.54} 56%|██████████████████████████████████████████▍ | 462/828
Exp2:
subset=general, sample_ratio=1
uv run python sft_train.py --model Qwen/Qwen3-1.7B --output_dir qwen3_1p7b_exp2_conservative_full --subset general --sample_ratio 1.0 --epochs 1 --batch 8 --grad_acc 16 --max_seq_length 768 --learning_rate 1e-5 --lora_r 8 --lora_alpha 16 --kl_coef 0.0 --mtbench_ru auto --mtbench_questions_limit 0 --mtbench_temperature 0.0 --baseline_eval_samples 40 --num_proc 4
Exp3:
sample_ratio=0.25 KL (coef=0.02, start=150, tail=128)
uv run python sft_train.py --model Qwen/Qwen3-1.7B --output_dir qwen3_1p7b_exp3_kl002_g025 --subset general --sample_ratio 0.25 --epochs 1 --batch 8 --grad_acc 16 --max_seq_length 768 --learning_rate 1e-5 --lora_r 8 --lora_alpha 16 --kl_coef 0.02 --kl_start_step 150 --kl_warmup_steps 1 --kl_limit_seq 128 --mtbench_ru auto --mtbench_questions_limit 0 --mtbench_temperature 0.0 --baseline_eval_samples 40 --num_proc 4
kl_limit_seq 128:后半段(长回答 / 推理展开 / 自由生成)约束回答尾部,通过KL拉回base模型
Exp4:
both + reasoning mix 20% KL (coef=0.03, start=200, warmup=300,tail=128)
uv run python sft_train.py --model Qwen/Qwen3-1.7B --output_dir qwen3_1p7b_exp4_mix_reasoning20 --subset both --mix_reasoning_ratio 0.2 --sample_ratio 0.25 --epochs 1 --batch 8 --grad_acc 16 --max_seq_length 768 --learning_rate 1e-5 --lora_r 8 --lora_alpha 16 --kl_coef 0.03 --kl_start_step 200 --kl_warmup_steps 300 --kl_limit_seq 128 --mtbench_ru auto --mtbench_questions_limit 0 --mtbench_temperature 0.0 --baseline_eval_samples 40 --num_proc 4
coef约束更强,由于数据更复杂(general + reasoning),需要KL 介入更晚模型有足够时间适应双重目标(SFT + KL)
对1.7B模型针对性微调策略:(1)缩短上下文长度;(2)更温和的kl策略
| Run | Subset | Sample | KL (coef/start/warmup/tail) | Val loss→ | PPL→ | MT-Bench avg→ | Notes |
|---|---|---|---|---|---|---|---|
| S1 | general | 0.10 | 0.02/150/300/128 | b: 1.7862 → f: 1.4188 | b: 5.9664 → f: 4.1323 | b: 2.4949 → f: 2.6585 | full 80Q, greedy, no ES |
| S2 | both | 0.25 | 0.03/200/300/128 | b: 1.4698 → f: 1.3185 | b: 4.3482 → f: 3.7378 | b: 2.4949 → f: 2.6294 | LR=8e-6; 20% reasoning mix; full 80Q, greedy |
| S3 | both | 0.25 | 0.035/200/400/128 | b: 1.4698 → f: 1.2949 | b: 4.3482 → f: 3.6507 | b: 2.5893 → f: 2.7721 (80Q) | batch=12, grad_acc=11; baseline 32Q=2.5893; final 80Q=2.7721; ES subset dip not representative |
| S4 | both | 0.25 | 0.03/200/400/128 | b: 1.4698 → f: 1.2672 | b: 4.3482 → f: 3.5509 | b: 2.4949 → f: 2.8033 | epochs=2; batch=12, grad_acc=11; full 80Q at baseline & final |
DPO single:
Exp1:
Parameters:
- Model: Qwen/Qwen3-1.7B
- Dataset: 13,176 TAT-QA preference pairs (full training set)
- DPO: beta=0.03, epochs=1, batch=1, grad_acc=32, lr=5e-6
- LoRA: rank=16, alpha=32, dropout=0.05
- 4-bit quantization: yes
- Memory optimization: max_length=768, max_prompt_length=384
[finance-instruct] Generated 1500 Finance-Instruct DPO pairs
[data] Hybrid training: 13,551 Reddit + 1,500 Finance-Instruct = 15,051 total pairs
[data] Final training dataset: 15,051 preference pairs
Loading checkpoint shards: 100%|█████████████████████████████████████████████████████████| 2/2 [00:01<00:00, 1.06it/s]
Loading checkpoint shards: 100%|█████████████████████████████████████████████████████████| 2/2 [00:01<00:00, 1.07it/s]
[eval] Baseline eval on TAT-QA validation
Eval validation — N=1000 | EM-like acc=0.418
- arithmetic: 0.073 (31/427)
- count: 0.733 (11/15)
- multi-span: 0.805 (103/128)
- span: 0.635 (273/430)
[mtbench] Running baseline MT-Bench eval
[warn] MT-Bench file mt_bench_en.json not found, skipping MT-Bench eval
[instruct] Running baseline instruction eval
[instruct] Running Finance-Instruct instruction eval
[instruct] Loading Skywork reward model for scoring...
[instruct] Reward model loaded successfully
[instruct] Loaded 518185 Finance-Instruct examples
[instruct] Evaluated 5/25 instructions
[instruct] Evaluated 10/25 instructions
[instruct] Evaluated 15/25 instructions
[instruct] Evaluated 20/25 instructions
[instruct] Evaluated 25/25 instructions
Finance-Instruct eval completed — N=25 instructions, avg score: 5.54/10, success rate: 32.0%
Saved Finance-Instruct results to qwen3_reddit_finance_dpo_hybrid/instruct_baseline.jsonl
[reddit] Running baseline Reddit Finance reward eval
[reddit] Running Reddit Finance reward evaluation
[reddit] Loading Skywork reward model for scoring...
[reddit] Reward model loaded successfully
[reddit] Loaded 250000 Reddit Finance examples
[reddit] Evaluated 25/100 examples
[reddit] Evaluated 50/100 examples
[reddit] Evaluated 75/100 examples
[reddit] Evaluated 100/100 examples
Reddit Finance reward eval completed — N=100 examples, avg reward: 3.43/10
Saved Reddit Finance results to qwen3_reddit_finance_dpo_hybrid/reddit_baseline.jsonl
Extracting prompt from train dataset: 100%|████████████████████████████| 15051/15051 [00:00<00:00, 33193.70 examples/s]
Applying chat template to train dataset: 100%|█████████████████████████| 15051/15051 [00:00<00:00, 51296.14 examples/s]
Tokenizing train dataset: 100%|██████████████████████████████████████████| 15051/15051 [00:32<00:00, 462.37 examples/s]
0%| | 0/236 [00:00<?, ?it/s]Could not estimate the number of tokens of the input, floating-point operations will not be computed
{'loss': 0.6933, 'grad_norm': 0.4566695988178253, 'learning_rate': 2.9788065277773537e-06, 'rewards/chosen': 0.001141993678174913, 'rewards/rejected': 0.0013736929977312684, 'rewards/accuracies': 0.49312499165534973, 'rewards/margins': -0.0002316994359716773, 'logps/chosen': -502.85003662109375, 'logps/rejected': -492.2593994140625, 'logits/chosen': 2.779862880706787, 'logits/rejected': 2.4311907291412354, 'epoch': 0.11}
11%|████████▋ | 26/236 [37:56<4:35:15, 78.65s/it]
Results:
- TAT-QA: 42.6% → 49.3% (+6.7pp, +15.8% relative)
- Arithmetic: 7.7% → 14.8% (almost doubled!)
- Count: 68.8% → 81.2% (+12.4pp)
- Multi-span: 79.7% → 87.6% (+7.9pp)
- Span: 65.6% → 71.3% (+5.7pp)
- MT-Bench: 1.76 → 1.72 (-0.04, minimal degradation)
- Instruction Following: 6.64 → 6.77 (+0.13), 36% → 36% success rate
较低的 beta (0.03) 成功保留了通用能力
较高的 LoRA 容量 (r=16, α=32) 提升了任务表现
Exp2:
Parameters:
- Model: Qwen/Qwen3-1.7B
- Dataset: 13,176 TAT-QA preference pairs (full training set)
- DPO: beta=0.02, epochs=1, batch=1, grad_acc=32, lr=5e-6
- LoRA: rank=16, alpha=32, dropout=0.05
- 4-bit quantization: yes
- Memory optimization: max_length=768, max_prompt_length=384
- Evaluation: Full validation set (N=1668)
- Training time: 53min 2s (3183.0s), Final loss: 0.623
Results:
- TAT-QA: 43.5% → 48.9% (+5.4pp, +12.3% relative)
- Arithmetic: 8.1% → 14.5% (strong improvement)
- Count: 75.0% → 84.4% (+9.4pp)
- Multi-span: 80.2% → 86.2% (+6.0pp)
- Span: 67.0% → 70.9% (+3.9pp)
- MT-Bench: 1.48 → 1.86 (+0.38 - MAJOR IMPROVEMENT! 🎉)
- Instruction Following: 6.64 → 6.72 (+0.08), 36% → 40% success rate (+4pp)
既提升了特定任务,又增强了通用能力
DPO hybrid:
- 先执行 reddit_sample_rate:决定 Reddit 数据池子。
- 再执行 hybrid_ratio:决定在这个池子基础上,如何切分空间给 Finance 数据。
Exp1:
MT-Bench 优化版
uv run dpo_train_mt.py --use_hybrid --hybrid_ratio 0.5 --beta 0.02 --learning_rate 5e-6 --finance_instruct_pairs 1800 --reddit_sample_rate 0.2 --exp_tag "production_mt_bench_optimized"
- Model: Qwen3-1.7B
- Dataset: Hybrid approach (17,809 total pairs)
- Reddit Finance: 15,809 pairs (70%)
- Finance-Instruct: 2,000 pairs (30%)
- Training: Beta=0.02, LoRA r=8/α=16, lr=5e-6, 1 epoch
- Evaluation: English MT-Bench (upgraded from Russian)
结果: MT-Bench +2.0%, TAT-QA +5.9%, 金融指令 -15.0%
Exp2:
平衡性能版
uv run dpo_train_mt.py --use_hybrid --hybrid_ratio 0.5 --beta 0.0175 --learning_rate 4e-6 --finance_instruct_pairs 1800 --reddit_sample_rate 0.2 --exp_tag "production_balanced_optimized"
结果: MT-Bench -0.2%, TAT-QA +1.9%, 金融指令 -4.3%
Exp3:
金融指令优化版
python dpo_train_mt.py --use_hybrid --hybrid_ratio 0.5 --beta 0.02 --learning_rate 4e-6 --finance_instruct_pairs 1800 --reddit_sample_rate 0.2 --exp_tag "production_finance_optimized"
- Model: Qwen3-1.7B
- Dataset: Balanced hybrid approach (9,328 total pairs)
- Reddit Finance: 7,528 pairs (81% actual)
- Finance-Instruct: 1,800 pairs (19% actual)
- Optimized Parameters:
- Beta=0.0175 (middle ground between 0.015-0.02)
- hybrid_ratio=0.5 (50-50 target, achieved 81-19 actual)
- learning_rate=4e-6 (increased from 3e-6)
- finance_instruct_pairs=1800 (increased from 1500)
- reddit_sample_rate=0.2 (reduced from 0.3)
Exp4:
渐进2阶段版
# 阶段 1:通用保留
uv run dpo_train_mt_v2.py --progressive --stage 1
--stage1_beta 0.01 --stage1_epochs 0.25 --stage1_lora_r 8
# 阶段 2:金融专业化
uv run dpo_train_mt_v2.py --progressive --stage 2
--stage2_beta 0.018 --stage2_epochs 0.75 --stage2_lora_r 12
Model: Qwen/Qwen3-1.7B
Method: Progressive 2-Stage Training (Revolutionary Approach)
Stage 1: General capability preservation (800 Intel/orca_dpo_pairs, β=0.01, LR=2e-6, epochs=0.25)
Stage 2: Financial specialization on preserved base (7,558 hybrid pairs, β=0.018, LR=3.5e-6, epochs=0.75)
领域 基线 训练后 变化 % 变化 状态 TAT-QA 40.8% 43.2% +2.4% +5.9% ✅ Best Yet MT-Bench 4.01/10 4.09/10 +0.08 +2.0% ✅ Goal Achieved Finance-Instruct 6.27/10 5.33/10 -0.94 -15.0% ❌ Major Decline Reddit Reward 3.58/10 3.70/10 +0.12 +3.4% ✅ Stable
Exp5:
渐进3阶段版
uv run dpo_train_mt.py --use_3way_hybrid --reddit_ratio 0.4 --finance_ratio 0.3 --general_ratio 0.3 --finance_instruct_pairs 2000 --general_pairs 3000 --beta 0.02 --instruct_limit 50 --reddit_limit 100 --mtbench_limit 50 --eval_limit 250 --general_dataset "Intel/orca_dpo_pairs" --exp_tag "3way_hybrid_mt_bench_fix"
Optimized Parameters:
- Model: Qwen/Qwen2.5-1.5B-Instruct
- Method: 3-Stage Progressive DPO Training (Next-generation approach)
- Output Directory:
qwen3_3stage_progressive_experiment - Experiment Tag:
3stage_breakthrough_attempt
3-Stage Training :
Stage 1: General Preservation
- Goal: Preserve MT-Bench performance and general reasoning
- Data: Intel/orca_dpo_pairs (800 general pairs)
- Parameters: 1 epoch, β=0.1, LR=5e-6, LoRA r=8, α=16
- Success Criteria: MT-Bench improvement ≥ +0.01 points
- Focus: Broad capability preservation foundation
Stage 2: Financial Foundation
- Goal: Build core financial knowledge in isolation
- Data: Finance-Instruct pairs only (1,200 pairs)
- Parameters: 1 epoch, β=0.018, LR=3.5e-6, LoRA r=12, α=24
- Success Criteria: Finance-Instruct improvement ≥ +0.05 points
- Focus: Pure financial specialization without social complexity
Stage 3: Social Finance Integration
- Goal: Complete multi-domain optimization
- Data: Reddit Finance + Finance-Instruct hybrid (70% Reddit, 30% Finance-Instruct)
- Parameters: 1 epoch, β=0.025, LR=4e-6, LoRA r=16, α=32
- Success Criteria: All 4 domains positive
- Focus: Social finance skills integration
混合阶段调整策略:
- 提前专业化: 在进行社交数据整合之前,在纯粹隔离环境中建立金融知识,提高专业能力。
- 渐进式 LoRA 扩展: 8 → 12 → 16 秩,用于增加专业化深度。
- 衡量细粒度的领域: 每个阶段都有具体的可衡量目标领域,不要一锅端测试。