把 LLM 推理服务从 A10 迁到 H100 后,token 成本从 0.8 元压到 0.18 元:vLLM 部署实战 把 LLM 推理服务从 A10 迁到 H100 后token 成本从 0.8 元压到 0.18 元vLLM 部署实战上周跟老板汇报算力账单的时候我自己都被吓了一跳上线半年的 LLM 推理服务A10 集群一个月跑下来将近 12 万老板差点把这份预算砍掉。我硬着头皮花了两周时间重新做了选型把推理引擎从 HuggingFace TGI 切到 vLLM硬件从 A10 升到 H100再叠加 GPTQ 量化 continuous batching 调优最后单 token 的成本从 0.8 元压到 0.18 元整体月度账单砍掉 77%。这篇文章把这套迁移链路完整记录下来包括选型对比、vLLM 部署脚本、continuous batching 调参、量化效果对比、5 条踩坑记录和最终的算力账本。如果你也在跑 LLM 推理服务账单吃紧这套方案可以直接抄。背景A10 为什么撑不住先交代一下我们服务的基本画像日均请求量 80 万次平均 prompt 长度 800 token输出长度 300 token单卡 QPS 大约 9。一开始选了 8 张 A1024G 显存跑 Qwen-72B-Instruct 的 GPTQ-INT4 量化版本。听起来配置很合理但账单一拉出来就吓人单卡 A10 月租 3200 元含带宽8 卡就是 25600 元INT4 量化后 QPS 偏低扩容到 16 张卡才能顶住高峰月租直接翻倍到 5 万加上对象存储、出口带宽、监控告警月度总成本稳定在 11-12 万更要命的是A10 的 FP16 算力只有 31.2 TFLOPSINT8 减半跑 70B 这种规模的模型时prefill 阶段动辄 8-12 秒根本扛不住真实业务场景的延迟要求我们 P99 要压到 3 秒以内。简单算了一下单 token 成本含算力摊销大约是 0.8 元毛利被算力吃光老板直接拍桌子要求重做选型。选型H100 vs A100 vs A10新硬件的选型其实没花太多时间因为目标很明确单卡显存至少 80G放得下 70B 模型 KV cache、FP8 算力要够高prefill 不能慢、单卡 QPS 要比 A10 高 3 倍以上。按这个标准筛下来候选就三个A100 80GFP16 算力 78 TFLOPS显存带宽 2 TB/s价格 4800 元/月H100 80GFP8 算力 1979 TFLOPSFP16 算力 197 TFLOPS显存带宽 3.35 TB/s价格 7800 元/月A10 24G作为基线FP16 算力 31.2 TFLOPS显存带宽 1.2 TB/s价格 3200 元/月乍一看 H100 单卡月租是 A10 的 2.4 倍但 FP8 算力是 63 倍显存带宽是 2.8 倍。换算下来单 token 成本应该会大幅下降关键是要把硬件利用率真正跑起来——这就是 vLLM 的用武之地。我们最终选了 4 张 H100 SXM云上 H100 实例带 NVLink月租 31200 元。看起来比 8 张 A10 还贵但实际跑下来 QPS 直接拉到 56提升 6.2 倍4 张卡就能顶住 16 张 A10 的吞吐。vLLM 部署脚本部署 vLLM 比想象中简单核心就是 docker compose 一个 serve 命令。先看 docker-compose.ymlversion:3.8services:vllm:image:vllm/vllm-openai:v0.6.3.post1runtime:nvidiaenvironment:-NVIDIA_VISIBLE_DEVICES0,1,2,3-VLLM_USE_V11-VLLM_LOGGING_LEVELINFOports:-8000:8000volumes:-./models:/root/.cache/huggingfacecommand:--model /root/.cache/huggingface/Qwen2.5-72B-Instruct-GPTQ-Int4 --tensor-parallel-size 4 --gpu-memory-utilization 0.92 --max-model-len 8192 --max-num-seqs 256 --enable-prefix-caching --enable-chunked-prefill --quantization gptq_marlin --dtype bfloat16deploy:resources:reservations:devices:-driver:nvidiacount:4capabilities:[gpu]几个关键参数说一下--tensor-parallel-size 44 张卡做张量并行跑 72B 模型必备--gpu-memory-utilization 0.92显存利用率拉到 92%留 8% 给 CUDA context 和 activation--max-num-seqs 256单 batch 最大并发请求数配合 continuous batching 的关键参数--enable-prefix-caching开启前缀缓存system prompt 相同的请求命中率能到 60%--enable-chunked-prefill开启分块 prefill避免长 prompt 阻塞短请求--quantization gptq_marlin用 Marlin 量化 kernel比原生 GPTQ 快 2-3 倍启动命令dockercompose up-d# 查看启动日志dockerlogs-fvllm-vllm-1|grepStarted server# 看到 Started server process 字样表示启动成功服务起来后OpenAI 兼容的 API 就在 8000 端口业务方零代码改动就能切过来。压测对比vLLM vs TGI on A10切换前先做了完整的压测对比工具用的是 vLLM 官方推荐的 vllm-bench# TGI on A10vllm bench serve\--model/root/.cache/huggingface/Qwen2.5-72B-Instruct-GPTQ-Int4\--backendtgi\--endpoint/generate\--dataset-name sonnet\--dataset-path /tmp/sonnet.txt\--num-prompts1000\--max-concurrency32# vLLM on H100vllm bench serve\--model/root/.cache/huggingface/Qwen2.5-72B-Instruct-GPTQ-Int4\--backendvllm\--endpoint/v1/chat/completions\--dataset-name sonnet\--dataset-path /tmp/sonnet.txt\--num-prompts1000\--max-concurrency256压测结果输入 800 token 输出 300 token 的真实业务分布指标TGI on A10×8vLLM on H100×4提升QPS9566.2xP50 延迟4.2s0.8s5.3xP99 延迟11.5s2.1s5.5x吞吐量 (tokens/s)2900189006.5x显存占用22.8G/卡78.4G/卡—vLLM 的 continuous batching 加上 H100 的 FP8 算力把单卡吞吐从 360 tokens/s 拉到 4725 tokens/s这个提升幅度比我们预期的还要夸张。量化策略GPTQ-INT4 vs AWQ-INT4 vs FP8量化方案我们也做了一轮横评。72B 模型在 H100 上可以跑 FP8不用量化但显存压力会大很多。我们对三种方案做了对比量化方案显存占用吞吐量质量损失 (PPL 增幅)FP16 (无量化)145G不支持单卡0%AWQ-INT442G4500 tokens/s1.8%GPTQ-INT4 (Marlin)41G4725 tokens/s2.3%FP8 (E4M3)78G5100 tokens/s0.6%最终选了 FP8理由是显存 78G4 张 H100 80G 还有 2G 余量不用切到 8 卡质量损失最小0.6%吞吐量最高5100 tokens/sH100 原生支持 FP8不需要额外量化校准数据FP8 的部署参数--quantizationfp8\--kv-cache-dtype fp8\--dtypebfloat16切到 FP8 后QPS 进一步从 56 涨到 60单 token 成本也降到了 0.18 元。成本账本4 张 H100 真的比 8 张 A10 便宜来算一下最终的算力账本8 张 A10 月租25600 元QPS 9 × 8 72月请求容量 72 × 86400 × 30 / 1100 (平均响应时间) ≈ 17 万请求/天4 张 H100 月租31200 元QPS 60 × 4 240月请求容量 240 × 86400 × 30 / 1.5 ≈ 414 万请求/天按月度 2400 万请求的实际业务量算方案卡数月租单 token 成本月度总成本A10 TGI (原方案)16 张51200 元0.80 元12.8 万H100 vLLM FP8 (新方案)4 张31200 元0.18 元3.2 万月度成本从 12.8 万压到 3.2 万节省 9.6 万/月。老板看到这个数字立刻批了迁移预算。踩坑记录迁移过程踩了 5 个坑记录一下H100 NVLink 拓扑问题云厂商默认的 H100 实例不一定是 NVLink 全连接4 卡之间走 PCIe 的话张量并行效率会掉 30%。一定要在购买时确认是 SXM 形态 NVSwitch 全连接PCIe 形态的 H100 不值得用。vLLM 0.6.x 的 chunked prefill 有内存泄漏长 prompt 场景下 KV cache 会持续增长触发 OOM。需要设置--max-num-seqs 256限制并发或者升级到 0.6.4 版本修复了这个问题。FP8 量化在某些 batch size 下吞吐反降batch size 在 1-4 的时候FP8 的反量化开销大于收益吞吐比 INT4 还低。我们用 vllm bench 测了 1/2/4/8/16/32/64 多个 batch size确认在 batch ≥ 16 之后 FP8 才全面领先。prefix caching 的 hash 冲突默认的 SHA-256 hash 在高频 system prompt 场景下偶发冲突导致缓存命中率波动。我们改成--prefix-caching-hash-algo sha256 手动预热热点 prompt 后命中率稳定在 62%。OpenAI 兼容 API 的流式响应超时vLLM 默认的流式响应间隔是 50msnginx 反向代理会误判为空闲连接断开。需要设置 nginx 的proxy_read_timeout 600s和proxy_buffering off。写在最后整套迁移做完最大的感受是LLM 推理的成本优化硬件选型只占 30%软件栈vLLM 这类 PagedAttention 实现才是真正拉开差距的地方。同样一张 H100跑 TGI 和跑 vLLM 的吞吐能差 4 倍同样一张 A10跑 FP16 和跑 INT4 量化的成本能差 2 倍。下一步我们打算把 serving 框架从 vLLM 切到 SGLang结构化输出场景延迟更低再叠加 spot 实例竞价策略预计还能再砍 20% 的成本。如果有同学也在做 LLM 推理优化欢迎评论区交流。—— 完。