跳转至

algorithm.py — 该文件定义了 算法相关的配置数据类

文件概述

模块路径: verl.trainer.config.algorithm

该文件定义了 算法相关的配置数据类,是整个训练算法行为的控制中心。它包含四个配置类: 1. AlgoConfig - 顶层算法配置(优势估计、KL 惩罚等) 2. KLControlConfig - KL 控制器配置 3. FilterGroupsConfig - 过滤组配置(DAPO、Entropy 等) 4. RolloutCorrectionConfig - Rollout 校正配置(处理 off-policy 问题)

在训练流程中的位置

这些配置在训练的各个关键环节被读取: - AlgoConfig.adv_estimator 决定使用哪种优势估计方法 - AlgoConfig.use_kl_in_reward 决定是否施加 KL 惩罚 - RolloutCorrectionConfig 控制 off-policy 校正行为

关键代码讲解

1. KL 控制配置

@dataclass
class KLControlConfig(BaseConfig):
    type: str = "fixed"       # "fixed" 或 "adaptive"
    kl_coef: float = 0.001    # 初始 KL 系数
    horizon: int = 10000      # 自适应控制器的调整速度
    target_kl: float = 0.1    # 目标 KL 值(仅自适应模式使用)

KL 惩罚防止策略偏离参考策略太远: - Fixed 模式:KL 系数始终不变 - Adaptive 模式:根据当前 KL 与目标 KL 的差距自动调整系数

2. 过滤组配置

@dataclass
class FilterGroupsConfig(BaseConfig):
    enable: bool = False              # 是否启用
    metric: Optional[str] = None      # 过滤指标: "acc", "score", "seq_reward" 等
    max_num_gen_batches: int = 0      # 最大生成批次数(0 = 无限制)

用于 DAPO 等算法中的样本过滤。

3. Rollout 校正配置(最复杂)

@dataclass
class RolloutCorrectionConfig(BaseConfig):
    rollout_is: Optional[str] = "sequence"
    # IS 权重的聚合级别:
    # - None: 不使用 IS 权重
    # - "token": 每个 token 独立的权重
    # - "sequence": 整条序列一个权重

    rollout_is_threshold: float = 2.0
    # IS 权重截断阈值,防止极端权重

    rollout_is_batch_normalize: bool = False
    # 是否对 IS 权重做 batch 归一化(均值为 1)

    rollout_rs: Optional[str] = None
    # 拒绝采样模式(支持 token_k1, seq_sum_k2, seq_mean_k3 等多种组合)

    rollout_rs_threshold: Optional[str | float] = None
    # 拒绝采样阈值

    bypass_mode: bool = False
    # Bypass 模式: old_log_probs = rollout_log_probs (2 策略)
    # Decoupled 模式: 重新计算 old_log_probs (3 策略)

    loss_type: str = "ppo_clip"
    # Bypass 模式下的损失类型: "ppo_clip" 或 "reinforce"

预设工厂方法

该类提供了大量工厂方法来快速创建常用配置:

    # === Decoupled 模式预设(3 策略)===
    @classmethod
    def decoupled_token_is(cls, threshold=2.0):
        """Token 级别 IS 权重"""
        return cls(rollout_is="token", rollout_is_threshold=threshold)

    @classmethod
    def decoupled_seq_is(cls, threshold=2.0):
        """序列级别 IS 权重"""
        return cls(rollout_is="sequence", rollout_is_threshold=threshold)

    @classmethod
    def decoupled_geo_rs(cls, rs_threshold="0.999_1.001"):
        """几何平均拒绝采样"""
        return cls(rollout_is=None, rollout_rs="seq_mean_k1", rollout_rs_threshold=rs_threshold)

    # === Bypass 模式预设(2 策略)===
    @classmethod
    def bypass_ppo_clip(cls):
        """PPO-clip + bypass(最简单)"""
        return cls(bypass_mode=True, loss_type="ppo_clip")

    @classmethod
    def bypass_ppo_clip_geo_rs(cls, rs_threshold="0.999_1.001"):
        """PPO-clip + bypass + 几何拒绝采样"""
        return cls(bypass_mode=True, loss_type="ppo_clip",
                   rollout_rs="seq_mean_k1", rollout_rs_threshold=rs_threshold)

    @classmethod
    def bypass_pg_is(cls, threshold=2.0):
        """REINFORCE + IS 权重"""
        return cls(bypass_mode=True, loss_type="reinforce",
                   rollout_is="sequence", rollout_is_threshold=threshold)

    @classmethod
    def disabled(cls):
        """禁用校正,仅记录指标"""
        return cls(rollout_is=None, rollout_rs=None)

4. 顶层算法配置

@dataclass
class AlgoConfig(BaseConfig):
    gamma: float = 1.0
    # 折扣因子。1.0 = 不折扣(适合对话任务,因为奖励只在最后一步给出)

    lam: float = 1.0
    # GAE 的 lambda 参数。1.0 = 蒙特卡洛估计

    adv_estimator: str = "gae"
    # 优势估计器: "gae", "grpo", "reinforce_plus_plus", "rloo", "opo" 等

    norm_adv_by_std_in_grpo: bool = True
    # GRPO 中是否用标准差归一化优势(False = Dr.GRPO)

    use_kl_in_reward: bool = False
    # 是否在奖励中加入 KL 惩罚

    kl_penalty: str = "kl"
    # KL 散度估计方式: "kl", "abs", "mse", "low_var_kl", "full"

    kl_ctrl: KLControlConfig = field(default_factory=KLControlConfig)
    # KL 控制器配置

    use_pf_ppo: bool = False
    # 是否使用 Preference Feedback PPO

    filter_groups: Optional[FilterGroupsConfig] = None
    # 过滤组配置

    rollout_correction: Optional[RolloutCorrectionConfig] = None
    # Rollout 校正配置(处理 off-policy 问题)

核心类/函数列表

名称 类型 作用
AlgoConfig dataclass 顶层算法配置
KLControlConfig dataclass KL 控制器配置
FilterGroupsConfig dataclass 样本过滤配置
RolloutCorrectionConfig dataclass Rollout 校正配置

配置示例

# YAML 配置示例
algorithm:
  gamma: 1.0
  lam: 1.0
  adv_estimator: grpo           # 使用 GRPO
  norm_adv_by_std_in_grpo: true
  use_kl_in_reward: false       # 不使用 KL 惩罚
  kl_ctrl:
    type: fixed
    kl_coef: 0.001
  rollout_correction: null      # 不使用 rollout 校正

数据流和调用关系

YAML 配置
    |
    v
OmegaConf 解析 --> config.algorithm (DictConfig)
    |
    v (在运行时访问)
ray_trainer.py:
    +-- config.algorithm.adv_estimator --> 选择优势估计器
    +-- config.algorithm.use_kl_in_reward --> 是否施加 KL 惩罚
    +-- config.algorithm.kl_ctrl --> 创建 KL 控制器
    +-- config.algorithm.rollout_correction --> 配置 rollout 校正

core_algos.py:
    +-- config.gamma / config.lam --> GAE 参数
    +-- config.norm_adv_by_std_in_grpo --> GRPO 归一化

小结

algorithm.py 是训练算法的"遥控器",通过修改这些配置可以切换:

  1. 优势估计方法(GAE vs GRPO vs REINFORCE++ ...)
  2. KL 惩罚策略(是否使用、固定/自适应、惩罚形式)
  3. Off-policy 校正(IS 权重、拒绝采样、bypass/decoupled 模式)
  4. 折扣因子和 GAE 参数

RolloutCorrectionConfig 特别值得关注,它提供了丰富的工厂方法,覆盖了从简单到复杂的各种 off-policy 处理策略。