Prhub

#25940 [SPEC] feat: add adaptive speculative decoding metrics

原始 PR 作者 alphabetc1 合并时间 2026-06-02 04:53 文件变更 4 提交数 6 评论 8 代码增减 +92 / -0

执行摘要

为自适应推测解码添加 Prometheus 指标

自适应推测解码在运行时根据当前负载动态调整推测步数和草稿 token 数,但此前缺乏对应的监控指标,用户无法直观了解当前使用的推测配置。PR body 明确说明目标为「add metrics for adaptive speculative decoding」。

该 PR 设计简洁清晰,适合作为如何为动态配置添加可观测性的参考。推荐在以下场景精读:需要为自适应或动态调整的参数添加指标暴露时;理解 metrics_reporterMetricsCollector 如何协作时。

讨论亮点

reviewer Qiaolin-Yu 提出 nit:使用 current_scheduler_metrics_enabled 替代 enable_metrics 条件判断更合适。作者 alphabetc1 回复 'good idea, updated'。最终代码采用了 current_scheduler_metrics_enabled,确保只在开启 metrics 时才执行 snapshot 抓取,避免无谓开销。

实现拆解

  1. metrics_reporter.py 中添加 _active_spec_config_snapshot() 方法,通过 draft_worker 对象获取当前活跃的 speculative_num_stepsspeculative_num_draft_tokens;若 draft_workerNone 则返回 0。
  2. report_decode_stats() 中,当 current_scheduler_metrics_enabled 为真时调用 snapshot,将结果写入 self.statsSchedulerStats 实例)。
  3. SchedulerStats dataclass 中新增 spec_num_steps: int = 0spec_num_draft_tokens: int = 0 字段,用于承载指标值。
  4. MetricsCollector__init__ 中创建 sglang:spec_num_stepssglang:spec_num_draft_tokens 两个 Gauge,并在 log_stats() 中推送数值。
  5. test_adaptive_speculative.py 中新增 test_adaptive_metrics_exposed 测试,启动服务器时添加 --enable-metrics,驱动自适应 upshift 后通过 /metrics 端点 scrape 新指标并断言值正确。
  6. production_metrics.mdx 中补充两个新指标的输出示例。
文件 模块 状态 重要度
python/sglang/srt/managers/scheduler_components/metrics_reporter.py 调度器 modified 7.22
test/registered/spec/eagle/test_adaptive_speculative.py 推测测试 modified 5.7
python/sglang/srt/observability/metrics_collector.py 可观测性 modified 5.52
docs_new/docs/references/production_metrics.mdx 文档 modified 2.61

关键符号

_active_spec_config_snapshot report_decode_stats log_stats _scrape_metric test_adaptive_metrics_exposed

关键源码片段

python/sglang/srt/managers/scheduler_components/metrics_reporter.py core-logic

核心实现文件,新增 `_active_spec_config_snapshot` 方法并在 `report_decode_stats` 中调用,完成配置读取与统计注入。

def _active_spec_config_snapshot(self) -> dict[str, int]:
    '''读取当前活跃的推测解码配置(步数和草稿 token 数)'''
    draft_worker = self.scheduler.draft_worker
    if draft_worker is None:
        return {'num_steps': 0, 'num_draft_tokens': 0}
    # 若 draft_worker 未直接暴露属性,则回退到 server_args
    server_args = self.scheduler.server_args
    num_steps = getattr(draft_worker, 'speculative_num_steps',
                        server_args.speculative_num_steps)
    num_draft_tokens = getattr(draft_worker, 'speculative_num_draft_tokens',
                               server_args.speculative_num_draft_tokens)
    return {'num_steps': num_steps or 0,
            'num_draft_tokens': num_draft_tokens or 0}# 在 report_decode_stats() 中:
if self.current_scheduler_metrics_enabled:
    spec_snapshot = self._active_spec_config_snapshot()
    spec_num_steps = spec_snapshot['num_steps']
    spec_num_draft_tokens = spec_snapshot['num_draft_tokens']# 随后赋值给 stats
self.stats.spec_num_steps = spec_num_steps
self.stats.spec_num_draft_tokens = spec_num_draft_tokens

评论区精华

使用 current_scheduler_metrics_enabled 替代 enable_metrics 设计

Qiaolin-Yu 在代码审核中建议,在 `report_decode_stats` 中检查指标是否启用的条件应使用 `current_scheduler_metrics_enabled` 而非 `enable_metrics`,以确保仅在 metrics 启用时才抓取 snapshot,避免不必要的开销。

结论:作者 alphabetc1 采纳建议,将条件从句改为 `current_scheduler_metrics_enabled`。 · 已解决

风险与影响

该 PR 新增的指标收集逻辑对核心推测解码路径无影响,风险较低。潜在风险:

  • _active_spec_config_snapshot 通过 getattr 回退到 server_args,保证了兼容性,但若 draft_worker 对象的属性名未来变化需同步更新。
  • 每次 decode 统计周期(由 decode_log_interval 控制)调用一次 snapshot,额外开销可忽略。
  • 指标通过 Prometheus 多进程模式暴露,需确保 multiprocess_mode='mostrecent' 在子进程中正确工作;现有架构已为此设计。

对用户:新增两个 Prometheus 指标,可监控自适应推测解码的当前 num_stepsnum_draft_tokens。对系统:无性能回归,仅增加极轻量的指标采集。对团队:新增的测试和文档降低了维护成本。影响范围限定于自适应推测解码场景。

新增 Prometheus 指标 依赖 draft_worker 动态属性

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论