运行时架构#

运行时架构部分关注的是模块边界,而不是请求顺序。请求生命周期章节已经回答了“请求怎么走”,这一部分要回答的是“走到哪里时,系统为什么把职责切成这些层”。这是两个不同问题:一个是路径问题,一个是边界问题。

对 SGLang 来说,这个问题尤其重要。因为从目录看,python/sglang/srt 下面同时有 entrypointsmanagersmodel_executormodelstokenizermem_cacheobservability 等区域。如果不先把这些区域的职责关系讲明白,后面任何局部章节都很容易写成一堆文件名列表。

这一部分的写作抓手,不是给每个目录找一句 marketing 式定义,而是沿着几个稳定事实来划分层次:http_server.pyengine.py 的文档字符串明确说明了进程与组件拆分;schedule_batch.py 明确给出了 ScheduleBatch -> ModelWorkerBatch -> ForwardBatch 的数据结构转换;memory_pool.py 又把 ReqToTokenPoolTokenToKVPoolAllocatorKVCache 之间的关系写成了显式注释。把这些事实拼起来,分层边界就不再只是目录直觉。

本节包含什么#

本节第一章是 3.1 Serving 层与 SRT 分层。它会先把对外入口、运行时编排层和更底层执行相关模块区分开来,再说明为什么“入口文件存在”并不等于“核心逻辑也在那里”。正文会继续落到 TokenizerManagerSchedulerDetokenizerManagerScheduleBatchModelRunnermemory_pool 这几组关键对象上,让目录结构能映射到真正的职责关系。

第二章是 3.2 进程边界、IPC 与运行时控制面。它进一步解释为什么 HTTP server、TokenizerManagerSchedulerDetokenizerManager 会被拆到不同进程,以及这类拆分如何影响 tracing、故障定位和控制流理解。

第三章是 3.3 请求状态对象与运行时抽象边界。这一章把 ReqStateScheduleBatchForwardBatchRequestStage 这些贯穿全书的对象放在一起看,帮助读者把“文件级理解”提升成“抽象级理解”。

第四章是 3.4 控制面、数据面与跨层耦合点。它继续回答一个更接近系统设计的问题:哪些部分更偏控制面,哪些部分更偏数据面,以及哪些地方虽然分层清晰,却仍然存在必须正视的跨层耦合。

第五章是 3.5 Engine 装配、端口分配与子进程拉起。它把 Engine.__init___launch_subprocesses(...)_launch_scheduler_processes(...)PortArgs.init_new(server_args)http_server.launch_server(...) 串成一条启动链,让运行时架构不只讲 steady state,也讲系统是怎样被组装起来的。

第六章是 3.6 TemplateManager、chat template 与请求解释边界。它把 TemplateManager、chat/completion template、apply_chat_template(...) 和 serving handler 放回运行时架构主线,解释系统怎样在进入 tokenizer 之前先“理解请求是什么意思”。

第七章是 3.7 权重更新、LoRA 注册表与暂停控制面。它把 model_update_lockis_pause_condupdate_weights_from_*check_weights(...)LoRARegistry 收成一条热变更控制面,解释系统如何在运行中安全改变模型状态。

第八章是 3.8 Typed IPC、Communicator 与 manager 消息织网。它把 TypeBasedDispatcher_Communicator、ZMQ 消息发送点和多 rank 控制请求聚合收成一张 typed message fabric,让运行时架构不只讲组件边界,也讲组件之间如何真正交换消息。

第九章是 3.9 DataParallelController、rank 路由与负载分发。它把 LoadBalanceMethodDPBudgetrouted_dp_rank、active ranks 和 dispatching_with_trace(...) 接回运行时主线,解释多 DP 部署下请求最终为什么会被送到某个特定 rank。

第十章是 3.10 Scheduler event loop 矩阵与运行模式切换。它把 dispatch_event_loop(...)、normal/overlap/pdmux/pp/disaggregation 这些主循环变体收成一张模式树,让运行时架构对 scheduler 的解释不只停在“有个主循环”,而是讲清“为什么主循环会有多种人格”。

第十一章是 3.11 ServerArgs:把运行时选项编译成拓扑。它把 ServerArgs_handle_*check_server_args() 与 engine/scheduler 初始化路径串起来,解释配置不是被动参数,而是会主动编译出一套可运行的系统人格。

第十二章是 3.12 TpModelWorker、ModelRunner 与 draft worker 的边界。它把 scheduler 之下的 worker / runner / speculative 分支边界讲清楚,解释真正执行模型的不是 scheduler 本身,而是由 worker 壳包住的一组执行人格。

第十三章是 3.13 ModelConfig、tokenizer 与 processor 的启动链。它把 ModelConfig、tokenizer、processor、multimodal processor 和 reasoning parser 这条启动链补进来,解释系统到底是怎样在启动时判定自己拥有哪些解释与执行能力。

第十四章是 3.14 rank 计算、并行维度与进程身份。它把 _calculate_rank_ranges(...)_compute_parallelism_ranks(...)configure_scheduler(...) 收成一条并行维度到进程身份的桥,让多机/多并行部署的日志和源码不再显得混乱。

第十五章是 3.15 模型定义、执行壳与 backend 实现边界。它把 models/layers/ModelRunnerTpModelWorkerdraft worker 这几层真正咬合起来,解释模型定义怎样最终被包装成可执行的 worker 单元。

第十六章是 3.16 分布式 group 初始化与通信边界。它把 parallel_state.py 里的 distributed init、model-parallel 初始化与 get_tp_group() / get_pp_group() / get_world_group() 的消费路径接起来,解释并行身份怎样真正落成通信现实。

第十七章是 3.17 warmup、权重就绪与 readiness 门。它把 _wait_weights_ready()_execute_server_warmup()server_status 和多节点 dummy health server 这些启动后门禁链收成一章,解释“进程已经起来”和“服务真的 ready”为什么不是一回事。

第十八章是 3.18 engine info bootstrap 与远端 transfer 协调。它把 EngineInfoBootstrapServerengine_info_bootstrap_portModelRunner._register_to_engine_info_bootstrap()/remote_instance_transfer_engine_info 收成一条分布式控制引导链,解释某些远端协调能力为什么要额外挂一层轻量 bootstrap 服务。

第十九章是 3.19 PortArgs、IPC 名称与 shared memory 引导。它把 PortArgs.init_new(...)、worker-local tokenizer_ipc_name、shared memory 参数传递和 SenderWrapper 重新接成一条连接信息传播链,解释运行时拓扑怎样真正被编译并分发给不同进程与 worker。

这一章与请求生命周期章节的关系,是互补而不是重复。前者讲穿透路径,后者讲分层边界;如果后续执行得当,读者应该能把“请求经过哪里”和“每层负责什么”放在同一张图里看。到这一步,你就不再只是背文件名,而是在脑中形成一张有进程边界、数据结构边界和模块职责边界的工作图。