手头正好有 8 张 V100 32G想把这批卡用起来跑大模型。很多人第一反应是“V100 太老了跑不了大模型”但实际部署完跑一波压测之后我觉得这批卡并没有网上说的那么不堪关键是把并行度、显存规划、推理引擎参数这三件事算清楚。这篇文章就从 vLLM 部署、实际业务吞吐测试的角度把我踩过的坑、测出来的数据和最终的部署建议完整写一遍适合手里有存量 V100、想压低推理成本、或者正在评估“旧卡能不能接大模型业务”的团队参考。1. 方案选型与整体思路1.1 为什么是 A100/H100 之外的选择大部分业务团队真正的问题不是“哪张卡最强”而是“我手头有什么卡”。现在机房和云上存量资源里有不少 V100尤其是 32G 版本当年主要是给训练任务购置的训完一波模型之后一直闲置。拿来跑推理单卡显存能到 32GB比常见的 24G 消费卡还大这是 V100 32G 最大的价值。当然 V100 的算力确实落后了。FP16 Tensor Core 算力大概在 125 TFLOPS 左右和 A100 的 312 TFLOPS、H100 的千级别相比差了一个量级但“算力不够”和“能不能用”是两回事。大模型推理瓶颈往往是显存容量、KV Cache 占用、以及 batch 时算力利用率V100 32G 在 7B/13B 这个级别上完全有机会把算力喂饱。对比几个常见部署卡卡型显存FP16 稠密算力显存带宽NVLink 互联对大模型推理的主要顾虑V100 32G32GB约 125 TFLOPS900GB/s有300GB/s无 BF16/FP8 支持Kernel 优化少A100 40G/80G40/80GB约 312 TFLOPS1.5/2TB/s600GB/s成本高不好抢H100 80G80GB约 990 TFLOPS3.3TB/s900GB/s贵匹配高端业务RTX 4090 24G24GB约 165 TFLOPS1TB/s无消费卡稳定性被怀疑V100 32G 的好处还有一点HBM2 的带宽有 900GB/s虽然不如 A100但比很多 GDDR6 的消费卡强这意味着大模型逐 token 生成时的访存效率并不差。真正拖后腿的是软件生态vLLM 在 V100 上有些优化 kernel 用不了这些后面我会细讲。1.2 8 卡并行度怎么定TP、PP 还是 DP8 张 V100 32G 摆在面前第一件事是决定模型怎么切。大模型并行部署通常有张量并行TP、流水线并行PP、数据并行DP三种。因为目标是把单卡显存合并成一个大显存池所以大多数人第一反应是开 TP8。我实测下来这个直觉只对了一半。TP 是把一个 Transformer 层的权重和计算切到多张卡上每张卡只算一部分通信量非常大。V100 的 NVLink 带宽虽然有 300GB/s但 TP8 时每层都有多次 all-reduce通信开销会吃掉不少算力尤其在小 batch 下通信占比甚至超过计算。对 7B 和 13B 这种模型TP2 或 TP4 通常就够显存不是问题硬切到 8 张只会更慢。PP 适合超大模型比如 70B 以上把不同层分给不同卡通信相对少但流水线会引入气泡问题而且 vLLM 对 PP 的支持历史上一直不如 TP 成熟这个方案优先级放后面。DP 则是多副本并行适合小模型高并发业务流量大时可以开多副本但 V100 32G 的单副本显存也够跑所以通常用 vLLM 的连续批处理来提升并发而不是粗暴开 DP。我最终的判断是7B 以下优先 TP2 甚至 DP 多副本13B 优先 TP470B 需要 TP8 并配合必要的量化。这个判断在后面压测数据里能得到验证。2. 部署前先把显存账算明白2.1 权重、激活与 KV Cache 的占用估算部署前最忌讳“直接启动报错就加参数”。大模型跑起来显存主要吃三块权重、激活、KV Cache。权重大小很好算半精度 FP16 每个参数占 2 字节。7B 模型权重约 14GB13B 约 26GB65B/70B 约 140GB。V100 32G 单卡跑 7B权重加激活能塞下但留给 KV Cache 的余量就要精打细算。激活一般不大在连续批处理下主要取决于当前 batch 的序列长度不过 vLLM 的 PagedAttention 已经把大部分临时显存需求压得很低。KV Cache 是大头也是 vLLM 最核心的优化点。传统推理框架为每个请求预分配固定长度的 K/V 缓存哪怕请求实际只生成几十个 token也要按最大长度占满显存。vLLM 的 PagedAttention 把 KV Cache 切成固定大小的页按需分配显存碎片和浪费大幅下降。估算 KV Cache 有个粗略公式每 token 的 KV Cache 字节数 2 × 层数 × KV 维度的总大小 × 字节数。以 7B 模型为例假设 32 层、每层 KV 维度 4096、FP16 存储那么单 token KV Cache 约 0.5MB13B 约 0.8MB70B 如果用了 GQAKV 维度会显著缩小单 token 可能反而更小。2.2 8 卡 V100 32G 到底能支撑多大模型总显存 8×32GB256GB减掉模型权重剩下的才是 KV Cache 可用空间。7B 用 14GB 权重剩下 240GB 左右按 0.5MB/token 算理论上可以缓存接近 50 万 token 的 KV 信息。13B 用 26GB剩下 230GB按 0.8MB/token 算约 29 万 token。70B 用 140GB 权重剩下 116GB如果单 token KV 约 0.4MB也能缓存约 29 万 token。这个结果表明在 7B 和 13B 这个量级上V100 32G 集群的瓶颈根本不是显存而是算力。真正限制并发的是模型生成速度你并发开再大GPU 的稠密算力就那么多总吞吐有一个天花板。而 70B 这种百 G 级模型8 卡 V100 能放下但算力会被吃得很紧生成速度会明显变慢。我建议用一句话总结配置逻辑先确定模型权重要占多少显存再留出至少 1-2GB/卡的余量剩余显存尽量交给 vLLM 做 KV Cache通过--gpu-memory-utilization控制。别把显存利用率拉满到 0.99V100 的显存频率波动、驱动预留都可能让你在业务高峰踩到 OOM。我见过不少团队为了多塞几个并发把比例调到 0.97 以上结果跑了一天业务后服务内存持续上涨最后只能靠重启续命这种老卡上保守一点绝对不亏。3. vLLM 部署与关键参数说明3.1 环境准备与安装V100 的软件栈有个和显卡新旧直接相关的坑。V100 是 Volta 架构SM 版本是 7.0和现在主流的 Ampere、Hopper 不同很多新编译的 kernel 并不向下兼容。我在最开始直接装了最新版 vLLM 配合 CUDA 12.4 的 PyTorch结果加载模型时直接报 device not capable后来换成 CUDA 11.8 编译的版本才正常。所以第一步一定是确认软件栈与 V100 兼容而不是追求最新版本。安装步骤倒是很简单# 创建 Python 环境 conda create -n vllm python3.10 -y conda activate vllm # 安装 PyTorch注意选择 CUDA 11.8 版本 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 # 安装 vLLM建议锁版本 pip install vllm0.4.2 # 验证 GPU 可用 python -c import torch; print(torch.cuda.is_available())这里踩过最大的坑是版本误导。网上大部分 vLLM 教程默认你用的是 Ampere 以上架构某些启动参数和量化方式在 V100 上并不适用。安装后先用nvidia-smi确认驱动够新再跑一个最简单的加载测试不要直接上生产配置。V100 上验证最快的方法就是加载一个小模型随便生成一句话如果这个流程能通说明 CUDA 和 kernel 层面没有大问题。3.2 启动命令与关键参数逐项拆解部署一个 7B 模型我最终用的启动命令大致是这样python -m vllm.entrypoints.openai.api_server \ --model /data/models/7b-chat \ --tensor-parallel-size 4 \ --max-model-len 4096 \ --gpu-memory-utilization 0.92 \ --max-num-seqs 128 \ --swap-space 16 \ --host 0.0.0.0 --port 8000这些参数每一个都对应一个显存或性能取舍我逐个说。--tensor-parallel-size 4是张量并行卡数。7B 模型单卡其实跑得动但生成速度不够TP4 能分摊注意力和 FFN 计算让单 token 生成延迟降下来。TP8 不是不行但我实测在 7B 上 TP4 到 TP8 的吞吐提升不大有时还会因为通信开销反而变慢这一点在后面的数据里能看到。--max-model-len 4096是最大上下文长度。这个值直接决定了单页 KV Cache 的规模设得越大同一并发下 KV Cache 占显存越多。很多团队上来就设 8192 甚至 16384结果 batch 稍微上去就 OOM。如果你业务实际平均长度只有 2000设 4096 完全够用还能让并发吞吐明显提升。--gpu-memory-utilization 0.92是允许 vLLM 使用的单卡显存比例。vLLM 会在模型权重加载之后把剩余显存绝大部分用于 KV Cache 池。0.92 是相对激进但可行的值如果模型权重本身就占大头剩余空间不多这个比例要相应降低。--max-num-seqs 128是单次调度允许的最大并发序列数。这个值不是越高越好它决定了连续批处理可以同时容纳多少个请求。128 是一个比较平衡的起点V100 算力不够强行开 256 会让每个请求的排队时间变长表现为 TTFT 飙升。--swap-space 16是 CPU 交换空间单位是 GB。显存不够时会把部分 KV 页换到 CPU 内存。V100 显存虽大但如果你同时跑多个模型或开了很大的上下文长度这个参数能防止直接 OOM代价是换页时延迟抖动。3.3 业务侧接入的注意点vLLM 启动后提供/v1/chat/completions这类兼容主流大模型 API 风格的 HTTP 接口业务方只需要把原来 SDK 请求的 base_url 改成 vLLM 服务地址即可。但实际业务接入时有几个问题很容易忽略。首先是超时设置。大模型推理不是传统 HTTP 接口一个请求可能要几秒甚至几十秒才返回业务方的网关超时如果设成 3 秒高峰时段会大量超时重试。我更建议把连接超时放宽到 60 秒同时不要让网关层无限重试重试只会雪上加霜把并发打到推理服务上。其次是流式输出绝大多数真实业务比如智能客服、写作助手需要流式返回vLLM 的streamTrue参数开启后首 token 延迟能明显改善用户体验但这要求业务方具备 SSE 解析能力。还有一件事我在项目里反复提醒vLLM 虽然是推理引擎但它和业务系统的关系更像一个异步调度器请求会排队。如果业务方用长连接把大量请求一股脑打进来vLLM 会在内存里积压很多未调度的请求表现为服务端内存上涨、TTFT 变大。所以生产环境一定要在 vLLM 前面加一层并发控制和队列比如把并发上限压到max-num-seqs的 80% 左右。4. 实际业务吞吐测试方案设计4.1 测试指标定义做吞吐测试之前先把指标口径统一不然测出来的数字没法指导业务容量规划。我重点关注四个指标QPS每秒能完成多少个完整请求反映系统整体吞吐能力。TTFT首 token 延迟用户发起请求到收到第一个 token 的时间直接影响交互体验流式场景尤其重要。TPOT每 token 生成时间生成阶段每个 token 的平均耗时决定长文本响应速度。端到端延迟从请求发出到完整响应返回的总时长。对于业务侧QPS 和 TTFT 是核心对于模型服务本身TPOT 决定你能支撑多高的并发。合理的目标是在满足 TTFT P95 小于 2000ms 的前提下尽可能提升 QPS。这四个指标不能只看平均值P95 和 P99 同样重要因为大模型推理的排队效应非常明显哪怕平均延迟很低高峰突刺也能让用户感受到明显卡顿。4.2 压测脚本与场景设计压测脚本我用 Python 写了一个比较简单的并发模拟器用线程模拟多个用户同时请求记录每个请求的开始时间、首 token 时间和完成时间。import json import time import threading import requests def single_request(url, prompt, max_tokens, results, idx): payload { model: 7b-chat, messages: [{role: user, content: prompt}], max_tokens: max_tokens, stream: False, } t0 time.time() try: resp requests.post(url, jsonpayload, timeout120) t1 time.time() data resp.json() content data[choices][0][message][content] results.append({ idx: idx, total_time: t1 - t0, output_tokens: len(content), }) except Exception as e: results.append({idx: idx, error: str(e)}) def run_concurrency(url, prompt, max_tokens, total, concurrency): results [] threads [] for i in range(total): t threading.Thread(targetsingle_request, args(url, prompt, max_tokens, results, i)) threads.append(t) if len(threads) concurrency: for th in threads: th.start() for th in threads: th.join() threads [] return results if __name__ __main__: results run_concurrency( http://127.0.0.1:8000/v1/chat/completions, 用一句话解释什么是大模型部署。, max_tokens200, total200, concurrency32, ) print(完成请求数:, len(results)) print(平均耗时:, sum(r[total_time] for r in results) / len(results))TTFT 单独测的时候要走流式接口测从发请求到第一个数据块到达的时间。这里有个细节压测并发最好从低到高递进而不是一开始就全并发否则服务端 OOM 和客户端大量超时会混在一起问题难以定位。我给的建议是先并发 1 测单请求延迟再并发 8、16、32、64 逐级上压每轮持续 2-3 分钟记录稳定后的指标。4.3 请求内容与业务场景的模拟方式很多团队压测喜欢用“请写一篇关于 XX 的文章”这种长 Prompt压出来的只是长文本生成吞吐和真实业务差距很大。我一般会按业务的真实数据分布设计至少三组场景短输入短输出Prompt 平均 100 字输出 100-300 字模拟日常问答、分类、抽取任务。短输入长输出Prompt 平均 100 字输出 800-1200 字模拟写作、摘要长文、代码生成。长输入短输出Prompt 平均 2000 字输出 200 字模拟长文档问答、合同审查。三组场景下 KV Cache 的压力完全不同。长输入场景即使输出短整个序列长度也很长KV Cache 占显存很大同时 prefill 阶段计算量高V100 的算力瓶颈会暴露得特别明显。压测结果必须分开汇报不能只给一个总 QPS 数字就完事否则你根本不知道业务切换场景后服务会不会崩。5. 实测数据与性能解读5.1 7B 模型在 8 卡 V100 上的吞吐表现先给结论8 卡 V100 32G 在 7B 模型、TP4、max-model-len4096、max-num-seqs128 的配置下短输入短输出场景稳定 QPS 能到 20 左右TPOT 约 30msTTFT 在并发 32 时有明显上升。这是一个“能用”的水平适合中低流量业务。下面是并发与吞吐的实测数量级基于业务短文本场景非精确基准并发数QPS请求/秒P95 TTFTmsTPOTms显存占用/卡11.23002815GB88.54203218GB1614.36203521GB3219.810503825GB6421.522004229GB从 16 并发到 64 并发QPS 只从 14.3 涨到 21.5增量明显放缓。这说明 V100 的算力已经到了瓶颈区间继续加并发只会让 TTFT 变差而不是让总吞吐继续线性增长。这也是我建议生产环境把并发控制在 20-30 的关键原因再往上拉用户体验掉的比吞吐涨的还快。5.2 13B 模型与长文本场景的表现13B 模型、TP4 配置下短输入短输出稳定 QPS 约 8-10TPOT 约 60msTTFT 在并发 8 时已经到 1000ms 左右。如果换成短输入长输出场景输出 token 数从 200 涨到 1000QPS 降到 3-4TPOT 反而会有所下降因为同 batch 内请求变少、GPU 利用率下降。长输入短输出场景是 V100 最难受的。2000 字 prompt 进来prefill 阶段要处理大量 token7B 模型并发 8 时 TTFT 直接到 2500ms 以上如果业务要求首 token 延迟小于 2 秒这基本是极限。原因在于 V100 缺少新卡上深度优化的 attention kernel长序列 prefill 的算力利用率上不去。这不是 vLLM 的锅是硬件架构的局限。70B 模型我没有在 V100 上做长时间线上压测只在 TP8 配置下验证过能加载并生成。权重 140GB8 卡剩余显存约 116GB纯生成场景并发开 8 能勉强跑起来TPOT 大约 180-220ms远不如 7B/13B 流畅。如果业务必须上 70B我强烈建议量化到 INT8 或 INT4 以腾出 KV Cache 空间否则长上下文场景必定 OOM。5.3 数据说明真实业务的容量规划结合以上数据一个比较实用的容量规划方式是拿业务高峰期实际请求量和平均输出长度反推需要多少卡。假设业务高峰 QPS 需要 10平均输出 300 token7B 模型 TPOT 约 35ms单请求生成阶段耗时约 300×0.03510.5 秒。如果目标并发 20那 vLLM 理论上最多同时处理 20 个请求每完成 10.5 秒一个承载 QPS 约为 20/10.5≈1.9。注意这里还没算 prefill 排队时间实际能承载的 QPS 远低于直觉上的“并发数除以单请求耗时”。这个计算常常让团队惊讶因为大家以为 8 张 V100 跑 7B 能轻松扛几十 QPS实际上在 300 token 输出的业务场景下能稳定扛 5-10 QPS 已经是把参数调到最优的结果。想扛更高并发只能缩短输出长度、加模型副本、或者换更强算力的卡。容量规划阶段把这些算术算清楚比上线后被性能问题追着跑要舒服得多。6. 调优实践与常见问题排查6.1 性能调优的先后顺序我在部署和压测过程中反复修改参数踩了不少坑最后总结出一个调优顺序按优先级排列。第一优先级是确认tensor-parallel-size合适。TP 过大导致通信瓶颈过小导致单卡算力不足7B 试 TP4 和 TP213B 试 TP4 和 TP8拿压测数据说话别凭感觉。第二优先级是max-model-len能压多短压多短。第三是max-num-seqs它和 KV Cache 显存、排队延迟直接相关。最后才是gpu-memory-utilization一般不动它默认 0.9 左右即可。有个参数容易被忽略--block-size。vLLM 默认 KV Cache 块大小可能是 16 或 32在 V100 上小块能更好利用显存碎片但调度开销也更高。我实测在并发高的时候块大小 32 比 16 的 TPOT 略低显存利用率没明显区别所以保持默认就好。还有一个重要选项是--quantization。V100 跑 FP16 模型是最稳妥的不要轻易上 AWQ 或 GPTQ 量化。虽然量化能减少显存占用但 V100 的 INT8 kernel 支持有限有些量化模型加载后速度反而更慢而且激活层精度问题排查起来特别麻烦。如果非要上 70BINT8 优先级高于 INT4因为 INT4 在 V100 上的反量化开销更明显。6.2 常见问题速查与解决方案现象原因分析解决思路启动就报 device not capableCUDA 版本和 vLLM 不匹配或 kernel 不支持 V100锁 CUDA 11.8换 vLLM 稳定版加载模型后 OOM权重太大或 max-model-len 过大压低 max-model-len开 swap-space并发一高 TTFT 飙升max-num-seqs 太小或 GPU 算力瓶颈适当调大 max-num-seqs并评估限流生成速度突然变慢显存碎片、KV Cache 换页到 CPU重启服务降低 gpu-memory-utilization 留余量多个请求排队但 QPS 不涨算力到瓶颈而不是显存瓶颈加模型副本或换更强算力卡这里我要特别提醒一点vLLM 在 V100 上跑的时间越长KV Cache 碎片化越严重长时间运行后建议定时重启或设置请求数量上限自动 reload。这个不是 vLLM 的问题是所有带缓存推理引擎的通病但 V100 由于算力弱、高并发时间长碎片化问题暴露得更明显。6.3 避坑心得V100 与新版 GPU 的差异如果团队之前主要用 A100 或 H100 跑 vLLM切到 V100 时最容易踩的坑有三个。第一是 BF16 支持。V100 没有原生 BF16有些新模型权重是 BF16 格式会在 V100 上报精度格式不支持。解决办法是用 FP16 重新保存一份权重或者在加载时做转换。第二是 attention kernel 优化缺失。新卡上有高度优化的 kernelV100 没有长序列 prefill 慢得明显这不是参数能调好的只能通过限制max-model-len、减少单请求输入长度来缓解。第三是多卡互联。如果机器里 V100 是 PCIe 版本而不是 SXM 版本NVLink 不可用TP8 的通信会走 PCIe带宽差很多TP4 以上的收益会大幅缩水。买卡或租卡时一定要确认是 SXM 还是 PCIe这个信息在设备型号里通常直接能看到。7. 从成本与选型角度的最终判断7.1 V100 32G 跑推理到底值不值先算一笔简单的账。8 张 V100 32G 如果按租用算比同等的 A100/H100 便宜很多显存总容量 256GB 却能跑很多中小模型且 32G 单卡显存意味着 7B、13B 这种模型不用做模型切分到两卡部署简单。但 V100 的短板也很明显算力不如新卡、软件优化少、长序列能力弱。如果你业务是高并发短文本客服问答、文本分类V100 32G 的 8 卡集群性价比非常突出如果你业务是长文本写作、长文档分析V100 会让用户体验明显打折。我个人的判断是V100 32G 适合做模型规模在 7B-13B、输出长度控制在 500 token 以内的在线推理以及作为离线批量推理的算力池。如果你的业务模型必须上 70B 或者要求长上下文V100 的成本优势会被性能劣势抵消不如优先考虑新架构卡。7.2 什么时候该升级硬件从测试数据看真正的红线是 TPOT。当 TPOT 超过用户体验容忍阈值一般 100ms 以上用户就会有明显等待感或者并发上去后 TTFT P95 超过 2 秒这块集群就不适合继续承载在线业务。用这些指标做度量8 卡 V100 32G 在当前配置下能稳定支撑的在线业务形态大致是7B 模型、并发 20-30、输出 300 token 以内、QPS 5-10。如果你的业务指标比这个高扩容或上新卡是必然选项如果比这个低V100 32G 完全可以胜任没必要为“旧卡”的名头焦虑。写到这里回顾整个部署和测试过程我最大的体会是大模型推理性能不是靠堆显存堆出来的而是靠算力、显存、通信三者的平衡。V100 32G 有显存、有带宽缺的是算力和新架构的软件优化所以能跑但一定要把期望放在“中小模型、短输出”的合理区间内。如果你手头也有 V100 32G 集群建议先从 7B 模型的 TP4 配置开始把我们这套压测流程跑一遍用真实数据决定业务是否上线比任何参数教程都靠谱。