跳转到内容
中

代码结构

建议按以下顺序阅读,先看列出的函数及其直接调用的代码,再深入具体平台的实现。

顺序代码入口帮你回答的问题
1xllm/xllm.cpp:main()、run()配置、master 和 HTTP 服务如何连接起来?
2chat_service_impl.cpp:ChatServiceImpl::process_async_impl()聊天消息如何转换为内部请求,并绑定输出回调?
3llm_master.cpp:LLMMaster::handle_request()、run()请求如何进入调度器?谁在驱动调度循环?
4continuous_scheduler.cpp:ContinuousSchedulerBase::step()一轮批次如何被调度、执行并处理结果?
5llm_engine.cpp:LLMEngine::step()批次如何发送到各个 worker,执行结果如何汇总?
6llm_worker_impl.cpp:LLMWorkerImpl::step_internal()模型执行、logits 计算和 token 采样发生在哪里?

第一遍先沿着未启用投机解码、PD 分离和调度重叠的路径阅读。这些功能是在基本流程 上增加分支,理解主流程后再展开会更容易。

概念在本页中的含义源码入口
Token、prefill、decodeTokenizer 将文本转换成 token ID。Prefill 处理输入提示词;decode 复用已有计算状态,继续生成输出。Chunked prefill 把提示词拆到多个调度轮次处理。tokenizer/、scheduler_policy.cpp
Request一次推理请求,包含生成参数、输出回调以及一个或多个 sequence。request.h、request_state.h
Sequence一条持续增长的 token 序列,记录生成进度、停止状态和缓存状态。同一个请求可以有多个候选序列。sequence.h
Batch、BatchGroupBatch 是一次执行步骤选中的工作集合;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 cacheKV cache 保存可复用的注意力状态;block manager 分配和回收缓存容量;prefix cache 让满足复用条件的请求共享已缓存的提示词前缀。kv_cache/、block/、prefix_cache/
Logits 与采样Logits 是模型对词表中各 token 给出的分数;采样根据生成参数,从这些分数中选择下一个 token。sampling/
Master、engine、worker、executorMaster 连接请求处理与调度;engine 协调各 worker 执行批次;worker 管理设备上的执行;其中的 executor 选择模型的执行方式。distributed_runtime/、runtime/

下面只列出用于定位代码的主要目录,并非完整文件清单。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 和权重。各类资源的映射与分配策略归各自模块管理, 本地资源由 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 -.-> remaining

framework/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/ 中的模型描述网络计算。

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。

下面是文本生成的逻辑流程。它跨越队列、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
  1. 接收并解析请求。 路由在 server/xllm_server.cpp 中注册。 api_service.cpp、 openai_request.cpp 和 chat_request_decoder.cpp 处理 HTTP 请求体、规范化、参数校验及内部协议转换。ChatServiceImpl 选择模型 master,准备聊天消息、生成参数和输出回调。

  2. 构造推理请求。 LLMMaster::handle_request() 把工作交给请求线程池。 LLMRequestFactory 应用聊天模板,对提示词分词并校验,创建请求和序列状态。随后 master 调用 scheduler_->add_request() 将请求加入调度器。

  3. 选择下一轮执行的工作。 ContinuousSchedulerBase 管理请求队列和执行循环。 scheduler_policy.cpp 中的 PrefillFirstPolicy、DecodeFirstPolicy 和 UnifiedPolicy 负责组批, 考虑 token/序列预算与缓存容量。想了解哪些请求会一起执行,应继续阅读策略文件; 策略选择与调度循环本身是分开的。

  4. 构造输入并派发。 LLMEngine::step() 为各 DP batch 准备输入,通过 WorkerClient 派发给 worker。定位 token 位置、序列长度和缓存映射等问题时,先阅读 batch/, 尤其是 ForwardInputBuilder,再进入模型层。

  5. 执行模型并采样。 LLMWorkerImpl::step_internal() 调用 Executor, 获取模型输出和 logits,并通过 sampling/ 选择输出 token。Executor 选择 C++ 或 Python 执行实现,具体边界见下一节。

  6. 返回结果,继续生成或结束。 Engine 的执行结果用于更新序列状态;调度器 处理批次输出和完成状态; RequestOutputDispatcher 生成解码后的 RequestOutput 并调用回调。聊天服务将结果组织成完整 JSON 响应, 或 Server-Sent Events(SSE)流。配置了推理过程或工具调用解析器时,它们也会 参与输出处理。停止条件见 stopping_checker.h, 资源释放则继续跟踪调度器与缓存管理器。

两条路径共用上面的 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 和设备专用 executorpy_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/ 及模型/层的 loaderC++ 模型桥接、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/ 包说明。