Repository navigation
Conversation
f3a5d57 to
3a6419f
Compare
3a6419f to
31fe2e5
Compare
31fe2e5 to
19f3a2f
Compare
19f3a2f to
3cd7ec6
Compare
|
@claude review |
|
Claude: Summary本 PR 在索引式 packing 之上接入 PPO:actor Ray worker 内挂载独立 critic(共享进程、样本缓存与 pack 计划),controller 收集 token value、在原样本顺序上计算 GAE,再分发 returns / advantages,并新增 LPT packing 策略与 LR schedule 辅助。整体数据流设计清晰,但 role 挂载采用 stringly-typed 反射接口、critic 大量依赖 host 私有方法、critic 核心路径完全没有单测,另有一处与 PPO 无关的 distillation padding 回归。 ProduceBatchResult impact: not affected Main Flowchart after this PRflowchart TD
A[_prepare_rollout_items] --> B[_build_pack_plan]
B --> C[ray.put per-DP RolloutState]
C --> D["load_train_batch<br/>缓存 samples/plan/batch_attr"]:::problem
D --> E{has_critic?}
E -- yes --> F["switch_role_modules('critic')"]:::changed
F --> G["call_attached('critic','collect_values')"]:::problem
G --> H["_compute_advantages / _compute_ppo_targets"]:::problem
E -- no --> I[_prepare_advantages]
H --> J["call_attached('critic','fit', token_returns)"]:::changed
I --> K["switch_role_modules('actor')"]:::changed
J --> K
K --> L["worker.fit(advantages)<br/>finally 释放缓存"]:::changed
L --> M[_build_trainer_log_info + _critic_log_scalars]
classDef changed fill:#dbeafe,stroke:#2563eb
classDef problem fill:#fee2e2,stroke:#dc2626
核心原理实现与单测
抽象与信息隐藏评估
单测建议
其他 Issues
VerdictREQUEST_CHANGES |
| forward_ctx = host._prepare_forward_seq_ctx( | ||
| forward_ctx, sequence_parallel=False, need_routed_experts=False | ||
| ) |
There was a problem hiding this comment.
Claude: [性能] collect_values 用 sequence_parallel=False 做全长 forward,而 critic 训练在 _prepare_loss 中是 SP 切分的。sp_size>1 时同一 DP 组的每个 SP rank 都重复算同一份 value,开销约 sp_size 倍,且 controller 只读取 replica 0 的结果。
| local_values = [row.tolist() for row in value_batches[dp_rank * data_replicate_size].split_samples()] | ||
| sample_indices = dispatch["global_indices"] | ||
| if len(local_values) != len(sample_indices): | ||
| raise ValueError( | ||
| f"Critic values for dp_rank={dp_rank} do not match the packed samples: " | ||
| f"{len(local_values)} vs {len(sample_indices)}" | ||
| ) | ||
| for local_index, global_index in enumerate(sample_indices): | ||
| dense_values[global_index] = local_values[local_index] | ||
| if any(sample_values is None for sample_values in dense_values): | ||
| raise RuntimeError("Critic values do not cover every training sample") |
There was a problem hiding this comment.
Claude: [测试] 本 PR 的核心正确性主张——critic value 按 global_indices 回填到原样本顺序、再把 returns 分发回各 DP rank——完全没有测试。_compute_ppo_targets 是纯函数(只依赖入参),不需要 Ray 即可直接覆盖长度不匹配、未覆盖全部样本、以及 data_replicate_size>1 时只读 replica 0 这三条路径。CriticWorker.collect_values / _materialize / fit 同样零覆盖。
3cd7ec6 to
1c6f161
Compare
4b34e86 to
90cb0e9
Compare
|
LGTM |
6f1dc3f to
7ff9422
Compare

Stack 关系
本 PR 属于 Stack #2189,依赖顺序从底到顶为:
本层基于 value-head #2188,是当前栈顶。 这是原 fork PR #2132 在主仓库中的 stack 版本。原 PR 的 packing 依赖 #2055 由 #2185 提供,value-head 依赖 #2099 由 #2188 提供;本层仅保留其上的 PPO、critic worker、GAE 和调度改动。原 PR 保留用于查阅 review 讨论。
概述
本 PR 在索引式 packing 上接入 PPO。actor Ray worker 承载一个独立的 critic 对象;两者共享进程、训练样本缓存和 pack 计划,分别持有自己的模型与优化器。controller 收集 critic value,在原始样本顺序上计算 GAE,再将 returns 和 advantages 分发给 critic 与 actor。
Value-head 依赖
value-head 模型、HF key 映射、CriticLossConfig、fp32_head 配置适配及 critic 模型加载测试属于下层 #2188。本层使用这些能力接入完整 PPO 训练,不再重复包含下层的实现 diff。
Controller 训练流程
未配置 critic 且使用组级 estimator 时,继续按下层的 reward/group 映射计算标量 advantage。GAE 需要 critic;配置与角色不匹配时直接报错。
共享样本与 packing 契约
TrainSample_PackPlan.dp_plansTokenTensorBatchglobal_indices对应回原始样本,GAE 的结果再按该映射分发,避免 packing 重排改变目标归属。GAE 与优化调度
LPT packing
新增
pack_strategy="lpt":按长度从大到小,把样本放入当前负载最低且能容纳该样本的 pack。容量不足时按 DP size 增加 pack 数并重新分配,随后完成 DP 分发和 optimizer-step 分组。既有 legacy、greedy、balance、native 策略继续保留。配置与文档
examples/v1/config/rl_ppo_gsm8k.py:PPO GSM8K 示例。recipe/ppo/config/rl_ppo_math.py、rl_ppo_qwen35_35b_a3b.py:PPO 训练配置。fp32_head。测试与验证
test_critic_sft.py的 value-head 和 critic-loss 覆盖位于下层 [feat] Support value head and critic loss #2188。test_ppo_role_wiring.py:角色注册/切换、GAE reward/action/trajectory/session 语义、advantage normalization 和调度。test_pack.py:LPT 策略及 packing 不变量。PPO 原始提交已重放到最新 packing 层,冲突和调用关系经过源码核对;本层当前 head 为
31fe2e5f。本次未运行单测、pre-commit 或 PPO 训练,仍保持 Draft。训练启动脚本