rank 计算、并行维度与进程身份#
这章解决什么问题#
运行时架构前面已经讲了 DataParallelController、TpModelWorker、ServerArgs 和 event loop 矩阵,但还有一个很容易被忽略、同时又对多机/多并行维度阅读特别关键的问题:一个 scheduler 进程到底怎样知道自己是哪个 TP / PP / ATTN_CP / MOE_DP / EP rank,它的进程名和日志前缀又为什么会长成现在这样?
这一章的目标,就是把这层 rank 数学与进程身份生成讲透。
为什么这层值得单独讲#
因为多并行维度系统最容易把读者搞糊涂的,不只是“有哪些 rank”,而是:
- 这些 rank 怎么算出来
- 某个 node 到底负责哪一段
pp_rank_range和tp_rank_range - 日志里看到的
PP/TP/EP前缀是怎么来的
如果不把这层讲清楚,后面多机日志和进程命名会很难读。
一张图:从 node 维度到多种并行 rank,是一层层展开的#
这张图解决的理解障碍是:读者容易把 node_rank、tp_rank、pp_rank、attn_cp_rank、moe_dp_rank 混成一锅。
flowchart TD
Node["node_rank"] --> Range["pp_rank_range / tp_rank_range"]
Range --> TP["tp_rank"]
TP --> Attn["attn_cp_rank"]
TP --> MoeDP["moe_dp_rank"]
TP --> MoeEP["moe_ep_rank"]
Range --> PP["pp_rank"]这张图比纯文字多解释的一点是:很多并行维度并不是并列算出来的,而是在 node -> range -> tp_rank 这条链上继续拆细。
_calculate_rank_ranges(...) 说明 node 到 rank range 的分配逻辑#
engine.py 里这个函数会根据:
nnodespp_sizetp_sizenode_rank
算出:
pp_rank_rangetp_rank_rangepp_size_per_nodetp_size_per_node
这说明 node 并不是“自然拥有一组 worker”,而是通过一套显式公式被映射到 pipeline 与 tensor 的 rank 区间。
这特别值得写进书里,因为很多多机系统的排障第一步就是先确认“这个 node 理论上该持有哪一段 rank”。
_compute_parallelism_ranks(...) 为什么更像“在 TP rank 之上再切层”#
这个函数接着会从单个 tp_rank 推导:
attn_cp_rankmoe_dp_rankmoe_ep_rank
它揭示了一个很重要的事实:很多更细的并行身份并不是直接从 node 算,而是站在 tensor-parallel 全局 rank 上再做第二层切分。
这也是为什么在读 scheduler 日志时,TP 往往像根骨架,而 ATTN_CP / MOE_DP / EP 更像附加人格。
configure_scheduler(...) 为什么是“身份落实”而不是简单日志配置#
这个函数会:
- 根据现有 rank 组装 prefix
- 设置进程标题
sglang::scheduler_... - 配置 logger prefix
表面上看像日志与进程名细节,实际上它在做一件更关键的事:把抽象 rank 身份真正落成“这个进程如何向外自我表述”。
对维护者来说,这一点特别重要,因为多机系统排障时首先读到的往往不是代码,而是进程名和日志前缀。
为什么 dp_rank 还有一条环境变量注入路径#
configure_scheduler(...) 里如果 dp_rank 为 None,但环境变量 SGLANG_DP_RANK 存在,就会用它。这说明系统承认:
- 有时 rank 身份来自显式进程参数
- 有时来自更外层 router / launcher 注入的环境
这再次体现出 SGLang 的运行时不是封闭单机模型,而是主动适配不同部署面。
进程名与日志前缀为什么值得技术书认真讲#
因为它们不是表面装饰。对于一个 PP × TP × EP × DP 的系统,命名和前缀就是你理解系统实际拓扑的第一手证据。如果这层读不懂,后面再多 trace、更多指标也很难快速定位问题。
这也是为什么这章虽然讲的是“看起来很基础的命名”,实际上却和平台维护高度相关。
这一层最容易出现的误判#
1. 把 rank 前缀当成简单标签#
它们其实是多层并行数学真正落地后的身份表示。
2. 以为 node_rank 直接等于某个 tp_rank#
中间还要经过 range 计算。
3. 以为 ATTN_CP / MOE_DP / EP 是独立平行维度#
它们在实现上很多是从 tp_rank 再拆出来的。
如果你在排查多机多并行问题,先怎么走#
建议按这个顺序:
- 先看 node 应该拿到的
pp_rank_range/tp_rank_range - 再看某个
tp_rank推导出的attn_cp_rank/moe_dp_rank/moe_ep_rank - 再对照进程标题和 logger prefix
- 最后再进 scheduler / worker / model runner 里看行为细节
小结#
这一章真正想补齐的,是运行时架构里非常容易被跳过、但对读懂多机系统极其重要的一层:
- rank 不是天然存在的,而是被计算出来的
- 进程身份不是附带标签,而是这些计算结果的外化表达
- 只有把这层看清,复杂并行拓扑在日志和源码里才会显得有序
到这里,运行时架构对“进程是谁、为什么是它”也有了更完整的解释。
叶王 © 2013-2026 版权所有。如果本文档对你有所帮助,可以请作者喝饮料。