导语
大模型推理的“性能”从来不是单一数字。离线压测能跑出漂亮的吞吐曲线,但线上真实流量的输入长度分布、输出长度分布、缓存命中率和并发模式,往往和压测环境完全不同——同一个模型、同一套硬件,两个口径下的吞吐数据可能相差数倍。
为了回答“B300 到底能把 GLM-5.2 和 Kimi-K3 跑到什么水平”这个问题,我们在 UCloud 优刻得 16×B300 SXM6 GPU 环境中,分别完成了离线压测和线上对照验证,并沉淀了两套可直接复用的高吞吐部署方案。本文将完整呈现测试数据、部署架构和关键配置,供有相同需求的技术团队参考。
测试环境
| 项目 | 配置 |
|---|---|
| GPU | 16 × B300 SXM6 |
| 机内互联 | NVLink / NVSwitch |
| 推理框架 | SGLang(GLM-5.2 用 v0.5.17,Kimi-K3 用 v0.5.18) |
| 量化 | GLM-5.2:NVFP4(modelopt_fp4);Kimi-K3:MXFP4 |
| KV Cache | FP8(fp8_e4m3) |
两台 B300 机器各 8 卡,机内通过 NVLink/NVSwitch 互联。两个模型采用了完全不同的部署思路:GLM-5.2 走 PD 分离 + Mooncake RDMA 跨机 KV 传输,Kimi-K3 则是单机单实例 + Router 分发,不依赖跨机 RDMA。这一差异本身就值得展开。
GLM-5.2-NVFP4:PD 分离架构下的双机高吞吐
压测与线上数据对照
| 指标 | 离线压测 | 线上 |
|---|---|---|
| 流量 profile | 64K→1K · 9 RPS · C64 · 500 请求 | 输入:几万;输出:多数 <1K |
| 缓存命中 | ~77% | ~77% |
| 输出吞吐 | 500 请求窗口平均:4,740.90 tok/s | P95:1,571 tok/s |
| 日收入(按列表价计算) | ¥34,068 / 日 | ~¥35,000 / 日 |
两点说明:收入的预估及测试均按工作日验证,周末流量会有所下降;真实收入也取决于客户端流量模型,上述数据仅供参考。
离线压测的吞吐高于线上 P95,原因很直观:压测流量的输入输出长度分布更规整,调度器可以维持更高的 batch 利用率;线上输入长度波动到“几万”级别,长尾请求会拉低瞬时吞吐。但缓存命中率在两个口径下高度一致(~77%),说明分层缓存策略对真实流量是有效的。
部署架构:双机 2P2D
GLM-5.2-NVFP4 采用 SGLang v0.5.17 + NVFP4 + 双机 2P2D 架构:2 个 Prefill 实例 + 2 个 Decode 实例,跨机通过 Mooncake RDMA 传输 KV。
Prefill 侧(B300 A 上分别启动 P0、P1):
# Prefill:B300 A 上分别启动 P0、P1
NCCL_NVLS_ENABLE=0 \
CUDA_VISIBLE_DEVICES=<P0: 0,1,2,3 | P1: 4,5,6,7> \
sglang serve \
--model-path <model-root>/GLM-5.2-NVFP4 \
--served-model-name GLM-5.2-NVFP4 \
--host 0.0.0.0 \
--port <P0: 30001 | P1: 30002> \
--context-length 262144 \
--tp 4 \
--dp 1 \
--ep-size 4 \
--moe-a2a-backend none \
--attn-cp-size 4 \
--enable-prefill-cp \
--cp-strategy interleave \
--nccl-port <P0: 31701 | P1: 31702> \
--disaggregation-mode prefill \
--disaggregation-transfer-backend mooncake \
--disaggregation-ib-device <rdma-device-list> \
--disaggregation-bootstrap-port <P0: 8998 | P1: 8999> \
--dsa-paged-mqa-logits-backend auto \
--quantization modelopt_fp4 \
--kv-cache-dtype fp8_e4m3 \
--max-running-requests 128 \
--chunked-prefill-size 16384 \
--max-prefill-tokens 16384 \
--prefill-max-requests 1 \
--mem-fraction-static 0.87 \
--reasoning-parser glm45 \
--tool-call-parser glm47 \
--speculative-algorithm EAGLE \
--speculative-num-steps 1 \
--speculative-eagle-topk 1 \
--speculative-num-draft-tokens 2 \
--disable-flashinfer-autotune \
--enable-hierarchical-cache \
--hicache-ratio 2 \
--hicache-size 0 \
--hicache-write-policy write_through \
--enable-metrics \
--enable-cache-report
Decode 侧(B300 B 上分别启动 D0、D1):
# Decode:B300 B 上分别启动 D0、D1
CUDA_VISIBLE_DEVICES=<D0: 0,1,2,3 | D1: 4,5,6,7> \
sglang serve \
--model-path <model-root>/GLM-5.2-NVFP4 \
--served-model-name GLM-5.2-NVFP4 \
--host 0.0.0.0 \
--port <D0: 33002 | D1: 33003> \
--context-length 262144 \
--tp 4 \
--dp 1 \
--ep-size 4 \
--moe-a2a-backend none \
--dcp-size 1 \
--dcp-comm-backend ag_rs \
--nccl-port <D0: 34702 | D1: 34703> \
--disaggregation-mode decode \
--disaggregation-transfer-backend mooncake \
--disaggregation-ib-device <rdma-device-list> \
--dsa-paged-mqa-logits-backend auto \
--quantization modelopt_fp4 \
--kv-cache-dtype fp8_e4m3 \
--max-running-requests 256 \
--mem-fraction-static 0.90 \
--reasoning-parser glm45 \
--tool-call-parser glm47 \
--speculative-algorithm EAGLE \
--speculative-num-steps 5 \
--speculative-eagle-topk 1 \
--speculative-num-draft-tokens 6 \
--enable-metrics \
--enable-cache-report
Router(Prefill/Decode 均用 Round Robin):
python -m sglang_router.launch_router \
--pd-disaggregation \
--prefill http://<prefill-host>:30001 8998 \
--prefill http://<prefill-host>:30002 8999 \
--decode http://<decode-host>:33002 \
--decode http://<decode-host>:33003 \
--prefill-policy round_robin \
--decode-policy round_robin \
--model-path <model-root>/GLM-5.2-NVFP4 \
--tokenizer-path <model-root>/GLM-5.2-NVFP4 \
--reasoning-parser glm45 \
--tool-call-parser glm47_moe \
--host 0.0.0.0 \
--port 30000 \
--health-check-interval-secs 30 \
--disable-retries
几个关键配置点:
- Prefill 侧开启
--enable-prefill-cp+--cp-strategy interleave的 context parallel,配合--chunked-prefill-size 16384,把长输入切块处理,降低单个长请求对 batch 的冲击; - 投机采样在两侧不对称配置:Prefill 侧
--speculative-num-steps 1/--speculative-num-draft-tokens 2,Decode 侧--speculative-num-steps 5/--speculative-num-draft-tokens 6,Decode 阶段吃更多投机收益; - Prefill 侧开启分层缓存(
--enable-hierarchical-cache,write_through 策略),这是 77% 缓存命中率的重要来源; --mem-fraction-static两侧分别设为 0.87 和 0.90,给 Decode 侧留出更多 KV 空间。
Kimi-K3:单机实例 + Router,实测不依赖跨机 RDMA
压测与线上数据对照
| 指标 | 离线压测 | 线上 |
|---|---|---|
| 流量 profile | 128K→1K · 9 RPS · C80 · 500 请求 | 输入:几万–几十万;输出:多数 <1K |
| 缓存命中 | 81.98% | ~82% |
| 输出吞吐 | 500 请求窗口平均:1,210.81 tok/s | P95:21,500 tok/s |
| 日收入(按列表价计算) | ¥26,934 / 日 | ~¥28,000 / 日 |
同样说明:收入的预估及测试均按工作日验证,周末流量会有所下降;真实收入也取决于客户端流量模型,数据仅供参考。
Kimi-K3 的离线和线上数据差异非常大,必须解释清楚口径:
- 离线压测用的是 128K 超长输入,且 1,210.81 tok/s 是 500 请求窗口的平均值,长 prompt 的重计算压力集中在 Prefill 阶段,拉低了平均吞吐;
- 线上 P95 21,500 tok/s 是瞬时聚合吞吐,线上流量输入虽同样达到“几万–几十万”,但 82% 的缓存命中率意味着大量前缀可以复用,Prefill 压力被缓存大幅摊薄,Decode 阶段可以维持很高的并发聚合吞吐。
这组数据最重要的启示是:对超长上下文模型,缓存命中率就是吞吐的生命线。82% 的命中率不是锦上添花,而是从 1,210 tok/s 到 21,500 tok/s 的量级差异。
部署架构:单机一个实例,共 2 实例
Kimi-K3 采用 SGLang v0.5.18 + MXFP4,两台 B300 各起一个完整实例,跨机仅由 Router 分发请求。实测最佳配置不使用跨机 RDMA 或 KV 传输——这与 GLM-5.2 的 PD 分离方案形成鲜明对比,也说明“要不要做跨机 KV 传输”没有标准答案,取决于模型架构、流量形态和实测结果。
Worker(两台 B300 各执行一次):
SGLANG_RAGGED_VERIFY_MODE=static \
SGLANG_MM_FEATURE_CACHE_MB=256 \
SGLANG_OPT_DEEPGEMM_MEGA_MOE_NUM_MAX_TOKENS_PER_RANK=8320 \
sglang serve \
--trust-remote-code \
--model-path /models/moonshotai/Kimi-K3 \
--served-model-name Kimi-K3 \
--host 0.0.0.0 \
--port 30000 \
--context-length 524288 \
--tp-size 8 \
--ep-size 8 \
--dcp-size 8 \
--dcp-comm-backend a2a \
--dcp-replicate-q-proj \
--mem-fraction-static 0.90 \
--kv-cache-dtype fp8_e4m3 \
--max-running-requests 40 \
--max-total-tokens 180224 \
--chunked-prefill-size 32768 \
--max-prefill-tokens 32768 \
--mamba-radix-cache-strategy extra_buffer_lazy \
--max-mamba-cache-size 160 \
--cuda-graph-max-bs-decode 40 \
--mm-feature-transport cpu \
--moe-runner-backend flashinfer_mxfp4 \
--moe-a2a-backend megamoe \
--speculative-algorithm DSPARK \
--speculative-draft-model-path /models/RadixArk/Kimi-K3-DSpark \
--speculative-dspark-block-size 5 \
--speculative-draft-attention-backend trtllm_mha \
--enable-linear-replayssm-spec \
--reasoning-parser kimi_k3 \
--tool-call-parser kimi_k3 \
--enable-metrics \
--enable-cache-report
Router(Round Robin):
python -m sglang_router.launch_router \
--worker-urls \
http://<worker-a-private-host>:30000 \
http://<worker-b-private-host>:30000 \
--policy round_robin \
--model-path /models/moonshotai/Kimi-K3 \
--tokenizer-path /models/moonshotai/Kimi-K3 \
--host 0.0.0.0 \
--port 30080 \
--prometheus-port 30081 \
--health-check-endpoint /model_info \
--health-check-interval-secs 15 \
--health-check-timeout-secs 5 \
--health-failure-threshold 3 \
--health-success-threshold 1 \
--max-concurrent-requests 256 \
--queue-size 256 \
--queue-timeout-secs 2400 \
--request-timeout-secs 2400 \
--disable-retries \
--cb-failure-threshold 10 \
--cb-success-threshold 3 \
--cb-timeout-duration-secs 60 \
--cb-window-duration-secs 120
几个关键配置点:
- 单机 8 卡做满 TP8 + EP8,配合
--dcp-size 8的 decode context parallel,支撑 524288 的超长 context length; - 投机采样用 DSPARK 方案,搭配独立的 draft 模型(Kimi-K3-DSpark),
--speculative-dspark-block-size 5; - 针对 Mamba 结构的缓存做了专门配置:
--mamba-radix-cache-strategy extra_buffer_lazy、--max-mamba-cache-size 160; --max-running-requests 40相对保守,这是超长上下文模型的必然取舍——每个请求占用的 KV/状态空间大,并发上限必须让位于单请求的资源保障;- Router 层配置了完整的健康检查、熔断(cb-* 参数)和队列超时(2400 秒),这是超长请求场景的必要防护,避免长任务被默认超时误杀。
两个模型的对比与解读
| 维度 | GLM-5.2-NVFP4 | Kimi-K3 |
|---|---|---|
| 部署架构 | 双机 2P2D,PD 分离,Mooncake RDMA | 单机一实例 ×2,Router 分发,无跨机 RDMA |
| 量化方案 | NVFP4(modelopt_fp4) | MXFP4(flashinfer_mxfp4) |
| 投机采样 | EAGLE | DSPARK(独立 draft 模型) |
| 离线吞吐(500 请求窗口平均) | 4,740.90 tok/s | 1,210.81 tok/s |
| 线上吞吐(P95) | 1,571 tok/s | 21,500 tok/s |
| 缓存命中 | ~77% | ~82% |
| 日收入(列表价) | ¥34,068 / 日(压测)/~¥35,000 / 日(线上) | ¥26,934 / 日(压测)/~¥28,000 / 日(线上) |
三点解读:
第一,架构选型没有通解。 GLM-5.2 通过 PD 分离把 Prefill 和 Decode 的资源需求拆开调度,用 Mooncake RDMA 做跨机 KV 传输,换来了离线压测下 4,740 tok/s 的高吞吐;Kimi-K3 实测发现跨机 RDMA 和 KV 传输反而拖累性能,最简单的单机实例 + Router 就是最优解。任何“先进架构”都必须在自己的模型和流量上实测验证。
第二,缓存命中率决定超长上下文模型的生死。 Kimi-K3 离线和线上吞吐相差近 18 倍,核心变量就是 82% 的缓存命中。线上真实流量中大量请求共享前缀(系统 prompt、工具定义、长文档),分层缓存和 radix cache 把这些前缀的 Prefill 成本摊到接近零。评估这类模型的推理成本时,脱离缓存命中谈吞吐没有意义。
第三,投机采样策略要按阶段差异化。 GLM-5.2 在 Prefill 侧用 1 step / 2 draft tokens 的轻量配置,在 Decode 侧放大到 5 steps / 6 draft tokens;Kimi-K3 则用独立的 DSPARK draft 模型。两种方式都指向同一个原则:Decode 阶段才是投机采样的主战场。
实践建议
基于这次测试,给计划在 B300 上部署这两个模型的团队几条建议:
- 先定流量模型,再选部署架构。 输入几万到几十万的超长上下文场景,优先把缓存体系做扎实;输入输出相对规整的场景,PD 分离的吞吐收益更明显。
- 离线压测必须做,但不能只看离线压测。 压测窗口平均吞吐和线上 P95 聚合吞吐是两个口径,收入测算建议同时用两套数据做区间估计。
- KV Cache 用 FP8、权重用 FP4 是当前 B300 上的高性价比组合,两个模型的测试均验证了这一组合的稳定性。
- Router 的健康检查和熔断参数不要省。 超长请求场景下,默认超时配置会误杀正常任务,队列和熔断参数需要按业务时延预算重新设定。
- 收入测算注意工作日口径。 本次测试按工作日验证,周末流量下降会直接影响按列表价折算的日收入,容量规划时建议按周均而非单日峰值估算。
FAQ
Q1:为什么离线压测吞吐和线上吞吐差别这么大?
离线压测的输入输出长度分布更可控,调度器更容易形成高效 batch;线上真实流量会出现长尾和更复杂的并发模式。对超长上下文模型来说,缓存命中率、前缀复用和请求长度分布都会放大这种差异。
Q2:为什么 GLM-5.2 适合 PD 分离,而 Kimi-K3 更适合单机实例?
GLM-5.2 的实测结果显示,Prefill 和 Decode 拆开后,再通过 Mooncake RDMA 传递 KV,可以把离线吞吐做高。Kimi-K3 的实测结果则说明,跨机 RDMA 并没有带来额外收益,单机实例 + Router 更稳、更简单。
Q3:缓存命中率为什么这么重要?
缓存命中率决定了多少前缀可以复用 Prefill 结果。对于系统 prompt、工具定义和长文档复用频繁的流量,缓存越高,Prefill 成本越低,整体吞吐越容易上去。
Q4:这些日收入可以直接拿来做预算吗?
不能直接照搬,只能作为区间参考。收入按列表价折算,并且受工作日、周末、客户端流量模型、计费方式和商务政策共同影响,实际结果会有明显差异。
Q5:部署参数可以直接复用吗?
不能直接照搬,端口、设备列表、模型路径、健康检查和熔断阈值都要按现场环境调整。B300 上的高吞吐方案必须先完成真实流量验证,再决定是否固定为生产配置。
结语
这次测试的全部工作都在 UCloud 优刻得的 B300 GPU 环境中完成,16 卡 SXM6 + NVLink/NVSwitch 的机内互联为 PD 分离、context parallel 等并行策略提供了必要的带宽底座。文中两套部署配置均已在真实线上流量下验证,可直接作为同类部署的起点参考。
对于正在评估 GLM-5.2、Kimi-K3 或其他大参数模型推理部署的团队,建议先明确自己的流量 profile——输入输出长度分布、缓存可复用比例、并发峰值——再对照本文的数据口径做容量测算。如果需要 B300 环境的测试资源,可直接在 UCloud 控制台申请对应规格的 GPU 实例进行验证。
边界提醒:本文所有吞吐和收入数据均基于特定流量 profile 和测试窗口,不同业务的流量模型差异会带来显著不同的结果。收入按列表价折算,仅供参考,实际收入受客户端流量模型、计费方式和商务政策影响。部署配置中的端口、设备列表、模型路径等需按实际环境调整。