vLLM 调优(2)--gpu-memory-utilization
结论
需要给底层驱动或某些算子预留多少显存?
公式化建议:如果显存 M > 40GB:建议预留 M * 0.05 和 2GB 之间的较大值。如果显存 M < 24GB:建议至少预留 2GB 绝对空间。
GPU服务器的物理内存,不能太小,否则会无法启动大模型。
CUDA Graph 录制阶段:约 4GB - 8GB + 模型权重(8bit量化qwen14 约为 15GB)+ 操作系统2-4G+python加载大模型的额外开销。
比如部署qwen14B,64GB RAM为比较安全的大小。
简单来说,--gpu-memory-utilization 参数定义的 不是 KV Cache 的大小,而是 vLLM 允许占用的 GPU 总内存上限。
在 vLLM 启动时,它会按照以下顺序“瓜分”这部分内存:
1. 内存包含的内容
--gpu-memory-utilization(默认 0.9,即 90%)涵盖了 vLLM 运行所需的所有核心显存:
- 模型权重 (Model Weights): 加载模型参数所需的显存(例如 FP16 的 7B 模型约占 14GB)。
- KV Cache (键值缓存): 这是 vLLM 管理的重点。它会预先分配剩下的绝大部分空间作为 KV Cache 块池(Block Pool),用于存储推理过程中的上下文。
- 激活值/工作空间 (Activations/Workspace): 推理过程中产生的临时张量和计算空间。
- CUDA Graph: 为了加速推理,vLLM 默认会捕获 CUDA 图,这也会占用一部分固定显存。
2. vLLM 是如何分配内存的?
vLLM 的内存管理非常“霸道”,它采用的是预分配机制。分配流程如下:
- 加载模型: 首先把模型权重塞进显存。
- 显存探测 (Profiling): vLLM 会进行一次模拟运行,测量推理时需要的峰值临时显存(Activations)。
- 计算剩余: 用
总显存 * utilization减去“权重”和“临时显存”,剩下的所有空间都会被立即划拨给 KV Cache。
举个例子:
如果你有 40GB 显存,设置--gpu-memory-utilization 0.9,则 vLLM 计划使用 36GB。
- 假设模型权重占 20GB,临时开销占 2GB。
- 那么 vLLM 会在启动之初就直接霸占剩余的 14GB 全部作为 KV Cache。
- 这就是为什么你一启动 vLLM,即使没发请求,
nvidia-smi也会显示显存占用瞬间飙升到 90% 的原因。
3. 常见误区与调优建议
- “设置 1.0 是不是性能最强?”
不建议。如果你设为 1.0,完全不给系统和其他潜在开销留余地,非常容易导致 Out of Memory (OOM) 崩溃,因为底层驱动或某些算子可能需要极少量的额外空间。一般 0.9 或 0.95 是比较稳妥的上限。 - “为什么我改小了利用率,吞吐量变低了?”
因为利用率变小 →KV Cache变小 →可同时处理的并发请求数 (Batch Size)变少。 - “如果显存被其他程序占了怎么办?”
vLLM 启动时会检查可用显存。如果被占用了,而你设置的utilization比例对应的显存超过了剩余可用量,程序会直接报错。
总结: 它是 vLLM 的显存总预算。你可以通过这个参数控制 vLLM 不要把显存占满,从而给其他任务留点空间,或者通过调高它来压榨出更多的 KV Cache 空间以提升高并发性能。
您是遇到了显存溢出(OOM)问题,还是想在同一块卡上运行多个模型服务?我可以为您提供针对性的配置建议。
需要给底层驱动或某些算子预留多少显存?
在评估 --gpu-memory-utilization 的设置时,理解那部分“预留内存”(即 1 - utilization 的部分)具体用来做什么至关重要。
通常情况下,预留 5% 到 10%(即设置 0.9 或 0.95) 是 vLLM 的标准做法,但在特定硬件或高负载场景下,你可能需要预留更多。以下是预留内存的详细构成和评估建议:
1. 预留内存里到底有什么?
除了模型权重和 KV Cache,这部分预留空间主要承载以下三个“隐形大户”:
-
CUDA Graph 捕获空间 (CUDA Graph Overhead):
-
vLLM 默认会为常用的 Batch Size(如 1, 2, 4, 8...)预先录制计算图。
-
这些图会占用固定显存。模型越大,CUDA Graph 占用的显存越高。在 80GB 的 H100 上,复杂的模型可能因为 CUDA Graph 录制瞬间吃掉几个 GB。
-
临时激活值与工作空间 (Temp Workspace):
-
PyTorch 在执行特定算子(如 FlashAttention 或 CuBLAS 矩阵乘法)时,需要临时的显存空间作为“草稿纸”。
-
虽然 vLLM 会进行 Profile 探测,但在高并发或长文本突然涌入时,某些算子的动态开销可能会超出探测值。
-
显存碎片与驱动消耗 (Fragmentation & Driver):
-
显存分配不是连续的,碎片化(Fragmentation)会导致虽然显示有余量,但无法分配出大的连续块。
-
NVIDIA 驱动本身也会占用几十到几百 MB。
2. 不同场景的预留建议表
你可以根据你的设备和任务,参考下表来设置 utilization:
| 场景 | 推荐设置 | 预留比例 | 原因 |
|---|---|---|---|
| 单实例/生产环境 | 0.90 | 10% | 最稳妥。 给 CUDA Graph 和算子留足 buffer,防止 OOM。 |
| 极限吞吐测试 | 0.95 | 5% | 压榨性能。 适合已知短文本、固定负载的场景。 |
| 多模型共用显卡 | 0.4 - 0.7 | 30%+ | 防止抢占。 如果这块卡还要跑其他 Web 服务或小模型,必须大幅降低。 |
| 小显存显卡 (<=12GB) | 0.75 - 0.8 | 20%+ | 容错低。 系统组件占用的绝对数值虽然不大,但在小卡上占比很高。 |
| CUDA Graph 报错 | 0.80 | 20% | 稳定性优先。 如果启动时报 std::bad_alloc,通常是预留不足。 |
3. 如何精准评估你的“安全水位”?
如果你想知道最极限能设多少,可以按以下步骤操作:
- 观察启动日志:
vLLM 启动时会打印一行:
INFO: # GPU blocks: 1234, # CPU blocks: 567
这代表了它最终划拨给 KV Cache 的物理块数量。 - 强制关闭 CUDA Graph:
如果你显存极度紧张,可以使用--enforce-eager参数。这会禁用 CUDA Graph。
- 好处: 节省大量预留显存(有时能省下 1-2GB)。
- 坏处: 推理速度会变慢(约 10%-20% 的延迟增加)。
- 公式化建议:
- 如果显存 :建议预留 和 之间的较大值。
- 如果显存 :建议至少预留 绝对空间。
避坑指南
如果你发现设置 0.9 依然崩溃,通常不是因为 KV Cache 占满了,而是因为 系统 RAM (内存) 耗尽了。vLLM 在录制 CUDA Graph 时会消耗大量的 CPU 内存。如果你的机器只有 16GB 内存却插了块 24GB 的显卡,建议把利用率降到 0.8。
你想针对具体的哪款显卡和模型进行配置?我可以帮你算一下具体的参数建议。
对于 Qwen-14B (8-bit 量化) 并在 48GB 显卡(如 RTX 6000 Ada 或 A4000/L40 等)上运行的配置,虽然显存非常充裕,但物理内存(RAM) 依然是启动成功的关键。
为了确保稳定运行,建议你的物理内存至少为 32GB,如果希望在高并发下完全不卡顿,64GB 是理想选择。
以下是具体的内存需求拆解:
1. 物理内存 (RAM) 需求评估
在 vLLM 启动 Qwen-14B (INT8) 时,RAM 的压力主要来自以下三个阶段:
- 模型加载阶段(峰值需求):约 16GB - 20GB
虽然 8-bit 模型文件大小约为 15GB,但在加载过程中,Python 进程、模型初始化以及权重反序列化会产生额外的内存开销。如果你的 RAM 只有 16GB,此时系统极易触发 OOM (Out of Memory) 导致进程被杀。 - CUDA Graph 录制阶段:约 4GB - 8GB
vLLM 默认会为多个 Batch Size 录制 CUDA Graph,这会在 RAM 中产生大量的临时元数据。 - 操作系统自身开销:2GB - 4GB
Windows 或 Linux 系统常驻后台也会占用一部分内存。
结论: > * 16GB RAM: 极度危险,大概率启动失败,必须开启
--enforce-eager且增加 Swap 虚拟内存才可能跑通。
- 32GB RAM: 安全线,可以正常启动并保持 CUDA Graph 开启。
- 64GB RAM: 舒适线,在处理长文本、多并发请求或同时运行其他任务时毫无压力。
2. 显存 (VRAM) 占用分析 (48GB 显卡)
在 48GB 的显卡上,默认设置 --gpu-memory-utilization 0.9 后的分布大约如下:
| 组件 | 占用大小 (估计) | 说明 |
|---|---|---|
| 模型权重 (8-bit) | ~15 GB | Qwen-14B 的 INT8 权重。 |
| KV Cache | ~26 GB | 显存剩下的绝大部分都被划给 Cache,能支撑极大的并发或超长上下文。 |
| 预留空间 (10%) | 4.8 GB | 用于处理算子临时开销和 CUDA Graph。 |
| 合计 | 43.2 GB | 即 48GB * 0.9。 |
3. 针对你的 48GB 显卡建议
由于你的显存(48GB)对于 14B 模型来说非常富余(权重只占了不到三分之一),你可以采取以下优化策略:
- 最大化上下文: 你可以承载非常长的 Context。Qwen-14B 默认支持很长的上下文,由于你有 26GB 的 KV Cache 空间,你可以放心把
--max-model-len设大(例如 32768 或更高)。 - 物理内存不足时的对策: 如果你的物理内存确实只有 16GB,启动时请务必加上:
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-14B-Instruct-INT8 \
--gpu-memory-utilization 0.85 \
--enforce-eager
注:--enforce-eager 虽然牺牲了一点速度,但能救命,防止 RAM 在启动时爆掉。
你的机器目前实际配了多少 GB 的物理内存?如果是新组装机器,建议直接上两条 32GB 内存条。

浙公网安备 33010602011771号