返回博客

/ AI Infra

[Infra-6] xLLM:从推理引擎到集群服务系统

理解 xLLM 在大模型 Infra 中的位置:它不是一个模型,而是一套面向多类 AI 加速器的推理引擎与集群服务系统;重点拆解 Service-Engine 解耦、PD/EPD 分离、全局 KV Cache、动态调度和 MoE 优化。

12 minInfra · xLLM · LLM Serving · Distributed Inference

第一次看到 xLLM 这个名字时,很容易把它误会成又一个 LLM,或者把它和 2023 年那篇多模态模型论文 X-LLM 混在一起。其实它们不是同一类东西。

**xLLM 不是模型,而是大模型推理与在线服务的基础设施。**模型决定“算什么”;xLLM 决定“如何更快、更稳定、更经济地把模型跑在一组 AI 加速器上”。它和 vLLM、SGLang、TensorRT-LLM、MindIE 处在相近的技术层,只是它把单个推理引擎之外的集群服务、容错和资源调度也放进了整体设计。

Qwen / DeepSeek / GLM 等模型

xLLM:推理执行、缓存、调度、通信、服务

NPU / MLU / DCU / GPU 等加速器

xLLM 项目主页将其定位为面向国产 AI 加速器的高效推理框架;项目当前列出了昇腾 NPU、寒武纪 MLU(包括 MLU590)、摩尔线程、海光 DCU、沐曦和天数智芯等硬件支持。项目以 C++ 为主,已于 2026 年 7 月捐赠至开放原子开源基金会。

我会把 xLLM 理解为两个相连的层次:Engine 把一次模型推理高效执行出来,Service 把许多 Engine 组织成一个可运营的服务系统。

1. 它解决的不是一次 generate,而是一整个 serving 系统#

直接用 PyTorch 调用:

model.generate(...)

当然能得到文本。但生产服务里的困难通常不在“能否完成一次 forward”,而在请求持续到来、长度各不相同、实例会失败、硬件并不完全相同之后,系统如何保持吞吐、延迟和成本都可接受。

例如:

  • 新请求如何插进正在生成的 batch,而不是等上一批全部结束?
  • 32K prompt 会不会让正在输出的短请求突然卡住?
  • KV Cache 如何分配、复用、换出和跨节点移动?
  • 模型用 TP、EP 后,AllReduce 和 All-to-All 如何避免成为瓶颈?
  • Prefill 与 Decode 要不要由不同资源池服务?
  • 在线流量下降时,闲置资源能否给离线任务使用?
  • 某个实例故障后,未完成的请求如何恢复?

这些问题共同指向一个目标:

更高吞吐+更低延迟+更高资源利用率+更强可靠性\text{更高吞吐} + \text{更低延迟} + \text{更高资源利用率} + \text{更强可靠性}

所以推理框架的价值不只是让某个 kernel 更快。它还要把动态请求、模型执行、显存、网络和集群资源组织成一个可控的系统。

2. 核心结构:Service 和 Engine 解耦#

xLLM 最有辨识度的设计,是把集群服务层与推理执行层拆开:

                         用户请求


              ┌────────────────────────┐
              │      xLLM-Service      │
              │ 路由、排队、资源调度    │
              │ 弹性、健康检查、容错    │
              └───────────┬────────────┘
                          │ RPC

              ┌────────────────────────┐
              │      xLLM-Engine       │
              │ 模型执行、KV Cache      │
              │ TP/EP、算子、通信、图   │
              └───────────┬────────────┘

                 NPU / MLU / DCU / GPU

这里的边界很重要:Engine 不需要承担整个集群的调度决策,Service 也不应介入每一个 attention kernel 的执行。前者尽量贴近硬件和模型图,后者则面向请求、SLO 和资源池。

2.1 xLLM-Engine:把模型真正跑起来#

Engine 负责单机或一组并行卡上的执行路径,典型能力包括:

  • 权重加载、Transformer 和多模态模型执行;
  • continuous batching、chunked prefill 和请求级调度;
  • 分页式 KV Cache、prefix cache 与缓存换入换出;
  • attention、MoE 等关键算子的硬件优化;
  • Tensor Parallel、Expert Parallel,以及相应通信;
  • Graph Mode 和 speculative decoding。

它和 vLLM、SGLang runtime、TensorRT-LLM 所在的层次较接近:重点是让一台或一组设备尽可能高效地完成推理。

2.2 xLLM-Service:把许多 Engine 变成服务#

xLLM-Service 面向的是集群级问题。根据其项目说明,它负责统一调度在线和离线请求、在线优先的抢占、动态调整 PD 比例、面向多模态的 EPD 分配,以及实例故障检测与中断请求的重调度。

Engine 关心:这个 batch 在这组卡上怎样执行?
Service 关心:这个请求该去哪里、何时执行、失败后怎么办?

这使 xLLM 不只是“一个推理 runtime”,而是尝试覆盖:

推理引擎+集群控制与服务编排\text{推理引擎} + \text{集群控制与服务编排}

3. 调度:不要让请求因为长度不同而互相等候#

3.1 Continuous Scheduling#

静态 batching 的问题很直观。若一次放入三个请求:

A: 生成 20 tokens
B: 生成 200 tokens
C: 生成 1000 tokens

在一个必须等整批结束的模型里,A 很快完成后,原本属于它的资源会闲着,直到 B 和 C 都结束。continuous scheduling 会在 sequence 结束时立刻补进新请求:

step 1: A B C
step 2: A B C
A 完成
step 3: D B C

这不是“让每个请求更快”的魔法,而是降低 batch 中的空洞时间,让设备尽量保持有工作可做。对于在线 LLM serving,它是吞吐和并发能力的基础机制。

3.2 Chunked Prefill#

长 prompt 的 prefill 是另一种调度难题。一个 16K 或 128K 的请求若完整 prefill,可能持续占据计算资源,正在 decode 的请求就会出现明显的 token 间隔抖动。

chunked prefill 将长输入拆成可调度的小块:

L=L1+L2++LnL = L_1 + L_2 + \cdots + L_n
16K prompt

4K + 4K + 4K + 4K

调度器可以把这些 prefill chunk 与 decode token 交织执行。它的核心取舍是:宁可让长 prompt 的 prefill 分段完成,也要避免它一次性占住设备,从而保护 decode 的 TPOT 和尾延迟。

这和上一篇 PD 分离解决的是同一类矛盾:Prefill 更偏大计算,Decode 更偏高频访存和低抖动;只是不做物理分离时,chunked prefill 是在同一资源池内缓和两者冲突的一种方法。

4. 从 PD 到 EPD:按阶段而不是按“整次请求”分配资源#

一次纯文本 LLM 请求可分为:

Prompt → Prefill → Decode → 输出

Prefill 一次性处理输入、生成初始 KV Cache,通常具有更大的 GEMM 和更高并行度;Decode 每步生成少量 token,但反复读取历史 KV Cache,对显存带宽、通信和调度延迟更敏感。二者的瓶颈不同,分别扩缩容就有意义。

4.1 PD 分离#

xLLM 支持把两个阶段放到不同实例上:

请求

Prefill Pool ── KV Cache ──→ Decode Pool

                                输出

这让 Prefill Pool 可以以 TTFT 为主要目标,而 Decode Pool 可以以 TPOT / ITL 稳定性为主要目标。更进一步,Service 层可以随工作负载调整资源比例:长输入增多时增加 Prefill 资源;短输入、长输出的请求增多时增加 Decode 资源。

但 PD 分离不是“拆开就一定更快”。它把原先本地的状态交接变成了 KV Cache 传输,因此网络、拓扑、KV transfer 实现和缓存命中率会成为新的关键变量。没有足够快的数据路径,省下的干扰可能被搬运 KV 的时间抵消。

4.2 EPD 分离#

多模态请求在文本 LLM 前还有视觉或其他模态编码:

图像 / 视频

Encode Pool → Prefill Pool → Decode Pool

这就是 Encode-Prefill-Decode(EPD)分离。图像编码、文本 prefill、逐 token decode 的计算形态差异更大,若都挤在 decode 实例上,视觉编码很容易破坏输出稳定性。将三段分别放进资源池后,调度器才有机会按每段的实际压力做分配。

从服务系统的角度看,PD / EPD 分离并不属于 TP 或 EP 一类“模型内部并行”。TP 解决的是一层矩阵如何分到多卡,EP 解决的是 MoE 专家如何分布;PD / EPD 解决的是一次在线请求的不同阶段由哪些资源池承担

5. KV Cache:从显存中的临时状态,变成服务系统的数据资产#

自回归生成时,每一层都会保存已处理 token 的 Key 和 Value。其存储量会随并发、上下文长度和模型结构线性增长,粗略可写为:

MKVB×L×Nlayer×Nkv head×dheadM_{\mathrm{KV}} \propto B \times L \times N_{\mathrm{layer}} \times N_{\mathrm{kv\ head}} \times d_{\mathrm{head}}

其中,BB 是并发 sequence 数,LL 是上下文长度。长上下文与高并发同时出现时,KV Cache 往往成为推理系统最紧张、也最动态的资源。

5.1 分页管理和 prefix cache#

xLLM 使用分页式思路管理 KV Cache:逻辑 token block 不要求对应一块连续物理内存,而是通过页表映射到离散页。

逻辑 KV:    [Page 0][Page 1][Page 2][Page 3]
物理地址:   A       D       C       F

这样可以减少为每个请求预留大块连续显存所造成的碎片和浪费。若多个请求共享 system prompt、文档前缀或对话历史,prefix cache 还可以直接复用相同前缀的 KV,避免重复 prefill。

5.2 全局和分层 KV Cache#

项目文档还提到基于 Mooncake 的混合 KV Cache 管理:KV 不只存在加速卡的 HBM,也可以在主机内存或远端缓存节点中管理。

加速卡 HBM
    ↓  offload / prefetch
主机内存

远端 KV Cache 节点

这带来 KV offload、prefetch、跨节点路由和分布式缓存的可能性。代价是缓存层从“引擎内部细节”变成了分布式系统的一部分:何时迁移、放在哪里、是否值得预取、哪个 worker 有相同 prefix,都直接影响调度质量。

6. Graph、MoE 与通信:引擎层的三个硬问题#

6.1 Graph Mode:减少每步运行时开销#

在 eager 模式中,一个 Transformer step 可能要逐个下发 RMSNorm、GEMM、RoPE、Attention、AllReduce 等算子。对 decode 这种小步高频 workload,host 侧调度、kernel launch 和临时内存分配本身都可能变得可见。

Graph Mode 的目标是提前捕获或构建执行图,让一组操作以更少的运行时交互完成:

输入 → 已构建的计算图 → 一次提交执行

困难在于 LLM 的 batch size、sequence length 和 KV 长度会持续变化,不是简单的静态 shape。xLLM 的文档将参数化动态 shape、多图缓存和受控 tensor 内存池作为应对方向。Graph 不是万能开关,它通常需要在图复用率、内存占用和动态形状适应性之间平衡。

6.2 MoE:不只是在本地多几个 expert#

MoE 模型中,每个 token 只经过一部分专家:

yt=iTopK(g(xt))piEi(xt)y_t = \sum_{i \in \operatorname{TopK}(g(x_t))} p_i E_i(x_t)

当专家分布在不同卡上时,token 要经历 dispatch、expert compute 和 combine,All-to-All 通信很容易成为路径的一部分。更麻烦的是路由不会均匀:热点专家收到更多 token,其他设备即使先完成,也必须等待最慢专家。

xLLM 将 Expert Parallel、GroupGEMM / GroupMatmul、通信计算重叠和 EPLB(Expert Parallel Load Balancing)列为优化点。它们的共同目标是降低专家热点造成的长尾,而不是只提高某个 expert 的单卡算力。

6.3 让等待重叠而非累加#

从调度、模型图到 kernel 层,许多优化最终都在尝试把原本串行累加的等待变成重叠:

Ttotalmax(Tcompute,Tcommunication)T_{\mathrm{total}} \approx \max(T_{\mathrm{compute}}, T_{\mathrm{communication}})

而不是:

Ttotal=Tcompute+TcommunicationT_{\mathrm{total}} = T_{\mathrm{compute}} + T_{\mathrm{communication}}

例如一部分通信可以与下一阶段准备工作交叠,kernel 也可以把下一块数据的加载与当前 tile 的计算交叠。实际能重叠多少取决于模型图、通信库和硬件能力,但这个目标解释了为什么“计算快”不等于“服务快”。

7. 和 vLLM、SGLang、TensorRT-LLM 怎么看#

下表适合帮助建立位置感,不代表每个框架只能做表中所列的能力:

框架更突出的定位
vLLM通用推理引擎与生态;PagedAttention、continuous batching 等能力成熟
SGLangRadixAttention、结构化生成,以及复杂请求与 agent 场景的编排能力
TensorRT-LLM面向 NVIDIA GPU 的深度 kernel、图和量化优化
MindIE华为昇腾的软件栈与推理方案
xLLM多类国产加速器适配,同时覆盖 Engine 和集群 Service 的解耦设计

若一定要做粗略映射,xLLM-Engine 接近 vLLM / SGLang runtime / TensorRT-LLM 所在的执行层;xLLM-Service 则覆盖更上层的路由、资源池、PD 控制、故障恢复与集群调度。它不是简单复制某一个引擎,而是试图把“单实例推理”和“生产服务系统”一起设计。

项目技术报告曾给出部分 Qwen 配置下、在相同 TPOT 约束中相对 MindIE 和 vLLM-Ascend 的吞吐结果。这样的数字只能视作特定版本、模型、硬件、输入输出分布和 benchmark 配置下的项目方测量,不能直接推广到其他硬件或生产负载。真正比较框架时,至少应固定模型、精度、并行策略、请求分布、SLO 和软件版本。

8. 对 MLU590 推理实验的实际意义#

如果工作重点是寒武纪 MLU590 上的 vLLM、PD 分离和性能测试,xLLM 最直接的意义是提供了一个明确的对照对象:它公开列出 MLU590 支持,并把 Engine 层性能和 Service 层资源调度放在同一系统中。

我会把对比拆成两层,而不是只比较一个总 token/s:

第一层:单实例 / 单资源池
  xLLM-MLU vs vLLM-MLU
  TTFT、TPOT、输出吞吐、最大并发、KV Cache 利用率
 
第二层:服务系统
  混合 PD vs 分离 PD
  长 prompt 对 decode P99 ITL 的影响、KV transfer 开销、资源比例变化后的 SLO

特别值得控制的变量包括:模型与量化精度、MLU 数量和拓扑、TP/EP 配置、prompt / output 长度分布、并发模型、prefix 命中率,以及 TTFT 和 TPOT 的约束。只测平均吞吐很容易掩盖真实服务体验:一个系统可能 tokens/s 很高,但长 prompt 到来时 decode 的 P99 已经不可接受。

9. 最后怎么记住 xLLM#

我会用下面一句话概括它:

xLLM 是一个面向多类 AI 加速器的大模型推理系统:
Engine 负责高效执行模型,Service 负责把推理资源组织成可调度、可扩缩、可容错的集群服务。

它的关键不是又发明了一种 LLM 架构,而是把 LLM serving 中相互关联的几个难题放到一起处理:动态请求调度、Prefill / Decode / Encode 的资源分离、KV Cache 的分页与全局化、MoE 通信与负载均衡,以及线上线下混部和实例故障恢复。

也因此,xLLM 的价值不该只用单一 benchmark 数字判断。它更值得从一个系统问题来观察:在给定硬件和真实请求分布下,它能否同时把 TTFT、TPOT、吞吐、缓存利用率和服务可靠性维持在可接受范围内。

参考资料#