惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hackread – Cybersecurity News, Data Breaches, AI and More
腾讯CDC
F
Fortinet All Blogs
I
InfoQ
Jina AI
Jina AI
有赞技术团队
有赞技术团队
A
About on SuperTechFans
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
Recent Announcements
Recent Announcements
aimingoo的专栏
aimingoo的专栏
雷峰网
雷峰网
B
Blog RSS Feed
C
Check Point Blog
Y
Y Combinator Blog
博客园 - 聂微东
云风的 BLOG
云风的 BLOG
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
Microsoft Security Blog
Microsoft Security Blog
Engineering at Meta
Engineering at Meta
G
Google Developers Blog

博客园 - 张善友

.NET 11 性能全解读:从 JIT 到基础库,这一版到底快了多少 .NET 11 性能深度解读:这一次,真的「到 11」了 把 LLM 密钥从环境变量里解放出来:OpenClaw.NET 迎来 Vault/OpenBao 密钥后端 RedNb.Nacos 2.0.0 正式发布:.NET 接入 Nacos 3.2.4,AI Registry 全能力落地 Rust 成为微软一线语言之后:谈谈 C# 与 Rust 的互补性 .NET 异常处理的"暗门":代码里写满 catch,你依然能抓住它——从一个 AI Agent 运行时的源码说起 写给 C++ 工程师的 OpenClaw.NET 上手指南:用你熟悉的 C++ 思维,跑起一个生产级 AI Agent .NET 11 RC1 发布:拿到"准生证",生产环境可以上了! 写给 PHP 工程师的 OpenClaw.NET 上手指南:用你熟悉的 PHP 思维,跑起一个生产级 AI Agent 写给 Rust 工程师的 OpenClaw.NET 上手指南:用你熟悉的 Rust 思维,跑起一个生产级 AI Agent 从对标 Java 到对标 Go:Native AOT 的"无痛化"之路,走到哪一站了? NuGet 半年度总结:周下载量从 54 亿到 67 亿,.NET 生态的"新一轮增长期"实锤了 写给 Java 工程师的 OpenClaw.NET 上手指南:用你熟悉的 Spring 思维,跑起一个生产级 AI Agent 写给 TypeScript 工程师的 OpenClaw.NET 上手指南:用你熟悉的 TS 思维,跑起一个生产级 AI Agent 写给 Python 工程师的 OpenClaw.NET 上手指南:用你熟悉的 Python 思维,跑起一个生产级 AI Agent 写给 Golang 工程师的 OpenClaw.NET 上手指南:用你熟悉的 Go 思维,跑起一个生产级 AI Agent MetaSkill 落地 .NET:当 Agent 从「调用工具」进化到「组织工具」 都是 AI 写代码,为什么 C# 比 Java 快半拍 MHS 三部曲(下):谁允许 AI 行动?——权力、合规与中国厂商的答卷 弱模型不能裸奔:Agent Harness 凭什么真实有效 MHS 三部曲(中):8 小时集成、六种被拦截的故障,和一次教科书级的翻车 TensorSharp 3.3.0.0 发布,视频生成、DFlash2 投机解码、安全加固一起来了 MHS 三部曲(上):别急着叫它「物理 MCP」——Anthropic 到底发布了什么 编程语言的「第三条道路」上,走得最远的其实是 C# 纯 .NET 手写 CUDA kernel,GLM-5.3-Flash decode 跑出 llama.cpp 的 2 倍 AI 编程时代,.NET 的机会在哪里? Vibe Coding 月提交量 29 亿次之后:GitHub 的危机、Azure 迁移,以及 .NET 的机会 从 PostgreSQL 到 Kubernetes:开源的护城河,从来不写在代码里 人工智能最先替代的,是人工智能学院自己 企业架构的六种场景:从"四大流派"到数字原生与 AI 原生
3 张卡到底能不能跑大模型推理?从 vLLM、llama.cpp 到 Tenso...
张善友 · 2026-08-28 · via 博客园 - 张善友

1

一个常见说法:3 卡跑不了 vLLM,只能跑 llama.cpp;3 卡通信损失可接受,4 卡就不行了,除非有高速互联。这话大方向没错,但魔鬼都在细节里。今天把这件事彻底讲清楚,最后再看一个把两种并行路线同时实现的实战案例——纯 .NET 推理引擎 TensorSharp。


一、vLLM 为什么"歧视"3 卡?

很多人觉得 vLLM 硬性规定张量并行(Tensor Parallelism)只能是 1、2、4、8 卡——这个理解其实不准确

vLLM 的真实约束只有一条:

Attention Head 数量(以及 KV Head 数量)必须能被 TP size 整除。

那为什么实践中就变成了"只能 1/2/4/8"?因为主流模型的头数几乎都是 2 的幂:

模型 Attention Heads KV Heads TP=3 可行?
Llama-3-70B 64 8 ❌ 直接报错
Qwen2.5-72B 64 8 ❌ 直接报错
Mistral-7B 32 8 ❌ 直接报错

64、32 这些数字除以 3 除不尽,--tensor-parallel-size 3 会直接抛 ValueError,于是 6 卡也不行,实际效果就退化成了"只能 1/2/4/8"。

结论:这是整除约束,不是框架写死的限制。 如果哪天遇到头数能被 3 整除的模型,vLLM 跑 3 卡完全没问题。


二、llama.cpp 为什么对卡数无所谓?

关键在于切分方式完全不同

llama.cpp 默认采用 Layer Split(按层切分)

  • 每张卡拿连续的若干层;
  • 层与层之间只传一次隐状态激活值,量级只有几百 KB 到几 MB;
  • 对互联带宽几乎没要求,普通 PCIe 绰绰有余。

这才是"3 卡能跑 llama.cpp"的真正原因——不是"3 卡通信损失可接受",而是 layer split 模式下通信量本来就小到可以忽略


三、"3 卡行、4 卡不行"?这个阈值其实不成立

这是流传最广、也最容易误导人的一个说法。拆开看:

对 llama.cpp(layer split)

4 卡和 3 卡的通信量几乎一样低——仍然只在层边界传激活值。4 卡没问题,6 卡、8 卡也一样没问题。唯一的瓶颈是显存够不够分,而不是通信。

对 vLLM(tensor parallel)

真正的悬崖不在 3→4,而在互联类型

  • TP 模式每一层都要做 all-reduce,通信频繁且量大;
  • 在 PCIe 下,2 卡就开始明显掉速
  • 4 卡以上基本必须 NVLink / NVSwitch 才有意义。

所以"除非高速互联"这个判断是对的,只是门槛比想象中来得更早——不是 4 卡才需要,而是 2 卡以上就明显受益。


四、一张图总结

卡数本身不是关键变量

  Layer Split(llama.cpp)
    └─ 对卡数免疫:3/4/6/8 卡都行,瓶颈在显存

  Tensor Parallel(vLLM)
    ├─ 对整除性敏感:头数必须能被 TP size 整除
    └─ 对互联敏感:PCIe 下 ≥2 卡掉速,4+ 卡需要 NVLink

五、实战案例:TensorSharp——同一个引擎里的两种切分

前面讲的还是"两个引擎两种路线",有没有一个引擎把两条路都实现了,可以直接对比?有——TensorSharp,一个纯 .NET 实现的 GGUF 推理引擎,性能上和 C++ 手写优化的 llama.cpp 互有胜负(CUDA prefill 最高快 1.28×,Vulkan decode 最高快 1.21×)[1]

它对多卡的处理方式,简直就是本文论点的活体演示:

默认:Layer Split,卡数随意

权重默认按层自动切分到所有可见 GPU——3 卡、5 卡、7 卡都行,没有任何整除要求。官方的一个标志性测试就是在 3 张 RTX PRO 6000 上跑 744B 参数的 GLM-5.2 MoE:layer split + CPU MoE offload(把 92% 的专家权重放内存),prefill 2048 tokens 跑出 918.9 tok/s,反超 llama.cpp 的 763.1 tok/s[1:1]

3 卡、PCIe 时代的常识告诉我们这"不该"跑得动——但 layer split 下卡数本来就不是变量,这就是最直接的证据。

可选:--tp N,但要面对真实代价

TensorSharp 也提供 Megatron 风格的张量并行(列/行并行 + 分层 AllReduce),支持单机多卡和跨机 TCP 集群[1:2]。但它的官方基准数据恰恰暴露了 TP 的软肋:

场景 TP=2 相对单卡加速
Gemma 4 E4B decode 1.39×
Muse-Glimmer 30B decode 1.57×
Muse-Glimmer 30B prefill 1.34×

理想情况下 2 卡应该是 2×,实际只有 1.4× 左右——消失的那 0.6× 就是 all-reduce 通信和同步开销。这正是"TP 对互联敏感"的量化体现。

更有意思的是它的跨机方案:多节点 TP 走普通 TCP 网络,在没有 CUDA P2P 时还会自动回退到主机内存中转[1:3]。工程上能跑,但性能显然要靠真正的硬件互联(NVLink 级别)来救——互联质量决定 TP 上限,这和前面 vLLM 一节的结论完全一致。


六、实操建议

  1. 卡数是 3 的倍数或奇数卡 → 优先 layer split 路线的引擎(llama.cpp,或 .NET 技术栈下的 TensorSharp),别跟 vLLM 的整除约束较劲;
  2. 卡数是 2/4/8 且模型头数匹配 → vLLM / --tp N 可以上,但注意互联:PCIe 环境控制卡数,有 NVLink 再放开;
  3. layer split 多卡部署时,重点调的是显存分布和 prompt processing 阶段瓶颈(TensorSharp 这类引擎还可以叠加 CPU MoE offload 进一步省显存),而不是纠结 3 卡还是 4 卡。

一句话总结:layer split 对卡数免疫,tensor parallel 对互联敏感——决定你能不能跑、跑得快的,从来不是"3 还是 4"这个数字本身。


  1. zhongkaifu/TensorSharp — A native .NET LLM inference engine for GGUF models ↩︎ ↩︎ ↩︎ ↩︎