读 models/ 与 layers/:模型定义与执行砖块#

这章解决什么问题#

代码导读前面已经给出了从入口到 scheduler、从 observability 到 disaggregation 的多条稳定阅读路径,但还有两棵最容易让人“越看越散”的源码树没有被正式导读:

  • python/sglang/srt/models/
  • python/sglang/srt/layers/

这一章的目标,就是把这两棵树重新收成一条更稳的阅读路径。

为什么这两棵树特别容易读散#

因为它们都很大,而且看起来都很重要:

  • models/ 里塞满了具体模型实现
  • layers/ 里又塞满了 attention backend、sampler、quantization、moe、rotary embedding 等执行砖块

如果没有阅读策略,读者很容易在这里陷入“文件越多越核心”的错觉,而失去对整本书主线的把握。

一张图:这两棵树在整本书里的角色并不对称#

这张图解决的理解障碍是:很多读者会把 models/layers/ 想成平行目录,而从运行时角度看,它们其实分别站在“模型定义层”和“执行砖块层”。

flowchart LR
    Models["models/"] --> Runner["ModelRunner"]
    Layers["layers/"] --> Runner
    Runner --> Worker["TpModelWorker / draft worker"]

图比纯文字多解释的一点是:你不应该直接把这两棵树当成“谁都可以先读”的入口,而更适合先知道它们在整体架构里是如何汇合的。

models/ 的正确心态#

models/ 最适合回答的问题不是“系统怎么跑”,而是:

  • 某个模型的特殊语义在哪里实现
  • 哪些模型是 generation / multimodal / rerank / classification 变体
  • 哪些模型需要特殊的 logits processor、vision projector、audio path、MTP 分支

也就是说,它更像“模型人格差异的具体落点”,而不是执行主循环本身。

为什么 layers/ 更像执行砖块仓库#

从目录就能看出来,layers/ 至少包括:

  • attention/
  • sampler.py
  • logits_processor.py
  • moe/
  • quantization/
  • rotary_embedding/

这说明它不是“一个层模块”,而是一整套组成执行壳的基础砖块。对读者来说,这意味着:

  • 先理解 ModelRunner 怎样消费这些砖块
  • 再按问题进入某一类砖块目录

通常比直接钻某个 backend 文件稳得多。

更稳的阅读顺序#

建议这样读:

  1. 先回到运行时架构里的 ModelRunner / TpModelWorker 心智模型
  2. 再看 models/registry.py 或具体模型目录,确认模型人格差异
  3. 然后只在你需要回答某个具体执行问题时,再进入 layers/attentionlayers/samplerlayers/quantization 等目录

这样读的关键,是先有壳,再看砖块。

models/ 更适合解决什么问题#

例如:

  • “这个模型为什么需要特殊 multimodal processor?”
  • “为什么某个模型用不同的 logits processor 或 MTP 路径?”
  • “这个 reward / rerank / OCR 模型为什么和普通 generation 模型长得不一样?”

这些问题更适合去 models/ 里找。

layers/ 更适合解决什么问题#

例如:

  • “为什么这个 attention backend 会改变执行限制?”
  • “为什么这个 quantization 会影响 KV cache 或 logits 路径?”
  • “sampler / logits processor / moe router 到底怎样工作?”

这些问题则更适合去 layers/ 里找。

为什么这章会和很多前文回扣#

它天然会回扣:

  • 运行时架构:解释 ModelRunner 汇合点
  • 执行模型:解释 samplerlogits_processor、attention backend 的源码落点
  • 结构化生成:解释 grammar/vocab-mask 会落到哪些层
  • 代码导读前文:解释为什么模型树和执行砖块树不能混着读

这一层最容易出现的误判#

1. 直接从 models/ 读执行主线#

这样容易忽略调度和执行壳层。

2. 直接从 layers/attention 读系统全貌#

这样容易把某个 backend 误当成系统主线。

3. 看到大目录就默认“这里才是核心”#

对系统书来说,更重要的是它在整体中的角色,而不是文件数。

小结#

这一章真正想补齐的,是代码导读对两棵最大源码树的稳定读法:

  • models/ 更像模型差异层
  • layers/ 更像执行砖块层
  • 它们都应该在 ModelRunner 这层执行壳心智模型建立之后再读

到这里,代码导读对源码树的导航就更完整了。