说实话我刚看到“在 2×V100 上跑 QUASAR-NVFP4 量化模型”这个需求时第一反应是V100Volta 架构Tensor Core 只认 FP16 的老卡NVFP4 可是 NVIDIA 给 Blackwell 那一代准备的东西这不是拿老爷车跑赛道吗后来把 vLLM 的加载逻辑翻了一遍又上手实测了两周才发现这条路不仅走得通而且对预算有限的本地部署党来说性价比意外地高。1Cat 是我给这次部署起的系列代号没啥高深的含义——就是一只猫。V100 当不了猛虎但当一只灵巧的猫跑跑量化模型还是够的。这篇就把我的完整过程写下来从硬件体检、Docker 环境、vLLM 启动参数到压测数据、踩坑经验争取让你照着抄就能在自己的两张 V100 上把模型拉起来。1. V100明明是FP16老卡为什么能跑NVFP4模型1.1 NVFP4不是高不可攀vLLM先把权重翻译成FP16先讲清楚一个很多人搞混的概念。NVFP4 是 NVIDIA 主推的 4-bit 浮点格式权重在磁盘和显存里确实是以 4-bit 存的但 V100 的硬件本身不认识 FP4Volta 架构的 Tensor Core 只支持 FP16连 BF16 都要走模拟路径更别提 FP8 和 FP4 了。那为什么能跑关键在于 vLLM 的加载流程它读到 NVFP4 格式的权重后不会直接把 4-bit 数据塞给计算核心而是先做一次反量化dequantize把权重恢复成 FP16再进入计算管线。换句话说NVFP4 只是“存储格式”不是“计算格式”。这就好比收到一个快递箱子里是压缩包但拆开之后读的还是普通文档。压缩操作在别处完成了V100 只需要会读解压后的文档。至于 QUASAR这是量化方案的名字。它和朴素 FP4 最大的区别在于朴素 FP4 就是简单地把权重四舍五入到最近的四位浮点误差不可控QUASAR 把“如何舍入、如何缩放”当作一个优化问题来解用校准数据学习一组对下游损失更友好的量化参数。两者组合起来权重精度逼近 4-bit 的理论极限比直接 round-to-nearest 的 FP4 量化要稳得多。1.2 2×V100 16GB的显存篮子究竟能装多大模型两张 V100 16GB总共 32GB 显存听起来不少。但注意vLLM 的 TP2 会把每一层权重切到两卡上每张卡上还要留 CUDA context、激活、KV cache实际能用的空间比你想象的紧。我按 14B 模型算了一笔账这是 2×V100 16GB 比较从容的上限模型规模NVFP4权重大致占用2×V100 16GB 可行性建议方案7B约 3.5GB轻松甚至可以单卡跑14B约 7GB可以TP2 从容我实测的主方案32B约 16GB很紧只能极短上下文不推荐34B 以上超过 17GB不建议换 32GB 显存或做 CPU offload计算逻辑是这样的14B 参数 × 4bit ÷ 8 7GB 权重。embedding 和 lm_head 在实现里通常保留为 FP16再加 1-2GB。TP2 切分后每卡权重约 4-5GB剩下 10-11GB 给 KV cache 和激活。把--max-model-len设成 8192、--gpu-memory-utilization设成 0.9 时KV cache 大概能到 8GB 量级跑一个小几十并发规模的内部服务没问题。你要是想硬上 32BNVFP4 权重就要 16GBTP2 切完两卡后每卡 9GB 左右留给 KV cache 的只剩两三个 GB基本只能单请求、短上下文地跑体验会很憋屈。2. 部署前先体检驱动、ECC和Docker透传2.1 nvidia-smi查ECC二手V100必做V100 是 HBM2 显存市面上大量是服务器拆机卡、矿场退役卡跑过长时间高负载后个别显存单元会出错。好在 V100 支持 ECC能自查。上手第一件事跑这条命令nvidia-smi -q -d ECC看两个指标Volatile 是本次驱动加载以来的错误计数Aggregate 是累计计数。Single-bit 错误偶尔一两个还好但如果 Uncorrectable 出现就要立刻拉高警惕。Aggregate 里只要 Uncorrectable 大于 0说明这块卡曾经发生过不可纠正的错误长任务推理中随时可能给你吐一个 NaN 出来。遇到这种情况别急着退卡。先清空计数nvidia-smi -r看显卡是否支持如果不支持就重启主机再跑一段时间复查 Volatile 是否复现。如果不再复现大概率是历史遗留问题可以继续用如果频繁出现 Uncorrectable这卡不适合跑量化推理——反量化过程对数值正确性非常敏感一个 bit 的错误都可能放大成整段输出的乱码。2.2 宿主驱动和容器CUDA的分工别再手动叠CUDA我很多朋友卡在驱动版本其实是把问题搞复杂了。V100 只需要宿主机装好 NVIDIA 驱动CUDA 和 PyTorch 相关依赖全部交给 vLLM 官方镜像不要在宿主机上手动装一堆 CUDA toolkit。判断标准很简单docker run -d --gpus all起的容器里能不能看到nvidia-smi。只要这步通了环境就算稳了。所以先装 NVIDIA Container Toolkitapt install nvidia-container-toolkit nvidia-ctk runtime configure --runtimedocker systemctl restart docker这套做完容器内nvidia-smi能列出两张卡才算拿到下一步的入场券。如果用的是显卡坞或者转接卡还要注意驱动里 display 输出会抢占显存的问题最好别把显示器插在 V100 上headless 模式跑推理最干净。2.3 Docker run 的两张卡透传与P2P检查我的启动命令大概长这样docker run -d --gpus all -p 8000:8000 \ -v /models:/models \ vllm/vllm-openai:latest \ vllm serve /models/qwen2.5-14b-quasar-nvfp4 \ --quantization nvfp4 --dtype float16 \ --tensor-parallel-size 2 \ --max-model-len 8192 --gpu-memory-utilization 0.9注意两点。第一官方镜像里不带模型模型要放到挂载目录里或者先从模型仓库下载好再映射进来。有些镜像 tag 会写 qwen3.8 之类那是预先集成了对应模型功能上一样但自己挂载更可控方便换模型和复现。第二TP2 依赖两张卡之间的通信。V100 没有 NVLink 的时候tensor parallel 通信走 PCIe速度差很多。启动前先检查拓扑nvidia-smi topo -m如果显示两张卡之间是NODE或PXB之类说明走的是 PCIe 路径能跑但并发高时通信会成为瓶颈。如果显示NV#恭喜你有 NVLink性能上限会高不少。3. vLLM启动确认量化元数据再填参数3.1 先看模型目录里的quantization_config现在 QUASAR-NVFP4 格式的模型仓库config.json里一般会有quantization_config字段长这样quantization_config: { quant_method: nvfp4, block_shape: [1, 16, 16, 16], group_size: 128 }看到quant_method是nvfp4就可以放心交给 vLLM。如果显示的是其他格式比如fp8或者awq别硬指定--quantization nvfp4因为反量化的 scale 和 group 参数对不上第一轮推理就会开始胡说八道。下载完模型后我建议先检查一下文件结构再启动。通常目录里会有一堆.safetensors文件量化后的张量名称会带qweight、weight_scales之类的后缀。确认无误再动手能省掉后面 debug 到崩溃的时间。还有一个点要提醒不是所有标着 “FP4” 的模型都是 NVFP4。市面上有些普通 FP4 量化模型group 结构完全不同vLLM 的 NVFP4 路径不一定兼容。遇到这种情况优先去找官方或社区确认格式不要想当然。3.2 启动参数逐个拆解核心参数就几个--quantization nvfp4强制 vLLM 走 NVFP4 反量化路径这是本次部署的关键开关。--dtype float16V100 没有 BF16 硬件支持显式指定 float16让权重和激活统一在 FP16 上计算。你不写的话vLLM 也会自动处理但显式写出来可以避免某些模型配置里默认 BF16 导致的慢速回退。--tensor-parallel-size 2两张卡跑 TP。--max-model-len决定单请求上下文长度上限直接影响 KV cache 规划。--gpu-memory-utilizationvLLM 会按这个比例预留 GPU 内存剩下的全部给 KV cache。我给 0.9 是因为 14B 在 TP2 下权重压力不大如果你启动就报 OOM先降到 0.85。这里特别强调一下不要尝试--quantization fp8之类的参数V100 不支持vLLM 要么直接报错要么退化成没人想用的慢速路径。新版 vLLM 对老卡的算子选择已经做了很多兼容但不支持的硬件特性就是不支持别硬开。3.3 KV cache爆掉的退路如果你启动成功但并发一上来就 OOM优先试这两条退路。第一条砍--max-model-len。8192 变 4096KV cache 直接减半。很多人把上下文开得很大实际业务根本用不到这才是 OOM 的常见原因。第二条加--enable-chunked-prefill。把预填充阶段拆成小块执行显存峰值明显下降代价是长输入的首 token 延迟略有上升。这是用小显存换稳定性的典型解法V100 上很实用。第三条--swap-space 16把 KV cache 换到系统内存。这个方案能救急但吞吐会掉到正常人无法接受的水平我建议只用来验证流程能通别当常规方案用。4. 实测压测数据、量化损失和调优教训4.1 并发压测的一组参考数据我实测的硬件组合2×V100 16GB无 NVLink走 PCIe 3.0。模型是 Qwen2.5-14B-Instruct 的 QUASAR-NVFP4 版本。测试方法不复杂用 OpenAI 兼容接口开 N 个线程同时发请求Prompt 约 500 token采样输出目标 256 token。并发数总吞吐 (tokens/s)首Token延迟 (s)每卡显存占用130-400.3-0.5约 10.5GB8140-1801.2-2.0约 11.8GB16190-2202.5-4.0约 12.5GB32210-2405.0-7.0约 13.2GB注意这是参考值。我的两张卡走 PCIe 没有 NVLink所以并发越高TP 通信消耗越明显。如果你有 NVLink32 并发的总吞吐还能再往上拉一截但首 token 延迟依然会受调度队列影响。4.2 NVFP4和FP16到底差多少这个问题的答案直接决定你能不能放心用。我拿同一批 30 条问题对比了 FP16 原版和 NVFP4 量化版的输出结论如下多轮对话、知识问答类两者差别很小偶尔用词不同但语义一致。代码补全几乎没差别函数体、注释风格都稳定。数学计算和长文档细节摘要NVFP4 有明显“丢粒度”的现象比如三位小数变成一位小数或者关键数字记错。QUASAR 相比朴素 FP4 的优势正是体现在极端错误出现的频率上。它用校准数据学到了更合理的舍入策略把误差峰值压下去了。所以我的建议是日常内部助手、摘要、代码场景放心用对数值精度敏感的任务还是单独保留一个 FP16 小模型需要的时候切换过去。4.3 调优方向锁版本、控制并发、别碰不支持的算子社区里最近总在讨论 vLLM 新版本性能下降的问题我自己也有体感。原因很复杂调度策略调整、算子实现变化、对新硬件做了优化但老卡没跟上。所以我的做法很简单——先锁定一个能稳定跑通 NVFP4 的镜像版本把它记进项目 Notes之后没出大问题就不动。调优项方面值得试的有三个--max-num-seqs控制单批最大序列数调小能降低显存峰值适合并发不高但请求很杂的服务。--block-size默认 16V100 上改成 32对连续文本生成场景偶尔有惊喜但需要实测对比。--enable-prefix-caching如果多人共用同一个系统提示词这个选项收益非常明显能省掉大量重复 prefill 计算。另外关于 vLLM 的 enginecore、scheduler、executor 交互我不展开讲源码但理解一个点就够TP2 时enginecore 负责整体调度每个 executor 负责对应卡上的算子执行两张卡之间通过 tensor parallel 通信。如果通信慢了调度再快也没用。所以 V100 无 NVLink 的机型调优重点永远是“降低通信频率”而不是“提高计算效率”。5. 按出现频率排序的五个坑下面这些坑每个都是我在实测中撞过的按出现频率从高到低重排了一下方便你对号入座。5.1 “Unsupported quantization method: nvfp4”现场症状vLLM 启动直接报错拒绝加载模型。原因几乎都是同一个vLLM 版本太老还不支持 NVFP4 格式。解法也简单拉新镜像——docker pull vllm/vllm-openai:latest或者找一个官方确认支持 NVFP4 的稳定版本 tag。这个坑之所以排第一是因为网上能找到的很多教程都是旧版本的照抄必踩。5.2 “CUDA out of memory”现场症状模型加载成功但一波并发上来就 OOM有时连启动阶段都过不去。原因--gpu-memory-utilization配太高或者--max-model-len开太大。很多显卡坞用户还额外叠加了 display 占用显存的问题。解法按顺序试降--gpu-memory-utilization到 0.85把--max-model-len从 8192 砍到 4096再加--enable-chunked-prefill。三步走完基本能解决九成以上的 OOM。5.3 TP2比单卡还慢或卡0报错、卡1正常现场症状吞吐上不去甚至比单卡还低或者日志里卡 0 报通信错误卡 1 却一切正常。原因两张卡之间没有 NVLink走 PCIe 通信开销太大或者 P2P 通信没打通。先用nvidia-smi topo -m查拓扑。没有 NVLink 时TP2 在低并发下反而可能比单卡慢因为每层都要同步权重和梯度通信时间比计算时间还长。这种场景下的选择是要么接受低并发上限要么干脆放弃 TP换成单卡跑 7B 模型有时综合体验更好。5.4 容器里nvidia-smi看不到显卡现场症状docker run成功但容器里跑nvidia-smi显示无设备。原因宿主机没装 NVIDIA Container Toolkit或者容器启动时没加--gpus all。先确认宿主机nvidia-smi正常再执行nvidia-ctk runtime configure --runtimedocker并重启 Docker最后检查启动命令里有没有--gpus all。这个坑其实最基础但也是最容易在环境迁移时被忽略的。5.5 偶发NaN和乱码现场症状服务跑几天后偶发请求返回乱码或坍缩式重复输出重启后恢复正常。原因概率排序显存 ECC 错误 电源供电不足 散热导致降频和时序不稳定。这是最阴间的坑因为不是每次都会触发。我排查到最后才定位到是一张二手卡的 HBM2 有轻微 ECC 问题重新插拔后发生频率下降但依然存在。建议提前做体检nvidia-smi -q -d ECC看 Uncorrectable 计数高负载时用nvidia-smi dmon盯温度。这种问题无解时该换卡就换卡别在推理服务上赌人品。最后说点掏心窝的话。V100 在本地部署圈里依然是“穷人快乐卡”二手价格已经跌到可以闭眼入手的地步而 NVFP4 这种“存小算满”的软件量化路径让老卡也能吃到新量化格式的红利。前提是心态摆正——它是一只能抓老鼠的猫但不是老虎。日常几十并发的内部服务、个人 AI 工作站、教学演示这套完全够用真要跑千级并发或超大上下文还是得老老实实攒钱上 Ampere 或更新的卡。如果你照着这篇把环境搭起来了欢迎回来告诉我你的压测数据。不同主板、不同散热、不同 PCIe 拓扑下V100 的表现差异还挺大的我也想多攒几组样本看看能不能总结出更普适的调优规律。