执行摘要
- 一句话:新增 fwd_occupancy 指标并暴露到 Prometheus
- 推荐动作:值得快速合并。该 PR 改动量小、逻辑清晰,且补充了关键的可观测性指标。建议在合并后补充自动化测试,确保
/metrics 端点包含该指标。同时,后续可以考虑集成 GPU 硬件占用率作为补充。
功能与动机
为了增强 GPU 前向传递占用率的可观测性,让运维和性能分析人员能够通过 /metrics 端点获取 sglang:fwd_occupancy 数值,从而更好地了解 GPU 利用情况。
实现拆解
- SchedulerStats 数据类增加字段(python/sglang/srt/observability/metrics_collector.py):在
SchedulerStats 数据类中,于 utilization 字段之后新增 fwd_occupancy: float = float("nan")。该字段默认为 NaN,表示未启用或尚未有数据。
- Prometheus Gauge 注册(python/sglang/srt/observability/metrics_collector.py):在
SchedulerMetricsCollector.__init__ 中,在 utilization Gauge 之后添加一个名为 sglang:fwd_occupancy 的 Gauge,标签与其它指标保持一致,文档说明为“Forward pass GPU occupancy percentage.”。
- 汇报逻辑集成(python/sglang/srt/observability/scheduler_metrics_mixin.py):在
report_prefill_stats 和 report_decode_stats 两个方法中,在 self.calculate_utilization() 之后将 self.fwd_occupancy 赋值给 self.stats.fwd_occupancy,确保指标在每次统计周期中被更新。
- 初始化位置调整:提交历史显示,第二个 commit 将
self.fwd_occupancy = float("nan") 从 ENABLE_METRICS_DEVICE_TIMER 条件块中移出,改为无条件初始化。这样即使 ENABLE_METRICS_DEVICE_TIMER 为 False,也能保证 fwd_occupancy 属性存在,避免访问时的 AttributeError。
- 指标收集:在
log_stats 方法中,通过 self._log_gauge(self.fwd_occupancy, stats.fwd_occupancy) 将数值推送给 Prometheus。
关键文件:
python/sglang/srt/observability/metrics_collector.py(模块 可观测性;类别 source;类型 core-logic;符号 SchedulerStats, SchedulerMetricsCollector): 在此文件中,SchedulerStats 数据类新增了 fwd_occupancy 字段,SchedulerMetricsCollector 注册了对应的 Prometheus Gauge,并在 log_stats 方法中添加了指标收集逻辑。
python/sglang/srt/observability/scheduler_metrics_mixin.py(模块 可观测性;类别 source;类型 core-logic;符号 init_metrics, report_prefill_stats, report_decode_stats): 在此文件中,fwd_occupancy 属性的初始化从条件块中移出变为无条件,并在 report_prefill_stats 和 report_decode_stats 方法中将该字段赋值给 stats 对象,确保指标在每次统计周期中被更新。
关键符号:init_metrics, report_prefill_stats, report_decode_stats, log_stats
关键源码片段
python/sglang/srt/observability/metrics_collector.py
在此文件中,SchedulerStats 数据类新增了 fwd_occupancy 字段,SchedulerMetricsCollector 注册了对应的 Prometheus Gauge,并在 log_stats 方法中添加了指标收集逻辑。
# python/sglang/srt/observability/metrics_collector.py
@dataclass
class SchedulerStats:
...
# Utilization
utilization: float = 0.0
# 新增字段:Forward pass GPU occupancy percentage
fwd_occupancy: float = float("nan")
...
class SchedulerMetricsCollector:
def __init__(self, labels, ...):
...
# 注册 fwd_occupancy Gauge
self.fwd_occupancy = Gauge(
name="sglang:fwd_occupancy",
documentation="Forward pass GPU occupancy percentage.",
labelnames=labels.keys(),
multiprocess_mode="mostrecent",
)
...
def log_stats(self, stats: SchedulerStats) -> None:
...
# Utilization
self._log_gauge(self.utilization, stats.utilization)
# 新增:收集 fwd_occupancy 指标
self._log_gauge(self.fwd_occupancy, stats.fwd_occupancy)
...
python/sglang/srt/observability/scheduler_metrics_mixin.py
在此文件中,fwd_occupancy 属性的初始化从条件块中移出变为无条件,并在 report_prefill_stats 和 report_decode_stats 方法中将该字段赋值给 stats 对象,确保指标在每次统计周期中被更新。
# python/sglang/srt/observability/scheduler_metrics_mixin.py
class SchedulerMetricsMixin:
def init_metrics(self):
...
# 无条件初始化 fwd_occupancy,避免当 ENABLE_METRICS_DEVICE_TIMER 关闭时属性缺失
self.fwd_occupancy = float("nan")
if ENABLE_METRICS_DEVICE_TIMER:
# 原有的设备定时器相关初始化,不再包含 fwd_occupancy
...
...
def report_prefill_stats(self):
...
# 记录 fwd_occupancy
self.stats.fwd_occupancy = self.fwd_occupancy
...
def report_decode_stats(self):
...
# 记录 fwd_occupancy
self.stats.fwd_occupancy = self.fwd_occupancy
...
评论区精华
该 PR 没有 review 讨论。但提交历史中有一条重要调整:第二个 commit 将 fwd_occupancy 的初始化从 ENABLE_METRICS_DEVICE_TIMER 条件块中移出,改为无条件初始化。这一改动避免了当特性开关关闭时直接访问 self.fwd_occupancy 导致的属性缺失错误,体现了对运行健壮性的考量。
风险与影响
- 风险:
- 回归风险:低。新增字段默认值为 NaN,不影响现有逻辑。
- 性能风险:低。仅新增一个 Gauge 汇报,开销可忽略。
- 兼容性:无。指标为新增,不涉及已有字段或 API 变更。
- 缺失测试:PR body 列出了两个手动验证步骤,但无自动化测试覆盖。生产环境需注意
/metrics 端点的实际输出验证。
- 影响:
- 用户/运维:可以在 Prometheus 中查询
sglang:fwd_occupancy 指标,监控 GPU 前向占用率,提升可观测性。
- 系统:无影响。
- 团队:为后续的利用率分析和调度优化提供了数据基础。
- 风险标记:缺少测试覆盖
关联脉络
- PR #24396 [sgl] expose swa and mamba cache metrics: 同样是在 observability 模块中新增指标(SWA/Mamba 缓存容量),与本 PR 属于同一类可观测性增强工作。
参与讨论