From 04325a693344c7d4fdde0791027af9686214bc36 Mon Sep 17 00:00:00 2001 From: functionstackx <47992694+functionstackx@users.noreply.github.com> Date: Thu, 30 Jul 2026 01:07:54 -0400 Subject: [PATCH 1/8] feat(minimaxm3-h100-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-h100-vllm-agentic-mtp, the spec-decoding=mtp variant of the MiniMax-M3 MXFP8 H100 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-h100-vllm-agentic-mtp,即 MiniMax-M3 MXFP8 H100 智能体 编码配方的投机解码(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_h100_mtp.sh | 205 ++++++++++++++++++ configs/nvidia-master.yaml | 26 +++ 2 files changed, 231 insertions(+) create mode 100755 benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh new file mode 100755 index 0000000000..0b42fe80b7 --- /dev/null +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh @@ -0,0 +1,205 @@ +#!/usr/bin/env bash +set -euo pipefail +set -x + +# MiniMax-M3 MXFP8 H100 AgentX (agentic-coding) recipe with EAGLE3 speculative +# decoding — the spec-decoding=mtp variant of agentic/minimaxm3_fp8_h100.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, 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 every merged MiniMax-M3 MTP recipe uses +# (fixed_seq_len/minimaxm3_fp8_{h100,h200,mi300x,mi325x}_mtp.sh). +# +# The drafter is pinned to FLASH_ATTN, as on every CUDA MiniMax-M3 MTP recipe: +# the EAGLE3 head is MHA and FlashInfer only serves page size 128 through its +# trtllm-gen kernel, which requires GQA/MQA. FLASH_ATTN accepts any +# multiple-of-16 block size, so the mandatory 128 is fine for the draft. (The +# ROCm recipes need no pin because their server runs TRITON_ATTN throughout.) +# +# 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 + +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 + hf download "$MODEL" + export MODEL_PATH="$MODEL" +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=() +MODEL_CPU_OFFLOAD_GB=26 +MODEL_CHECKPOINT_PAGE_CACHE_GIB=414 +MOONCAKE_LOCAL_BUFFER_GIB=4 +if require_agentic_kv_offload_backend mooncake; then + TOTAL_CPU_DRAM_GIB=$((TOTAL_CPU_DRAM_GB * 1000000000 / 1073741824)) + PER_RANK_GIB=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP - MODEL_CPU_OFFLOAD_GB - MOONCAKE_LOCAL_BUFFER_GIB)) + if (( PER_RANK_GIB <= 0 )); then + echo "Error: CPU DRAM budget is too small for checkpoint cache, model, 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" < "$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.95 \ + --cpu-offload-gb "$MODEL_CPU_OFFLOAD_GB" \ + --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 \ + --safetensors-load-strategy lazy \ + --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 diff --git a/configs/nvidia-master.yaml b/configs/nvidia-master.yaml index a376a9a16b..6bd360121e 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7106,6 +7106,32 @@ minimaxm3-fp8-h100-vllm-agentic: - { tp: 8, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16] } - { tp: 8, ep: 8, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16] } +# EAGLE3 speculative-decoding (spec-decoding: mtp) variant of +# minimaxm3-fp8-h100-vllm-agentic, pairing MiniMaxAI/MiniMax-M3-MXFP8 with the +# Inferact/MiniMax-M3-EAGLE3 draft head (3 speculative tokens, FLASH_ATTN +# drafter) and pinning synthetic acceptance to the golden AL 2.83 +# (golden_al_distribution/minimaxm3_eagle3.yaml, thinking_on, K=3). Same TP8-only +# layout and KV arms as the non-MTP entry so the spec-decode delta is readable at +# equal concurrency, trimmed at the extreme-conc end: the draft head plus its KV +# eat into the same HBM budget that already puts the GPU-resident cliff near +# conc 6 on 80 GB H100s. +minimaxm3-fp8-h100-vllm-agentic-mtp: + image: vllm/vllm-openai:nightly-04c2a8deac44fdb1ca3e2b5ec3e6bf16f3f6a914 + model: MiniMaxAI/MiniMax-M3-MXFP8 + model-prefix: minimaxm3 + runner: cluster:h100-dgxc + precision: fp8 + framework: vllm + multinode: false + scenarios: + agentic-coding: + - dram-utilization: 0.80 + search-space: + - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] } + - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] } + - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [3, 4, 5, 6, 7, 8, 9, 10, 12, 14] } + - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [3, 4, 5, 6, 7, 8, 9, 10, 12, 14] } + minimaxm3-fp8-h200-vllm-agentic: image: vllm/vllm-openai:nightly-04c2a8deac44fdb1ca3e2b5ec3e6bf16f3f6a914 model: MiniMaxAI/MiniMax-M3-MXFP8 From 56c8745ac1464c85500111a570f7186ecceceb45 Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 16:53:20 -0500 Subject: [PATCH 2/8] perf(h100): broaden MiniMax-M3 AgentX fast search --- .../agentic/minimaxm3_fp8_h100_mtp.sh | 38 ++++++++++++------- configs/nvidia-master.yaml | 15 +++++--- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh index 0b42fe80b7..94adccfad6 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh @@ -9,9 +9,8 @@ set -x # --kv-cache-dtype fp8, TRITON_ATTN, 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 every merged MiniMax-M3 MTP recipe uses -# (fixed_seq_len/minimaxm3_fp8_{h100,h200,mi300x,mi325x}_mtp.sh). +# Speculative config: the current Inferact/MiniMax-M3-EAGLE3-GQA draft head +# with three speculative tokens and the committed thinking-on golden AL. # # The drafter is pinned to FLASH_ATTN, as on every CUDA MiniMax-M3 MTP recipe: # the EAGLE3 head is MHA and FlashInfer only serves page size 128 through its @@ -26,7 +25,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}" @@ -126,31 +125,40 @@ if [[ "$DP_ATTENTION" == "true" ]]; then agentic_pip_install --quiet 'vllm-router==0.1.14' fi +# The public endpoint is the router for DEP, so explicitly scrape the engine +# endpoint. Pure TP/TEP deduplicates this URL against the automatic scrape. +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)) +# AgentX concurrency counts live session trees, not individual requests. DEP +# splits those trees across eight data-parallel ranks; TP/TEP keeps them local. +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 @@ -162,13 +170,15 @@ vllm serve "$MODEL_PATH" --served-model-name "$MODEL" \ --port "$VLLM_BACKEND_PORT" \ "${PARALLEL_ARGS[@]}" \ "${EP_ARGS[@]}" \ - --gpu-memory-utilization 0.95 \ + --gpu-memory-utilization 0.90 \ --cpu-offload-gb "$MODEL_CPU_OFFLOAD_GB" \ --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 6bd360121e..5df8537d22 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7116,7 +7116,7 @@ minimaxm3-fp8-h100-vllm-agentic: # eat into the same HBM budget that already puts the GPU-resident cliff near # conc 6 on 80 GB H100s. minimaxm3-fp8-h100-vllm-agentic-mtp: - image: vllm/vllm-openai:nightly-04c2a8deac44fdb1ca3e2b5ec3e6bf16f3f6a914 + image: vllm/vllm-openai:v0.27.1 model: MiniMaxAI/MiniMax-M3-MXFP8 model-prefix: minimaxm3 runner: cluster:h100-dgxc @@ -7125,12 +7125,17 @@ minimaxm3-fp8-h100-vllm-agentic-mtp: multinode: false scenarios: agentic-coding: + # Fast discovery covers latency-oriented TP8, expert-parallel TEP8, and + # session-routed DEP8. Mooncake starts before the tight H100 HBM knee and + # extends each viable topology far enough to expose its host-tier tail. - dram-utilization: 0.80 search-space: - - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] } - - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12] } - - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [3, 4, 5, 6, 7, 8, 9, 10, 12, 14] } - - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [3, 4, 5, 6, 7, 8, 9, 10, 12, 14] } + - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5, 6, 8, 10] } + - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5, 6, 8, 10] } + - { tp: 8, ep: 8, dp-attn: true, spec-decoding: mtp, kv-offloading: none, conc-list: [8, 12, 16, 24, 32] } + - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [2, 4, 6, 8, 10, 12, 16] } + - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [2, 4, 6, 8, 10, 12, 16] } + - { 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: [16, 24, 32] } minimaxm3-fp8-h200-vllm-agentic: image: vllm/vllm-openai:nightly-04c2a8deac44fdb1ca3e2b5ec3e6bf16f3f6a914 From 996b7213751b946364dbc6447af34c1cf85bbc1f Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 16:55:06 -0500 Subject: [PATCH 3/8] docs(perf): document H100 MiniMax-M3 tuning --- perf-changelog.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 7ae8479441..4b455aec50 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-h100-vllm-agentic-mtp + scenario-type: + - agentic-coding + description: + - "Refresh H100 MiniMax-M3 MXFP8 AgentX with vLLM v0.27.1 and 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/2564 From 58103d89237ae72ed0753d6b7ac3f0efe2fccf0d Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 22:00:38 -0500 Subject: [PATCH 4/8] perf(h100): refine MiniMax-M3 offload search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 恢复基础设施丢失点,并在 H100 MiniMax-M3 拐点附近测试 vLLM SimpleCPUOffloadConnector。 --- .../single_node/agentic/minimaxm3_fp8_h100.sh | 29 +++++++++++++++++-- configs/nvidia-master.yaml | 17 +++++------ perf-changelog.yaml | 8 +++++ 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h100.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h100.sh index c5ab50b37f..643cce67e9 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h100.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h100.sh @@ -36,7 +36,27 @@ OFFLOAD_ARGS=() MODEL_CPU_OFFLOAD_GB=26 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 - MODEL_CPU_OFFLOAD_GB)) + if (( CPU_OFFLOAD_GIB_PER_RANK <= 0 )); then + echo "Error: CPU DRAM budget is too small for checkpoint cache, model, 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_GIB=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP - MODEL_CPU_OFFLOAD_GB - MOONCAKE_LOCAL_BUFFER_GIB)) if (( PER_RANK_GIB <= 0 )); then @@ -73,7 +93,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 5df8537d22..37880fb8fd 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7125,17 +7125,16 @@ minimaxm3-fp8-h100-vllm-agentic-mtp: multinode: false scenarios: agentic-coding: - # Fast discovery covers latency-oriented TP8, expert-parallel TEP8, and - # session-routed DEP8. Mooncake starts before the tight H100 HBM knee and - # extends each viable topology far enough to expose its host-tier tail. + # Recover the six points lost to one node's NVML failure in broad fast run + # 31540120174, and compare vLLM's built-in host tier around the H100 knee. + # DEP is omitted here because four independent points already proved that + # its native 1M-token KV allocation cannot fit on 80 GB H100s. - dram-utilization: 0.80 search-space: - - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5, 6, 8, 10] } - - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5, 6, 8, 10] } - - { tp: 8, ep: 8, dp-attn: true, spec-decoding: mtp, kv-offloading: none, conc-list: [8, 12, 16, 24, 32] } - - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [2, 4, 6, 8, 10, 12, 16] } - - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [2, 4, 6, 8, 10, 12, 16] } - - { 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: [16, 24, 32] } + - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [2] } + - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [2, 4, 5] } + - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [10, 16] } + - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [4, 6, 8, 10] } minimaxm3-fp8-h200-vllm-agentic: image: vllm/vllm-openai:nightly-04c2a8deac44fdb1ca3e2b5ec3e6bf16f3f6a914 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 4b455aec50..e327b5f899 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/2564 + +- config-keys: + - minimaxm3-fp8-h100-vllm-agentic-mtp + scenario-type: + - agentic-coding + description: + - "Recover six broad-search points lost to one node's NVML failure and compare TP8 vLLM-simple DRAM offload at c4/c6/c8/c10." + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2564 From 48ce187c26c5d1560d4cb4f23e7ff1438f37850e Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Tue, 11 Aug 2026 22:32:31 -0500 Subject: [PATCH 5/8] fix(h100): 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 运行时,按检查点与模型预留计算主机内存,并排除已确认 NVML 故障的 H100 节点。 --- .../single_node/agentic/minimaxm3_fp8_h100.sh | 29 ++----------------- .../agentic/minimaxm3_fp8_h100_mtp.sh | 29 +++++++++++++++++-- configs/nvidia-master.yaml | 10 ++----- perf-changelog.yaml | 8 +++++ runners/launch_h100-dgxc-slurm.sh | 9 +++++- 5 files changed, 48 insertions(+), 37 deletions(-) diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h100.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h100.sh index 643cce67e9..c5ab50b37f 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h100.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h100.sh @@ -36,27 +36,7 @@ OFFLOAD_ARGS=() MODEL_CPU_OFFLOAD_GB=26 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 - MODEL_CPU_OFFLOAD_GB)) - if (( CPU_OFFLOAD_GIB_PER_RANK <= 0 )); then - echo "Error: CPU DRAM budget is too small for checkpoint cache, model, 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 +if require_agentic_kv_offload_backend mooncake; then TOTAL_CPU_DRAM_GIB=$((TOTAL_CPU_DRAM_GB * 1000000000 / 1073741824)) PER_RANK_GIB=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP - MODEL_CPU_OFFLOAD_GB - MOONCAKE_LOCAL_BUFFER_GIB)) if (( PER_RANK_GIB <= 0 )); then @@ -93,12 +73,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_h100_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh index 94adccfad6..e203d1bff0 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh @@ -69,7 +69,27 @@ OFFLOAD_ARGS=() MODEL_CPU_OFFLOAD_GB=26 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 - MODEL_CPU_OFFLOAD_GB)) + if (( CPU_OFFLOAD_GIB_PER_RANK <= 0 )); then + echo "Error: CPU DRAM budget is too small for checkpoint cache, model, 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_GIB=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP - MODEL_CPU_OFFLOAD_GB - MOONCAKE_LOCAL_BUFFER_GIB)) if (( PER_RANK_GIB <= 0 )); then @@ -106,7 +126,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 85f49e4d03..439276cef4 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7160,15 +7160,11 @@ minimaxm3-fp8-h100-vllm-agentic-mtp: multinode: false scenarios: agentic-coding: - # Recover the six points lost to one node's NVML failure in broad fast run - # 31540120174, and compare vLLM's built-in host tier around the H100 knee. - # DEP is omitted here because four independent points already proved that - # its native 1M-token KV allocation cannot fit on 80 GB H100s. + # Compare vLLM's built-in host tier around the H100 knee. DEP is omitted + # because four independent points proved that its native 1M-token KV + # allocation cannot fit on 80 GB H100s. - dram-utilization: 0.80 search-space: - - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [2] } - - { tp: 8, ep: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [2, 4, 5] } - - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [10, 16] } - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [4, 6, 8, 10] } minimaxm3-fp8-h200-vllm-agentic: diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 18f45ae5a7..560ce04f09 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -5836,3 +5836,11 @@ description: - "Recover six broad-search points lost to one node's NVML failure and compare TP8 vLLM-simple DRAM offload at c4/c6/c8/c10." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2564 + +- config-keys: + - minimaxm3-fp8-h100-vllm-agentic-mtp + scenario-type: + - agentic-coding + description: + - "Route vLLM-simple through the MTP launcher and exclude the H100 node with a confirmed NVML device fault." + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2564 diff --git a/runners/launch_h100-dgxc-slurm.sh b/runners/launch_h100-dgxc-slurm.sh index 1334c95542..92fa067be6 100644 --- a/runners/launch_h100-dgxc-slurm.sh +++ b/runners/launch_h100-dgxc-slurm.sh @@ -4,6 +4,7 @@ set -e # System-specific configuration for H100 DGXC Slurm cluster SLURM_PARTITION="hpc-gpu-1" SLURM_ACCOUNT="customer" +H100_SLURM_EXCLUDED_NODELIST="${H100_SLURM_EXCLUDED_NODELIST-hpc-gpu-1-8}" # Route spec-decoding=mtp configs to the _mtp benchmark script (parity with # the h200 launchers, which have carried SPEC_SUFFIX since #392). @@ -289,7 +290,13 @@ else export GPU_COUNT="${GPU_COUNT:-${TP:?TP must be set}}" - salloc --partition=$SLURM_PARTITION --account=$SLURM_ACCOUNT --gres=gpu:$GPU_COUNT --exclusive --time=180 --no-shell --job-name="$RUNNER_NAME" + SALLOC_EXCLUDE_ARGS=() + if [[ -n "$H100_SLURM_EXCLUDED_NODELIST" ]]; then + SALLOC_EXCLUDE_ARGS=(--exclude="$H100_SLURM_EXCLUDED_NODELIST") + echo "Excluding H100 nodes: $H100_SLURM_EXCLUDED_NODELIST" + fi + + salloc --partition=$SLURM_PARTITION --account=$SLURM_ACCOUNT --gres=gpu:$GPU_COUNT --exclusive --time=180 --no-shell --job-name="$RUNNER_NAME" "${SALLOC_EXCLUDE_ARGS[@]}" JOB_ID=$(squeue --name="$RUNNER_NAME" -u "$USER" -h -o %A | head -n1) if [[ -z "$JOB_ID" ]]; then echo "ERROR: failed to resolve H100 Slurm allocation" >&2 From 6058da49557ef86fe8fbdc2ec85fc7acf5dbd8da Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Wed, 12 Aug 2026 01:39:37 -0500 Subject: [PATCH 6/8] docs(h100): correct MiniMax EAGLE3 metadata --- configs/nvidia-master.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/nvidia-master.yaml b/configs/nvidia-master.yaml index 439276cef4..80e6c7979d 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7143,9 +7143,9 @@ minimaxm3-fp8-h100-vllm-agentic: # EAGLE3 speculative-decoding (spec-decoding: mtp) variant of # minimaxm3-fp8-h100-vllm-agentic, pairing MiniMaxAI/MiniMax-M3-MXFP8 with the -# Inferact/MiniMax-M3-EAGLE3 draft head (3 speculative tokens, FLASH_ATTN -# drafter) and pinning synthetic acceptance to the golden AL 2.83 -# (golden_al_distribution/minimaxm3_eagle3.yaml, thinking_on, K=3). Same TP8-only +# Inferact/MiniMax-M3-EAGLE3-GQA draft head (3 speculative tokens, FLASH_ATTN +# drafter) and pinning synthetic acceptance to the golden AL 2.78 +# (golden_al_distribution/minimaxm3_eagle3_gqa.yaml, thinking_on, K=3). Same TP8-only # layout and KV arms as the non-MTP entry so the spec-decode delta is readable at # equal concurrency, trimmed at the extreme-conc end: the draft head plus its KV # eat into the same HBM budget that already puts the GPU-resident cliff near From 51d533910984bc152e3732b1d47a8b4f69296c75 Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Wed, 12 Aug 2026 02:09:18 -0500 Subject: [PATCH 7/8] perf(h100): select MiniMax-M3 strict frontier --- .../agentic/minimaxm3_fp8_h100_mtp.sh | 15 -------------- configs/nvidia-master.yaml | 11 ++++++---- perf-changelog.yaml | 20 ++----------------- runners/launch_h100-dgxc-slurm.sh | 9 +-------- 4 files changed, 10 insertions(+), 45 deletions(-) diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh index e203d1bff0..3518a85a70 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh @@ -73,21 +73,6 @@ 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 - MODEL_CPU_OFFLOAD_GB)) - if (( CPU_OFFLOAD_GIB_PER_RANK <= 0 )); then - echo "Error: CPU DRAM budget is too small for checkpoint cache, model, 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)) diff --git a/configs/nvidia-master.yaml b/configs/nvidia-master.yaml index 80e6c7979d..51c853352b 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7160,12 +7160,15 @@ minimaxm3-fp8-h100-vllm-agentic-mtp: multinode: false scenarios: agentic-coding: - # Compare vLLM's built-in host tier around the H100 knee. DEP is omitted - # because four independent points proved that its native 1M-token KV - # allocation cannot fit on 80 GB H100s. + # The complete fast sweep places the GPU-resident cliff between c5 and c6. + # Retain the resident latency/knee curve through c5, then use Mooncake at + # c6/c8 to extend throughput without crossing that HBM cliff. TEP was + # dominated, DEP could not allocate its 1M-token KV cache on 80 GB H100s, + # and the vLLM-simple function screen did not justify a frontier row. - dram-utilization: 0.80 search-space: - - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: vllm-simple }, conc-list: [4, 6, 8, 10] } + - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5] } + - { tp: 8, spec-decoding: mtp, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [6, 8] } minimaxm3-fp8-h200-vllm-agentic: image: vllm/vllm-openai:nightly-04c2a8deac44fdb1ca3e2b5ec3e6bf16f3f6a914 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 560ce04f09..2484290a97 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -5825,22 +5825,6 @@ - agentic-coding description: - "Refresh H100 MiniMax-M3 MXFP8 AgentX with vLLM v0.27.1 and 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/2564 - -- config-keys: - - minimaxm3-fp8-h100-vllm-agentic-mtp - scenario-type: - - agentic-coding - description: - - "Recover six broad-search points lost to one node's NVML failure and compare TP8 vLLM-simple DRAM offload at c4/c6/c8/c10." - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2564 - -- config-keys: - - minimaxm3-fp8-h100-vllm-agentic-mtp - scenario-type: - - agentic-coding - description: - - "Route vLLM-simple through the MTP launcher and exclude the H100 node with a confirmed NVML device fault." + - "Use the complete fast sweep to retain TP8 c1-c5 and Mooncake TP8 c6/c8 for the strict Pareto sweep; TEP is dominated, DEP is infeasible at its required KV allocation, and vLLM-simple is not retained after its function screen." + - "Require vLLM server metrics and keep strict request and profile validation." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2564 diff --git a/runners/launch_h100-dgxc-slurm.sh b/runners/launch_h100-dgxc-slurm.sh index 92fa067be6..1334c95542 100644 --- a/runners/launch_h100-dgxc-slurm.sh +++ b/runners/launch_h100-dgxc-slurm.sh @@ -4,7 +4,6 @@ set -e # System-specific configuration for H100 DGXC Slurm cluster SLURM_PARTITION="hpc-gpu-1" SLURM_ACCOUNT="customer" -H100_SLURM_EXCLUDED_NODELIST="${H100_SLURM_EXCLUDED_NODELIST-hpc-gpu-1-8}" # Route spec-decoding=mtp configs to the _mtp benchmark script (parity with # the h200 launchers, which have carried SPEC_SUFFIX since #392). @@ -290,13 +289,7 @@ else export GPU_COUNT="${GPU_COUNT:-${TP:?TP must be set}}" - SALLOC_EXCLUDE_ARGS=() - if [[ -n "$H100_SLURM_EXCLUDED_NODELIST" ]]; then - SALLOC_EXCLUDE_ARGS=(--exclude="$H100_SLURM_EXCLUDED_NODELIST") - echo "Excluding H100 nodes: $H100_SLURM_EXCLUDED_NODELIST" - fi - - salloc --partition=$SLURM_PARTITION --account=$SLURM_ACCOUNT --gres=gpu:$GPU_COUNT --exclusive --time=180 --no-shell --job-name="$RUNNER_NAME" "${SALLOC_EXCLUDE_ARGS[@]}" + salloc --partition=$SLURM_PARTITION --account=$SLURM_ACCOUNT --gres=gpu:$GPU_COUNT --exclusive --time=180 --no-shell --job-name="$RUNNER_NAME" JOB_ID=$(squeue --name="$RUNNER_NAME" -u "$USER" -h -o %A | head -n1) if [[ -z "$JOB_ID" ]]; then echo "ERROR: failed to resolve H100 Slurm allocation" >&2 From 8744c2c5d3b3715f85bcb67a4bd0cbb6dd2b0458 Mon Sep 17 00:00:00 2001 From: Cam Quilici Date: Wed, 12 Aug 2026 09:56:08 -0500 Subject: [PATCH 8/8] chore(h100): simplify MiniMax-M3 benchmark --- .../agentic/minimaxm3_fp8_h100_mtp.sh | 235 +++++++----------- configs/nvidia-master.yaml | 15 +- perf-changelog.yaml | 4 +- 3 files changed, 87 insertions(+), 167 deletions(-) diff --git a/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh index 3518a85a70..9e5f8fc8d6 100755 --- a/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh +++ b/benchmarks/single_node/agentic/minimaxm3_fp8_h100_mtp.sh @@ -1,36 +1,15 @@ #!/usr/bin/env bash -set -euo pipefail +set -eo pipefail set -x -# MiniMax-M3 MXFP8 H100 AgentX (agentic-coding) recipe with EAGLE3 speculative -# decoding — the spec-decoding=mtp variant of agentic/minimaxm3_fp8_h100.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, minimax_m3 parsers, vllm-router for -# DP-attention), so the spec-decode delta is readable at equal concurrency. -# -# Speculative config: the current Inferact/MiniMax-M3-EAGLE3-GQA draft head -# with three speculative tokens and the committed thinking-on golden AL. -# -# The drafter is pinned to FLASH_ATTN, as on every CUDA MiniMax-M3 MTP recipe: -# the EAGLE3 head is MHA and FlashInfer only serves page size 128 through its -# trtllm-gen kernel, which requires GQA/MQA. FLASH_ATTN accepts any -# multiple-of-16 block size, so the mandatory 128 is fine for the draft. (The -# ROCm recipes need no pin because their server runs TRITON_ATTN throughout.) -# -# Throughput runs pin synthetic acceptance to the committed golden AL; the -# EVAL_ONLY accuracy run keeps real target verification. See SYNTHETIC_ACCEPT_LEN. +# H100 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 - 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" @@ -40,11 +19,7 @@ else export MODEL_PATH="$MODEL" 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 @@ -61,33 +36,44 @@ 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_CPU_OFFLOAD_GB=26 MODEL_CHECKPOINT_PAGE_CACHE_GIB=414 MOONCAKE_LOCAL_BUFFER_GIB=4 -case "${KV_OFFLOAD_BACKEND:-}" in - "") - require_agentic_kv_offload_none - ;; - mooncake) - require_agentic_kv_offload_backend mooncake - TOTAL_CPU_DRAM_GIB=$((TOTAL_CPU_DRAM_GB * 1000000000 / 1073741824)) - PER_RANK_GIB=$(((TOTAL_CPU_DRAM_GIB - MODEL_CHECKPOINT_PAGE_CACHE_GIB) / TP - MODEL_CPU_OFFLOAD_GB - MOONCAKE_LOCAL_BUFFER_GIB)) - if (( PER_RANK_GIB <= 0 )); then - echo "Error: CPU DRAM budget is too small for checkpoint cache, model, 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 -# The public endpoint is the router for DEP, so explicitly scrape the engine -# endpoint. Pure TP/TEP deduplicates this URL against the automatic scrape. -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 -# AgentX concurrency counts live session trees, not individual requests. DEP -# splits those trees across eight data-parallel ranks; TP/TEP keeps them local. -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 \ - --cpu-offload-gb "$MODEL_CPU_OFFLOAD_GB" \ - --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 \ - --safetensors-load-strategy lazy \ - --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 + --cpu-offload-gb "$MODEL_CPU_OFFLOAD_GB" + --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 + --safetensors-load-strategy lazy + --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/configs/nvidia-master.yaml b/configs/nvidia-master.yaml index 51c853352b..007cc48ed7 100644 --- a/configs/nvidia-master.yaml +++ b/configs/nvidia-master.yaml @@ -7141,15 +7141,6 @@ minimaxm3-fp8-h100-vllm-agentic: - { tp: 8, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16] } - { tp: 8, ep: 8, kv-offloading: dram, kv-offload-backend: { name: mooncake, version: "0.3.11.post1" }, conc-list: [3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16] } -# EAGLE3 speculative-decoding (spec-decoding: mtp) variant of -# minimaxm3-fp8-h100-vllm-agentic, pairing MiniMaxAI/MiniMax-M3-MXFP8 with the -# Inferact/MiniMax-M3-EAGLE3-GQA draft head (3 speculative tokens, FLASH_ATTN -# drafter) and pinning synthetic acceptance to the golden AL 2.78 -# (golden_al_distribution/minimaxm3_eagle3_gqa.yaml, thinking_on, K=3). Same TP8-only -# layout and KV arms as the non-MTP entry so the spec-decode delta is readable at -# equal concurrency, trimmed at the extreme-conc end: the draft head plus its KV -# eat into the same HBM budget that already puts the GPU-resident cliff near -# conc 6 on 80 GB H100s. minimaxm3-fp8-h100-vllm-agentic-mtp: image: vllm/vllm-openai:v0.27.1 model: MiniMaxAI/MiniMax-M3-MXFP8 @@ -7160,11 +7151,7 @@ minimaxm3-fp8-h100-vllm-agentic-mtp: multinode: false scenarios: agentic-coding: - # The complete fast sweep places the GPU-resident cliff between c5 and c6. - # Retain the resident latency/knee curve through c5, then use Mooncake at - # c6/c8 to extend throughput without crossing that HBM cliff. TEP was - # dominated, DEP could not allocate its 1M-token KV cache on 80 GB H100s, - # and the vLLM-simple function screen did not justify a frontier row. + # The fast sweep places the resident HBM cliff between c5 and c6. - dram-utilization: 0.80 search-space: - { tp: 8, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 2, 3, 4, 5] } diff --git a/perf-changelog.yaml b/perf-changelog.yaml index a644bce1fc..3aac6d1586 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -5843,7 +5843,5 @@ scenario-type: - agentic-coding description: - - "Refresh H100 MiniMax-M3 MXFP8 AgentX with vLLM v0.27.1 and EAGLE3-GQA synthetic golden AL 2.78." - - "Use the complete fast sweep to retain TP8 c1-c5 and Mooncake TP8 c6/c8 for the strict Pareto sweep; TEP is dominated, DEP is infeasible at its required KV allocation, and vLLM-simple is not retained after its function screen." - - "Require vLLM server metrics and keep strict request and profile validation." + - "Add MiniMax-M3 MXFP8 AgentX on H100 with vLLM v0.27.1, EAGLE3 golden AL 2.78, resident TP8 c1-c5, and Mooncake DRAM offload c6/c8." pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2564