ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

V100老卡跑NVFP4量化模型双卡部署实录:原理、踩坑与提速实践

V100老卡跑NVFP4量化模型双卡部署实录:原理、踩坑与提速实践 上周帮人部署一台双卡V100的推理服务器目标很明确把QUASAR-NVFP4量化模型在2×V100上跑起来对外提供稳定的OpenAI兼容接口给内部业务用。这活儿看着简单真正做起来牵扯的东西不少——V100是Volta架构的老卡NVFP4是NVIDIA为Blackwell准备的4-bit浮点格式1Cat-vLLM又是一套在vLLM基础上做量化适配的社区分支三个变量叠在一起想把它们拧到同一根轴上我前后折腾了快三天。这篇文章就把整个过程从头到尾捋一遍包括那些文档里找不到的坑给同样手里攥着几块V100又不想扔的朋友一个参考。整个部署过程中最反直觉的一点是V100本身没有任何FP4计算单元但量化模型跑起来不仅显存问题解决了速度反而比FP16版本更快。这个结论背后牵扯到量化格式的存储方式、kernel的加载路径、以及两张卡之间的通信方式。把这些搞明白你就不会觉得这是一件碰运气的事而是一套可以稳定复现的工程方案。1. 为什么要在V100这种老卡上跑NVFP4量化模型——背景与选型1.1 这件事的起点两张V100和QUASAR模型V100是2017年发布的Volta架构数据中心卡放在今天确实算老古董了。但它有个优势二手市场价格很低而且16GB HBM2在某些场景下依然比消费级显卡能打。QUASAR这个模型我拿到的版本是35B总参数、约3B激活参数的MoE结构长上下文能力比较强从架构特征看跟最近开源的Qwen系35B-A3B-MTP-Compact模型同源。原版FP16权重的话35B×2字节就是70GB两张32GB V100都塞不下更不用说我手上这两张只是16GB版本。所以量化是唯一出路而不是什么可选项。NVFP4量化之后权重直接从2字节/参数降到0.5字节/参数35B模型大约只需要17.5GB的权重存储。加上scaler表和一些开销两张16GB V100做tensor parallel切分后每卡大概只需要9GB左右放权重剩下6GB可以全部留给KV cache和激活值。这个数学账一算方案就基本定了。1.2 不量化的路根本走不通用数字说话我们先把显存账算细一点。QUASAR这类35B级MoE模型FP16权重是70GB如果退一步用INT8量化权重降到35GB两张32GB V100勉强装下但16GB版本依然无望。NTFP4/4-bit量化后权重是17.5GB加上每128个元素一个FP32 scale粗略增加1.1GB合计18.6GB。两张16GB V100总显存32GBTP2后权重均摊到每卡约9.3GB剩余空间可以支撑几万token的KV cache。这不是优化问题是能不能跑的问题。V100只有16GB和32GB两个显存版本二手市场上16GB居多。对很多预算有限的团队来说与其换全套平台不如让老卡继续服役。另外还有个隐性好处权重变小后两张卡之间 tensor parallel 通信的数据量也小了这在没有NVLink的PCIe平台上尤其重要。后面我会专门讲这个点。1.3 为什么是1Cat-vLLM而不是原版vLLM原版vLLM对FP4/NVFP4这类格式的支持是最近才逐步完善的而且主要针对Blackwell新卡。1Cat-vLLM这个分支做的事情是在原版基础上补齐了老卡的兼容路径注册了nvfp4量化方式入口修改了权重加载逻辑让FP4权重可以在kernel内部反量化成FP16参与计算。也就是说它保留了vLLM的调度器、PagedAttention、continuous batching这些核心组件只是在图编译和kernel选择上做了适配。我的选型建议是如果你只是想在V100上跑量化模型优先考虑这种针对性分支不要自己去改原版代码。用原版vLLM强行加载NVFP4模型大概率会卡在不支持的量化格式或者错误的kernel选择上改起来成本不低。1Cat-vLLM对社区量化模型的支持更积极能省下大量调试时间。2. 平台搭建与驱动准备X99、供电、ECC与TCC模式的坑2.1 X99平台双卡怎么拆PCIe通道这次用的是一块X99主板配两颗至强处理器的平台这是目前DIY双卡推理服务器最常见的方案之一。X99属于LGA2011-3接口Haswell-E/Broadwell-E级别的CPU一般提供40条PCIe 3.0通道足够拆成x16x16给两张V100用。需要注意的点是CPU通道数不够40条的低端型号会变成x16x8对TP2这种通信敏感的负载有一定影响。实际装机时还要确认PCIe插槽的物理带宽是否被其他设备占用比如有些主板插上M.2 SSD后会从PCIe x16槽借通道。我的做法是装系统前先在BIOS里把PCIe链路设置为x16/x16并检查两条槽位是否跑在Gen3速率。V100的PCIe版对外功耗一般在250W左右如果主板插槽供电不够两张卡满载时会直接掉驱动或者触发保护。稳妥的方案是使用服务器电源并用转接线给每张卡单独供电别指望主板PCIe插槽那75W能扛住。2.2 V100驱动选型与TCC/WDDM问题V100的驱动选择有个容易被忽略的分叉如果你只是跑Linux容器装数据中心驱动datacenter driver就好不要装带显示功能的桌面驱动。我在实际部署中用的驱动分支是r535系列对V100支持稳定CUDA runtime可以用12.x编译vLLM和flash-attn都没有问题。如果你在Windows下做前期验证就会遇到TCC和WDDM的问题。V100默认可能跑在WDDM模式这个模式会保留显示输出能力但对纯计算负载有额外开销而且显存管理方式不友好。切成TCC模式后GPU对CUDA计算是直通状态显存利用率更高也不会有桌面刷新抢占计算资源的问题。切换命令需要管理员权限在Windows设备管理器里找到显卡属性中的compute mode或直接用nvidia-smi切换切完必须重启。不过TCC只解决Windows下的验证问题正式服务我还是强烈建议搬到Linux。2.3 ECC内存错误跑大模型前先体检V100的HBM2显存带ECC纠错这是它非常适合长期跑推理任务的原因之一。二手卡到手后第一步不是急着装环境而是查看ECC错误计数。命令很简单nvidia-smi -q -d ECC看Volatile和Aggregate两个字段Volatile代表开机以来的瞬时错误Aggregate是累积计数。单bitSingle Bit错误少量出现问题不大ECC能自动纠正但如果Double Bit错误持续增长说明显存颗粒可能已经开始不稳定跑长任务随时可能触发CUDA错误。我在这次部署中就有一次经历模型加载后跑了两个钟头突然出现计算错误排查一圈发现是另一张卡的Aggregate Double Bit计数在增加。处理方式是先重启机器排除瞬时状态然后在BIOS里把卡的供电策略调保守一点同时用nvidia-smi --ecc-config1强制开启ECC让硬件做纠错。V100开ECC会损失约6%可用显存但换来稳定性非常值得尤其跑30B级模型一次推理的时间那么长中途崩一下代价太大。3. QUASAR-NVFP4量化格式解析V100没有FP4单元凭什么能跑3.1 NVFP4到底怎么存数E2M1与分组缩放NVFP4是NVIDIA定义的4-bit浮点格式核心规格是E2M11位符号、2位指数、1位尾数。什么意思呢它表示的数比传统4-bit整数格式比如INT4动态范围更大接近浮点的分布特性更适合神经网络权重那种大部分值集中在0附近偶尔有大的离群值的分布。但只有4位不可能表示足够精确的数值所以NVFP4的关键设计是分组量化FP32缩放因子。实际存储时每128个权重值共享一个FP32的scale参数存储时保存量化后的4-bit值和scale计算时用scale反量化回浮点。这样的好处是即便单个4-bit值只有15种可表示状态但乘以合适的scale后每个组内都有高精度的动态范围。对MoE模型来说专家矩阵的权重分布差异大分组缩放能显著降低量化误差。3.2 V100上的真实执行路径FP4存储、FP16计算V100的Tensor Core支持FP16和INT8但不支持FP8和FP4。那怎么跑NVFP4模型答案在于NVFP4是存储精度不是计算精度。1Cat-vLLM的实际执行路径是这样的模型权重在磁盘和显存中以FP4格式存放显存占用减半执行GEMM时自定义kernel把FP4权重从显存加载到寄存器/SRAM解码成FP16解码后的FP16矩阵在V100的Tensor Core上做标准矩阵乘。这里有个很关键的性能逻辑V100的HBM2带宽约900GB/s16GB版FP16权重加载开销大而FP4格式把加载数据量削减一半以上。虽然多了一步反量化但反量化在SM内部完成不占用HBM带宽。对于推理这种访存密集负载省下来的显存带宽比多出来的计算开销更值钱。这就是为什么V100这种不带FP4单元的卡跑量化模型反而比FP16版本整体更快的底层原因。3.3 量化结果怎么看三档量化模型对比如果你见过开源模型量化档排名这类讨论会发现不同量化精度之间的规律基本是FP16效果最好但显存最大INT8是安全退路FP4/NVFP4显存最小但需要慎用。放在V100这种老卡上我的建议是量化方式权重显存速度表现适合场景FP1670GB需4卡以上追求效果显存宽裕INT835GBV100原生INT8加速双卡32GB或四卡16GBNVFP4约19GB带宽压力小速度可观双卡16GB/32GB实用优先对QUASAR这种35B级模型双16GB V100其实只有NVFP4一条路。既然没有别的选择重点就是如何把量化质量保住。实际用下来模型在长文本生成和指令跟随上的损失可以接受数学推理上比FP16弱一些但不算明显崩坏。这个代价换来的是从不能跑到能跑的质变。4. 1Cat-vLLM部署实操从源码安装到双卡推理服务4.1 环境依赖与源码编译部署前先把基础环境理清楚。我的建议环境是Ubuntu 22.04、CUDA 12.x、Python 3.10/3.11。V100的算力是7.0CUDA 12.x依然支持sm_70所以编译不会有问题不建议追新CUDA 13那种版本对Volta的兼容性已经出现松动。1Cat-vLLM的安装我推荐源码编译方式。先按照项目仓库README把依赖装齐然后在项目根目录执行pip install -e .编译过程会构建自定义的量化kernel耗时要看机器性能通常十几分钟到半小时。如果编译过程中报flash-attn相关错误多半是flash-attn版本和CUDA版本不匹配。处理办法是不让它强制安装改用项目要求的指定版本或者直接设环境变量在V100上走eager模式兜底。4.2 模型权重获取与目录准备模型权重建议放在一个纯路径里不要带中文和空格。将Quasar-NVFP4的模型目录准备好后注意检查里面的配置文件是否包含quantization_config字段。如果字段缺失启动时需要手动指定--quantization nvfp4如果字段写着fp4或者nvfp41Cat-vLLM会自动识别。我习惯先单独验证一下权重目录的完整性和tokenizer文件python -c from transformers import AutoTokenizer; AutoTokenizer.from_pretrained(/path/to/QUASAR-NVFP4); print(ok)这个步骤能提前暴露目录结构问题避免后面启动服务时才发现tokenizer加载失败。4.3 启动服务的完整命令与参数解读服务启动命令如下这段配置我在双卡V100上实测可用python -m vllm.entrypoints.openai.api_server \ --model /path/to/QUASAR-NVFP4 \ --served-model-name QUASAR \ --quantization nvfp4 \ --dtype float16 \ --tensor-parallel-size 2 \ --gpu-memory-utilization 0.92 \ --max-model-len 32768 \ --max-num-seqs 16 \ --port 8000逐个说下关键参数。--quantization nvfp4是1Cat-vLLM注册的量化入口告诉后端按NVFP4格式解析权重--dtype float16指定计算精度因为V100不支持BF16 Tensor Core所以统一用float16--tensor-parallel-size 2是把模型按TP切分到两张卡上这是双卡部署最重要的参数--gpu-memory-utilization 0.92表示每张卡允许vLLM占用92%显存留一点给CUDA context和其他开销--max-model-len 32768是上下文上限如果业务对长文本需求不强烈可以降到16384能换来更大的KV cache和并发能力。4.4 验证接口与常见启动报错启动后看到Application startup complete和监听端口号服务就算起来了。用curl验证一下curl http://localhost:8000/v1/completions \ -H Content-Type: application/json \ -d { model: QUASAR, prompt: 用一句话介绍人工智能, max_tokens: 64, temperature: 0.7 }能正常返回choices就说明链路通了。常见启动报错我列几个自己踩过的一是shared memory相关的Bus error多半是Docker容器或系统的/dev/shm太小TP2模式下两个worker进程需要共享权重页Docker启动要加--shm-size10g二是ValueError: Unknown quantization method: nvfp4说明你用的vLLM不是1Cat-vLLM或者分支版本太旧三是CUDA error: out of memory多半是--gpu-memory-utilization给太高TP初始化时CUDA context申请不到空间适当降到0.88再试。5. 双卡实测吞吐、显存与把V100压到极限的经验5.1 显存占用分布权重量化省下的都给了KV cache模型加载完成后用nvidia-smi观察显存两张卡的显存占用非常均衡基本都在14GB左右。其中权重占9GB左右剩下的空间被PagedAttention按需分配给KV cache。这一步的收获很直观如果不量化这个模型根本进不来量化之后KV cache的余量反而比很多小模型还宽裕。长上下文的业务要的就是这个效果。--gpu-memory-utilization 0.92这个值不是无脑越高越好。V100上跑CUDA图形时如果显存被压得太满kernel并发调度可能失败。我的经验是0.90到0.93是甜点区间超过0.95就容易出现CUDA error 2: out of memory这种不是真OOM但确实分配失败的问题。5.2 吞吐量实测与并发调优吞吐量方面我没有把具体数字当标杆来宣传但可以给一个参考趋势在8并发、输出200~500 token的常规负载下双卡整体吞吐能稳定跑在几十到一百多token每秒的区间远满足内部工具链使用。对比同模型FP16在四卡上的表现双卡量化方案的速度大约有20%~50%的领先原因是前面说的带宽优势。并发调优的关键参数是--max-num-seqs。V100的SM数量多但单卡算力不如新卡所以更适合小批量多长度混合的调度模式。max-num-seqs太小会导致GPU利用率不足太大会挤占KV cache或触发排队延迟。我实测16到24之间比较合适你可以用vllm benchmark脚本跑一轮或者直接在业务侧压测看首token延迟和整体吞吐的平衡点。5.3 TP2在无NVLink的PCIe平台上的通信问题没有NVLink是这套平台最大的物理短板。V100的SXM2版本有NVLink但PCIe版本只能走PCIe 3.0 x16双向带宽大约16GB/s。FP16模型在做TP2时每层forward都要做allreduce同步激活值通信量很大而NVFP4模型因为权重本身就是4-bit反量化发生在GEMM之前通信的主要是较小的激活值部分整体压力大幅下降。实测中我发现一个有意思的现象FP16权重时两张卡之间的PCIe通信能把PCIe带宽吃到70%以上GPU利用率反而只在50%上下徘徊换成NVFP4后通信占比下降明显GPU利用率能拉到80%以上。所以这套方案在X99这种无NVLink平台上优势被进一步放大。如果条件允许尽量让两张卡插在直连CPU的槽位上别经过PCH芯片组转接否则延迟会增加P2P还可能直接不可用。可以用nvidia-smi topo -m检查拓扑确认两卡之间是否有P2P能力。5.4 跑长任务时最该小心的三件事第一件是共享内存。刚才提到过/dev/shm太小会导致TP worker之间共享权重失败但即使服务启动成功长时间运行后共享内存被碎块化也可能触发相同错误。建议在系统层面就把共享内存调大比如mount -o remount,size16G /dev/shm一劳永逸。第二件是ECC错误复发。如果长时间跑高负载任务后出现不明CUDA错误第一反应应该是看ECC计数而不是怀疑软件配置。若Volatile Double Bit从0变成几次说明硬件层面的纠错能力被击穿了。此时建议降低gpu-memory-utilization让显存控制器稍微喘口气并观察是否继续增长真要是持续增长老老实实换卡别硬撑。第三件是CUDA graph与V100的兼容性。有几次我刻意开启CUDA graph加速反而在捕获阶段报错。1Cat-vLLM在V100上如果走CUDA graph路径不稳定可以加--enforce-eager参数禁用图模式。代价是每次请求都重新调度吞吐略有下降但稳定性明显提升。老卡上稳妥比微小的性能提升重要。6. 最后聊几句这套方案适合什么人、不适合什么人如果你问我这套2×V100 QUASAR-NVFP4 1Cat-vLLM的组合到底值不值得搞我的回答是看场景。如果你的业务就是提供一个中等并发的内部对话接口对首token延迟不敏感预算又有限这套方案性价比极高。二手V100价格很低加上一套X99平台整个硬件成本可能还不如一张新卡贵却能跑35B级量化模型长上下文能力还很强。但如果你追求高并发、大批量推理或者需要低延迟响应V100已经不适合了——再量化也弥补不了算力代差。另外如果模型效果在这个量化精度下无法满足业务要求也别硬刚换个8-bit量化方案或者上更大显存的新卡才是正路。我个人在实际操作中的体会是做这类老卡部署最大的障碍不是性能而是信息差。文档不会告诉你V100该选哪个驱动分支、TP2该给/dev/shm留多少、FP4权重在老卡上究竟走什么执行路径。把这些问题一个个摸清楚老卡依然能发挥余热。这篇文章里提到的流程和命令都是我实际验证过的东西希望帮你少走几步弯路。下次如果你手里也恰好躺着几块吃灰的V100不妨照着这个思路重新算一笔账——很多模型不是跑不动是没找到合适的跑法。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进