Skip to content

【No.5】fix(agentic): aggregate speculative decoding metrics - #391

Open
Pinoeer-kingxi wants to merge 9 commits into
redai-studio:mainfrom
Pinoeer-kingxi:fix/task5-speculative-metrics
Open

Pinoeer-kingxi wants to merge 9 commits into
redai-studio:mainfrom
Pinoeer-kingxi:fix/task5-speculative-metrics

Conversation

@Pinoeer-kingxi

@Pinoeer-kingxi Pinoeer-kingxi commented Sep 29, 2026 •

Copy link
Copy Markdown

What

Fix speculative decoding metrics for Agentic rollouts.

  • Preserve each committed generation's (session_id, generation_id) and its accepted, proposed, verify, and completion counters in exported samples.
  • Deduplicate a shared generation once per rollout batch before aggregating counters; keep equal-text requests and different sessions distinct.
  • Compute weighted spec/accept_rate and spec/tokens_per_verify from summed counters.
  • Report counter coverage while preserving the distinction between missing counters and explicit zero values.
  • Keep spec_accept_rate and spec_accept_length as arithmetic per-sample compatibility metrics.

Why

The previous implementation averaged per-sample acceptance rates and could count a shared generation node once for every exported trajectory. Missing backend fields could also become false zero values. The new metrics therefore use committed generation work and preserve legacy metric names and serialized data.

How

Agentic exports carry committed generation records through the session forest, TrainingFieldArtifact, and Sample JSON serialization. Rollout aggregation validates records, deduplicates (session_id, generation_id), sums known counters, computes ratios from complete counter pairs, omits a ratio only when its summed paired denominator is zero, and reports coverage for each counter pair. Discarded branches and uncommitted nodes are excluded. Legacy payloads retain known and unknown field state across JSON round trips and resumed generation.

The acceptance examples are covered directly:

  • (accepted, proposed) = (1, 2) and (9, 10) produce spec/accepted_total=10, spec/proposed_total=12, and spec/accept_rate=10/12 ≈ 83.33%.
  • For A→B and A→C, with A=(1,2,1,2), B=(9,10,2,11), and C=(2,4,1,3), four record occurrences become three unique generations; totals are (12,16,4,16), so spec/accept_rate=0.75 and spec/tokens_per_verify=4.

Testing

  • Previous targeted CPU regression at eeddb2f in the dependency-complete environment: 35 passed, 0 skipped. The covered command is:

    PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -m pytest -q \
      tests/utils/test_speculative_counts.py \
      tests/utils/test_speculative_metrics.py \
      tests/test_agentic_speculative_export.py \
      tests/distributed/ray/test_speculative_metrics_wiring.py \
      tests/engine/rollout/test_data_source.py
  • Latest targeted CPU regression at 70356c8: 38 passed, 2 skipped with the same five-file command. The two Ray rollout wiring tests skip because optional rollout deployment imports are unavailable in the local environment. The five new cases cover nested export/serialization/artifact isolation, duplicate generation IDs with conflicting counters or response states (both rejected without forest mutation), and idempotent identical generation commits without duplicate counts.

  • Real GPU evidence: an NVIDIA RTX A6000 Qwen3-0.6B NGRAM rollout at source revision cb38e75 produced six metadata records. The post-fix CPU replay of those records reproduced accepted/proposed=326/476, completion/verify=384/68, spec/accept_rate=0.6848739496, and spec/tokens_per_verify=5.6470588235; the non-speculative control emitted no spec/* metrics.

  • pre-commit run --all-files --show-diff-on-failure passes for 70356c8.

  • GitHub Actions at 5d92395: all eight checks passed — Python 3.10/3.11/3.12 tests and pre-commit, H20 unit tests on four GPUs, and GPU/NPU training integration (Qwen3-VL-4B-2xgpu, Qwen3-4B-4xgpu-async, and Qwen3-4B-4xnpu-async). These validations are complete; no further action is required for those runs. Task5-specific A6000 inference was collected at cb38e75; later metric fixes were checked by CPU replay.

The Task5 validation JSON was removed in 059e5e3 in response to maintainer feedback; validation evidence is retained in this PR description. The latest commit, 70356c8, adds only regression tests for the remaining export-isolation and forest-conflict coverage gaps identified by the review. Production code is unchanged from the validated 5d92395. The eight successful GitHub checks above are historical results for 5d92395; CI/GPU/integration results for 70356c8 are not yet confirmed.

Compatibility

spec/accept_rate and spec/tokens_per_verify are weighted batch metrics over deduplicated generation records. spec_accept_rate and spec_accept_length retain arithmetic per-sample averages when every sample has the required complete positive-denominator pair. Missing ratios are omitted, while an explicit zero numerator can produce a real 0%. Completion-only ordinary samples do not emit spec/* metrics.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Refactoring
  • Performance improvement
  • CI/CD or build changes

Reference

Task 5 requirements

@Pinoeer-kingxi

Copy link
Copy Markdown
Author

@rai-studio-bot review

@rai-studio-bot

rai-studio-bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Nyanpasu 审查看板

审查状态: ✅ 已通过

审查版本: 70356c8

目标分支: main

70356c8 轮复核完成并已提交 APPROVE:本提交仅新增 5 个回归用例(+77 行),生产代码与已批准的 5d92395 逐字节一致;连同 059e5e3 的验收 JSON 删除一并确认(维护者要求,删除完整、零残留引用)。新用例闭合了前轮审计标注的两个次要缺口(导出/序列化/artifact 嵌套计数隔离、森林冲突 ValueError),本机 40 项全部通过,6 个定向变异均被检出,检出能力经变异验证。三项历史发现保持修复状态,无新发现。当前 head 无失败 CI 检查(八项测试检查最近一次绿于 5d92395,PR 描述已如实披露待重跑)。

审查阶段进度范围与结果
常规审查 ✅ 已完成 增量复核 059e5e3 → 70356c8 完成:+77 行仅测试文件;生产代码与前轮逐字节一致(git diff 空);40 项测试本机全通过(作者环境 38+2 跳过,口径一致);PR 描述 Testing 更新逐项核对无误。无新发现。
深度审查 ✅ 已完成 测试必要性审计已更新:5 个新用例全部保留(各自覆盖独立边界——森林导出隔离、序列化/artifact 隔离、冲突拒绝×两种触发维度含森林不可变、幂等提交),复用既有 helper 无新增脚手架,与既有用例无重复。检出能力经 6 个定向变异验证(共享记录缓存、to_dict/from_dict 别名、移除冲突检查、冲突部分写入、删除幂等守卫均被对应用例捕获),前轮审计标注的 M8/M15 次要缺口已闭合。生产必要性沿用前轮结论(文件未变)。

审查发现

待处理
编号 严重性 问题状态规则来源
暂无待处理的记录。
已解决或已取代
编号 严重性 问题状态规则来源
F1 Medium severity 非 speculative 训练也会输出 spec/* 指标(has_data 探测含 completion) ✅ 已解决 —
F2 Medium severity 指标接线缺少回归测试(移除委托后全部测试仍绿) ✅ 已解决 —
F3 Low severity 合并重复的集成测试场景(D1 并入导出测试)
精简建议(非阻塞)
✅ 已解决 —
提交范围 · 接收 14 · 建议移出 0 · 待确认 0

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

文件结论仓库维护必要性依据替代去向或方案
relax/utils/speculative.py
relax/utils/types.py
接收 计数归一化与 Sample 序列化兼容;单权威计数状态(known_counts 访问器)。责任与前轮(5d92395 全量审查)相同,生产文件本轮逐字节未变。 PR 描述;调用方 update_from_meta_info 与 Sample.to_dict/from_dict。 外部实验无法改变序列化语义。
relax/utils/metrics/speculative_metrics.py
relax/distributed/ray/rollout.py
relax/engine/rollout/data_source.py
接收 批内去重、完整计数对比率、spec 专有字段门控与可用性感知别名口径;单遍聚合接入统一日志入口。 PR 描述;调用方 compute_metrics_from_samples。 门控缺失会产生非 speculative 指标噪音(已在 48b66a5 修复并验证)。
relax/agentic/session/service.py
relax/agentic/session/state.py
接收 SessionForest 提交生成标识并在 AgenticSessionShard 累计规范化计数;去重所需输入。本轮新增的导出隔离与冲突测试即针对该层契约。 PR 描述;_terminal_response_locked → append_resp、build_sample。 没有现成机制记录共享前缀导出的每生成标识。
tests/utils/test_speculative_counts.py
tests/utils/test_speculative_metrics.py
tests/test_agentic_speculative_export.py
tests/distributed/ray/test_speculative_metrics_wiring.py
tests/engine/rollout/test_data_source.py
接收 CPU 回归测试覆盖真实生产路径。70356c8 在导出测试中新增 5 个用例(嵌套计数/列表跨森林导出、Sample 序列化与训练 artifact 的隔离;冲突计数/响应状态的重复生成 ID 拒绝且不改动已提交森林;幂等重复提交不重复计数),对应前轮审计标注的两个次要缺口 M8/M15。 PR 描述(Testing 最新一段);测试直接导入 relax 生产模块。 仅 GPU 端到端无法作为 CI 回归覆盖。
docs/en/guide/agentic-rollout.md
docs/zh/guide/agentic-rollout.md
接收 用户文档记录 spec/* 指标口径(单行段落,纯格式变更已在前轮逐词验证)。验收报告 JSON 已按维护者意见在 059e5e3 从树中删除,验证仅保留于 PR 描述。 维护者评审(SigureMo:"这个也不要放进来");PR 描述 Testing 一节。 验收证据保留在 PR 描述/外部存档(现状),不放仓库树内。
精简审查与验证依据
审查范围进度结论
生产代码 ✅ 已完成 生产代码必要性审计沿用前轮结论(文件逐字节一致,责任不变);本轮新增 remove 决策:验收 JSON 按维护者意见移出仓库并验证无残留引用。
测试 ✅ 已完成 测试必要性审计已随 70356c8 更新:新增 5 个用例全部保留——独立边界、变异验证的检出能力、无重复与新增脚手架;此前 6 个测试族的审计结论不变。

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

范围必须保留的契约更简单的方案结论依据与限制
relax/utils/speculative.py 计数模型与别名解析(SpeculativeCounts/SpeculativeGeneration) 显式 0 与缺失/非法值区分;三类别名族解析(整对优先);序列化往返。调用方:types.py、service.py、state.py、speculative_metrics.py。 types.py 内联解析或哨兵值(独立参考设计已排除);无记录的样本聚合比无法去重(实测 0.5846 vs 去重 oracle 0.575)。 保留 独立设计参考从相同需求推导出等价解析层;4 个生产模块共享。局限:SGLang 字段可用性依赖覆盖率指标在生产侧观测。
SessionForest 生成标识机制(committed_generations、generation_ids_by_state、untracked_generation_states 及冲突 ValueError) 批内每个已提交后端生成恰好计一次;跨 session 不混淆;abort/重试单次提交累计。调用方:_terminal_response_locked → append_resp;build_sample。 导出时派生 (session_id, state_hash) 标识:无需新增状态与冲突守卫,但内容相同的两个后端生成会被合并计数。 保留 request_id 标识分开计数内容寻址合并的生成(测试固定该行为),更忠实于后端 verify 工作量;两种设计均满足需求。
SpecInfo 双轨记录(旧整数合计 + counts 可用性计数) 旧指标名保持 base 算术平均口径;新指标保持缺失/0 区分。 由 counts 派生旧整数或删除旧整数(分别丢失可用性区分与旧名兼容)。 保留 参考设计得出相同结论;48b66a5 后旧整数仅作兼容口径与门控触发,语义一致。
compute_speculative_log_metrics 输出门控(48b66a5 起 has_speculative_fields) 未启用投机解码且无 spec 专有计数时不输出 spec/* 指标。调用方:_compute_spec_metrics 唯一日志入口。 (审计建议的替换方案)保持 base 开关门控或仅探测 spec 专有字段。 替换 替换已在 48b66a5 实施并验证:原复现用例返回 {},completion 从探测与 legacy 触发中移除,恒真的 agentic 子句删除;speculative 批次与旧 dump 行为不变(本机 5 个场景复验);文档同步。
验收报告文件 docs/public/validation/task5-speculative-metrics.json(前轮保留于树中,本轮移除) PR 描述保留验收证据(Testing 一节含 A6000 复放数据与 CI 运行链接);仓库树不维护一次性任务验证 JSON。 保留 JSON 在树中并由 PR 描述引用(前轮状态)——维护者已明确否决("这个也不要放进来")。 删除 059e5e3 删除全部 342 行,docs/public/validation/ 目录同步消失;git grep 全树与 docs 配置零残留引用;PR 描述无该路径链接。已对照 5d92395 验证为纯删除。

测试的必要性与替代方案

范围必须保留的契约更简单的方案结论依据与限制
tests/utils/test_speculative_counts.py(6 个测试) 计数归一化、别名族(含整对优先)、plus()、SpecInfo 序列化与旧数据识别、无开关累计。 无更小替代:已最小化。 保留 M2/M5/M12/M17 首检者;唯一执行真实 update_from_meta_info 的测试族。
tests/utils/test_speculative_metrics.py(11 个测试,48b66a5 增补) 批聚合:去重、session 隔离、覆盖率、比率抑制、旧别名、门控(新增 completion-only 与 enabled 语义)、冲突排除(新增)。 审计建议的 strengthen 已执行;无缩小空间。 保留 检出 M1/M2/M3/M3b/M7/M9(新增冲突测试);新增门控测试固定 F1 修复。
tests/test_agentic_speculative_export.py(4 个测试,48b66a5 吸收 D1 断言) 森林导出生成标识:分支成员、丢弃分支排除、request/session 区分、未跟踪节点保守性、artifact+JSON 往返、record_occurrence_count 与 tokens_per_verify。 无:合并后为唯一场景副本。 保留 检出 M1/M4/M7;D1 独有断言已并入并通过。
tests/integration/test_agentic_speculative_metrics.py::test_cpu_metadata_accumulation_reaches_committed_generation 服务累计边界:_accumulate_request_meta 别名解析 → pending_spec_counts → 森林 → 指标。 无:服务侧别名解析回退变异(M6)的唯一检者。 保留 检出 M6;D1 删除后本文件职责单一。
tests/integration/test_agentic_speculative_metrics.py::test_cpu_agentic_export_report(已删除) 与导出测试 C1 相同场景的重复副本。 删除并将独有断言并入 C1。 合并 合并已在 48b66a5 执行:D1 删除、record_occurrence_count==4 与 tokens_per_verify==16/4 并入 C1,测试通过。
tests/distributed/ray/test_speculative_metrics_wiring.py(48b66a5 新增,2 个测试)+ tests/engine/rollout/test_data_source.py 增补(1 个测试) 日志接线:真实 _compute_spec_metrics 入口输出加权指标、禁用批次返回 {};浅拷贝重置 spec_generations。 无:此前移除委托的变异(M10)与浅拷贝重置(M11)无任何覆盖。 保留 按 F2 建议新增,沿用 tests/distributed/ray 的 HAS_DEPS 条件导入模式;断言逐条核对,本环境按设计跳过、依赖完整环境可运行。
tests/test_agentic_speculative_export.py 新增 5 个用例(70356c8:导出隔离、序列化/artifact 隔离、冲突拒绝×2、幂等提交) 每次导出产生独立嵌套计数(跨森林/样本/序列化/artifact);冲突生成 ID 在改动森林前拒绝(计数与状态两种触发维度均覆盖);相同重复提交不重复计数。 合并为单一隔离测试会丢失故障定位维度(哪个隔离层被破坏);仅测一种冲突触发会漏另一等价维度。 保留 6 个定向变异全部被对应用例捕获(A 共享缓存→用例1;B/C 序列化别名→用例2;D 移除冲突检查、E 冲突部分写入→用例3 两参数;F 删除幂等守卫→用例4);本机 40 项全通过;复用既有 _forest/_response helper。
Powered by Nyanpasu with glm-5.3[1m] xhigh, please check the suggestions carefully.

@Pinoeer-kingxi
Pinoeer-kingxi force-pushed the fix/task5-speculative-metrics branch from 01b3d27 to 1b11590 Compare September 29, 2026 16:13
@Pinoeer-kingxi
Pinoeer-kingxi force-pushed the fix/task5-speculative-metrics branch from 1b11590 to d54bc50 Compare September 29, 2026 16:28

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

审查结论:无阻塞问题,3 条非阻塞建议

完整审查在 01b3d27 上进行(含独立设计参考与测试审计两个深度证据源),并在 rebase 后的当前 head d54bc50 上复核:relax/utils/metrics/speculative_metrics.py 与前次逐字节一致,20 个新增测试本机全部通过,新增的别名整对优先逻辑、文档口径与 append_resp 重排后的等价性均已核对。核心设计(样本级生成记录 + 批内去重 + 计数可用性区分 + 旧名兼容)与从相同需求独立推导的最小设计一致,未发现多余机制;去重正确性、abort/重试下的单次提交、跨 session 隔离与旧序列化兼容均有验证。3 条非阻塞建议见行内评论,汇总与验证依据见看板。

看板:#391 (comment)

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

Comment on lines +136 to +140
has_data |= any(
counts is not None
and any(value is not None for value in (counts.accepted, counts.proposed, counts.verify, counts.completion))
for counts in sample_counts
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Medium severity P2 · 非 speculative 训练也会输出 spec/ 指标*

has_data 探测把 counts.completion 也当作 speculative 数据,而 completion_tokens 是 SGLang 每条响应 meta_info 的常规字段(与是否开启投机解码无关,见 relax/utils/speculative.py:58 的提取)。结果是 update_from_meta_info 改为无条件累计后,任何非 speculative 的 colocate 批次都会满足 has_data,从而输出约 25 个 spec/* 指标键(spec/sample/completion_total、spec/sample/accept_count_coverage=0.0 等);旧实现在 sglang_speculative_algorithm is None 时返回 {}(见被替换的 relax/distributed/ray/rollout.py _compute_spec_metrics)。对未启用投机解码的用户,这是日志与看板面板的指标噪音,PR 描述与文档也只在这些指标属于投机解码的前提下描述它们。

本机用 head 代码验证:3 个样本、meta_info 仅含 {"completion_tokens": 5, "prompt_tokens": 10, "finish_reason": "stop"}、enabled=False 时,输出 25 个键,其中 spec/sample/completion_total = 15。

建议从探测条件中去掉 completion,只看投机解码特有的字段(accepted / proposed / verify):

Suggested change
has_data |= any(
counts is not None
and any(value is not None for value in (counts.accepted, counts.proposed, counts.verify, counts.completion))
for counts in sample_counts
)
has_data |= any(
counts is not None
and any(value is not None for value in (counts.accepted, counts.proposed, counts.verify))
for counts in sample_counts
)

这样投机解码批次不受影响(enabled=True 本来就会输出;有 spec 字段时探测也为真),非 speculative colocate 批次恢复旧行为。

另外一个相关问题请确认意图:非 speculative 的 agentic 批次因首个条件 spec_generations is not None(新导出恒成立)同样会输出 spec/* 指标(unique_generation_count、record_occurrence_count 等生成计数与投机解码无关)。如果这是有意保留的诊断信息,建议在文档中说明这些指标在未开启投机解码时也会出现;否则同样可以按「记录中存在任一 spec 专有字段」来收紧。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

已确认修复(commit 48b66a5):has_data 探测重写为 has_speculative_fields,仅检查 accepted / proposed / verify;completion_token_num 已从 legacy 正数触发条件移除;原先恒为真的 spec_generations is not None / agentic_trace 子句也一并删除,因此非 speculative 的 agentic 批次同样不再输出——与我评论中询问的第二点一致。

本机在 48b66a5 上复验:原复现用例(3 个仅含 completion_tokens 的样本、enabled=False)现返回 {};含 spec 字段的 colocate 与 agentic 批次仍正常输出(accept_rate、legacy 别名不变);旧序列化样本(9/10/2/11)仍产出 spec_accept_rate=0.9、spec_accept_length=5.5。新增 test_completion_only_metadata_does_not_enable_speculative_logging 与 test_enabled_speculative_logging_can_report_unknown_counters 固定门控行为,中英文文档已补充说明。

Comment on lines 4940 to +4944
def _compute_spec_metrics(args, all_samples: list[Sample]):
if getattr(args, "sglang_speculative_algorithm", None) is None:
return {}
num_samples = len(all_samples)
metrics = {}
metrics["spec_accept_rate"] = sum(sample.spec_info.spec_accept_rate for sample in all_samples) / num_samples
metrics["spec_accept_length"] = sum(sample.spec_info.spec_accept_length for sample in all_samples) / num_samples
return metrics
return compute_speculative_log_metrics(
all_samples,
enabled=getattr(args, "sglang_speculative_algorithm", None) is not None,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Medium severity P2 · 指标接线缺少回归测试

本 PR 的用户可见行为(rollout 日志中的 spec/* 指标)没有接线级测试保护。在本 head 副本上把 _compute_spec_metrics 改为 return {} 后,全部 20 个新增测试以及可运行的既有相关测试依然全绿(本机实际运行验证);全仓也没有任何用例经由 compute_metrics_from_samples / _compute_spec_metrics 断言 spec/* 键(tests/utils/test_repetition_integration.py 调用了该入口但只断言重复度指标)。也就是说,未来一次重构若悄悄删掉这几行委托,指标会整体静默消失且 CI 不会被察觉。

建议补一个直接断言加权指标从日志入口产出的小型测试(可放在 tests/distributed/ray/ 下,沿用该目录 conftest 的 HAS_DEPS 条件导入模式,缺依赖时跳过):

def test_compute_spec_metrics_emits_weighted_spec_metrics():
    args = SimpleNamespace(sglang_speculative_algorithm="ngram")
    samples = [
        _sample(_record("a", SpeculativeCounts(1, 2, 1, 2)), _record("b", SpeculativeCounts(9, 10, 2, 11))),
        _sample(_record("a", SpeculativeCounts(1, 2, 1, 2))),  # 共享 generation "a"
    ]
    metrics = _compute_spec_metrics(args, samples)
    assert metrics["spec/unique_generation_count"] == 2
    assert metrics["spec/accept_rate"] == 10 / 12

(_sample / _record 可复用 tests/utils/test_speculative_metrics.py 的构造方式。)

同类缺口同属本 PR 新增行为、均无覆盖,可一并补:

  • relax/engine/rollout/data_source.py 中 new.spec_generations = None 的重置:回归会让浅拷贝样本携带模板样本的旧生成记录,重采样时重复计数(适合放 tests/engine/rollout/test_data_source.py)。
  • 冲突语义(spec/conflicting_generation_count 的排除与旧别名抑制)和 enabled / has_data 门控行为。

说明:接线测试在本评审的纯 CPU 环境因 relax/distributed/ray/rollout.py 模块级的 sglang / transfer_queue 依赖无法端到端运行;上述变异实验与全仓检索均在本 head 副本上完成,测试草案在依赖可用的环境下可直接运行。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

已确认修复(commit 48b66a5):新增 tests/distributed/ray/test_speculative_metrics_wiring.py,沿用该目录的 HAS_DEPS 条件导入模式,在真实 _compute_spec_metrics 入口断言加权指标(spec/unique_generation_count == 2、spec/accept_rate == 10/12)与禁用批次返回 {};tests/engine/rollout/test_data_source.py::test_shallow_copy_drops_generation_export_state 覆盖浅拷贝重置;tests/utils/test_speculative_metrics.py::test_conflicting_generation_is_excluded_from_ratios_and_aliases 覆盖冲突排除语义。

本机复验:相关测试通过(接线测试在本环境因 rollout 模块级依赖缺失按设计跳过,其断言已逐条核对);此前「移除 _compute_spec_metrics 委托后全部测试仍绿」的变异现在会被接线测试以 KeyError 检出。

return "".join(chr(token) for token in tokens)


def test_cpu_agentic_export_report() -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Low severity P3 · 精简建议(非阻塞):合并重复的集成场景

test_cpu_agentic_export_report 与 tests/test_agentic_speculative_export.py::test_export_tracks_committed_branch_nodes_and_excludes_discarded_branch 是同一场景的两份副本:相同的 A/B/C 计数 (1,2,1,2) / (9,10,2,11) / (2,4,1,3)、相同的 A→B / A→C 树形和共享节点、相同的 12/16 断言,且二者都不经过 service 层——本文件真正的集成边界是 test_cpu_metadata_accumulation_reaches_committed_generation(覆盖 _accumulate_request_meta → 森林 → 指标的链路)。

本轮测试审计做过删除实验:移除本测试后,两类关键变异(dedup key 改为逐次唯一、session_id 从 key 中移除)仍被其余测试检出,检出力不降;本测试独有的两条断言 record_occurrence_count == 4 与 spec/tokens_per_verify == 16 / 4 各一行即可并入导出测试。建议删除本测试、把这两条断言并入 C1,少维护一份场景副本——本次 rebase 中两份副本已各自同步改过一遍(token_delta 改名),后续 append_resp 签名再变化时也要改两处。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

已确认(commit 48b66a5):test_cpu_agentic_export_report 已删除,其独有断言 record_occurrence_count == 4 与 spec/tokens_per_verify == 16/4 已并入 tests/test_agentic_speculative_export.py 的导出测试;集成文件现仅保留真正的服务边界测试 test_cpu_metadata_accumulation_reaches_committed_generation。

本机复验:4 个测试文件 22 通过 + 2 跳过(接线测试在本环境因依赖缺失跳过),导出测试含吸收后的断言全部通过。

@Pinoeer-kingxi Pinoeer-kingxi changed the title fix(agentic): aggregate speculative decoding metrics 【No.5】fix(agentic): aggregate speculative decoding metrics Sep 30, 2026

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

审查结论:通过

前一轮的三条建议已在 48b66a5 全部修复并逐项验证:门控收紧为仅投机专有字段(原复现用例现返回 {},speculative 批次与旧序列化样本行为不变);新增日志接线、门控、冲突与浅拷贝测试;重复的集成场景已合并进导出测试。本轮增量 diff 已全量审阅,未发现新问题;本机复跑相关测试 22 通过 + 2 项按设计跳过(接线测试在缺依赖环境跳过,断言已核对)。汇总与验证依据见看板。

一个非阻塞小提醒:PR 描述的 Testing 一节仍写「20 passed(4 个文件)」,当前 head 相应文件已有 22 个测试,另有接线与 data_source 测试,方便的话可顺手更新。

看板:#391 (comment)

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

# 🐛 Bug Fix

- Compute acceptance and verification ratios only from generations with both counters available.
- Keep every known counter in diagnostic totals without synthesizing ratios from unrelated records.

---

# ✅ Tests

- Cover disjoint and mixed counter availability in the existing aggregation regression.
- Exercise service metadata accumulation in the shared forest export fixture and remove its duplicate integration scene.
- Merge the legacy identity fallback into the content-addressed export regression.
- Verify 25 core tests, 2 rollout wiring tests, and 60 related regression tests.
- Confirm the consolidated export tests still detect service parser and untracked-node regressions.

---

# 📝 Documentation

- Document complete-pair ratio semantics and independent counter totals in the English and Chinese Agentic guides.
- Pass pre-commit checks across all tracked files before committing.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

审查结论:通过

cb38e75 增量已复核:比率口径改为仅使用分子分母均完整的计数对——修正了未配对计数混入导致接受率可能超过 100% 的缺陷(本机构造未配对记录验证:旧口径 8/6≈1.33,新口径按完整对 3/6=0.5,覆盖率如实报告 0.5),totals 仍保留全部已知值,文档两处口径同步;服务累计边界并入导出测试(_response 助手经真实 _accumulate_request_meta 累计,原集成文件删除后检出力保持);未跟踪节点断言合并进保留用例。三项历史发现(F1 门控、F2 接线测试、F3 测试合并)在本 head 均保持修复状态。本机复跑相关测试 21 通过 + 2 项按设计跳过(接线测试在缺依赖环境跳过)。汇总与验证依据见看板。

看板:#391 (comment)

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

# 🐛 Bug Fix

- Preserve legacy counter field presence through Sample serialization and resumed generation.
- Require known counter pairs before emitting compatibility ratios, preserving explicit zero and new pending-sample classification.
- Reuse parsed metadata counters when updating legacy numeric totals.

---

# ✅ Tests

- Extend the existing legacy regression to cover deleted fields, null values, explicit zero, zero denominators and repeated JSON roundtrips.
- Aggregate CPU integration metrics after artifact and JSON restoration.
- Targeted CPU suite: 34 passed, no skips. Saved real GPU metadata replays match speculative and non-speculative results.

---

# 📝 Documentation

- Explain compatibility and missing-counter semantics in both Agentic guides.
- Include the Task5 acceptance report with manually checkable input/output cases and GPU evidence provenance.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

审查结论:通过

e7ed28e 增量已复核:旧序列化数据的缺失字段不再被补成 0——legacy_field_counts 在反序列化、重复 JSON 往返与继续生成时保留已知/未知计数状态,兼容比率改用可用性感知的数值对(本机验证:缺失 accepted 的旧 payload 此前会伪造 spec_accept_rate=0.0,现在按可用性省略该比率,显式 0 仍产出真实的 0%,状态经 3 次往返保持不变;8 场景参数化矩阵测试覆盖)。导出测试改为在 TrainingFieldArtifact + JSON 序列化恢复后的样本上断言指标,捕获序列化丢失。验证记录 docs/public/validation/task5-speculative-metrics.json 沿用 docs/public 既有数据工件惯例并被双语指南链接,GPU 证据为修复前 head 采集 + 修复后 CPU 回放,披露如实。三项历史发现保持修复状态;本机复跑 28 通过 + 2 项按设计跳过。汇总与验证依据见看板。

看板:#391 (comment)

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

# ♻️ Refactor

- Keep one normalized counter snapshot for new samples and preserve
  unknown fields when resuming legacy data.
- Decode committed generation records once for batch and sample metrics.
- Use normalized verify/completion values in metadata accumulation.

---

# ✅ Tests

- Extend existing roundtrip and ratio tests for mixed new/legacy batches.
- Check negative and nonnumeric backend counters at metadata accumulation.
- Targeted CPU regressions: 35 passed. Saved GPU metadata replay matches
  both speculative and non-speculative results. All pre-commit checks pass.

---

# 📝 Documentation

- Update compatibility notes and the checkable Task5 acceptance report.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

审查结论:通过

eeddb2f 增量已复核:计数状态统一为单一权威来源——_aggregate 单遍解析生成记录并同时产出指标、样本计数对与门控信号(消除了首审指出的双遍解析);known_counts 统一兼容口径访问器,新样本 add 后清除兼容快照(消除双份序列化);服务层 verify/completion 复用同一份规范化计数;混合批次别名的纯度限制被移除,可用性感知的样本对使新旧混合批次可证明(本机验证混合批 spec_accept_rate=0.7、spec_accept_length=3.75,与手算逐样本比率一致),文档与验证记录同步更新。三项历史发现(F1 门控、F2 接线测试、F3 测试合并)保持修复状态,F1 门控经回归复验。本机复跑 29 通过 + 2 项按设计跳过。汇总与验证依据见看板。

看板:#391 (comment)

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

Comment thread docs/zh/guide/agentic-rollout.md Outdated
- Output metadata 的顶层 numeric field 使用 `<field>/mean|median|max|min`,不带 `rollout/` 前缀。
- Rollout dump 保留完整 metadata。

Agentic 导出还会保留每个已提交生成节点的 ID 及

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.

markdown 里不需要换行

Comment thread docs/zh/guide/agentic-rollout.md Outdated
生成节点,汇总为 `(accepted, proposed, verify, completion)=(12,16,4,16)`,
所以 `spec/accept_rate=0.75`、`spec/tokens_per_verify=4`。

[Task5 验收结果报告](/Relax/validation/task5-speculative-metrics.json)记录了可人工核对的

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 这你 review 不出来???

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

这两点确实应当由我先指出,是我的疏漏:换行风格与仓库文档既有的单行长段落排版不一致,验收报告段落服务的是本 PR 的验收记录而不是文档读者——我在审查中把重心放在指标正确性与必要性上,没有把文档风格与内容海拔问题报出来。

已复核 5d92395:两份指南均已重排为单行段落(英文内容逐字一致,中文仅代码 span 周围因换行产生的空白差异),验收报告段落已从中英文指南移除;docs/public/validation/task5-speculative-metrics.json 仍保留在树中、仅由 PR 描述引用——若评审认为它也不宜入库(只留 PR 引用或外部存档),删掉该文件即可,我这边没有发现其它引用。

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

审查结论:通过

5d92395 增量已复核:维护者评审提出的两点均已处理——两份指南重排为单行段落(经逐词比对确认为纯格式变更,英文内容逐字一致)、验收报告段落已从中英文指南移除(docs/public/validation/task5-speculative-metrics.json 保留在树中、由 PR 描述引用,回复中已向维护者说明可按需删除)。生产代码与测试无变化,三项历史发现保持修复状态。汇总与验证依据见看板。

看板:#391 (comment)

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

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.

这个也不要放进来

@SigureMo

SigureMo commented Oct 4, 2026

Copy link
Copy Markdown
Member

以及如果完成了,记得按照流程「提交」

@Pinoeer-kingxi

Copy link
Copy Markdown
Author

以及如果完成了,记得按照流程「提交」

您好,@SigureMo 请问是提交什么?

@SigureMo

SigureMo commented Oct 4, 2026

Copy link
Copy Markdown
Member

在 PR 下通过 comment 发送「@SigureMo 任务已完成,请求 review。」以请求研发导师进行人工 Review。

PR 里跟我直接说就好

# ✅ Tests

## Protect speculative generation export boundaries

- Verify nested counters and lists remain isolated across forest exports,
  Sample serialization and training artifacts.
- Reject duplicate generation IDs with conflicting counters or response
  states without mutating the committed forest.
- Preserve idempotent identical generation commits without duplicate counts.
- Validate 38 CPU cases; two rollout wiring tests skip because optional
  deployment dependencies are unavailable. All pre-commit hooks pass.
@Pinoeer-kingxi

Copy link
Copy Markdown
Author

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

审查结论:通过

70356c8 增量已验证:本提交仅新增 5 个回归用例(+77 行,tests/test_agentic_speculative_export.py),生产代码与已批准的 5d92395 逐字节一致;上轮因 head 推进未发布的 059e5e3 验收 JSON 删除(维护者要求)一并确认——342 行全删、无任何残留引用。新增用例针对前轮审计标注的两个次要缺口:嵌套计数在森林导出 / Sample 序列化 / 训练 artifact 间的隔离,以及森林冲突 ValueError;本机运行相关 40 项全部通过,6 个定向变异(导出共享缓存、序列化别名 ×2、移除冲突检查、冲突部分写入、删除幂等守卫)均被对应用例检出。三项历史发现保持修复状态,未发现新问题。

看板:#391 (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