第三章 进阶原理:显存、缓存与 GPU 共享 导读:第二章你跑通了一个能用的服务。但「能用」和「好用」之间隔着一整章的原理。为什么并发一高就 OOM?为什么长上下文这么吃显存?一张 80G 的卡能不能服务两个模型?这一章把 vLLM 的底层机制拆开讲,让你从「照抄 YAML」进阶到「能根据负载调参数」。三节分别讲:PagedAttention 与 KV Cache、长上下文的显存账、以及 GPU 共享(MIG / 时间切片)。 3.1 PagedAttention 与 KV Cache:显存为什么能省下来 要懂 vLLM 为什么快,必须先懂 KV Cache。
导读:第二章你跑通了一个能用的服务。但「能用」和「好用」之间隔着一整章的原理。为什么并发一高就 OOM?为什么长上下文这么吃显存?一张 80G 的卡能不能服务两个模型?这一章把 vLLM 的底层机制拆开讲,让你从「照抄 YAML」进阶到「能根据负载调参数」。三节分别讲:PagedAttention 与 KV Cache、长上下文的显存账、以及 GPU 共享(MIG / 时间切片)。
要懂 vLLM 为什么快,必须先懂 KV Cache。Transformer 每生成一个 token,都要用到之前所有 token 的 Key/Value 向量,这些被缓存下来避免重复计算,叫 KV Cache。问题是:传统实现给每个请求预先分配「最大长度」的连续显存,哪怕实际只用了 10%,剩下的 90% 也占着——这就是显存浪费和「并发上不去」的根源。
vLLM 的 PagedAttention 借鉴了操作系统的虚拟内存分页思想:把 KV Cache 切成固定大小的 Block,请求按需申请 Block,Block 可以非连续存放。好处是:
这对 GLM-5.2 意义重大:它主打长上下文,KV Cache 随上下文长度线性增长,传统方案在长文本下会迅速 OOM;PagedAttention 把这笔开销压到接近理论下限,让「长上下文 + 高并发」成为可能。理解这一点,你才会明白为什么本教程坚定选 vLLM,而不是裸 transformers。
调参上,vLLM 提供 --gpu-memory-utilization(默认 0.9)控制 KV Cache 能占用的显存比例。显存紧张又想多并发,可以稍微调高;但如果模型权重本身就快占满显存,调太高会导致权重放不下而启动失败——这正是「参数要按实测调,不能照抄网上的 0.95」的原因。
GLM-5.2 的 1M 上下文是卖点,但工程上要清醒:上下文长度直接决定 KV Cache 峰值显存。粗略地说,KV Cache 显存 ≈ 请求数 × 序列长度 × 每层 KV 维度 × 层数 × 精度字节数。序列长度从 32k 翻到 1M(约 32 倍),在其它不变时 KV Cache 也近似翻 32 倍。这就是为什么「一上来就开 max-model-len=1048576」大概率 OOM。
实战策略是分级的:
--max-model-len 上调一档,观察 nvidia-smi 显存峰值和 DCGM 指标,找到「不 OOM 前提下的最大长度」;一句话原则:上下文长度是显存预算,不是配置开关。 它和并发数、模型体量三者互相挤占同一块显存,调其中一个必须看另外两个的余量。
GPU 很贵,很多时候单模型吃不满一张卡。能否「切分」?可以,但方式不同:
nvidia.com/gpu 配置成「可超分」,比如一张卡报成 2 个或更多逻辑 GPU。本质是时间片轮转,没有显存隔离,一个 Pod OOM 可能影响同卡其他 Pod。适合「显存都不大、能接受偶尔互相影响」的开发/测试场景。选型建议:生产多租户且要求隔离 → MIG;内部测试想省卡 → 时间切片。无论哪种,配置都在 GPU Operator 的 clusterPolicy 里,改完要重启相关 DaemonSet 才能生效。再次提醒:共享必然带来「邻居噪声」,上线前务必压测确认彼此影响在可接受范围。