现代 LLM 推理引擎剖析:从一次 forward 到千卡服务
现代 LLM 推理引擎剖析:从一次 forward 到千卡服务
前情说明:这是一份"读源整理"——从 fin 那三篇讲商业与架构宿命的姊妹篇之后,视角切换到工程实现层:一个真正跑在生产上的 LLM 推理引擎,内部长什么样? 素材来自 vLLM 官方博客 2025-09-05 那篇 41 分钟长文 《Inside vLLM: Anatomy of a High-Throughput LLM Inference System》(作者 Aleksa Gordic,vLLM core contributor)。本文以中文重构叙事,保留原文技术细节。所有技术判断归属原作者。
引子:一个 curl 请求背后发生了什么
当你在终端敲下:
curl -X POST http://localhost:8000/v1/completions -d '{
"model": "TinyLlama/TinyLlama-1.1B-Chat-v1.0",
"prompt": "The capital of France is",
"max_tokens": 50
}'
半秒钟之后,Paris 蹦出来。看起来是一次简单的 HTTP 调用。但底下发生了什么?
一个正在生产环境里跑的现代 LLM 推理引擎,需要同时完成的事情包括:
- 把 prompt 分词、hash 后去 KV cache 里找有没有匹配过的前缀(prefix caching)
- 把这次请求和同时进来的几十上百个请求打包成一批(continuous batching)
- 决定这一步做 prefill 还是 decode、要不要切成 chunk(chunked prefill)
- 从 KV cache 池里分配 paged 内存块(PagedAttention)
- 如果开了 speculative decoding,先让小模型草稿几个 token,再让大模型批量校验
- 如果模型太大装不下单卡,把 forward 分散到多个 GPU 的 tensor parallel group
- 如果一台机器装不下,还得跨节点做 pipeline parallel
- 如果 QPS 高,前面还得挂一个 DP 负载均衡器决定这次请求给哪个副本
每一层都在解决一个具体的物理约束。这篇文章我们把这套系统一层层剥开,从最里面的 forward pass 一路讲到千卡集群的分布式服务。
按 vLLM 官方博客那篇长文的骨架,可以拆成五层:
- 引擎核心:调度、Paged Attention、Continuous Batching
- 高级特性:Chunked Prefill、Prefix Caching、Guided Decoding、Speculative Decoding、Disaggregated P/D
- 单机多 GPU:从 UniProc 到 MultiProc Executor
- 分布式服务:多节点 DP、协调器、API server
- 性能哲学:Latency vs Throughput 的 roofline
一、引擎核心:调度、Paged Attention、Continuous Batching
1.1 一个最简单的 vLLM 例子
先看看单机同步模式下 vLLM 是怎么用的:
from vllm import LLM, SamplingParams
prompts = ["Hello, my name is", "The president of the United States is"]
sampling_params = SamplingParams(temperature=0.8, top_p=0.95)
llm = LLM(model="TinyLlama/TinyLlama-1.1B-Chat-v1.0")
outputs = llm.generate(prompts, sampling_params)
这个例子跑的是最裸的模式——没有 web、没有异步、单 GPU、没有分布式。但它已经用上了核心的几个技术:PagedAttention、continuous batching、KV cache 管理。
1.2 LLM Engine 的骨架
一个 LLM Engine 由四大块组成:
- vLLM Config:所有旋钮(模型、cache、并行度)
- Processor:把原始输入变成
EngineCoreRequest(tokenize、validate) - Engine Core Client:单进程时是
InprocClient,扩容后会变DPLBAsyncMPClient - Output Processor:把 raw 输出变成用户看到的
RequestOutput
Engine Core 里面又有:
- Model Executor:驱动 forward pass(单卡时是
UniProcExecutor,多卡时是MultiProcExecutor) - Structured Output Manager:负责 guided decoding
- Scheduler:决定下一步跑哪些 request
- policy: FCFS 或 priority
- waiting queue / running queue
- KV cache manager——PagedAttention 的心脏
1.3 KV Cache Manager:PagedAttention 的核心数据结构
KV cache manager 维护一个 free_block_queue——可用 KV cache 块的池子(通常几十万个,取决于 VRAM 和 block size)。
一个标准 transformer layer 的 block 大小:
2 (key/value) × block_size (default=16) × num_kv_heads × head_size × dtype_num_bytes
PagedAttention 的关键洞察:不再给每个 request 预分配连续内存,而是把 KV 切成固定大小的 block(默认 16 token 一块),按需分配。用一张 block table(req_to_blocks)映射 request → block 列表。
这样做的好处:
- 没有内部碎片(不用预留最坏情况的连续空间)
- 可以做 prefix caching(同一 block 可以被多个 request 共享)
- 可以做抢占(低优先级 request 的 block 可以还回 pool)
1.4 Continuous Batching:不用 padding 的批处理
传统批处理需要把不同长度的 request 用 padding 补齐——浪费算力,还得等最慢的那个跑完才能接下一批。
Continuous batching 的思路是:
forward pass 把整个 batch 展平 (flatten) 成一个长的 "super sequence"。用 position indices 和 attention mask 保证每个 sequence 只看自己的 token。
也就是把 [req1_prompt, req1_decode, req2_prompt, req3_decode, ...] 拼成一整条向量喂进去,配合自定义 kernel。每一步(step)结束都能:
- 新 request 立刻加进来(不用等这一批跑完)
- 已完成的 request 立刻踢出去
- prefill 和 decode 混在一起跑(V1 相比 V0 的关键升级——V0 只能纯 prefill 或纯 decode)
这就是"continuous"的含义:batch 是流动的、不是静态的。
1.5 Scheduler:一步 (step) 里发生的事
引擎的 step() 函数每次做三件事:
- Schedule:决定这一步跑谁
- Forward pass:跑模型、采样
- Postprocess:token 加到 request、detokenize、检查停止条件、清理
Scheduler 内部两种 workload:
| 类型 | 特征 | 瓶颈 |
|---|---|---|
| Prefill | 一次 forward 处理所有 prompt token | 算力 bound(compute-bound) |
| Decode | 每次只处理最新一个 token(KV 已缓存) | 带宽 bound(memory-bandwidth-bound) |
Scheduler 优先跑 decode(因为已经在 running queue 里了):
- 算这次要生成多少新 token(speculative decoding 时不止 1 个)
- 调
allocate_slots分配 KV block - 扣减 token budget
再从 waiting queue 里挑 prefill 补进来:
- 查 prefix cache 有没有命中(如果开了)
- 分配 block
- 状态从 WAITING → RUNNING
1.6 Forward Pass 内部
调 execute_model 后:
- Update states:踢出完成的 request,更新 KV block 索引
- Prepare inputs:CPU→GPU 拷贝、构建 attention metadata、
slot_mapping - Forward pass:跑模型(用自定义 paged attn kernel)——所有序列展平成一条 super sequence
- Gather last-token states:抽出每个 sequence 最后一位的 hidden state 算 logits
- Sample:按 sampling config 采样
Forward 有两种执行模式:
- Eager 模式:标准 PyTorch forward
- Captured 模式:重放预先捕获的 CUDA Graph——省 kernel launch overhead
CUDA Graph 是把整个 forward 的 GPU 工作录成一个 DAG,重放时不用再一层一层调用 kernel。这个优化对 decode(GPU 空转严重)的收益特别大。
二、高级特性:把引擎推向生产级
2.1 Chunked Prefill:不让长 prompt 独占引擎
问题:一个 100k token 的 prompt 跑一次 prefill,会独占整个 engine step,其他 request 全部要等它。
解法很简单——把 prefill 切成小块(比如每块 8 token):x-y-z,一个 step 只跑一块。
实现极其简单:给 step 加一个 token 上限。如果这次请求要跑的 token 数 > long_prefill_token_threshold,就砍成阈值。剩下的下一步接着跑。
代价:一个长 prompt 要 ≥3 个 step 才跑完。收益:其他 request 不用饿死。
2.2 Prefix Caching:默认开启的降维打击
这是 PagedAttention 最闪耀的地方。看这段代码:
long_prefix = "<比 16 个 token 长的公共前缀>"
outputs = llm.generate(long_prefix + prompts[0], sampling_params)
outputs = llm.generate(long_prefix + prompts[1], sampling_params)
两次调用的 prompt 前面都是同一个 long_prefix。传统实现每次都要重新算一遍 KV。Prefix caching 让这个前缀只算一次,后面所有共享该前缀的请求直接复用。
关键实现(hash_request_tokens):
- 把
long_prefix + prompt切成 16 token 的 chunk(对齐 block boundary) - 每个完整 chunk 算一个 hash(内置 hash 或 SHA-256)——hash 组合了前一 block 的 hash + 当前 tokens + 可选 metadata(MM hash、LoRA ID、cache salt)
- 每个 BlockHash 存进
cached_block_hash_to_block
后续请求进来:
- 同样 hash 化 prompt
find_longest_cache_hit线性查找匹配的 block- 找到就直接复用(引用计数 +1),跳过 forward 中该前缀部分的计算
对典型 agentic workload(system prompt 长且共享)——prefix caching 可以让 prefill 加速 5-10 倍,因为 system prompt 部分完全不用重算。
vLLM V1 默认开启 prefix caching。
PagedAttention 和 Prefix Caching 是同一个东西的两面——原文有一句点睛:"如果你理解了 prefix caching 这个例子,你也理解了 paged attention 是怎么工作的。" 因为二者共用同一个 block table + free block pool 的数据结构。
2.3 Guided Decoding:用 FSM 卡住采样空间
场景:你想让模型只输出 "Positive" 或 "Negative",或者一段严格的 JSON。
传统做法是靠 prompt engineering 求菩萨保佑。Guided decoding 直接把语法编译成有限状态机(FSM),每一步 sampling 用 bitmask 屏蔽掉不合法的 token。
- 起手:FSM 只允许 "P" 或 "N"
- 如果采到 "P",进入 "Positive" 分支,下一步只允许 "o"
- 如果采到 "N",进入 "Negative" 分支
- ……
强大到什么程度?Chomsky 3 型(正则)→ 2 型(上下文无关,覆盖大部分编程语言)都能表达。
vLLM 里的实现流程:
- Engine 构造时创建
StructuredOutputManager+_grammar_bitmasktensor - 请求进来时状态
WAITING_FOR_FSM,异步编译 grammar(backend 用 xgrammar 等三方库) - 编译完 → 状态转
WAITING→ 加入调度 - Forward 出 logits 后,
_grammar_bitmask扩展成 vocab_size,非法 token 的 logits 设为 -∞ - 采样后调
accept_tokens推进 FSM 状态
bitmask 是压位存储:如果 vocab_size=32,一个 32 位整数就能表达;vocab_size=100k 就是几千个 32 位整数拼起来。扩展率是 32×。
这个技术对Function Calling / JSON Mode / SQL 生成是刚需——OpenAI 的 response_format: json_object 底层就是这类实现。
2.4 Speculative Decoding:让小模型给大模型打草稿
Decode 阶段慢得离谱的根源是:每生成 1 个 token 都要把整个模型权重从 HBM 读一遍。B200 也扛不住。
Speculative decoding 的思路:
- Draft(草稿):小模型跑一次,一口气提出 k 个候选 token
- Verify(校验):大模型跑一次 forward,同时验证这 k 个 token + 多算 1 个 → 得到 k+1 个 candidate
- Accept/Reject:从左到右扫这 k 个 token:
- 若
p_large(token) ≥ p_draft(token)→ 接受 - 否则以
p_large/p_draft的概率接受 - 遇到第一次拒绝就停,从修正分布
(p_large - p_draft)采一个新 token
- 若
- Bonus:如果 k 个全接受,大模型的第 k+1 个采样也白给一个
数学保证:在期望意义下,输出分布和纯大模型采样完全等价——不是近似,是严格等价。但一次大模型 forward 可以吐 1~k+1 个 token。
vLLM V1 不支持独立的小 draft model(比如 Llama 70B 配 Llama 7B),而是用三种更快的方案:
| 方法 | 原理 |
|---|---|
| n-gram | 从 prompt 里找匹配窗口,命中就把后面 k 个 token 当草稿 |
| EAGLE | 大模型"外科手术"——保留 embedding 和 LM head,中间 transformer 换成 lightweight MLP,微调 |
| Medusa | 在大模型 embedding 之后加多个辅助线性头,并行预测未来 k 个 token |
为什么 vLLM 不做独立 draft model? 因为跑独立小模型本身开销就不小,权重加载、kernel launch、scheduling 全要重来一遍。EAGLE/Medusa 复用大模型的 hidden state,几乎零开销。
在 vLLM 里启用只要:
speculative_config = {
"method": "ngram",
"prompt_lookup_max": 5,
"prompt_lookup_min": 3,
"num_speculative_tokens": 3,
}
llm = LLM(model=..., speculative_config=speculative_config)
2.5 Disaggregated P/D:Prefill 和 Decode 各奔前程
回到 Section 1.5 里那张表——prefill 是 compute-bound,decode 是 memory-bandwidth-bound。
把它们跑在同一批 GPU 上会有两个问题:
- 长 prefill 抢 decode 的 GPU cycle → TTFT 波动 + ITL 抖动
- GPU 采购策略被迫两头兼顾(既要算力又要带宽)
Disaggregated P/D 的方案:N 台 vLLM 只跑 prefill,M 台只跑 decode——中间用一个 KV cache 服务做接力。Prefill worker 算完 KV 写出去,Decode worker 拉过来接着算。
架构简单,但工程上有几个细节:
- Connector 抽象:vLLM 用
KVTransferConfig + Connector抽象 KV 迁移。示例用SharedStorageConnector(写文件系统)方便调试;生产上用LMCache+ NVIDIA NIXL 后端做零拷贝 RDMA - 调度插桩:Scheduler 在处理 prefill 请求时先调
connector.get_num_new_matched_tokens——decode 侧可能已有 cache 命中,命中数直接加到 prefix cache 命中数上 - 元数据:
connector.build_connector_meta决定 prefill 是"写"、decode 是"读" - 同步窗口:forward 前进入 context manager
- 进入时
start_load_kv:decode 从外部拉 KV - 退出时
wait_for_save:prefill 阻塞直到 KV 上传完成
- 进入时
- 只在 decode 首步拉一次:decode 侧只在第一步从外部拉 KV,后续自己算自己存
这个设计让 CSP 可以针对不同角色用不同硬件——prefill 用高算力卡(H200/B200),decode 用高带宽卡或未来的 LPU/SRAM 方案。GTC 2026 Nvidia 的 CPX + Rubin + LPU 异构架构,就是这个思路的极致化。
三、Scale-Up:从 UniProc 到 MultiProc Executor
到目前为止,一切都在单卡。但模型大到 70B/405B 时,单卡装不下。
并行策略优先级:
- Tensor Parallel (TP):intranode 用(NVLink 快),把每层参数横切
- Pipeline Parallel (PP):internode 用(网络慢),把模型纵切
- Expert Parallel (EP):只对 MoE 有意义
- Data Parallel (DP):完整复制模型跑多份
优先级原因:intranode 带宽 >> internode 带宽,TP 通信量大所以要留在节点内;PP 通信量小可以跨节点。
MultiProcExecutor 就是把 UniProcExecutor 拷贝 world_size 份的编排层:
MultiProcExecutor
│
├── Worker 0 (rank 0, driver) - GPU 0
├── Worker 1 - GPU 1
├── Worker 2 - GPU 2
│ ...
└── Worker 7 - GPU 7
跨进程协调用 shared memory 实现的两个消息队列:
rpc_broadcast_mq:父进程广播 work item 给所有 workerworker_response_mq:worker 把结果回传(只有 rank 0 driver 的 output 会被收集)
每个 worker 是一个 daemon process,跑同样的 init device / load model 流程,只是 tensor 被切片。
对 engine 来说这一切完全透明——execute_model 一个调用就搞定,底下是 UniProc 还是 MultiProc 完全无感。
四、Scale-Out:分布式服务
模型能跑之后,下一步是"服务化"——多副本、负载均衡、API server、跨节点。
假设你有 2 台 8×H100 节点,要跑 TP=4, DP=4 的部署(每节点 2 个副本,共 4 副本):
# 节点 1:headless
vllm serve <model> --tensor-parallel-size 4 --data-parallel-size 4 \
--data-parallel-size-local 2 --data-parallel-start-rank 0 \
--data-parallel-address <master-ip> --data-parallel-rpc-port 13345 \
--headless
# 节点 2:带 API server
vllm serve <model> --tensor-parallel-size 4 --data-parallel-size 4 \
--data-parallel-size-local 2 --data-parallel-start-rank 2 \
--data-parallel-address <master-ip> --data-parallel-rpc-port 13345
4.1 Engine Core 侧(每个 DP 副本)
每个 DP 副本是一个 DPEngineCoreProc 进程,跑三个线程:
- Input thread:阻塞在 input socket,收到请求就丢进
input_queue - Main thread:从
input_queue取,跑engine.step(),结果丢进output_queue - Output thread:从
output_queue取,通过 output socket 送回 API server
副本之间通过 NCCL DP group 协调(尤其是 MoE 模型需要 lockstep)。
Dummy step 机制:即使某个 DP 副本这一步没请求,也要跑一次 dummy forward 来参与 NCCL 同步——否则整个 DP group 会卡死。MoE 模型必需,非 MoE 现在也是这么做(等未来解耦)。
4.2 API Server 侧
AsyncLLM 包装了一整套 asyncio 任务:
- 每个 client 请求:一个 asyncio task 进入 generate path
process_outputs_socket+output_handler:处理返回消息run_engine_stats_update_task:和 DP coordinator 保持通信
DP Coordinator(独立进程):
- 周期性发送负载均衡信息(queue size, waiting/running 数)给 frontend
- 处理
SCALE_ELASTIC_EP命令(只有 Ray backend 支持动态扩缩容) - 发
START_DP_WAVE事件同步"wave"状态
负载均衡策略(get_core_engine_for_request)——选得分最低的副本:
score = len(waiting) * 4 + len(running)
FastAPI + Uvicorn 提供 HTTP 端点(/v1/completions 等 OpenAI 兼容 API)。
4.3 完整请求生命周期
回到最开始那个 curl:
curl → FastAPI OpenAIServingCompletion.create_completion
→ AsyncLLM.generate (async task)
→ DPAsyncMPClient.add_request_async
→ get_core_engine_for_request (LB 选副本)
→ 发到该副本 input_socket
→ Input thread 收到 → input_queue
→ Main thread → engine.step() → scheduler → MultiProcExecutor
→ 8 个 GPU worker 各跑 TP=4 部分
→ 收集 rank 0 结果 → output_queue
→ Output thread → output_socket
→ AsyncLLM output_handler → FastAPI JSONResponse
→ Uvicorn 回 client
用户看到的一个 curl,是几十个 asyncio task、几十个进程、几百次 shared memory 拷贝合作的产物。
五、性能哲学:Latency vs Throughput 的 Roofline
现在 zoom out——怎么衡量一个推理系统好不好?
5.1 核心指标
| 指标 | 定义 |
|---|---|
| TTFT (Time To First Token) | 请求到达 → 第一个输出 token |
| ITL (Inter-Token Latency) | 相邻两个 token 之间 |
| TPOT (Time Per Output Token) | 一个请求的平均 ITL |
| E2E Latency | 请求提交 → 最后一个 token = TTFT + Σ(ITLs) |
| Throughput | token/s 或 req/s |
| Goodput | 满足 SLO 的 throughput(例如 TTFT<500ms 的那部分 token) |
Latency 关心 TTFT(chat / copilot 场景),Throughput 关心 tokens/s(batch 推理 / 数据生成)。
5.2 Roofline:为什么这俩天然对立
假设 weight I/O 主导(短序列)。看 batch size B 怎么影响一次 decode step:
- B ↓ → 1:ITL 低,用户体感快,但 GPU 大量空转 → throughput 低
- B ↑ → ∞:ITL 涨,但 weight I/O 被摊到更多 token → throughput 高
关键阈值 B_sat:
- B < B_sat:memory-bound,一步时间几乎不变(一次读 weight 顺便算 1 个 vs 算 10 个 token 差不多)
- B > B_sat:compute-bound,一步时间随 B 线性涨
step time
│
│ ╱ compute-bound (B > B_sat)
│ ╱
│──────────╱ ← B_sat 拐点
│─────────
│ memory-bound (B < B_sat)
└──────────────→ batch size
这就是为什么"低延迟"和"高吞吐"是两个几乎对立的目标——你要么让 B 小、单请求快、GPU 半空;要么让 B 大、GPU 满载、单请求排队。
生产系统的实际策略:根据 SLO 反推最优 B——例如"TTFT < 500ms、TPOT < 50ms 时吞吐最大"。vLLM 有一整套 auto-tuner 干这个。
六、把整套东西拼起来
从"一次 forward"到"千卡服务"的完整技术栈:
┌────────────────────────────────────────────────────────────────┐
│ 用户视角: 一次 curl │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 服务层 API Server + DP Coordinator + Load Balancer │
│ (FastAPI/Uvicorn, ZMQ, asyncio) │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 副本层 DP 副本 x N (每副本是 DPEngineCoreProc) │
│ (3 线程: input / main / output) │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 并行层 MultiProcExecutor (TP + PP) │
│ (world_size 个 daemon Worker 进程) │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 引擎核心 Scheduler + KV Cache Manager │
│ (PagedAttention block table, prefix cache hash map) │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 高级特性 Chunked Prefill / Prefix Caching / Guided Decoding │
│ Speculative Decoding / Disaggregated P/D │
└────────────────────────────────────────────────────────────────┘
↓
┌────────────────────────────────────────────────────────────────┐
│ 执行层 Model Runner + CUDA Graph │
│ (super-sequence flatten, custom paged attn kernel) │
└────────────────────────────────────────────────────────────────┘
↓
GPU 硬件
如果只能记住三件事:
-
PagedAttention 是所有一切的基石——block table + free block pool 这个数据结构,同时支撑了 continuous batching / prefix caching / preemption / disaggregated P/D。理解了 prefix caching 就理解了 paged attention。
-
推理引擎的核心永远是 scheduler——决定谁跑、跑多少、什么时候跑,才是引擎的价值所在。forward pass 大家都会写;scheduler 决定生死。
-
每一层抽象都在解决一个物理约束:paged 解决内存碎片、continuous batching 解决 padding、prefix caching 解决重复计算、speculative decoding 解决 decode 带宽墙、disaggregated P/D 解决 compute/memory 性能剖面差异、MultiProcExecutor 解决单卡 VRAM 上限、DP + Coordinator 解决 QPS 上限。每一步都对应一个具体的硬件瓶颈。
七、承前启后
前几篇 fin 的姊妹篇讲的是:为什么 HBM 会代代翻倍、为什么 CPU 会回归、为什么训练时代黄昏推理接棒——那些是宿命论层面的判断。
这一篇讲的是工程实现层:当整个行业都同意"推理是未来"的时候,一个真正跑得动千亿参数模型的推理引擎,代码层面到底长什么样。
有意思的是,vLLM 现在的架构选择,几乎每一项都能对应到 fin 讲的那些趋势:
| fin 讲的宿命 | vLLM 的实现 |
|---|---|
| Token throughput = HBM size × HBM 带宽 | PagedAttention 把 KV 存 HBM,KV manager 榨干 HBM 每一 byte |
| Prefill 和 Decode 性能剖面完全不同 | Disaggregated P/D + Chunked Prefill + Continuous Batching |
| Speculative decoding 是必然 | n-gram / EAGLE / Medusa 内建,V1 支持 |
| CPU 是永远在忙的 orchestrator | AsyncLLM + DP Coordinator + 3 线程 per 副本 |
| Test-time compute / reasoning 崛起 | Guided decoding + FSM + 长 context 优化 |
架构师的宿命论 + 工程师的实现层,合起来才是完整的 AI Infra 图景。
下一篇会挑一个具体机制往深挖——比如 SGLang 的 RadixAttention 和 vLLM PagedAttention 的架构哲学差异,或者 Speculative Decoding 的算法全家桶(EAGLE / P-EAGLE / DFlash / DSpark / MTP)。
附:素材来源
主线
- vLLM Blog · Inside vLLM: Anatomy of a High-Throughput LLM Inference System(2025-09-05, Aleksa Gordic)——本文全部技术骨架
- 原文对应代码基线:vLLM commit 42172ad(2025-08-09)
引用论文
- PagedAttention(vLLM 原论文, SOSP'23)
- EAGLE、Medusa(speculative decoding drafters)
- Jenga(hybrid KV cache allocator, 用于 Jamba 等混合模型)
- xgrammar(guided decoding backend)
姊妹篇(fin 商业/宿命视角三部曲)
整理于 2026-07-31。原文技术细节归属 vLLM 和 Aleksa Gordic。中文表达可能有解读偏差,请以原文为准。

Written by
Zoe
AI Infra Engineer · LLM Serving · GPU/RDMA · 造工具的偏执狂