跳转至

06 - 最新研究进展 (2024-2025)

学习时间: 5-6小时 重要性: ⭐⭐⭐⭐⭐ 了解强化学习前沿动态 前置知识: Transformer、离线RL、PPO基础


🎯 学习目标

完成本章后,你将能够: - 了解2024-2025年强化学习的最新进展 - 掌握Decision Transformer的核心思想 - 理解序列建模在RL中的应用 - 了解多模态强化学习方法 - 掌握RL for Reasoning的核心方法(GRPO、STaR、PRM) - 理解从o1到DeepSeek-R1的推理增强范式 - 了解RL for Code Generation的前沿进展(CodeRL、RLEF)


1. 2024年强化学习领域重大事件

1.1 图灵奖授予强化学习先驱

2025年3月:ACM宣布将图灵奖授予 Andrew BartoRichard Sutton,以表彰他们在强化学习领域的奠基性贡献。

意义: - 强化学习成为AI核心领域获得最高荣誉 - 标志着RL从学术研究走向主流应用 - 激励更多研究者投入RL领域

1.2 主要研究趋势

Text Only
2024-2025研究趋势:
├── 序列建模方法
│   ├── Decision Transformer
│   └── Online Decision Transformer
├── 多模态强化学习
│   └── Gato-like通用智能体
├── 大模型+RL
│   └── RLHF → DPO → GRPO演进
├── ⭐ RL for Reasoning(最热门)
│   ├── DeepSeek-R1 / OpenAI o1
│   ├── GRPO / STaR / PRM
│   └── 蒸馏与RL结合
├── RL for Code Generation
│   ├── CodeRL / RLEF
│   └── 代码Agent训练
├── 样本效率提升
│   └── 更好的离线RL方法
└── 世界模型
    └── 更稳定的模型学习方法

2. Decision Transformer

2.1 核心思想

将RL视为序列建模问题: - 不学习价值函数或策略 - 直接建模轨迹序列 - 使用Transformer架构

关键洞察

轨迹 = (回报, 状态, 动作) 的序列

2.2 与传统RL的区别

特性 传统RL Decision Transformer
核心 学习价值函数/策略 序列建模
训练 时序差分/Bellman方程 监督学习
架构 DQN/PPO等 Transformer
样本 需要在线交互 离线数据即可

2.3 算法流程

Text Only
输入: 轨迹 τ = (R_0, s_0, a_0, R_1, s_1, a_1, ...)

1. 将轨迹转换为序列:
   [R_0, s_0, a_0, R_1, s_1, a_1, ...]

2. 使用Transformer建模条件分布:
   P(a_t | R_t, s_t, R_{t-1}, s_{t-1}, a_{t-1}, ...)

3. 训练目标: 最大化动作预测准确率

4. 推理时: 给定目标回报,生成动作序列

2.4 代码实现

Python
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np

class DecisionTransformer(nn.Module):  # 继承nn.Module定义网络层
    """Decision Transformer模型"""

    def __init__(self, state_dim, action_dim, hidden_dim=128,
                 n_layers=3, n_heads=4, max_len=100):
        super(DecisionTransformer, self).__init__()

        self.state_dim = state_dim
        self.action_dim = action_dim
        self.hidden_dim = hidden_dim
        self.max_len = max_len

        # 嵌入层
        self.embed_return = nn.Linear(1, hidden_dim)
        self.embed_state = nn.Linear(state_dim, hidden_dim)
        self.embed_action = nn.Linear(action_dim, hidden_dim)

        # 位置编码
        self.pos_embed = nn.Parameter(torch.randn(1, max_len, hidden_dim))

        # Transformer
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=hidden_dim,
            nhead=n_heads,
            dim_feedforward=hidden_dim * 4,
            batch_first=True
        )
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=n_layers)

        # 预测头
        self.predict_action = nn.Sequential(
            nn.Linear(hidden_dim, hidden_dim),
            nn.ReLU(),
            nn.Linear(hidden_dim, action_dim),
            nn.Tanh()
        )

        self.predict_return = nn.Linear(hidden_dim, 1)
        self.predict_state = nn.Linear(hidden_dim, state_dim)

    def forward(self, returns, states, actions, timesteps):
        """
        前向传播

        参数:
            returns: (batch, seq_len, 1)
            states: (batch, seq_len, state_dim)
            actions: (batch, seq_len, action_dim)
            timesteps: (batch, seq_len)

        返回:
            预测的动作、状态、回报
        """
        batch_size, seq_len = states.shape[0], states.shape[1]

        # 嵌入
        return_embeddings = self.embed_return(returns)
        state_embeddings = self.embed_state(states)
        action_embeddings = self.embed_action(actions)

        # 交错排列: [r_1, s_1, a_1, r_2, s_2, a_2, ...]
        stacked_inputs = torch.stack(  # torch.stack沿新维度拼接张量
            [return_embeddings, state_embeddings, action_embeddings], dim=2
        ).reshape(batch_size, 3 * seq_len, self.hidden_dim)  # 重塑张量形状

        # 添加位置编码
        pos_embeddings = self.pos_embed[:, :3 * seq_len, :]
        stacked_inputs = stacked_inputs + pos_embeddings

        # Transformer
        transformer_out = self.transformer(stacked_inputs)

        # 提取动作预测(每隔3个token)
        action_preds = self.predict_action(transformer_out[:, 2::3])

        return action_preds

    def get_action(self, returns, states, actions, timesteps):
        """获取动作预测"""
        action_preds = self.forward(returns, states, actions, timesteps)
        return action_preds[:, -1, :]  # 返回最后一个动作

class DTTrainer:
    """Decision Transformer训练器"""

    def __init__(self, state_dim, action_dim, lr=1e-4):
        self.model = DecisionTransformer(state_dim, action_dim)
        self.optimizer = optim.Adam(self.model.parameters(), lr=lr)
        self.loss_fn = nn.MSELoss()

    def train_step(self, trajectories):
        """
        训练一步

        参数:
            trajectories: 轨迹批次
                - returns: (batch, seq_len, 1)
                - states: (batch, seq_len, state_dim)
                - actions: (batch, seq_len, action_dim)
        """
        returns = trajectories['returns']
        states = trajectories['states']
        actions = trajectories['actions']

        # 前向传播
        action_preds = self.model(returns, states, actions, None)

        # 计算损失(只计算动作预测)
        loss = self.loss_fn(action_preds, actions)

        # 反向传播
        self.optimizer.zero_grad()  # 清零梯度
        loss.backward()  # 反向传播计算梯度
        torch.nn.utils.clip_grad_norm_(self.model.parameters(), 0.25)
        self.optimizer.step()  # 更新参数

        return loss.item()  # 将单元素张量转为Python数值

2.5 优势与局限

优势: - 无需Bellman更新,训练稳定 - 天然支持离线学习 - 可以利用大规模预训练 - 可扩展到多任务

局限: - 需要大量离线数据 - 对长序列建模能力有限 - 难以处理稀疏奖励


3. Online Decision Transformer (ODT)

3.1 动机

问题:原始DT只能离线学习

解决方案:ODT结合在线探索和离线预训练

3.2 核心思想

Text Only
ODT框架:
├── 离线阶段
│   └── 在静态数据集上预训练
├── 在线阶段
│   └── 边交互边微调
└── 统一目标
    └── 最大化动作预测准确率 + 探索奖励

3.3 代码框架

Python
class OnlineDecisionTransformer:
    """Online Decision Transformer"""

    def __init__(self, state_dim, action_dim):
        self.dt_model = DecisionTransformer(state_dim, action_dim)
        self.exploration_bonus = 0.1  # 探索奖励系数

    def select_action(self, state, target_return):
        """选择动作(带探索)"""
        # 使用DT模型预测动作
        with torch.no_grad():  # 禁用梯度计算,节省内存
            action = self.dt_model.get_action(
                target_return, state, prev_actions, timesteps
            )

        # 添加探索噪声
        action = action + np.random.normal(0, self.exploration_bonus, size=action.shape)

        return action

    def online_update(self, new_trajectory):
        """在线更新"""
        # 将新轨迹加入缓冲区
        self.replay_buffer.add(new_trajectory)

        # 从缓冲区采样训练
        batch = self.replay_buffer.sample()
        loss = self.dt_model.train_step(batch)

        return loss

4. 多模态强化学习

4.1 Gato回顾

DeepMind的Gato(2022): - 单一Transformer处理多种任务 - 文本、图像、控制任务统一建模 - 展示了通用智能体的可能性

4.2 2024年进展

主要方向: 1. 视觉-语言-动作模型(VLA) 2. 机器人基础模型 3. 多模态世界模型

4.3 视觉-语言-动作模型

Python
class VLAModel(nn.Module):
    """视觉-语言-动作模型"""

    def __init__(self, vocab_size, image_size, action_dim):
        super(VLAModel, self).__init__()

        # 视觉编码器
        self.vision_encoder = VisionEncoder(image_size)

        # 语言编码器
        self.language_encoder = LanguageEncoder(vocab_size)

        # 多模态融合
        self.fusion = MultiModalFusion()

        # 动作解码器
        self.action_decoder = ActionDecoder(action_dim)

    def forward(self, image, text, previous_actions):
        """
        前向传播

        参数:
            image: 视觉输入
            text: 语言指令
            previous_actions: 历史动作
        """
        # 编码
        visual_features = self.vision_encoder(image)
        language_features = self.language_encoder(text)

        # 融合
        fused_features = self.fusion(visual_features, language_features, previous_actions)

        # 解码动作
        action = self.action_decoder(fused_features)

        return action

5. 大模型时代的强化学习

📌 交叉引用:RLHF的完整技术讲解请参考 LLM学习/03-系统与工程/04-对齐技术.md,本节侧重RLHF的最新研究进展与演进趋势。

5.1 RLHF的演进

从InstructGPT到GPT-4: - 奖励模型规模增大 - 多轮RL优化 - Constitutional AI(宪法AI)

2024年新方向: - DPO (Direct Preference Optimization):无需奖励模型 - KTO (Kahneman-Tversky Optimization):基于人类心理 - RLAIF:用AI反馈替代人类反馈

5.2 DPO简介

核心思想:直接优化策略满足人类偏好

目标函数: $\(L_{DPO} = -\mathbb{E}_{(x, y_w, y_l) \sim D} \left[ \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) \right]\)$

优势: - 无需训练奖励模型 - 训练更稳定 - 计算效率更高


6. 未来展望

6.1 研究趋势

Text Only
未来5年趋势:
├── 通用智能体
│   └── 单一模型处理多种任务
├── 样本效率
│   └── 从更少数据学习
├── 可解释性
│   └── 理解RL决策过程
├── 安全对齐
│   └── 确保RL系统安全
└── 跨领域应用
    └── 科学发现、医疗、教育

6.2 挑战与机遇

挑战: - 奖励设计困难 - 样本效率仍需提升 - 泛化能力有限 - 安全对齐问题

机遇: - 大模型结合RL - 多模态学习 - 世界模型 - 具身智能


7. RL for Reasoning — 推理增强(2024-2025 最热门方向)

📌 核心洞察:2024-2025年,强化学习最具突破性的应用方向是推理增强(RL for Reasoning)。从OpenAI o1到DeepSeek-R1,RL被证明能显著提升大语言模型的推理能力,开启了"后RLHF时代"的新范式。

7.1 背景:从 o1 到 DeepSeek-R1 的范式革命

时间线

Text Only
RL for Reasoning 里程碑:
├── 2024.05  DeepSeek-V2 —— 高效MoE架构
├── 2024.09  OpenAI o1 —— 首个推理增强模型(闭源)
├── 2024.11  QwQ-32B-Preview —— 阿里开源推理模型探索
├── 2025.01  DeepSeek-R1 —— 首个完全开源的RL推理模型
├── 2025.02  DeepSeek-R1蒸馏系列 —— 多尺寸开源
├── 2025.03  Kimi k1.5 / Claude 3.7 Sonnet —— 推理模型持续涌现
└── 2025.Q2  开源社区复现浪潮 —— Open-R1, SimpleRL等

为什么重要?

传统RLHF(Reinforcement Learning from Human Feedback)主要解决的是模型对齐(alignment)问题——让模型输出更符合人类偏好。而RL for Reasoning的目标是提升模型的推理能力本身,让模型学会"慢思考"(slow thinking),在数学、编程、逻辑推理等任务上实现质的飞跃。

这种新范式也被称为 RLVR(Reinforcement Learning with Verifiable Rewards)——用可验证的奖励(如数学答案正确性、代码通过测试)替代人类偏好作为训练信号,是 DeepSeek-R1-Zero 等推理模型的核心训练方法。

维度 传统RLHF RL for Reasoning (RLVR)
目标 对齐人类偏好 提升推理能力
奖励来源 人类标注 / 偏好数据 可验证的正确性(数学答案、代码执行)
训练信号 主观偏好 客观对错(可自动验证)
典型方法 PPO + 奖励模型 GRPO / STaR / PRM
代表系统 InstructGPT, ChatGPT o1, DeepSeek-R1, DeepSeek-R1-Zero

7.2 RLHF / RLAIF 回顾与局限

📌 交叉引用:RLHF完整技术细节请参考 LLM学习/03-系统与工程/04-对齐技术.md

RLHF经典流程

Text Only
RLHF三阶段:
┌─ Stage 1: SFT ──────────────────────────┐
│  在高质量指令数据上微调基座模型            │
└──────────────────────────────────────────┘
┌─ Stage 2: Reward Model ─────────────────┐
│  训练奖励模型学习人类偏好排序             │
│  输入(x, y) → 输出标量得分 r(x, y)       │
└──────────────────────────────────────────┘
┌─ Stage 3: RL Fine-tuning ───────────────┐
│  使用PPO优化策略模型,最大化奖励          │
│  同时加入KL散度约束防止偏离太远           │
└──────────────────────────────────────────┘

RLHF/RLAIF的局限

  1. 奖励模型的天花板:奖励模型本身不完美,存在reward hacking风险
  2. 标注成本高昂:高质量人类偏好标注成本极高,RLAIF虽缓解但引入AI偏见
  3. PPO训练不稳定:超参数敏感,需要Critic网络(额外的显存开销)
  4. 对推理能力提升有限:RLHF主要改善风格和安全性,对数学/编码推理提升有限
  5. 奖励信号模糊:人类偏好是主观的,不适合评判推理正确性

7.3 GRPO:DeepSeek-R1 的核心训练方法

GRPO(Group Relative Policy Optimization) 是DeepSeek-R1的核心RL训练算法,也是2025年最受关注的RL算法之一。

7.3.1 核心原理

关键创新:不需要额外的Critic(价值)网络,通过组内相对奖励来估计基线(baseline)。

传统PPO的问题

\[J_{PPO}(\theta) = \mathbb{E}_t \left[ \min \left( r_t(\theta) \hat{A}_t, \; \text{clip}(r_t(\theta), 1-\epsilon, 1+\epsilon) \hat{A}_t \right) \right]\]

其中优势函数 \(\hat{A}_t\) 需要一个Critic网络来估计,这意味着: - 额外的模型参数(Critic通常与Policy同等规模) - 额外的显存占用 - Critic的训练误差会传播到Policy更新

GRPO的解决方案

对于每个问题 \(q\),采样一组(Group)回答 \(\{o_1, o_2, \ldots, o_G\}\),然后用组内相对奖励代替Critic:

\[\hat{A}_i = \frac{r_i - \text{mean}(\{r_1, ..., r_G\})}{\text{std}(\{r_1, ..., r_G\})}\]

GRPO目标函数

\[J_{GRPO}(\theta) = \mathbb{E}_{q \sim P(Q), \, \{o_i\} \sim \pi_{\theta_{old}}(\cdot|q)} \left[ \frac{1}{G} \sum_{i=1}^{G} \min \left( \frac{\pi_\theta(o_i|q)}{\pi_{\theta_{old}}(o_i|q)} \hat{A}_i, \; \text{clip}(\cdot, 1-\epsilon, 1+\epsilon) \hat{A}_i \right) - \beta \, D_{KL}(\pi_\theta \| \pi_{ref}) \right]\]

7.3.2 与PPO的详细对比

维度 PPO (RLHF) GRPO (DeepSeek-R1)
Critic网络 ✅ 需要(与Policy同等规模) ❌ 不需要
显存占用 4个模型(Policy/Ref/Reward/Critic) 3个模型(Policy/Ref/Reward)
优势估计 GAE (Generalized Advantage Estimation) 组内标准化奖励
采样方式 逐条采样 批量采样一组
计算效率 较低(Critic前向传播) 较高(省去Critic计算)
训练稳定性 受Critic误差影响 更稳定(直接使用奖励)
奖励信号 学习到的奖励模型 可验证的规则奖励(如数学正确性)
适用场景 通用对齐 有明确对错的推理任务

7.3.3 训练流程详解

Python
import torch
import torch.nn.functional as F

class GRPOTrainer:
    """
    GRPO训练器(简化版)

    核心思想:
    1. 对每个问题,用当前策略采样G个回答
    2. 用规则/奖励模型对每个回答打分
    3. 在组内做标准化得到相对优势
    4. 用PPO-clip目标更新策略
    """

    def __init__(self, policy_model, ref_model, reward_fn,
                 group_size=8, clip_eps=0.2, kl_coeff=0.01, lr=1e-6):
        self.policy = policy_model        # 策略模型 π_θ
        self.ref_model = ref_model          # 参考模型 π_ref(冻结)
        self.reward_fn = reward_fn          # 奖励函数 r(q, o)
        self.group_size = group_size        # 每个问题采样数 G
        self.clip_eps = clip_eps            # PPO裁剪参数 ε
        self.kl_coeff = kl_coeff            # KL散度系数 β
        self.optimizer = torch.optim.Adam(self.policy.parameters(), lr=lr)

    def compute_group_advantages(self, rewards):
        """
        计算组内相对优势(GRPO核心)

        参数:
            rewards: shape (batch_size, group_size) -- 每组G个回答的奖励
        返回:
            advantages: shape (batch_size, group_size) -- 标准化后的优势
        """
        # 组内均值和标准差
        mean_r = rewards.mean(dim=-1, keepdim=True)       # (batch, 1)
        std_r = rewards.std(dim=-1, keepdim=True) + 1e-8  # (batch, 1)

        # 标准化
        advantages = (rewards - mean_r) / std_r            # (batch, G)
        return advantages

    def compute_kl_divergence(self, log_probs_policy, log_probs_ref):
        """计算策略与参考模型的KL散度"""
        kl = (log_probs_policy - log_probs_ref).mean()
        return kl

    def train_step(self, questions):
        """
        GRPO训练一步

        参数:
            questions: 一批问题 [q_1, q_2, ..., q_B]
        """
        all_losses = []

        for question in questions:
            # ===== Step 1: 采样一组回答 =====
            with torch.no_grad():
                outputs = []
                for _ in range(self.group_size):
                    output = self.policy.generate(question, temperature=0.7)
                    outputs.append(output)

            # ===== Step 2: 计算奖励 =====
            rewards = torch.tensor([
                self.reward_fn(question, output) for output in outputs
            ])  # shape: (G,)

            # ===== Step 3: 计算组内相对优势 =====
            advantages = self.compute_group_advantages(rewards.unsqueeze(0)).squeeze(0)  # unsqueeze增加一个维度  # squeeze压缩维度

            # ===== Step 4: 计算策略比率和损失 =====
            for i, output in enumerate(outputs):  # enumerate同时获取索引和元素
                # 当前策略的对数概率
                log_prob = self.policy.log_prob(question, output)
                # 旧策略的对数概率(采样时的)
                with torch.no_grad():
                    log_prob_old = self.policy.log_prob(question, output)
                    log_prob_ref = self.ref_model.log_prob(question, output)

                # 策略比率
                ratio = torch.exp(log_prob - log_prob_old)

                # PPO-Clip损失
                surr1 = ratio * advantages[i]
                surr2 = torch.clamp(ratio, 1 - self.clip_eps, 1 + self.clip_eps) * advantages[i]
                policy_loss = -torch.min(surr1, surr2)

                # KL惩罚
                kl_penalty = self.kl_coeff * self.compute_kl_divergence(log_prob, log_prob_ref)

                loss = policy_loss + kl_penalty
                all_losses.append(loss)

        # ===== Step 5: 反向传播 =====
        total_loss = torch.stack(all_losses).mean()
        self.optimizer.zero_grad()
        total_loss.backward()
        torch.nn.utils.clip_grad_norm_(self.policy.parameters(), max_norm=1.0)
        self.optimizer.step()

        return total_loss.item()

def math_reward_function(question, answer):
    """
    数学推理奖励函数示例

    DeepSeek-R1使用的奖励信号:
    - 准确性奖励:答案是否正确(0/1)
    - 格式奖励:是否按要求格式输出(如\\boxed{})
    """
    # 提取模型输出的最终答案
    predicted = extract_answer(answer)
    # 获取标准答案
    ground_truth = get_ground_truth(question)

    # 准确性奖励
    accuracy_reward = 1.0 if predicted == ground_truth else 0.0

    # 格式奖励(鼓励使用思维链和规范格式)
    format_reward = 0.0
    if "<think>" in answer and "</think>" in answer:
        format_reward += 0.1
    if "\\boxed{" in answer:
        format_reward += 0.1

    return accuracy_reward + format_reward

7.3.4 DeepSeek-R1 训练Pipeline

DeepSeek-R1的完整训练分为多个阶段:

Text Only
DeepSeek-R1 训练流程:
┌─ Stage 0: 基座模型 ─────────────────────────────┐
│  DeepSeek-V3 Base(671B MoE)                    │
└──────────────────────────────────────────────────┘
┌─ Stage 1: 冷启动SFT ────────────────────────────┐
│  少量高质量CoT数据微调                            │
│  目的:教会模型产生<think>...</think>格式          │
│  数据量:数千条精选推理轨迹                        │
└──────────────────────────────────────────────────┘
┌─ Stage 2: RL训练(GRPO)─────────────────────────┐
│  使用GRPO在数学/编程/逻辑推理任务上训练            │
│  奖励信号:可验证的正确性 + 格式规范               │
│  关键发现:模型自发涌现"aha moment"、自我反思      │
└──────────────────────────────────────────────────┘
┌─ Stage 3: 拒绝采样 + SFT ───────────────────────┐
│  从Stage 2模型采样大量CoT数据                     │
│  过滤出高质量推理轨迹                              │
│  在全领域数据(含通用对话)上SFT                   │
└──────────────────────────────────────────────────┘
┌─ Stage 4: 第二轮RL ─────────────────────────────┐
│  在全领域上进行RL微调                              │
│  包括有用性+安全性+推理能力的综合奖励             │
│  最终得到DeepSeek-R1                               │
└──────────────────────────────────────────────────┘

关键发现——"aha moment"

在Stage 2的纯RL训练中,DeepSeek团队观察到模型自发涌现了以下推理行为: - 自我验证:"Wait, let me check this again..." - 回溯修正:"Hmm, that doesn't seem right. Let me reconsider..." - 分步推理:将复杂问题分解为子步骤 - 探索多条路径:尝试不同解题方法

这些行为并非通过数据教授,而是RL训练过程中自然涌现的。

7.4 STaR:自我改进推理

STaR(Self-Taught Reasoner) 是一种让模型通过自我生成推理过程来迭代改进的方法。

7.4.1 算法流程

Text Only
STaR算法:
┌─ Step 1: 初始推理 ──────────────────────────────┐
│  对每个问题(q, a*),让模型生成推理过程            │
│  (q) → 模型生成 → rationale + answer              │
└──────────────────────────────────────────────────┘
┌─ Step 2: 过滤 ──────────────────────────────────┐
│  保留 answer == a* 的样本 → 正确推理集            │
│  丢弃 answer ≠ a* 的样本                          │
└──────────────────────────────────────────────────┘
┌─ Step 3: Rationalization(合理化)──────────────┐
│  对失败的问题:将正确答案a*作为提示               │
│  让模型生成能推导出a*的推理过程                    │
│  → "反向合理化"                                    │
└──────────────────────────────────────────────────┘
┌─ Step 4: 微调 ──────────────────────────────────┐
│  在正确推理 + 合理化推理的数据上微调模型          │
│  重复Step 1-4,迭代改进                           │
└──────────────────────────────────────────────────┘

7.4.2 代码示例

Python
class STaRTrainer:
    """STaR (Self-Taught Reasoner) 训练器"""

    def __init__(self, model, tokenizer, num_iterations=5):
        self.model = model
        self.tokenizer = tokenizer
        self.num_iterations = num_iterations

    def generate_rationale(self, question, hint=None):
        """生成推理过程"""
        if hint:
            prompt = f"Question: {question}\nHint: The answer is {hint}\nLet's think step by step:"
        else:
            prompt = f"Question: {question}\nLet's think step by step:"

        output = self.model.generate(prompt, max_length=512, temperature=0.7)
        rationale, answer = self.parse_output(output)
        return rationale, answer

    def star_iteration(self, dataset):
        """STaR一轮迭代"""
        training_data = []

        for question, ground_truth in dataset:
            # Step 1: 直接推理
            rationale, predicted = self.generate_rationale(question)

            if predicted == ground_truth:
                # Step 2: 正确 → 保留
                training_data.append({
                    'question': question,
                    'rationale': rationale,
                    'answer': predicted
                })
            else:
                # Step 3: 错误 → 合理化(提供答案作为hint)
                rationale_hint, predicted_hint = self.generate_rationale(
                    question, hint=ground_truth
                )
                if predicted_hint == ground_truth:
                    training_data.append({
                        'question': question,
                        'rationale': rationale_hint,
                        'answer': predicted_hint
                    })

        # Step 4: 微调
        self.finetune(training_data)
        return len(training_data)

    def train(self, dataset):
        """完整STaR训练"""
        for i in range(self.num_iterations):
            n_samples = self.star_iteration(dataset)
            accuracy = self.evaluate(dataset)
            print(f"Iteration {i+1}: {n_samples} samples, accuracy={accuracy:.2%}")

Quiet-STaR(2024):STaR的进阶版本,让模型在生成每个token时都进行内部推理("quiet thinking"),无需显式标注推理数据。

7.5 过程奖励模型 (PRM) vs 结果奖励模型 (ORM)

奖励建模是RL for Reasoning的关键环节。

7.5.1 两种范式对比

Text Only
ORM(Outcome Reward Model):
  输入:问题q + 完整回答o
  输出:单一标量奖励 r(q, o) ∈ [0, 1]
  判断:最终答案对不对?

PRM(Process Reward Model):
  输入:问题q + 推理过程的每一步 s_1, s_2, ..., s_n
  输出:每步的奖励 r(q, s_1), r(q, s_1, s_2), ...
  判断:每一步推理是否正确?
维度 ORM PRM
奖励粒度 整体结果 逐步骤
标注成本 低(只需最终答案) 高(需标注每一步)
信用分配 差(稀疏奖励) 好(密集奖励)
对错误检测 只知道最终错了 能定位哪一步出错
训练效率
代表工作 基础RLHF OpenAI PRM800K, Math-Shepherd

7.5.2 PRM的训练与使用

Python
class ProcessRewardModel:
    """过程奖励模型(PRM)"""

    def __init__(self, base_model, step_separator="\\n\\n"):
        self.model = base_model
        self.step_separator = step_separator
        self.reward_head = torch.nn.Linear(base_model.hidden_size, 1)

    def score_steps(self, question, reasoning_steps):
        """
        对推理过程的每一步打分

        参数:
            question: 问题
            reasoning_steps: ["Step 1: ...", "Step 2: ...", ...]

        返回:
            step_scores: 每步的得分 [0.9, 0.85, 0.3, ...]
        """
        step_scores = []
        context = f"Question: {question}\n"

        for step in reasoning_steps:
            context += step + self.step_separator
            # 编码到当前步骤的上下文
            hidden = self.model.encode(context)
            # 取最后一个token的隐藏状态
            score = torch.sigmoid(self.reward_head(hidden[:, -1, :]))
            step_scores.append(score.item())

        return step_scores

    def best_of_n_with_prm(self, question, candidates, aggregation="min"):
        """
        使用PRM进行Best-of-N选择

        aggregation:
          - "min": 取所有步骤得分的最小值(保守策略)
          - "last": 取最后一步的得分
          - "prod": 取所有步骤得分的乘积
        """
        best_score = -float('inf')
        best_candidate = None

        for candidate in candidates:
            steps = candidate.split(self.step_separator)
            scores = self.score_steps(question, steps)

            if aggregation == "min":
                final_score = min(scores)
            elif aggregation == "last":
                final_score = scores[-1]  # [-1]负索引取最后元素
            elif aggregation == "prod":
                final_score = 1.0
                for s in scores:
                    final_score *= s

            if final_score > best_score:
                best_score = final_score
                best_candidate = candidate

        return best_candidate, best_score

2025关键进展: - Math-Shepherd:自动化PRM标注,用Monte Carlo Tree Search估计每步的正确概率 - 自动PRM:无需人工标注,通过多次采样自动判断每步正确性 - 隐式PRM:不显式训练PRM,而是通过RL训练过程隐式学习过程奖励

7.6 思维链 (CoT) 作为 RL 动作空间

核心思想:将思维链推理视为RL中的"动作序列",每一步推理是一个动作。

7.6.1 形式化定义

Text Only
将推理问题建模为MDP:
  状态 s_t:问题 + 已生成的推理步骤 (s_0, s_1, ..., s_{t-1})
  动作 a_t:生成下一个推理步骤 s_t
  转移 T:确定性转移(拼接新步骤到上下文)
  奖励 r:
    - 中间奖励:PRM对每步的评分(可选)
    - 最终奖励:答案是否正确
  策略 π(a_t | s_t):语言模型的条件生成概率

7.6.2 搜索策略

不同的搜索策略决定了如何在推理空间中探索:

Python
class ReasoningSearch:
    """推理搜索策略"""

    @staticmethod  # @staticmethod不需要实例即可调用
    def best_of_n(model, question, n=64, reward_model=None):
        """
        Best-of-N采样
        最简单的方法:生成N个答案,选最好的
        """
        candidates = []
        for _ in range(n):
            response = model.generate(question, temperature=0.7)
            score = reward_model.score(question, response)
            candidates.append((response, score))

        return max(candidates, key=lambda x: x[1])  # lambda匿名函数

    @staticmethod
    def beam_search_with_prm(model, question, beam_width=5, max_steps=10, prm=None):
        """
        带PRM引导的Beam Search
        在推理步骤层面进行搜索
        """
        # 初始beam
        beams = [{"steps": [], "score": 0.0, "context": f"Q: {question}\n"}]

        for step_idx in range(max_steps):
            all_candidates = []

            for beam in beams:
                # 对每个beam,生成多个候选下一步
                for _ in range(beam_width):
                    next_step = model.generate_step(beam["context"], temperature=0.8)

                    # PRM打分
                    step_score = prm.score_step(question, beam["steps"] + [next_step])

                    all_candidates.append({
                        "steps": beam["steps"] + [next_step],
                        "score": beam["score"] + step_score,
                        "context": beam["context"] + next_step + "\n"
                    })

            # 保留top-k
            beams = sorted(all_candidates, key=lambda x: x["score"], reverse=True)[:beam_width]

            # 检查是否有beam已完成
            for beam in beams:
                if is_answer_complete(beam["steps"][-1]):
                    return beam

        return beams[0]

    @staticmethod
    def monte_carlo_tree_search(model, question, num_simulations=100, prm=None):
        """
        蒙特卡洛树搜索(MCTS)用于推理
        在step级别构建搜索树
        """
        root = MCTSNode(state=question, parent=None)

        for _ in range(num_simulations):
            # Selection:选择最有前途的节点
            node = root.select(exploration_weight=1.4)

            # Expansion:生成新的推理步骤
            next_step = model.generate_step(node.state, temperature=1.0)
            child = node.expand(next_step)

            # Simulation:完成剩余推理并评估
            full_solution = model.complete_reasoning(child.state)
            reward = evaluate_solution(question, full_solution)

            # Backpropagation:更新统计
            child.backpropagate(reward)

        # 返回最佳路径
        return root.best_path()

7.7 RL for Code / Agent

7.7.1 代码Agent的RL训练

SWE-Agent / Devin等代码Agent正在使用RL进行训练优化:

Text Only
代码Agent的RL训练框架:
┌─ 环境 ──────────────────────────────────────────┐
│  代码仓库 + 终端 + 测试套件 + Issue描述           │
└──────────────────────────────────────────────────┘
┌─ 状态空间 ──────────────────────────────────────┐
│  当前代码文件、终端输出、已执行的操作历史          │
└──────────────────────────────────────────────────┘
┌─ 动作空间 ──────────────────────────────────────┐
│  编辑文件、执行命令、搜索代码、提交修复           │
│  create_file / edit_file / run_test / search     │
└──────────────────────────────────────────────────┘
┌─ 奖励 ──────────────────────────────────────────┐
│  测试通过率、代码质量、步骤效率                    │
│  r = test_pass_rate + λ_1·quality - λ_2·steps    │
└──────────────────────────────────────────────────┘
Python
class CodeAgentRewardFunction:
    """代码Agent的奖励函数设计"""

    def __init__(self, test_weight=1.0, quality_weight=0.1, efficiency_weight=0.05):
        self.test_weight = test_weight
        self.quality_weight = quality_weight
        self.efficiency_weight = efficiency_weight

    def compute_reward(self, trajectory):
        """
        计算代码修复轨迹的奖励

        trajectory包含:
          - issue_description: Bug描述
          - actions: Agent执行的操作序列
          - final_patch: 最终提交的代码补丁
          - test_results: 测试运行结果
        """
        # 1. 测试通过奖励(核心)
        test_reward = self.compute_test_reward(trajectory['test_results'])

        # 2. 代码质量奖励
        quality_reward = self.compute_quality_reward(trajectory['final_patch'])

        # 3. 效率惩罚(步骤越少越好)
        efficiency_penalty = len(trajectory['actions']) * self.efficiency_weight

        total_reward = (
            self.test_weight * test_reward +
            self.quality_weight * quality_reward -
            efficiency_penalty
        )

        return total_reward

    def compute_test_reward(self, test_results):
        """基于测试结果的奖励"""
        if test_results['all_passed']:
            return 1.0
        else:
            # 部分奖励:通过的测试比例
            return test_results['passed'] / test_results['total'] * 0.5

    def compute_quality_reward(self, patch):
        """基于代码质量的奖励"""
        score = 0.0
        # 修改行数适当
        if len(patch.split('\n')) < 50:
            score += 0.3
        # 无语法错误
        if not has_syntax_errors(patch):
            score += 0.5
        # 包含注释
        if has_comments(patch):
            score += 0.2
        return score

7.7.2 工具使用 (Tool-Use) 中的RL

RL在训练LLM使用外部工具(API调用、搜索、计算器等)方面也取得了重要进展:

Text Only
Tool-Use RL训练:
┌─ 工具定义 ────────────────────────────────────────┐
│  search(query) → results                           │
│  calculator(expr) → number                         │
│  code_exec(code) → output                          │
│  api_call(endpoint, params) → response             │
└────────────────────────────────────────────────────┘
┌─ 训练信号 ────────────────────────────────────────┐
│  工具调用是否正确(语法/参数)                      │
│  工具返回结果是否被有效利用                         │
│  最终回答是否因工具使用而更准确                     │
└────────────────────────────────────────────────────┘

关键方法: - Toolformer:自监督学习工具使用时机和方式 - RL from Execution Feedback:通过执行结果作为奖励训练工具调用 - ReAct + RL:在Reason-Act框架上叠加RL优化

7.8 蒸馏与RL的结合

DeepSeek-R1蒸馏系列是2025年最具影响力的开源成果之一:将大模型的推理能力蒸馏到小模型中。

7.8.1 蒸馏流程

Text Only
R1蒸馏流程:
┌─ 教师模型 ──────────────────────────────────────┐
│  DeepSeek-R1 (671B MoE)                          │
│  生成大量高质量推理轨迹                           │
│  800K条包含<think>...</think>的完整推理数据       │
└──────────────────────────────────────────────────┘
         ↓ 蒸馏数据
┌─ 学生模型 ──────────────────────────────────────┐
│  Qwen-2.5系列: 1.5B / 7B / 14B / 32B            │
│  Llama-3系列:  8B / 70B                          │
│  在蒸馏数据上进行SFT微调                          │
└──────────────────────────────────────────────────┘
┌─ 结果 ──────────────────────────────────────────┐
│  DeepSeek-R1-Distill-Qwen-32B:                   │
│    AIME 2024: 72.6% (超越OpenAI o1-mini)         │
│    MATH-500: 94.3%                                │
│  仅通过SFT蒸馏,无需RL训练!                      │
└──────────────────────────────────────────────────┘

7.8.2 蒸馏 vs RL vs 蒸馏+RL

训练方式 性能 成本 适用场景
纯SFT蒸馏 ★★★★ 资源受限,追求性价比
纯RL训练 ★★★★★ 极高 旗舰模型,算力充足
蒸馏 → RL ★★★★★+ 中高 用蒸馏数据冷启动后再RL

DeepSeek的关键发现: - 纯蒸馏(无RL)的小模型在benchmark上已经很强 - 但蒸馏模型缺乏泛化能力——在未见过的推理模式上表现差 - RL训练让模型真正"学会推理",而非仅仅模仿推理格式 - 最佳实践:先蒸馏冷启动,再进行RL训练

7.8.3 开源社区复现

2025年Q1-Q2的主要复现工作

项目 方法 基座模型 特点
Open-R1 (HuggingFace) GRPO复现 多种 社区协作,完整pipeline
SimpleRL 简化GRPO Qwen-2.5 最简化的R1复现
TinyZero GRPO 小模型 验证RL在小模型上的涌现
Logic-RL GRPO变体 Qwen-2.5 逻辑推理专项
STILL-2 蒸馏+RL Qwen-2.5 蒸馏后RL的完整流程

7.9 2025-2026 展望

7.9.1 端到端推理RL

趋势:跳过SFT冷启动阶段,直接从基座模型开始RL训练。

DeepSeek-R1-Zero实验已证明这是可能的(虽然训练不稳定),未来随着算法改进,端到端推理RL有望成为主流。

7.9.2 多模态推理RL

数学/几何推理:模型需要"看图"推理(几何证明、图表分析)

视觉编程:通过观察UI界面生成代码

科学推理:理解实验图表、分子结构等

7.9.3 可预期的突破方向

Text Only
2025-2026展望:
├── 算法改进
│   ├── 更高效的RL算法(GRPO变体/改进)
│   ├── 更好的过程奖励建模(自动PRM)
│   └── 更稳定的端到端训练策略
├── 应用拓展
│   ├── RL for Agent(工具使用/代码修复/自动化)
│   ├── RL for 多模态推理(视觉/语音/视频)
│   └── RL for 科学发现(数学定理证明/化学合成)
├── 开源生态
│   ├── 完整开源训练框架
│   ├── 高质量推理数据集
│   └── 标准化评估基准
└── 理论理解
    ├── 为什么RL能涌现推理能力?
    ├── 推理能力的scaling law
    └── RL vs 蒸馏的本质区别

8. RL for Code Generation — 代码生成强化学习

📌 代码生成是RL for Reasoning的重要分支,因为代码具有可自动验证的天然优势(编译通过、测试通过 = 正确)。

8.1 CodeRL / PPOCoder

CodeRL(2022) 是最早将RL系统性地应用于代码生成的工作之一。

8.1.1 核心思想

Text Only
CodeRL框架:
┌─ 代码生成模型 (Actor) ───────────────────────────┐
│  基于CodeT5/StarCoder等代码LM                     │
│  输入:问题描述/函数签名                           │
│  输出:候选代码                                    │
└──────────────────────────────────────────────────┘
┌─ Critic模型 ─────────────────────────────────────┐
│  预测代码在不同测试用例上的通过概率                │
│  提供细粒度反馈(不只是对/错)                     │
│  分类:compile error / runtime error /             │
│        wrong answer / correct                      │
└──────────────────────────────────────────────────┘
┌─ RL优化 ─────────────────────────────────────────┐
│  使用Critic信号作为奖励                            │
│  PPO优化代码生成策略                               │
└──────────────────────────────────────────────────┘

PPOCoder(2023)进一步改进,引入: - 基于代码结构的奖励(AST相似度) - 执行反馈的多阶奖励设计 - 更好的探索策略

8.2 代码执行反馈作为奖励信号

代码生成的天然优势:奖励信号可以通过自动执行获得!

Python
class CodeExecutionReward:
    """基于代码执行的奖励计算"""

    def __init__(self, timeout=10):
        self.timeout = timeout

    def compute_reward(self, generated_code, test_cases):
        """
        执行代码并计算奖励

        test_cases: [
            {"input": "...", "expected_output": "..."},
            ...
        ]
        """
        reward = 0.0

        # Level 1: 语法检查
        if not self.syntax_check(generated_code):
            return -0.5  # 语法错误

        # Level 2: 编译/解析检查
        if not self.compile_check(generated_code):
            return -0.3  # 编译错误

        # Level 3: 执行测试用例
        passed = 0
        for test in test_cases:
            try:  # try/except捕获异常
                result = self.execute(generated_code, test['input'], timeout=self.timeout)
                if result == test['expected_output']:
                    passed += 1
            except TimeoutError:
                reward -= 0.1  # 超时惩罚
            except RuntimeError:
                reward -= 0.1  # 运行时错误

        # 通过率奖励
        pass_rate = passed / len(test_cases)
        reward += pass_rate  # [0, 1]

        return reward

    def multi_level_reward(self, generated_code, test_cases):
        """
        多层级奖励(更细粒度)

        返回:
            dict: 各维度的得分
        """
        return {
            'syntax': self.syntax_score(generated_code),        # 语法正确性
            'compilable': self.compile_score(generated_code),    # 可编译性
            'functional': self.functional_score(generated_code, test_cases),  # 功能正确
            'efficiency': self.efficiency_score(generated_code, test_cases),  # 运行效率
            'style': self.style_score(generated_code)           # 代码风格
        }

8.3 RLEF:从执行反馈中强化学习

RLEF(Reinforcement Learning from Execution Feedback) 是2024-2025年代码生成RL的主流方法。

8.3.1 与RLHF的区别

维度 RLHF (代码) RLEF
反馈来源 人类评判代码质量 自动执行测试用例
反馈成本 高(需要人类标注) 极低(自动运行)
反馈准确性 主观(代码风格偏好) 客观(通过/不通过)
反馈规模 受限于标注预算 几乎无限
奖励设计 学习奖励模型 直接用执行结果

8.3.2 RLEF训练流程

Text Only
RLEF训练循环:
┌────────────────────────────────────────────────┐
│  1. 从题目库采样编程问题 q                      │
│  2. 用策略模型生成N个候选代码 {c_1, ..., c_N}   │
│  3. 在沙箱中执行每个代码,运行测试用例          │
│  4. 根据测试结果计算奖励 r_i                    │
│  5. 使用GRPO/PPO更新策略                        │
│  6. 重复                                        │
└────────────────────────────────────────────────┘

安全执行环境:
  - Docker容器隔离
  - 资源限制(CPU/内存/时间)
  - 网络隔离(禁止外部访问)
  - 文件系统只读挂载

2025关键应用: - Competitive Programming:AlphaCode 2、CodeForces级别的RL代码Agent - 自动Bug修复:SWE-bench上的RL训练Agent(通过率从20%→50%+) - 代码翻译:跨语言代码转换的RL优化(Python→Rust、Java→Go等) - 测试生成:RL训练模型自动生成高覆盖率测试用例


9. 本章总结

2024-2025关键进展

Text Only
最新研究:
├── Decision Transformer
│   └── RL作为序列建模
├── Online DT
│   └── 离线+在线结合
├── 多模态RL
│   └── 视觉-语言-动作
├── RLHF演进
│   └── DPO、RLAIF、KTO
├── RL for Reasoning ⭐⭐⭐(最热门)
│   ├── GRPO(DeepSeek-R1核心算法)
│   ├── STaR / Quiet-STaR(自我改进)
│   ├── PRM vs ORM(过程奖励建模)
│   ├── CoT作为RL动作空间
│   ├── 蒸馏与RL结合
│   └── 开源社区复现浪潮
├── RL for Code Generation
│   ├── CodeRL / PPOCoder
│   ├── RLEF(执行反馈强化学习)
│   └── 代码Agent训练
└── 通用智能体
    └── Gato-like模型

学习建议

  1. 关注顶会论文:NeurIPS、ICML、ICLR
  2. 跟踪开源项目:GitHub trending,特别是Open-R1、SimpleRL等复现项目
  3. 参与社区讨论:Reddit r/reinforcementlearning、r/LocalLLaMA
  4. 实践新算法:复现GRPO,在小模型上验证推理RL的效果
  5. 阅读技术报告:DeepSeek-R1、OpenAI o1等系统技术报告

✅ 自测问题

  1. Decision Transformer与传统RL的主要区别是什么?

  2. 为什么2024年图灵奖授予Barto和Sutton?

  3. DPO相比PPO+RLHF有什么优势?

  4. 多模态强化学习的主要挑战是什么?

  5. GRPO与PPO的核心区别是什么?为什么GRPO更适合推理任务的RL训练?

  6. PRM(过程奖励模型)相比ORM(结果奖励模型)有哪些优势?在实际训练中如何权衡?

  7. DeepSeek-R1的训练分为哪几个阶段?每个阶段的目的是什么?

  8. STaR算法中的"Rationalization"步骤解决了什么问题?

  9. RLEF相比RLHF在代码生成场景中有什么优势?

  10. 蒸馏和RL训练在推理能力获取上的本质区别是什么?


📚 延伸阅读

  1. Chen et al. (2021) - Decision Transformer: Reinforcement Learning via Sequence Modeling
  2. Zheng et al. (2022) - Online Decision Transformer
  3. Rafailov et al. (2023) - Direct Preference Optimization
  4. Reed et al. (2022) - A Generalist Agent (Gato)
  5. DeepSeek-AI (2025) - DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning
  6. Shao et al. (2024) - DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models (GRPO原始论文)
  7. Zelikman et al. (2022) - STaR: Bootstrapping Reasoning With Reasoning
  8. Zelikman et al. (2024) - Quiet-STaR: Language Models Can Teach Themselves to Think Before Speaking
  9. Lightman et al. (2023) - Let's Verify Step by Step (OpenAI PRM)
  10. Wang et al. (2024) - Math-Shepherd: Verify and Reinforce LLMs Step-by-step without Human Annotations
  11. Le et al. (2022) - CodeRL: Mastering Code Generation through Pretrained Models and Deep Reinforcement Learning
  12. Shojaee et al. (2023) - PPOCoder: Execution-Based Code Generation using Deep Reinforcement Learning

恭喜完成所有前沿主题学习!

→ 回到:06-前沿主题README