[Feat] Add off-policy masking for partial rollouts - #2003
Conversation
|
@claude review |
1 similar comment
|
@claude review |
|
Claude: ## Summary Adds off-policy masking for partial rollouts: response tokens from prior partial-rollout rounds are masked out of the loss via IssuesCritical
Warning
Nit
ProduceBatchResult impactNot directly affected — no fields on RoutedExperts impactThe off-policy masking path replaces routed_experts instead of concatenating. Old history refs are freed via Ray concurrency impactNot affected — no changes to Ray actor methods, decorators, or concurrency groups. VerdictREQUEST_CHANGES — the missing |
|
@claude review |
|
Claude: ## Summary PATCH 4/4 addresses all critical and most warning-level issues from the previous review (missing One remaining issue: Warning
ProduceBatchResult impactNot affected — no RoutedExperts impactOff-policy path replaces (rather than concatenates) routed_experts, freeing the old ref via Ray concurrency impactNot affected. VerdictCOMMENT — the remaining |
39de861 to
0561379
Compare
|
对 partial rollout 样本做 off-policy mask 时, off-policy 的定义应该也要跟当前"过期"的定义一致?
|
|
@claude review |
04f0f12 to
1f40fff
Compare
|
@claude review |
1f40fff to
8d65892
Compare
|
@claude review |
8d65892 to
43c9e5e
Compare
|
@claude review |
8694013 to
b26bc3f
Compare
|
@claude review |
|
Claude: Summary本 PR 引入 token 级 staleness:新增 ProduceBatchResult impact: 三处 trainer-visible 变化 —(1) RoutedExperts impact: token-expiry 只对过期 state 调 Ray concurrency impact: not affected(无 Main Flowchart after this PRflowchart TD
A[put / refresh_staleness] --> B[_apply_staleness_lifecycle]
B --> C{seq_staleness >= stale_threshold}
C -- 是 --> F[标记该 state EXPIRED]
C -- 否 --> D{agentic group 或 token_stale_threshold 为空}
D -- 是 --> E[保持原状态]
D -- 否 --> G[calculate_effective_response_mask]
G --> H{存在有效 token}
H -- 是 --> E
H -- 否 --> F
F --> I{expired_groups_retryable}
I -- 是 --> J[只重置过期 state 的 response<br/>整组进 EXPIRED pool]
I -- 否 --> K[整组丢弃<br/>含仍新鲜成员]
E --> L[take_batch]
J --> M[从 EXPIRED pool rerollout]
M --> A
L --> N[take_train_batch 重算 response_mask]
N --> O[_prepare_train_data / 训练]
style K fill:#ffcccc,stroke:#cc0000
style N fill:#ffe0b2,stroke:#e65100
style G fill:#e3f2fd,stroke:#1565c0
style J fill:#e3f2fd,stroke:#1565c0
核心原理实现与单测核心实现为三段: 真实代码路径已被覆盖的部分:
覆盖缺口见「单测建议」。 抽象与信息隐藏评估
单测建议
其他 Issues
VerdictREQUEST_CHANGES |
|
|
||
| async def put_generated_group(self, group: list[RolloutState]) -> bool: | ||
| produced_tokens = sum(len(item.response_ids) for item in group if item.response_ids is not None) | ||
| produced_tokens = sum(len(item.response_ids or []) - len(item.response_model_steps or []) for item in group) |
There was a problem hiding this comment.
Claude: [测试] produced_tokens 语义改为「仅本轮新增 token」(原为整条 response 长度),这是 ProduceBatchResult 的 trainer-visible 字段,但没有任何断言覆盖。建议补一例:同一 group 连续两轮 partial rollout,断言第二轮只计入新增 token。
| @@ -92,11 +95,6 @@ def default_should_continue_fn(completed_count: int, batch_size: int, **kwargs) | |||
|
|
|||
|
|
|||
| def calculate_stale_threshold(max_staleness: int, sync_weights_interval: int) -> int: | |||
There was a problem hiding this comment.
感觉也没有必要,因为sync_weight_interval 会在RL trainer中检查是否小于0,token和seq的staleness作为AsyncproducerConfig中检查是否大于0
背景
在 partial rollout 场景下,同一条 response 中的 token 可能由不同版本的 policy 生成。
现有 sequence staleness 使用 response 中最早的模型版本表示整条样本的 staleness,无法区分:
本 PR 引入 token staleness,使系统能够:
主要改动
max_token_staleness配置,计算方式与 seq staleness 相同,在 take batch 阶段统一更新 response maskreplay_buffer.put和refresh_staleness,与更新 sequence staleness 相同说明:这个PR不改动agentic RL的过期语义
token staleness 处理关键阶段
如何采样
flowchart LR A[刷新 staleness] --> B[统计 EXPIRED groups] B --> C{tail_batch_trigger_size} C -- -1 --> D[采样 ABORTED 或新数据] C -- 0 且存在 EXPIRED --> E[优先采样 EXPIRED group] C -- 大于0且达到阈值 --> F[进入 tail batch] C -- 大于0但未达到阈值 --> D E --> G[保持正常异步生产和 oversampling] F --> H[关闭本轮 oversampling] D --> I[执行 rollout] G --> I H --> I如何判断一个样本是否过期
flowchart LR A[刷新 seq staleness] --> B{超过 seq threshold} B -- 是 --> C[state 标记为 EXPIRED] B -- 否 --> D{普通 rollout 且配置 token threshold} D -- 否 --> E[state 保持有效] D -- 是 --> F[计算 effective response mask] F --> G{是否存在有效 token} G -- 否 --> C G -- 是 --> E C --> H[StorageItem 标记为 EXPIRED] H --> I{是否允许 rerollout} I -- 是 --> J[只清空实际过期 state 的 response] I -- 否 --> K[丢弃整个 group]配置示例
该配置表示: