Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions benchmarks/single_node/agentic/qwen3.5_fp4_mi355x_sglang_mtp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/env bash
set -euo pipefail
set -x

# AgentX trace replay for Qwen3.5-397B-A17B MXFP4 on MI355X with SGLang
# native EAGLE MTP. Throughput uses the committed golden synthetic
# acceptance length; evaluation retains real target-model verification.

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

export EVAL_FRAMEWORK="lm-eval"

check_env_vars \
MODEL TP CONC EP_SIZE RESULT_DIR DURATION

SCHEDULER_RECV_INTERVAL=${SCHEDULER_RECV_INTERVAL:-30}

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

rocm-smi || true
amd-smi || true

export WEKA_LOADER_OVERRIDE=semianalysis_cc_traces_weka_062126_256k
resolve_trace_source
install_agentic_deps

export AIPERF_SERVER_METRICS_URLS="http://localhost:${PORT}/metrics"
export AIPERF_REQUIRED_SERVER_METRIC_PREFIX="sglang:"

SERVER_LOG="$RESULT_DIR/server.log"
mkdir -p "$RESULT_DIR"

SERVER_PID=""
cleanup_agentic_services() {
local exit_code=$?
trap - EXIT INT TERM
set +e
stop_background_process_tree "$SERVER_PID" "SGLang server" 60
exit "$exit_code"
}
trap cleanup_agentic_services EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

PARALLEL_ARGS=(
--tp "$TP"
--dp 1
--ep-size "$EP_SIZE"
)

TOKENIZER_ARGS=()
if [ "$TP" -ge 4 ]; then
TOKENIZER_ARGS=(--tokenizer-worker-num 6)
fi

MAX_RUNNING_REQUESTS=$((2 * CONC))
CUDA_GRAPH_MAX_BS="$CONC"
[ "$CUDA_GRAPH_MAX_BS" -gt 64 ] && CUDA_GRAPH_MAX_BS=64

export PYTHONNOUSERSITE=1
export SGLANG_USE_AITER=1
export SGLANG_USE_AITER_UNIFIED_ATTN=1
export AITER_FLYDSL_FORCE=1
export SGLANG_MAMBA_SSM_DTYPE=bfloat16
export SGLANG_TIMEOUT_KEEP_ALIVE=1800

if [ "${EVAL_ONLY:-false}" != "true" ]; then
export SGLANG_SIMULATE_ACC_LEN=3.39
export SGLANG_SIMULATE_ACC_METHOD=match-expected
export SGLANG_SIMULATE_ACC_TOKEN_MODE=real-draft-token
fi

SGLANG_CMD=(
python3 -m sglang.launch_server
--model-path "$MODEL_PATH"
--served-model-name "$MODEL"
--host 0.0.0.0
--port "$PORT"
--trust-remote-code
"${PARALLEL_ARGS[@]}"
--attention-backend aiter
--mem-fraction-static 0.80
--model-loader-extra-config '{"enable_multithread_load": true}'
--watchdog-timeout 1200
--page-size 16
--cuda-graph-max-bs "$CUDA_GRAPH_MAX_BS"
--max-running-requests "$MAX_RUNNING_REQUESTS"
--max-prefill-tokens 32768
--chunked-prefill-size 32768
--scheduler-recv-interval "$SCHEDULER_RECV_INTERVAL"
--stream-interval 50
"${TOKENIZER_ARGS[@]}"
--tokenizer-path "$MODEL"
--reasoning-parser qwen3
--tool-call-parser qwen3_coder
--speculative-algorithm EAGLE
--speculative-num-steps 3
--speculative-eagle-topk 1
--speculative-num-draft-tokens 4
--enable-metrics
--enable-cache-report
)

printf '%q ' "${SGLANG_CMD[@]}" | tee "$RESULT_DIR/sglang_command.txt"
printf '\n' | tee -a "$RESULT_DIR/sglang_command.txt"
"${SGLANG_CMD[@]}" > "$SERVER_LOG" 2>&1 &
SERVER_PID=$!

wait_for_server_ready --port "$PORT" --server-log "$SERVER_LOG" --server-pid "$SERVER_PID"

if [ "${EVAL_ONLY:-false}" = "true" ]; then
run_eval --port "$PORT"
else
build_replay_cmd "$RESULT_DIR"
REPLAY_CMD+=" --apply-chat-template"
run_agentic_replay_and_write_outputs "$RESULT_DIR"
fi
Comment on lines +125 to +128

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Line 177 appends REPLAY_CMD+=" --use-chat-template" after build_replay_cmd, but build_replay_cmd (benchmark_lib.sh:1927) builds an aiperf profile invocation for the agentic /v1/chat/completions replay path, not the run_benchmark_serving (benchmark_serving.py) path where this flag is actually recognized. This will make aiperf profile reject the unrecognized argument and exit non-zero, failing every non-eval (throughput) concurrency point in this new recipe. Fix: delete line 177 entirely.

Extended reasoning...

build_replay_cmd in benchmark_lib.sh:1887-2053 constructs REPLAY_CMD as an $AIPERF_CLI profile --scenario inferencex-agentx-mvp ... invocation, targeting --endpoint /v1/chat/completions with --endpoint-type chat. Nowhere in this function (or anywhere in the aiperf profile argument set) is --use-chat-template handled — that flag is defined and consumed exclusively inside run_benchmark_serving (benchmark_lib.sh:520 for parsing, :636-638 for application), which drives utils/bench_serving/benchmark_serving.py for the fixed-seq-len scripts, not the agentic replay path.

In qwen3.5_fp4_mi355x_sglang_mtp.sh:176-179, the non-EVAL_ONLY branch calls build_replay_cmd "$RESULT_DIR" and then appends REPLAY_CMD+=" --use-chat-template" before calling run_agentic_replay_and_write_outputs "$RESULT_DIR". That function executes $REPLAY_CMD literally at benchmark_lib.sh:2112 ($REPLAY_CMD 2>&1 | tee "$result_dir/benchmark.log") and gates success on the exit code (replay_rc). Since aiperf profile has no such flag, it will reject the unrecognized CLI argument and exit non-zero, causing run_agentic_replay_and_write_outputs to treat the run as failed.

This is not a stylistic mismatch — it's a straightforward "passing an unsupported flag to a CLI tool" bug. The only reason it isn't obviously wrong from a shallow read is that --use-chat-template is a real, valid flag elsewhere in the same file, which makes it plausible at a glance that it belongs here too. But tracing which command REPLAY_CMD actually becomes shows it doesn't apply to this call site.

Corroborating evidence from the rest of the codebase: (1) the direct sibling B200 recipe qwen3.5_fp4_b200_sglang_mtp.sh appends --server-metrics after build_replay_cmd, never --use-chat-template; (2) no other agentic *_mtp.sh script (dsv4 variants, glm5.2, etc.) adds this flag to REPLAY_CMD; (3) kimik3_fp4_b300_vllm_mtp.sh:35-38 has an explicit comment stating exactly why agentic recipes must not add it: "AGENTS.md requires MTP scripts to pass --use-chat-template to run_benchmark_serving. Agentic recipes never call it -- the replay drives AIPerf against /v1/chat/completions, so prompts are already chat-formatted ... Nothing to add here."

Step-by-step proof of the failure: (1) Script reaches the else branch (EVAL_ONLY defaults to false, so this is the default/majority path — the sweep's agentic-coding scenario in configs/amd-master.yaml runs many conc-list throughput points, e.g. conc-list: [1, 4, 8, 12, 16, ...]). (2) build_replay_cmd "$RESULT_DIR" sets REPLAY_CMD="$AIPERF_CLI profile --scenario inferencex-agentx-mvp --url http://localhost:$PORT --endpoint /v1/chat/completions --endpoint-type chat ... --output-artifact-dir $RESULT_DIR/aiperf_artifacts ...". (3) Line 177 appends --use-chat-template to this string. (4) run_agentic_replay_and_write_outputs runs $REPLAY_CMD, i.e. invokes aiperf profile ... --use-chat-template. (5) aiperf's CLI parser (argparse or similar) has no such option registered for the profile subcommand and will error out ("unrecognized arguments: --use-chat-template") with a non-zero exit code. (6) replay_rc becomes non-zero, and the run is recorded as failed — for every throughput concurrency point across all four search-space rows in the new qwen3.5-fp4-mi355x-sglang-agentic-mtp config entry.

The fix is simply to delete line 177 (REPLAY_CMD+=" --use-chat-template"), leaving build_replay_cmd's output untouched, matching every other agentic *_mtp.sh script's pattern.

15 changes: 15 additions & 0 deletions configs/amd-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,21 @@ qwen3.5-fp4-mi355x-sglang-mtp:
- { tp: 2, conc-start: 4, conc-end: 128, spec-decoding: mtp }
- { tp: 4, conc-start: 4, conc-end: 16, spec-decoding: mtp }

qwen3.5-fp4-mi355x-sglang-agentic-mtp:
image: lmsysorg/sglang-rocm:v0.5.17-rocm720-mi35x-20260811
model: amd/Qwen3.5-397B-A17B-MXFP4
model-prefix: qwen3.5
runner: cluster:mi355x-amds
precision: fp4
framework: sglang
multinode: false
scenarios:
agentic-coding:
- dram-utilization: 0.80
search-space:
- { tp: 2, ep: 2, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 4, 8, 12, 16, 20] }
- { tp: 4, ep: 1, spec-decoding: mtp, kv-offloading: none, conc-list: [1, 4, 8, 12, 16, 20, 24, 28, 32, 40] }

qwen3.5-fp4-mi355x-sglang-disagg:
image: lmsysorg/sglang-rocm:v0.5.12.post1-rocm720-mi35x-20260523
model: amd/Qwen3.5-397B-A17B-MXFP4
Expand Down
8 changes: 8 additions & 0 deletions perf-changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5874,3 +5874,11 @@
description:
- "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

- config-keys:
- qwen3.5-fp4-mi355x-sglang-agentic-mtp
description:
- "Add Qwen3.5-397B-A17B MXFP4 MI355X SGLang AgentX with native EAGLE MTP and the committed golden synthetic acceptance length."
- "Cover the measured resident TP2/EP2 and TP4 Pareto ranges through their HBM capacity knees, with required SGLang metrics exports."
- "Use SGLang v0.5.17 and disable unstable AITER all-reduce fusion for TP2/EP2 EAGLE rank consistency."
pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2562