Skip to content
Open
31 changes: 21 additions & 10 deletions benchmarks/single_node/agentic/minimaxm3_fp4_b200_mtp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ set -x

source "$(dirname "$0")/../../benchmark_lib.sh"

check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION
check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION PORT EVAL_ONLY

DRAFT_MODEL="Inferact/MiniMax-M3-EAGLE3-GQA"
NUM_SPEC_TOKENS=3
TOKENS_PER_SEQ=$((1 + NUM_SPEC_TOKENS))
# Golden AL for the GQA draft head: golden_al_distribution/minimaxm3_eagle3_gqa.yaml
# minimax-m3.thinking_on[3]. The non-GQA curve (minimaxm3_eagle3.yaml) reads 2.83.
SYNTHETIC_ACCEPT_LEN=2.78
Expand Down Expand Up @@ -103,8 +104,8 @@ install_agentic_deps

OFFLOAD_ARGS=()
if require_agentic_kv_offload_backend vllm-simple; then
python3 "$(dirname "$0")/../../../runners/patch_vllm_simple_kv_offload.py"
CPU_OFFLOAD_BYTES=$((TOTAL_CPU_DRAM_GB * 1024 * 1024 * 1024))
# The matrix emits decimal GB; SimpleCPUOffloadConnector expects bytes.
CPU_OFFLOAD_BYTES=$((TOTAL_CPU_DRAM_GB * 1000 * 1000 * 1000))
export VLLM_USE_SIMPLE_KV_OFFLOAD=1
OFFLOAD_CONFIG=$(printf \
'{"kv_connector":"SimpleCPUOffloadConnector","kv_role":"kv_both","kv_connector_extra_config":{"cpu_bytes_to_use":%d,"lazy_offload":true}}' \
Expand All @@ -116,10 +117,18 @@ export PYTHONNOUSERSITE=1
export VLLM_ENGINE_READY_TIMEOUT_S=3600
export VLLM_FLOAT32_MATMUL_PRECISION=high
export VLLM_FLASHINFER_ALLREDUCE_BACKEND=trtllm

# B200's 180 GB leaves little beyond the ~250 GB checkpoint: TP2 cannot
# host 1M-context KV for one request at 0.9, so TP4 is the smallest topology.
GPU_MEMORY_UTILIZATION="0.9"
export AIPERF_SERVER_METRICS_URLS="http://localhost:${PORT}/metrics"
export AIPERF_REQUIRED_SERVER_METRIC_PREFIX="vllm:"

# Reserve 5% of HBM for runtime spikes while giving the KV pool more room.
# TP2 failed the full-context startup check at 0.90; it needs a separate GPU
# qualification before joining the sweep at this higher utilization.
GPU_MEMORY_UTILIZATION="0.95"
MAX_NUM_SEQS=$((2 * CONC))
MAX_CUDAGRAPH_CAPTURE_SIZE=$((TOKENS_PER_SEQ * MAX_NUM_SEQS))
if (( MAX_CUDAGRAPH_CAPTURE_SIZE > 512 )); then
MAX_CUDAGRAPH_CAPTURE_SIZE=512
fi

SERVER_LOG="$RESULT_DIR/server.log"
mkdir -p "$RESULT_DIR"
Expand All @@ -138,11 +147,11 @@ trap 'exit 143' TERM

if [ "${EVAL_ONLY:-}" = "true" ]; then
SPEC_CONFIG=$(printf \
'{"method":"eagle3","model":"%s","num_speculative_tokens":%d,"attention_backend":"FLASH_ATTN"}' \
'{"method":"eagle3","model":"%s","num_speculative_tokens":%d,"attention_backend":"TRITON_ATTN","kv_cache_dtype":"fp8"}' \
"$DRAFT_MODEL_PATH" "$NUM_SPEC_TOKENS")
else
SPEC_CONFIG=$(printf \
'{"method":"eagle3","model":"%s","num_speculative_tokens":%d,"attention_backend":"FLASH_ATTN","rejection_sample_method":"synthetic","synthetic_acceptance_length":%.2f}' \
'{"method":"eagle3","model":"%s","num_speculative_tokens":%d,"attention_backend":"TRITON_ATTN","kv_cache_dtype":"fp8","rejection_sample_method":"synthetic","synthetic_acceptance_length":%.2f}' \
"$DRAFT_MODEL_PATH" "$NUM_SPEC_TOKENS" "$SYNTHETIC_ACCEPT_LEN")
fi

Expand All @@ -157,14 +166,16 @@ VLLM_CMD=(
--block-size 128
--language-model-only
--enable-prefix-caching
--enable-chunked-prefill
--no-enable-flashinfer-autotune
--reasoning-parser minimax_m3
--tool-call-parser minimax_m3
--enable-auto-tool-choice
--default-chat-template-kwargs '{"thinking_mode":"enabled"}'
--attention-config '{"backend":"FLASHINFER","use_trtllm_attention":true,"indexer_kv_dtype":"fp8"}'
--kv-cache-dtype fp8
--max-cudagraph-capture-size 512
--max-cudagraph-capture-size "$MAX_CUDAGRAPH_CAPTURE_SIZE"
--max-num-seqs "$MAX_NUM_SEQS"
--max-num-batched-tokens 16384
--stream-interval 20
--trust-remote-code
Expand Down
27 changes: 19 additions & 8 deletions benchmarks/single_node/agentic/minimaxm3_fp4_b300_mtp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ set -x

source "$(dirname "$0")/../../benchmark_lib.sh"

check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION
check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION PORT EVAL_ONLY

DRAFT_MODEL="Inferact/MiniMax-M3-EAGLE3-GQA"
NUM_SPEC_TOKENS=3
TOKENS_PER_SEQ=$((1 + NUM_SPEC_TOKENS))
# Golden AL for the GQA draft head: golden_al_distribution/minimaxm3_eagle3_gqa.yaml
# minimax-m3.thinking_on[3]. The non-GQA curve (minimaxm3_eagle3.yaml) reads 2.83.
SYNTHETIC_ACCEPT_LEN=2.78
Expand Down Expand Up @@ -40,8 +41,8 @@ install_agentic_deps

OFFLOAD_ARGS=()
if require_agentic_kv_offload_backend vllm-simple; then
python3 "$(dirname "$0")/../../../runners/patch_vllm_simple_kv_offload.py"
CPU_OFFLOAD_BYTES=$((TOTAL_CPU_DRAM_GB * 1024 * 1024 * 1024))
# The matrix emits decimal GB; SimpleCPUOffloadConnector expects bytes.
CPU_OFFLOAD_BYTES=$((TOTAL_CPU_DRAM_GB * 1000 * 1000 * 1000))
export VLLM_USE_SIMPLE_KV_OFFLOAD=1
OFFLOAD_CONFIG=$(printf \
'{"kv_connector":"SimpleCPUOffloadConnector","kv_role":"kv_both","kv_connector_extra_config":{"cpu_bytes_to_use":%d,"lazy_offload":true}}' \
Expand All @@ -53,6 +54,14 @@ export PYTHONNOUSERSITE=1
export VLLM_ENGINE_READY_TIMEOUT_S=3600
export VLLM_FLOAT32_MATMUL_PRECISION=high
export VLLM_FLASHINFER_ALLREDUCE_BACKEND=trtllm
export AIPERF_SERVER_METRICS_URLS="http://localhost:${PORT}/metrics"
export AIPERF_REQUIRED_SERVER_METRIC_PREFIX="vllm:"

MAX_NUM_SEQS=$((2 * CONC))
MAX_CUDAGRAPH_CAPTURE_SIZE=$((TOKENS_PER_SEQ * MAX_NUM_SEQS))
if (( MAX_CUDAGRAPH_CAPTURE_SIZE > 512 )); then
MAX_CUDAGRAPH_CAPTURE_SIZE=512
fi

SERVER_LOG="$RESULT_DIR/server.log"
mkdir -p "$RESULT_DIR"
Expand All @@ -71,11 +80,11 @@ trap 'exit 143' TERM

if [ "${EVAL_ONLY:-}" = "true" ]; then
SPEC_CONFIG=$(printf \
'{"method":"eagle3","model":"%s","num_speculative_tokens":%d,"attention_backend":"FLASH_ATTN"}' \
'{"method":"eagle3","model":"%s","num_speculative_tokens":%d,"attention_backend":"TRITON_ATTN","kv_cache_dtype":"fp8"}' \
"$DRAFT_MODEL_PATH" "$NUM_SPEC_TOKENS")
else
SPEC_CONFIG=$(printf \
'{"method":"eagle3","model":"%s","num_speculative_tokens":%d,"attention_backend":"FLASH_ATTN","rejection_sample_method":"synthetic","synthetic_acceptance_length":%.2f}' \
'{"method":"eagle3","model":"%s","num_speculative_tokens":%d,"attention_backend":"TRITON_ATTN","kv_cache_dtype":"fp8","rejection_sample_method":"synthetic","synthetic_acceptance_length":%.2f}' \
"$DRAFT_MODEL_PATH" "$NUM_SPEC_TOKENS" "$SYNTHETIC_ACCEPT_LEN")
fi

Expand All @@ -86,19 +95,21 @@ VLLM_CMD=(
--host 0.0.0.0
--port "$PORT"
--tensor-parallel-size "$TP"
--gpu-memory-utilization 0.9
--gpu-memory-utilization 0.95
--block-size 128
--language-model-only
--enable-prefix-caching
--enable-chunked-prefill
--no-enable-flashinfer-autotune
--reasoning-parser minimax_m3
--tool-call-parser minimax_m3
--enable-auto-tool-choice
--default-chat-template-kwargs '{"thinking_mode":"enabled"}'
--attention-config '{"backend":"FLASHINFER","use_trtllm_attention":true,"indexer_kv_dtype":"fp8"}'
--kv-cache-dtype fp8
--max-cudagraph-capture-size 512
--max-num-batched-tokens 16384
--max-cudagraph-capture-size "$MAX_CUDAGRAPH_CAPTURE_SIZE"
--max-num-seqs "$MAX_NUM_SEQS"
--max-num-batched-tokens 32768
--stream-interval 20
--trust-remote-code
--speculative-config "$SPEC_CONFIG"
Expand Down
35 changes: 18 additions & 17 deletions configs/nvidia-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5562,7 +5562,7 @@ qwen3.5-fp4-gb200-dynamo-sglang-agentic-mtp:
additional-settings:
- "CONFIG_FILE=recipes/qwen3.5/sglang/gb200-fp4/agentx/agg-tp2ep2-mtp-hicache-cap48.yaml"
minimaxm3-fp4-b300-vllm-agentic-mtp:
image: vllm/vllm-openai:nightly-1dc464d42681d22f38caf1fdc1eb632dc4421c45
image: vllm/vllm-openai:nightly-29468dde8b515031dc6d4d9d06bf0a2fa0442098
model: nvidia/MiniMax-M3-NVFP4
model-prefix: minimaxm3
runner: cluster:b300-dsxe
Expand All @@ -5571,14 +5571,14 @@ minimaxm3-fp4-b300-vllm-agentic-mtp:
multinode: false
scenarios:
agentic-coding:
- dram-utilization: 0.683
- dram-utilization: 1.0
search-space:
- { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1] }
- { tp: 4, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 5, 10, 15, 20] }
- { tp: 4, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [30] }
- { tp: 4, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [30, 40, 48, 64] }
- dram-utilization: 1.0
search-space:
- { tp: 2, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [24] }
- { tp: 2, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [24, 32, 40] }

minimaxm3-fp4-gb300-dynamo-vllm-agentic-mtp-disagg:
image: vllm/vllm-openai:nightly-5e35a6f4f9bbc217c599692157ca985c894373f7
Expand Down Expand Up @@ -5690,33 +5690,34 @@ minimaxm3-fp4-b300-trtllm-agentic-mtp:
# MiniMax-M3's only active B200 configuration -- the 8k1k scenario that carried
# the previous B200 curves was removed in #2493.
#
# TP4-only. The B300 sibling also runs a TP2 arm, but TP2 does not fit on B200:
# TP4-only until a new TP2 arm is qualified. At 0.90 HBM utilization TP2
# does not fit on B200:
# the ~250 GB NVFP4 checkpoint leaves a 31.72 GiB KV pool at
# --gpu-memory-utilization 0.9, and one request at the model's 1,048,576-token
# max_model_len needs 37.62 GiB, so vLLM raises in _check_enough_kv_cache_memory
# and the engine never reaches serving (run 31141913741 -- both TP2 cells, c1
# and c2, died identically at init; every TP4 cell passed). This is structural,
# not a concurrency cliff: the estimated max model length at TP2 is 883,840,
# below the corpus context, so no conc-list would have made the arm run.
# and c2, died identically at init; every TP4 cell passed). This is a startup
# capacity limit at 0.90, not a concurrency cliff: the estimated max model
# length at TP2 is 883,840, below the corpus context. The new 0.95 limit may
# clear that check, but needs a live full-context run.
#
# Concurrency on the surviving arms still differs from B300, whose TP4 pool is
# ~787 GB against B200's ~398 GB:
# Concurrency on the surviving arms still differs from B300; at the prior
# 0.90 HBM limit, its TP4 KV pool was ~787 GB against B200's ~398 GB:
# TP4 B300 runs 1-20; B200 samples 5-15 densely because the cliff lands
# inside that range at roughly half the KV, and retains 20 past it.
# TP4 + SimpleCPU picks up at 20 rather than B300's 30, since the host tier
# has to start absorbing the working set one step earlier, and stops at
# 40 rather than following B300 to 75. Past 40 the host tier is
# 40 rather than following B300's new sweep to 64. Past 40 the host tier is
# absorbing a working set that never fit in B200's ~398 GB TP4 pool to
# begin with, so those points cost four engine starts each to trace a
# tail that is offload bandwidth, not the SKU.
#
# dram-utilization 0.683 is the B300 value verbatim, and it resolves to the same
# 1,024 GB engine-level CPU KV budget at TP4: b200-nscale and b300-nv both report
# more installed DRAM than MAX_AGENTIC_AVAILABLE_CPU_DRAM_MIB, so both clamp to
# the same 3 TB AgentX ceiling before the proportional-GPU rule is applied.
# GPU-resident points receive a zero budget.
# B200's 1.0 offload arm uses the full declared host budget: 2,063,920 MiB
# times TP4/8, or about 1,082 GB for this server. GPU-resident points receive
# no host KV budget. B300 has a higher, 3 TB capped node budget (1,499 GB for
# TP4, 749 GB for TP2 after whole-GB rounding).
minimaxm3-fp4-b200-vllm-agentic-mtp:
image: vllm/vllm-openai:nightly-1dc464d42681d22f38caf1fdc1eb632dc4421c45
image: vllm/vllm-openai:nightly-29468dde8b515031dc6d4d9d06bf0a2fa0442098
model: nvidia/MiniMax-M3-NVFP4
model-prefix: minimaxm3
runner: cluster:b200-nscale
Expand Down
37 changes: 37 additions & 0 deletions perf-changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8950,3 +8950,40 @@
description:
- "Update SGLang image from v0.5.19-cu130 to v0.5.20-cu130 and pass --cuda-graph-max-bs-decode after the alias removal."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3334

- config-keys:
- minimaxm3-fp4-b200-vllm-agentic-mtp
- minimaxm3-fp4-b300-vllm-agentic-mtp
scenario-type:
- agentic-coding
description:
- "Pin MiniMax-M3 B200/B300 AgentX to vLLM nightly-29468dde8b515031dc6d4d9d06bf0a2fa0442098 and remove the obsolete SimpleCPU KV patch."
- "Increase HBM and B300 host KV budgets, tune serving limits, expand the B300 sweep, and correct host-capacity units."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3435

- config-keys:
- minimaxm3-fp4-b200-vllm-agentic-mtp
- minimaxm3-fp4-b300-vllm-agentic-mtp
scenario-type:
- agentic-coding
description:
- "Use BF16 EAGLE3 draft KV cache to avoid the FA4 FP8 descale startup failure."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3435

- config-keys:
- minimaxm3-fp4-b200-vllm-agentic-mtp
- minimaxm3-fp4-b300-vllm-agentic-mtp
scenario-type:
- agentic-coding
description:
- "Use FlashInfer with FP8 EAGLE3 draft KV cache on B200 and B300."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3435

- config-keys:
- minimaxm3-fp4-b200-vllm-agentic-mtp
- minimaxm3-fp4-b300-vllm-agentic-mtp
scenario-type:
- agentic-coding
description:
- "Use Triton attention with FP8 EAGLE3 draft KV cache."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3435
Loading
Loading