2026-04-22 · architecture / ai-infra
【大模型基础设施工程】05:训练全景:Pre-train、SFT、RLHF、DPO、蒸馏
以工程视角串联现代 LLM 的四阶段训练栈——预训练、中训、SFT 与对齐——覆盖数据、Tokenizer、优化器、精度、Scaling Law 与代表性训练框架。





















本文是【大模型基础设施工程】系列第 9 篇。前一篇《MoE 训练工程》聚焦稀疏专家的并行切分与 all-to-all 通信;本篇进入对齐(alignment)的世界——从 SFT、奖励模型到 PPO / DPO / GRPO,再到 2024–2025 年以 OpenAI o1、DeepSeek-R1、Kimi K1.5 为代表的 RL-for-Reasoning 新范式。对齐不再只是”让模型说人话”,而是直接决定模型能不能推理、敢不敢拒绝、会不会谄媚。
预训练出来的 base model 是一个”补全机”:给它一段文本,它预测下一个 token。它不会主动回答问题、不会遵守安全边界、也不会区分”有用答案”和”可能的答案”。把 base 模型变成 ChatGPT / Claude / 豆包这样的助手,需要一条完整的对齐流水线(alignment pipeline):
InstructGPT(OpenAI,2022)第一次把这三段完整串起来,证明了 1.3B 的 RLHF 模型在人类偏好上能击败 175B 的 GPT-3。从此”SFT → RM → PPO”成为工业对齐的标准三段式。到 2023 年 DPO 论文提出无 RM 的闭式优化,2024 年 DeepSeek-R1 用 GRPO 跑出开源推理 SOTA,这条流水线仍在快速演化。
flowchart LR
A[Base LLM<br/>预训练模型] --> B[SFT<br/>指令微调]
B --> C{偏好数据}
C --> D[Reward Model<br/>奖励模型]
C --> E[DPO / ORPO<br/>直接偏好优化]
D --> F[PPO / GRPO<br/>RL 微调]
B --> E
B --> F
F --> G[Aligned LLM<br/>对齐后模型]
E --> G
G --> H[Safety / Red Team<br/>评估回环]
H -.-> C
SFT 的本质是在”指令 → 回答”的条件分布上做标准的交叉熵训练。数据形如:
{
"messages": [
{"role": "system", "content": "你是一个助人、诚实、无害的助手。"},
{"role": "user", "content": "用 Python 写一个快排"},
{"role": "assistant", "content": "```python\ndef quicksort(arr): ..."}
]
}SFT 阶段的几个工程要点:
-100,否则模型会学会”模仿用户提问”。现代开源模型都有自己的 chat template(Jinja2 格式),它决定了 system / user / assistant / tool 的分隔符。常见格式:
# Llama 3
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
你是助手<|eot_id|><|start_header_id|>user<|end_header_id|>
...
# Qwen2 / Qwen3
<|im_start|>system
你是助手<|im_end|>
<|im_start|>user
...<|im_end|>
<|im_start|>assistant
# DeepSeek-R1(含 thinking)
<|begin▁of▁sentence|><|User|>...<|Assistant|><think>
推理过程
</think>
最终答案
坑点:
<think> /
</think>
标签,训练时要确保这些是单 token(加入
special tokens),否则会被拆成多 token,学习效率低。<tool_call> XML、Llama 的
<|python_tag|>)差异极大,跨模型迁移时必须重新设计模板。| 来源 | 规模 | 特点 | 代表 |
|---|---|---|---|
| 人工编写 | 10k–100k | 质量最高、成本最高 | OpenAI 内部、Anthropic HH |
| 模型蒸馏 | 100k–10M | 用 GPT-4 / Claude 生成 | Alpaca、WizardLM、OpenHermes |
| 开源合集 | 1M+ | 质量参差 | OpenOrca、UltraChat、Magpie |
| 领域数据 | 变 | 代码 / 数学 / 医学等 | CodeAlpaca、MetaMathQA |
| 拒绝采样 | 变 | 自举生成 + RM 过滤 | Llama 2 / 3、DeepSeek-R1 cold start |
2024 年之后主流做法是 “大规模 + 严筛”:生成 10× 量的候选数据,再用打分模型 / 规则 / 去重留下 Top-k。
给定 prompt \(x\) 和两个回答 \(y_w\)(被选中的)和 \(y_l\)(被拒的),RM \(r_\phi\) 输出标量分数。Bradley-Terry 模型假设人选 \(y_w\) 的概率为:
\[ P(y_w \succ y_l \mid x) = \sigma(r_\phi(x, y_w) - r_\phi(x, y_l)) \]
训练损失是二元交叉熵:
\[ \mathcal{L}_{RM} = -\mathbb{E}_{(x, y_w, y_l)} \log \sigma(r_\phi(x, y_w) - r_\phi(x, y_l)) \]
工程上的 RM 实现很简单:在 SFT 模型最后一层挂一个 scalar head(Linear → 1),只取最后一个 token 的 logit 作为分数。
Anthropic/hh-rlhf。是早期开源 RLHF
的事实标准数据集。RM 是 RL 阶段的”监督信号”,一旦有偏,整个策略都会被带歪。常见陷阱:
Anthropic 提出的 Constitutional AI(CAI) 和 RLAIF(RL from AI Feedback) 用 LLM 替代人类打标注:给出一套”宪法”(如”避免输出暴力内容”),让模型自己批评、自己改写、自己生成偏好对。优点是成本低、可扩展;缺点是会放大 judge 模型自身的偏见。
2024 年主流实践是混合 RLAIF:人类只标注最难 / 最关键的 5–10%,其余用 GPT-4o / Claude 3.5 生成。
PPO 在对齐场景的完整数据流涉及四个模型:
flowchart LR
P[Prompt Batch] --> A[Actor<br/>可训练<br/>π_θ]
A -- 生成 y --> R[Reward Model<br/>冻结<br/>r_φ]
A -- logits --> K[Reference Model<br/>冻结<br/>π_ref]
A -- hidden --> V[Critic<br/>可训练<br/>V_ψ]
R -- r(x,y) --> ADV[Advantage<br/>A = r - V + KL 惩罚]
K -- log π_ref --> ADV
V -- V(s) --> ADV
ADV --> LOSS[PPO Loss<br/>clip ratio + VF loss]
LOSS --> A
LOSS --> V
四个模型同时驻留,显存是标准 SFT 的 3–4 倍。以 13B 模型、bf16 为例:
| 模型 | 参数 | 梯度 | 优化器 | 合计 |
|---|---|---|---|---|
| Actor | 26 GB | 26 GB | 104 GB(Adam fp32) | 156 GB |
| Critic | 26 GB | 26 GB | 104 GB | 156 GB |
| RM | 26 GB | - | - | 26 GB |
| Reference | 26 GB | - | - | 26 GB |
合计 ~364 GB,一台 8×H100(640 GB)刚好能放下。工程上的常见优化:
PPO 在 RLHF 里最重要的 hyperparameter 就是 KL 系数 \(\beta\):
两种策略:
# 极简 PPO-RLHF 伪代码
for epoch in range(E):
prompts = sample_batch()
# 1. Rollout:actor 生成回答
responses, old_logprobs = actor.generate(prompts)
# 2. 打分
rewards = rm(prompts, responses) # [B]
ref_logprobs = ref.forward(prompts, responses)
kl = old_logprobs - ref_logprobs # [B, T]
shaped_rewards = rewards - beta * kl.sum(-1)
values = critic(prompts, responses) # [B, T]
advantages, returns = gae(shaped_rewards, values)
# 3. PPO 多步更新
for _ in range(ppo_epochs):
new_logprobs = actor.forward(prompts, responses)
ratio = torch.exp(new_logprobs - old_logprobs)
pg_loss = -torch.min(
ratio * advantages,
torch.clamp(ratio, 1 - eps, 1 + eps) * advantages
).mean()
vf_loss = (critic(prompts, responses) - returns).pow(2).mean()
loss = pg_loss + 0.5 * vf_loss
loss.backward(); optimizer.step()DPO(Direct Preference Optimization,Rafailov et al. 2023)证明了一个优雅结论:PPO 的最优策略和 reward 之间存在闭式关系,因此可以直接在偏好数据上用类似监督学习的方式优化策略,不再需要显式训练 RM、不再需要 actor/critic/RM/ref 四模型 rollout。
给定偏好对 \((x, y_w, y_l)\),DPO 损失:
\[ \mathcal{L}_{DPO} = -\mathbb{E} \log \sigma\left(\beta \log \frac{\pi_\theta(y_w|x)}{\pi_{ref}(y_w|x)} - \beta \log \frac{\pi_\theta(y_l|x)}{\pi_{ref}(y_l|x)}\right) \]
直观理解:让”被选答案”的策略概率相对 ref 升高、“被拒答案”相对 ref 下降。
flowchart LR
D[(Preference<br/>(x, y_w, y_l))] --> A[Actor π_θ<br/>可训练]
D --> R[Reference π_ref<br/>冻结]
A -- log π(y_w), log π(y_l) --> L[DPO Loss]
R -- log π_ref(y_w), log π_ref(y_l) --> L
L --> A
只有 actor + reference 两个模型,都是 forward(reference 不需要 backward),显存和 SFT 同数量级。训练时:
| 算法 | 核心改动 | 解决的问题 |
|---|---|---|
| IPO (Identity PO) | 用平方损失替代 logsigmoid | DPO 偏好对过度自信时会发散 |
| KTO (Kahneman-Tversky) | 只需单条回答 + 好/坏二元标签 | 不需成对数据,降低标注成本 |
| ORPO | 把 SFT 和偏好对齐合并成单阶段 | 少一个阶段,少一份 ref model |
| SimPO | 用 length-normalized 对数似然,完全去掉 ref | 进一步减少显存;抑制长度偏见 |
| RSO (Rejection Sampling Opt) | 偏好对来自 on-policy 采样 | 缓解 DPO 的 off-policy 问题 |
| cDPO / Robust DPO | 对噪声标注更鲁棒 | 真实偏好数据 label noise |
| 维度 | PPO | DPO |
|---|---|---|
| 训练复杂度 | 高(4 模型 + rollout) | 低(2 模型,类 SFT) |
| 显存 | 3–4× SFT | ~1.5× SFT |
| 数据形式 | prompt(在线 rollout) | 离线偏好对 |
| 性能上限 | 更高(on-policy 探索) | 受限于偏好数据分布 |
| 调参难度 | 高(KL、clip、lr 等) | 低(主要就 β) |
| 推理 RL | 更主流(可结合可验证 reward) | 可以但较弱 |
经验法则:
PPO 的 critic 和 actor 一样大,显存开销巨大,而且 critic 本身难训(一个标量估计要拟合长序列累积奖励)。DeepSeek 在 DeepSeekMath / DeepSeek-R1 中提出 GRPO(Group Relative Policy Optimization):直接去掉 critic,用组内相对奖励做 baseline。
对每个 prompt \(x\),采样 \(G\) 条回答 \(\{y_1, \dots, y_G\}\)(通常 \(G=8\sim 64\)),得到奖励 \(\{r_1, \dots, r_G\}\)。组内标准化后的 advantage:
\[ \hat{A}_i = \frac{r_i - \mathrm{mean}(r)}{\mathrm{std}(r) + \epsilon} \]
策略梯度用与 PPO 相同的 clipped ratio:
\[ \mathcal{L}_{GRPO} = -\mathbb{E}\left[\min(\rho_i \hat{A}_i, \mathrm{clip}(\rho_i, 1-\epsilon, 1+\epsilon)\hat{A}_i)\right] + \beta \cdot \mathrm{KL}(\pi_\theta \| \pi_{ref}) \]
其中 \(\rho_i = \pi_\theta(y_i|x) / \pi_{old}(y_i|x)\)。
R1 开源后,GRPO 成为 2025 年推理训练事实标准。
2024 年 9 月 OpenAI 发布 o1,宣告”推理时也要花算力”的新范式。核心假设:LLM 能通过超长 CoT(几千到几万 token)大幅提升数学、代码、科学推理能力,而长 CoT 的”思考策略”可以用 RL 训出来。
之后 2024 Q4 – 2025 Q2,推理模型井喷:
| 模型 | 机构 | 关键技术 |
|---|---|---|
| o1 / o1-pro / o3 | OpenAI | 闭源,据信 RL + test-time scaling |
| DeepSeek-R1 / R1-Zero | DeepSeek | GRPO + 可验证 reward,全开源权重 |
| Kimi K1.5 | 月之暗面 | 长上下文 RL + online policy mirror descent |
| Qwen-QwQ / Qwen3 Thinking | 阿里 | 推理混合模式,thinking / non-thinking 可切换 |
| 豆包 1.5 Pro / Seed-Thinking | 字节 | 自研 veRL 框架 + 大规模 RL |
| GLM-Zero / GLM-4.6 | 智谱 | 推理 RL + Agent 增强 |
| Claude 3.7 / 4 Sonnet Thinking | Anthropic | extended thinking 模式 |
| Gemini 2.5 Thinking | native multimodal reasoning |
推理 RL 与 Chat RLHF 最大的不同:reward 不再来自 RM,而来自确定性检验器。
def math_reward(response: str, gold: str) -> float:
# 1. 格式:必须有 <think>...</think> 和最终 \boxed{...}
if "<think>" not in response or "</think>" not in response:
return -0.1
answer = extract_boxed(response)
if answer is None:
return 0.0
# 2. 正确性:数值等价
return 1.0 if math_equal(answer, gold) else 0.0
def code_reward(response: str, tests: list) -> float:
code = extract_code_block(response)
passed = run_tests(code, tests, timeout=10)
return passed / len(tests)好处:
Kimi 技术报告强调”长上下文 RL”:上下文拉到 128k–1M,让模型生成超长思维链;用 mirror descent 风格的稳定策略更新替代 PPO 的 clipped ratio,同时去掉 critic。工程上还提出 partial rollout(部分回滚再继续)来重用显存。
Qwen3 提出 hybrid
thinking:同一个模型通过 system prompt
think=true/false
切换”思考”与”非思考”模式,thinking 模式下输出
<think>...</think>
再输出答案。训练时把两类数据混在一起,模型学会”根据任务复杂度自适应调用深思考”。
| 方法 | 做法 | 代价 | 收益 |
|---|---|---|---|
| best-of-N | 采 N 条答案,选 reward 最高 | N× 推理 | 稳定提升 |
| self-consistency | 采 N 条,多数表决 | N× 推理 | 数学 / 选择题有效 |
| 长 CoT(o1 式) | 单条输出几千 token 思考 | 1× 但长 | 对复杂推理最有效 |
| PRM-guided search | 逐步用 PRM 打分,beam search | N×L× | 更细粒度 |
| MCTS | 蒙特卡洛树搜索展开子问题 | 很贵 | Toolformer/Agent 型任务 |
PRM 数据昂贵(每一步都要标注),DeepSeek / OpenAI 的做法是用蒙特卡洛展开自动生成 PRM 监督信号:从中间某步采样 K 条到终点,用成功率估计此步的”正确概率”。
推理服务化时 best-of-N 很常见,典型架构:
async def best_of_n(prompt, n=8):
# 并发采样,tempreture=0.7~1.0,共用 vLLM prefix cache
responses = await asyncio.gather(*[
llm.generate(prompt, sampling=SamplingParams(temperature=0.8))
for _ in range(n)
])
scores = rm.score_batch(prompt, responses)
return responses[scores.argmax()]prefix cache 让 N 条共享 prompt 的 KV,只在 decode 阶段分叉,代价远小于 N×。这是”训练开销大 + 推理开销可控”的重要工程支撑。
| 框架 | 主要算法 | 特点 | 适用规模 |
|---|---|---|---|
| TRL(HuggingFace) | SFT/DPO/ORPO/KTO/PPO/GRPO | 最通用,生态好;PPO 性能一般 | ≤ 30B,单 / 多卡 |
| OpenRLHF | PPO/DPO/GRPO/REINFORCE++ | Ray + vLLM + DeepSpeed;业界最常用的开源 PPO | 7B ~ 70B+ |
| DeepSpeed-Chat | 端到端三阶段 | 微软官方;ZeRO-3 深度整合 | 早期 13B–66B |
| veRL | PPO/GRPO/DAPO | 字节开源;hybrid engine(训练 + 推理同卡切换) | 大规模多任务 |
| LLaMA-Factory | SFT/DPO/ORPO/PPO | 一键脚本 + WebUI;中文社区首选 | ≤ 70B |
| TRLX | PPO/ILQL | CarperAI 早期方案,现维护较少 | 历史遗产 |
| Nemo-Aligner | SFT/RM/DPO/PPO | NVIDIA 官方,Megatron 底座 | 大规模训练 |
| Axolotl | SFT/DPO/ORPO | yaml 配置驱动,易上手 | ≤ 70B |
┌─────────────┐ ┌─────────────┐
│ Ray Head │ │ vLLM Engine │ ← rollout(推理,TP=8)
│ Controller │←──────→│ Cluster │
└──────┬──────┘ └─────────────┘
│
├──→ Actor Train(DeepSpeed ZeRO-3,8 GPU)
├──→ Critic Train(ZeRO-3,4 GPU)
├──→ RM Inference(vLLM,2 GPU)
└──→ Ref Inference(vLLM,2 GPU)
关键优化:
字节 veRL 提出在同一张卡上切换训练 / 推理模式:训练时用 FSDP/Megatron,推理 rollout 时切回 vLLM 引擎、共享显存上的权重。避免训推两套集群的权重搬运开销,在大规模 GRPO 场景能把吞吐提 30–50%。
# pip install trl transformers datasets peft accelerate
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForCausalLM
from trl import DPOTrainer, DPOConfig
from peft import LoraConfig
model_name = "Qwen/Qwen2.5-1.5B-Instruct"
tok = AutoTokenizer.from_pretrained(model_name)
tok.pad_token = tok.eos_token
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="bfloat16")
ref = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="bfloat16")
# UltraFeedback:prompt / chosen / rejected 三列
ds = load_dataset("HuggingFaceH4/ultrafeedback_binarized", split="train_prefs")
def to_dpo(ex):
return {
"prompt": tok.apply_chat_template(ex["chosen"][:1], tokenize=False),
"chosen": ex["chosen"][-1]["content"],
"rejected": ex["rejected"][-1]["content"],
}
ds = ds.map(to_dpo, remove_columns=ds.column_names).select(range(5000))
cfg = DPOConfig(
output_dir="./dpo-qwen2.5-1.5b",
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
learning_rate=5e-7,
num_train_epochs=1,
beta=0.1,
max_length=2048,
max_prompt_length=1024,
bf16=True,
logging_steps=10,
save_steps=500,
)
lora = LoraConfig(r=16, lora_alpha=32, target_modules="all-linear", task_type="CAUSAL_LM")
trainer = DPOTrainer(
model=model, ref_model=ref, args=cfg,
train_dataset=ds, tokenizer=tok, peft_config=lora,
)
trainer.train()
trainer.save_model("./dpo-qwen2.5-1.5b-final")要点:
beta=0.1 是常用默认;偏好数据噪声大时降到
0.01。learning_rate=5e-7 比 SFT 小 10–100 倍,DPO
对 lr 极敏感,过大直接崩。# 1. 安装
pip install openrlhf[vllm]
# 2. 单机 8 卡 PPO,以 Qwen2.5-7B 为例
ray start --head --num-gpus=8
python -m openrlhf.cli.train_ppo_ray \
--ref_num_nodes 1 --ref_num_gpus_per_node 2 \
--reward_num_nodes 1 --reward_num_gpus_per_node 2 \
--critic_num_nodes 1 --critic_num_gpus_per_node 2 \
--actor_num_nodes 1 --actor_num_gpus_per_node 2 \
--vllm_num_engines 2 --vllm_tensor_parallel_size 1 \
--colocate_actor_ref \
--pretrain Qwen/Qwen2.5-7B-Instruct \
--reward_pretrain OpenRLHF/Llama-3-8b-rm-mixture \
--save_path ./ckpt/ppo-qwen2.5-7b \
--micro_train_batch_size 4 --train_batch_size 128 \
--micro_rollout_batch_size 8 --rollout_batch_size 1024 \
--max_samples 100000 \
--prompt_data OpenRLHF/prompt-collection-v0.1 \
--input_key context_messages --apply_chat_template \
--max_epochs 1 --num_episodes 1 \
--prompt_max_len 1024 --generate_max_len 1024 \
--actor_learning_rate 5e-7 --critic_learning_rate 9e-6 \
--init_kl_coef 0.01 \
--zero_stage 3 --bf16 --flash_attn --gradient_checkpointing读法:
--colocate_actor_ref:actor 和 reference
共享 GPU,省一半显存。--vllm_num_engines 2:独立的 rollout
集群。--init_kl_coef 0.01:KL
惩罚,训练中可自适应。reward_pretrain 必须提前训好或用开源
RM。from trl import GRPOConfig, GRPOTrainer
from datasets import load_dataset
import re
def math_reward_func(prompts, completions, **kw):
"""可验证 reward:最终 \\boxed{答案} 是否与 gt 一致"""
rewards = []
for completion, gt in zip(completions, kw["gold"]):
m = re.search(r"\\boxed\{([^}]+)\}", completion)
pred = m.group(1).strip() if m else ""
rewards.append(1.0 if pred == str(gt).strip() else 0.0)
return rewards
ds = load_dataset("openai/gsm8k", "main", split="train")
ds = ds.map(lambda x: {"prompt": x["question"], "gold": x["answer"].split("####")[-1].strip()})
cfg = GRPOConfig(
output_dir="./grpo-qwen2.5-1.5b",
learning_rate=1e-6,
num_generations=8, # 组大小 G
max_completion_length=1024,
per_device_train_batch_size=1,
gradient_accumulation_steps=4,
bf16=True,
beta=0.04, # KL 系数
logging_steps=5,
)
trainer = GRPOTrainer(
model="Qwen/Qwen2.5-1.5B-Instruct",
reward_funcs=[math_reward_func],
args=cfg, train_dataset=ds,
)
trainer.train()这是复现 R1-Zero 思路的最小框架:base / instruct 模型 + 可验证 reward + GRPO。在 GSM8K 上跑几千步就能看到 pass@1 显著提升。
| 指标 | 健康范围 | 异常 |
|---|---|---|
| KL(π || π_ref) | 5–30 | >100 说明 actor 漂飞 |
| Response length | 稳定或缓慢上升 | 突增→长度 hacking |
| Reward 均值 | 单调上升 | 停滞或跳水→ RM 失效 |
| Entropy | 缓慢下降 | 骤降→ mode collapse |
| Clip fraction | 0.1–0.3 | >0.5 说明 lr 太大 |
R1 / o1 这种长推理模型训练的核心瓶颈不是算力而是高质量长 CoT 数据。主流路径:
def rejection_sample_pipeline(prompts, model, verifier, N=16, topk=2):
out = []
for p in prompts:
candidates = [model.generate(p, temperature=0.9) for _ in range(N)]
scored = [(c, verifier(p, c)) for c in candidates]
# 规则过滤:格式 + 答案正确 + 长度合理 + 无语言混杂
filtered = [c for c, s in scored if s > 0.99 and 200 < len(c) < 8000]
out.extend(filtered[:topk])
return out # 回灌做第二轮 SFTR1 技术报告里明确:第三阶段用约 60 万条拒绝采样推理数据 + 20 万条通用数据做 SFT,再进第四阶段全场景 RL。
长 CoT RL 训练的一个关键是难度课程:开局全是难题会导致 reward 长期为零、策略原地打转;全是简单题又学不到新东西。常见做法:
def build_curriculum(prompts, base_model, stages=3):
# 用 base 模型预估每条 prompt 的 pass@8
pass_rates = [estimate_pass_at_k(base_model, p, k=8) for p in prompts]
buckets = {
"easy": [p for p, r in zip(prompts, pass_rates) if 0.4 <= r <= 0.8],
"medium": [p for p, r in zip(prompts, pass_rates) if 0.1 <= r < 0.4],
"hard": [p for p, r in zip(prompts, pass_rates) if 0 < r < 0.1],
}
# 阶段性放入 easy → medium → hard
return buckets也可以做在线难度调度:训练中持续统计每个 prompt 最近 K 次的通过率,通过率≥0.9 的移出训练集,通过率=0 的暂时冻结,中间区间重点训。DeepSeek-R1 / Kimi K1.5 都提到类似技巧。
生成长度从 SFT 的几百 token 暴涨到 RL 的 8k–32k,带来几个工程问题:
flowchart TD
S[起点:有 base 或 SFT 模型] --> Q1{任务是否有<br/>客观验证器?}
Q1 -- 是(数学 / 代码 / 格式)--> Q2{显存是否充足?}
Q2 -- 充足 --> GRPO[GRPO / PPO + 可验证 reward]
Q2 -- 紧张 --> RFT[Rejection Sampling SFT<br/>自举迭代]
Q1 -- 否(chat / 安全 / 风格)--> Q3{是否有偏好对数据?}
Q3 -- 有 --> Q4{是否要在线策略探索?}
Q4 -- 要 --> PPO[PPO + RM]
Q4 -- 不要 --> DPO[DPO / SimPO / ORPO]
Q3 -- 没有,只有单条好/坏 --> KTO[KTO]
Q3 -- 什么都没有 --> DATA[先做数据:众包 or RLAIF]
场景 A:预算有限,只想把 base 做成 chat 助手 - 8×A100 / H100,30B 以内 - 路线:SFT(LoRA,10k 条)→ DPO(UltraFeedback,5k–50k 对) - 框架:LLaMA-Factory 或 TRL
场景 B:要做垂直领域(医疗 / 金融 / 代码) - 先做领域 continual pretrain(小步、低 lr) - SFT:领域指令 5k–50k + 通用指令 5k(防遗忘) - DPO:领域偏好 5k + 通用 5k - 评估重点:领域 benchmark + 保留通用 MT-Bench 不掉
场景 C:做通用推理模型(开源 R1 级别) - ≥ 64 × H100,资源密集 - 路线:冷启动 SFT(千条长 CoT)→ GRPO(数学 / 代码可验证 reward)→ 拒绝采样 SFT → 全场景 RL - 框架:OpenRLHF 或 veRL - 关键:验证器稳定性、reward 稀疏性处理、训推权重同步延迟
场景 D:只做 Agent / 工具调用对齐 - SFT 工具调用模板必须精确 - 偏好数据:成功调用 vs 幻觉参数调用 - 或直接 GRPO + “工具调用是否成功” 作为 0/1 reward
| 症状 | 可能原因 | 处理 |
|---|---|---|
| DPO 训几十步 loss 下降、eval 崩 | β 太小 / lr 太大 | β→0.2,lr→1e-7 |
| PPO reward 飙升但回答变差 | reward hacking | 加 KL、重训 RM、加正则 |
| 模型疯狂加长答案 | length bias | 换 SimPO / ORPO,或加 length penalty |
| 对齐后推理能力掉 | 分布偏移太远 | 混合 SFT 数据进 DPO;降低 epochs |
| GRPO 很多组全对 / 全错 | 数据难度不匹配 | 按通过率筛 prompt 到 30–70% 区间 |
| 过度拒绝 | RLHF 太重 safety | 混入 over-refusal 反例 SFT |
| 维度 | 中国 | 全球 |
|---|---|---|
| 代表对齐开源 | DeepSeek-R1、Qwen3、GLM-4.6、Kimi K1.5 | Llama 3.3、Mistral Large 2 |
| 开源 RLHF 框架 | OpenRLHF、veRL、LLaMA-Factory | TRL、Nemo-Aligner、Axolotl |
| 偏好数据 | BELLE、COIG-CQIA、AlignBench-dev | UltraFeedback、HH-RLHF、Nectar |
| 云厂 PaaS | 阿里 PAI、火山方舟、百度千帆、腾讯 TI | AWS Bedrock、Azure AI、Vertex AI |
| 推理模型付费 API | Doubao 1.5-pro、Qwen-Max Thinking、GLM-Zero | o1/o3、Claude thinking、Gemini 2.5 |
以 7B 模型、8×H100 单机为例,完整跑一轮”SFT + DPO + GRPO”的大致时间:
| 阶段 | 数据量 | 时间 | 备注 |
|---|---|---|---|
| SFT(full) | 100k 条,seq 4k | 8–12 h | 2 epoch,packing |
| SFT(LoRA r=64) | 100k 条 | 3–4 h | 显存 <= 40 GB/卡 |
| RM 训练 | 100k 对 | 6–8 h | 单 epoch |
| DPO(LoRA) | 50k 对 | 3–5 h | β=0.1 |
| PPO(OpenRLHF) | 20k prompt × 1 epoch | 24–48 h | rollout 占比大 |
| GRPO(G=8,GSM8K) | 20k prompt | 20–30 h | 长 CoT 更慢 |
实际资源往往不是瓶颈,数据准备 + 评估迭代才是主要工期占用,通常要预留 2–3 周做数据清洗和结果调优。
标准 PPO 用 GAE(Generalized Advantage Estimation)平滑 advantage。在 LLM-RLHF 中,reward 大多是稀疏的序列级 reward(整条回答只有一个 RM 分数),加上逐 token 的 KL 惩罚构成 shaped reward:
\[ r_t = \begin{cases} -\beta \log \dfrac{\pi_\theta(a_t|s_t)}{\pi_{ref}(a_t|s_t)} & t < T \\[4pt] r_{RM}(x, y) - \beta \log \dfrac{\pi_\theta(a_T|s_T)}{\pi_{ref}(a_T|s_T)} & t = T \end{cases} \]
GAE 展开:
\[ \hat{A}_t^{GAE(\gamma, \lambda)} = \sum_{l=0}^{T-t-1} (\gamma \lambda)^l \delta_{t+l},\quad \delta_t = r_t + \gamma V(s_{t+1}) - V(s_t) \]
RLHF 里常用 \(\gamma=1, \lambda=0.95\)。\(\gamma=1\) 对应”把最终 reward 完整回传到每个 token”,比 \(\gamma<1\) 更稳(否则前几个 token 几乎没有学习信号)。
一次 PPO step 里,rollout(生成样本)耗时常占 60–80%。优化手段:
“严格 on-policy” 意味着每次更新前数据都用最新策略采样。工程上为了效率常引入小幅 off-policy:
滞后过大会导致 importance weight \(\pi_\theta / \pi_{old}\) 偏离 1,PPO clip 频繁触发,训练不稳。实践中保持 K ≤ 4、rollout/train 权重同步延迟 ≤ 1 step 最稳。
nn.Linear(hidden, 1)。RM 本身也要评估,常用指标:
真实对齐往往要同时优化多个目标(helpfulness、harmlessness、honesty)。做法:
一个产线级 RLHF 训练 job 的组件拓扑:
┌──────────────────────────────────────────────────┐
│ 数据层:Prompt DB / Preference DB / Gold Dataset │
└───────┬──────────────────────────────────────────┘
│
┌───────▼──────┐ ┌──────────────┐ ┌──────────┐
│ Trainer Ctrl │──→│ Rollout Pool │──→│ Verifier │
│ (Ray head) │ │ (vLLM x N) │ │ (math/code│
└───────┬──────┘ └──────────────┘ │ sandbox)│
│ └──────────┘
├──→ Actor Train (DeepSpeed)
├──→ Critic Train
├──→ Weight Sync (NCCL broadcast → vLLM)
└──→ Metrics (Prom/Grafana + W&B)
监控看板必须有:
RLHF 从 InstructGPT 的”SFT + RM + PPO 三段式”起步,到 2024 年 DPO 把它压扁成”一段式”,再到 2025 年 GRPO + 可验证 reward 把它推进到推理模型新纪元。这条流水线的工程本质是:
对于基础设施工程师而言,真正的难点不是写 loss 函数——TRL / OpenRLHF 把算法都封装好了——而是:
过去三年对齐范式演进速度远超其他方向:2022 PPO、2023 DPO、2024 GRPO、2025 长 CoT + 可验证 reward,每一代都在降低工程门槛或抬高能力上限。可以预见的方向是:
下一篇 10《Checkpoint 与故障容忍》会进入另一个硬工程话题:数百 B 模型、几十天训练周期、几千卡集群下,如何做到”挂了一张卡不必从头再来”——这是支撑所有上面这些训练 / RL 流水线真正落地的底座。
上一篇:【大模型基础设施工程】08:MoE 训练工程 下一篇:【大模型基础设施工程】10:Checkpoint 与故障容忍
把当前热点继续串成多页阅读,而不是停在单篇消费。
2026-04-22 · architecture / ai-infra
以工程视角串联现代 LLM 的四阶段训练栈——预训练、中训、SFT 与对齐——覆盖数据、Tokenizer、优化器、精度、Scaling Law 与代表性训练框架。
2026-04-22 · architecture / ai-infra
面向工程师的大模型基础设施开篇地图,覆盖 2022 到 2026 的工程分水岭、五层工程栈、训练与推理的工程差异、中国与全球行业版图以及成本曲线。
2026-04-22 · architecture / ai-infra
从 CPU 与 GPU 的架构差异出发,讲清楚 SM、Warp、Tensor Core、HBM、NVLink 的工程含义,并结合 Roofline、FlashAttention 与国产算力栈,给出大模型工程师能直接上手的 GPU 心智模型。
2026-04-22 · architecture / ai-infra
从 nvcc 到 Triton,把 NVIDIA 软件栈的每一层拆给大模型工程师看,顺便谈谈 ROCm、CANN 为什么一直追不上。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。