Skip to content

【No.9】 feat(rollout): add stop-reason distribution and turn percentiles - #330

Open
Echo-Nie wants to merge 4 commits into
redai-studio:mainfrom
Echo-Nie:feat/no9-rollout-metrics
Open

Echo-Nie wants to merge 4 commits into
redai-studio:mainfrom
Echo-Nie:feat/no9-rollout-metrics

Conversation

@Echo-Nie

@Echo-Nie Echo-Nie commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

What

为 Agentic Rollout 增加停止原因分布和轮数分位数指标。

停止原因会按类别分别统计 count 和 ratio,例如:

  • stop_reason/max_turns/count
  • stop_reason/max_turns/ratio
  • stop_reason/unknown/count
  • stop_reason/unknown/ratio

轮数新增:

  • num_turn/p50
  • num_turn/p90
  • num_turn/p95
  • num_turn/p99

同时保留已有的 num_turn/min、num_turn/mean 和 num_turn/max。

停止原因优先读取 rollout_stop_reason;当该字段缺失、为空或无效时,兼容读取现有 Agentic metadata 中的 stop_reason。两者均无有效值时统一统计到 unknown。

Why

Relates to #321.

【No.9】Agentic Rollout 停止原因分布与轮数分位数指标

Task No.9 需要补充 Agentic Rollout 的停止原因计数、占比和轮数分位数,方便观察异常停止情况和长尾轨迹。

项目现有数据路径中同时存在 rollout_stop_reason 和 stop_reason。聚合时保持任务建议的 rollout_stop_reason 为主字段,并在主字段无有效值时兼容 stop_reason,避免已有 Agentic 停止原因被误统计为 unknown。

rollout_turns 缺失时继续沿用原来的默认值 1,停止原因占比以当前 samples 总数为分母。

How

  • 新增 compute_rollout_stop_reason_and_turn_metrics 聚合停止原因和轮数指标。
  • 从 sample metadata 中优先读取 rollout_stop_reason,主字段无有效值时回退到 stop_reason。
  • 当两个停止原因字段均缺失、为空或无效时归入 unknown。
  • 当两个字段同时有效时,保持 rollout_stop_reason 优先。
  • 使用 Counter 统计每种停止原因的 count 和 ratio。
  • 使用 np.percentile 计算 P50、P90、P95、P99。
  • 接入 compute_metrics_from_samples,空输入返回 {}。
  • 保留 rollout_turns 缺失时默认值为 1 的原有统计语义。
  • 原有 rollout reward、staleness、停止条件和调度逻辑保持不变。
  • 新增单元测试和汇总入口测试,覆盖空输入、单条、多条样本、缺失 metadata、unknown、停止原因 fallback 与字段优先级、占比之和、轮数分位数和输入不变性。

Testing

python -m pytest -q \
  tests/utils/test_metric_utils_agentic.py \
  tests/utils/test_metric_utils_rloo.py \
  tests/utils/test_multimodal_rollout_stats.py \
  tests/test_agentic_rollout.py

Result:

57 passed, 31 warnings in 30.76s
  • Related unit/integration tests pass
  • New tests added
  • Rebased onto latest upstream/main
  • pre-commit run --all-files passes
  • Documentation updated (not applicable)

Type of Change

新增 Rollout 指标和对应测试。

Screenshots / Logs

No screenshots. Test output is included above.

@Echo-Nie
Echo-Nie marked this pull request as ready for review September 18, 2026 04:10
@Echo-Nie
Echo-Nie force-pushed the feat/no9-rollout-metrics branch from 80a263a to 10fc164 Compare September 18, 2026 04:27
@Echo-Nie

Copy link
Copy Markdown
Contributor Author

@SigureMo 任务已完成,请求 review。

@rai-studio-bot rai-studio-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查版本:10fc164e(3 个文件、6 个 hunk;CI 全绿,新增测试在 H20 上实际执行并通过)。

停止原因分布与轮数分位数的实现本身没问题:比例分母取当前 samples 总数(各类 ratio 之和为 1)、rollout_turns 缺失时保持默认 1、min/mean/max 行为不变,且只接在 compute_metrics_from_samples 这一既有聚合入口上,没有改动 rollout 主循环与调度。PR 描述的 stop_reason 兼容回退已实现,并有 test_rollout_stop_reason_fallback_and_precedence 覆盖优先级与回退。

两项非阻塞意见见行内评论:

  • 回退读取的 agent 侧原因可能是自由文本(如 env_error:<detail>),会原样进入指标名并持续新增序列(P2)。
  • compute_metrics_from_samples 的空输入早退分支在生产调用点不可达,仅影响直接调用者的行为(P3)。
Powered by Nyanpasu with deepseek-v4.1-flash-ali medium, please check the suggestions carefully.

for sample in samples:
reason = sample.metadata.get("rollout_stop_reason")
if not isinstance(reason, str) or not reason.strip():
reason = sample.metadata.get("stop_reason")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 优先级:P2

回退到 agent 侧写入的 stop_reason 后,该值会原样进入指标名(relax/utils/metrics/metric_utils.py:118 的 prefix = f"stop_reason/{reason}/"),但它并不保证是有限枚举:examples/deepeyes_v2_agentic/app/agent.py:230 写的是 f"env_error:{obs.error}",错误串里可能带具体细节。relax/utils/tracking_utils.py:34 会把这个 dict 直接交给 wandb.log(TensorBoard :38、ClearML :42 同理),于是每个不同的错误串都会持续新增 2 条序列(/count、/ratio),指标基数随错误多样性增长。

建议在拼 key 前归一化到有限桶,例如:

        if not isinstance(reason, str) or not reason.strip():
            reason = "unknown"
        else:
            # 自由文本(如 "env_error:<detail>")只保留类别,避免指标基数膨胀
            reason = reason.split(":", 1)[0].strip()

若确实需要细分错误类型,建议由 agent 侧额外写入有限枚举字段,而不是把自由文本拼进指标名。

@Echo-Nie Echo-Nie Sep 18, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这条检查了一下是的,修了

现在只对 fallback 的 stop_reason 做类别归一化,比如 env_error:connection refused 会统一统计成 env_error;主字段 rollout_stop_reason 不变

同时补了对应的单测,验证 env_error:<detail> 不会直接进入 metric key

测试结果:

python -m pytest -q tests/utils/test_metric_utils_agentic.py

12 passed, 17 warnings in 25.58s

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确认这一版修得没问题:

  • reason.strip().split(":", 1)[0] 只作用于 fallback 分支:env_error:connection refused 归为 env_error;退化值(如 ":detail" 或只剩空白)会在下一层落到 unknown,非字符串也仍走 unknown,没有引入新的行为回退。
  • 主字段 rollout_stop_reason 保持原值同样合理:当前唯一写入方是 examples/deepeyes/rollout.py:434(_record_rollout_stats),取值来自有限集合(finish_length / finish_abort / budget_exhausted / env_done 等),确实不需要归一化。若将来有 agent 往该字段写自由文本,同一问题会复现,届时再处理即可。
  • 新增的 env_error:connection refused 参数化用例在 H20 上实际执行通过,CI 全绿,12 项用例覆盖完整。
  • 本条按已解决记录;同一 PR 上另一条 P3(compute_metrics_from_samples 的空输入早退分支)本版未改动,仍为未解决,非阻塞。

感谢补充测试。

Comment on lines +4840 to +4841
if not samples:
return {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3 优先级:P3

这个早退分支在当前生产调用点上不可达,且 compute_rollout_stop_reason_and_turn_metrics 本身已经对空输入返回 {}(任务要求「空输入返回空指标,不触发统计异常」,helper 层面已经满足):

  • _log_rollout_data 用 if samples: 保护(relax/distributed/ray/rollout.py:4817),空列表时根本不会调用本函数
  • _log_eval_rollout_data 在 rewards 为空时已经 continue(relax/distributed/ray/rollout.py:4768),而 samples 与 rewards 由同一批样本构造(agentic 见 relax/agentic/rollout.py:929-930,sglang 见 relax/engine/rollout/sglang_rollout.py:1292-1294),两者长度一致,空 samples 必然对应空 rewards

它的唯一实际效果,是把空输入时原有的硬失败(compute_statistics 里 np.max([]) 抛 ValueError)变成静默返回 {};目前只有新增测试 tests/utils/test_metric_utils_agentic.py:108 直接以空列表调用它。如果目的是覆盖任务里的「空输入」约定,放在 helper 上已经足够;若保留这一层,建议补一行注释说明面向的直接调用场景,否则可以删掉以缩小对既有入口函数的改动(任务同时要求不新增控制分支)。

@Echo-Nie Echo-Nie Sep 18, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#330 (comment)

F3改好了,不过F2有一个小的分歧是:

bot 的理解是:生产调用链已经保证 samples 非空,所以 compute_metrics_from_samples 里的这个 early return 是重复保护,No.9 的空输入要求只让新 helper 满足就可以

我这边的理解是:No.9 写了“空输入返回空指标,不触发统计异常”,而且新指标最终是接到 compute_metrics_from_samples 里的,所以我原本理解总入口直接传空列表时也应该安全

感觉都能说得通,所以暂时不改,麻烦 @xiaoliang0601 帮忙确认一下


2026/9/18/20:51 二编...

刚刚闲来无事瞅了一眼,刚看到 #336 里有类似F2的review建议, @rai-studio-bot 你咋左右脑互搏了,那边没有 compute_metrics_from_samples 的空输入 early return 然后建议加上 if not samples: return {}

#336 (comment)

所以感觉这里应该可以保留🤔

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你指出的前后不一致是对的,这条 F2 撤回,保留现有 early return 即可,不需要为此额外加注释。

No.9 正式任务要求空输入返回空指标;681ae833 中 compute_metrics_from_samples 在读取参数、计算统计前返回 {},也有直接调用的回归测试。这是合理的入口边界保护,不改变 rollout 调度或停止决策。生产调用者已有保护,并不足以构成删除它的理由。我之前将「不新增控制分支」套用到这里不恰当,抱歉造成困扰。

上一条汇总审查已撤回 F2,这里同步到原线程;F3 的 fallback 归一化修复仍按已解决记录。

@rai-studio-bot

rai-studio-bot commented Sep 18, 2026 •

Copy link
Copy Markdown

Nyanpasu 审查看板

审查状态: ✅ 已通过

审查版本: 752ab2d

已通过 752ab2d 的复核(maintainer 将 main 合入分支触发的新版本)。PR 自身实现与已通过的 681ae83 逐字节一致;本轮增量核对了合并结果:main 对共享文件 relax/utils/metrics/metric_utils.py 的修改(has_repetition 改为 detect_repetition 委托)与新指标无语义冲突、无循环导入,PR 的入口集成测试在 CI 中实际流经合并后的调用路径。新版本 8 项 CI 检查全部通过(含 Python 3.10/3.11/3.12 全量单测与 H20 GPU 单测)。F1、F3 维持已解决,F2、F4 维持已撤回,本轮无新增发现。深度必要性审计(production/tests)均按全 PR 范围完成,结论为保留现有实现;未运行本地定向变异实验(本机无 torch/megatron 环境,记录为缺口,由 CI 实际执行与 F3 回归测试历史佐证)。

审查阶段进度范围与结果
常规审查 ✅ 已完成 增量复核 681ae83 → 752ab2d:合并结构、PR 文件一致性(逐字节比对)、共享文件 metric_utils.py 的 main 侧修改(版权头、detect_repetition 导入、has_repetition 重写)与新指标的语义交互、调用点与 CI(8/8 通过,run 已核对 pin 到 752ab2d)。无新增发现。
深度审查 ✅ 已完成 未派发子任务:head 增量仅为已审查 main 代码的合并,PR 实现不变,设计已在 10fc164/681ae833 两轮验证,独立设计跳过(记录于 review-plan.json)。父级直接完成全 PR 范围的 production 与 tests 必要性审计,共 3 条 retain 决策,无删除/合并机会;缺口:本机无 torch/megatron 环境,未做本地变异实验。

审查发现

待处理
编号 严重性 问题状态规则来源
暂无待处理的记录。
已解决或已取代
编号 严重性 问题状态规则来源
F1 Medium severity 停止原因键约定不一致(rollout_stop_reason / stop_reason)——已由回退实现修复 ✅ 已解决 —
F2 Low severity 已撤回:总入口空输入保护合理,保留现有实现 ➖ 已被后续变更取代 —
F3 Medium severity agent 侧自由文本停止原因会原样进入指标名,序列数随错误信息增长——已按 fallback 归一化修复 ✅ 已解决 —
F4 Low severity 已撤回:metadata=None 超出现有 dict 契约,staleness 为已有逻辑,不列为本 PR 待办 ➖ 已被后续变更取代 —
提交范围 · 接收 3 · 建议移出 0 · 待确认 0

接收 3 个文件 · 建议移出 0 个文件 · 待确认 0 个文件。移出与待确认部分暂停深审,不代表审查通过。

文件结论仓库维护必要性依据替代去向或方案
relax/utils/metrics/metric_utils.py
接收 新增 compute_rollout_stop_reason_and_turn_metrics 聚合 helper,实现任务 No.9 要求的停止原因 count/ratio 与轮数分位数;由既有聚合入口 compute_metrics_from_samples 调用(relax/distributed/ray/rollout.py:4871),属于必须随 PR 维护的生产行为。 任务 No.9(redai-studio/community contributor-program 2026-cohort-2 official-task.md)+ 既有调用点 relax/distributed/ray/rollout.py compute_metrics_from_samples 仅作为外部实验证据保留无法落地指标契约;复用 compute_statistics 不能按停止原因分组,且不产出分位数。
relax/distributed/ray/rollout.py
接收 把 helper 接入既有聚合入口并替换原 num_turn min/mean/max 三行,同时保留任务验收要求的总入口空输入保护(读取参数前返回 {});未改动 rollout 调度与停止决策。 任务 No.9 验收标准(总入口空输入返回 {},无统计异常)+ 生产调用点 _log_rollout_data / _log_eval_rollout_data 新建独立指标入口会重复聚合路径并要求调用方双写;不加空输入保护则直接调用者空列表会触发 np.max([]) ValueError。
tests/utils/test_metric_utils_agentic.py
接收 针对新 helper 的 CPU 回归测试:空输入、单条/多条、缺失 metadata、unknown、fallback 优先级与归一化、ratio 之和、分位数、输入不变性,测试真实入口函数,属于应长期维护的回归覆盖。 任务 No.9 测试要求 + 本 PR Testing 一节(57 passed) 现有 tests/utils/test_metric_utils_rloo.py 等不覆盖新指标;用模拟器测试模拟器不能作为生产回归覆盖。
精简审查与验证依据
审查范围进度结论
生产代码 ✅ 已完成 审查了 PR 的全部生产改动(helper + 接线 + 空输入保护)的必要性:每项均有任务验收要求或生产调用点支撑,未发现可删除、合并或替换的冗余实现。
测试 ✅ 已完成 审查了 tests/utils/test_metric_utils_agentic.py 全部 12 个用例的检出力与维护必要性:每个用例对应 reason 选择逻辑或统计契约的一个独立分支,期望值为独立手算而非复现实现输出,无冗余用例可合并或删除。

生产代码的必要性与替代方案

范围必须保留的契约更简单的方案结论依据与限制
compute_rollout_stop_reason_and_turn_metrics(relax/utils/metrics/metric_utils.py:96-140)及 rollout.py:4868-4871 用 helper 调用替换原三行 num_turn 统计 由 compute_metrics_from_samples(relax/distributed/ray/rollout.py:4871,唯一生产调用点)无条件调用,输入完整 samples 列表,输出 stop_reason/{reason}/count|ratio 与 num_turn/{min,mean,max,p50,p90,p95,p99};rollout_turns 缺省 1;fallback stop_reason 归一化为类别前缀;无效/缺失归 unknown 内联进 compute_metrics_from_samples,或保留三行内联并单独补分位数:入口函数已混合 reward/RLOO/重复率/staleness 多个关注点,任务 No.9 明确要求独立聚合函数;拆出的 helper 可在不依赖 megatron 的环境独立单测(入口需要 megatron.core) 保留 rollout.py:4871 为唯一生产调用点;两轮完整审查(10fc164、681ae833)验证该分解;752ab2df 上 CI 全量测试通过(Python 3.10/3.11/3.12 + H20 GPU Unit Tests)。局限:本机无 torch/megatron 环境,未做本地变异实验。
compute_metrics_from_samples 空输入早退(relax/distributed/ray/rollout.py:4840-4842) 总入口在任何参数读取与统计前对空 samples 返回 {};直接调用者含回归测试 test_compute_metrics_from_samples_empty_input;生产调用点 _log_rollout_data(rollout.py:4819,if samples 保护)与 _log_eval_rollout_data(rollout.py:4780,rewards 空时 continue)不会传空 删除该保护:生产路径不可达空输入且 helper 自身已处理空列表。被否决——任务 No.9 验收标准明确要求总入口空输入返回 {} 且无统计异常;无保护时直接以 [] 调用会在 np.max([]) 抛 ValueError(F2 线程讨论后据此撤回删除建议) 保留 任务验收文本 + PR #330 F2 线程(discussion_r4044060478)的撤回记录;对应测试在 752ab2d CI 通过。

测试的必要性与替代方案

范围必须保留的契约更简单的方案结论依据与限制
tests/utils/test_metric_utils_agentic.py(190 行,12 用例:空输入、单条、多条+输入不变性+ratio 之和、3 组缺失/空白参数化、4 组 fallback/优先级参数化、总入口空输入、总入口集成) 对真实 helper 与真实总入口 compute_metrics_from_samples 的回归覆盖;期望值为独立手算(如 turns [1,2,4,10] 的 p50=3.0/p90=8.2/p95=9.1/p99=9.82,本轮已人工复核),非快照或自比对 并入 test_metric_utils_rloo.py(仓库按主题拆分 metric 测试,rloo 覆盖不同入口,不合并);删减参数化用例(None/空串/空白、fallback+归一化、优先级各自对应不同分支与缺陷类,无冗余);移除总入口集成测试(它是唯一证明指标确实流经生产聚合入口的覆盖,本轮合并验证正依赖它;monkeypatch 恰为 6 个消费 args 的 helper,最小化训练配置依赖) 保留 逐行审阅 + 期望分位数值手算核对全部正确;752ab2df CI 实际执行通过;F3 修复轮新增的 env_error:connection refused 用例证明该套件对该缺陷类的实际检出力。局限:本机无 torch/megatron 环境,未运行定向变异实验;入口集成测试在无 megatron 的环境 importorskip 跳过(CI 矩阵已安装 megatron,覆盖成立)。
Powered by Nyanpasu with glm-5.3[1m] xhigh, please check the suggestions carefully.

@SigureMo

Copy link
Copy Markdown
Member

辛苦 merge 下最新 main,新增了两条流水线

@Echo-Nie

Copy link
Copy Markdown
Contributor Author

辛苦 merge 下最新 main,新增了两条流水线

@SigureMo 已 merge 最新流水线,无冲突,CI 全部通过

@rai-studio-bot rai-studio-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复核 681ae833(含 main 合并):

  • F3(agent 侧自由文本停止原因进入指标名)已在 51744804 修复,归一化与单测都已验证。
  • F2(compute_metrics_from_samples 空输入早退分支)撤回:按 issue #326 原文核对,第 4 节写明「总入口也需要在任何统计和参数读取前处理空输入」,验收标准也要求「辅助函数和总入口对空输入返回 {},无统计异常」,且实现范围明确「指标入口的空输入保护及局部字段归一化不属于调度控制改动」——我之前引用的「不新增控制分支」不适用于这条入口保护,保留现有实现是正确的。

本轮新增 1 项非阻塞意见(P2):metadata=None 时新 helper 与 staleness 读取仍会抛 AttributeError,与验收矩阵的「缺失 metadata」「partial 模式缺 metadata」两条必测项不符,详见行内评论。

Powered by Nyanpasu with deepseek-v4.1-flash-ali medium, please check the suggestions carefully.

Comment on lines +104 to +115
reason = sample.metadata.get("rollout_stop_reason")
if not isinstance(reason, str) or not reason.strip():
reason = sample.metadata.get("stop_reason")
if isinstance(reason, str) and reason.strip():
reason = reason.strip().split(":", 1)[0]
if not isinstance(reason, str) or not reason.strip():
reason = "unknown"
else:
reason = reason.strip()

stop_reasons.append(reason)
turns.append(sample.metadata.get("rollout_turns", 1))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 优先级:P2

这段读取假定 sample.metadata 一定是 dict,但本任务的验收矩阵把 metadata=None 列为必测项,当前实现会抛 AttributeError:

  • 本行以及 metric_utils.py:106、:115 都直接 sample.metadata.get(...)。Sample.metadata 是普通 dict 字段(relax/utils/types.py:84),构造期没有校验,--custom-generate-function-path 这类外部入口可以传 None。
  • 同一路径上的 staleness 读取也仍是 sample.metadata.get("start_rollout_id", rollout_id)(relax/distributed/ray/rollout.py:4873),同样是 None 会失败。issue 【No.9】Agentic Rollout 停止原因分布与轮数分位数指标 #326 第 4 节写明「已有 partial rollout staleness 统计读取 metadata 时,兼容 metadata=None,缺失 start_rollout_id 继续按当前 rollout id 处理,即 gap 为 0」。

对应的矩阵条目:「缺失 metadata:{}、None、字段缺失有确定结果;全部缺失时 unknown/ratio = 1,轮数为 1」与「partial 模式缺 metadata:传入 rollout id 且进入 staleness 分支时,metadata=None 不报错」。现有测试只覆盖了 metadata 为 dict 的情形(tests/utils/test_metric_utils_agentic.py 中没有 metadata=None 用例)。

同任务的另一份实现(#336)在两处都用了 sample.metadata if isinstance(sample.metadata, dict) else {},并补了 Sample(metadata=None) 的单测,可作参考。这里建议在循环开头取一次安全 metadata:

Suggested change
reason = sample.metadata.get("rollout_stop_reason")
if not isinstance(reason, str) or not reason.strip():
reason = sample.metadata.get("stop_reason")
if isinstance(reason, str) and reason.strip():
reason = reason.strip().split(":", 1)[0]
if not isinstance(reason, str) or not reason.strip():
reason = "unknown"
else:
reason = reason.strip()
stop_reasons.append(reason)
turns.append(sample.metadata.get("rollout_turns", 1))
metadata = sample.metadata if isinstance(sample.metadata, dict) else {}
reason = metadata.get("rollout_stop_reason")
if not isinstance(reason, str) or not reason.strip():
reason = metadata.get("stop_reason")
if isinstance(reason, str) and reason.strip():
reason = reason.strip().split(":", 1)[0]
if not isinstance(reason, str) or not reason.strip():
reason = "unknown"
else:
reason = reason.strip()
stop_reasons.append(reason)
turns.append(metadata.get("rollout_turns", 1))

staleness 一行可改为 (sample.metadata or {}).get(...),两处各补一条 metadata=None 的单测即可覆盖该矩阵行。

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

补充更正这条意见的依据和优先级:#326 是另一位贡献者整理的任务细化,不能直接当作本 PR 新增的强制验收要求。正式 No.9要求覆盖缺失 metadata,但没有明确要求支持 metadata=None;Sample.metadata 的声明类型是 dict,默认也是 {},当前测试已覆盖该默认情况。

None 会在 helper 的 .get() 处报错这一代码事实成立,但此前的轮数统计也有同样前提,尚无证据表明本 PR 引入了生产路径回归。因此将本条降为 P3 可选健壮性建议,不作为必须修改项。若选择扩展对 None 的支持,再同时处理 helper、staleness 并补相应测试;前述建议代码的替换范围已核对为 104–115 行。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

metadata=None 这个 edge case 我认你了... 实在不行我给你 helper 里补个防御😭

不过你小汁偷偷拿开发者自己写issue来糊弄我是吧, No.9 里面只写了“缺失 metadata”,没明确要求 metadata=None,也没要求顺手改 partial rollout 的 staleness;

我瞅了一眼, Sample 当前定义本身也是:metadata: dict = field(default_factory=dict) ,你不信你瞅瞅https://github.com/redai-studio/Relax/blob/main/relax/utils/types.py#L84

staleness 那行也是 main 里原本就有的逻辑,不是本 PR 引入!!!!你瞅瞅这个 https://github.com/redai-studio/Relax/blob/main/relax/distributed/ray/rollout.py#L4871-L4876

严格反对(除非研发觉得可以补)你的Review !!!

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这条反对成立。已核对基线:Sample.metadata 的契约是 dict、默认 {};staleness 读取 也确实是已有逻辑。

我错误地把贡献者自己的 issue 细化当成正式验收要求,扩大了本 PR 的修改范围,抱歉。上一条虽降为可选建议,却仍将它挂为未解决项,也不妥:F4 现撤回,不再作为本 PR 的待办。你无需为满足这条审查补 helper 防御,也无需修改 staleness。 后续若维护者希望扩展 None 的支持,可另行明确契约和范围。

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rai-studio-bot 不要过度设计,不要过度防御,请参考 https://github.com/ShigureLab/nyanpasu/blob/main/AGENTS.md 重新 review

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

按你链接的开发原则重新核对了当前 681ae833 的输入契约与聚合实现:内部应信任 Sample.metadata 的 dict 契约,不能仅凭构造时能传入 None 就要求 helper 和既有 staleness 增加防御;F4 撤回。总入口空输入返回 {} 则对应本任务的明确空输入行为,保留合理,F2 也保持撤回。

未发现需要追加的修改,维持已通过的审查。审查看板已核实为“已通过”,F2/F4 均已标记撤回,没有待办项。

@rai-studio-bot rai-studio-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复核 681ae833 后通过。F1、F3 已解决,F2、F4 已撤回;关于任务范围与 metadata 契约的更正见原线程。目前没有剩余审查问题,7 项 CI 检查通过。本轮未重复运行本地或多节点 GPU 测试。

Powered by Nyanpasu with gpt-6-astra medium, please check the suggestions carefully.

@rai-studio-bot rai-studio-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复核通过(752ab2df)

本轮由 maintainer 将 main 合入分支触发:PR 自身实现与已通过的 681ae83 逐字节一致。增量核对确认合并结果无问题——main 对共享文件 relax/utils/metrics/metric_utils.py 的修改(has_repetition 改为 detect_repetition 委托)与新指标所在区域无重叠、无循环导入,PR 的入口集成测试在 CI 中实际流经合并后的调用路径;新版本 8 项 CI 检查全部通过(含 Python 3.10/3.11/3.12 全量单测与 H20 GPU 单测)。

无新增发现,F1–F4 状态不变;全 PR 范围的生产/测试必要性审计已完成,结论为保留现有实现(详见看板)。

看板:#330 (comment)

Powered by Nyanpasu with glm-5.3[1m] xhigh, please check the suggestions carefully.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants