MiniMax-M2.7:用 vLLM-Ascend 官方配方在8张昇腾 910B4 上做性能实测

本文摘要MiniMax-M2.7:用 vLLM-Ascend 官方配方在8张昇腾 910B4 上做性能实测本文来源: vLLM 生产工程(公众号:vLLM 生产工程) 原文链接: https://mp.weixin.qq.com/s/41NPRh8GHoWkgH6igkC5Fg 发布时间: 2026-08-27 08:55作者: vLLM 生产工程  发布时间: 2026-08-27 08:55咱们新系列...

MiniMax-M2.7:用 vLLM-Ascend 官方配方在8张昇腾 910B4 上做性能实测

本文来源: vLLM 生产工程(公众号:vLLM 生产工程)
原文链接: https://mp.weixin.qq.com/s/41NPRh8GHoWkgH6igkC5Fg
发布时间: 2026-08-27 08:55

MiniMax-M2.7:用 vLLM-Ascend 官方配方在8张昇腾 910B4 上做性能实测

作者: vLLM 生产工程  发布时间: 2026-08-27 08:55


咱们新系列开始啦。基于 vLLM Ascend 官方 CI 验证过的配方,咱们来补性能报告。

1. 引言:在8张昇腾 910B4 上部署 MiniMax-M2.7

MiniMax-M2.7 的 W8A8 量化权重,配方取自 vLLM-Ascend 官方文档🔗1 A2 单机一节,逐字照抄。部署形态:

  • 62 层 · 48 Q / 8 KV 头 · 256 专家
  • 主权重 216 GB,EAGLE3 草稿头 2.68 GB
  • TP8 + 专家并行 · DP1,EAGLE3 一次 3 个候选
  • KV 池 695,936 token(20.91 GiB/卡),每 token 252 KiB
  • max_model_len

204,800 —— 配方未写该参数,取的是模型自身上限

六档场景全部跑完,零错误率,抢占计数全为 0。

2. 测试方法

2.1 环境

加速卡昇腾 910B4-1 × 8(单机),单卡 64 GB,节点内 HCCS
驱动npu-smi 26.0.rc1 · torch_npu 2.10.0.post2
引擎vLLM 0.23.0 + vllm-ascend v0.23.0rc1
镜像sha256:e96491044bbc…(按内容摘要固定,不按标签)
权重MiniMax-M2.7-w8a8-QuaRot
压测工具sglang.bench_serving🔗2 0.5.17,打 /v1/chat/completions

引擎和压测客户端同机,走回环地址。

关于压测工具的选择。 用 SGLang 仓库里的工具测 vLLM,看着别扭,但它是 OpenAI 协议层的负载生成器,只发 HTTP 请求、只按 SSE 分片计时,不碰引擎内部;源码里 vllm-chat 与 sglang-oai-chat 两个后端指向同一个请求函数、同一条路径,对 vLLM 没有单独的代码路径,也就谈不上偏向。

选它是因为六档里的多轮会话档需要 agentic-trace 做多轮串行回放,而 vllm bench serve 和 GuideLLM 都没有这个能力(前者的 timed_trace 是带时间戳的单轮,源码里还限定只能走 completions 后端)。既然有一档非它不可,其余五档就没有理由换工具 —— 混用工具会破坏表内可比性,尤其 GuideLLM 的 ITL 是逐 token 而这个工具的是逐分片,两者不能并排。

工具的数字也没有盲信:六档的吞吐都用服务端 /metrics 计数器增量重算过一遍,与工具自报值逐档吻合,差 0.00% 到 0.09%

2.2 场景与口径

全部在 ignore_eos 与 temperature=0 下测得 —— 模型想停也得继续写,输出长度被强制拉满,贪心解码。

标「排队」的两档一次性灌进 1,000 条,而 --max-num-seqs 是 32,它们的 TTFT 量的是队列深度不是模型速度。

TPOT 和吞吐都带着 EAGLE3 的加成,没有关闭对照,和没开投机的系统比不对等。实测接受长度按档在 2.386(ShareGPT)到 2.608(多轮会话)之间,也就是一次猜 3 个平均落袋 2.4 到 2.6 个;由此得到的加速上界是 2.54 倍。

ITL 记的是一个解码步而不是一个 token —— 开了 EAGLE3 之后一步产出的两三个 token 挤在同一个流式分片里,所以 ITL 与 TPOT 不能相除。

输入吞吐含前缀命中的部分。多轮会话档扣掉命中后实际 prefill 只有 1,088 tok/s,不是表里的 13,271。

高生成量档那个 1,217.3 tok/s 也要打个折:它的 409,600 个输出 token 重分词后只剩 300,576,少了 27%,而同样口径、128 输出的两档重分词差值是 0 —— 长档的尾部退化成了重复文本。这个数要读作定长解码的吞吐上界,不是有效内容吞吐。

2.3 判据与样本量

容量档的 SLO 在开跑前冻结为 TTFT p95 ≤ 2,000 毫秒,取 MLPerf Inference server 场景 Llama2-70B 的约束原值。

分位数的可引用门槛同样取 MLPerf 的早停规则:p99 约需 662 条查询,p90 约 64 条。下表中带 * 的 p99 样本量不足,是真实的次序统计量但方差过大,不能用于 SLO 判定或跨轮比较。

2.4 复现命令

六档一行一档。<SG> 为本地 ShareGPT 语料路径,<TRACE> 为本地会话轨迹路径:

COMMON="--backend vllm-chat \  --base-url http://127.0.0.1:8077 \  --model /models/MiniMax-M2.7-w8a8-QuaRot \  --served-model-name MiniMax-M2.7 \  --warmup-requests 0 --output-details --disable-tqdm --seed 1024"# 定长档必须写 --random-range-ratio 1# random 档必须给 --dataset-path# 延迟python3 -m sglang.bench_serving $COMMON \  --dataset-name random --dataset-path <SG> \  --num-prompts 100 --max-concurrency 1 \  --random-input-len 1024 --random-output-len 128 \  --random-range-ratio 1# 高生成量python3 -m sglang.bench_serving $COMMON \  --dataset-name random --dataset-path <SG> \  --num-prompts 200 --max-concurrency 32 \  --random-input-len 1024 --random-output-len 2048 \  --random-range-ratio 1# 长上下文python3 -m sglang.bench_serving $COMMON \  --dataset-name random --dataset-path <SG> \  --num-prompts 100 --max-concurrency 16 \  --random-input-len 32768 --random-output-len 128 \  --random-range-ratio 1# ShareGPTpython3 -m sglang.bench_serving $COMMON \  --dataset-name sharegpt --dataset-path <SG> \  --num-prompts 1000# 吞吐python3 -m sglang.bench_serving $COMMON \  --dataset-name random --dataset-path <SG> \  --num-prompts 1000 \  --random-input-len 1024 --random-output-len 512 \  --random-range-ratio 1# 多轮会话python3 -m sglang.bench_serving $COMMON \  --dataset-name agentic-trace --dataset-path <TRACE> \  --num-prompts 16 --max-concurrency 8 \  --agentic-max-turns 32 --sharegpt-output-len 220

每档之间调用 POST /reset_prefix_cache 清冷缓存,前后各采一次 /metrics 快照。容量档把 --max-concurrency 换成 --request-rate,泊松到达,九个速率点每点 300 秒。

3. 性能

吞吐

场景并发 · n输出 tok/s输入 tok/s前缀命中
延迟 1024/1281 · 10072.96090%
高生成量 1024/204832 · 2001,217.36320.66%
长上下文 32768/12816 · 10056.014,4590%
ShareGPT(排队)不限 · 1,000494.08490.81%
吞吐 1024/512(排队)不限 · 1,000825.31,7090.98%
多轮会话 ≤32 轮8 · 362258.213,27191.80%

TTFT(毫秒)

场景p50p90p95p99
延迟 1024/128355.6369.7377.4388.6 *
高生成量 1024/2048443.12,094.12,098.72,102.3 *
长上下文 32768/1286,099.413,549.323,279.131,176.5 *
ShareGPT(排队)185,377.4337,928.9357,426.6373,005.8
吞吐 1024/512(排队)300,626.4546,708.1579,147.5603,587.2
多轮会话 ≤32 轮477.2760.1813.61,077.9 *

TPOT(毫秒,逐 token)

场景p50p90p95p99
延迟 1024/12810.9212.6613.5314.72 *
高生成量 1024/204825.0729.9130.4131.37 *
长上下文 32768/128241.6300.7317.4337.0 *
ShareGPT60.0685.42103.2178.8
吞吐 1024/51238.4443.5145.2249.19
多轮会话 ≤32 轮26.3533.2536.3843.54 *

ITL(毫秒,逐解码步)

场景p50p90p95p99
延迟 1024/12826.7729.0330.1841.01 *
高生成量 1024/204853.5955.4658.85337.3 *
长上下文 32768/12864.511,978.81,999.22,038.8 *
ShareGPT55.38377.0399.2418.0
吞吐 1024/51253.55313.7340.8371.2
多轮会话 ≤32 轮43.9163.04334.2391.7 *

卡顿尾巴分成三类

3.1 容量:每副本能扛多少

六档要么钉死并发、要么一次性灌完,都不是固定到达率。而这类测法测不出崩溃点 —— 系统再慢,在途请求也被并发数钉死,队列不会无限堆积。要回答容量问题得换开环:固定到达率,看队列什么时候开始发散。

我们另跑了一轮泊松到达的速率扫描:random 数据集,512 输入 / 256 输出,九个速率点,每点 300 秒,前后各采一次 /metrics 快照。SLO 在开跑前冻结为 TTFT p95 ≤ 2,000 毫秒,取的是 MLPerf server 场景 Llama2-70B 的约束原值。

开环速率扫描:TTFT p95 的拐点与吞吐天花板

六档场景全程零抢占。原因在下面这张图上:--max-num-seqs 32 与 KV 池容量两条约束,在 21,748 token 处交叉,而本轮没有一档的请求长度够得着。

两条约束,哪一条先生效

结果是每副本 ### 2.25 请求/秒。服务端硬上界 2.76 请求/秒,越过 2.25 之后 TTFT p95 从 1,624 毫秒跳到 2,299 毫秒。

拐点两侧各复测了一次:2.25 两次都达标,2.42 两次都不达标。所以 safe_rps 取的是「两次都达标的最高速率」,而不是「下一档不达标所以上一档是上界」—— 后一种说法要依赖单次测量,而 TTFT p95 恰好是全表噪声最大的指标。

横轴用的是实测到达速率,不是设定值。压测客户端发不到设定速率(实测/设定在 0.840 到 0.955 之间),机制未查明;照设定速率画会把安全速率报高。

这个数是形态相关的,换负载必须重测。它同样在强制定长口径下测得,很可能偏保守。判定用的 TTFT p95 在同配置复跑下波动达 8.6% 到 22.9%,是全表噪声最大的指标,而这还是三重低估的下界(n=2、同 seed、未跨引擎重启),所以拐点只精确到相邻两档之间。

预登记里还有一条次 SLO(TPOT p95 ≤ 50 ms)。它在拐点附近实测平在 49 到 52 毫秒,与阈值重合,本实验分辨率下无法判定达标与否 —— 不能默认 2.25 请求/秒下 TPOT 也达标。

3.2 长上下文的延迟形状

长上下文档跑的是 random 数据集,32,768 输入 / 128 输出,并发 16,共 100 条请求。它的输入吞吐 14,459 tok/s 是六档最高,前缀命中率为 0,是最接近纯 prefill 能力的一档。

反常的是它的 ITL 分布:中位只有 64.5 毫秒,却有 22.7% 落在 1,500 毫秒以上,而 100 到 1,500 毫秒这一整段只占 9.3%。两个截然分开的峰,慢峰几乎是个定值。

三档 ITL 的累积分布:长上下文的平台段与跃迁

慢峰的量级和一条 32K 提示的 prefill 耗时对得上。按该档 14,459 tok/s 折算,33,077 token 约需 2.3 秒。

再看配方:--max-num-batched-tokens 是 32,768,而单条提示实测 33,077 token(标称 32,768 加上聊天模板)。一条提示的 prefill 就能占满整个批次预算。引擎 V1 架构把 prefill 切块和 decode 混在同一个调度步里,于是 decode 步之间持续插进大块 prefill。该档每条请求只输出 128 个 token,整条请求的生命周期几乎全泡在混合批里。

这个链条讲得通,但讲得通不等于成立。我们只改这一个参数、其余逐字不动,同一档重跑了三次。

批次预算改变 ITL 分布形状,但不改变总量

--max-num-batched-tokens8,19216,38432,768(官方)
输入吞吐 (tok/s)14,25814,40514,470
整批耗时 (s)229.8227.5226.5
ITL 均值 (ms)492.7502.5510.7
ITL 中位 (ms)519.9199.664.9
ITL p95 (ms)673.71,207.51,995.5
ITL p95 ÷ 中位1.3×6.0×30.7×
ITL ≥ 1,500 ms 的比例0.00%0.2%22.5%

批次预算变化 4 倍,总量三项全部守恒:输入吞吐差 1.5%,整批耗时差 1.5%,ITL 均值差 3.6%。而分布形状彻底翻转:中位相差 8 倍,p95 相差 3 倍,那个 2 秒的慢峰完全消失。

prefill 的总工作量是守恒的,它必须插进 decode 流里。这个参数决定的只是你以什么粒度承受它 —— 是大部分步很快、22.5% 的步卡两秒,还是所有步都均匀地不快。

官方文档把 --max-num-batched-tokens 列在 OOM 时的调节顺序里,排在 --max-num-seqs 之后。从这组数据看,它同时是个延迟整形参数,而这一面文档没提。

  • 交互式长上下文、对卡顿敏感,就降低批次预算。换来可预测的吐字节奏,吞吐几乎不付代价,代价在中位数变慢。
  • 能接受偶发两秒停顿、要大部分时候快,就保持官方的 32,768。
  • 两者兼得做不到。三个工作点的 ITL 均值守恒在 3.6% 以内,总时间就那么多。

降低批次预算会连带把 KV 池撑大(695,936 到 767,872 token),所以这个对照还差一步才干净。我们用 --num-gpu-blocks-override 把 8,192 那一档的 KV 池钉回 696,064,和官方档逐字相同,重跑:全部 ITL 指标变化不超过 2.1%,抢占仍为 0。KV 池容量不是成因,批次预算才是。

官方 32,768 那一档同时是与首轮的复现对照,全部指标吻合在 3.3% 以内。

有一条同因没能分离:图模式配的是 FULL_DECODE_ONLY,只覆盖纯 decode 批,调度步一旦混进 prefill 就回落逐算子执行 —— 而批次预算恰好也决定混合批出现的频率,两者绑在一起,拆不开。

4. 部署

配方取自官方文档🔗1 A2 单机一节,逐字照抄。下面是实际跑的那一份,四处偏离已标出,全是环境适配,不是调优。

export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOADexport HCCL_OP_EXPANSION_MODE="AIV"export HCCL_BUFFSIZE=512export TASK_QUEUE_ENABLE=1export PYTORCH_NPU_ALLOC_CONF=expandable_segments:Trueexport HCCL_INTRA_PCIE_ENABLE=1export HCCL_INTRA_ROCE_ENABLE=0export OMP_PROC_BIND=falseexport OMP_NUM_THREADS=1# 偏离 1(本地追加):容器内 8 个加速卡设备节点全部可见,运行时认的是这个变量export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7# 偏离 2(本地追加):不设它,POST /reset_prefix_cache 返回 404export VLLM_SERVER_DEV_MODE=1# 偏离 3:两处权重路径改为本地路径vllm serve /models/MiniMax-M2.7-w8a8-QuaRot \    --served-model-name MiniMax-M2.7 \    --host 0.0.0.0 --port 8077 \    --trust-remote-code \    --tensor-parallel-size 8 \    --quantization ascend \    --enable-expert-parallel \    --max-num-seqs 32 \    --seed 1024 \    --max-num-batched-tokens 32768 \    --compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY"}' \    --gpu-memory-utilization 0.85 \    --additional-config '{"enable_cpu_binding":true}' \    --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":16}' \    --speculative_config '{"method": "eagle3", "model": "/models/MiniMax-M2.7-eagle-model-short", "num_speculative_tokens":3}'

官方在同一段里还给了三条宿主机内核参数,要单独在宿主上执行,改之前记原值、跑完还原:

sysctl -w vm.swappiness=0sysctl -w kernel.numa_balancing=0sysctl -w kernel.sched_migration_cost_ns=50000

我们照抄了这三条,但没做开关对照,给不出它们值多少性能。

Pod 需要 hostNetwork 与特权模式,生产环境应改用设备插件。冷启动到就绪 141 秒(编译 77 秒),编译缓存命中后 52.8 秒 —— 这两个数决定探针超时怎么配。

--enable-prefix-caching 官方没写,但引擎 V1 默认开启,所以本轮是开着的。三个解析器官方标为「若要用命令行测试工具调用则追加」,不属于基础配方,本轮没开;要对外提供工具调用能力这三项必须加,加了之后输出 token 的计数口径不变。

5. 结论

官方 A2 单机配方在这台八卡机器上照抄就能跑,不需要打补丁。并发 32 时每用户 39.9 tok/s、整机输出 1,217 tok/s,32K 输入的输入吞吐 14,459 tok/s,每副本安全速率 2.25 请求/秒。

跑长上下文交互式负载的话,--max-num-batched-tokens 值得单独调一次。它不提速,但能把两秒的停顿摊平成均匀的慢 —— 官方文档只把它列在 OOM 的调节顺序里,没提这一面。

版本基线:vLLM 0.23.0 配 vllm-ascend v0.23.0rc1,昇腾 910B4-1 单机八卡,权重为官方发布的 W8A8 量化包。换权重、换引擎版本、换硬件,结论都可能变,需要重新测量。

附录:各项测试的口径一览

测试数据集 / 规格样本量并发或速率工具
延迟random 1024 / 128100并发 1sglang.bench_serving 0.5.17
高生成量random 1024 / 2048200并发 32同上
长上下文random 32768 / 128100并发 16同上
ShareGPTShareGPT V3 真实对话1,000不限并发同上
吞吐random 1024 / 5121,000不限并发同上
多轮会话agent 编码轨迹,16 会话 ≤32 轮362 轮并发 8同上
容量random 512 / 2569 点 × 300 s泊松到达 0.5–3.0 rps同上,--request-rate
批次预算敏感性random 32768 / 1283 × 100并发 16同上

全部在 ignore_eos + temperature=0 下测得。除多轮会话档外每档一轮;多轮会话两轮,批次预算三档各一轮外加一组固定 KV 池的对照。

免责:本文为单次实验的测量记录,除多轮会话档外各档只跑一轮,不构成普适结论,亦不构成选型建议。数据取自特定版本、特定硬件与特定配方,换任一条件均需重新测量。

参考链接

🔗1  https://docs.vllm.ai/projects/ascend/zh-cn/latest/tutorials/models/MiniMax-M2.html

🔗2  https://github.com/sgl-project/sglang/blob/main/python/sglang/bench_serving.py

🔗3  https://github.com/vllm-project/vllm-ascend

🔗4  https://huggingface.co/datasets/anon8231489123/ShareGPT_Vicuna_unfiltered


本文转载自微信公众号「vLLM 生产工程」,仅供学习交流使用。

觉得内容不错?我要

打赏杯咖啡或蜜雪冰城吧
微信扫一扫
微信赞赏码
支付宝扫一扫
支付宝赞赏码
评论 暂无评论
请登录后参与评论