From 5733d3267717050d697e55b16547869bd99f6dc3 Mon Sep 17 00:00:00 2001 From: functionstackx <47992694+functionstackx@users.noreply.github.com> Date: Thu, 30 Jul 2026 01:09:18 -0400 Subject: [PATCH 1/7] feat(minimaxm3-h200-agentic-mtp): add EAGLE3 AgentX recipe with golden-AL synthetic acceptance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add minimaxm3-fp8-h200-vllm-agentic-mtp, the spec-decoding=mtp variant of the MiniMax-M3 MXFP8 H200 agentic-coding recipe: Inferact/MiniMax-M3-EAGLE3 draft head, 3 speculative tokens, FLASH_ATTN drafter, and synthetic acceptance pinned to the committed golden AL 2.83 (minimaxm3_eagle3.yaml, thinking_on, K=3). EVAL_ONLY keeps real target verification. Serve shape, Mooncake offload and search-space arms mirror the non-MTP sibling, trimmed at the top concurrencies. 中文:新增 minimaxm3-fp8-h200-vllm-agentic-mtp,即 MiniMax-M3 MXFP8 H200 智能体 编码配方的投机解码(spec-decoding=mtp)变体:Inferact/MiniMax-M3-EAGLE3 草稿头、 3 个投机 token、drafter 固定为 FLASH_ATTN,合成接受长度固定为黄金 AL 2.83 (minimaxm3_eagle3.yaml,thinking_on,K=3)。EVAL_ONLY 保留真实目标验证。服务参数、 Mooncake KV 卸载与搜索空间沿用非 MTP 版本,仅在高并发端裁剪。 Co-Authored-By: Claude Opus 5 (1M context) --- .../agentic/minimaxm3_fp8_h200_mtp.sh | 243 ++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100755 benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh new file mode 100755 index 0000000000..ad3b6a5115 --- /dev/null +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh @@ -0,0 +1,243 @@ +#!/usr/bin/env bash +set -euo pipefail +set -x + +# MiniMax-M3 MXFP8 H200 AgentX (agentic-coding) recipe with EAGLE3 speculative +# decoding — the spec-decoding=mtp variant of agentic/minimaxm3_fp8_h200.sh. +# Everything outside the speculative block mirrors the non-MTP agentic sibling +# (Mooncake host-DRAM KV offload, --block-size 128, --language-model-only, +# --kv-cache-dtype fp8, TRITON_ATTN, gmu 0.92, minimax_m3 parsers, vllm-router +# for DP-attention), so the spec-decode delta is readable at equal concurrency. +# +# Speculative config: Inferact/MiniMax-M3-EAGLE3 draft head, 3 speculative +# tokens — the same draft/level as every merged MiniMax-M3 MTP recipe. The +# drafter is pinned to FLASH_ATTN as on the other CUDA M3 MTP recipes: the +# EAGLE3 head is MHA and FlashInfer only serves page size 128 through its +# trtllm-gen kernel, which requires GQA/MQA. +# +# Throughput runs pin synthetic acceptance to the committed golden AL; the +# EVAL_ONLY accuracy run keeps real target verification. See SYNTHETIC_ACCEPT_LEN. + +source "$(dirname "$0")/../../benchmark_lib.sh" + +check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION EP_SIZE DP_ATTENTION + +DRAFT_MODEL="Inferact/MiniMax-M3-EAGLE3" + +if [[ -n "${SLURM_JOB_ID:-}" ]]; then + echo "JOB $SLURM_JOB_ID running on ${SLURMD_NODENAME:-unknown}" +fi + +resolve_complete_model_snapshot() { + python3 - "$1" <<'PY' +import json +import sys +from pathlib import Path + +model_cache_dir = Path(sys.argv[1]) +try: + revision = model_cache_dir.joinpath("refs/main").read_text().strip() +except OSError: + raise SystemExit + +if not revision or Path(revision).name != revision: + raise SystemExit + +snapshot = model_cache_dir / "snapshots" / revision +index_path = snapshot / "model.safetensors.index.json" +required_files = ( + snapshot / "config.json", + snapshot / "tokenizer_config.json", + index_path, +) +if not all(path.is_file() for path in required_files): + raise SystemExit +try: + weight_map = json.loads(index_path.read_text())["weight_map"] +except (KeyError, json.JSONDecodeError, OSError): + raise SystemExit +shards = {snapshot / filename for filename in weight_map.values()} +if shards and all(path.is_file() for path in shards): + print(snapshot) +PY +} + +if [[ -n "${MODEL_PATH:-}" ]]; then + if [[ ! -d "$MODEL_PATH" || -z "$(ls -A "$MODEL_PATH" 2>/dev/null)" ]]; then + hf download "$MODEL" --local-dir "$MODEL_PATH" + fi +else + MODEL_CACHE_ROOT="${HF_HUB_CACHE:-${HF_HOME:-$HOME/.cache/huggingface/hub}}" + MODEL_CACHE_DIR="$MODEL_CACHE_ROOT/models--${MODEL//\//--}" + mkdir -p "$MODEL_CACHE_ROOT" + MODEL_PATH=$(resolve_complete_model_snapshot "$MODEL_CACHE_DIR") + if [[ -z "$MODEL_PATH" ]]; then + exec 9>"$MODEL_CACHE_ROOT/.minimaxm3-download.lock" + flock -w 3600 9 + MODEL_PATH=$(resolve_complete_model_snapshot "$MODEL_CACHE_DIR") + if [[ -z "$MODEL_PATH" ]]; then + DOWNLOADED_MODEL_PATH=$(hf download "$MODEL") + MODEL_PATH=$(resolve_complete_model_snapshot "$MODEL_CACHE_DIR") + if [[ -z "$MODEL_PATH" ]]; then + echo "Downloaded model snapshot is incomplete: $DOWNLOADED_MODEL_PATH" >&2 + exit 1 + fi + fi + flock -u 9 + fi + echo "Using complete cached model snapshot: $MODEL_PATH" + export MODEL_PATH +fi + +# The EAGLE3 draft is never pre-staged next to the target checkpoint; fetch it +# into the shared HF cache. That cache is a network FS where concurrent +# day-zero downloads hit huggingface_hub's WeakFileLock "[Errno 116] Stale file +# handle" race, so retry (the download resumes) as the fixed-seq-len MTP +# recipes do. +for attempt in 1 2 3 4 5; do + hf download "$DRAFT_MODEL" && break + if [ "$attempt" = 5 ]; then echo "hf download of $DRAFT_MODEL failed after $attempt attempts" >&2; exit 1; fi + echo "hf download attempt $attempt failed; retrying in 60s" >&2 + sleep 60 +done +nvidia-smi + +export WEKA_LOADER_OVERRIDE=semianalysis_cc_traces_weka_062126 +resolve_trace_source +install_agentic_deps + +export VLLM_ENGINE_READY_TIMEOUT_S=3600 +export PYTHONNOUSERSITE=1 + +SERVER_LOG="$RESULT_DIR/server.log" +ROUTER_LOG="$RESULT_DIR/router.log" +MOONCAKE_MASTER_LOG="$RESULT_DIR/mooncake_master.log" +mkdir -p "$RESULT_DIR" + +OFFLOAD_ARGS=() +if require_agentic_kv_offload_backend mooncake; then + PER_RANK_GB=$((TOTAL_CPU_DRAM_GB / TP)) + MOONCAKE_VERSION=0.3.11.post1 + agentic_pip_install --quiet --no-cache-dir --no-deps \ + --force-reinstall "mooncake-transfer-engine-cuda13==$MOONCAKE_VERSION" + python3 -c "from mooncake.store import MooncakeDistributedStore" >/dev/null + MOONCAKE_MASTER_PORT=$((PORT + 12000)) + MOONCAKE_CONFIG_PATH="$RESULT_DIR/mooncake_config.json" + cat > "$MOONCAKE_CONFIG_PATH" < "$MOONCAKE_MASTER_LOG" 2>&1 & + MOONCAKE_MASTER_PID=$! + sleep 2 + kill -0 "$MOONCAKE_MASTER_PID" + OFFLOAD_ARGS=( + --kv-transfer-config + '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both","kv_connector_extra_config":{"load_async":true}}' + ) +fi + +PARALLEL_ARGS=(--tensor-parallel-size "$TP" --data-parallel-size 1) +if [[ "$DP_ATTENTION" == "true" ]]; then + PARALLEL_ARGS=(--tensor-parallel-size 1 --data-parallel-size "$TP") +fi + +EP_ARGS=() +if (( EP_SIZE > 1 )); then + EP_ARGS=(--enable-expert-parallel) +fi + +VLLM_BACKEND_PORT="$PORT" +if [[ "$DP_ATTENTION" == "true" ]]; then + VLLM_BACKEND_PORT=$((PORT + 1)) + export AIPERF_HTTP_X_SESSION_ID_FROM_CORRELATION_ID=1 + agentic_pip_install --quiet 'vllm-router==0.1.14' +fi + +# use 3 speculative tokens for all configs, matching the MiniMax-M3 MTP recipes +NUM_SPEC_TOKENS=3 +TOKENS_PER_SEQ=$((1 + NUM_SPEC_TOKENS)) + +# AgentX pins acceptance to the committed golden AL so submissions are compared +# on system performance at a fixed acceptance target rather than on draft-head +# quality (golden_al_distribution/README.md). 2.83 is the MiniMax-M3 EAGLE3 +# curve at num_speculative_tokens=3, thinking_on +# (golden_al_distribution/minimaxm3_eagle3.yaml). The separate +# minimaxm3_eagle3_gqa.yaml curve belongs to the Inferact/MiniMax-M3-EAGLE3-GQA +# draft and is not mixed in here. +# +# EVAL_ONLY switches back to real verification: synthetic acceptance commits +# drafted tokens regardless of the target logits, so generated text is wrong and +# the eval would score ~0 (same split as dsv4_fp4_b*_vllm_mtp.sh). +SYNTHETIC_ACCEPT_LEN=2.83 +if [ "${EVAL_ONLY:-false}" = "true" ]; then + SPEC_CONFIG="{\"method\": \"eagle3\", \"model\": \"$DRAFT_MODEL\", \"num_speculative_tokens\": $NUM_SPEC_TOKENS, \"attention_backend\": \"FLASH_ATTN\"}" +else + SPEC_CONFIG="{\"method\": \"eagle3\", \"model\": \"$DRAFT_MODEL\", \"num_speculative_tokens\": $NUM_SPEC_TOKENS, \"attention_backend\": \"FLASH_ATTN\", \"rejection_sample_method\": \"synthetic\", \"synthetic_acceptance_length\": $SYNTHETIC_ACCEPT_LEN}" +fi + +# AgentX concurrency counts live session trees, not individual requests, so keep +# the non-MTP recipe's 2x scheduler headroom for subagent fan-out. +MAX_NUM_SEQS=$((2 * CONC)) +# Cudagraph capture sizes are in TOKENS: a decode batch of S sequences verifies +# S*(1+NUM_SPEC_TOKENS) tokens, so cap capture at MAX_NUM_SEQS*(1+N) or the +# FULL_DECODE_ONLY ladder tops out at MAX_NUM_SEQS/(1+N) sequences and the +# largest decode batches fall back to eager. +MAX_CUDAGRAPH_CAPTURE_SIZE=$((MAX_NUM_SEQS * TOKENS_PER_SEQ)) + +vllm serve "$MODEL_PATH" --served-model-name "$MODEL" \ + --host 0.0.0.0 \ + --port "$VLLM_BACKEND_PORT" \ + "${PARALLEL_ARGS[@]}" \ + "${EP_ARGS[@]}" \ + --gpu-memory-utilization 0.92 \ + --kv-cache-dtype fp8 \ + --attention-backend TRITON_ATTN \ + --block-size 128 \ + --language-model-only \ + --enable-prefix-caching \ + --max-num-seqs "$MAX_NUM_SEQS" \ + --max-cudagraph-capture-size "$MAX_CUDAGRAPH_CAPTURE_SIZE" \ + --speculative-config "$SPEC_CONFIG" \ + --tool-call-parser minimax_m3 \ + --reasoning-parser minimax_m3 \ + --enable-auto-tool-choice \ + --trust-remote-code \ + "${OFFLOAD_ARGS[@]}" > "$SERVER_LOG" 2>&1 & +SERVER_PID=$! + +wait_for_server_ready --port "$VLLM_BACKEND_PORT" --server-log "$SERVER_LOG" --server-pid "$SERVER_PID" + +if [[ "$DP_ATTENTION" == "true" ]]; then + vllm-router \ + --worker-urls "http://localhost:$VLLM_BACKEND_PORT" \ + --policy consistent_hash \ + --intra-node-data-parallel-size "$TP" \ + --host 0.0.0.0 \ + --port "$PORT" \ + --prometheus-host 127.0.0.1 \ + --prometheus-port "$((PORT + 10000))" \ + --request-timeout-secs 14400 \ + --disable-retries > "$ROUTER_LOG" 2>&1 & + ROUTER_PID=$! + wait_for_server_ready --port "$PORT" --server-log "$ROUTER_LOG" --server-pid "$ROUTER_PID" +fi + +if [ "${EVAL_ONLY}" = "true" ]; then + run_eval --port "$PORT" +else + build_replay_cmd "$RESULT_DIR" + run_agentic_replay_and_write_outputs "$RESULT_DIR" +fi From 316facdaedbffcece15b0d4ba0b188fa78085d26 Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 16:53:20 -0500 Subject: [PATCH 2/7] perf(h200): add MiniMax-M3 AgentX fast search --- .../agentic/minimaxm3_fp8_h200_mtp.sh | 43 +++++++++++++------ configs/nvidia-master.yaml | 21 +++++++++ 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh index ad3b6a5115..8713b738c7 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh @@ -9,8 +9,8 @@ set -x # --kv-cache-dtype fp8, TRITON_ATTN, gmu 0.92, minimax_m3 parsers, vllm-router # for DP-attention), so the spec-decode delta is readable at equal concurrency. # -# Speculative config: Inferact/MiniMax-M3-EAGLE3 draft head, 3 speculative -# tokens — the same draft/level as every merged MiniMax-M3 MTP recipe. The +# Speculative config: Inferact/MiniMax-M3-EAGLE3-GQA, 3 speculative tokens, +# and the committed thinking-on golden AL. The # drafter is pinned to FLASH_ATTN as on the other CUDA M3 MTP recipes: the # EAGLE3 head is MHA and FlashInfer only serves page size 128 through its # trtllm-gen kernel, which requires GQA/MQA. @@ -22,7 +22,7 @@ source "$(dirname "$0")/../../benchmark_lib.sh" check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION EP_SIZE DP_ATTENTION -DRAFT_MODEL="Inferact/MiniMax-M3-EAGLE3" +DRAFT_MODEL="Inferact/MiniMax-M3-EAGLE3-GQA" if [[ -n "${SLURM_JOB_ID:-}" ]]; then echo "JOB $SLURM_JOB_ID running on ${SLURMD_NODENAME:-unknown}" @@ -115,8 +115,15 @@ MOONCAKE_MASTER_LOG="$RESULT_DIR/mooncake_master.log" mkdir -p "$RESULT_DIR" OFFLOAD_ARGS=() +MODEL_CHECKPOINT_PAGE_CACHE_GIB=414 +MOONCAKE_LOCAL_BUFFER_GIB=4 if require_agentic_kv_offload_backend mooncake; then - PER_RANK_GB=$((TOTAL_CPU_DRAM_GB / TP)) + TOTAL_CPU_DRAM_GIB=$((TOTAL_CPU_DRAM_GB * 1000000000 / 1073741824)) + PER_RANK_GB=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP - MOONCAKE_LOCAL_BUFFER_GIB)) + if (( PER_RANK_GB <= 0 )); then + echo "Error: CPU DRAM budget is too small for checkpoint cache and KV offload" >&2 + exit 1 + fi MOONCAKE_VERSION=0.3.11.post1 agentic_pip_install --quiet --no-cache-dir --no-deps \ --force-reinstall "mooncake-transfer-engine-cuda13==$MOONCAKE_VERSION" @@ -166,31 +173,37 @@ if [[ "$DP_ATTENTION" == "true" ]]; then agentic_pip_install --quiet 'vllm-router==0.1.14' fi +export AIPERF_SERVER_METRICS_URLS="http://localhost:${VLLM_BACKEND_PORT}/metrics" +export AIPERF_REQUIRED_SERVER_METRIC_PREFIX="vllm:" + # use 3 speculative tokens for all configs, matching the MiniMax-M3 MTP recipes NUM_SPEC_TOKENS=3 TOKENS_PER_SEQ=$((1 + NUM_SPEC_TOKENS)) # AgentX pins acceptance to the committed golden AL so submissions are compared # on system performance at a fixed acceptance target rather than on draft-head -# quality (golden_al_distribution/README.md). 2.83 is the MiniMax-M3 EAGLE3 -# curve at num_speculative_tokens=3, thinking_on -# (golden_al_distribution/minimaxm3_eagle3.yaml). The separate -# minimaxm3_eagle3_gqa.yaml curve belongs to the Inferact/MiniMax-M3-EAGLE3-GQA -# draft and is not mixed in here. +# quality. 2.78 is minimaxm3_eagle3_gqa.yaml thinking_on[3]. # # EVAL_ONLY switches back to real verification: synthetic acceptance commits # drafted tokens regardless of the target logits, so generated text is wrong and # the eval would score ~0 (same split as dsv4_fp4_b*_vllm_mtp.sh). -SYNTHETIC_ACCEPT_LEN=2.83 +SYNTHETIC_ACCEPT_LEN=2.78 if [ "${EVAL_ONLY:-false}" = "true" ]; then SPEC_CONFIG="{\"method\": \"eagle3\", \"model\": \"$DRAFT_MODEL\", \"num_speculative_tokens\": $NUM_SPEC_TOKENS, \"attention_backend\": \"FLASH_ATTN\"}" else SPEC_CONFIG="{\"method\": \"eagle3\", \"model\": \"$DRAFT_MODEL\", \"num_speculative_tokens\": $NUM_SPEC_TOKENS, \"attention_backend\": \"FLASH_ATTN\", \"rejection_sample_method\": \"synthetic\", \"synthetic_acceptance_length\": $SYNTHETIC_ACCEPT_LEN}" fi -# AgentX concurrency counts live session trees, not individual requests, so keep -# the non-MTP recipe's 2x scheduler headroom for subagent fan-out. -MAX_NUM_SEQS=$((2 * CONC)) +# DEP distributes the live AgentX session trees across its data-parallel ranks. +if [[ "$DP_ATTENTION" == "true" ]]; then + if (( 2 * CONC % TP != 0 )); then + echo "DEP requires 2*CONC divisible by TP (CONC=$CONC TP=$TP)" >&2 + exit 1 + fi + MAX_NUM_SEQS=$((2 * CONC / TP)) +else + MAX_NUM_SEQS=$((2 * CONC)) +fi # Cudagraph capture sizes are in TOKENS: a decode batch of S sequences verifies # S*(1+NUM_SPEC_TOKENS) tokens, so cap capture at MAX_NUM_SEQS*(1+N) or the # FULL_DECODE_ONLY ladder tops out at MAX_NUM_SEQS/(1+N) sequences and the @@ -202,12 +215,14 @@ vllm serve "$MODEL_PATH" --served-model-name "$MODEL" \ --port "$VLLM_BACKEND_PORT" \ "${PARALLEL_ARGS[@]}" \ "${EP_ARGS[@]}" \ - --gpu-memory-utilization 0.92 \ + --gpu-memory-utilization 0.90 \ --kv-cache-dtype fp8 \ --attention-backend TRITON_ATTN \ --block-size 128 \ --language-model-only \ --enable-prefix-caching \ + --enable-prompt-tokens-details \ + --default-chat-template-kwargs '{"thinking_mode":"enabled"}' \ --max-num-seqs "$MAX_NUM_SEQS" \ --max-cudagraph-capture-size "$MAX_CUDAGRAPH_CAPTURE_SIZE" \ --speculative-config "$SPEC_CONFIG" \ diff --git a/configs/nvidia-master.yaml b/configs/nvidia-master.yaml index a376a9a16b..a7afb17024 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7126,6 +7126,27 @@ minimaxm3-fp8-h200-vllm-agentic: - { tp: 8, ep: 8, kv-offloading: none, conc-list: [2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20] } - { tp: 8, ep: 8, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20] } +minimaxm3-fp8-h200-vllm-agentic-mtp: + image: vllm/vllm-openai:v0.27.1 + model: MiniMaxAI/MiniMax-M3-MXFP8 + model-prefix: minimaxm3 + runner: cluster:h200-dgxc + precision: fp8 + framework: vllm + multinode: false + scenarios: + agentic-coding: + # Broad fast discovery spans TP8, TEP8, and session-routed DEP8. Mooncake + # overlaps the expected HBM knee and continues into the host-tier tail. + - dram-utilization: 0.80 + search-space: + - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 4, 6, 8, 10, 12, 14, 16, 20] } + - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 4, 6, 8, 10, 12, 14, 16, 20] } + - { tp: 8, ep: 8, dp-attn: true, spec-decoding: mtp, kv-offloading: none, conc-list: [8, 12, 16, 24, 32, 48] } + - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [8, 10, 12, 14, 16, 20, 24, 32] } + - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [8, 10, 12, 14, 16, 20, 24, 32] } + - { tp: 8, ep: 8, dp-attn: true, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [24, 32, 48, 64] } + qwen3.5-fp4-b200-sglang-agentic-mtp: image: lmsysorg/sglang:v0.5.16-cu130 model: nvidia/Qwen3.5-397B-A17B-NVFP4 From 6f7795bc99f27d82fa66e62aa837e3ee1588a9cf Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 16:55:06 -0500 Subject: [PATCH 3/7] docs(perf): document H200 MiniMax-M3 tuning --- perf-changelog.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 7ae8479441..b6297aac91 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -5794,3 +5794,13 @@ - "Keep DSpark K=2 probabilistic throughput on synthetic golden AL 2.51 while the generated EVAL_ONLY row uses real block verification" - "Cap the GPU-resident search at concurrency 8 after concurrency 16 failed to complete deterministic warmup; retain concurrency 16 for the DRAM-offload capacity tier" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2476 + +- config-keys: + - minimaxm3-fp8-h200-vllm-agentic-mtp + scenario-type: + - agentic-coding + description: + - "Add H200 MiniMax-M3 MXFP8 AgentX on vLLM v0.27.1 with EAGLE3-GQA synthetic golden AL 2.78." + - "Screen TP8, TEP8, DEP8, and Mooncake DRAM-offload curves in AgentX fast mode before the final full sweep." + - "Require vLLM server metrics and session-aware DEP routing without relaxed request thresholds." + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 From cce3900df05a385abfe6708a897532fea4892ee1 Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 21:54:22 -0500 Subject: [PATCH 4/7] perf(h200): test MiniMax-M3 vLLM-simple offload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 H200 MiniMax-M3 的拐点附近测试 vLLM SimpleCPUOffloadConnector。 --- .../single_node/agentic/minimaxm3_fp8_h200.sh | 23 +++++++++++++++++-- configs/nvidia-master.yaml | 12 ++++------ perf-changelog.yaml | 8 +++++++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h200.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h200.sh index 6b984cee03..5b9f049248 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h200.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h200.sh @@ -85,7 +85,21 @@ MOONCAKE_MASTER_LOG="$RESULT_DIR/mooncake_master.log" mkdir -p "$RESULT_DIR" OFFLOAD_ARGS=() -if require_agentic_kv_offload_backend mooncake; then +case "${KV_OFFLOAD_BACKEND:-}" in + "") + require_agentic_kv_offload_none + ;; + vllm-simple) + require_agentic_kv_offload_backend vllm-simple + CPU_BYTES_PER_RANK=$((TOTAL_CPU_DRAM_GB * 1000 * 1000 * 1000 / TP)) + export PYTHONHASHSEED=42 + OFFLOAD_ARGS=( + --kv-transfer-config + "{\"kv_connector\":\"SimpleCPUOffloadConnector\",\"kv_role\":\"kv_both\",\"kv_connector_extra_config\":{\"cpu_bytes_to_use_per_rank\":${CPU_BYTES_PER_RANK},\"lazy_offload\":false}}" + ) + ;; + mooncake) + require_agentic_kv_offload_backend mooncake PER_RANK_GB=$((TOTAL_CPU_DRAM_GB / TP)) MOONCAKE_VERSION=0.3.11.post1 agentic_pip_install --quiet --no-cache-dir --no-deps \ @@ -117,7 +131,12 @@ EOF --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both","kv_connector_extra_config":{"load_async":true}}' ) -fi + ;; + *) + echo "Error: unsupported KV_OFFLOAD_BACKEND='$KV_OFFLOAD_BACKEND'" >&2 + exit 1 + ;; +esac PARALLEL_ARGS=(--tensor-parallel-size "$TP" --data-parallel-size 1) if [[ "$DP_ATTENTION" == "true" ]]; then diff --git a/configs/nvidia-master.yaml b/configs/nvidia-master.yaml index a7afb17024..7081344e0f 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7136,16 +7136,12 @@ minimaxm3-fp8-h200-vllm-agentic-mtp: multinode: false scenarios: agentic-coding: - # Broad fast discovery spans TP8, TEP8, and session-routed DEP8. Mooncake - # overlaps the expected HBM knee and continues into the host-tier tail. + # Broad fast run 31540120459 located the TP8 knee at c10-c14. Compare the + # built-in vLLM host tier at equal concurrency before selecting the final + # full-duration Pareto sweep. - dram-utilization: 0.80 search-space: - - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 4, 6, 8, 10, 12, 14, 16, 20] } - - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 4, 6, 8, 10, 12, 14, 16, 20] } - - { tp: 8, ep: 8, dp-attn: true, spec-decoding: mtp, kv-offloading: none, conc-list: [8, 12, 16, 24, 32, 48] } - - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [8, 10, 12, 14, 16, 20, 24, 32] } - - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [8, 10, 12, 14, 16, 20, 24, 32] } - - { tp: 8, ep: 8, dp-attn: true, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [24, 32, 48, 64] } + - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [10, 12, 14, 16] } qwen3.5-fp4-b200-sglang-agentic-mtp: image: lmsysorg/sglang:v0.5.16-cu130 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index b6297aac91..2fc5902043 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -5804,3 +5804,11 @@ - "Screen TP8, TEP8, DEP8, and Mooncake DRAM-offload curves in AgentX fast mode before the final full sweep." - "Require vLLM server metrics and session-aware DEP routing without relaxed request thresholds." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 + +- config-keys: + - minimaxm3-fp8-h200-vllm-agentic-mtp + scenario-type: + - agentic-coding + description: + - "Broad fast run 31540120459 identifies the TP8 knee at c10-c14; compare vLLM-simple DRAM offload at c10/c12/c14/c16 before the final full sweep." + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 From f5c81c56483ba2b8fade8ecf52050f399b7e59ee Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 22:05:34 -0500 Subject: [PATCH 5/7] fix(h200): route MiniMax-M3 offload through MTP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 vLLM SimpleCPUOffloadConnector 配置接入实际的 MiniMax-M3 MTP 运行时,并保留检查点缓存的主机内存预算。 --- .../single_node/agentic/minimaxm3_fp8_h200.sh | 23 ++------------- .../agentic/minimaxm3_fp8_h200_mtp.sh | 29 +++++++++++++++++-- perf-changelog.yaml | 8 +++++ 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h200.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h200.sh index 5b9f049248..6b984cee03 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h200.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h200.sh @@ -85,21 +85,7 @@ MOONCAKE_MASTER_LOG="$RESULT_DIR/mooncake_master.log" mkdir -p "$RESULT_DIR" OFFLOAD_ARGS=() -case "${KV_OFFLOAD_BACKEND:-}" in - "") - require_agentic_kv_offload_none - ;; - vllm-simple) - require_agentic_kv_offload_backend vllm-simple - CPU_BYTES_PER_RANK=$((TOTAL_CPU_DRAM_GB * 1000 * 1000 * 1000 / TP)) - export PYTHONHASHSEED=42 - OFFLOAD_ARGS=( - --kv-transfer-config - "{\"kv_connector\":\"SimpleCPUOffloadConnector\",\"kv_role\":\"kv_both\",\"kv_connector_extra_config\":{\"cpu_bytes_to_use_per_rank\":${CPU_BYTES_PER_RANK},\"lazy_offload\":false}}" - ) - ;; - mooncake) - require_agentic_kv_offload_backend mooncake +if require_agentic_kv_offload_backend mooncake; then PER_RANK_GB=$((TOTAL_CPU_DRAM_GB / TP)) MOONCAKE_VERSION=0.3.11.post1 agentic_pip_install --quiet --no-cache-dir --no-deps \ @@ -131,12 +117,7 @@ EOF --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both","kv_connector_extra_config":{"load_async":true}}' ) - ;; - *) - echo "Error: unsupported KV_OFFLOAD_BACKEND='$KV_OFFLOAD_BACKEND'" >&2 - exit 1 - ;; -esac +fi PARALLEL_ARGS=(--tensor-parallel-size "$TP" --data-parallel-size 1) if [[ "$DP_ATTENTION" == "true" ]]; then diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh index 8713b738c7..6917307c76 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh @@ -117,7 +117,27 @@ mkdir -p "$RESULT_DIR" OFFLOAD_ARGS=() MODEL_CHECKPOINT_PAGE_CACHE_GIB=414 MOONCAKE_LOCAL_BUFFER_GIB=4 -if require_agentic_kv_offload_backend mooncake; then +case "${KV_OFFLOAD_BACKEND:-}" in + "") + require_agentic_kv_offload_none + ;; + vllm-simple) + require_agentic_kv_offload_backend vllm-simple + TOTAL_CPU_DRAM_GIB=$((TOTAL_CPU_DRAM_GB * 1000000000 / 1073741824)) + CPU_OFFLOAD_GIB_PER_RANK=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP)) + if (( CPU_OFFLOAD_GIB_PER_RANK <= 0 )); then + echo "Error: CPU DRAM budget is too small for checkpoint cache and KV offload" >&2 + exit 1 + fi + CPU_BYTES_PER_RANK=$((CPU_OFFLOAD_GIB_PER_RANK * 1024 * 1024 * 1024)) + export PYTHONHASHSEED=42 + OFFLOAD_ARGS=( + --kv-transfer-config + "{\"kv_connector\":\"SimpleCPUOffloadConnector\",\"kv_role\":\"kv_both\",\"kv_connector_extra_config\":{\"cpu_bytes_to_use_per_rank\":${CPU_BYTES_PER_RANK},\"lazy_offload\":false}}" + ) + ;; + mooncake) + require_agentic_kv_offload_backend mooncake TOTAL_CPU_DRAM_GIB=$((TOTAL_CPU_DRAM_GB * 1000000000 / 1073741824)) PER_RANK_GB=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP - MOONCAKE_LOCAL_BUFFER_GIB)) if (( PER_RANK_GB <= 0 )); then @@ -154,7 +174,12 @@ EOF --kv-transfer-config '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both","kv_connector_extra_config":{"load_async":true}}' ) -fi + ;; + *) + echo "Error: unsupported KV_OFFLOAD_BACKEND='$KV_OFFLOAD_BACKEND'" >&2 + exit 1 + ;; +esac PARALLEL_ARGS=(--tensor-parallel-size "$TP" --data-parallel-size 1) if [[ "$DP_ATTENTION" == "true" ]]; then diff --git a/perf-changelog.yaml b/perf-changelog.yaml index e879a58e3d..d9bf18de36 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -5836,3 +5836,11 @@ description: - "Broad fast run 31540120459 identifies the TP8 knee at c10-c14; compare vLLM-simple DRAM offload at c10/c12/c14/c16 before the final full sweep." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 + +- config-keys: + - minimaxm3-fp8-h200-vllm-agentic-mtp + scenario-type: + - agentic-coding + description: + - "Route the vLLM-simple refinement through the MiniMax-M3 MTP runtime and preserve its checkpoint-cache DRAM reservation." + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 From d621268bed643afa3e33be318481c7e37871806a Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 22:54:00 -0500 Subject: [PATCH 6/7] perf(h200): finalize MiniMax-M3 AgentX curve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 保留 TP8 常驻 c1/c2/c4/c6/c8/c10 和 Mooncake c12/c14,依据完整快速扫描形成严格全量扫点。 --- configs/nvidia-master.yaml | 10 ++++++---- perf-changelog.yaml | 8 ++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/configs/nvidia-master.yaml b/configs/nvidia-master.yaml index 57df6b0c91..9a826653a2 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7171,12 +7171,14 @@ minimaxm3-fp8-h200-vllm-agentic-mtp: multinode: false scenarios: agentic-coding: - # Broad fast run 31540120459 located the TP8 knee at c10-c14. Compare the - # built-in vLLM host tier at equal concurrency before selecting the final - # full-duration Pareto sweep. + # Fast runs 31540120459 and 31558981228 locate the resident knee at c10 + # and show Mooncake retaining throughput at c12-c14. TEP is dominated, + # DEP cannot allocate the 1M-token KV cache, and vLLM-simple falls after + # c10, so the strict sweep keeps only the measured Pareto candidates. - dram-utilization: 0.80 search-space: - - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [10, 12, 14, 16] } + - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 4, 6, 8, 10] } + - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [12, 14] } qwen3.5-fp4-b200-sglang-agentic-mtp: image: lmsysorg/sglang:v0.5.16-cu130 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index d9bf18de36..50d329c160 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -5844,3 +5844,11 @@ description: - "Route the vLLM-simple refinement through the MiniMax-M3 MTP runtime and preserve its checkpoint-cache DRAM reservation." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 + +- config-keys: + - minimaxm3-fp8-h200-vllm-agentic-mtp + scenario-type: + - agentic-coding + description: + - "Finalize the strict TP8 MTP sweep at resident c1/c2/c4/c6/c8/c10 and Mooncake c12/c14 from completed fast-run measurements." + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 From 6cd6832ff1281711c474e7d18cce08f549ffbe27 Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Wed, 12 Aug 2026 09:02:55 -0500 Subject: [PATCH 7/7] chore(h200): simplify MiniMax-M3 benchmark --- benchmarks/benchmark_lib.sh | 8 + .../agentic/minimaxm3_fp8_h200_mtp.sh | 240 ++++++------------ perf-changelog.yaml | 28 +- 3 files changed, 92 insertions(+), 184 deletions(-) diff --git a/benchmarks/benchmark_lib.sh b/benchmarks/benchmark_lib.sh index 4e2e7b7b17..d51ebece63 100644 --- a/benchmarks/benchmark_lib.sh +++ b/benchmarks/benchmark_lib.sh @@ -343,6 +343,14 @@ check_env_vars() { fi } +# Record a shell-array command in a reproducible, shell-escaped form. +write_command() { + local output_file="$1" + shift + printf '%q ' "$@" | tee "$output_file" + printf '\n' | tee -a "$output_file" +} + # Wait for server to be ready by polling the health endpoint # All parameters are required # Parameters: diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh index 6917307c76..28e7adc4a0 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h200_mtp.sh @@ -1,33 +1,15 @@ #!/usr/bin/env bash -set -euo pipefail +set -eo pipefail set -x -# MiniMax-M3 MXFP8 H200 AgentX (agentic-coding) recipe with EAGLE3 speculative -# decoding — the spec-decoding=mtp variant of agentic/minimaxm3_fp8_h200.sh. -# Everything outside the speculative block mirrors the non-MTP agentic sibling -# (Mooncake host-DRAM KV offload, --block-size 128, --language-model-only, -# --kv-cache-dtype fp8, TRITON_ATTN, gmu 0.92, minimax_m3 parsers, vllm-router -# for DP-attention), so the spec-decode delta is readable at equal concurrency. -# -# Speculative config: Inferact/MiniMax-M3-EAGLE3-GQA, 3 speculative tokens, -# and the committed thinking-on golden AL. The -# drafter is pinned to FLASH_ATTN as on the other CUDA M3 MTP recipes: the -# EAGLE3 head is MHA and FlashInfer only serves page size 128 through its -# trtllm-gen kernel, which requires GQA/MQA. -# -# Throughput runs pin synthetic acceptance to the committed golden AL; the -# EVAL_ONLY accuracy run keeps real target verification. See SYNTHETIC_ACCEPT_LEN. +# H200 MiniMax-M3 MXFP8 AgentX with EAGLE3 and optional Mooncake DRAM KV offload. source "$(dirname "$0")/../../benchmark_lib.sh" -check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION EP_SIZE DP_ATTENTION +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" -if [[ -n "${SLURM_JOB_ID:-}" ]]; then - echo "JOB $SLURM_JOB_ID running on ${SLURMD_NODENAME:-unknown}" -fi - resolve_complete_model_snapshot() { python3 - "$1" <<'PY' import json @@ -89,11 +71,7 @@ else export MODEL_PATH fi -# The EAGLE3 draft is never pre-staged next to the target checkpoint; fetch it -# into the shared HF cache. That cache is a network FS where concurrent -# day-zero downloads hit huggingface_hub's WeakFileLock "[Errno 116] Stale file -# handle" race, so retry (the download resumes) as the fixed-seq-len MTP -# recipes do. +# Concurrent downloads on the shared HF cache can hit transient stale handles. for attempt in 1 2 3 4 5; do hf download "$DRAFT_MODEL" && break if [ "$attempt" = 5 ]; then echo "hf download of $DRAFT_MODEL failed after $attempt attempts" >&2; exit 1; fi @@ -110,47 +88,43 @@ export VLLM_ENGINE_READY_TIMEOUT_S=3600 export PYTHONNOUSERSITE=1 SERVER_LOG="$RESULT_DIR/server.log" -ROUTER_LOG="$RESULT_DIR/router.log" MOONCAKE_MASTER_LOG="$RESULT_DIR/mooncake_master.log" mkdir -p "$RESULT_DIR" +SERVER_PID="" +MOONCAKE_MASTER_PID="" +cleanup_services() { + local exit_code=$? + trap - EXIT INT TERM + set +e + stop_background_process_tree "$SERVER_PID" "vLLM server" 60 + stop_background_process_tree "$MOONCAKE_MASTER_PID" "Mooncake master" 30 + exit "$exit_code" +} +trap cleanup_services EXIT +trap 'exit 130' INT +trap 'exit 143' TERM + OFFLOAD_ARGS=() MODEL_CHECKPOINT_PAGE_CACHE_GIB=414 MOONCAKE_LOCAL_BUFFER_GIB=4 -case "${KV_OFFLOAD_BACKEND:-}" in - "") - require_agentic_kv_offload_none - ;; - vllm-simple) - require_agentic_kv_offload_backend vllm-simple - TOTAL_CPU_DRAM_GIB=$((TOTAL_CPU_DRAM_GB * 1000000000 / 1073741824)) - CPU_OFFLOAD_GIB_PER_RANK=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP)) - if (( CPU_OFFLOAD_GIB_PER_RANK <= 0 )); then - echo "Error: CPU DRAM budget is too small for checkpoint cache and KV offload" >&2 - exit 1 - fi - CPU_BYTES_PER_RANK=$((CPU_OFFLOAD_GIB_PER_RANK * 1024 * 1024 * 1024)) - export PYTHONHASHSEED=42 - OFFLOAD_ARGS=( - --kv-transfer-config - "{\"kv_connector\":\"SimpleCPUOffloadConnector\",\"kv_role\":\"kv_both\",\"kv_connector_extra_config\":{\"cpu_bytes_to_use_per_rank\":${CPU_BYTES_PER_RANK},\"lazy_offload\":false}}" - ) - ;; - mooncake) - require_agentic_kv_offload_backend mooncake - TOTAL_CPU_DRAM_GIB=$((TOTAL_CPU_DRAM_GB * 1000000000 / 1073741824)) - PER_RANK_GB=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP - MOONCAKE_LOCAL_BUFFER_GIB)) - if (( PER_RANK_GB <= 0 )); then - echo "Error: CPU DRAM budget is too small for checkpoint cache and KV offload" >&2 - exit 1 - fi - MOONCAKE_VERSION=0.3.11.post1 - agentic_pip_install --quiet --no-cache-dir --no-deps \ - --force-reinstall "mooncake-transfer-engine-cuda13==$MOONCAKE_VERSION" - python3 -c "from mooncake.store import MooncakeDistributedStore" >/dev/null - MOONCAKE_MASTER_PORT=$((PORT + 12000)) - MOONCAKE_CONFIG_PATH="$RESULT_DIR/mooncake_config.json" - cat > "$MOONCAKE_CONFIG_PATH" <&2 + exit 1 + fi + MOONCAKE_VERSION=0.3.11.post1 + agentic_pip_install --quiet --no-cache-dir --no-deps \ + --force-reinstall "mooncake-transfer-engine-cuda13==$MOONCAKE_VERSION" + python3 -c "from mooncake.store import MooncakeDistributedStore" >/dev/null + MOONCAKE_MASTER_PORT=$((PORT + 12000)) + MOONCAKE_CONFIG_PATH="$RESULT_DIR/mooncake_config.json" + cat > "$MOONCAKE_CONFIG_PATH" < "$MOONCAKE_MASTER_LOG" 2>&1 & - MOONCAKE_MASTER_PID=$! - sleep 2 - kill -0 "$MOONCAKE_MASTER_PID" - OFFLOAD_ARGS=( - --kv-transfer-config - '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both","kv_connector_extra_config":{"load_async":true}}' - ) - ;; - *) - echo "Error: unsupported KV_OFFLOAD_BACKEND='$KV_OFFLOAD_BACKEND'" >&2 - exit 1 - ;; -esac - -PARALLEL_ARGS=(--tensor-parallel-size "$TP" --data-parallel-size 1) -if [[ "$DP_ATTENTION" == "true" ]]; then - PARALLEL_ARGS=(--tensor-parallel-size 1 --data-parallel-size "$TP") -fi - -EP_ARGS=() -if (( EP_SIZE > 1 )); then - EP_ARGS=(--enable-expert-parallel) -fi - -VLLM_BACKEND_PORT="$PORT" -if [[ "$DP_ATTENTION" == "true" ]]; then - VLLM_BACKEND_PORT=$((PORT + 1)) - export AIPERF_HTTP_X_SESSION_ID_FROM_CORRELATION_ID=1 - agentic_pip_install --quiet 'vllm-router==0.1.14' + export MOONCAKE_CONFIG_PATH PYTHONHASHSEED=0 MC_SLICE_SIZE=1048576 MC_WORKERS_PER_CTX=4 + export MC_ENABLE_DEST_DEVICE_AFFINITY=1 + mooncake_master --port "$MOONCAKE_MASTER_PORT" \ + --eviction_high_watermark_ratio=0.80 \ + --eviction_ratio=0.10 > "$MOONCAKE_MASTER_LOG" 2>&1 & + MOONCAKE_MASTER_PID=$! + sleep 2 + kill -0 "$MOONCAKE_MASTER_PID" + OFFLOAD_ARGS=( + --kv-transfer-config + '{"kv_connector":"MooncakeStoreConnector","kv_role":"kv_both","kv_connector_extra_config":{"load_async":true}}' + ) +else + echo "Error: unsupported KV_OFFLOADING='$KV_OFFLOADING'" >&2 + exit 1 fi -export AIPERF_SERVER_METRICS_URLS="http://localhost:${VLLM_BACKEND_PORT}/metrics" +export AIPERF_SERVER_METRICS_URLS="http://localhost:${PORT}/metrics" export AIPERF_REQUIRED_SERVER_METRIC_PREFIX="vllm:" -# use 3 speculative tokens for all configs, matching the MiniMax-M3 MTP recipes NUM_SPEC_TOKENS=3 TOKENS_PER_SEQ=$((1 + NUM_SPEC_TOKENS)) -# AgentX pins acceptance to the committed golden AL so submissions are compared -# on system performance at a fixed acceptance target rather than on draft-head -# quality. 2.78 is minimaxm3_eagle3_gqa.yaml thinking_on[3]. -# -# EVAL_ONLY switches back to real verification: synthetic acceptance commits -# drafted tokens regardless of the target logits, so generated text is wrong and -# the eval would score ~0 (same split as dsv4_fp4_b*_vllm_mtp.sh). +# Golden AL is minimaxm3_eagle3_gqa.yaml thinking_on[3]; eval uses real verification. SYNTHETIC_ACCEPT_LEN=2.78 -if [ "${EVAL_ONLY:-false}" = "true" ]; then +if [ "$EVAL_ONLY" = "true" ]; then SPEC_CONFIG="{\"method\": \"eagle3\", \"model\": \"$DRAFT_MODEL\", \"num_speculative_tokens\": $NUM_SPEC_TOKENS, \"attention_backend\": \"FLASH_ATTN\"}" else SPEC_CONFIG="{\"method\": \"eagle3\", \"model\": \"$DRAFT_MODEL\", \"num_speculative_tokens\": $NUM_SPEC_TOKENS, \"attention_backend\": \"FLASH_ATTN\", \"rejection_sample_method\": \"synthetic\", \"synthetic_acceptance_length\": $SYNTHETIC_ACCEPT_LEN}" fi -# DEP distributes the live AgentX session trees across its data-parallel ranks. -if [[ "$DP_ATTENTION" == "true" ]]; then - if (( 2 * CONC % TP != 0 )); then - echo "DEP requires 2*CONC divisible by TP (CONC=$CONC TP=$TP)" >&2 - exit 1 - fi - MAX_NUM_SEQS=$((2 * CONC / TP)) -else - MAX_NUM_SEQS=$((2 * CONC)) -fi -# Cudagraph capture sizes are in TOKENS: a decode batch of S sequences verifies -# S*(1+NUM_SPEC_TOKENS) tokens, so cap capture at MAX_NUM_SEQS*(1+N) or the -# FULL_DECODE_ONLY ladder tops out at MAX_NUM_SEQS/(1+N) sequences and the -# largest decode batches fall back to eager. +MAX_NUM_SEQS=$((2 * CONC)) +# MTP verifies four tokens per sequence, so CUDA graph capture is token-sized. MAX_CUDAGRAPH_CAPTURE_SIZE=$((MAX_NUM_SEQS * TOKENS_PER_SEQ)) -vllm serve "$MODEL_PATH" --served-model-name "$MODEL" \ - --host 0.0.0.0 \ - --port "$VLLM_BACKEND_PORT" \ - "${PARALLEL_ARGS[@]}" \ - "${EP_ARGS[@]}" \ - --gpu-memory-utilization 0.90 \ - --kv-cache-dtype fp8 \ - --attention-backend TRITON_ATTN \ - --block-size 128 \ - --language-model-only \ - --enable-prefix-caching \ - --enable-prompt-tokens-details \ - --default-chat-template-kwargs '{"thinking_mode":"enabled"}' \ - --max-num-seqs "$MAX_NUM_SEQS" \ - --max-cudagraph-capture-size "$MAX_CUDAGRAPH_CAPTURE_SIZE" \ - --speculative-config "$SPEC_CONFIG" \ - --tool-call-parser minimax_m3 \ - --reasoning-parser minimax_m3 \ - --enable-auto-tool-choice \ - --trust-remote-code \ - "${OFFLOAD_ARGS[@]}" > "$SERVER_LOG" 2>&1 & +VLLM_CMD=( + vllm serve "$MODEL_PATH" + --served-model-name "$MODEL" + --host 0.0.0.0 + --port "$PORT" + --tensor-parallel-size "$TP" + --data-parallel-size 1 + --gpu-memory-utilization 0.90 + --kv-cache-dtype fp8 + --attention-backend TRITON_ATTN + --block-size 128 + --language-model-only + --enable-prefix-caching + --enable-prompt-tokens-details + --default-chat-template-kwargs '{"thinking_mode":"enabled"}' + --max-num-seqs "$MAX_NUM_SEQS" + --max-cudagraph-capture-size "$MAX_CUDAGRAPH_CAPTURE_SIZE" + --speculative-config "$SPEC_CONFIG" + --tool-call-parser minimax_m3 + --reasoning-parser minimax_m3 + --enable-auto-tool-choice + --trust-remote-code + "${OFFLOAD_ARGS[@]}" +) +write_command "$RESULT_DIR/vllm_command.txt" "${VLLM_CMD[@]}" +"${VLLM_CMD[@]}" > "$SERVER_LOG" 2>&1 & SERVER_PID=$! -wait_for_server_ready --port "$VLLM_BACKEND_PORT" --server-log "$SERVER_LOG" --server-pid "$SERVER_PID" - -if [[ "$DP_ATTENTION" == "true" ]]; then - vllm-router \ - --worker-urls "http://localhost:$VLLM_BACKEND_PORT" \ - --policy consistent_hash \ - --intra-node-data-parallel-size "$TP" \ - --host 0.0.0.0 \ - --port "$PORT" \ - --prometheus-host 127.0.0.1 \ - --prometheus-port "$((PORT + 10000))" \ - --request-timeout-secs 14400 \ - --disable-retries > "$ROUTER_LOG" 2>&1 & - ROUTER_PID=$! - wait_for_server_ready --port "$PORT" --server-log "$ROUTER_LOG" --server-pid "$ROUTER_PID" -fi +wait_for_server_ready --port "$PORT" --server-log "$SERVER_LOG" --server-pid "$SERVER_PID" -if [ "${EVAL_ONLY}" = "true" ]; then +if [ "$EVAL_ONLY" = "true" ]; then run_eval --port "$PORT" else build_replay_cmd "$RESULT_DIR" diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 50d329c160..a80a48f248 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -5824,31 +5824,5 @@ scenario-type: - agentic-coding description: - - "Add H200 MiniMax-M3 MXFP8 AgentX on vLLM v0.27.1 with EAGLE3-GQA synthetic golden AL 2.78." - - "Screen TP8, TEP8, DEP8, and Mooncake DRAM-offload curves in AgentX fast mode before the final full sweep." - - "Require vLLM server metrics and session-aware DEP routing without relaxed request thresholds." - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 - -- config-keys: - - minimaxm3-fp8-h200-vllm-agentic-mtp - scenario-type: - - agentic-coding - description: - - "Broad fast run 31540120459 identifies the TP8 knee at c10-c14; compare vLLM-simple DRAM offload at c10/c12/c14/c16 before the final full sweep." - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 - -- config-keys: - - minimaxm3-fp8-h200-vllm-agentic-mtp - scenario-type: - - agentic-coding - description: - - "Route the vLLM-simple refinement through the MiniMax-M3 MTP runtime and preserve its checkpoint-cache DRAM reservation." - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565 - -- config-keys: - - minimaxm3-fp8-h200-vllm-agentic-mtp - scenario-type: - - agentic-coding - description: - - "Finalize the strict TP8 MTP sweep at resident c1/c2/c4/c6/c8/c10 and Mooncake c12/c14 from completed fast-run measurements." + - "Add MiniMax-M3 MXFP8 AgentX on H200 with vLLM v0.27.1, EAGLE3 golden AL 2.78, resident TP8 c1/c2/c4/c6/c8/c10, and Mooncake DRAM offload c12/c14." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2565