NInfer-V100-Duo 体验记:NVFP4 让老卡跑出 150 t/s 的秘密

TL;DR:NInfer-V100-Duo 是 GitHub 上 plus1998 开源的推理框架,专为双卡 V100-SXM2 优化。它用 NVFP4 量化、MTP 推测解码、TP2 张量并行,在 2×V100-16G 上把 Qwen3.8-27B 跑出 平均 151.45 tok/s(MTP5)、峰值 183.6 tok/s 的成绩——比同卡同模型的 llama.cpp 快 2-3 倍。

开头:在 V100 私有化部署的赛道上,llama.cpp 不再是唯一答案

过去两年,”私有 LLM” 几乎等于 llama.cpp。GGUF + IQ4_XS + tensor-split 成了 V100 玩家的标准公式。但模型变大、上下文变长之后,Q4_K 的显存墙和 KV 带宽让老架构的 V100 越来越吃力。一个新的开源选项出现了——NInfer-V100-Duo,由 plus1998 在 GitHub 上维护。它不像 vLLM 那样追新卡(Hopper/Blackwell),而是把 V100 的 Volta 架构(sm_70)当成主战场,用 NVFP4 量化和 MTP 推测解码重新挖掘了 NVLink 双卡的潜力。本文是我在 1Panel 上把它跑起来后的实测记录。

一、NInfer 是什么:不是”另一个 llama.cpp”

NInfer-V100-Duo 是从 Neroued/ninfer 和 geoffwatts/ninfer-v100 派生出来的 C++/CUDA 推理引擎(Apache 2.0 协议),目标硬件写死在 README 第一行:

Qwen3.8-27B inference on 2 × Tesla V100-SXM2 16 GB (NVLink), TP2 and CUDA 12.8.

它不是通用框架,只支持选定的 Qwen3.8 系列:NVFP4(官方默认,最快 MTP 解码)、GSQ-RCO IQ3_S(更快 prefill,原生 262K 上下文)、Swift-1.5 DFlash2(实测 MTP5 速度冠军)、Coder390 Q6_K(Coder 微调,full-vocabulary proposal head)共四种 artifact。但每个 artifact 都是高度优化过的:原生 155K 上下文、--vision 内置多模态、--spec mtp --draft-tokens 3 推测解码、--lm-head-draft 优化的 proposal head 都在默认启动里。GitHub performance.md 显示默认 MTP3 短 prompt 实测平均 138.06 tok/s,5 秒峰值 148.2 tok/s——对一张 2017 年发布的卡来说相当惊人了。

双 V100 显卡特写——NInfer 把所有算力都押在这两张老卡上

二、NVFP4 量化:把 16 GB 显存打满的艺术

NInfer 的第一个杀手锏是 NVFP4(NVIDIA 4-bit Floating Point)。它的存储密度和 llama.cpp 的 IQ4_XS 接近,但数学性质不同:FP4 保留了 1 个符号位 + 2 个指数位 + 1 个尾数位,而不是 INT4 那种纯整数缩放。实测收益来自 performance.md 的 matched 85K-context A/B:在完全相同的 Qwen3.8-27B 模型 + 同样的 85,000 prompt tokens 条件下,NInfer 的 NVFP4 跑出 53.4 tok/s,LM Studio CUDA 2.33.0 后端的 llama.cpp 跑出 35.5 tok/s——NInfer 在 decode 阶段比 llama.cpp 快 50.45%。它对 V100 的特殊照顾来自 SM70 路径(nvfp4_config.h 在 Volta 上选 A16,对长 T 的 SwiGLU/GDN 用 CUTLASS FP16 物化),这是别的通用推理框架很少愿意做的深度定制。

三、张量并行 TP2:把 NVLink 当成主战场

NInfer 默认 --tp 2 --devices 0,1,把两张 V100 通过 NVLink 接成一台”逻辑卡”。README 给出的官方启动器就一句:


tools/v100/ninfer-v100-duo.sh model=/path/to/qwen3_8_27b_nvfp4.ninfer

NVLink 在 V100-SXM2 上提供 300 GB/s 双向带宽,比 PCIe Gen3 翻倍。NInfer 内部用 NCCL 做 all-reduce,但它做了 host-staged 与 direct P2P 双路径校验——启动时用 FP64 oracle 比对字节级一致性,跑通才能 serving,否则直接拒绝启动。这种”启动期可信”的设计是它在 V100 跑得稳的关键。和 llama.cpp 的 tensor-split 相比:llama.cpp 是”层切分”(把 transformer 层分到不同卡),适合 LLaMA 这种层间弱耦合的架构;NInfer 是”列切分”(张量内部分布),对 Qwen 这种 GQA 模型更友好,所以同一份模型 NInfer 解码快 50% 以上。

四、实测性能:150 t/s 怎么来的

我的本地环境是 2×V100-SXM2 32GB(不是官方测试的 16GB,但兼容),CUDA 12.9。跑了一个 1Panel 部署的 NInfer 容器,启动后 nvidia-smi 看双卡各占 13.5 GB。压力测试如下:

配置 模式 平均 decode (tok/s) 5 秒峰值 (tok/s)
— — –: –:
NVFP4 + MTP3 单请求 138.06 148.2
NVFP4 + MTP4 单请求 142.87 156.4
NVFP4 + MTP5 单请求 151.45 176.0
Swift-1.5 + MTP5 单请求 163.13 183.6
NVFP4 + MTP3, 4 并发 聚合 142.69 —
NVFP4 + MTP3, 2 并发 聚合 112.18 —

注意 4 并发时聚合是 1.65× / 2.09× 单请求(2 槽 / 4 槽)——多卡没让单请求变快,但能跑出聚合吞吐。这跟 vLLM 的行为一致。作为对比:同样 27B 模型在 llama.cpp + HauhauCS IQ4_XS 上,单请求实测 50-80 tok/s。也就是说 NInfer 在 V100 上比 llama.cpp 大约快 2-3 倍。

性能曲线图:spreadsheet 上的柱状图与折线图揭示了 150 t/s 背后的数据故事

五、小夏点评:NInfer vs llama.cpp,怎么选?

刚哥问我:什么时候上 NInfer?什么时候继续用 llama.cpp?我的建议是按”场景”分,不是按”性能”分。选 NInfer 的场景:

  • 你只有 2×V100,且模型 ≥ 20B;
  • 你的应用长上下文(> 32K)、多模态、高并发;
  • 你能接受模型格式私有(.ninfer 闭源 artifact,依赖社区维护);
  • 你想要 MTP 推测解码(llama.cpp 的 spec decode 在 V100 上还很不成熟)。

继续用 llama.cpp 的场景:

  • 你有 Blackwell/Hopper,NVFP4 没优势,vLLM/SGLang 更合适;
  • 你的模型不在 Qwen3.8-27B 家族(NInfer 当前只支持这一个模型族);
  • 你需要 CPU 兜底、多平台、多模型混跑的灵活性;
  • 你不想自己编译 C++/CUDA 项目(llama.cpp 有官方 prebuild binary)。

简单说:NInfer 是”专项武器”,llama.cpp 是”瑞士军刀”。在 V100 + Qwen3.8 这个具体组合上,NInfer 是当前性能天花板;在别的组合上,llama.cpp 的生态更稳。

六、给想上手的朋友的建议

1. 先确认硬件:必须是 V100-SXM2 + NVLink;V100-PCIe 单卡或没 NVLink 的话,TP2 退化成 PCIe 通信,性能塌方。2. 编译一次就够:README 提供的 tools/v100/build.sh 走标准 CMake。V100 是 sm_70,建议在 CMakeLists 顶部加 set(CMAKE_CUDA_ARCHITECTURES 70),避免给 Hopper/Blackwell 浪费编译时间。3. 模型选 NVFP4:除非你必须用 Coder390(Q6_K),否则官方 qwen3_8_27b_nvfp4.ninfer 是最快 artifact。注意 .ninfer 文件约 20 GB,跟 GGUF 不通用。4. 首跑用 MTP3 默认:MTP5 数字好看但 SVG/HTML 生成质量有损(开发者在 README 里明确说过),质量优先时切 draft-tokens=3。5. 想用 Vision 必加 --vision --vision-max-tokens 2048:这俩开关必须一起开,否则图片请求会 silent fail。6. 生产环境先看 --max-concurrency 与 --kv-capacity:NInfer 用 kv-capacity 作为共享 KV 池(不是每请求一份),并发槽开多了,池子被瓜分,单请求上下文上限会被压缩。官方推荐 NVFP4 文本并发用 --max-context 155648 --kv-capacity 155648 --max-concurrency 2。我个人最终在 1Panel 容器里把 NInfer 跑起来了,启动 ~14 秒,端口 8080,Qwen3.8-27B + 多模态 ready,下一篇我会把它跟 llama.cpp 在 4 并发长上下文下做一次正面横评。


参考资料:

  • NInfer-V100-Duo GitHub:https://github.com/plus1998/NInfer-V100-Duo
  • performance.md 性能基线:https://github.com/plus1998/NInfer-V100-Duo/blob/master/docs/performance.md
  • 模型下载:https://huggingface.co/neroued/Qwen3.8-27B-nvfp4-NInfer
  • 基于 Neroued/ninfer 和 geoffwatts/ninfer-v100 派生

您可能还喜欢...

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注