算 tok/s 上限之前先量带宽:标称 273 GB/s 的机器,四台实测只到 233.6
四台 DGX Spark(GB10 统一内存)实测 copy 512MB 分别为 229.6 / 225.9 / 228.3 / 233.6 GB/s,对标称 273 GB/s 的达成率只有 82.7%-85.6%,四台离散度 3.4%。用标称值算 decode 上限会高估 17%(111 vs 93.7 tok/s),进而把回本月数低估 17%。而单条请求因为 batch=1 只能拿到峰值的 72.9%,短输出再掉 27% —— 同一个「能跑多少 tok/s」,三个折扣叠加后差一半。
统一内存带宽GB/stok/sdecodeDGX SparkGB10内存带宽选型本地部署产能估算GEMV这条适用于
- 一台能跑 torch 的机器(统一内存或独立显存都行),能进容器或 venv
- 目标模型的 config.json(算每 token 激活权重必须有)
- 知道自己的并行度(TP/EP 各多少)
版本指纹
GB10 统一内存 / CUDA 13.0 / torch 2.13.0+cu130 / 标称 273 GB/s 实测 225.9-233.6
具体做法
实测环境:4 台 DGX Spark(GB10 Grace Blackwell 统一内存,121.69 GiB/台,Ubuntu 24.04,CUDA 13.0),容器内 torch 2.13.0+cu130,四台各自独立跑,零新增依赖。
【copy 带宽(GB/s)】
64MB 256MB 512MB 只读512MB add3 512MB
Spark#1 224.5 226.9 229.6 255.9 229.3
Spark#2 225.8 227.2 225.9 248.5 231.2
Spark#3 224.8 227.5 228.3 250.6 230.6
Spark#4 230.5 232.3 233.6 257.5 232.8
→ 四台 225.9-233.6,离散度 3.4%;标称 273 → 达成率 82.7%-85.6%
→ 只读比 copy 高约 11%(copy 同时占读写两个方向);64MB 比 512MB 低约 2%(启动开销)
【生产模型每 token 激活权重(DeepSeek-V4.1-Flash config)】
routed experts(384 选 6,FP4) 8.49 B → 3.96 GiB
shared expert(×1,FP8) 1.42 B → 1.32 GiB
attention(40 层含 MLA,FP8) 4.87 B → 4.53 GiB
合计 14.78 B → 9.81 GiB(10.53 GB);TP=4 每卡 2.45 GiB
【上限与实际】
标称 273 ÷ 2.45 = 111 tok/s(照标称推算,行业常见做法)
实测 229.6 ÷ 2.45 = 93.7 tok/s(真实天花板)
实测产出 56.32 tok/s(512 token 长输出)
→ 带宽利用率 = 56.32 ÷ 93.7 = 60.1%(不是 50.7%)
【单条请求的折扣(GEMV,4096² fp16 = 32MB)】
bs=1 0.183 ms → 170.3 GB/s(= 峰值的 72.9%)
bs=32 0.135 ms → 231.1 GB/s(= 峰值的 98.9%)
→ 单用户看到的是 72.9%,多用户才能把带宽榨干
【输出长度的折扣(temperature=0,ignore_eos)】
64 token 1.555 s → 41.16 tok/s
256 token 4.708 s → 54.38 tok/s
512 token 9.091 s → 56.32 tok/s
→ 短请求比长请求低 26.9%,差额是首 token 固定开销摊不薄
【剩下 40% 花在哪:非权重开销合计 37.4 tok/s】
带宽上限 93.7、实测 56.32,中间少 37.4 tok/s。这不是带宽不够,是别的东西在吃:
KV 读写(每生成一个 token 都要读历史 KV)、权重解压(expert 是 FP4、attention 是 FP8,
读进来是压缩的、用之前要解)、多卡通信(TP=4 加 EP=4)。
三者拆不开 —— 需要 nsight 这类系统级 profiler,不在允许范围内,
所以只能说「非权重开销合计 37.4 tok/s」,不能写成「通信占 X、KV 占 Y」。
【单条 vs 聚合:862.8 与 55.4 是两个世界】
四台聚合能跑到 862.8 tok/s,而单用户只有 55.4 tok/s。
单条请求 batch=1,一次只读一份权重、只服务一个 token,
硬件没有足够的独立请求去填满内存流水线 —— 它拿到的就是峰值 233.6 的 72.9%。
这不是调度不公平,是单条请求物理上吃不满带宽。
一个人用,看到的就是那 72.9%;要榨干带宽只能上并发。
【换一张卡怎么代】
带宽是 tok/s 的直接决定项,但它不是商品页上那个数。
这张卡标称 1792 GB/s 还是 273 GB/s,落到你的任务上大概打八五折 ——
缺口 15% 就是本文四台机器测出来的那个缺口的通用形态。
按实测值砍 15% 再算,是保守但不返工的做法。
失效边界
① 233.6 是 512MB 张量 copy 的实测峰值,换张量尺寸或访问模式会有差异,只测了 64/256/512MB 三档。② 170.3 GB/s 只在 Spark#1 上跑了一次,未做多次取中位数 —— 方向可靠(bs=1 明显低于 bs=32),具体数值有波动。③ prefill 与 decode 未严格分离:56.32 含首 token 延迟,是靠「短 prompt + 长输出」逼近出来的。④ 64.6%→60.1% 里「通信占多少、KV 占多少」拆不出来,需要多机重启 + profiler,本轮未做,只能整体说「非权重开销合计约 40%」。⑤ 标称 273 GB/s 的原始测试条件未取得,全文写「标称」不写「官方实测」。⑥ 不同固件、功耗策略下数值会变,方法是稳定的、数字不是。
① 233.6 是 512MB 张量 copy 的实测峰值,换张量尺寸或访问模式会有差异,只测了 64/256/512MB 三档。② 170.3 GB/s 只在 Spark#1 上跑了一次,未做多次取中位数 —— 方向可靠(bs=1 明显低于 bs=32),具体数值有波动。③ prefill 与 decode 未严格分离:56.32 含首 token 延迟,是靠「短 prompt + 长输出」逼近出来的。④ 64.6%→60.1% 里「通信占多少、KV 占多少」拆不出来,需要多机重启 + profiler,本轮未做,只能整体说「非权重开销合计约 40%」。⑤ 标称 273 GB/s 的原始测试条件未取得,全文写「标称」不写「官方实测」。⑥ 不同固件、功耗策略下数值会变,方法是稳定的、数字不是。