遇到 bug 时,先从仓库哪几处下手#

这章解决什么问题#

知道仓库结构,和真正会用仓库排障,是两件不同的事。很多读者在读完代码导读之后,仍然会在真实问题面前卡住:目录都知道了,但第一步到底该打开哪个文件,第二步该看哪个测试,第三步又该去对照哪份文档?

这一章就是把“仓库地图”进一步压成“故障入口地图”。它不是再讲一遍目录,而是回答:遇到不同类型的 bug,先去哪几处最可能拿到高价值线索。

如果 bug 表现为“请求进来了但行为不对”#

这类问题最稳的起手式通常还是主链路:launch_server.pyhttp_server.pyTokenizerManagerSchedulerDetokenizerManager。因为只要你还没有确认请求究竟卡在 lifecycle 的哪一段,过早跳进 cache 或 backend 往往只会增加噪音。

一个简单判断是:如果你仍然说不清“请求有没有真正完成闭环”,那就还没到应该读 model_executor 深处的时候。

如果 bug 表现为“性能或资源行为异常”#

这类问题最常见的错误入口,是直接去看 benchmark 脚本。更稳的顺序通常是:先回到 scheduler.pyschedule_batch.pymemory_pool.pyradix_cache.pychunk_cache.pymodel_runner.py,确认问题更像 batch、cache 还是执行路径差异,然后再去看 benchmark 和 profiling 路径。

原因很简单:benchmark 往往告诉你“慢了”,但不一定告诉你“为什么慢了”。仓库里最先告诉你原因的,通常还是主机制文件。

如果 bug 表现为“结构化结果或工具调用不稳”#

这时最稳的入口不在 scheduler,而在 SamplingParams、frontend gen(...)tool_parser 文档与 function_call 路径。因为这类问题首先是“约束和解释是否一致”,其次才是 runtime 细节。

也就是说,bug 类型一旦变化,最短阅读路径就应该立刻变化。代码导读真正想提供的,正是这种“不要总从同一个地方开始”的判断能力。

如果 bug 表现为“改动后不确定是否伤到别处”#

这类问题不属于单个源码文件,而属于“验证路径是否找对”。起手式应当是 test/README.mdrun_suite.py、对应 registered / unit / manual 测试路径,以及必要时的 benchmark / profiling 文档。很多时候,读者真正缺的不是更多源码,而是更清楚的验证地图。

对一本厚一点的技术书来说,这种章节很重要,因为它把“仓库导读”从静态说明,推进成了维护者真正能用的排障工具。

一个按故障类型选入口的表#

现象:请求不回包
先看:launch_server.py / http_server.py / TokenizerManager / Scheduler / DetokenizerManager

现象:吞吐或显存异常
先看:scheduler.py / schedule_batch.py / memory_pool.py / radix_cache.py / model_runner.py

现象:结构化结果不稳
先看:sampling_params.py / lang/api.py / tool_parser 文档 / function_call 路径

现象:改动后不确定影响范围
先看:test/README.md / run_suite.py / registered / unit / benchmark 文档

本章对应哪些代码路径#

这一章本质上回指整本书前面已经建立好的锚点:python/sglang/launch_server.pypython/sglang/srt/entrypoints/http_server.pypython/sglang/srt/managers/*python/sglang/srt/model_executor/*python/sglang/srt/mem_cache/*python/sglang/srt/function_call/*test/README.mdtest/run_suite.py

小结#

如果代码导读最后能给读者留下的不只是“目录长什么样”,而是“不同 bug 该从哪里开刀”,它就更接近一本真正有用的技术书,而不是一份地图说明。