Chapter 03

DeepSeek-R1 解析:强化学习训练推理

2025 年 1 月,DeepSeek-R1 的开源震惊了整个 AI 界。它证明了一件事:推理能力可以通过强化学习自发涌现,无需人工标注推理过程。

为什么 DeepSeek-R1 重要

在 R1 之前,业界有一个根深蒂固的假设:训练推理模型需要大量人工标注的推理轨迹(Step-by-step solutions)。这个假设既提高了训练门槛,也意味着只有少数大公司才有资源复现 o1 级别的推理模型。

DeepSeek-R1 打破了这个假设,证明了一条更纯粹的路径:

无需人工标注推理过程
R1 的关键创新是使用结果奖励(Outcome Reward)代替过程奖励(Process Reward)。只需判断最终答案是否正确(对于数学和代码题,可以自动验证),模型自发学会了生成有效的中间推理步骤。这将标注成本降低了数个量级。
性能对标 o1,成本更低
在 AIME 2024(83.9%)、MATH-500(97.3%)、Codeforces(96.3 百分位)等关键基准上,R1 性能与 OpenAI o1 相当,部分指标超越。DeepSeek 公开的训练成本约 550 万美元,估计不到 o1 的 1/10,引发了"AI 民主化"的广泛讨论。
完全开源,推动生态
R1 的模型权重(671B MoE + 多个蒸馏版本 1.5B/7B/14B/32B/70B)、训练细节(论文)全部开源。这催生了大量开源推理模型:QwQ-32B、Sky-T1、STILL-2、Phi-4-Reasoning 等,以及基于 R1 技术的系列研究。
GRPO 算法贡献
R1 使用的 GRPO(Group Relative Policy Optimization)算法本身是一个重要的 RL 算法贡献,它去除了 PPO 中昂贵的 Critic 网络,用组内相对奖励代替绝对值估计,使大规模 RL 训练变得更稳定、更经济。

强化学习基础:为什么 RL 可以训练推理

要理解 GRPO,需要先理解为什么强化学习适合训练推理能力:

监督学习(SFT)的局限: 训练信号:人工标注的"正确推理步骤" 问题:需要大量标注,且"正确推理"不唯一 模型只会模仿示例,难以泛化到新问题 强化学习(RL)的优势: 训练信号:最终答案是否正确(自动验证) 奖励来源:数学题 → 计算器验证;代码题 → 测试用例 模型可以探索无数种推理路径 只要最终答案正确,任何推理过程都是合法的 关键洞见:对于有确定性答案的任务, 结果奖励 = 充足的训练信号 不需要告诉模型"怎么想",只需告诉它"对了没有"

GRPO:Group Relative Policy Optimization 原理

GRPO 是 DeepSeek 团队对 PPO 算法的一个重要改进,核心思想是用"组内相对排名"代替"绝对值估计":

PPO(传统 RLHF)的问题: 需要单独训练 Critic(价值网络 V(s)) Critic 与 Policy 规模相当(数百亿参数)→ 训练成本翻倍 Critic 的估计本身有误差 → 训练不稳定,调参复杂 显存占用极高 GRPO(Group Relative Policy Optimization)的解决方案: 对同一个问题,采样 G 个输出(G = 4~16) 计算每个输出的奖励 r_i(只需结果验证) 用组内相对排名代替 Critic: 优势(i) = (r_i - mean(r_1...r_G)) / std(r_1...r_G) 结果好于平均的输出被强化(优势 > 0) 结果差于平均的输出被抑制(优势 < 0) 优点:无需 Critic 网络,节省一半训练资源 组内归一化使训练更稳定 天然适合分布式训练(每组独立计算)
import torch
import numpy as np

# GRPO 核心逻辑(简化伪代码,展示算法原理)

def compute_reward(problem: dict, output: str) -> float:
    """
    奖励函数:只看结果,不看过程
    对于数学题:提取答案,与标准答案对比
    对于代码题:执行测试用例,统计通过率
    """
    answer = extract_answer(output)  # 提取最终答案
    correct = problem['answer']

    # 基础奖励:答案正确给 1.0,错误给 0.0
    base_reward = 1.0 if is_equivalent(answer, correct) else 0.0

    # 格式奖励:使用了 <think> 标签给 0.1 分(鼓励展示推理)
    format_reward = 0.1 if "<think>" in output else 0.0

    return base_reward + format_reward

def grpo_step(model, problem: dict, G: int = 8):
    """
    GRPO 训练的单步更新
    G: 每个问题采样的输出数量(推荐 8-16)
    """
    # Step 1: 采样 G 个不同的输出(使用 temperature > 0 增加多样性)
    outputs = []
    for _ in range(G):
        output = model.generate(
            problem['question'],
            temperature=0.8,  # 适当随机性确保探索多样性
            max_tokens=2048
        )
        outputs.append(output)

    # Step 2: 计算每个输出的奖励
    rewards = [compute_reward(problem, o) for o in outputs]
    # rewards 示例:[1.1, 0.0, 1.1, 0.0, 1.0, 0.0, 1.1, 0.0]

    # Step 3: 组内归一化(关键步骤,替代 Critic)
    mean_r = np.mean(rewards)
    std_r = np.std(rewards)
    advantages = [(r - mean_r) / (std_r + 1e-8) for r in rewards]
    # 正优势 → 该输出被强化;负优势 → 该输出被抑制

    # Step 4: PPO-clip 风格的策略梯度更新
    total_loss = 0
    for output, adv in zip(outputs, advantages):
        # 计算当前策略 vs 旧策略的概率比
        log_probs = model.compute_log_probs(problem['question'], output)
        old_log_probs = output.detach().log_probs
        ratio = (log_probs - old_log_probs).exp()

        # Clip 防止更新步长过大(PPO 的核心技巧)
        clipped = torch.clamp(ratio, 1 - 0.2, 1 + 0.2)
        loss = -torch.min(ratio * adv, clipped * adv).mean()
        total_loss += loss

    # 添加 KL 散度惩罚(防止模型偏离原始策略太远)
    kl_penalty = model.compute_kl_divergence(reference_model)
    total_loss += 0.01 * kl_penalty

    # 反向传播更新 Policy 模型
    total_loss.backward()
    optimizer.step()
    optimizer.zero_grad()

Aha-Moment:推理行为的自发涌现

DeepSeek 团队在训练过程中观察到了一个令人惊叹的现象:在训练中期,模型自发地开始使用自我反思语言,没有被显式训练这样做。这被称为"Aha-Moment"(顿悟时刻),是 2025 年 AI 研究的重大发现之一。

训练初期的模型输出: 问:1+1+1+1+1+1+1+1+1+1+1+1+1+1+1 等于多少? 答:15 ← 直接输出,无推理过程 训练中期(Aha-Moment 出现后): 问:[同题] 答:让我重新数一数... 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 确认答案是 15。 ← 自发出现了"重新数一数"的行为 训练后期(成熟的推理模式): 问:[复杂数学题] 答:<think> 我需要先分析题目的约束条件... 假设方案 A:...代入验证... 不满足条件 等等,我可能漏掉了一个约束... 让我重新从基础开始推导... 方案 B:... 满足所有约束! 答案是 42。 </think> 答案是 42。 ← 显示了完整的自我反思推理链
论文原文(DeepSeek-R1 技术报告)

"We observe that the model initially tends to think in a shallow manner... After the emergence of aha moments, the model started exploring multiple solution strategies before settling on one... This emergent behavior is particularly inspiring as it shows the power of RL in unlocking new capabilities that were not present in the base model and were not explicitly trained."

关键点:这些能力不是从人类示例中学来的,而是模型在 RL 训练压力下自主"发明"的。强化学习的奖励信号(答案正确性)足以驱动模型涌现出复杂的元认知行为。

R1 的四阶段训练流程

虽然 GRPO 是核心,但 DeepSeek-R1 的实际训练是一个精心设计的四阶段流程:

Stage 1: Cold Start(冷启动,SFT) ───────────────────────────────────── 问题:从零开始纯 RL 训练极不稳定 模型初期输出混乱,难以产生有效奖励 解决:收集少量(数千条)高质量 Long CoT 数据 来源:人工标注 + 用已有模型生成并过滤 方法:标准 SFT(监督微调),让模型学会基本的推理格式 目标:给 RL 训练一个好的起点,输出格式稳定 Stage 2: 推理导向强化学习(GRPO) ───────────────────────────────────── 奖励信号: - 答案正确性(数学/代码自动验证)0/1 - 格式合规性(使用了 <think>...</think> 标签) 训练数据:数学竞赛题(MATH、AMC/AIME)+ 代码(LeetCode/Codeforces) 关键结果:Aha-Moment 涌现,推理能力大幅提升 Stage 3: 拒绝采样 + SFT(Reject Sampling) ───────────────────────────────────── 操作:从 Stage 2 的 RL 模型中大量采样 只保留答案正确的推理轨迹(拒绝采样) 问题:RL 训练后模型可能"能力塌缩" 数学/代码强了,但通用对话、写作、指令跟随变差 解决:将拒绝采样的推理数据 + 通用 SFT 数据混合训练 目标:在保持推理能力的同时,恢复通用能力 Stage 4: 全面强化学习(RL + RLHF) ───────────────────────────────────── 在 Stage 3 的基础上继续 GRPO 训练 加入人类偏好数据(RLHF)进行安全性和对齐调整 最终版本:推理 + 安全 + 通用能力全面平衡
常见误区:R1 不是"纯 RL 训练"

很多人以为 DeepSeek-R1 完全通过纯强化学习训练,不需要任何监督数据。实际上 DeepSeek-R1 有一个"冷启动" SFT 阶段(Stage 1),使用了少量人工标注数据来稳定训练起点。真正的纯 RL 版本是 DeepSeek-R1-Zero(论文中的对照实验),它确实完全不用标注数据——但训练不稳定,输出语言切换混乱(中英文混杂),需要额外处理。R1 是"RL 为核心 + 少量 SFT 辅助"的实用方案。

R1 蒸馏:让小模型拥有推理能力

R1 的另一个重要贡献是证明了推理能力可以通过知识蒸馏传递给小模型,且效果出奇地好:

# 蒸馏策略:用 R1 生成推理轨迹,微调小模型
# 这比直接对小模型做 RL 训练效果好得多

# Step 1: 用 R1(大模型)为每个训练问题生成推理轨迹
r1_outputs = []
for problem in training_problems:
    # R1 生成完整的思维链(包含 thinking 过程)
    output = r1_model.generate(
        problem['question'],
        temperature=0.6,  # 稍低温度,提高质量
        include_thinking=True
    )
    r1_outputs.append({
        "input": problem['question'],
        "thinking": output.thinking,   # 推理过程
        "answer": output.final_answer   # 最终答案
    })

# Step 2: 质量过滤(关键!只保留答案正确的轨迹)
quality_data = [
    x for x in r1_outputs
    if verify_answer(x['answer'], training_problems[r1_outputs.index(x)]['correct'])
]
print(f"过滤保留率:{len(quality_data)/len(r1_outputs):.1%}")  # 通常 60-80%

# Step 3: 格式化为训练数据(包含完整的思维链)
def format_distill_sample(item: dict) -> dict:
    return {
        "messages": [
            {"role": "user", "content": item["input"]},
            {"role": "assistant",
             "content": f"<think>\n{item['thinking']}\n</think>\n\n{item['answer']}"}
        ]
    }

# Step 4: 用 SFT 微调小模型(如 Qwen-7B, Llama-3.1-8B)
# 小模型学习大模型的推理风格,而不是自己从零发现

# 蒸馏结果(R1 论文数据):
# DeepSeek-R1-Distill-Qwen-7B:AIME 55.5%(原始 Qwen-7B 约 12%)
# DeepSeek-R1-Distill-Llama-8B:AIME 56.7%
# DeepSeek-R1-Distill-Qwen-32B:AIME 72.6%
# 对比:OpenAI o1-mini 63.6%
# 结论:蒸馏 7B 模型接近 o1-mini 水平,代价是 7B 的推理成本!
本章小结

DeepSeek-R1 的核心:GRPO 算法(用组内相对奖励代替 Critic 网络)+ 四阶段训练(冷启动 SFT → 推理 RL → 拒绝采样 SFT → 综合 RL)。推理行为通过 RL 自发涌现,无需人工标注推理链。蒸馏技术让 7B 小模型也能拥有接近 o1-mini 的推理能力。这三点共同使得推理模型的训练从"大公司专利"变为了"可复现的工程方法"。下一章进入 Claude 扩展思考 API 的工程实践。