从单用户到万级并发:构建工业级推理基座
序幕:部署的陷阱——为什么 Demo 很快,生产很慢
你兴致勃勃地在本地环境跑通了一个简单的推理脚本:加载模型,输入 Prompt,模型一个字一个字蹦了出来,速度飞快。 你觉得大功告成了。 然而,当 100 个真实用户同时点击你的产品,后端服务瞬间陷入了“死亡螺旋”:
- 第一个用户等了 30 秒才看到第一个字(TTFT 爆炸)。
- 第二个用户的请求直接因为显存溢出(OOM)而崩溃。
- 你的 GPU 核心利用率高达 100%,但每秒产出的总 Token 数却低得可怜。
这就是项目 27 要解决的硬核工程问题:Serving(服务化)。在这一章,我们将拆解现代推理引擎的黑盒,看它们如何通过精妙的调度和内存管理,将昂贵的 GPU 转化为高效的“Token 生产力工厂”。
第一章:vLLM 的革命——PagedAttention 与内存的零浪费
如果说有什么技术真正定义了 2024 年的大模型服务标准,那一定是 vLLM 项目提出的 PagedAttention。它彻底改变了我们管理 GPU 显存(尤其是 KV Cache)的方式。
1. 痛点:KV Cache 的内存碎片黑洞
在传统的推理引擎(如 HuggingFace 原生实现)中,KV Cache 必须在显存中申请一段连续的空间。
- 预留的恐惧:因为系统不知道用户会聊多久,它必须为每个用户预留最大长度的空间(比如 4096 个位置)。
- 内部碎片:用户只问了三个字,剩下 4000 个位置的显存就被死死霸占着,谁也不能用。
- 外部碎片:由于长度不确定,请求结束后的空隙很难被再次利用。
- 统计结果:在传统模式下,高达 60%-80% 的 GPU 显存处于这种“名义上在用,实际上闲置”的低效状态。
2. 解法:像操作系统管理内存一样管理显存
vLLM 借鉴了操作系统中“虚拟内存”的概念:
- 它将 KV Cache 切成一小块一小块的“页(Pages)”,每页包含固定数量(如 16 个)Token。
- 这些页在物理显存中不需要连续,通过一个“页表(Page Table)”进行逻辑映射。
- 奇迹发生了:由于可以按需动态申请,显存浪费率从 60% 降到了 4% 以下。这意味着在同样的硬件上,你可以支持 3 倍甚至更多的并发用户。
第二章:SGLang 的超越——Prefix Cache 与结构化推理
如果 vLLM 解决了“空间”问题,那么 SGLang 则解决了“冗余”和“格式”问题,它是目前 Agent 和长上下文场景下的绝对标杆。
1. Prefix Cache(前缀缓存):给知识装上加速器
在很多业务场景中,不同的请求往往共享同样的背景知识。比如在一个基于公司年报的 RAG 系统中,所有的用户问题前面都带着那 10 万字的背景。
- 传统引擎:每一个新请求,模型都要从头计算一遍这 10 万字的特征。这是极大的算力浪费。
- SGLang:它会自动识别不同请求之间共同的前缀,并将其 KV Cache 永久驻留在显存中。
- 收益:对于长文本请求,首字延迟(TTFT)从秒级瞬间降低到毫秒级。
2. 结构化解码(Structured Decoding)
现在的 Agent 往往要求模型输出特定的 JSON。
- SGLang 的降维打击:它通过控制 Logits 掩码,在推理的每一步强行限制模型只能输出符合 JSON 语法的字符。这不仅保证了 100% 的格式正确率,还因为减少了模型在错误选项上的“犹豫”,变相提高了生成吞吐量。
第三章:llama.cpp 与本地推理的“平民英雄”
并不是所有的推理都发生在 8 卡 A100 的云端服务器上。
- 技术本原:由纯 C++ 编写,彻底摆脱了厚重的 Python 环境。
- 极致的卸载策略(Layer Offloading):它允许你精准指定将模型的前 N 层放在 GPU 显存,后 M 层留在 CPU 内存。
- 应用场景:它赋予了个人开发者在笔记本上运行 70B 模型的能力。如果你在做私有化、离线的桌面助手,llama.cpp 是你唯一需要掌握的基座。
第四章:工程师的精算——如何科学评估一个引擎
作为资深 Serving 工程师,你必须掌握这四个黄金指标的实测与分析:
- TTFT (Time to First Token):首字延迟。它决定了用户的“第一印象”。如果 TTFT 超过 2 秒,用户就会觉得系统“卡住了”。
- TPOT (Time Per Output Token):逐字延迟。它决定了阅读的流畅度。理想值在 30-50ms,也就是每秒出 20-30 个字,正好匹配人类的阅读速度。
- Throughput (吞吐量):每秒钟系统总共能产出多少个 Token。这直接决定了你的服务器成本。
- Batch Saturation(批处理饱和度):观察随着并发数增加,吞吐量何时到达天花板。如果吞吐量不再增长而延迟飙升,那就是你的系统“崩盘”的临界点。
第五章:实战横评实验——你的性能压力测试
在本项目中,你将构建一个自动化的压测流水线:
- 并发梯度实验:使用脚本向服务发送从 1 到 500 的梯度并发请求。
- 关键图表:绘制“并发数 vs 平均延迟”和“并发数 vs 总吞吐量”。
- 观测点:找到延迟开始指数级增长的那个“拐点”。
- 显存逃逸实验:故意给系统喂入超过显存承载能力的超长文本。
- 观察:看 vLLM 的抢占式调度(Preemption)是如何工作的。它是会直接 OOM 崩溃,还是会优雅地暂停部分请求,腾出显存给正在生成的请求?
- Prefix Cache 收益分析:针对一个固定的长 Prompt,对比开启与关闭缓存时的 TTFT 差异。
第六章:深度决策——我该选哪一个 Engine?
为了你的 Capstone 能够落地,请参考以下决策矩阵:
| 场景 | 推荐引擎 | 核心考量 |
|---|---|---|
| 云端高并发对话 | vLLM | 极致的内存利用率和并发吞吐 |
| 复杂 Agent / 结构化输出 | SGLang | 前缀缓存效率与格式控制 |
| 边缘计算 / 个人开发 | llama.cpp | 低硬件门槛与跨平台便携性 |
| NVIDIA 深度绑定 | TensorRT-LLM | 硬件底层指令集的极致压榨 |
总结:Serving 是 AI 落地的最后一公里
项目 27 告诉我们:算法是灵魂,但工程是肉体。 一个好的 Serving 引擎能让你的模型在有限的资源下焕发出数倍的生命力。理解了 PagedAttention 和 Prefix Cache,你就掌握了管理昂贵算力资源的钥匙。
在你的 Capstone 报告中,一个经过深度压测、参数调优后的推理架构,将是你技术专业度的最高勋章。
延伸阅读与参考文献
- vLLM: High-throughput LLM serving with PagedAttention
- SGLang: Efficiently Serving Structured and Long-context LLMs
- Continuous Batching: The secret to high-throughput LLM inference
- Performance Comparison of LLM Serving Frameworks (2024)
版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。
(采用 CC BY-NC-SA 4.0 许可协议进行授权)
本文标题:项目 27:吞吐量之王:Serving Stack 与推理引擎横评
本文链接:https://www.sshipanoo.com/blog/ai/llm-roadmap/lab-27-serving-stack/
本文最后一次更新为 天前,文章中的某些内容可能已过时!