ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

vLLM多卡分布式推理部署实战:从张量并行到显存优化全指南

2026/9/20 3:26:58 拓冰建站 浏览量
vLLM多卡分布式推理部署实战:从张量并行到显存优化全指南 1. 从单卡爆显存说起为什么需要分布式推理搞大模型部署的朋友应该都经历过这样一个瞬间模型加载到一半屏幕上赫然出现一行显存不足的报错或者OOM直接把进程杀了。明明自己的显卡已经是旗舰级别却连一个大参数的模型参数都装不下。就拿现在常见的Qwen3-27B这类模型来说光模型权重按BF16精度就要占用54GB的显存这还没算KV Cache、中间激活值和CUDA上下文。一张24GB的消费级显卡根本塞不下即使塞得下推理时的吞吐量和并发能力也会惨不忍睹。我在刚开始接触vLLM的时候就天真地以为多卡部署就是把模型复制到几块卡上让每块卡独立做推理最后汇总结果。后来实践了才发现事情并没有这么简单。多卡推理真正要做的是把一个大模型拆开让多张GPU协同完成一次推理运算这就是分布式推理的核心价值所在。vLLM作为目前大模型推理框架中的顶流天然支持这种分布式部署方式而且实现得相当优雅。这个系列的上一篇我们聊完了单卡场景下的完整部署和推理流程这次就把视野拉大到多卡集群的维度。无论你是手上有两张4090的本地玩家还是有四张A800的GPU服务器管理员这篇文章都会告诉你如何用vLLM把显存资源榨干到极致。我会从理论基础讲起逐步走到实际操作最后附上我踩过的各种坑和解决方案帮助你在自己的机器上顺利完成多卡部署。2. 多卡部署前必须搞懂的几个基础概念2.1 显存占用公式一张卡到底能挤下多大模型在动手部署前先要弄清楚一个最核心的问题你的模型能不能跑得起来。显存估算其实有一个非常直观的公式我平时做资源评估基本都是这么算的。模型权重占用 参数量 × 精度字节数举例来说27B模型用BF16推理权重就需要 ( 27 \times 10^9 \times 2 ) 字节 ≈ 54GB。再加上KV Cache、推理过程中的中间激活值、CUDA context和内存碎片实际上单卡没有70GB以上的显存很难舒服地跑起来。这还不考虑并发请求一旦有多个用户同时访问KV Cache的开销会呈倍数上涨。如果你有2张24GB的卡按照传统思路可能觉得两张卡加起来有48GB够跑了吧其实不对多卡部署并不是简单地把显存累加。vLLM的多卡推理用的是Tensor Parallelism张量并行方式每一层网络会被切分成不同的块放到不同的卡上每张卡只承担一部分计算任务。这种方式对显存的利用效率非常高因为每张卡的权重显存占用等于总权重除以卡数再加上各自独立维护的KV Cache和激活值。2.2 张量并行、流水线并行与数据并行该选哪个vLLM目前主要支持两种分布式并行方式理解它们之间的区别是部署的第一步。初学者经常会混淆张量并行TP和流水线并行PP实际场景下两者的应用逻辑完全不同。张量并行的核心思路是把一个矩阵运算切成多份让多张GPU同时计算同一层的不同部分。比如模型中有个4096×4096的矩阵乘法用TP2的方式运行每张卡只算这个矩阵的一半最终通过all-reduce通信把结果合并起来。这样每次计算都需要卡之间同步通信对卡间带宽的要求比较高。如果服务器内部走的是PCIe 4.0以上的高速总线或者直接是NVLink/NVSwitch互联TP就是首选方案。流水线并行则是把整个网络按层切分卡1只负责训练或推理前面的若干层卡2只负责中间的若干层卡3负责后面的若干层。数据按顺序在卡之间流转每一层的结果直接传给下一卡。这样做的好处是卡间通信频率低不依赖极高的卡间带宽但缺点是存在流水线气泡pipeline bubble某些卡在等待上一级输出时处于空闲状态利用率不够满。数据并行是指每张卡都保存一份完整的模型副本各自处理不同的batch定期同步梯度或结果。对于纯部署推理场景vLLM并不直接采用数据并行作为默认方案因为多卡做同一个模型的推理数据并行在单机多卡下反而利用率低。在实际生产环境中TP是最常用的方案。vLLM对TP的支持非常成熟底层集成了NCCL通信库你只需要在启动命令里加一个--tensor-parallel-size参数框架会自动帮你完成切分和通信。PP的配置稍微复杂一些需要配合--pipeline-parallel-size使用通常只在模型特别大、单机多卡TP无法满足显存需求时才考虑。2.3 为什么说NVLink和PCIe差很多在选多卡方案之前你最好先搞清楚自己所在的机器硬件拓扑是什么。这直接影响你是否应该使用TP模式以及速度能跑到多少。NVIDIA的NVLink技术允许GPU到GPU之间以极高的带宽直接通信比如A100的NVLink每方向可以达到600GB/s的速率NVSwitch全互联架构下任意两张卡之间都能以这个速度交互。对于TP模式这种频繁进行all-reduce通信的模式NVLink的带宽优势体现得淋漓尽致。如果你的机器有NVLink桥接器或者采用的是SXM模组放心大胆地把TP值设大。反过来如果你的卡只是通过PCIe插槽互联比如两台4卡的机器通过PCIe switch连接那么每张卡之间的通信带宽最多只有64GB/sPCIe 4.0 x16实际有效速率还会打折扣。TP2还能勉强接受一旦TP8通信开销可能占据整体开销的40%以上性能提升远达不到线性。这种情况下就得换思路了参考后面讲到的多机部署方案让每张卡处理更少的通信诉求。很多人会问那我用两张普通的3060通过PCIe互联跑TP2是不是能跑起更大的模型答案是能跑但性能一般。一方面两张3060的显存加起来也才24GB跑不了多大的模型另一方面TP2的通信瓶颈会让推理速度还不如单卡。我的建议是本地双卡玩玩可以生产环境还是得看硬件条件决定方案。3. 环境准备vLLM安装与版本选择的学问3.1 安装前必须确认的CUDA和驱动版本vLLM的安装是整个部署流程中最容易出错的一环。很多人拿着最新版的PyTorch和CUDA直接pip install结果跑起来后不是这里报错就是那里崩溃。我自己的实践经验是安装vLLM之前先把版本矩阵查清楚确认PyTorch、CUDA、显卡驱动的兼容性。2019年以后的NVIDIA显卡驱动对CUDA的向下兼容做得不错你只需要保证驱动版本支持的最低CUDA版本低于或等于你安装的CUDA版本即可。用nvidia-smi看到右上角的CUDA Version表示当前驱动支持的最高CUDA版本而实际运行时的CUDA由PyTorch自带runtime决定。两者经常不一致这不影响使用只要PyTorch内置的CUDA版本不超过驱动支持的上限就好。vLLM本身依赖特定版本的PyTorch如果你用官方镜像或者pip安装基本不会遇到大问题。需要注意的点是pip install vllm的时候会强制重装匹配的torch版本如果你已经装好了最新版本的PyTorchvLLM的安装过程中可能会静默地把torch降级或升级这可能导致其他依赖环境出问题。我的建议是安装vLLM时使用独立的conda环境从源头隔离这些坑。3.2 从pip到源码编译新手和老手的两种选择vLLM目前的安装方式主要有两种。最简单的是直接用pip安装预编译的wheel包pip install vllm这个命令会自动拉取匹配当前Python和CUDA版本的预编译包。vLLM官方在PyPI上发布了多个CUDA版本的wheel如果你用的是常见配置安装过程非常丝滑。装好后可以用python -c import vllm; print(vllm.__version__)验证是否安装成功。但预编译包的缺点是版本固化没法自定义某些编译选项。如果你需要vLLM的特定分支特性或者你的显卡架构比较新比如RTX 4090的Ada架构预编译包可能不是最新优化的那就要走源码编译这条路了。源码编译其实也没有想象中那么吓人核心步骤就几步git clone https://github.com/vllm-project/vllm.git cd vllm pip install -e .pip install -e .会自动检测GPU型号和CUDA版本做everything的编译优化。这个过程需要几分钟到半小时不等取决于机器性能。源码编译能针对你的具体GPU架构做kernel级优化推理性能往往比预编译wheel好一些。如果你是Production部署建议花点时间做源码编译。3.3 Windows和WSL2环境下的特殊处理这里单独开一小节因为实在太多人在Windows上踩坑了。vLLM的官方文档并不支持Windows原生环境Windows下的依赖包经常装不全NCCL库在Windows上也没有原生的稳定实现。所以如果你看到Windows上硬装vLLM成功的文章那基本是走了WSL2方案。WSL2环境下跑vLLM有两点必须注意。第一点是WSL2里无法直接安装NVIDIA驱动你需要在Windows宿主机安装最新驱动WSL2里的Linux会自动共享宿主机的CUDA驱动所以你并不需要在WSL2里单独装CUDA driver。第二点是显存和内存的分配问题WSL2默认会限制GPU内存访问但可以通过/etc/wsl.conf配置[automount]和[wsl2]的memory设置来调整。我实测下来WSL2跑vLLM的速度和原生Linux差距不大但对多卡TP模式支持有不小的局限。WSL2的GPU passthrough对多卡通信的支持并不完美特别是两台物理显卡之间的NCCL通信会绕道走宿主机的PCIe性能损耗会大一些。如果只是测试小模型、做单卡推理WSL2完全没问题真要跑多卡并行还是建议直接用Linux系统。顺带说一句最近有人在Windows上折腾vLLM加载Rerank模型这个方向其实比较冷门。vLLM目前对纯Rerank模型的支持并不直接因为Rerank一般只需要单卡跑交叉编码器而且vLLM的推理内核优化更多集中在Decoder-only的生成模型上。如果你确实要在Windows下跑Rerank模型我建议先用Transformers库或专用框架跑通再考虑是否值得用vLLM。多卡场景下需要Rerank的情况也比较少见毕竟Rerank的模型体积通常不大。4. vLLM分布式推理实战从参数到启动全过程4.1 核心参数逐项解析tensor-parallel-size和pipeline-parallel-sizevLLM暴露的分布式推理配置项非常清晰核心就是两个参数--tensor-parallel-size和--pipeline-parallel-size。--tensor-parallel-size简写TP控制张量并行的大小表示把模型切成多少份放到多少张卡上。比如你的机器有4张卡设置TP4vLLM就会自动把模型切分到4张卡上。每一层的计算由4张卡协同完成KV Cache也会在各卡上分片存储。这个参数的取值不能超过单节点内的GPU数量因为TP需要依赖极其高效的卡间通信跨节点的TP延迟会高到让人怀疑人生。--pipeline-parallel-size简写PP控制流水线并行大小。当单机卡数较少、TP无法覆盖所有卡时可以用PP 总卡数 / TP 来补足。比如你有8张卡设置TP4、PP2表示先用4卡做张量并行然后将整个切分后的模型分为两段分别跑在两个4卡节点上。实际操作中我总结了一条经验法则单机内优先调大TP只有在显存不够或需要跨机时才引入PP。TP8是目前单机八卡机型的常见配置很多大模型在8卡A800/H800上用TP8跑起来效果最好。如果你的形态是4卡机型TP4基本就是最优解了不需要把PP引入进来徒增复杂性。4.2 单机多卡部署命令行启动和Python调用两种方式单机多卡部署是最常见的场景操作起来也相对简单。我用一个实际的例子演示一下完整的启动流程假设你的机器有四张NVIDIA GPU准备用vLLM部署Qwen3-27B模型。第一种方式直接用命令行启动兼容OpenAI接口的推理服务python -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen3-27B \ --tensor-parallel-size 4 \ --dtype bfloat16 \ --gpu-memory-utilization 0.9 \ --max-model-len 8192 \ --port 8000这里最关键的就是--tensor-parallel-size 4vLLM检测到你用了4张卡的TP模式会自动将27B的模型权重切分为四份分别加载到4张GPU上。--gpu-memory-utilization 0.9表示vLLM会占用每张卡90%的显存剩下10%留给CUDA context和其他开销避免占满导致系统卡死。这个参数按经验一般不要设成1.0否则并发请求多了之后显存分配会失败。启动后你可以用OpenAI的客户端去测试也就是标准的/v1/completions和/v1/chat/completions接口。举个例子用curl发送一个测试请求看看输出curl http://localhost:8000/v1/completions \ -H Content-Type: application/json \ -d {model: /data/models/Qwen3-27B, prompt: 解释一下什么是分布式推理, max_tokens: 128}如果返回了内容说明多卡推理已经成功了。第二种方式是直接在Python代码里初始化模型适合需要深度定制的用户from vllm import LLM, SamplingParams llm LLM( model/data/models/Qwen3-27B, tensor_parallel_size4, dtypebfloat16, gpu_memory_utilization0.9, max_model_len8192, ) sampling_params SamplingParams( temperature0.7, top_p0.9, max_tokens512, ) results llm.generate([什么是分布式推理, 多卡推理的优势有哪些], sampling_params) for result in results: print(result.outputs[0].text)tensor_parallel_size在Python API里对应命令行中的--tensor-parallel-size。启动时的初始化过程会比单卡多一小段时间因为vLLM需要做切分和NCCL通信组的初始化这个过程通常只有几秒到几十秒。初始化完成后推理速度的提升会立竿见影特别是处理大批量请求时。4.3 多机多卡部署跨节点如何组网单机多卡搞定了那如果我有两台机器每台4卡总共有8张卡能不能合起来跑一个大模型答案是可以但需要做一些额外的配置。vLLM的多机部署本质上靠分布式通信库NCCL把多个节点连接在一起。你需要确保机器之间可以通过RDMA或者TCP通信并且设置好NCCL的相关环境变量。最核心的是要保证所有节点能通过SSH或某种方式统一启动同一个命令。以两台4卡机器为例假设两台机器的IP分别是192.168.1.10和192.168.1.11想跑TP8或TP4PP2两种方式都可以。方式一是TP8跨节点这要求两台机器之间的通信延迟非常低且带宽高一般需要InfiniBand或者专用RDMA网络仅靠千兆网卡你就别想了。方式二是TP4、PP2这种情况下每台机器内部用NVLink做TP通信跨机器之间只需要传输每层的中间激活值对网络带宽的要求低不少。我推荐大多数用户用TP4PP2的跨节点部署方案把TP限制在单机内减少跨节点的通信频率。启动时需要设置NCCL_SOCKET_IFNAME环境变量指定通信网卡例如以太网接口名为eth0则设置export NCCL_SOCKET_IFNAMEeth0两台机器上的命令保持一致python -m vllm.entrypoints.openai.api_server \ --model /data/models/Qwen3-27B \ --tensor-parallel-size 4 \ --pipeline-parallel-size 2 \ --distributed-executor-backend ray \ --dtype bfloat16 \ --port 8000这里有个关键点vLLM支持两种分布式执行后端一种是自带的mpmultiprocessing只支持单机多卡另一种是ray才能支持跨节点。所以上面加了一个--distributed-executor-backend ray参数。使用ray后端时框架会尝试通过Ray集群连接多台机器你需要先在主节点和从节点上初始化Ray集群。# 在主节点上执行 ray start --head --node-ip-address192.168.1.10 --port6379 # 在从节点上执行 ray start --address192.168.1.10:6379 --node-ip-address192.168.1.11接着在任意一台机器上启动vLLM命令即可框架会通过Ray调度所有的GPU资源。跨节点分布式部署最怕网络丢包和延迟波动生产环境务必用千兆以上内网并开启巨型帧。测试时如果发现吞吐量远低于预期首先排查网络延迟而不是怪vLLM代码有问题。4.4 TP切分时模型文件如何处理多卡部署时有一个细节经常被新手忽略模型文件并不需要做任何手工切分。你依然只需要保留一个完整的HuggingFace格式的checkpoint目录vLLM在初始化时会在内存里读取完整权重然后通过NCCL广播到各张卡每张卡只保存自己负责的shard。所以你完全不用像某些框架那样手动把权重切成8份再放到不同的目录。这里有个小坑模型目录里的config.json中可能会包含tensor_parallel相关的字段有些模型在导出时已经预置了TP分片信息。vLLM会自动读取这些字段并适配一般不需要手动修改。但如果发现TP执行后误差较大或崩溃可以检查一下配置文件里的model_type字段确认是兼容的类型。如果你用的是量化模型比如GPTQ或AWQ格式TP切分时的处理逻辑会有差异。量化模型每张卡只保留一部分权重同时还需要维护对应的量化参数表。vLLM对GPTQ和AWQ的多卡支持在近年已经非常完善了但强烈建议使用官方导出的分片格式。如果遇到量化模型分布式加载失败优先去HuggingFace仓库看是否提供了多卡版本的分片权重。5. 多卡部署性能调优与实测对比5.1 吞吐量和延迟指标怎么理解部署完成只是第一步更重要的是理解多卡并行带来了什么样的收益。我模拟了一份Qwen3-27B模型在单卡假设A100 80GB和四卡A100 80GB ×4TP4下的性能对比数据。这里要强调数据会因硬件型号、模型参数、并发请求数等因素波动但是趋势可以作为参考。配置单卡TP2TP4模型权重显存占用54GB27GB/卡13.5GB/卡可运行的最大batch32128512单请求延迟首token约350ms约420ms约520ms总吞吐量tokens/s约3500约6500约12000从表格中可以看到一个有趣的现象多卡减少了单卡处理单个请求时的延迟首token延迟增加了为什么因为多卡并行切分模型之后矩阵运算被拆散到多张卡理论上单次计算时间应该更短。但实际上TP4的通信开销增加导致单个请求的延迟反而略有上升。这不是vLLM实现的问题而是张量并行本身的特点单请求时计算量小通信占比高。多卡真正的价值在于高并发场景下的总吞吐量提升。单卡受显存限制只能同时处理32个请求的KV Cache而TP4能同时处理512个请求吞吐量几乎线性增长。生产环境中动辄几十上百的并发请求多卡部署的意义就体现在这里。如果只是单用户做简单的测试多卡反而可能让你觉得变慢了这是完全正常的现象。5.2 提升多卡推理速度的六个调参思路多卡部署做完如何榨干性能是另一个深层话题。我这里分享几个调优参数都是我实测过有效的。第一调整--max-num-seqs。这个参数控制一个forward pass能处理的序列数默认256。如果你的卡片显存充足、并发请求多可以调大到512或1024大幅提升吞吐量。但调太高会导致显存OOM务必结合监控逐步上调。第二合理设置--max-model-len。模型最大序列长度直接影响KV Cache的显存预分配。如果业务场景很少用长文本把8192改成4096显存占用会下降30%以上腾出的显存可以分配给更大的batch处理间接提高吞吐。第三启用--enable-prefix-caching。如果有大量共享前缀的请求比如多轮对话中相同的system prompt前缀缓存能直接跳过重复的前缀计算效果明显。多卡场景下前缀缓存按卡分片存储命中率不减。第四选择--dtype bfloat16而不是float16。很多模型发布时给出的基准是BF16因为FP16在模型参数值过大时会溢出而BF16保持了更大的动态范围。只要显卡支持Ampere及以上架构优先BF16。第五注意--cpu-offload-gb的使用边界。这个参数可以把一部分模型参数放到CPU显存GPU只保留活跃层能帮助小显存用户跑大模型。但代价是CPU到GPU的传输会成为瓶颈多卡场景下不建议开除非模型卡在临界点。第六监控nvidia-smi的GPU利用率。如果发现某张GPU利用率高、其他GPU利用率低说明模型切分不均匀或通信阻塞。TP模式下NCCL通信占用的时间其实不长更多的瓶颈在于CUDA kernel效率。此时可以检查是否开启了--enable-chunked-prefill把长prompt切成chunk处理降低单次显存峰值。5.3 实测调优案例两张4090跑27B模型我手头有一台专门用来做实验的4卡机器用了两张RTX 4090加上一张旧的Tesla T4做过一些奇怪配置不过最稳定的还是双4090服务器的组合。RTX 4090单卡24GB显存两张48GB理论跑27B模型还是捉襟见肘但配合TP2和一些参数调整效果出乎意料。操作过程如下模型是Qwen3-27BBF16权重54GB按TP2切分后每卡27GB加上KV Cache和激活值单卡至少需要32GB。这张卡只有24GB没法直接跑。这时候就需要动用量化手段我用AWQ量化到4bit版本权重降到13.5GBTP2后每卡只有7GB不到剩下的显存可以大量分配给KV Cache于是最大并发可以做到不错的水准。启动命令如下python -m vllm.entrypoints.openai.api_server \ --model /models/Qwen3-27B-AWQ \ --tensor-parallel-size 2 \ --quantization awq \ --dtype float16 \ --gpu-memory-utilization 0.92 \ --max-model-len 8192 \ --max-num-seqs 64我实测在并发32个请求的情况下模型总吞吐量能稳定在4500 tokens/s左右每个请求的首token延迟约800ms。对于消费级显卡来说这个成绩已经很能打了。如果你手头也是多张消费级显卡不追求高精度量化TP的组合是我们用得最多的方案。6. 高频问题排查多卡部署常见报错全解6.1 NCCL通信错误和超时的排查思路多卡部署最折磨人的就是通信库NCCL的报错很多人被逼到放弃。我这边整理了集中最常见的NCCL相关错误以及解决办法。报错一NCCL error: unhandled system error。这通常表示NCCL无法在预期时间内完成初始化。排查顺序是先确认GPU驱动版本和NCCL版本兼容再用nvidia-smi topo -m查看GPU之间的拓扑结构确认不存在NCCL无法识别的拓扑比如CPU直连的PCIe switch。有时候NCCL需要设置NCCL_P2P_LEVELLOC或NCCL_P2P_DISABLE1来禁用一些不稳定的P2P传输。我是这样做测试的先裸跑一个NCCL测试脚本确认底层通信正常再回过来排查vLLM配置。报错二torch.distributed.DistBackendError: NCCL error 2: Unhandled system error。这个错误在跨节点部署时很常见通常是防火墙拦截了NCCL使用的端口或者节点间物理网络质量差导致超时。解决方案是设置NCCL_SOCKET_IFNAME指定正确的网卡并通过ping和iperf验证节点间带宽。报错三初始化很慢或者卡住。vLLM在TP模式下启动时会建立NCCL通信组如果每张卡的响应时间差异过大会等待很久。可以在启动命令中加入NCCL_DEBUGINFO环境变量输出NCCL日志定位是哪个卡没有响应。6.2 显存不足和模型加载失败显存不足CUDA out of memory是多卡部署中最常见的报错但并不总是因为显存真的不够。这里有个迷惑性很强的点TP模式下每张卡的显存占用相对均衡如果其中一张卡报OOM往往是因为该卡被其他的CUDA进程占用了。排查时务必用nvidia-smi看每一张卡的使用状态不要只看第一张卡。另一个常见问题是模型加载到一半提示KeyError: model.layers.0.self_attn.q_proj.weight这类缺权重报错。这通常是因为模型权重文件被分片了但vLLM在读取时没有正确拼接。解决办法是检查模型目录下的pytorch_model.bin.index.json或model.safetensors.index.json确认所有分片文件都在且SHA256校验通过。如果使用safetensors可以用safetensors库直接读取索引手动验证每个文件中的键是否完整。多卡部署还有一个特殊的坑控制节点和worker节点的模型路径必须一致。通过ray启动多机时如果每台机器上模型存放的位置不同就会导致某几台卡找不到权重文件。解决办法是把模型放在所有节点相同的路径下或者通过共享存储NFS、NAS挂载。6.3 加载模型时报model class not found怎么解决最近网上经常看到有人部署MiniMax-H3这类相对冷门的模型时遇到ValueError: model class MiniMaxH3ModularPipeline not found之类的错误。这类报错的本质是vLLM找不到对应模型架构的实现代码。vLLM支持的模型架构列表是固定的冷门架构需要自己注册自定义模型类。解决方法有两种。简单的方式好用的方式是换一个官方支持的同类模型不必强行折腾。如果你确实需要在vLLM里跑这种架构那就得自己写model implementation文件并在vllm/model_executor/models/__init__.py里注册。这个操作难度较高对vLLM内部结构不了解的话不建议尝试。顺带说一句网上有关vLLM 0.29版本和WSL2的记录有一定参考价值但是0.29已经是相当古老的版本了后来vLLM的接口和参数有过多次变动不建议新项目沿用旧版本。新手遇到奇奇怪怪的报错时第一反应应该是升级到最新版vLLM很多老版本的问题在新版中已经修复了。6.4 性能不达标时的检查项清单多卡部署完毕但性能远不如预期比如TP4的吞吐量还不如单卡这通常是几个方面出了问题按以下顺序排查基本能定位第一GPU利用率。用nvidia-smi dmon -i 0,1,2,3实时查看各卡利用率如果某张卡长期低于90%说明负载不均衡或通信瓶颈。TP模式下如果每张卡利用率都很低但显存满负载多半是NCCL通信在等待。第二NCCL通信耗时。在vLLM启动日志中开启VLLM_LOG_LEVELDEBUG可以看到每次forward pass里NCCL all-reduce的耗时分布。如果通信耗时占总计算时间超过20%就该考虑是不是改用PP或减少TP大小。第三CPU成为瓶颈。TP模式下CPU负责分发任务和回收结果如果CPU核数太少或主频太低GPU再强也白搭。建议生产环境至少配置16核以上的CPU。第四存储IO。模型加载阶段如果从机械硬盘或者网络存储读权重加载时间会很长看起来像是卡住了或者性能极差。第一次加载后vLLM会把模型缓存在内存中后续推理不会受存储影响但如果频繁重启服务还是建议用NVMe SSD存放模型。7. 工具链选型vLLM和其他推理框架的取舍7.1 vLLM和SGLang怎么选关于vLLM和其他框架的对比网上讨论度最高的无疑是SGLang和vLLM之争。两个框架都是目前开源大模型推理领域的顶尖选手选型时我主要看业务诉求。vLLM最大的优势是生态成熟、社区庞大、OpenAI兼容API开箱即用部署成本低配套的工具链完善。无论是FastAPI调用、Prometheus监控还是PostgreSQL日志都能快速集成。SGLang则在radix attention等高级调度算法上做得比vLLM更极致某些工作负载下的吞吐量能高出20%-40%。实测中如果你的场景是标准的Chat Completion或Completion APIvLLM完全够用运维成本低。如果你的场景包含大量结构化数据生成、复杂约束解码或者超长序列推理SGLang的调度优势能体现出来。不过SGLang的文档和生态还是不如vLLM丰富公司团队如果没有专职的推理优化工程师优先选vLLM更稳妥。从多卡部署的角度看vLLM的TP支持和NCCL调优经过多年优化已经非常稳定很多人只在单卡场景下用vLLM实际上多卡部署也是它的强项。我个人跑生产环境的研判是嵌套框架越少越稳vLLM直接提供服务SGLang留给特定的优化任务。7.2 vLLM和Ollama的差异现在很多个人用户喜欢用Ollama部署模型界面简单一行命令搞定。Ollama主打的是本地使用的便捷性它底层也在推理框架上做了很多封装。但如果你的需求是并发API服务、精细化显存控制、多卡并行部署Ollama的能力边界就比较明显了。Ollama的多卡支持更多是简单的显存叠加并不能做到TP切分后的计算协同遇到大模型会直接说放不下。vLLM则目标就是生产级部署从底层加速到分布式并行全部覆盖。个人用来跑通小模型可以选Ollama企业级并发API务必上vLLM。7.3 关于纯CPU模式和便携一键部署包网络上经常看到关于vLLM纯CPU模式和一键部署包的询问这里一并说下我的看法。vLLM纯CPU模式的性能其实没有多大实用价值。vLLM的核心优化依赖于CUDA kernel和NCCL通信换到CPU上跑本质上就是退化成普通的全精度矩阵运算推理速度比GPU慢数十倍以上。除了在验证流程或做架构测试的场景我找不到需要纯CPU跑vLLM的合理理由。部署大模型的初衷就是为了高性能推理如果连GPU都没有建议先用Ollama或llama.cpp这种针对CPU做过优化的框架。关于便携一键部署包这类打包确实方便了新手环境搭建但带来的问题是版本锁定、静态编译参数无法变更、以及底层依赖不可控。多数一键包使用Docker镜像实现环境隔离性和重复性没得说适合快速验证。但生产环境我还是推荐手动构建因为你需要对每一步都有掌控力。多卡部署场景下尤其不适合一键包。TP切分、NCCL配置、GPU规划都需要避开动态检测一键包打包的时候往往按单卡或通用配置优化过反而成了多卡的累赘。在这个前提下vLLM的多卡部署最终还是要回到手动化、标准化这个路线来。7.4 常见问题速查表最后整理了一份多卡部署中最高频问题的速查表方便大家作为自查手册收藏。问题现象可能原因推荐解法NCCL初始化失败驱动版本不兼容、NVLink未启用、防火墙阻挡更新驱动、检查nvidia-smi拓扑、关闭防火墙并指定网卡某张卡OOM其他进程占显存、TP切分不均、KV Cache过大nvidia-smi排查、降低max-model-len或max-num-seqs权重加载报KeyError分片文件缺失或索引损坏校验safetensors索引、确认模型文件完整多机部署无响应Ray集群未初始化、网络拉通失败初始化Ray集群、验证节点间ping/iperf、检查IP多卡吞吐量低CPU瓶颈、NCCL通信开销过大、存储IO慢加CPU核数、调低TP改用PP、模型放NVMe SSD模型兼容报错冷门架构vLLM不支持换官方支持的模型或自定义注册模型类WSL2多卡通信慢显卡passthrough限制确认是否原生Linux部署WSL2只建议单卡测试这张表覆盖了绝大多数多卡部署过程中的实际问题。所有网络框架和工具选型的核心原则就是这么一条设备资源有限、业务需求明确选最合适的方案而不是选最热门的方案。从vLLM到SGLang到Ollama从单卡到多卡到多机层层递进稳定优先。8. 多卡部署的更深层应用与扩展思路8.1 多模型多卡的资源隔离与分配多卡部署并不只限于把一张大模型切分成多卡还有另外一个方向是让多张卡分别跑不同的模型也就是模型级并行。vLLM支持在同一个服务启动时指定多个模型每个模型使用不同的卡互不干扰。这个功能在多模型推理场景中非常实用比如你需要同时提供生成和Embedding服务之前得开两个进程现在可以在一个vLLM实例中统一管理。启动方式如下python -m vllm.entrypoints.openai.api_server \ --model /models/Qwen3-27B \ --tensor-parallel-size 2 \ --model /models/bge-m3 \ --tensor-parallel-size 1 \ --port 8000第一个模型占用了两张卡做TP推理第二个模型占用了第三张卡做单卡推理。vLLM会通过显存调度和CUDA context管理实现这两个模型并行工作互不抢占。业务高峰期不同模型的负载波动会被自动隔离非常适合混合负载场景。不过一个坑是这些模型必须能同时放进剩余的显存空间且各自的KV Cache分配配额要合理设置。具体可以分别给每个模型加--gpu-memory-utilization参数但我实测过更推荐使用vLLM的--enable-multimodal和调度优先级配置来实现精细管控。8.2 多卡场景下的日志监控与自动化部署多卡部署完成后服务稳定运行的前提是充分的观测能力。vLLM的API服务内置了Prometheus指标暴露功能通过/metrics端点可以访问实时指标包括吞吐量、延迟、GPU显存使用率、正在处理的请求数、排队数等。配上Grafana面板日常运维一目了然。我在生产环境中的自动化部署方案通常是这样用Docker Compose编排服务配合环境变量控制TP值。Docker化的好处是环境一致性GPU资源通过--gpus all暴露给容器NCCL通信使用host网络模式来降低网络栈开销。启动脚本中我会把不确定的参数都抽成环境变量由部署平台注入避免修改代码。多卡还经常配合Kubernetes使用通过设备插件nvidia.com/gpu申请GPU调度器根据卡的拓扑选择合适的节点然后vLLM在容器中启动。需要特别注意pod间通信必须使用hostNetwork或SR-IOV保障性能否则NCCL跨pod通信会走overlay网络延迟高得离谱。8.3 模型量化与多卡部署的组合玩法量化技术跟多卡部署并不是非此即彼的关系而是一个叠加的工具组合。多卡解决的是显存不够的问题量化解决的是单卡内部内存体积太大的问题。两者叠加能进一步缓解显存压力让模型推理和KV Cache之间的资源分配更均衡。如今常见的是4-bit量化比如GPTQ和AWQ。当模型被量化后单卡能容纳的模型权重更小KV Cache的占比就更大链条反应是并发度更高、吞吐量更大。前面提到的双4090跑Qwen3-27B就是一个例子纯BF16跑不了AWQTensor Parallel就能流畅运行。从部署者的视角来看量化版本的多卡部署并不增加额外的复杂度。只要在启动命令中加上对应的量化参数--quantization awqvLLM会自动处理量化权重的分片和反量化计算。如果你要在多卡模式下使用量化模型有一点心得建议记住优先使用为多卡场景做过分片的量化模型文件不然后处理时的权重重分配会产生额外的显存开销。8.4 从单机走向集群的下一步建议当你已经能够熟练地在单机多卡上部署vLLM服务下一步就是考虑跨节点集群了。前面说过跨节点TP的限制但那只是针对TP模式而言。真正生产级的集群架构通常会用比较复杂的拓扑组合每一台机器内部用TPPP处理大模型机器之间再用数据并行或异步复制的方式做水平扩展。举个例子你有一个由4台8卡机器组成的集群总共32张A800。一个大模型可以用TP8在单机内部跑然后每台机器都部署一个独立的vLLM实例前端负载均衡器根据请求量和显存负载做流量分发这样水平扩展就非常方便。数据副本之间不需要进行复杂的梯度同步部署复杂度低很多。如果你想更进一步还可以考虑vLLM官方推出的vLLM Ray Serve方案在Ray Serve的部署图里定义多副本自动进行弹性伸缩和故障恢复。这种方案的复杂度更高但很灵活适合业务流量波动大的场景。多卡部署的长期演进核心目标就是延迟、吞吐量和成本三者的平衡。模型切分降低单卡复杂度水平扩展提升整体容量量化控制成本三者叠在一起就是目前最主流的生产级方案。9. 最后的经验分享多卡部署这条路上我踩过的几个坑这篇教程写到这里想再和大家聊聊我自己踩过坑之后沉淀下来的体会。最大的体会是多卡部署和单卡部署是完全不同的思维模式。单卡只需要关心一个GPU的显存、算力、带宽多卡则变成了一个分布式调度问题。你不仅要操心每个GPU的资源分配还要关心它们之间的通信效率。我在第一次做四卡TP部署时傻乎乎地没有检查卡间通信的拓扑结构结果发现有一张卡走的是PCIe总线而不是NVLink推理性能和其他三张卡明显脱节引发了难以排查的NCCL超时错误。后来我会专门先用nvidia-smi topo -m和NCCL_DEBUGINFO去验证卡间通信质量再正式上线。第二个体会是要敢于用监控工具暴露问题而不是靠感觉。我用vLLM的Prometheus指标跑了一段时间后惊讶地发现自己设置的高并发请求并没有压到想要的吞吐量瓶颈出在CPU的tokenizer和采样器上。通过Grafana面板直观地看到GPU空转和CPU满载后我把采样请求改成了异步批处理才把那部分性能解放出来。没有日志和监控的分布式系统就像在开夜路不打远光灯出问题全靠赌。第三个体会是永远给显存留一点余量。我踩过一个非常惨痛的坑把--gpu-memory-utilization设成0.99看似把所有显存都用上了结果一旦并发请求的KV Cache增长超过了预分配的池子直接OOM崩溃。后来我改为0.9并设置--max-num-seqs上限腾出了显存空间给CUDA context和NCCL通信用从此再也没有遇到过类似的报错。记住显存用完必死稳定运行比极致的资源利用率重要得多。经验这种东西光看不算数建议你拿到这篇文章之后找一台至少双卡的机器按我前三章的步骤先跑通一次TP2部署再逐步跑通TP4和并发压测。等你自己亲手体验过模型从一张卡迁移到多张卡的过程遇见过一两次OOM和NCCL报错之后你对分布式推理的掌控感就真正建立起来了。