From c964c295e16c0cefa0c9d67605cd185fa55570d2 Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Thu, 10 Sep 2026 17:48:58 +0800 Subject: [PATCH 01/11] feat: add draft DS V4.1 Flash AgentX recipe for MI355X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 MI355X 的 DS V4.1 Flash AgentX 草案配方:TP4、并发 1–32、原生 DSpark 和 AITER,并补充 launcher、测试及中英文文档。ROCm 镜像发布与 Engram 兼容性仍待验证。 --- MODELS.md | 1 + MODELS_zh.md | 1 + .../agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 87 +++++++++++++++++++ configs/amd-master.yaml | 17 ++++ docs/configuration-procedures.md | 8 ++ docs/configuration-procedures_zh.md | 8 ++ perf-changelog.yaml | 7 ++ runners/launch_mi355x-amds.sh | 15 +++- runners/test_slurm_utils.py | 50 +++++++++++ 9 files changed, 192 insertions(+), 2 deletions(-) create mode 100755 benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh diff --git a/MODELS.md b/MODELS.md index 21cc16d682..b0371e1ee4 100644 --- a/MODELS.md +++ b/MODELS.md @@ -155,6 +155,7 @@ Other offloading tiers, including NVMe KV cache offloading, are outside the init | Kimi-K3 | `kimik3` | 2026-07-27 ([#2391](https://github.com/SemiAnalysisAI/InferenceX/pull/2391)) | Agentic coding (DSpark only) | Agentic coding non-DSpark arm (deprecated from day 0) | | GLM-5.2 | `glm5.2` | 2026-07-18 ([#2268](https://github.com/SemiAnalysisAI/InferenceX/pull/2268)) | Agentic coding (the non-MTP arm still runs while the MTP-only transition remains pending, as explained in the Deprecation Notice) | | | MiniMax-M3 | `minimaxm3` | 2026-06-12 ([#1724](https://github.com/SemiAnalysisAI/InferenceX/pull/1724)) | Agentic coding | Single-turn 1k1k, Single-turn 8k1k (removed 2026-08-04, [#2493](https://github.com/SemiAnalysisAI/InferenceX/pull/2493)) | +| DeepSeek-V4.1-Flash | `dsv41flash` | Pending | Agentic coding on MI355X (draft; ROCm image publication and GPU validation pending) | — | | DeepSeek-V4-Pro | `dsv4` | 2026-04-24 ([#1130](https://github.com/SemiAnalysisAI/InferenceX/pull/1130)) | Single-turn 8k1k (last day 2026-09-08, see [Deprecation Notice](#deprecation-notice)), Agentic coding (the non-MTP arm still runs while the MTP-only transition remains pending, as explained in the Deprecation Notice) | Single-turn 1k1k | | GLM-5 / GLM-5.1 | `glm5`, `glm5.1` | 2026-03-06 ([#762](https://github.com/SemiAnalysisAI/InferenceX/pull/762)), with GLM-5.1 added 2026-04-21 ([#1098](https://github.com/SemiAnalysisAI/InferenceX/pull/1098)) | None (retired 2026-07-18, [#2276](https://github.com/SemiAnalysisAI/InferenceX/pull/2276)) | Single-turn 1k1k, Single-turn 1k8k (GLM-5 only), Single-turn 8k1k | | MiniMax-M2.5/2.7 | `minimaxm2.5` | 2026-02-18 ([#755](https://github.com/SemiAnalysisAI/InferenceX/pull/755)) | None (retired 2026-06-20, [#1874](https://github.com/SemiAnalysisAI/InferenceX/pull/1874)) | Single-turn 1k1k, Single-turn 1k8k, Single-turn 8k1k | diff --git a/MODELS_zh.md b/MODELS_zh.md index 2ab04fae2e..2e3cd93d88 100644 --- a/MODELS_zh.md +++ b/MODELS_zh.md @@ -155,6 +155,7 @@ InferenceX 支持 SGLang 和 vLLM 双方的维护者,并响应 AI 实验室和 | Kimi-K3 | `kimik3` | 2026-07-27 ([#2391](https://github.com/SemiAnalysisAI/InferenceX/pull/2391)) | 智能体编码(仅 DSpark) | 智能体编码非 DSpark 分支(自第 0 天起弃用) | | GLM-5.2 | `glm5.2` | 2026-07-18([#2268](https://github.com/SemiAnalysisAI/InferenceX/pull/2268)) | 智能体编码(非 MTP 分支仍在运行,「仅 MTP」转换仍待执行,见弃用公告) | | | MiniMax-M3 | `minimaxm3` | 2026-06-12([#1724](https://github.com/SemiAnalysisAI/InferenceX/pull/1724)) | 智能体编码 | 单轮 1k1k、单轮 8k1k(2026-08-04 移除,[#2493](https://github.com/SemiAnalysisAI/InferenceX/pull/2493)) | +| DeepSeek-V4.1-Flash | `dsv41flash` | 待验证 | MI355X 上的 Agentic coding(草案;等待 ROCm 镜像发布与 GPU 验证) | — | | DeepSeek-V4-Pro | `dsv4` | 2026-04-24([#1130](https://github.com/SemiAnalysisAI/InferenceX/pull/1130)) | 单轮 8k1k、智能体编码(非 MTP 分支仍在运行,「仅 MTP」转换仍待执行,见弃用公告) | 单轮 1k1k | | GLM-5 / GLM-5.1 | `glm5`、`glm5.1` | 2026-03-06([#762](https://github.com/SemiAnalysisAI/InferenceX/pull/762)),GLM-5.1 于 2026-04-21 加入([#1098](https://github.com/SemiAnalysisAI/InferenceX/pull/1098)) | 无(2026-07-18 退役,[#2276](https://github.com/SemiAnalysisAI/InferenceX/pull/2276)) | 单轮 1k1k、单轮 1k8k(仅 GLM-5)、单轮 8k1k | | MiniMax-M2.5/2.7 | `minimaxm2.5` | 2026-02-18([#755](https://github.com/SemiAnalysisAI/InferenceX/pull/755)) | 无(2026-06-20 退役,[#1874](https://github.com/SemiAnalysisAI/InferenceX/pull/1874)) | 单轮 1k1k、单轮 1k8k、单轮 8k1k | diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh new file mode 100755 index 0000000000..49346d0e8a --- /dev/null +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +set -eo pipefail + +# DeepSeek-V4.1-Flash on MI355X: native DSpark and GPU-resident KV. +# Follow upstream AMD defaults for Engram; storage behavior needs verification. +# The upstream ROCm image is not published yet; runtime validation is pending. +# https://github.com/vllm-project/recipes/blob/main/models/deepseek-ai/DeepSeek-V4.1-Flash.yaml +source "$(dirname "$0")/../../benchmark_lib.sh" +check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION +require_agentic_kv_offload_none +export GPU_COUNT="$TP" + +# Complete/resume partial downloads instead of trusting nonempty directories. +if [[ -n "${MODEL_PATH:-}" && "$MODEL_PATH" != "$MODEL" ]]; then + hf download "$MODEL" --local-dir "$MODEL_PATH" +else + hf download "$MODEL" + export MODEL_PATH="$MODEL" +fi + +if [[ -n "${ROCR_VISIBLE_DEVICES:-}" ]]; then + export HIP_VISIBLE_DEVICES="$ROCR_VISIBLE_DEVICES" +fi +export VLLM_ROCM_USE_AITER=1 +export VLLM_ROCM_USE_AITER_MOE=1 +export OMP_NUM_THREADS=1 +resolve_trace_source +install_agentic_deps +mkdir -p "$RESULT_DIR" +SERVER_LOG="$RESULT_DIR/server.log" +export VLLM_ENGINE_READY_TIMEOUT_S=3600 +export VLLM_USE_RUST_FRONTEND=1 +export PYTHONUNBUFFERED=1 + +# Match the sibling's scheduler headroom for AgentX subagent fan-out. +MAX_NUM_SEQS=$((2 * CONC)) +NUM_SPEC_TOKENS=5 +CAPTURE_SIZE=1 +while (( CAPTURE_SIZE < MAX_NUM_SEQS * (1 + NUM_SPEC_TOKENS) && CAPTURE_SIZE < 2048 )); do + CAPTURE_SIZE=$((CAPTURE_SIZE * 2)) +done + +# Use the runner-specific port assigned by launch_mi355x-amds.sh. +export AIPERF_SERVER_URL="http://localhost:${PORT}" +export AIPERF_SERVER_METRICS_URLS="${AIPERF_SERVER_URL}/metrics" +export AIPERF_REQUIRED_SERVER_METRIC_PREFIX="vllm:" +echo "Using vLLM endpoint ${AIPERF_SERVER_URL}" + +# Both throughput and eval use real target verification, never synthetic AL. +VLLM_CMD=( + vllm serve "$MODEL_PATH" --served-model-name "$MODEL" + --host 0.0.0.0 --port "$PORT" --tensor-parallel-size "$TP" + --language-model-only + --tokenizer-mode deepseek_v41 + --tool-call-parser deepseek_v41 --enable-auto-tool-choice + --reasoning-parser deepseek_v41 + --moe-backend aiter_triton_mxfp4_bf16 + --gpu-memory-utilization 0.9 + --speculative-config '{"method":"dspark","num_speculative_tokens":5,"draft_sample_method":"probabilistic","rejection_sample_method":"block","enable_adaptive_verification":true}' + --max-model-len 1048576 + --max-num-seqs "$MAX_NUM_SEQS" + --max-cudagraph-capture-size "$CAPTURE_SIZE" + --max-num-batched-tokens 16384 + --disable-uvicorn-access-log +) +printf '%q ' "${VLLM_CMD[@]}" | tee "$RESULT_DIR/vllm_command.txt" +printf '\n' | tee -a "$RESULT_DIR/vllm_command.txt" +SERVER_PID="" +cleanup_server() { + local rc=$? + trap - EXIT INT TERM + stop_background_process_tree "$SERVER_PID" "vLLM server" 60 + exit "$rc" +} +trap cleanup_server EXIT +trap 'exit 130' INT +trap 'exit 143' TERM +"${VLLM_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" + run_agentic_replay_and_write_outputs "$RESULT_DIR" +fi diff --git a/configs/amd-master.yaml b/configs/amd-master.yaml index a9e98586ff..acfac4911e 100644 --- a/configs/amd-master.yaml +++ b/configs/amd-master.yaml @@ -1752,3 +1752,20 @@ dsv4-fp4-mi355x-sglang-agentic-mtp: - { tp: 8, ep: 1, dp-attn: false, kv-offloading: none, conc-list: [1, 4, 16], spec-decoding: mtp } - { tp: 8, ep: 1, dp-attn: false, kv-offloading: dram, kv-offload-backend: { name: hicache }, conc-list: [32, 48], spec-decoding: mtp } - { tp: 8, ep: 1, dp-attn: true, kv-offloading: dram, kv-offload-backend: { name: hicache }, conc-list: [128, 256], spec-decoding: mtp } + +# Draft: upstream documents this ROCm image, but Docker Hub returned 404 on +# 2026-09-10. Verify publication before dispatching a sweep. +dsv41flash-fp4-mi355x-vllm-agentic-dspark: + image: vllm/vllm-openai-rocm:deepseekv41-flash-0909 + model: deepseek-ai/DeepSeek-V4.1-Flash + model-prefix: dsv41flash + runner: cluster:mi355x-amds + precision: fp4 + framework: vllm + multinode: false + scenarios: + agentic-coding: + - dram-utilization: 0.60 + search-space: + # Follow upstream AMD Engram defaults; omit the CUDA-only config flag. + - { tp: 4, kv-offloading: none, spec-decoding: mtp, conc-list: [1, 2, 4, 8, 16, 32] } diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index 59facfa4de..45a2ec9827 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -396,3 +396,11 @@ Stop before dispatching GPU work or claiming the configuration complete when any - YAML, Bash, strict schema, exact-key generation, launcher simulation, or recipe validation fails. A configuration is ready for sweep only when the executable files agree, the exact key generates, the runtime route exists, the changelog selects it, and all layer-specific checks above pass. + +## DeepSeek-V4.1-Flash on MI355X + +The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) to MI355X AgentX: TP4, concurrency 1–32, native five-token DSpark with adaptive verification, and real target verification for throughput and eval. FP4 describes the MXFP4 experts; the checkpoint also contains MXFP8 weights. + +Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`. + +**Runtime validation is blocked:** Docker Hub returned HTTP 404 for the upstream-documented `vllm/vllm-openai-rocm:deepseekv41-flash-0909` on 2026-09-10. The upstream shared Engram implementation also defaults to CPU offload while its explicit configuration rejects ROCm; verify that the published AMD build resolves this inconsistency. Verify the image exists and includes the AMD implementation before dispatch. Then run the exact key at concurrency 1 with `agentx-fast`, inspect the server and replay artifacts, and run the canonical sweep plus evals using the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence). Local generation is not GPU evidence. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index 0dcdb629f1..21ccab366e 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -374,3 +374,11 @@ python -m pytest utils/matrix_logic/ -v - YAML、Bash、严格 schema、精确 key 生成、launcher 模拟或配方验证失败。 只有当所有可执行文件一致、精确 key 能生成、运行时路由存在、changelog 能选择该 key,且以上各层检查全部通过时,配置才可以进入 sweep。 + +## MI355X 上的 DeepSeek-V4.1-Flash + +草案配方 `dsv41flash-fp4-mi355x-vllm-agentic-dspark` 将 [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) 扩展至 MI355X AgentX:TP4、并发 1–32、原生五 token DSpark 和自适应验证,吞吐测试与 eval 均使用真实目标模型验证。FP4 表示 MXFP4 专家权重;检查点还包含 MXFP8 权重。 + +遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`。 + +**运行时验证受阻:** 2026-09-10,Docker Hub 对上游文档指定的 `vllm/vllm-openai-rocm:deepseekv41-flash-0909` 返回 HTTP 404。上游共享 Engram 实现还默认启用 CPU 卸载,而显式配置拒绝 ROCm;须确认发布的 AMD 构建已解决此不一致。调度前须确认镜像已发布且包含 AMD 实现。随后使用 `agentx-fast` 对此配置键运行并发 1,检查服务端与回放产物,再按 [AgentX 流程](./eval-agentx-procedures_zh.md) 运行正式 sweep 和 eval。本地矩阵生成不等于 GPU 验证。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index f1e48d3766..19921e4ca0 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7338,3 +7338,10 @@ - "Resolve the requested H100 SGLang container instead of a hardcoded older image, and stop benchmark/eval clients when their ready server or required worker exits." - "H100 SGLang 使用所请求的容器而非硬编码旧镜像;已就绪的服务或必需工作进程退出后,停止其 benchmark/评测客户端。" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3020 + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Add draft DeepSeek-V4.1-Flash FP4 AgentX on MI355X: TP4, concurrency 1-32, native five-token DSpark with adaptive real verification" + - "Use upstream ROCm AITER recipe with GPU-resident KV; image publication, Engram compatibility, and GPU validation pending" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 diff --git a/runners/launch_mi355x-amds.sh b/runners/launch_mi355x-amds.sh index 49c3af0cf5..185c4bd97d 100644 --- a/runners/launch_mi355x-amds.sh +++ b/runners/launch_mi355x-amds.sh @@ -304,6 +304,17 @@ else export HF_HUB_CACHE_MOUNT="/it-share/hf-hub-cache/" fi + # DSv4.1 weights live on the persistent shared cache. Mount this recipe + # outside /workspace so runtime setup does not create directories there. + CONTAINER_REPO=/workspace + if [[ "$MODEL" == "deepseek-ai/DeepSeek-V4.1-Flash" ]]; then + export HF_HUB_CACHE_MOUNT="/it-share/hf-hub-cache/" + CONTAINER_REPO=/ix + case "${RESULT_DIR:-}" in + /workspace/*) export RESULT_DIR="/ix/${RESULT_DIR#/workspace/}" ;; + esac + fi + SCRIPT_BASE="${EXP_NAME%%_*}_${PRECISION}_mi355x" SCRIPT_FW="benchmarks/single_node/${SCENARIO_SUBDIR:-fixed_seq_len/}${SCRIPT_BASE}_${FRAMEWORK}${SPEC_SUFFIX}.sh" SCRIPT_FALLBACK="benchmarks/single_node/${SCENARIO_SUBDIR:-fixed_seq_len/}${SCRIPT_BASE}${FRAMEWORK_SUFFIX}${SPEC_SUFFIX}.sh" @@ -315,10 +326,10 @@ else srun --jobid=$JOB_ID \ --container-image=$SQUASH_FILE \ - --container-mounts=$GITHUB_WORKSPACE:/workspace/,$HF_HUB_CACHE_MOUNT:$HF_HUB_CACHE,$AIPERF_MMAP_CACHE_HOST_PATH:/aiperf_mmap_cache \ + --container-mounts=$GITHUB_WORKSPACE:$CONTAINER_REPO/,$HF_HUB_CACHE_MOUNT:$HF_HUB_CACHE,$AIPERF_MMAP_CACHE_HOST_PATH:/aiperf_mmap_cache \ $SLRUM_HOME_MOUNT \ --container-writable \ - --container-workdir=/workspace/ \ + --container-workdir=$CONTAINER_REPO/ \ --container-remap-root \ --no-container-entrypoint --export=ALL,AIPERF_DATASET_MMAP_CACHE_DIR=/aiperf_mmap_cache \ bash "$BENCHMARK_SCRIPT" diff --git a/runners/test_slurm_utils.py b/runners/test_slurm_utils.py index f473000c88..c93a0cbbc5 100644 --- a/runners/test_slurm_utils.py +++ b/runners/test_slurm_utils.py @@ -576,3 +576,53 @@ def test_eval_only_acceptance_rewrite_allows_non_speculative_recipe( assert result.returncode == 0, result.stderr assert recipe.read_text() == original + + +@pytest.mark.parametrize( + ("model", "prefix", "mount", "cache"), + [ + ("deepseek-ai/DeepSeek-V4.1-Flash", "dsv41flash", "/ix", "/it-share/hf-hub-cache/"), + ("deepseek-ai/DeepSeek-V4-Pro", "dsv4", "/workspace", "/it-share/hf-hub-cache/"), + ], +) +def test_mi355x_agentic_model_mount_and_routing( + tmp_path: Path, model: str, prefix: str, mount: str, cache: str, +) -> None: + capture = tmp_path / "launch.txt" + env = { + **os.environ, + "IS_MULTINODE": "false", "MODEL": model, + "EXP_NAME": f"{prefix}_tp4_conc1", "FRAMEWORK": "vllm", + "PRECISION": "fp4", "SPEC_DECODING": "mtp", + "SCENARIO_SUBDIR": "agentic/", "TP": "4", "GPU_COUNT": "4", + "RUNNER_NAME": "mi355x-amds_01", "IMAGE": "test/image:mock", + "GITHUB_WORKSPACE": str(REPO_ROOT), "HF_HUB_CACHE": "/mnt/hf_hub_cache/", + "RESULT_DIR": "/workspace/results", "CAPTURE": str(capture), + } + result = subprocess.run( + ["bash", "-c", ''' + salloc() { :; } + squeue() { echo 123; } + scancel() { :; } + srun() { + case "$*" in + *--container-image=*) + printf '%s\n' "$@" > "$CAPTURE" + printf 'RESULT_DIR=%s\n' "$RESULT_DIR" >> "$CAPTURE" + ;; + esac + } + source runners/launch_mi355x-amds.sh + '''], cwd=REPO_ROOT, env=env, capture_output=True, text=True, check=False, + ) + assert result.returncode == 0, result.stderr + args = capture.read_text().splitlines() + assert f"--container-workdir={mount}/" in args + assert f"RESULT_DIR={mount}/results" in args + assert ( + f"--container-mounts={REPO_ROOT}:{mount}/,{cache}:/mnt/hf_hub_cache/," + "/it-share/aiperf-cache/:/aiperf_mmap_cache" + ) in args + script = f"benchmarks/single_node/agentic/{prefix}_fp4_mi355x_vllm_mtp.sh" + assert args[-2] == script + assert (REPO_ROOT / script).is_file() From acef493119f377b960d26669532abdaa379bade5 Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Thu, 10 Sep 2026 18:33:20 +0800 Subject: [PATCH 02/11] fix: pin MI355X DS V4.1 Flash to full-context traces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 MI355X DS V4.1 Flash 固定至 semianalysis_cc_traces_weka_062126,避免使用 256k 语料,并同步更新文档与性能变更记录。 --- .../single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 2 ++ docs/configuration-procedures.md | 2 +- docs/configuration-procedures_zh.md | 2 +- perf-changelog.yaml | 6 ++++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh index 49346d0e8a..ae02dbfc45 100755 --- a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -24,6 +24,8 @@ fi export VLLM_ROCM_USE_AITER=1 export VLLM_ROCM_USE_AITER_MOE=1 export OMP_NUM_THREADS=1 +# Pin the full-context corpus for this 1M-context recipe. +export WEKA_LOADER_OVERRIDE=semianalysis_cc_traces_weka_062126 resolve_trace_source install_agentic_deps mkdir -p "$RESULT_DIR" diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index 45a2ec9827..841811f810 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -401,6 +401,6 @@ A configuration is ready for sweep only when the executable files agree, the exa The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) to MI355X AgentX: TP4, concurrency 1–32, native five-token DSpark with adaptive verification, and real target verification for throughput and eval. FP4 describes the MXFP4 experts; the checkpoint also contains MXFP8 weights. -Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`. +Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`. **Runtime validation is blocked:** Docker Hub returned HTTP 404 for the upstream-documented `vllm/vllm-openai-rocm:deepseekv41-flash-0909` on 2026-09-10. The upstream shared Engram implementation also defaults to CPU offload while its explicit configuration rejects ROCm; verify that the published AMD build resolves this inconsistency. Verify the image exists and includes the AMD implementation before dispatch. Then run the exact key at concurrency 1 with `agentx-fast`, inspect the server and replay artifacts, and run the canonical sweep plus evals using the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence). Local generation is not GPU evidence. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index 21ccab366e..d8a3892d79 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -379,6 +379,6 @@ python -m pytest utils/matrix_logic/ -v 草案配方 `dsv41flash-fp4-mi355x-vllm-agentic-dspark` 将 [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) 扩展至 MI355X AgentX:TP4、并发 1–32、原生五 token DSpark 和自适应验证,吞吐测试与 eval 均使用真实目标模型验证。FP4 表示 MXFP4 专家权重;检查点还包含 MXFP8 权重。 -遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`。 +遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`。 **运行时验证受阻:** 2026-09-10,Docker Hub 对上游文档指定的 `vllm/vllm-openai-rocm:deepseekv41-flash-0909` 返回 HTTP 404。上游共享 Engram 实现还默认启用 CPU 卸载,而显式配置拒绝 ROCm;须确认发布的 AMD 构建已解决此不一致。调度前须确认镜像已发布且包含 AMD 实现。随后使用 `agentx-fast` 对此配置键运行并发 1,检查服务端与回放产物,再按 [AgentX 流程](./eval-agentx-procedures_zh.md) 运行正式 sweep 和 eval。本地矩阵生成不等于 GPU 验证。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 19921e4ca0..264cdc0488 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7345,3 +7345,9 @@ - "Add draft DeepSeek-V4.1-Flash FP4 AgentX on MI355X: TP4, concurrency 1-32, native five-token DSpark with adaptive real verification" - "Use upstream ROCm AITER recipe with GPU-resident KV; image publication, Engram compatibility, and GPU validation pending" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Pin AgentX to semianalysis_cc_traces_weka_062126, preventing the 256k corpus override" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 From caf5031025c3e546bd02939eeeda3c026b43f4ce Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Fri, 11 Sep 2026 00:45:06 +0800 Subject: [PATCH 03/11] config: use golden synthetic AL for DSv4.1 Flash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DSv4.1 Flash 吞吐测试使用 thinking 开启、五个草稿 token 对应的黄金合成 AL 3.51,关闭自适应验证;准确率评测保留真实验证。同步中英文文档并追加性能变更记录。 --- .../agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 10 ++++++++-- docs/configuration-procedures.md | 2 +- docs/configuration-procedures_zh.md | 2 +- perf-changelog.yaml | 6 ++++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh index ae02dbfc45..3a984159f5 100755 --- a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -48,7 +48,13 @@ export AIPERF_SERVER_METRICS_URLS="${AIPERF_SERVER_URL}/metrics" export AIPERF_REQUIRED_SERVER_METRIC_PREFIX="vllm:" echo "Using vLLM endpoint ${AIPERF_SERVER_URL}" -# Both throughput and eval use real target verification, never synthetic AL. +# Golden AL: golden_al_distribution/dsv41flash_dspark.yaml, thinking_on, five draft tokens. +# Accuracy evals keep real block rejection; throughput fixes acceptance to AL 3.51. +if [[ "${EVAL_ONLY:-false}" == true ]]; then + SPEC_CONFIG='{"method":"dspark","num_speculative_tokens":5,"draft_sample_method":"probabilistic","rejection_sample_method":"block","enable_adaptive_verification":true}' +else + SPEC_CONFIG='{"method":"dspark","num_speculative_tokens":5,"draft_sample_method":"probabilistic","rejection_sample_method":"synthetic","synthetic_acceptance_length":3.51,"enable_adaptive_verification":false}' +fi VLLM_CMD=( vllm serve "$MODEL_PATH" --served-model-name "$MODEL" --host 0.0.0.0 --port "$PORT" --tensor-parallel-size "$TP" @@ -58,7 +64,7 @@ VLLM_CMD=( --reasoning-parser deepseek_v41 --moe-backend aiter_triton_mxfp4_bf16 --gpu-memory-utilization 0.9 - --speculative-config '{"method":"dspark","num_speculative_tokens":5,"draft_sample_method":"probabilistic","rejection_sample_method":"block","enable_adaptive_verification":true}' + --speculative-config "$SPEC_CONFIG" --max-model-len 1048576 --max-num-seqs "$MAX_NUM_SEQS" --max-cudagraph-capture-size "$CAPTURE_SIZE" diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index 841811f810..290bf8ef4d 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -399,7 +399,7 @@ A configuration is ready for sweep only when the executable files agree, the exa ## DeepSeek-V4.1-Flash on MI355X -The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) to MI355X AgentX: TP4, concurrency 1–32, native five-token DSpark with adaptive verification, and real target verification for throughput and eval. FP4 describes the MXFP4 experts; the checkpoint also contains MXFP8 weights. +The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) to MI355X AgentX: TP4, concurrency 1–32, native five-token DSpark. Throughput uses the [committed golden AL](../golden_al_distribution/dsv41flash_dspark.yaml) of 3.51 for thinking on and five draft tokens, with synthetic rejection sampling and adaptive verification disabled. Accuracy evals retain real block rejection and adaptive verification. FP4 describes the MXFP4 experts; the checkpoint also contains MXFP8 weights. Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index d8a3892d79..ce3de5e76b 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -377,7 +377,7 @@ python -m pytest utils/matrix_logic/ -v ## MI355X 上的 DeepSeek-V4.1-Flash -草案配方 `dsv41flash-fp4-mi355x-vllm-agentic-dspark` 将 [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) 扩展至 MI355X AgentX:TP4、并发 1–32、原生五 token DSpark 和自适应验证,吞吐测试与 eval 均使用真实目标模型验证。FP4 表示 MXFP4 专家权重;检查点还包含 MXFP8 权重。 +草案配方 `dsv41flash-fp4-mi355x-vllm-agentic-dspark` 将 [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) 扩展至 MI355X AgentX:TP4、并发 1–32、原生五 token DSpark。吞吐测试使用[已提交的黄金 AL](../golden_al_distribution/dsv41flash_dspark.yaml):thinking 开启、五个草稿 token 对应 3.51,采用合成拒绝采样并关闭自适应验证。准确率 eval 保留真实块拒绝采样和自适应验证。FP4 表示 MXFP4 专家权重;检查点还包含 MXFP8 权重。 遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 264cdc0488..7f26995ff8 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7351,3 +7351,9 @@ description: - "Pin AgentX to semianalysis_cc_traces_weka_062126, preventing the 256k corpus override" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Use thinking-on golden synthetic AL 3.51 for five-token DSpark throughput; disable adaptive verification and retain real verification for evals" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 From b89ce4a5898f6f6e183b0ccec461befee412c1ce Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Fri, 11 Sep 2026 09:01:46 +0800 Subject: [PATCH 04/11] fix: use published ROCm release image for DS V4.1 Flash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用指定的 ECR ROCm release 镜像替代不可用的 Docker Hub 标签,保留完整上下文语料与 DSpark 设置,并同步文档及性能变更记录。 --- MODELS.md | 2 +- MODELS_zh.md | 2 +- .../single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 2 +- configs/amd-master.yaml | 5 ++--- docs/configuration-procedures.md | 2 +- docs/configuration-procedures_zh.md | 2 +- perf-changelog.yaml | 7 +++++++ 7 files changed, 14 insertions(+), 8 deletions(-) diff --git a/MODELS.md b/MODELS.md index b0371e1ee4..5d8185c86a 100644 --- a/MODELS.md +++ b/MODELS.md @@ -155,7 +155,7 @@ Other offloading tiers, including NVMe KV cache offloading, are outside the init | Kimi-K3 | `kimik3` | 2026-07-27 ([#2391](https://github.com/SemiAnalysisAI/InferenceX/pull/2391)) | Agentic coding (DSpark only) | Agentic coding non-DSpark arm (deprecated from day 0) | | GLM-5.2 | `glm5.2` | 2026-07-18 ([#2268](https://github.com/SemiAnalysisAI/InferenceX/pull/2268)) | Agentic coding (the non-MTP arm still runs while the MTP-only transition remains pending, as explained in the Deprecation Notice) | | | MiniMax-M3 | `minimaxm3` | 2026-06-12 ([#1724](https://github.com/SemiAnalysisAI/InferenceX/pull/1724)) | Agentic coding | Single-turn 1k1k, Single-turn 8k1k (removed 2026-08-04, [#2493](https://github.com/SemiAnalysisAI/InferenceX/pull/2493)) | -| DeepSeek-V4.1-Flash | `dsv41flash` | Pending | Agentic coding on MI355X (draft; ROCm image publication and GPU validation pending) | — | +| DeepSeek-V4.1-Flash | `dsv41flash` | Pending | Agentic coding on MI355X (draft; GPU validation pending) | — | | DeepSeek-V4-Pro | `dsv4` | 2026-04-24 ([#1130](https://github.com/SemiAnalysisAI/InferenceX/pull/1130)) | Single-turn 8k1k (last day 2026-09-08, see [Deprecation Notice](#deprecation-notice)), Agentic coding (the non-MTP arm still runs while the MTP-only transition remains pending, as explained in the Deprecation Notice) | Single-turn 1k1k | | GLM-5 / GLM-5.1 | `glm5`, `glm5.1` | 2026-03-06 ([#762](https://github.com/SemiAnalysisAI/InferenceX/pull/762)), with GLM-5.1 added 2026-04-21 ([#1098](https://github.com/SemiAnalysisAI/InferenceX/pull/1098)) | None (retired 2026-07-18, [#2276](https://github.com/SemiAnalysisAI/InferenceX/pull/2276)) | Single-turn 1k1k, Single-turn 1k8k (GLM-5 only), Single-turn 8k1k | | MiniMax-M2.5/2.7 | `minimaxm2.5` | 2026-02-18 ([#755](https://github.com/SemiAnalysisAI/InferenceX/pull/755)) | None (retired 2026-06-20, [#1874](https://github.com/SemiAnalysisAI/InferenceX/pull/1874)) | Single-turn 1k1k, Single-turn 1k8k, Single-turn 8k1k | diff --git a/MODELS_zh.md b/MODELS_zh.md index 2e3cd93d88..29e1b55404 100644 --- a/MODELS_zh.md +++ b/MODELS_zh.md @@ -155,7 +155,7 @@ InferenceX 支持 SGLang 和 vLLM 双方的维护者,并响应 AI 实验室和 | Kimi-K3 | `kimik3` | 2026-07-27 ([#2391](https://github.com/SemiAnalysisAI/InferenceX/pull/2391)) | 智能体编码(仅 DSpark) | 智能体编码非 DSpark 分支(自第 0 天起弃用) | | GLM-5.2 | `glm5.2` | 2026-07-18([#2268](https://github.com/SemiAnalysisAI/InferenceX/pull/2268)) | 智能体编码(非 MTP 分支仍在运行,「仅 MTP」转换仍待执行,见弃用公告) | | | MiniMax-M3 | `minimaxm3` | 2026-06-12([#1724](https://github.com/SemiAnalysisAI/InferenceX/pull/1724)) | 智能体编码 | 单轮 1k1k、单轮 8k1k(2026-08-04 移除,[#2493](https://github.com/SemiAnalysisAI/InferenceX/pull/2493)) | -| DeepSeek-V4.1-Flash | `dsv41flash` | 待验证 | MI355X 上的 Agentic coding(草案;等待 ROCm 镜像发布与 GPU 验证) | — | +| DeepSeek-V4.1-Flash | `dsv41flash` | 待验证 | MI355X 上的 Agentic coding(草案;等待 GPU 验证) | — | | DeepSeek-V4-Pro | `dsv4` | 2026-04-24([#1130](https://github.com/SemiAnalysisAI/InferenceX/pull/1130)) | 单轮 8k1k、智能体编码(非 MTP 分支仍在运行,「仅 MTP」转换仍待执行,见弃用公告) | 单轮 1k1k | | GLM-5 / GLM-5.1 | `glm5`、`glm5.1` | 2026-03-06([#762](https://github.com/SemiAnalysisAI/InferenceX/pull/762)),GLM-5.1 于 2026-04-21 加入([#1098](https://github.com/SemiAnalysisAI/InferenceX/pull/1098)) | 无(2026-07-18 退役,[#2276](https://github.com/SemiAnalysisAI/InferenceX/pull/2276)) | 单轮 1k1k、单轮 1k8k(仅 GLM-5)、单轮 8k1k | | MiniMax-M2.5/2.7 | `minimaxm2.5` | 2026-02-18([#755](https://github.com/SemiAnalysisAI/InferenceX/pull/755)) | 无(2026-06-20 退役,[#1874](https://github.com/SemiAnalysisAI/InferenceX/pull/1874)) | 单轮 1k1k、单轮 1k8k、单轮 8k1k | diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh index 3a984159f5..8a811944a7 100755 --- a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -3,7 +3,7 @@ set -eo pipefail # DeepSeek-V4.1-Flash on MI355X: native DSpark and GPU-resident KV. # Follow upstream AMD defaults for Engram; storage behavior needs verification. -# The upstream ROCm image is not published yet; runtime validation is pending. +# The ROCm release image is configured in amd-master.yaml; GPU validation is pending. # https://github.com/vllm-project/recipes/blob/main/models/deepseek-ai/DeepSeek-V4.1-Flash.yaml source "$(dirname "$0")/../../benchmark_lib.sh" check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION diff --git a/configs/amd-master.yaml b/configs/amd-master.yaml index acfac4911e..47b63ceadb 100644 --- a/configs/amd-master.yaml +++ b/configs/amd-master.yaml @@ -1753,10 +1753,9 @@ dsv4-fp4-mi355x-sglang-agentic-mtp: - { tp: 8, ep: 1, dp-attn: false, kv-offloading: dram, kv-offload-backend: { name: hicache }, conc-list: [32, 48], spec-decoding: mtp } - { tp: 8, ep: 1, dp-attn: true, kv-offloading: dram, kv-offload-backend: { name: hicache }, conc-list: [128, 256], spec-decoding: mtp } -# Draft: upstream documents this ROCm image, but Docker Hub returned 404 on -# 2026-09-10. Verify publication before dispatching a sweep. +# ROCm release image; MI355X runtime validation is pending. dsv41flash-fp4-mi355x-vllm-agentic-dspark: - image: vllm/vllm-openai-rocm:deepseekv41-flash-0909 + image: public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm model: deepseek-ai/DeepSeek-V4.1-Flash model-prefix: dsv41flash runner: cluster:mi355x-amds diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index 290bf8ef4d..532e56abba 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -403,4 +403,4 @@ The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](htt Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`. -**Runtime validation is blocked:** Docker Hub returned HTTP 404 for the upstream-documented `vllm/vllm-openai-rocm:deepseekv41-flash-0909` on 2026-09-10. The upstream shared Engram implementation also defaults to CPU offload while its explicit configuration rejects ROCm; verify that the published AMD build resolves this inconsistency. Verify the image exists and includes the AMD implementation before dispatch. Then run the exact key at concurrency 1 with `agentx-fast`, inspect the server and replay artifacts, and run the canonical sweep plus evals using the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence). Local generation is not GPU evidence. +**GPU validation is pending:** The recipe uses `public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm`. Its public manifest was verified on 2026-09-11; image metadata includes ROCm and `gfx950`. This replaces the Docker Hub tag that returned HTTP 404 in run 34466680355. Engram behavior and serving compatibility still require GPU validation. Follow the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence) for runtime evidence; local generation and registry metadata are not GPU proof. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index ce3de5e76b..f319557e13 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -381,4 +381,4 @@ python -m pytest utils/matrix_logic/ -v 遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`。 -**运行时验证受阻:** 2026-09-10,Docker Hub 对上游文档指定的 `vllm/vllm-openai-rocm:deepseekv41-flash-0909` 返回 HTTP 404。上游共享 Engram 实现还默认启用 CPU 卸载,而显式配置拒绝 ROCm;须确认发布的 AMD 构建已解决此不一致。调度前须确认镜像已发布且包含 AMD 实现。随后使用 `agentx-fast` 对此配置键运行并发 1,检查服务端与回放产物,再按 [AgentX 流程](./eval-agentx-procedures_zh.md) 运行正式 sweep 和 eval。本地矩阵生成不等于 GPU 验证。 +**GPU 验证尚待完成:** 配方使用 `public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm`。2026-09-11 已验证其公开 manifest,镜像元数据包含 ROCm 和 `gfx950`。此镜像替代了在运行 34466680355 中返回 HTTP 404 的 Docker Hub 标签。Engram 行为与服务兼容性仍需 GPU 验证。请按 [AgentX 流程](./eval-agentx-procedures_zh.md) 获取运行时证据;本地矩阵生成和镜像元数据不等于 GPU 验证。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 7f26995ff8..f6383cb126 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7357,3 +7357,10 @@ description: - "Use thinking-on golden synthetic AL 3.51 for five-token DSpark throughput; disable adaptive verification and retain real verification for evals" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Replace unavailable Docker Hub image with public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm" + - "Keep TP4, DSpark settings, and the full-context semianalysis_cc_traces_weka_062126 corpus" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 From 08f46551922012e41221b08f998dc0af41d372ae Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Fri, 11 Sep 2026 13:37:47 +0800 Subject: [PATCH 05/11] fix: align MI355X AgentX paths with the container mount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为 DS V4.1 Flash 的 /ix 挂载设置 INFMAX_CONTAINER_WORKSPACE,修复 AgentX 依赖与输出路径,并验证共享 helper 的实际路径解析。 --- docs/configuration-procedures.md | 2 +- docs/configuration-procedures_zh.md | 2 +- perf-changelog.yaml | 6 ++++++ runners/launch_mi355x-amds.sh | 1 + runners/test_slurm_utils.py | 5 +++++ 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index 532e56abba..1fdd1a4ca1 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -401,6 +401,6 @@ A configuration is ready for sweep only when the executable files agree, the exa The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) to MI355X AgentX: TP4, concurrency 1–32, native five-token DSpark. Throughput uses the [committed golden AL](../golden_al_distribution/dsv41flash_dspark.yaml) of 3.51 for thinking on and five draft tokens, with synthetic rejection sampling and adaptive verification disabled. Accuracy evals retain real block rejection and adaptive verification. FP4 describes the MXFP4 experts; the checkpoint also contains MXFP8 weights. -Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`. +Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`, and exports `INFMAX_CONTAINER_WORKSPACE=/ix` so AgentX dependencies and outputs resolve inside that mount. **GPU validation is pending:** The recipe uses `public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm`. Its public manifest was verified on 2026-09-11; image metadata includes ROCm and `gfx950`. This replaces the Docker Hub tag that returned HTTP 404 in run 34466680355. Engram behavior and serving compatibility still require GPU validation. Follow the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence) for runtime evidence; local generation and registry metadata are not GPU proof. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index f319557e13..b13c16553f 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -379,6 +379,6 @@ python -m pytest utils/matrix_logic/ -v 草案配方 `dsv41flash-fp4-mi355x-vllm-agentic-dspark` 将 [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) 扩展至 MI355X AgentX:TP4、并发 1–32、原生五 token DSpark。吞吐测试使用[已提交的黄金 AL](../golden_al_distribution/dsv41flash_dspark.yaml):thinking 开启、五个草稿 token 对应 3.51,采用合成拒绝采样并关闭自适应验证。准确率 eval 保留真实块拒绝采样和自适应验证。FP4 表示 MXFP4 专家权重;检查点还包含 MXFP8 权重。 -遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`。 +遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`,同时导出 `INFMAX_CONTAINER_WORKSPACE=/ix`,确保 AgentX 依赖与输出路径位于该挂载中。 **GPU 验证尚待完成:** 配方使用 `public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm`。2026-09-11 已验证其公开 manifest,镜像元数据包含 ROCm 和 `gfx950`。此镜像替代了在运行 34466680355 中返回 HTTP 404 的 Docker Hub 标签。Engram 行为与服务兼容性仍需 GPU 验证。请按 [AgentX 流程](./eval-agentx-procedures_zh.md) 获取运行时证据;本地矩阵生成和镜像元数据不等于 GPU 验证。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index f6383cb126..33d9906490 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7364,3 +7364,9 @@ - "Replace unavailable Docker Hub image with public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm" - "Keep TP4, DSpark settings, and the full-context semianalysis_cc_traces_weka_062126 corpus" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Set INFMAX_CONTAINER_WORKSPACE=/ix for the MI355X DS V4.1 mount so AgentX dependencies and outputs resolve correctly" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 diff --git a/runners/launch_mi355x-amds.sh b/runners/launch_mi355x-amds.sh index 185c4bd97d..accd850219 100644 --- a/runners/launch_mi355x-amds.sh +++ b/runners/launch_mi355x-amds.sh @@ -310,6 +310,7 @@ else if [[ "$MODEL" == "deepseek-ai/DeepSeek-V4.1-Flash" ]]; then export HF_HUB_CACHE_MOUNT="/it-share/hf-hub-cache/" CONTAINER_REPO=/ix + export INFMAX_CONTAINER_WORKSPACE="$CONTAINER_REPO" case "${RESULT_DIR:-}" in /workspace/*) export RESULT_DIR="/ix/${RESULT_DIR#/workspace/}" ;; esac diff --git a/runners/test_slurm_utils.py b/runners/test_slurm_utils.py index c93a0cbbc5..31fa6f2183 100644 --- a/runners/test_slurm_utils.py +++ b/runners/test_slurm_utils.py @@ -609,6 +609,8 @@ def test_mi355x_agentic_model_mount_and_routing( *--container-image=*) printf '%s\n' "$@" > "$CAPTURE" printf 'RESULT_DIR=%s\n' "$RESULT_DIR" >> "$CAPTURE" + bash -c 'source benchmarks/benchmark_lib.sh; + printf "%s\n" "$INFMAX_CONTAINER_WORKSPACE" "$AGENTIC_DIR" "$AIPERF_DIR"' > "$CAPTURE.paths" ;; esac } @@ -619,6 +621,9 @@ def test_mi355x_agentic_model_mount_and_routing( args = capture.read_text().splitlines() assert f"--container-workdir={mount}/" in args assert f"RESULT_DIR={mount}/results" in args + assert Path(f"{capture}.paths").read_text().splitlines() == [ + mount, f"{mount}/utils/agentic-benchmark", f"{mount}/utils/aiperf", + ] assert ( f"--container-mounts={REPO_ROOT}:{mount}/,{cache}:/mnt/hf_hub_cache/," "/it-share/aiperf-cache/:/aiperf_mmap_cache" From 1c11fb2fba9e3f8d7d3bbc124d79f6756f2a1ca4 Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Fri, 11 Sep 2026 19:29:03 +0800 Subject: [PATCH 06/11] fix: set VLLM_USE_BREAKABLE_CUDAGRAPH=1 for DSv4.1-Flash MI355X Upstream vLLM does not apply @support_torch_compile to DeepseekV41ForCausalLM, so the default cudagraph_mode=FULL_AND_PIECEWISE aborts at engine init ("piecewise CUDA graphs unavailable, model is not torch-compiled and breakable CUDA graph is off"). All concurrencies failed this way in run 34566727564. The model targets the breakable cudagraph path -- amd/attention.py imports eager_break_during_capture -- so enable it explicitly. Co-Authored-By: Claude Opus 5 (1M context) --- .../single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 5 +++++ perf-changelog.yaml | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh index 8a811944a7..a7947e8acf 100755 --- a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -23,6 +23,11 @@ if [[ -n "${ROCR_VISIBLE_DEVICES:-}" ]]; then fi export VLLM_ROCM_USE_AITER=1 export VLLM_ROCM_USE_AITER_MOE=1 +# DeepseekV41ForCausalLM is not torch-compiled upstream, so the default +# cudagraph_mode=FULL_AND_PIECEWISE aborts at engine init with "piecewise CUDA +# graphs unavailable" (run 34566727564). The model is built for the breakable +# cudagraph path -- amd/attention.py uses eager_break_during_capture. +export VLLM_USE_BREAKABLE_CUDAGRAPH=1 export OMP_NUM_THREADS=1 # Pin the full-context corpus for this 1M-context recipe. export WEKA_LOADER_OVERRIDE=semianalysis_cc_traces_weka_062126 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 33d9906490..3d8b69960c 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7370,3 +7370,9 @@ description: - "Set INFMAX_CONTAINER_WORKSPACE=/ix for the MI355X DS V4.1 mount so AgentX dependencies and outputs resolve correctly" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Set VLLM_USE_BREAKABLE_CUDAGRAPH=1. Upstream does not torch-compile DeepseekV41ForCausalLM, so the default cudagraph_mode=FULL_AND_PIECEWISE aborted at engine init with piecewise CUDA graphs unavailable (run 34566727564, all concurrencies); the model targets the breakable cudagraph path" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 From f3bd5bbbbb9f6bf6267b0a196cc5ae4416c8fb56 Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Fri, 11 Sep 2026 20:33:01 +0000 Subject: [PATCH 07/11] Use official vllm/vllm-openai-rocm:deepseekv41-flash-0909 image for DSv4.1 Flash MI355X The upstream vLLM recipe image is now public on Docker Hub (AMD-verified, pushed 2026-09-11). Replace the interim ECR release-repo image and update docs/changelog to match. --- .../single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 2 +- configs/amd-master.yaml | 4 ++-- docs/configuration-procedures.md | 2 +- docs/configuration-procedures_zh.md | 2 +- perf-changelog.yaml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh index a7947e8acf..dee7351732 100755 --- a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -3,7 +3,7 @@ set -eo pipefail # DeepSeek-V4.1-Flash on MI355X: native DSpark and GPU-resident KV. # Follow upstream AMD defaults for Engram; storage behavior needs verification. -# The ROCm release image is configured in amd-master.yaml; GPU validation is pending. +# Image: vllm/vllm-openai-rocm:deepseekv41-flash-0909 (configured in amd-master.yaml); GPU validation is pending. # https://github.com/vllm-project/recipes/blob/main/models/deepseek-ai/DeepSeek-V4.1-Flash.yaml source "$(dirname "$0")/../../benchmark_lib.sh" check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION diff --git a/configs/amd-master.yaml b/configs/amd-master.yaml index 47b63ceadb..3d9a3dccaf 100644 --- a/configs/amd-master.yaml +++ b/configs/amd-master.yaml @@ -1753,9 +1753,9 @@ dsv4-fp4-mi355x-sglang-agentic-mtp: - { tp: 8, ep: 1, dp-attn: false, kv-offloading: dram, kv-offload-backend: { name: hicache }, conc-list: [32, 48], spec-decoding: mtp } - { tp: 8, ep: 1, dp-attn: true, kv-offloading: dram, kv-offload-backend: { name: hicache }, conc-list: [128, 256], spec-decoding: mtp } -# ROCm release image; MI355X runtime validation is pending. +# Official upstream ROCm image from the vLLM recipe; MI355X runtime validation is pending. dsv41flash-fp4-mi355x-vllm-agentic-dspark: - image: public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm + image: vllm/vllm-openai-rocm:deepseekv41-flash-0909 model: deepseek-ai/DeepSeek-V4.1-Flash model-prefix: dsv41flash runner: cluster:mi355x-amds diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index 1fdd1a4ca1..da173ead58 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -403,4 +403,4 @@ The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](htt Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`, and exports `INFMAX_CONTAINER_WORKSPACE=/ix` so AgentX dependencies and outputs resolve inside that mount. -**GPU validation is pending:** The recipe uses `public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm`. Its public manifest was verified on 2026-09-11; image metadata includes ROCm and `gfx950`. This replaces the Docker Hub tag that returned HTTP 404 in run 34466680355. Engram behavior and serving compatibility still require GPU validation. Follow the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence) for runtime evidence; local generation and registry metadata are not GPU proof. +**GPU validation is pending:** The recipe uses `vllm/vllm-openai-rocm:deepseekv41-flash-0909`, the image referenced by the [upstream vLLM recipe](https://recipes.vllm.ai/deepseek-ai/DeepSeek-V4.1-Flash?hardware=mi355x). The tag was published to Docker Hub on 2026-09-11 after AMD verification; it returned HTTP 404 in run 34466680355 before publication. Engram behavior and serving compatibility still require GPU validation. Follow the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence) for runtime evidence; local generation and registry metadata are not GPU proof. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index b13c16553f..146965a7a7 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -381,4 +381,4 @@ python -m pytest utils/matrix_logic/ -v 遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`,同时导出 `INFMAX_CONTAINER_WORKSPACE=/ix`,确保 AgentX 依赖与输出路径位于该挂载中。 -**GPU 验证尚待完成:** 配方使用 `public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm`。2026-09-11 已验证其公开 manifest,镜像元数据包含 ROCm 和 `gfx950`。此镜像替代了在运行 34466680355 中返回 HTTP 404 的 Docker Hub 标签。Engram 行为与服务兼容性仍需 GPU 验证。请按 [AgentX 流程](./eval-agentx-procedures_zh.md) 获取运行时证据;本地矩阵生成和镜像元数据不等于 GPU 验证。 +**GPU 验证尚待完成:** 配方使用 `vllm/vllm-openai-rocm:deepseekv41-flash-0909`,即[上游 vLLM 配方](https://recipes.vllm.ai/deepseek-ai/DeepSeek-V4.1-Flash?hardware=mi355x)引用的镜像。该标签经 AMD 验证后于 2026-09-11 发布到 Docker Hub;发布前在运行 34466680355 中返回 HTTP 404。Engram 行为与服务兼容性仍需 GPU 验证。请按 [AgentX 流程](./eval-agentx-procedures_zh.md) 获取运行时证据;本地矩阵生成和镜像元数据不等于 GPU 验证。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 3d8b69960c..e5c057c035 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7343,7 +7343,7 @@ - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Add draft DeepSeek-V4.1-Flash FP4 AgentX on MI355X: TP4, concurrency 1-32, native five-token DSpark with adaptive real verification" - - "Use upstream ROCm AITER recipe with GPU-resident KV; image publication, Engram compatibility, and GPU validation pending" + - "Use upstream ROCm AITER recipe with GPU-resident KV on the official vllm/vllm-openai-rocm:deepseekv41-flash-0909 image; Engram compatibility and GPU validation pending" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 - config-keys: From 86699be610d5e6916eb6eb5b0c4a74676e8fb53d Mon Sep 17 00:00:00 2001 From: functionstackx <47992694+functionstackx@users.noreply.github.com> Date: Fri, 11 Sep 2026 19:19:45 -0400 Subject: [PATCH 08/11] fix: disable adaptive verification for MI355X DSpark evals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EVAL_ONLY speculative config enabled adaptive verification, which trims verification requests on device. The ROCm DeepseekV4IndexerBackend does not support that, so the eval-only engine refused to start (run 34651830283, c32). Keep real block rejection for evals; throughput settings are unchanged. EVAL_ONLY 的推测解码配置启用了自适应验证,它会在设备端裁剪验证请求;ROCm 的 DeepseekV4IndexerBackend 不支持该操作,导致仅评测引擎拒绝启动(运行 34651830283,c32)。评测仍保留真实块拒绝采样;吞吐设置不变。 Co-Authored-By: Claude Fable 5.1 --- .../single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 5 ++++- docs/configuration-procedures.md | 2 +- docs/configuration-procedures_zh.md | 2 +- perf-changelog.yaml | 7 +++++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh index dee7351732..40ec8d58a5 100755 --- a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -55,8 +55,11 @@ echo "Using vLLM endpoint ${AIPERF_SERVER_URL}" # Golden AL: golden_al_distribution/dsv41flash_dspark.yaml, thinking_on, five draft tokens. # Accuracy evals keep real block rejection; throughput fixes acceptance to AL 3.51. +# Adaptive verification stays off in both modes on ROCm: it trims verification +# requests on device, which DeepseekV4IndexerBackend does not support, so the +# engine refused to start with it enabled (run 34651830283, eval-only c32). if [[ "${EVAL_ONLY:-false}" == true ]]; then - SPEC_CONFIG='{"method":"dspark","num_speculative_tokens":5,"draft_sample_method":"probabilistic","rejection_sample_method":"block","enable_adaptive_verification":true}' + SPEC_CONFIG='{"method":"dspark","num_speculative_tokens":5,"draft_sample_method":"probabilistic","rejection_sample_method":"block","enable_adaptive_verification":false}' else SPEC_CONFIG='{"method":"dspark","num_speculative_tokens":5,"draft_sample_method":"probabilistic","rejection_sample_method":"synthetic","synthetic_acceptance_length":3.51,"enable_adaptive_verification":false}' fi diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index da173ead58..d853f6493e 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -399,7 +399,7 @@ A configuration is ready for sweep only when the executable files agree, the exa ## DeepSeek-V4.1-Flash on MI355X -The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) to MI355X AgentX: TP4, concurrency 1–32, native five-token DSpark. Throughput uses the [committed golden AL](../golden_al_distribution/dsv41flash_dspark.yaml) of 3.51 for thinking on and five draft tokens, with synthetic rejection sampling and adaptive verification disabled. Accuracy evals retain real block rejection and adaptive verification. FP4 describes the MXFP4 experts; the checkpoint also contains MXFP8 weights. +The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) to MI355X AgentX: TP4, concurrency 1–32, native five-token DSpark. Throughput uses the [committed golden AL](../golden_al_distribution/dsv41flash_dspark.yaml) of 3.51 for thinking on and five draft tokens, with synthetic rejection sampling and adaptive verification disabled. Accuracy evals retain real block rejection but, unlike the CUDA arms, also keep adaptive verification disabled: it trims verification requests on device, which the ROCm `DeepseekV4IndexerBackend` does not support, and the engine refused to start with it enabled ([run 34651830283](https://github.com/SemiAnalysisAI/InferenceX/actions/runs/34651830283)). FP4 describes the MXFP4 experts; the checkpoint also contains MXFP8 weights. Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`, and exports `INFMAX_CONTAINER_WORKSPACE=/ix` so AgentX dependencies and outputs resolve inside that mount. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index 146965a7a7..883f1f8e23 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -377,7 +377,7 @@ python -m pytest utils/matrix_logic/ -v ## MI355X 上的 DeepSeek-V4.1-Flash -草案配方 `dsv41flash-fp4-mi355x-vllm-agentic-dspark` 将 [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) 扩展至 MI355X AgentX:TP4、并发 1–32、原生五 token DSpark。吞吐测试使用[已提交的黄金 AL](../golden_al_distribution/dsv41flash_dspark.yaml):thinking 开启、五个草稿 token 对应 3.51,采用合成拒绝采样并关闭自适应验证。准确率 eval 保留真实块拒绝采样和自适应验证。FP4 表示 MXFP4 专家权重;检查点还包含 MXFP8 权重。 +草案配方 `dsv41flash-fp4-mi355x-vllm-agentic-dspark` 将 [#2958](https://github.com/SemiAnalysisAI/InferenceX/pull/2958) 扩展至 MI355X AgentX:TP4、并发 1–32、原生五 token DSpark。吞吐测试使用[已提交的黄金 AL](../golden_al_distribution/dsv41flash_dspark.yaml):thinking 开启、五个草稿 token 对应 3.51,采用合成拒绝采样并关闭自适应验证。准确率 eval 保留真实块拒绝采样,但与 CUDA 分支不同,同样关闭自适应验证:它会在设备端裁剪验证请求,而 ROCm 的 `DeepseekV4IndexerBackend` 不支持该操作,启用后引擎拒绝启动([运行 34651830283](https://github.com/SemiAnalysisAI/InferenceX/actions/runs/34651830283))。FP4 表示 MXFP4 专家权重;检查点还包含 MXFP8 权重。 遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`,同时导出 `INFMAX_CONTAINER_WORKSPACE=/ix`,确保 AgentX 依赖与输出路径位于该挂载中。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index e5c057c035..b53589a752 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7376,3 +7376,10 @@ description: - "Set VLLM_USE_BREAKABLE_CUDAGRAPH=1. Upstream does not torch-compile DeepseekV41ForCausalLM, so the default cudagraph_mode=FULL_AND_PIECEWISE aborted at engine init with piecewise CUDA graphs unavailable (run 34566727564, all concurrencies); the model targets the breakable cudagraph path" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Disable adaptive verification in the EVAL_ONLY DSpark config as well. It trims verification requests on device, which the ROCm DeepseekV4IndexerBackend does not support, so the eval-only engine refused to start (run 34651830283, c32). Evals keep real block rejection; throughput settings are unchanged." + - "EVAL_ONLY 的 DSpark 配置同样关闭自适应验证:它会在设备端裁剪验证请求,而 ROCm 的 DeepseekV4IndexerBackend 不支持该操作,导致仅评测引擎拒绝启动(运行 34651830283,c32)。评测仍保留真实块拒绝采样;吞吐设置不变。" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 From 55995353a5a6120294feabe20f5d6e77ab53b5a3 Mon Sep 17 00:00:00 2001 From: functionstackx <47992694+functionstackx@users.noreply.github.com> Date: Sat, 12 Sep 2026 00:17:34 +0000 Subject: [PATCH 09/11] fix(amd): validate quiet AITER automatic backend selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在 MI355X 配方启动前应用 AITER 静默自动后端补丁,保留后端选择和日志级别,并添加幂等性及分派测试。 Signed-off-by: functionstackx <47992694+functionstackx@users.noreply.github.com> --- .../agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 3 + docs/configuration-procedures.md | 2 + docs/configuration-procedures_zh.md | 2 + perf-changelog.yaml | 21 ++- runners/patch_aiter_quiet_auto_backend.py | 130 ++++++++++++++ runners/test_slurm_utils.py | 167 ++++++++++++++++++ 6 files changed, 318 insertions(+), 7 deletions(-) create mode 100644 runners/patch_aiter_quiet_auto_backend.py diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh index 40ec8d58a5..e012bd6468 100755 --- a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -10,6 +10,9 @@ check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION require_agentic_kv_offload_none export GPU_COUNT="$TP" +# Patch the installed AITER inside this serving container; keep backend selection. +python3 "$(dirname "${BASH_SOURCE[0]}")/../../../runners/patch_aiter_quiet_auto_backend.py" + # Complete/resume partial downloads instead of trusting nonempty directories. if [[ -n "${MODEL_PATH:-}" && "$MODEL_PATH" != "$MODEL" ]]; then hf download "$MODEL" --local-dir "$MODEL_PATH" diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index d853f6493e..79922d15dc 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -403,4 +403,6 @@ The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](htt Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`, and exports `INFMAX_CONTAINER_WORKSPACE=/ix` so AgentX dependencies and outputs resolve inside that mount. +Before model download or server startup, this recipe runs [`patch_aiter_quiet_auto_backend.py`](../runners/patch_aiter_quiet_auto_backend.py), equivalent to [AITER #5471](https://github.com/ROCm/aiter/pull/5471), against the installed AITER in the existing serving image. Automatic Gluon-to-Triton fallback is quiet; an unsupported explicit `backend="gluon"` request warns once per process. Backend selection, vLLM dispatch, and log levels are unchanged. The patcher rejects partial/unknown source before writing, accepts an already-patched file, and prints the target path plus before/after SHA256 hashes for provenance. + **GPU validation is pending:** The recipe uses `vllm/vllm-openai-rocm:deepseekv41-flash-0909`, the image referenced by the [upstream vLLM recipe](https://recipes.vllm.ai/deepseek-ai/DeepSeek-V4.1-Flash?hardware=mi355x). The tag was published to Docker Hub on 2026-09-11 after AMD verification; it returned HTTP 404 in run 34466680355 before publication. Engram behavior and serving compatibility still require GPU validation. Follow the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence) for runtime evidence; local generation and registry metadata are not GPU proof. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index 883f1f8e23..87a6d192ed 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -381,4 +381,6 @@ python -m pytest utils/matrix_logic/ -v 遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`,同时导出 `INFMAX_CONTAINER_WORKSPACE=/ix`,确保 AgentX 依赖与输出路径位于该挂载中。 +在下载模型或启动服务前,此配方通过 [`patch_aiter_quiet_auto_backend.py`](../runners/patch_aiter_quiet_auto_backend.py) 为现有服务镜像中安装的 AITER 应用与 [AITER #5471](https://github.com/ROCm/aiter/pull/5471) 等效的补丁。自动从 Gluon 回退至 Triton 时不再告警;显式请求不受支持的 `backend="gluon"` 时,每个进程只告警一次。Backend 选择、vLLM 调度和日志级别均保持不变。补丁脚本在写入前拒绝部分应用或未知源码,允许重复运行,并输出目标路径及修改前后的 SHA256,便于追溯。 + **GPU 验证尚待完成:** 配方使用 `vllm/vllm-openai-rocm:deepseekv41-flash-0909`,即[上游 vLLM 配方](https://recipes.vllm.ai/deepseek-ai/DeepSeek-V4.1-Flash?hardware=mi355x)引用的镜像。该标签经 AMD 验证后于 2026-09-11 发布到 Docker Hub;发布前在运行 34466680355 中返回 HTTP 404。Engram 行为与服务兼容性仍需 GPU 验证。请按 [AgentX 流程](./eval-agentx-procedures_zh.md) 获取运行时证据;本地矩阵生成和镜像元数据不等于 GPU 验证。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index b53589a752..9e78eed657 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7344,42 +7344,49 @@ description: - "Add draft DeepSeek-V4.1-Flash FP4 AgentX on MI355X: TP4, concurrency 1-32, native five-token DSpark with adaptive real verification" - "Use upstream ROCm AITER recipe with GPU-resident KV on the official vllm/vllm-openai-rocm:deepseekv41-flash-0909 image; Engram compatibility and GPU validation pending" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Pin AgentX to semianalysis_cc_traces_weka_062126, preventing the 256k corpus override" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Use thinking-on golden synthetic AL 3.51 for five-token DSpark throughput; disable adaptive verification and retain real verification for evals" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Replace unavailable Docker Hub image with public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm" - "Keep TP4, DSpark settings, and the full-context semianalysis_cc_traces_weka_062126 corpus" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Set INFMAX_CONTAINER_WORKSPACE=/ix for the MI355X DS V4.1 mount so AgentX dependencies and outputs resolve correctly" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Set VLLM_USE_BREAKABLE_CUDAGRAPH=1. Upstream does not torch-compile DeepseekV41ForCausalLM, so the default cudagraph_mode=FULL_AND_PIECEWISE aborted at engine init with piecewise CUDA graphs unavailable (run 34566727564, all concurrencies); the model targets the breakable cudagraph path" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Disable adaptive verification in the EVAL_ONLY DSpark config as well. It trims verification requests on device, which the ROCm DeepseekV4IndexerBackend does not support, so the eval-only engine refused to start (run 34651830283, c32). Evals keep real block rejection; throughput settings are unchanged." - "EVAL_ONLY 的 DSpark 配置同样关闭自适应验证:它会在设备端裁剪验证请求,而 ROCm 的 DeepseekV4IndexerBackend 不支持该操作,导致仅评测引擎拒绝启动(运行 34651830283,c32)。评测仍保留真实块拒绝采样;吞吐设置不变。" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/2962 + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Inherit the MI355X recipe from InferenceX #2962; apply AITER #5471 inside the existing serving image before startup: quiet automatic backend fallback and warn once for an unsupported explicit Gluon request; backend selection, vLLM dispatch, and log levels are unchanged." + - "继承 InferenceX #2962 的 MI355X 配方;启动前在现有服务镜像内应用 AITER #5471:自动 backend 回退不再告警,显式请求不受支持的 Gluon 时仅告警一次;backend 选择、vLLM 调度和日志级别不变。" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX diff --git a/runners/patch_aiter_quiet_auto_backend.py b/runners/patch_aiter_quiet_auto_backend.py new file mode 100644 index 0000000000..cfbdb399db --- /dev/null +++ b/runners/patch_aiter_quiet_auto_backend.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +"""Keep AITER automatic backend fallback quiet; warn once for explicit Gluon. + +Runtime equivalent of https://github.com/ROCm/aiter/pull/5471. +""" + +from __future__ import annotations + +import hashlib +import importlib.util +import sys +from pathlib import Path + +OLD_IMPORT = """import itertools + +import torch +""" +NEW_IMPORT = """import itertools +from functools import lru_cache + +import torch +""" +OLD_HELPER = """_GLUON_SUPPORTED_ARCHS = ("gfx1250",) + + +def _is_gluon_available(): +""" +NEW_HELPER = """_GLUON_SUPPORTED_ARCHS = ("gfx1250",) + + +@lru_cache(maxsize=1) +def _warn_gluon_fallback_once(): + _LOGGER.warning( + "Gluon was explicitly requested for moe_gemm_a16w4 but is not supported " + "on this GPU; using Triton." + ) + + +def _is_gluon_available(): +""" +OLD_DISPATCH = """ if backend in (None, "gluon"): + if _is_gluon_available(): + backend = "gluon" + else: + _LOGGER.warning("GLUON backend not available. Using TRITON backend!!!") + backend = "triton" + + backend = backend.lower() +""" +NEW_DISPATCH = """ if backend in (None, "gluon"): + if _is_gluon_available(): + backend = "gluon" + else: + if backend == "gluon": + _warn_gluon_fallback_once() + backend = "triton" + + backend = backend.lower() +""" +REPLACEMENTS = ( + (OLD_IMPORT, NEW_IMPORT), + (OLD_HELPER, NEW_HELPER), + (OLD_DISPATCH, NEW_DISPATCH), +) + + +def installed_backend_path() -> Path: + """Locate the backend from the installed AITER root without importing it.""" + spec = importlib.util.find_spec("aiter") + if spec is None or not spec.submodule_search_locations: + raise RuntimeError("aiter package is not installed") + package_root = Path(next(iter(spec.submodule_search_locations))) + return package_root / "ops/triton/moe/moe_op_gemm_a16w4.py" + + +def patch_backend(backend_path: Path) -> bool: + """Preflight all supported blocks before writing; return whether changed.""" + source_bytes = backend_path.read_bytes() + source = source_bytes.decode("utf-8") + states = [(source.count(old), source.count(new)) for old, new in REPLACEMENTS] + if all(state == (0, 1) for state in states): + changed = False + elif all(state == (1, 0) for state in states): + changed = True + else: + raise RuntimeError(f"partially patched or unsupported AITER backend at {backend_path}") + + # Reject stray/modified pieces even if the supported blocks also exist. + expected_markers = 0 if changed else 2 + if any( + source.count(marker) != expected_markers + for marker in ("lru_cache", "_warn_gluon_fallback_once") + ): + raise RuntimeError(f"partially patched or unsupported AITER backend at {backend_path}") + + patched = source + if changed: + for old, new in REPLACEMENTS: + patched = patched.replace(old, new) + patched_bytes = patched.encode("utf-8") + compile(patched_bytes, str(backend_path), "exec") + if changed: + backend_path.write_bytes(patched_bytes) + return changed + + +def main(argv: list[str]) -> int: + if len(argv) > 2: + print(f"Usage: {argv[0]} [BACKEND_PATH]", file=sys.stderr) + return 2 + + try: + backend_path = ( + Path(argv[1]) if len(argv) == 2 else installed_backend_path() + ).resolve() + before = hashlib.sha256(backend_path.read_bytes()).hexdigest() + changed = patch_backend(backend_path) + after = hashlib.sha256(backend_path.read_bytes()).hexdigest() + except (OSError, RuntimeError, SyntaxError, UnicodeError) as error: + print(f"ERROR: failed to patch AITER quiet auto backend: {error}", file=sys.stderr) + return 1 + + state = "Patch applied" if changed else "Already patched" + print(f"{state}: AITER quiet auto backend at {backend_path}") + print(f"SHA256 before={before} after={after}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv)) diff --git a/runners/test_slurm_utils.py b/runners/test_slurm_utils.py index 31fa6f2183..cae81e087f 100644 --- a/runners/test_slurm_utils.py +++ b/runners/test_slurm_utils.py @@ -1,8 +1,11 @@ +import hashlib import json import os import runpy import subprocess +import sys from pathlib import Path +from types import SimpleNamespace import pytest import yaml @@ -14,6 +17,7 @@ PATCH_SRT_DP_RANKS = REPO_ROOT / "runners" / "patch_srt_vllm_dp_ranks.py" PATCH_TRTLLM_CHAT_STORE = REPO_ROOT / "runners" / "patch_trtllm_chat_store.py" PATCH_VLLM_SIMPLE_KV = REPO_ROOT / "runners" / "patch_vllm_simple_kv_offload.py" +PATCH_AITER_QUIET = REPO_ROOT / "runners" / "patch_aiter_quiet_auto_backend.py" INJECT_ACCEPTANCE = REPO_ROOT / "runners" / "inject_synthetic_acceptance.py" @@ -419,6 +423,169 @@ def test_patch_vllm_simple_kv_offload_rejects_unknown_source( assert worker.read_text() == "unsupported worker\n" +@pytest.fixture +def aiter_backend_source() -> str: + # Independent, reduced upstream source: never assembled from patch constants. + return '''# Surrounding source must survive unchanged. +import itertools + +import torch + +_GLUON_SUPPORTED_ARCHS = ("gfx1250",) + + +def _is_gluon_available(): + return get_arch() in _GLUON_SUPPORTED_ARCHS + + +def moe_gemm_a16w4(backend=None): + if backend in (None, "gluon"): + if _is_gluon_available(): + backend = "gluon" + else: + _LOGGER.warning("GLUON backend not available. Using TRITON backend!!!") + backend = "triton" + + backend = backend.lower() + assert backend in ("triton", "gluon"), "Unknown backend" + return backend + + +UNCHANGED = "surrounding source" +''' + + +def test_patch_aiter_quiet_is_idempotent_with_provenance( + tmp_path: Path, aiter_backend_source: str, +) -> None: + backend = tmp_path / "backend.py" + backend.write_text(aiter_backend_source) + before = hashlib.sha256(backend.read_bytes()).hexdigest() + first = subprocess.run( + [sys.executable, str(PATCH_AITER_QUIET), str(backend)], + capture_output=True, text=True, check=False, + ) + patched = backend.read_bytes() + modified_at = backend.stat().st_mtime_ns + after = hashlib.sha256(patched).hexdigest() + second = subprocess.run( + [sys.executable, str(PATCH_AITER_QUIET), str(backend)], + capture_output=True, text=True, check=False, + ) + + assert first.returncode == second.returncode == 0, first.stderr + second.stderr + assert before != after + assert f"Patch applied: AITER quiet auto backend at {backend}" in first.stdout + assert f"SHA256 before={before} after={after}" in first.stdout + assert f"Already patched: AITER quiet auto backend at {backend}" in second.stdout + assert f"SHA256 before={after} after={after}" in second.stdout + assert backend.read_bytes() == patched + assert backend.stat().st_mtime_ns == modified_at + assert patched.startswith(b"# Surrounding source must survive unchanged.\n") + assert patched.endswith(b'UNCHANGED = "surrounding source"\n') + + +@pytest.mark.parametrize("arch", ["gfx942", "gfx950", "gfx1100", "gfx1250"]) +def test_patch_aiter_quiet_preserves_dispatch_and_warns_once( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, aiter_backend_source: str, arch: str, +) -> None: + backend = tmp_path / "backend.py" + backend.write_text(aiter_backend_source) + runpy.run_path(str(PATCH_AITER_QUIET))["patch_backend"](backend) + warnings: list[str] = [] + monkeypatch.setitem(sys.modules, "torch", SimpleNamespace()) + symbols = runpy.run_path( + str(backend), + init_globals={"get_arch": lambda: arch, "_LOGGER": SimpleNamespace(warning=warnings.append)}, + ) + dispatch = symbols["moe_gemm_a16w4"] + expected_auto = "gluon" if arch == "gfx1250" else "triton" + for _ in range(3): + assert dispatch() == expected_auto + assert dispatch("triton") == "triton" + assert warnings == [] + for _ in range(3): + assert dispatch("gluon") == expected_auto + assert dispatch() == expected_auto + assert len(warnings) == (0 if arch == "gfx1250" else 1) + if warnings: + assert "explicitly requested" in warnings[0] + with pytest.raises(AssertionError, match="Unknown backend"): + dispatch("invalid") + # Exercise the real cached helper independently of dispatch. + symbols["_warn_gluon_fallback_once"]() + symbols["_warn_gluon_fallback_once"]() + assert len(warnings) == 1 + + +@pytest.mark.parametrize( + "failure", ["partial-import", "partial-helper", "unknown", "duplicate", "syntax"], +) +def test_patch_aiter_quiet_preflights_before_writing( + tmp_path: Path, aiter_backend_source: str, failure: str, +) -> None: + if failure == "partial-import": + source = aiter_backend_source.replace( + "import itertools\n", "import itertools\nfrom functools import lru_cache\n", + ) + elif failure == "partial-helper": + source = aiter_backend_source + "\ndef _warn_gluon_fallback_once():\n pass\n" + elif failure == "unknown": + source = aiter_backend_source.replace("backend.lower()", "str(backend).lower()") + elif failure == "duplicate": + source = aiter_backend_source + aiter_backend_source + else: + source = aiter_backend_source + "\ndef invalid(:\n" + backend = tmp_path / "backend.py" + backend.write_bytes(source.encode()) + modified_at = backend.stat().st_mtime_ns + result = subprocess.run( + [sys.executable, str(PATCH_AITER_QUIET), str(backend)], + capture_output=True, text=True, check=False, + ) + assert result.returncode == 1 + assert "failed to patch AITER quiet auto backend" in result.stderr + assert "Patch applied" not in result.stdout + assert backend.read_bytes() == source.encode() + assert backend.stat().st_mtime_ns == modified_at + + +@pytest.mark.parametrize("supported", [True, False]) +def test_mi355x_recipe_patches_installed_aiter_before_download( + tmp_path: Path, aiter_backend_source: str, supported: bool, +) -> None: + package = tmp_path / "aiter" + backend = package / "ops/triton/moe/moe_op_gemm_a16w4.py" + backend.parent.mkdir(parents=True) + # Discovery must not import AITER (and initialize GPU dependencies). + (package / "__init__.py").write_text('raise AssertionError("AITER imported")\n') + original = aiter_backend_source if supported else "# unknown backend\n" + backend.write_text(original) + recipe = REPO_ROOT / "benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh" + result = subprocess.run( + ["bash", "-c", 'hf() { echo hf-called; exit 0; }; export -f hf; bash "$1"', + "bash", str(recipe)], + cwd=tmp_path, + env={ + **os.environ, "PYTHONPATH": str(tmp_path), "MODEL": "test/model", + "MODEL_PATH": "", "TP": "4", "CONC": "1", "KV_OFFLOADING": "none", + "KV_OFFLOAD_BACKEND": "", "TOTAL_CPU_DRAM_GB": "100", + "RESULT_DIR": str(tmp_path / "results"), "DURATION": "1", + "PYTHONPYCACHEPREFIX": str(tmp_path / "pycache"), + }, + capture_output=True, text=True, check=False, + ) + if supported: + assert result.returncode == 0, result.stderr + assert backend.read_text() != original + assert result.stdout.index("Patch applied") < result.stdout.index("hf-called") + assert str(backend) in result.stdout + else: + assert result.returncode == 1 + assert "hf-called" not in result.stdout + assert backend.read_text() == original + + def test_patch_srt_eval_dispatch_preflights_before_writing(tmp_path: Path) -> None: do_sweep = tmp_path / "src/srtctl/cli/do_sweep.py" eval_script = tmp_path / "src/srtctl/benchmarks/scripts/lm-eval/bench.sh" From bdfdff58175bbde29e51fe936cfa39de5d750865 Mon Sep 17 00:00:00 2001 From: functionstackx <47992694+functionstackx@users.noreply.github.com> Date: Sat, 12 Sep 2026 00:17:57 +0000 Subject: [PATCH 10/11] chore: link validation changelog to PR 3031 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将此验证分支新增的八条 changelog 关联到 PR #3031,保留主分支历史内容。 Signed-off-by: functionstackx <47992694+functionstackx@users.noreply.github.com> --- perf-changelog.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 9e78eed657..324aa5d7ff 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7344,49 +7344,49 @@ description: - "Add draft DeepSeek-V4.1-Flash FP4 AgentX on MI355X: TP4, concurrency 1-32, native five-token DSpark with adaptive real verification" - "Use upstream ROCm AITER recipe with GPU-resident KV on the official vllm/vllm-openai-rocm:deepseekv41-flash-0909 image; Engram compatibility and GPU validation pending" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Pin AgentX to semianalysis_cc_traces_weka_062126, preventing the 256k corpus override" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Use thinking-on golden synthetic AL 3.51 for five-token DSpark throughput; disable adaptive verification and retain real verification for evals" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Replace unavailable Docker Hub image with public.ecr.aws/q9t5s3a7/vllm-release-repo:79a7108d9aea27ddab99ce1779290d300b17fc23-rocm" - "Keep TP4, DSpark settings, and the full-context semianalysis_cc_traces_weka_062126 corpus" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Set INFMAX_CONTAINER_WORKSPACE=/ix for the MI355X DS V4.1 mount so AgentX dependencies and outputs resolve correctly" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Set VLLM_USE_BREAKABLE_CUDAGRAPH=1. Upstream does not torch-compile DeepseekV41ForCausalLM, so the default cudagraph_mode=FULL_AND_PIECEWISE aborted at engine init with piecewise CUDA graphs unavailable (run 34566727564, all concurrencies); the model targets the breakable cudagraph path" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Disable adaptive verification in the EVAL_ONLY DSpark config as well. It trims verification requests on device, which the ROCm DeepseekV4IndexerBackend does not support, so the eval-only engine refused to start (run 34651830283, c32). Evals keep real block rejection; throughput settings are unchanged." - "EVAL_ONLY 的 DSpark 配置同样关闭自适应验证:它会在设备端裁剪验证请求,而 ROCm 的 DeepseekV4IndexerBackend 不支持该操作,导致仅评测引擎拒绝启动(运行 34651830283,c32)。评测仍保留真实块拒绝采样;吞吐设置不变。" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 - config-keys: - dsv41flash-fp4-mi355x-vllm-agentic-dspark description: - "Inherit the MI355X recipe from InferenceX #2962; apply AITER #5471 inside the existing serving image before startup: quiet automatic backend fallback and warn once for an unsupported explicit Gluon request; backend selection, vLLM dispatch, and log levels are unchanged." - "继承 InferenceX #2962 的 MI355X 配方;启动前在现有服务镜像内应用 AITER #5471:自动 backend 回退不再告警,显式请求不受支持的 Gluon 时仅告警一次;backend 选择、vLLM 调度和日志级别不变。" - pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/XXX + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 From 1d894b495b32ff8ed15c76c9d97853d90ee2f742 Mon Sep 17 00:00:00 2001 From: functionstackx <47992694+functionstackx@users.noreply.github.com> Date: Sat, 12 Sep 2026 00:25:05 +0000 Subject: [PATCH 11/11] fix(amd): test AITER and vLLM backend patches together MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 联合应用 AITER 静默自动选择和 vLLM gfx942/gfx950 显式 Triton 补丁,保留日志级别并验证补丁来源与幂等性。 Signed-off-by: functionstackx <47992694+functionstackx@users.noreply.github.com> --- .../agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh | 3 +- docs/configuration-procedures.md | 2 +- docs/configuration-procedures_zh.md | 2 +- perf-changelog.yaml | 7 + runners/patch_vllm_w4a16_backend.py | 129 +++++++++++++ runners/test_slurm_utils.py | 182 +++++++++++++++++- 6 files changed, 315 insertions(+), 10 deletions(-) create mode 100644 runners/patch_vllm_w4a16_backend.py diff --git a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh index e012bd6468..4fcbd72a21 100755 --- a/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh +++ b/benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh @@ -10,8 +10,9 @@ check_env_vars MODEL TP CONC KV_OFFLOADING TOTAL_CPU_DRAM_GB RESULT_DIR DURATION require_agentic_kv_offload_none export GPU_COUNT="$TP" -# Patch the installed AITER inside this serving container; keep backend selection. +# Patch both installed libraries inside this serving container, before downloads. python3 "$(dirname "${BASH_SOURCE[0]}")/../../../runners/patch_aiter_quiet_auto_backend.py" +python3 "$(dirname "${BASH_SOURCE[0]}")/../../../runners/patch_vllm_w4a16_backend.py" # Complete/resume partial downloads instead of trusting nonempty directories. if [[ -n "${MODEL_PATH:-}" && "$MODEL_PATH" != "$MODEL" ]]; then diff --git a/docs/configuration-procedures.md b/docs/configuration-procedures.md index 79922d15dc..89b8a6683d 100644 --- a/docs/configuration-procedures.md +++ b/docs/configuration-procedures.md @@ -403,6 +403,6 @@ The draft `dsv41flash-fp4-mi355x-vllm-agentic-dspark` recipe extends [#2958](htt Follow the AMD overrides in [upstream recipe #946](https://github.com/vllm-project/recipes/pull/946): `VLLM_ROCM_USE_AITER=1`, `VLLM_ROCM_USE_AITER_MOE=1`, and `--moe-backend aiter_triton_mxfp4_bf16`. The recipe pins `semianalysis_cc_traces_weka_062126` (the unfiltered corpus) via `WEKA_LOADER_OVERRIDE`. KV stays GPU-resident; Engram follows upstream AMD defaults. Do not copy the NVIDIA `--engram-config` option: upstream currently rejects it on ROCm. The MI355X launcher uses the shared HF cache and mounts this model's repository at `/ix`, and exports `INFMAX_CONTAINER_WORKSPACE=/ix` so AgentX dependencies and outputs resolve inside that mount. -Before model download or server startup, this recipe runs [`patch_aiter_quiet_auto_backend.py`](../runners/patch_aiter_quiet_auto_backend.py), equivalent to [AITER #5471](https://github.com/ROCm/aiter/pull/5471), against the installed AITER in the existing serving image. Automatic Gluon-to-Triton fallback is quiet; an unsupported explicit `backend="gluon"` request warns once per process. Backend selection, vLLM dispatch, and log levels are unchanged. The patcher rejects partial/unknown source before writing, accepts an already-patched file, and prints the target path plus before/after SHA256 hashes for provenance. +Before model download or server startup, this recipe applies two patches inside the existing serving image. [`patch_aiter_quiet_auto_backend.py`](../runners/patch_aiter_quiet_auto_backend.py), equivalent to [AITER #5471](https://github.com/ROCm/aiter/pull/5471), keeps automatic Gluon-to-Triton fallback quiet and warns once per process for an unsupported explicit `backend="gluon"` request. [`patch_vllm_w4a16_backend.py`](../runners/patch_vllm_w4a16_backend.py) makes vLLM explicitly request `backend="triton"` for both W4A16 GEMMs on gfx942/gfx950; gfx1250 and other architectures retain automatic selection, and the MX scale swizzle is unchanged. Neither patch changes log levels. Both patchers reject partial/unknown source before writing, accept already-patched files, and print the target path plus before/after SHA256 hashes for provenance. **GPU validation is pending:** The recipe uses `vllm/vllm-openai-rocm:deepseekv41-flash-0909`, the image referenced by the [upstream vLLM recipe](https://recipes.vllm.ai/deepseek-ai/DeepSeek-V4.1-Flash?hardware=mi355x). The tag was published to Docker Hub on 2026-09-11 after AMD verification; it returned HTTP 404 in run 34466680355 before publication. Engram behavior and serving compatibility still require GPU validation. Follow the [AgentX procedure](./eval-agentx-procedures.md#7-run-agentx-fast-feedback-versus-canonical-evidence) for runtime evidence; local generation and registry metadata are not GPU proof. diff --git a/docs/configuration-procedures_zh.md b/docs/configuration-procedures_zh.md index 87a6d192ed..47030ffbab 100644 --- a/docs/configuration-procedures_zh.md +++ b/docs/configuration-procedures_zh.md @@ -381,6 +381,6 @@ python -m pytest utils/matrix_logic/ -v 遵循[上游配方 #946](https://github.com/vllm-project/recipes/pull/946) 的 AMD 设置:`VLLM_ROCM_USE_AITER=1`、`VLLM_ROCM_USE_AITER_MOE=1` 和 `--moe-backend aiter_triton_mxfp4_bf16`。配方通过 `WEKA_LOADER_OVERRIDE` 固定使用完整语料 `semianalysis_cc_traces_weka_062126`。KV 驻留 GPU;Engram 沿用上游 AMD 默认设置。不要复制 NVIDIA 的 `--engram-config` 选项:上游目前在 ROCm 上拒绝该选项。MI355X launcher 使用共享 HF 缓存,并将此模型的仓库挂载至 `/ix`,同时导出 `INFMAX_CONTAINER_WORKSPACE=/ix`,确保 AgentX 依赖与输出路径位于该挂载中。 -在下载模型或启动服务前,此配方通过 [`patch_aiter_quiet_auto_backend.py`](../runners/patch_aiter_quiet_auto_backend.py) 为现有服务镜像中安装的 AITER 应用与 [AITER #5471](https://github.com/ROCm/aiter/pull/5471) 等效的补丁。自动从 Gluon 回退至 Triton 时不再告警;显式请求不受支持的 `backend="gluon"` 时,每个进程只告警一次。Backend 选择、vLLM 调度和日志级别均保持不变。补丁脚本在写入前拒绝部分应用或未知源码,允许重复运行,并输出目标路径及修改前后的 SHA256,便于追溯。 +在下载模型或启动服务前,此配方在现有服务镜像内应用两个补丁。[`patch_aiter_quiet_auto_backend.py`](../runners/patch_aiter_quiet_auto_backend.py) 与 [AITER #5471](https://github.com/ROCm/aiter/pull/5471) 等效:自动从 Gluon 回退至 Triton 时不再告警,显式请求不受支持的 `backend="gluon"` 时每个进程只告警一次。[`patch_vllm_w4a16_backend.py`](../runners/patch_vllm_w4a16_backend.py) 让 vLLM 在 gfx942/gfx950 上对两个 W4A16 GEMM 显式传入 `backend="triton"`;gfx1250 和其他架构仍采用自动选择,MX scale swizzle 保持不变。两个补丁均不调整日志级别;脚本在写入前拒绝部分应用或未知源码,允许重复运行,并输出目标路径及修改前后的 SHA256,便于追溯。 **GPU 验证尚待完成:** 配方使用 `vllm/vllm-openai-rocm:deepseekv41-flash-0909`,即[上游 vLLM 配方](https://recipes.vllm.ai/deepseek-ai/DeepSeek-V4.1-Flash?hardware=mi355x)引用的镜像。该标签经 AMD 验证后于 2026-09-11 发布到 Docker Hub;发布前在运行 34466680355 中返回 HTTP 404。Engram 行为与服务兼容性仍需 GPU 验证。请按 [AgentX 流程](./eval-agentx-procedures_zh.md) 获取运行时证据;本地矩阵生成和镜像元数据不等于 GPU 验证。 diff --git a/perf-changelog.yaml b/perf-changelog.yaml index 324aa5d7ff..36aa4f4348 100644 --- a/perf-changelog.yaml +++ b/perf-changelog.yaml @@ -7390,3 +7390,10 @@ - "Inherit the MI355X recipe from InferenceX #2962; apply AITER #5471 inside the existing serving image before startup: quiet automatic backend fallback and warn once for an unsupported explicit Gluon request; backend selection, vLLM dispatch, and log levels are unchanged." - "继承 InferenceX #2962 的 MI355X 配方;启动前在现有服务镜像内应用 AITER #5471:自动 backend 回退不再告警,显式请求不受支持的 Gluon 时仅告警一次;backend 选择、vLLM 调度和日志级别不变。" pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 + +- config-keys: + - dsv41flash-fp4-mi355x-vllm-agentic-dspark + description: + - "Test both runtime patches together in the existing image: retain AITER #5471 quiet-auto fallback and add vLLM explicit Triton selection for both W4A16 GEMMs on gfx942/gfx950. Preserve automatic selection on gfx1250 and other architectures, MX scale swizzle, and log levels." + - "在现有镜像中联合测试两个运行时补丁:保留 AITER #5471 的静默自动回退,并让 vLLM 在 gfx942/gfx950 上为两个 W4A16 GEMM 显式选择 Triton。gfx1250 和其他架构的自动选择、MX scale swizzle 及日志级别保持不变。" + pr-link: https://github.com/SemiAnalysisAI/InferenceX/pull/3031 diff --git a/runners/patch_vllm_w4a16_backend.py b/runners/patch_vllm_w4a16_backend.py new file mode 100644 index 0000000000..5496327f6c --- /dev/null +++ b/runners/patch_vllm_w4a16_backend.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python3 +"""Request AITER Triton W4A16 GEMMs on gfx942/gfx950; retain auto elsewhere. + +Runtime equivalent of https://github.com/vllm-project/vllm/pull/56543. +""" + +from __future__ import annotations + +import hashlib +import importlib.util +import sys +from pathlib import Path + +OLD_IMPORT = """ from vllm.model_executor.layers.quantization.utils.mxfp4_utils import ( + should_use_cdna4_mx_scale_swizzle, + ) + from vllm.platforms.rocm import on_gfx1250 +""" +NEW_IMPORT = """ from vllm.model_executor.layers.quantization.utils.mxfp4_utils import ( + should_use_cdna4_mx_scale_swizzle, + ) + from vllm.platforms.rocm import on_gfx942, on_gfx950, on_gfx1250 +""" +OLD_SETUP = """ swz = "CDNA4_SCALE" if should_use_cdna4_mx_scale_swizzle() else None + + intermediate = moe_gemm_a16w4( +""" +NEW_SETUP = """ swz = "CDNA4_SCALE" if should_use_cdna4_mx_scale_swizzle() else None + + # This AITER Gluon GEMM is gfx1250-only. Preserve auto selection there. + gemm_backend = "triton" if on_gfx942() or on_gfx950() else None + + intermediate = moe_gemm_a16w4( +""" +OLD_FIRST_GEMM = """ swiglu_add_residual=swiglu_add_residual, + unpadded_N=unpadded_N_w1, + unpadded_K=unpadded_K_w1, + ) +""" +NEW_FIRST_GEMM = """ swiglu_add_residual=swiglu_add_residual, + unpadded_N=unpadded_N_w1, + unpadded_K=unpadded_K_w1, + backend=gemm_backend, + ) +""" +OLD_SECOND_GEMM = """ gammas=None if apply_router_weight_on_input else gammas, + swizzle_mx_scale=swz, + unpadded_N=unpadded_N_w2, + unpadded_K=unpadded_K_w2, + ) +""" +NEW_SECOND_GEMM = """ gammas=None if apply_router_weight_on_input else gammas, + swizzle_mx_scale=swz, + unpadded_N=unpadded_N_w2, + unpadded_K=unpadded_K_w2, + backend=gemm_backend, + ) +""" +REPLACEMENTS = ( + (OLD_IMPORT, NEW_IMPORT), + (OLD_SETUP, NEW_SETUP), + (OLD_FIRST_GEMM, NEW_FIRST_GEMM), + (OLD_SECOND_GEMM, NEW_SECOND_GEMM), +) + + +def installed_backend_path() -> Path: + """Locate the expert module from the installed vLLM root without importing it.""" + spec = importlib.util.find_spec("vllm") + if spec is None or not spec.submodule_search_locations: + raise RuntimeError("vllm package is not installed") + package_root = Path(next(iter(spec.submodule_search_locations))) + return package_root / "model_executor/layers/fused_moe/experts/aiter_mxfp4_w4a16_moe.py" + + +def patch_backend(backend_path: Path) -> bool: + """Preflight all four supported changes before writing; return whether changed.""" + source = backend_path.read_bytes().decode("utf-8") + states = [(source.count(old), source.count(new)) for old, new in REPLACEMENTS] + if all(state == (0, 1) for state in states): + changed = False + elif all(state == (1, 0) for state in states): + changed = True + else: + raise RuntimeError( + f"partially patched or unsupported vLLM W4A16 backend at {backend_path}" + ) + + # Reject stray or modified pieces even if all supported anchors also exist. + if source.count("gemm_backend") != (0 if changed else 3): + raise RuntimeError( + f"partially patched or unsupported vLLM W4A16 backend at {backend_path}" + ) + + patched = source + if changed: + for old, new in REPLACEMENTS: + patched = patched.replace(old, new) + patched_bytes = patched.encode("utf-8") + compile(patched_bytes, str(backend_path), "exec") + if changed: + backend_path.write_bytes(patched_bytes) + return changed + + +def main(argv: list[str]) -> int: + if len(argv) > 2: + print(f"Usage: {argv[0]} [BACKEND_PATH]", file=sys.stderr) + return 2 + + try: + backend_path = ( + Path(argv[1]) if len(argv) == 2 else installed_backend_path() + ).resolve() + before = hashlib.sha256(backend_path.read_bytes()).hexdigest() + changed = patch_backend(backend_path) + after = hashlib.sha256(backend_path.read_bytes()).hexdigest() + except (OSError, RuntimeError, SyntaxError, UnicodeError) as error: + print(f"ERROR: failed to patch vLLM W4A16 backend: {error}", file=sys.stderr) + return 1 + + state = "Patch applied" if changed else "Already patched" + print(f"{state}: vLLM W4A16 backend at {backend_path}") + print(f"SHA256 before={before} after={after}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main(sys.argv)) diff --git a/runners/test_slurm_utils.py b/runners/test_slurm_utils.py index cae81e087f..ecd55beb53 100644 --- a/runners/test_slurm_utils.py +++ b/runners/test_slurm_utils.py @@ -18,6 +18,7 @@ PATCH_TRTLLM_CHAT_STORE = REPO_ROOT / "runners" / "patch_trtllm_chat_store.py" PATCH_VLLM_SIMPLE_KV = REPO_ROOT / "runners" / "patch_vllm_simple_kv_offload.py" PATCH_AITER_QUIET = REPO_ROOT / "runners" / "patch_aiter_quiet_auto_backend.py" +PATCH_VLLM_W4A16 = REPO_ROOT / "runners" / "patch_vllm_w4a16_backend.py" INJECT_ACCEPTANCE = REPO_ROOT / "runners" / "inject_synthetic_acceptance.py" @@ -550,17 +551,176 @@ def test_patch_aiter_quiet_preflights_before_writing( assert backend.stat().st_mtime_ns == modified_at -@pytest.mark.parametrize("supported", [True, False]) -def test_mi355x_recipe_patches_installed_aiter_before_download( - tmp_path: Path, aiter_backend_source: str, supported: bool, +@pytest.fixture +def vllm_w4a16_source() -> str: + # Independent reduced wrapper, including both GEMMs and the scale contract. + return '''# Preserve unrelated source. +def forward( + swiglu_add_residual=True, apply_router_weight_on_input=False, gammas="weights", + unpadded_N_w1=11, unpadded_K_w1=12, unpadded_N_w2=21, unpadded_K_w2=22, +): + from vllm.model_executor.layers.quantization.utils.mxfp4_utils import ( + should_use_cdna4_mx_scale_swizzle, + ) + from vllm.platforms.rocm import on_gfx1250 + + swz = "CDNA4_SCALE" if should_use_cdna4_mx_scale_swizzle() else None + + intermediate = moe_gemm_a16w4( + "hidden_states", + "w1", + swizzle_mx_scale=swz, + swiglu_add_residual=swiglu_add_residual, + unpadded_N=unpadded_N_w1, + unpadded_K=unpadded_K_w1, + ) + + out = moe_gemm_a16w4( + intermediate, + "w2", + gammas=None if apply_router_weight_on_input else gammas, + swizzle_mx_scale=swz, + unpadded_N=unpadded_N_w2, + unpadded_K=unpadded_K_w2, + ) + + return out + + +def supports_device(): + from vllm.platforms.rocm import on_gfx942, on_gfx950, on_gfx1250 + return on_gfx942() or on_gfx950() or on_gfx1250() + + +UNCHANGED = "surrounding source" +''' + + +def test_patch_vllm_w4a16_is_idempotent_with_provenance( + tmp_path: Path, vllm_w4a16_source: str, +) -> None: + backend = tmp_path / "backend.py" + backend.write_text(vllm_w4a16_source) + before = hashlib.sha256(backend.read_bytes()).hexdigest() + first = subprocess.run( + [sys.executable, str(PATCH_VLLM_W4A16), str(backend)], + capture_output=True, text=True, check=False, + ) + patched = backend.read_bytes() + modified_at = backend.stat().st_mtime_ns + after = hashlib.sha256(patched).hexdigest() + second = subprocess.run( + [sys.executable, str(PATCH_VLLM_W4A16), str(backend)], + capture_output=True, text=True, check=False, + ) + assert first.returncode == second.returncode == 0, first.stderr + second.stderr + assert before != after + assert f"Patch applied: vLLM W4A16 backend at {backend}" in first.stdout + assert f"SHA256 before={before} after={after}" in first.stdout + assert f"Already patched: vLLM W4A16 backend at {backend}" in second.stdout + assert f"SHA256 before={after} after={after}" in second.stdout + assert backend.read_bytes() == patched + assert backend.stat().st_mtime_ns == modified_at + assert patched.startswith(b"# Preserve unrelated source.\n") + assert patched.endswith(b'UNCHANGED = "surrounding source"\n') + + +@pytest.mark.parametrize("arch", ["gfx942", "gfx950", "gfx1250", "gfx1100"]) +@pytest.mark.parametrize("swizzle", [True, False]) +def test_patch_vllm_w4a16_selects_both_gemms_and_preserves_swizzle( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, vllm_w4a16_source: str, + arch: str, swizzle: bool, +) -> None: + backend = tmp_path / "backend.py" + backend.write_text(vllm_w4a16_source) + runpy.run_path(str(PATCH_VLLM_W4A16))["patch_backend"](backend) + monkeypatch.setitem(sys.modules, "vllm.platforms.rocm", SimpleNamespace( + on_gfx942=lambda: arch == "gfx942", + on_gfx950=lambda: arch == "gfx950", + on_gfx1250=lambda: arch == "gfx1250", + )) + monkeypatch.setitem( + sys.modules, "vllm.model_executor.layers.quantization.utils.mxfp4_utils", + SimpleNamespace(should_use_cdna4_mx_scale_swizzle=lambda: swizzle), + ) + calls: list[tuple[tuple, dict]] = [] + + def gemm(*args, **kwargs): + calls.append((args, kwargs)) + return f"gemm-{len(calls)}" + + forward = runpy.run_path(str(backend), init_globals={"moe_gemm_a16w4": gemm})["forward"] + assert forward() == "gemm-2" + assert len(calls) == 2 + assert calls[1][0] == ("gemm-1", "w2") + expected_backend = "triton" if arch in ("gfx942", "gfx950") else None + assert [kwargs["backend"] for _, kwargs in calls] == [expected_backend] * 2 + expected_swizzle = "CDNA4_SCALE" if swizzle else None + assert [kwargs["swizzle_mx_scale"] for _, kwargs in calls] == [expected_swizzle] * 2 + assert [(kw["unpadded_N"], kw["unpadded_K"]) for _, kw in calls] == [(11, 12), (21, 22)] + assert calls[0][1]["swiglu_add_residual"] is True + assert calls[1][1]["gammas"] == "weights" + + +@pytest.mark.parametrize( + "failure", ["partial-import", "partial-gemm", "stray-setup", "unknown", "duplicate", "syntax"], +) +def test_patch_vllm_w4a16_preflights_before_writing( + tmp_path: Path, vllm_w4a16_source: str, failure: str, +) -> None: + if failure == "partial-import": + source = vllm_w4a16_source.replace( + "import on_gfx1250\n", "import on_gfx942, on_gfx950, on_gfx1250\n", + ) + elif failure == "partial-gemm": + source = vllm_w4a16_source.replace( + " unpadded_K=unpadded_K_w2,\n", + " unpadded_K=unpadded_K_w2,\n backend=gemm_backend,\n", + ) + elif failure == "stray-setup": + source = vllm_w4a16_source + '\ngemm_backend = "triton"\n' + elif failure == "unknown": + source = vllm_w4a16_source.replace( + "unpadded_N=unpadded_N_w2", "unpadded_N=None", + ) + elif failure == "duplicate": + source = vllm_w4a16_source + vllm_w4a16_source + else: + source = vllm_w4a16_source + "\ndef invalid(:\n" + backend = tmp_path / "backend.py" + backend.write_bytes(source.encode()) + modified_at = backend.stat().st_mtime_ns + result = subprocess.run( + [sys.executable, str(PATCH_VLLM_W4A16), str(backend)], + capture_output=True, text=True, check=False, + ) + assert result.returncode == 1 + assert "failed to patch vLLM W4A16 backend" in result.stderr + assert "Patch applied" not in result.stdout + assert backend.read_bytes() == source.encode() + assert backend.stat().st_mtime_ns == modified_at + + +@pytest.mark.parametrize("failure", [None, "aiter", "vllm"]) +def test_mi355x_recipe_patches_both_installed_libraries_before_download( + tmp_path: Path, aiter_backend_source: str, vllm_w4a16_source: str, + failure: str | None, ) -> None: package = tmp_path / "aiter" backend = package / "ops/triton/moe/moe_op_gemm_a16w4.py" backend.parent.mkdir(parents=True) # Discovery must not import AITER (and initialize GPU dependencies). (package / "__init__.py").write_text('raise AssertionError("AITER imported")\n') - original = aiter_backend_source if supported else "# unknown backend\n" + original = "# unknown backend\n" if failure == "aiter" else aiter_backend_source backend.write_text(original) + vllm_package = tmp_path / "vllm" + vllm_backend = ( + vllm_package / "model_executor/layers/fused_moe/experts/aiter_mxfp4_w4a16_moe.py" + ) + vllm_backend.parent.mkdir(parents=True) + (vllm_package / "__init__.py").write_text('raise AssertionError("vLLM imported")\n') + vllm_original = "# unknown backend\n" if failure == "vllm" else vllm_w4a16_source + vllm_backend.write_text(vllm_original) recipe = REPO_ROOT / "benchmarks/single_node/agentic/dsv41flash_fp4_mi355x_vllm_mtp.sh" result = subprocess.run( ["bash", "-c", 'hf() { echo hf-called; exit 0; }; export -f hf; bash "$1"', @@ -575,15 +735,23 @@ def test_mi355x_recipe_patches_installed_aiter_before_download( }, capture_output=True, text=True, check=False, ) - if supported: + if failure is None: assert result.returncode == 0, result.stderr assert backend.read_text() != original - assert result.stdout.index("Patch applied") < result.stdout.index("hf-called") + assert vllm_backend.read_text() != vllm_original + assert ( + result.stdout.index("AITER quiet auto backend at") + < result.stdout.index("vLLM W4A16 backend at") + < result.stdout.index("hf-called") + ) assert str(backend) in result.stdout + assert str(vllm_backend) in result.stdout else: assert result.returncode == 1 assert "hf-called" not in result.stdout - assert backend.read_text() == original + assert vllm_backend.read_text() == vllm_original + if failure == "aiter": + assert backend.read_text() == original def test_patch_srt_eval_dispatch_preflights_before_writing(tmp_path: Path) -> None: