显存不够用,vLLM 多卡并行配置与优化技巧

📅 2026/7/2 12:52:21
显存不够用,vLLM 多卡并行配置与优化技巧
为什么单卡总是“爆显存”跑大模型最让人头秃的瞬间莫过于看着终端里CUDA out of memory或者在 AMD 平台上是HIP out of memory的报错发呆。尤其是面对 Llama 3.1 405B 这种巨无霸单张显卡哪怕有 80GB 甚至 192GB 显存光是加载权重就捉襟见肘更别提留出空间给 KV Cache 做推理了。之前我也试过强行量化到 INT4虽然能塞进去但模型“智商”下降得厉害生成的内容逻辑混乱完全没法用在生产环境。其实解决这个问题的核心思路很简单既然单卡装不下那就多卡一起扛。vLLM 对多卡并行的支持已经非常成熟特别是在 ROCm 7.x 生态下配合 AMD Instinct MI300X 这类大显存 GPU只要配置得当不仅能跑起来吞吐量还能线性增长。今天就不聊那些虚的理论直接复盘一下我在 DevCloud 上折腾 vLLM 张量并行Tensor Parallelism, TP的实战过程重点讲讲怎么配才能让卡间通信不成为瓶颈以及如何通过细节调优把显存榨干。张量并行让多卡变成“一张卡”vLLM 实现多卡并行的核心参数是--tensor-parallel-size简称 TP。它的原理是把模型的权重切分分散存储在不同的 GPU 上计算时各卡协同工作。对于 405B 这种模型我们通常需要 8 卡甚至更多。启动命令并不复杂关键在于环境变量的预设。在 ROCm 环境下务必先指定架构代码否则编译出的内核可能无法运行exportPYTORCH_ROCM_ARCHgfx942exportHSA_OVERRIDE_GFX_VERSION9.4.2接着是启动服务。假设我们有 8 张 MI300X想要全用上python-mvllm.entrypoints.api_server\--modelmeta-llama/Meta-Llama-3.1-405B-Instruct\--tensor-parallel-size8\--gpu-memory-utilization0.92\--block-size16\--port8000这里有个极易被忽视的坑通信总线。TP 模式下卡与卡之间需要频繁交换中间激活值如果通信走的是低速的 PCIe 甚至以太网延迟会高到让你怀疑人生。在 AMD 的多卡服务器如 HGX 模组中必须确保卡间通信走Infinity Fabric高速互联。这通常依赖于正确的 RCCLROCm 版 NCCL配置。如果是在容器化环境如 DevCloud要检查是否透传了所有 GPU 设备并且没有错误的网络隔离策略阻碍了 P2P 通信。可以通过rccl-test工具简单测一下带宽如果达不到数百 GB/s 的水平说明通信链路有问题这时候跑大模型基本就是“爬着走”。显存碎片与进程绑核细节决定生死配置好 TP 只是第一步真正让服务稳定运行的是对显存和 CPU 资源的精细控制。对抗显存碎片vLLM 的 PagedAttention 技术虽然高效但在多卡场景下显存碎片化问题会被放大。--block-size参数决定了显存块的大小。默认值通常是 16这对于大多数场景是平衡点。但如果你的业务场景中长序列请求特别多可以尝试调大到 32 或 64减少管理开销反之短序列居多则保持较小值以提高利用率。更重要的是--gpu-memory-utilization。很多教程建议设为 0.95 甚至更高但在生产环境我强烈建议压在0.90 - 0.92。多卡系统中只要有一张卡因为瞬时峰值 OOM整个推理进程就会崩溃重启。留出 8%-10% 的缓冲空间是为了应对并发突增时的 KV Cache 动态分配这点“浪费”换来的是服务的稳定性绝对值得。进程绑核CPU Affinity这是一个容易被遗忘的性能杀手。vLLM 启动多个 TP 进程时如果操作系统随意调度很可能出现多个 GPU 进程争抢同一个 CPU 核心的情况导致上下文切换开销剧增推理延迟抖动。我们需要使用numactl将每个进程绑定到对应的 NUMA 节点。虽然 vLLM 启动脚本内部做了一些优化但在极端高并发下手动干预更稳妥。你可以编写一个简单的封装脚本利用taskset或numactl根据 GPU ID 绑定 CPU 核心掩码。例如将 GPU 0-3 的进程绑定到 CPU 0-31GPU 4-7 绑定到 CPU 32-63。这样能确保数据在本地内存访问减少跨 NUMA 节点的内存拷贝显著降低首字延迟TTFT。并发测试与扩容建议配置完成后别急着上线先用benchmark_serving.py压测一下。我发现一个有趣的现象在 TP8 的配置下随着并发数Concurrency的提升吞吐量Token/s并非一直线性增长。在并发数较低时如 1-16系统表现完美延迟极低。但当并发数超过某个阈值比如 64 或 128取决于具体模型和硬件吞吐量开始 plateau 甚至下降。这通常是因为显存带宽饱和或者 CPU 调度成为了瓶颈。实操建议寻找拐点通过压测绘制“并发数 - 吞吐量”曲线找到性能拐点。生产环境的最大并发限制应设定在拐点左侧预留 20% 余量。动态批处理vLLM 的 Continuous Batching 是提升吞吐的关键确保--max-num-seqs参数设置合理。如果显存允许适当调大该值可以容纳更多并发请求。监控指标上线后重点监控 GPU 显存使用率和 RCCL 通信流量。如果发现某张卡显存长期高于其他卡可能是负载不均如果通信流量异常低再次检查互联总线状态。总的来说用 vLLM 跑超大参数模型本质上是在做资源管理的艺术。TP 参数解决了“能不能跑”的问题而显存预留、进程绑核和通信优化则决定了“跑得稳不稳、快不快”。在 AMD ROCm 生态日益成熟的今天这套方案已经具备了替代昂贵专有方案的能力只要肯在细节上多磨一磨效果往往出乎意料。200小时GPU算力已就位快来领取https://marketing.csdn.net/questions/Q2604140858304426315?utm_sourceAIpaper