双 V100 + 1Panel 实战:把 27B 大模型塞进老卡,两条路都帮你趟过坑了
2026 年还在用 Tesla V100 跑大模型,听起来像考古,但对很多中小团队来说,这是把”本地私有 LLM”这件事跑通的现实选择——单张 V100 32GB 二手只要几千块,NVLink 互联后双卡 64GB 显存能塞下 27B 量化版,关键是不依赖任何云服务,数据完全在自己机柜里。
我们手上这套双 V100-SXM2-16GB(NVLink NV6)折腾了整整一周,从 llama.cpp 到 NInfer-V100-Duo,两条路都走通了。这篇文章把最有价值的部分提炼出来:两条路的取舍、11 个坑里最致命的几个、以及最终稳定的性能数字。
一、为什么是双 V100
V100 是 NVIDIA 第一代支持 NVLink 的数据中心卡(sm_70 架构,2017 年发布),二手市场存量极大。两张 16GB 版通过 NVLink 互联后,tensor parallel 可以做层内切分,单卡装不下的 27B 模型(IQ4_XS 量化约 15GB)就能跑起来了。如果是 32GB 版,64GB 联合显存甚至能装下未量化的 13B 全精度。
二、两条路径对比
我们同时测了 llama.cpp b11365(通用推理引擎)和 NInfer-V100-Duo(专为双 V100 优化的私有框架),跑的是同一个 27B 模型(Swift-1.5-Qwen3.8-27B):
| 维度 | llama.cpp + MTP | NInfer-V100-Duo |
|---|---|---|
| 模型格式 | GGUF IQ4_XS | NVFP4(私有) |
| Decode 速度 | ~65 t/s | 120-150 t/s |
| 上下文 | 16K | 155K |
| Vision | 需 mmproj | 内置 |
| 部署难度 | 中(通用生态) | 高(私有框架) |
简单说:想要稳、想要生态、想要跟社区走 → llama.cpp;追求极致速度、且能接受私有格式 → NInfer。我们最终两条都留了,NInfer 做主力推理(速度快),llama.cpp 做兼容兜底(任何 GGUF 模型都能直接换)。
三、最值得说的 5 个坑
完整 11 个坑都在我们内部 wiki 里,这里只挑最致命的:
坑 1:NCCL 版本不匹配(最难发现的根因)——builder 镜像和 runtime 镜像预装的 NCCL 版本不一致时(NCCL 2.27 vs 2.32),NCCL 初始化会静默 fallback 到内部 AllReduce,性能直接掉 20%。表现是”能跑但慢”,日志里没有 error,只有 warn。我们 debug 了整整 2 小时才发现。解决:在 builder 阶段 apt-get install libnccl2=2.27.3-1+cuda12.9 libnccl-dev=2.27.3-1+cuda12.9 固定版本。
坑 2:编译时 OOM——llama.cpp 默认 -j$(nproc),32 核 × 每个编译进程 4GB = 128GB,直接把 32GB 物理内存打爆。解法是 MAKEFLAGS="-j2" + LLAMA_BUILD_UI=OFF(省 8GB+)+ 不开 GGML_CUDA_FA_ALL_QUANTS=ON。
坑 3:只编 sm_70——NVCC 默认会编所有架构(21 个),既慢又爆内存。在 cmake -B build 时加 -DCMAKE_CUDA_ARCHITECTURES=70,只针对 V100 优化,编译时间从 60 分钟降到 25 分钟。
坑 4:nvidia base image 的 ENTRYPOINT 陷阱——nvidia/cuda:* 镜像自带 ENTRYPOINT=/opt/nvidia/nvidia_entrypoint.sh,如果你的 command: 第一行是参数(不是二进制名),entrypoint 脚本的 exec "$@" 会把你的参数当 entrypoint 自己的参数,疯狂报 invalid option。解法:compose 里显式覆盖 entrypoint: ["llama-server"],或 command: 第一行必须是二进制名。
坑 5:MTP draft 数不是越大越好——投机解码(MTP)的 draft token 数从 3 试到 5,draft=3 接受率 47%,draft=4 接受率暴跌到 30%,速度反而从 64 t/s 掉到 56 t/s。结论:draft=3 是甜点。
四、稳定性能(实测)
| 场景 | llama.cpp | NInfer |
|---|---|---|
| 短回复 (<100 token) | 74 t/s | ~150 t/s |
| 中回复 (100-300) | 64-67 t/s | 120-140 t/s |
| 长回复 (>500) | 56-62 t/s | 100-120 t/s |
| 4 并发满载 | 248-264 t/s 总吞吐 | ~480 t/s 总吞吐 |
这个速度对单机私有 LLM 已经够用——日常对话、代码补全、长文档摘要,体感都顺。
五、小夏点评
我跟着刚哥从头到尾把这两条路都跑了一遍,最深的感受是:老硬件最大的敌人不是性能,是”看起来能跑但实际跑偏”。NCCL 那个坑尤其阴险——它不报错,只是静默 fallback,让你在错误的性能基线上调一整天参数,越调越困惑。debug 的时候我们几乎要怀疑 NVLink 没接好,最后用 env | grep NCCL 看 builder 和 runtime 的环境变量对比才破案。
另外想说,1Panel 在这里的体验其实是加分项——它的”应用商店”模式让 Docker 部署有了 UI,但对深度定制的场景(比如这次我们需要打自定义 NCCL 版本),命令行 docker build -t xxx . 反而更直接。特别是 1Panel 默认开启的”构建后推送 Docker Hub”在我们这里因为没配 Hub 账号一直失败,但这个失败完全不影响本地运行,日志看着吓人而已。
如果你也在用老卡跑 LLM,建议:先花半小时把 NCCL 版本对齐,再谈性能调优。这一个点能省你 2 小时的 debug 时间。
六、给同样在折腾老卡的朋友的几条建议
- 必看 NCCL 版本对齐——builder 和 runtime 必须一字不差,否则 20% 性能白丢
- 编译只编目标架构(V100 是 sm_70),省时省内存
- 限制编译并发(
-j2或-j4),别用-j$(nproc)爆内存 - 用 nvidia base image 时覆盖 ENTRYPOINT,否则你的
command会被 entrypoint 脚本吃掉 - 投机解码先试 draft=3,别默认 5——接受率掉了速度反而慢
- 1Panel 推送失败别慌,本地镜像 build 成功就够了
老卡有老卡的好——便宜、安静、够用。只要踩坑踩得明白,V100 在 2026 年依然是跑本地 LLM 的甜品级选择。
