Prhub

#26821 Add periodic KV-canary stats logging and kernel-run-counter health check

原始 PR 作者 fzyzcjy 合并时间 2026-05-31 10:00 文件变更 9 提交数 1 评论 3 代码增减 +304 / -0

执行摘要

增加 KV-canary 周期性统计日志与健康检查

PR说明中强调两个组件均为纯观察者(pure observers of CanaryDeviceState counters and the sweep orchestrator),不依赖其输出。目的是增加可观测性,特别是检测canary kernel wiring退化的静默故障。

该PR设计清晰,纯观察者模式值得学习;DelayedDeviceHostHandler的异步D2H拷贝模式可复用于其他需要获取设备状态但不阻塞前向的场景。阅读重点:health_checker.py中的延迟出队和增量计算逻辑。

讨论亮点

该PR没有人工review评论,仅包含自动tag-and-rerun-ci请求和Gemini quota警告,无实质性设计讨论。

实现拆解

  1. 新增KernelRunCounterHealthChecker(health_checker.py):构造时保存设备状态、活跃标签和步数获取器;step()方法通过DelayedDeviceHostHandler异步将设备上的kernel_run_counters拷贝到主机;在主机端计算增量,若某个标签计数器未增加则抛出RuntimeError。检查每100步执行一次,前100步为预热期。

  2. 新增PeriodicCanaryStatsLogger(stats_logger.py):step()时通过DelayedDeviceHostHandler读取设备上的slot_run_counters总和及violation_write_index,然后在主机端打印INFO日志,包含步数、受保护token数、清扫轮次、违规数和活跃标签占比。打印频率由CanaryConfig.stats_print_every_n_steps控制(环境变量SGLANG_KV_CANARY_STATS_PRINT_EVERY_N_STEPS,默认100,设为0关闭)。

  3. 集成配置:在CanaryConfig(config.py)新增stats_print_every_n_steps字段,在environ.py添加环境变量默认值100。

  4. 集成到CanaryManager(canary_manager.py):在__init__中构造两个对象,在_post_ops_outside_graph末尾依次调用_health_checker.step()_stats_logger.step()

  5. 测试配套:新增test/registered/kv_canary/test_self_unit_runner_health.py,覆盖健康检查的计数器停滞检测、忽略disable sweep时的清扫标签、以及统计日志的间隔打印;同时修改runner_test_base.pyfixtures.py以传递新配置参数。

文件 模块 状态 重要度
python/sglang/srt/kv_canary/runner/health_checker.py 健康检查 added 8.51
python/sglang/srt/kv_canary/runner/stats_logger.py 统计日志 added 8.15
test/registered/kv_canary/test_self_unit_runner_health.py 单元测试 added 7.25
python/sglang/srt/kv_canary/runner/canary_manager.py 管理器 modified 5.74
python/sglang/srt/kv_canary/config.py 配置 modified 4.67
python/sglang/srt/environ.py 环境变量 modified 4.35
python/sglang/test/kv_canary/runner_test_base.py 测试基础 modified 3.42
python/sglang/test/kv_canary/fixtures.py 测试 fixtures modified 3.28
test/registered/kv_canary/test_self_unit_buffer_alloc.py 缓冲区测试 modified 2.88

关键符号

KernelRunCounterHealthChecker.__init__ KernelRunCounterHealthChecker.step KernelRunCounterHealthChecker._compute_on_device KernelRunCounterHealthChecker._postprocess_on_host KernelRunCounterHealthChecker._expected_active_tags_for_health_check PeriodicCanaryStatsLogger.__init__ PeriodicCanaryStatsLogger.step PeriodicCanaryStatsLogger._compute_on_device PeriodicCanaryStatsLogger._postprocess_on_host TestSelfUnitManagerHealth.test_kernel_run_counter_watchdog_raises_on_zero TestSelfUnitManagerHealth.test_kernel_run_counter_watchdog_ignores_sweep_when_sweep_is_disabled TestSelfUnitManagerHealth.test_periodic_stats_log_every_n_step TestKernelRunCounterDeltaCheck.test_first_check_raises_when_counter_never_incremented

关键源码片段

python/sglang/srt/kv_canary/runner/stats_logger.py core-logic

核心新增:PeriodicCanaryStatsLogger 实现周期性统计日志,读取设备状态并打印到 INFO 日志。

from __future__ import annotationsimport logging
from collections.abc import Callable
from typing import Any, Optionalimport torchfrom sglang.jit_kernel.kv_canary.verify import CanaryLaunchTag
from sglang.srt.kv_canary.config import CanaryConfig
from sglang.srt.kv_canary.runner.future_tensor import DelayedDeviceHostHandler
from sglang.srt.kv_canary.runner.sweep import SweepOrchestrator
from sglang.srt.kv_canary.state import CanaryDeviceStatelogger = logging.getLogger(__name__)
​
​
class PeriodicCanaryStatsLogger:
    """
    周期统计日志器:每隔 N 步将 canary 的关键统计信息打印到日志(INFO 级别)。
    通过 DelayedDeviceHostHandler 异步读取设备状态,不阻塞前向。
    """
    def __init__(
        self,
        *,
        config: CanaryConfig,
        device_state: CanaryDeviceState,
        active_tags: tuple[CanaryLaunchTag, ...],
        outer_step_counter_getter: Callable[[], int],
        sweep_orchestrator: SweepOrchestrator, # 用于获取清扫轮次计数
        d2h_stream: torch.cuda.Stream,
    ) -> None:
        self._config = config
        self._device_state = device_state
        self._active_tags = active_tags
        self._outer_step_counter_getter = outer_step_counter_getter
        self._sweep_orchestrator = sweep_orchestrator
        # 异步 D2H 处理器
        self._handler = DelayedDeviceHostHandler(d2h_stream=d2h_stream)
​
    def step(self) -> None:
        """每步调用:提交异步读取请求"""
        self._handler.step(
            compute_on_device=self._compute_on_device,
            postprocess_on_host=self._postprocess_on_host,
        )
​
    def _compute_on_device(self) -> Optional[dict[str, Any]]:
        """在设备上决定是否读取:间隔 <=0 或非打印步则跳过"""
        period = self._config.stats_print_every_n_steps
        if period <= 0:
            return None
        outer_step_counter = self._outer_step_counter_getter()
        if outer_step_counter == 0 or outer_step_counter % period != 0:
            return None
        device_state = self._device_state
        # 返回需要读取的设备张量(slot_run_counters 之和、violation_write_index)
        return {
            "step": outer_step_counter,
            "slot_sum": device_state.slot_run_counters.sum().view(1),
            "write_index": device_state.violation_log.violation_write_index,
        }
​
    def _postprocess_on_host(self, host_data: dict[str, Any]) -> None:
        """主机端后处理:打印日志,包含步数、受保护 token 数、清扫轮次、违规数、活跃标签数"""
        logger.info(
            "[canary] step=%d protected_tokens=%d sweep_passes=%d violations=%d "
            "launch_tags_active=%d/%d",
            int(host_data["step"]),
            int(host_data["slot_sum"].item()),
            self._sweep_orchestrator.sweep_passes,
            int(host_data["write_index"].item()),
            len(self._active_tags),
            len(CanaryLaunchTag),
        )

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. 健康检查在检测到内核停滞时抛出RuntimeError,可能导致服务中断;但这是预期行为用于暴露问题,且可通过设置SGLANG_KV_CANARY_STATS_PRINT_EVERY_N_STEPS=0完全禁用(虽然该变量控制统计而非健康检查,健康检查有独立硬编码间隔100步,没有开关,但可以通过设置active_tags为空绕过)。
  2. DelayedDeviceHostHandler避免阻塞前向,但D2H拷贝仍占用PCIe带宽和流资源,高并发场景可能影响性能;不过每100步才执行一次,开销可接受。
  3. 环境变量默认启用,用户可能不清楚新增的日志行和潜在异常,建议在文档或changelog中说明。

对用户:如果启用,用户会在日志中看到[canary]行,出现健康检查失败时会看到RuntimeError堆栈。对系统:新增两个每步调用的step()方法,但内部大部分步骤跳过(预热期、非检查步),对性能影响极小。对团队:增加了kv-canary子系统的可观测性,便于定位问题。

运行时异常中断 默认启用可能影响用户 D2H 拷贝带宽开销

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论