mcpField
S
sglang-prod-incident-triage

sglang-prod-incident-triage

github.com/bbuf云与 DevOps1.1k94 次安装今天更新
代码仓库

关于 sglang-prod-incident-triage

面向 SGLang 运维人员的服务故障排查技能,适用于健康状态、性能、输出或崩溃问题。它先收集证据并重放故障请求,再进入深入分析或专门的调试流程。

主要功能

  1. 01收集并汇总在线故障信息包
  2. 02保存并重放请求或崩溃转储
  3. 03指导追踪、性能分析与提交二分
  4. 04定义结构化故障报告

适用场景

  1. 01排查服务延迟或吞吐量退化
  2. 02利用已保存请求或转储复现崩溃
  3. 03定位间歇性挂起与超时
  4. 04比较已知正常与异常的提交

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bbuf/ai-infra-auto-driven-skills --skill sglang-prod-incident-triage

安装后在 Claude Code 中输入/sglang-prod-incident-triage确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
case-studies.md
decision-tree.md
endpoints-and-signals.md
replay-trace-profile.md
scripts/
incident_artifact_tool.py
replay_trusted_request_dump.py

详细介绍

SGLang 服务调试

将历史证据应用到当前分支时,请使用维护中的源代码契约。 评审和历史语料保留了各自的采集日期;它们不能证明今天的调度逻辑 或数值默认值。替换内核时,请先验证真实模型能够执行候选内核,再将端到端测试视为覆盖依据。

概述

使用此技能,将线上服务问题转化为可重放的调试路径。

采用一个循环:

  • 收集基线信息包
  • 保存失败请求或崩溃转储
  • 在干净的目标环境上重放
  • 然后再切换工具

不要一开始就进行性能分析。

截至 SGLang v0.5.21(2026-09-29),还有两个与线上服务相关的重要信号:

  • --enable-session-radix-cache 和 /close_session:如果 Agent 或 RL rollout 忘记关闭会话,KV 增长可能看起来像是原因不明
  • 可选启用的 Rust ingress(SGLANG_RUST_SERVER=1)没有 API 密钥边界;如果事件与身份验证有关,请先确认实际提供服务的是哪个服务二进制,再怀疑应用令牌

此技能应与更专注的技能配合使用,而不是重新实现它们:

  • 当重放加上核心转储指向 CUDA 崩溃路径时,使用 debug-cuda-crash
  • 当问题明显是 TP/PP/DP/EP 挂起时,使用 debug-distributed-hang
  • 当问题已缩小到计算侧路径时,使用 llm-torch-profiler-analysis

其中包含三个示例:

  • 队列时间较短但 TTFT 激增
  • 优先重放的 CUDA 崩溃流程
  • 按请求特征排查分布式挂起的流程

输出约定

返回:

  • 问题类别
  • 已检查的内容
  • 目前最强的信号
  • 当前最佳猜测
  • 已排除的可能性
  • 下一步
  • 生产风险

适用场景

  • /health 或 /health_generate 状态不正常
  • 服务负载下延迟或吞吐量退化
  • 队列大小增长,但健康状态仍显示正常
  • 某类请求超时或挂起
  • 服务器仅在处理若干请求后崩溃
  • 部署、拓扑变更或权重切换后,输出发生变化
  • 已知某个较旧的提交正常,而较新的提交异常

工作流

1. 收集基线信息包

先确认 ingress:Python /server_info.frontend 的值为 python。Rust ingress 缺少 /v1/loads、/metrics、/configure_logging、/hicache/*、 /set_trace_level、/start_profile 和 /ready;这些端点返回 404 属于 ingress 限制。Rust 健康状态会保持 503,直到启动预热成功。

如果可以访问线上服务器,请先收集只读信息包,再进行任何更具侵入性的操作:

python3 scripts/incident_artifact_tool.py collect-bundle \
  --base-url http://127.0.0.1:30000 \
  --outdir /tmp/incident_bundle

python3 scripts/incident_artifact_tool.py summarize-bundle \
  /tmp/incident_bundle

如果服务器受到保护:

python3 scripts/incident_artifact_tool.py collect-bundle \
  --base-url http://127.0.0.1:30000 \
  --token "$SGLANG_BEARER_TOKEN" \
  --outdir /tmp/incident_bundle

信息包脚本会收集:

  • /ready
  • /health
  • /health_generate
  • /model_info
  • /server_info
  • /v1/loads?include=all
  • /v1/loads?include=core,queues,disagg,spec
  • /metrics
  • 尽力收集 /hicache/storage-backend

如果当前判断是 HiCache 内容过期或损坏,请先捕获信息包和相关请求转储,再调用 POST /hicache/storage-backend/clear。该端点会清除已连接后端中的内容,但不会断开连接;请将其视为破坏性操作,仅在可以接受缓存内容丢失时使用。有关连接、断开连接和清除的详细信息,请参阅 references/endpoints-and-signals.md。

使用摘要快速查看:

  • 健康状态与主动健康状态
  • 拓扑和运行时标志
  • 某一时点的队列和令牌用量
  • 根据 Prometheus 指标估算的 TTFT / E2E / 队列时间

如果摘要表明信息包是在服务器空闲时采集的,请在有流量时重新采集,或尽快转向转储加重放。

如果无法访问线上服务器,请从现有的最佳转储或日志入手:

  • 崩溃转储
  • 请求转储
  • 日志
  • CUDA 核心转储
  • OTel 跟踪
  • torch 性能分析
2. 保存触发问题的请求

只有在问题类别仍不明确时,才阅读 references/decision-tree.md:

  • 服务宕机或运行不健康
  • 延迟或吞吐量回退
  • 输出错误或行为回退
  • 间歇性超时或挂起

然后保留实际触发问题的请求载荷:

  • 崩溃路径:使用 --crash-dump-folder
  • 非崩溃路径:启用请求转储,或保存确切的触发请求

不要在没有先保存可供重放的内容时,就从线上症状直接跳到低层调试。

3. 在干净的目标上重放

需要了解基线包或重放目标时,请阅读 references/endpoints-and-signals.md。

需要了解重放、跟踪、性能分析或二分路径时,请阅读 references/replay-trace-profile.md。

标准顺序:

  1. 收集基线包
  2. 捕获请求转储或崩溃转储
  3. 如有需要,重启干净的调试目标
  4. 重放相同的问题
  5. 收集重放期间的日志和转储
4. 仅在重放后深入排查
重放

以下情况请使用重放:

  • 存在崩溃转储
  • 存在请求转储
  • 问题取决于请求形态或工作负载组合

如果存在崩溃转储,请先对其进行摘要分析:

python3 scripts/incident_artifact_tool.py summarize-dump \
  --input-file /path/to/crash_dump.pkl

然后重放:

python3 /path/to/sglang/scripts/playground/replay_request_dump.py \
  --input-file /path/to/crash_dump.pkl \
  --host 127.0.0.1 \
  --port 30000 \
  --parallel 128

如果 safe_pickle_load 阻止加载本地捕获的可信转储,请使用:

python3 scripts/replay_trusted_request_dump.py \
  --input-file /path/to/request_dump.pkl \
  --host 127.0.0.1 \
  --port 30000 \
  --parallel 1

如果重放显示问题属于 CUDA 崩溃路径,请在再次复现前,使用启用 coredump 的相同构建重启:

SGLANG_CUDA_COREDUMP=1 \
SGLANG_CUDA_COREDUMP_DIR=/tmp/sglang_cuda_coredumps \
python -m sglang.launch_server \
  --model-path ... \
  --crash-dump-folder /tmp/sglang_crash_dump \
  ...

然后检查生成的 coredump:

cuda-gdb "$(which python3)" \
  -ex "target cudacore /tmp/sglang_cuda_coredumps/cuda_coredump_<host>.<pid>.<ts>"

如需了解以重放为先的崩溃示例,请阅读 references/case-studies.md。

OTel 跟踪

以下情况请使用跟踪:

  • 请求各阶段的耗时不明确
  • 无法明确归因于路由器还是工作进程
  • 可能涉及 PD 预填充/解码传输

如果在启动时已启用跟踪,则无需重启即可更改级别:

curl "http://127.0.0.1:30000/set_trace_level?level=1"
curl "http://127.0.0.1:30000/set_trace_level?level=2"
Torch 性能分析

以下情况请使用性能分析:

  • 问题已缩小到计算侧归因
  • 重放已能复现问题
  • 指标和负载无法解释此次回退

此时请切换到 llm-torch-profiler-analysis。请勿在此处重复其性能分析工作流。

如需了解低噪声延迟示例,请阅读 references/case-studies.md。

分布式挂起

如果看起来像是集体通信停滞,请保存触发问题的请求,在干净的目标上重放,收集重放期间的包和堆栈,然后切换到 debug-distributed-hang。

如需了解该流程示例,请阅读 references/case-studies.md。

两个提交之间的回归

如果已知一个提交正常,另一个提交异常,请先构建确定性测试框架,再进行更深入的手动调试:

  1. 选择稳定的复现方式:请求重放、基准测试命令或正确性检查
  2. 让测试框架在行为正常时返回 0,在行为异常时返回非零值
  3. 运行 git bisect start <bad> <good>
  4. 运行 git bisect run <harness>
  5. 仅在确定候选提交后再返回此处

如果回归取决于请求形态或长时间运行的服务状态,优先使用基于重放的二分定位。

5. 明确问题边界后切换工具

一旦明确故障类别,就切换工具:

  • llm-torch-profiler-analysis:用于内核和重叠归因
  • debug-distributed-hang:用于集体通信或 rank 分歧导致的挂起
  • debug-cuda-crash:用于 CUDA 崩溃复现和内核 API 日志记录

除非用户已提供明确的日志或转储,否则收集第一个包之前不要切换工具。

参考资料

仅加载当前步骤所需的内容:

脚本

如果已收集在线信息包,请注明其路径。

如果选择了回放、跟踪或性能分析,请说明为何信息包加转储还不够。

当前上游调试控制项 — 2026-10-05

SGLang 仓库的配套技能现位于 .agents/skills/(#40515): debug-cuda-crash、debug-distributed-hang、generate-profile 和 sglang-bisect-ci-regression。调用前请先核实仓库中的副本。

如果环境变量尚未设置,--crash-dump-folder X 会配置 CUDA 核心转储,并设置 CUDA_COREDUMP_FILE=X/%h/core.cuda.%t.%p 和 CUDA_COREDUMP_PIPE=/tmp/corepipe.cuda.%h.%p。崩溃发生前,默认启用 py-spy 和用户触发的 CUDA 转储,并等待核心转储 60 s。SGLANG_CUDA_COREDUMP=1 使用单独的 cuda_coredump_%h.%p.%t 命名方式;根据导入顺序的代码读取结果,已设置的路径优先。此优先级未经 GPU 测试。配置的管道也可以捕获卡住的内核。

来源:崩溃转储钩子, Rust 入口。

评论

支持 Markdown