代码结构
第一次阅读,从这些文件开始
Section titled “第一次阅读,从这些文件开始”建议按以下顺序阅读,先看列出的函数及其直接调用的代码,再深入具体平台的实现。
| 顺序 | 代码入口 | 帮你回答的问题 |
|---|---|---|
| 1 | xllm/xllm.cpp:main()、run() | 配置、master 和 HTTP 服务如何连接起来? |
| 2 | chat_service_impl.cpp:ChatServiceImpl::process_async_impl() | 聊天消息如何转换为内部请求,并绑定输出回调? |
| 3 | llm_master.cpp:LLMMaster::handle_request()、run() | 请求如何进入调度器?谁在驱动调度循环? |
| 4 | continuous_scheduler.cpp:ContinuousSchedulerBase::step() | 一轮批次如何被调度、执行并处理结果? |
| 5 | llm_engine.cpp:LLMEngine::step() | 批次如何发送到各个 worker,执行结果如何汇总? |
| 6 | llm_worker_impl.cpp:LLMWorkerImpl::step_internal() | 模型执行、logits 计算和 token 采样发生在哪里? |
第一遍先沿着未启用投机解码、PD 分离和调度重叠的路径阅读。这些功能是在基本流程 上增加分支,理解主流程后再展开会更容易。
先认识代码中的几个概念
Section titled “先认识代码中的几个概念”| 概念 | 在本页中的含义 | 源码入口 |
|---|---|---|
| Token、prefill、decode | Tokenizer 将文本转换成 token ID。Prefill 处理输入提示词;decode 复用已有计算状态,继续生成输出。Chunked prefill 把提示词拆到多个调度轮次处理。 | tokenizer/、scheduler_policy.cpp |
Request | 一次推理请求,包含生成参数、输出回调以及一个或多个 sequence。 | request.h、request_state.h |
Sequence | 一条持续增长的 token 序列,记录生成进度、停止状态和缓存状态。同一个请求可以有多个候选序列。 | sequence.h |
Batch、BatchGroup | Batch 是一次执行步骤选中的工作集合;BatchGroup 汇总该步骤中各个数据并行(DP)rank 的 batch。 | batch.h、batch_group.h |
| Rank 与并行方式 | Rank 标识并行执行中的参与者。DP 将请求工作分配到不同组;张量并行(TP)把模型的张量计算拆分到多个 rank;专家并行(EP)分布部署混合专家模型中的专家。 | parallel_state/ |
| Continuous batching(连续批处理) | 调度器每轮重新选择工作,让新请求加入、已完成请求退出。一个 batch 的成员不会在整个请求生命周期内保持固定。 | continuous_scheduler.h |
| KV cache、block、prefix cache | KV cache 保存可复用的注意力状态;block manager 分配和回收缓存容量;prefix cache 让满足复用条件的请求共享已缓存的提示词前缀。 | kv_cache/、block/、prefix_cache/ |
| Logits 与采样 | Logits 是模型对词表中各 token 给出的分数;采样根据生成参数,从这些分数中选择下一个 token。 | sampling/ |
| Master、engine、worker、executor | Master 连接请求处理与调度;engine 协调各 worker 执行批次;worker 管理设备上的执行;其中的 executor 选择模型的执行方式。 | distributed_runtime/、runtime/ |
仓库目录导航
Section titled “仓库目录导航”下面只列出用于定位代码的主要目录,并非完整文件清单。C++ 可执行程序的入口是
源码目录内的 xllm/xllm.cpp。
.├── xllm/│ ├── xllm.cpp # C++ 可执行程序入口│ ├── launch_server.py # xllm serve 的 Python 启动器│ ├── server/ # HTTP 服务生命周期与路由注册│ ├── api_service/ # 请求解析、校验与响应构造│ ├── core/│ │ ├── common/ # 公共类型、选项、指标与辅助定义│ │ ├── distributed_runtime/ # Master、engine、worker RPC 与协同管理│ │ ├── scheduler/ # 队列、调度策略与输出处理│ │ ├── framework/ # 推理数据结构与公共机制│ │ │ ├── config/ # 分类配置与命令行选项│ │ │ ├── request/ # 请求、序列与停止状态│ │ │ ├── batch/ # 批次与模型输入构造│ │ │ ├── block/ # 组合缓存与运行时分配适配器│ │ │ ├── kv_cache/ # 依赖模型的线性状态恢复适配器│ │ │ ├── model/ # 模型接口与输入输出类型│ │ │ ├── model_loader/ # 模型配置与 checkpoint 加载│ │ │ │ └── weight/ # 权重资源、分配策略与传输│ │ │ ├── tokenizer/ # 文本与 token 转换│ │ │ ├── chat_template/ # 聊天消息转换为模型提示词│ │ │ ├── sampling/ # Token 采样与约束解码│ │ │ ├── parallel_state/ # 并行分组与通信状态│ │ │ ├── eplb/ # 专家并行负载均衡│ │ │ ├── transfer/ # 共用字节传输、会话与内存注册│ │ │ └── allocator/ # 通用内存能力与页预算记账│ │ │ ├── virtual_memory/ # 通用物理页与虚拟映射│ │ │ └── torch/ # 映射字节区域上的 tensor 视图│ │ ├── kv_cache/ # 缓存领域:布局、存储、块、前缀与传输│ │ ├── runtime/ # Worker、本地资源与模型 executor│ │ ├── layers/ # C++ 神经网络层│ │ ├── kernels/ # 设备算子实现与封装│ │ ├── platform/ # 设备、流、内存与通信接口│ │ └── util/ # 辅助工具│ ├── models/ # C++ 模型注册与实现│ │ ├── llm/ # 语言模型及 Python 模型桥接│ │ ├── vlm/ # 视觉语言模型│ │ ├── dit/ # 扩散模型│ │ └── rec/ # 生成式推荐模型│ ├── python/ # Python 模型执行│ │ ├── models/ # Python 模型定义│ │ ├── model_executor/ # 执行协调与 eager/graph runner│ │ ├── attention/ # 注意力后端与元数据│ │ ├── model_loader/ # 权重加载与切分│ │ ├── layers/ # Python 神经网络层│ │ ├── kernels_cuda/ # CUDA 算子│ │ ├── kernels_npu/ # NPU 算子,含 TileLang/Triton 源码│ │ └── distributed/ # 模型内部的集合通信│ ├── processors/ # 多模态输入预处理│ ├── parser/ # 推理过程输出解析器│ ├── function_call/ # 工具调用解析器│ ├── proto/ # 服务与内部 RPC 协议定义│ ├── pybind/ # 面向用户的 Python 推理 API 与 C++ 绑定│ ├── c_api/ # C 集成接口│ ├── cc_api/ # C++ 集成接口│ ├── compiler/ # 算子编译与 AOT 构建工具│ └── auto_config/ # 按模型和硬件生成启动配置├── examples/ # 离线推理示例├── tests/ # C++、Python 测试及设备测试├── scripts/ # 构建、测试、启动与开发辅助脚本├── tools/ # 转换、张量比较与 profiling 工具├── third_party/ # 外部依赖与算子库├── docs/ # 中英文文档站点├── CMakeLists.txt # C++ 构建配置└── setup.py # Python 打包与构建入口KV cache 与虚拟内存的边界
Section titled “KV cache 与虚拟内存的边界”内存基础能力同时服务 KV cache 和权重。各类资源的映射与分配策略归各自模块管理, 本地资源由 runtime 持有,共享预算、跨 worker 操作及模型休眠、唤醒由分布式层协调。 图中实线表示“使用或持有”,虚线表示接口实现或尚待拆分的耦合。
flowchart TB subgraph runtime["runtime"] worker["WorkerImpl<br/>组装与注入"] resources["WorkerMemoryResources<br/>本地设备与资源生命周期"] end
blocks["framework/block<br/>组合 manager 与分页适配器"]
subgraph distributed["distributed_runtime"] residency["ModelResidencyCoordinator<br/>模型初始化、休眠与唤醒"] coordination["DistributedVirtualMemoryCoordinator<br/>共享 KV/权重预算、worker 选择与派发"] rpc["WorkerMemoryRpc<br/>client、service、server"] end
subgraph cache["core/kv_cache"] policy["layout、block 与 prefix<br/>KV 策略与状态"] pages["storage / VirtualKVCachePageAllocatorImpl<br/>页队列、预分配与 block 到页换算"] backend["storage / KVCachePageBackend<br/>容量预留与映射接口"] ports["storage 与 transfer 接口<br/>页分配、tensor 分配、内存 provider"] storage["storage / VirtualKVCacheMemoryRegistry<br/>本地 KV 映射与分页 tensor 分配"] kvtransfer["transfer<br/>内存 provider、KV peer/layout 状态<br/>重分片与缓存传输"] end
subgraph framework["framework"] weight["model_loader/weight<br/>WeightVirtualMemoryManager、store<br/>分配策略与权重传输"] tensor["allocator/torch<br/>映射内存上的 tensor 视图"] shared["allocator<br/>WorkerPhysicalPageBudget / GlobalVirtualMemoryRegion"] memory["allocator/virtual_memory<br/>物理页与字节映射"] transport["transfer<br/>Mooncake 字节传输<br/>会话与内存注册"] end
remaining["framework/request / Sequence<br/>framework/config 与 runtime options"] worker --> resources worker --> blocks worker --> storage worker --> kvtransfer residency --> coordination residency -->|worker 生命周期操作| worker coordination --> pages coordination --> rpc coordination -->|本地执行| resources coordination --> shared rpc --> resources resources --> storage resources --> weight resources --> shared blocks --> policy blocks --> ports pages -.->|实现页分配接口| ports pages --> backend coordination -.->|实现映射后端| backend storage -.->|实现 tensor 分配接口| ports kvtransfer -.->|实现内存 provider| ports storage --> tensor tensor --> memory shared --> memory weight --> memory weight --> shared weight --> transport kvtransfer --> storage kvtransfer --> shared kvtransfer --> transport policy -.-> remainingframework/allocator/virtual_memory 提供 PhysicalPage、PhysicalPagePool、
MappedVirtualMemoryRegion 和 SharedPhysicalPageMapping。映射区域管理字节、物理页与虚拟地址,
tensor 的 shape、dtype 和视图构造放在 framework/allocator/torch;返回的 tensor
视图不拥有底层区域。通用内存代码不负责 KV 布局、权重策略或模型生命周期。
GlobalVirtualMemoryRegion 是带生命周期 lease 的共享映射 facade。传输注册及注册期间
持有的映射 lease 属于 framework/transfer,该模块没有 KV 或 distributed-runtime
目标依赖。
core/kv_cache/storage 保存 VirtualKVCacheMemoryRegions 和 VirtualKVCacheMemoryRegistry,
负责各模型本地的缓存映射及物理偏移查询。VirtualKVCacheTensorAllocator 使用注入的
registry 实现 KVCacheTensorAllocator。core/kv_cache/transfer 中的
VirtualKVCacheTransferMemoryProviderImpl 使用该 registry 和注入的 GlobalVirtualMemoryRegion
实现 VirtualKVCacheTransferMemoryProvider。WorkerImpl 提供这些依赖,具体缓存后端使用
通用分配能力,不依赖分布式协调器。
framework/model_loader/weight 管理 WeightVirtualMemoryManager、ModelWeightStore、
WeightAllocation 和权重传输适配器,使用构造时传入的物理页池和共享映射,负责
权重预留的所有权、连续或分散映射、区域内分配及清理。权重传输与 KV 传输共同使用
Mooncake 字节传输。KV manifest、peer 状态和重分片 plan 仍属于
core/kv_cache/transfer,由 MooncakeKVCacheTransferEngine 等类管理。
runtime/WorkerMemoryResources 持有本地 KV registry 和 WeightVirtualMemoryManager,
管理设备初始化、物理页池以及本地资源的创建与清理。它是独立的构建目标,
不依赖 runtime 聚合目标、RPC 或 distributed-runtime。
distributed_runtime/WorkerMemoryRpcClient、WorkerMemoryRpcService 和
WorkerMemoryRpcServer 负责跨 worker 请求;service 只调用本地资源,
不反向进入分布式协调器。
core/kv_cache/storage/VirtualKVCachePageAllocatorImpl 管理 KV 页队列、预分配和
block 到虚拟页的换算,实现 VirtualKVCachePageAllocator。它通过注入的
KVCachePageBackend 请求容量预留及 map/unmap,不包含权重策略或 RPC。
map/unmap 接收每层 K/V 区域内的字节偏移,由 allocator 将虚拟页 ID 乘以页大小得到。
KVCacheManagerFactory 将页分配接口经 pool 和组合 manager 注入
VirtualMemoryKVCacheBlockManager,block 适配器不访问分布式单例。
DistributedVirtualMemoryCoordinator 实现该 backend,持有分页 allocator,使用通用的
WorkerPhysicalPageBudget 记账,并选择目标 worker、派发本地或 RPC 操作。
模型初始化、休眠与唤醒由 ModelResidencyCoordinator 组织;KV 和权重的共同预算
在唤醒时由分布式协调器以一个预算事务原子预留。初次以唤醒状态初始化时,先预留
权重容量,后续 KV 页分配再从同一共享预算扣账。休眠先冻结 KV 分配和回收,等待预分配及执行中的
映射结束,再改变映射与权重生命周期,避免预算释放与后台映射交错。
分页策略归 KV cache,跨资源事务及分布式执行归 distributed-runtime。
Block 值类型编译为 kv_cache_block_types,供 request 和 prefix cache 使用;
缓存领域叶子编译为 kv_cache_block;framework 中的组合与分配适配器组成
block 聚合目标。这是渐进的边界调整:缓存 block 策略仍操作 Sequence,
容量估算仍读取 framework 配置与 runtime options,也仍有模型专属缓存策略。
这些策略和输入边界需要后续切片,才能把 core/kv_cache 视为完全独立的领域模块。
proto/mooncake_transfer_engine.proto 暂时作为兼容桥:保留原有 service 和 method
名称,共用同一个 listener。通用传输服务处理 session RPC,把 cache RPC 转发给
KV 扩展 service,不解释其消息。schema 仍包含 KV 消息,因此当前拆分消除了 C++
领域与构建目标依赖,协议层尚未完全分离。
配置使用 enable_virtual_memory、worker_memory_master_node_addr。
启用虚拟内存且 nnodes > 1 时,rank 0 在 worker_memory_master_node_addr
监听,收集各 worker 的内存 RPC 服务地址。各 worker 在此注册自己的服务地址,
rank 0 再连接这些地址,派发内存操作。这套注册服务独立于 master_node_addr
配置的执行 worker 注册服务。显式 CLI 参数优先于 JSON 配置。
本次本地资源、分布式协调器与 RPC C++ 类的拆分保持 protobuf 字段编号:
proto/model_memory_dist.proto 使用 ModelMemoryDist 服务和
GetVirtualKVCacheOffsets 方法。该方法服务于虚拟内存 KV 后端,返回共享物理页池
映射中的字节偏移,而非模型本地 tensor 视图内的偏移。heartbeat 的 JSON 字段为
virtual_memory_info。这些协议名称与旧 xtensor 版本不同,master、worker 和外部
heartbeat 消费方需要一起升级,不能混用重命名前后的 RPC 路由。
阅读时先区分状态、调度、执行:framework/ 定义请求、批次、缓存和模型接口;
scheduler/ 决定下一轮运行哪些工作;distributed_runtime/ 和 runtime/ 负责
派发并执行这些工作;models/ 或 python/models/ 中的模型描述网络计算。
跟踪一次聊天请求
Section titled “跟踪一次聊天请求”launch_server.py
处理 xllm serve 启动命令。进入 C++ 可执行程序后,main() 初始化配置,run()
通过 create_master()
创建 master。对于 llm 后端,LLMMaster 建立 engine、scheduler、tokenizer
和 request factory。master->run() 启动循环,提供服务的 rank 通过
server/xllm_server.cpp
启动 APIService。
请求与响应流程
Section titled “请求与响应流程”下面是文本生成的逻辑流程。它跨越队列、worker 通信和响应回调,并非一个同步调用栈。 调度器会重复执行其中的计算步骤,直到生成结束。
POST /v1/chat/completions -> HTTP route / APIService / ChatServiceImpl -> LLMMaster / LLMRequestFactory messages -> chat template -> prompt -> token IDs -> Request -> ContinuousSchedulerBase / SchedulerPolicy choose sequences and token budgets -> BatchGroup -> LLMEngine build inputs -> dispatch to worker ranks -> LLMWorkerImpl / Executor model forward -> logits -> sampling -> token results -> update sequences / RequestOutputDispatcher token IDs -> text -> RequestOutput -> ChatServiceImpl callback -> JSON response or SSE stream-
接收并解析请求。 路由在
server/xllm_server.cpp中注册。api_service.cpp、openai_request.cpp和chat_request_decoder.cpp处理 HTTP 请求体、规范化、参数校验及内部协议转换。ChatServiceImpl选择模型 master,准备聊天消息、生成参数和输出回调。 -
构造推理请求。
LLMMaster::handle_request()把工作交给请求线程池。LLMRequestFactory应用聊天模板,对提示词分词并校验,创建请求和序列状态。随后 master 调用scheduler_->add_request()将请求加入调度器。 -
选择下一轮执行的工作。
ContinuousSchedulerBase管理请求队列和执行循环。scheduler_policy.cpp中的PrefillFirstPolicy、DecodeFirstPolicy和UnifiedPolicy负责组批, 考虑 token/序列预算与缓存容量。想了解哪些请求会一起执行,应继续阅读策略文件; 策略选择与调度循环本身是分开的。 -
构造输入并派发。
LLMEngine::step()为各 DP batch 准备输入,通过WorkerClient派发给 worker。定位 token 位置、序列长度和缓存映射等问题时,先阅读batch/, 尤其是ForwardInputBuilder,再进入模型层。 -
执行模型并采样。
LLMWorkerImpl::step_internal()调用Executor, 获取模型输出和 logits,并通过sampling/选择输出 token。Executor 选择 C++ 或 Python 执行实现,具体边界见下一节。 -
返回结果,继续生成或结束。 Engine 的执行结果用于更新序列状态;调度器 处理批次输出和完成状态;
RequestOutputDispatcher生成解码后的RequestOutput并调用回调。聊天服务将结果组织成完整 JSON 响应, 或 Server-Sent Events(SSE)流。配置了推理过程或工具调用解析器时,它们也会 参与输出处理。停止条件见stopping_checker.h, 资源释放则继续跟踪调度器与缓存管理器。
C++ 与 Python 模型执行路径
Section titled “C++ 与 Python 模型执行路径”两条路径共用上面的 HTTP 服务和调度流程。--model_impl=python 选择 Python
模型执行,而请求、调度、缓存管理、worker 协调与采样仍由 C++ 负责。
| 关注点 | C++ 模型路径 | Python 模型路径 |
|---|---|---|
| 选择方式 | model_impl 为空,或 --model_impl=native | --model_impl=python,同时需要模型和平台支持 |
| 模型入口 | models/model_registry.h,可从 models/llm/qwen3.h 开始阅读 | models/llm/py_causal_lm.cpp、python/registry.py 与 python/models/qwen3.py |
| 执行方式 | core/runtime/ 中的基础 executor 和设备专用 executor | py_executor_impl.cpp 桥接到 ModelExecutor 及其 runner |
| 层与算子 | core/layers/、core/kernels/、core/platform/ | python/layers/、python/attention/、python/kernels_cuda/、python/kernels_npu/ |
| 权重加载 | core/framework/model_loader/、core/framework/state_dict/ 及模型/层的 loader | C++ 模型桥接、python/model_loader/ 及模型自身的加载逻辑 |
跟踪配置时,请区分三个选择:
- 服务后端(
llm、vlm、dit、rec)决定 master/engine 类型,从master_factory.cpp开始查看。 - 模型实现(
native或python)决定模型执行路径,从core/runtime/executor.cpp和model_config.cpp开始查看。 - 硬件与执行模式决定可用的设备算子和 eager/graph executor。Python 路径中,
python_graph_backend的处理见ModelExecutor与runners/。 可用组合依赖模型和平台;启用图模式不代表每一种 batch 都会走图执行。
xllm/pybind/ 提供面向用户的 Python 推理 API,例如
examples/generate.py
使用的接口;xllm/python/ 实现模型执行。使用 Python 推理 API 本身并不意味着
选择了 Python 模型实现。
更详细的说明见
C++ 框架与 Python 模型设计、
图模式设计以及
xllm/python/ 包说明。