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 是训练算法的"遥控器",通过修改这些配置可以切换:
- 优势估计方法(GAE vs GRPO vs REINFORCE++ ...)
- KL 惩罚策略(是否使用、固定/自适应、惩罚形式)
- Off-policy 校正(IS 权重、拒绝采样、bypass/decoupled 模式)
- 折扣因子和 GAE 参数
RolloutCorrectionConfig 特别值得关注,它提供了丰富的工厂方法,覆盖了从简单到复杂的各种 off-policy 处理策略。