From 94a3c6af47baa6303a2ee1a7e68fec7028df94aa Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 23:45:29 +0000 Subject: [PATCH 1/6] [AMD][CI] Stop scheduling the V3-0324/V3.1 MI30x nightly jobs nightly-8-gpu-deepseek-v31 and nightly-8-gpu-deepseek-v3-kv-fp8 do not test what their names say, and what they do test is already covered. Both serve deepseek-ai/DeepSeek-V3-0324 for their accuracy legs; only the v31 perf step serves V3.1. Every MI30x path they exercise -- aiter MLA under SGLANG_USE_AITER=1, EAGLE 3-1-4 MTP with an accept-length floor, enable_multithread_load, bs=1 send_one speed -- is exercised by the retained V3.2 basic and MTP jobs on a current checkpoint. Drops both jobs, their job_select options and their check-all-jobs needs. All four test files stay registered, so the three suites remain reachable from workflow_dispatch and manual runs. One combination is no longer covered on gfx942 by this workflow: MLA with --kv-cache-dtype fp8_e4m3. The closest retained gfx942 signal is test_glm51_perf_amd.py, which runs KV-FP8 on GLM-5.1 (also DSA/MLA). DeepSeek plus KV-FP8 stays covered on MI35x. The ROCm 7.0 nightly still schedules both jobs and is untouched here. Co-authored-by: quitenode --- .../workflows/nightly-test-amd-rocm720.yml | 103 ++---------------- 1 file changed, 7 insertions(+), 96 deletions(-) diff --git a/.github/workflows/nightly-test-amd-rocm720.yml b/.github/workflows/nightly-test-amd-rocm720.yml index fbea5306599a..d11c05876b25 100644 --- a/.github/workflows/nightly-test-amd-rocm720.yml +++ b/.github/workflows/nightly-test-amd-rocm720.yml @@ -59,11 +59,9 @@ on: # 8-GPU Grok2 (MI30x + MI35x) - nightly-8-gpu-grok2-rocm720 - nightly-8-gpu-mi35x-grok2-rocm720 - # 8-GPU DeepSeek-V3.x (MI30x) - - nightly-8-gpu-deepseek-v31-rocm720 + # 8-GPU DeepSeek-V3.2 (MI30x) - nightly-8-gpu-deepseek-v32-rocm720 - nightly-8-gpu-deepseek-v32-mtp-rocm720 - - nightly-8-gpu-deepseek-v3-kv-fp8-rocm720 # 8-GPU DeepSeek-V3.2 (MI35x) - nightly-accuracy-8-gpu-mi35x-deepseek-v32-rocm720 - nightly-accuracy-8-gpu-mi35x-deepseek-v32-mtp-rocm720 @@ -854,60 +852,13 @@ jobs: exit ${TEST_EXIT_CODE:-0} # ============================================================================== - # 8-GPU DeepSeek-V3.x (MI30x) + # 8-GPU DeepSeek-V3.2 (MI30x) + # + # V3-0324 and V3.1 are no longer scheduled here: V3.2 covers the same MI30x + # paths (aiter MLA, EAGLE MTP, multithread weight load) on a current + # checkpoint, and DeepSeek-R1/V4 carry the MI35x side. # ============================================================================== - nightly-8-gpu-deepseek-v31-rocm720: - name: ${{ format('nightly-8-gpu-deepseek-v31 ({0}, linux-mi300-8gpu-sglang)', matrix.rocm_version) }} - strategy: - fail-fast: false - matrix: - rocm_version: ${{ fromJson(inputs.rocm_version && inputs.rocm_version != 'all' && format('["{0}"]', inputs.rocm_version) || '["rocm724", "rocm720"]') }} - if: (github.repository == 'sgl-project/sglang' || github.event_name == 'pull_request') && (!(inputs.job_filter || inputs.job_select) || (inputs.job_filter || inputs.job_select) == 'all' || contains(format(',{0},', inputs.job_filter || inputs.job_select), ',nightly-8-gpu-deepseek-v31-rocm720,')) - runs-on: linux-mi300-8gpu-sglang - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - ref: ${{ inputs.ref || github.sha }} - - - name: Ensure VRAM is clear - run: bash scripts/ci/amd/ensure_vram_clear.sh rocm - - - name: Setup docker (${{ matrix.rocm_version }}) - run: | - touch github_summary.md - bash scripts/ci/amd/amd_ci_start_container.sh --rocm-version ${{ matrix.rocm_version }} - env: - GITHUB_WORKSPACE: ${{ github.workspace }} - ENABLE_CACHE_HOST: "1" - - - name: Install dependencies - run: bash scripts/ci/amd/amd_ci_install_dependency.sh --skip-test-time-deps - - - name: Accuracy Test ROCm 7.2 (8-GPU DeepSeek-V3.1) - timeout-minutes: 120 - run: | - > github_summary.md # Clear summary file - bash scripts/ci/amd/amd_ci_exec.sh -w /sglang-checkout/test \ - -e SGLANG_USE_AITER=1 \ - -e GITHUB_STEP_SUMMARY="/sglang-checkout/github_summary.md" \ - python3 run_suite.py --hw amd --suite nightly-amd-accuracy-8-gpu-deepseek-v31 --nightly --timeout-per-file 3600 ${{ (github.event_name == 'schedule' || inputs.continue_on_error) && '--continue-on-error' || '' }} || TEST_EXIT_CODE=$? - echo "$(> $GITHUB_STEP_SUMMARY || true - exit ${TEST_EXIT_CODE:-0} - - - name: Performance Test ROCm 7.2 (8-GPU DeepSeek-V3.1) - timeout-minutes: 300 - continue-on-error: true - run: | - > github_summary.md # Clear summary file - bash scripts/ci/amd/amd_ci_exec.sh -w /sglang-checkout/test \ - -e SGLANG_USE_ROCM700A=1 \ - -e GITHUB_STEP_SUMMARY="/sglang-checkout/github_summary.md" \ - python3 run_suite.py --hw amd --suite nightly-perf-8-gpu-deepseek-v31 --nightly --timeout-per-file 18000 ${{ (github.event_name == 'schedule' || inputs.continue_on_error) && '--continue-on-error' || '' }} || TEST_EXIT_CODE=$? - echo "$(> $GITHUB_STEP_SUMMARY || true - exit ${TEST_EXIT_CODE:-0} - nightly-8-gpu-deepseek-v32-rocm720: name: ${{ format('nightly-8-gpu-deepseek-v32 ({0}, linux-mi300-8gpu-sglang)', matrix.rocm_version) }} strategy: @@ -1006,44 +957,6 @@ jobs: echo "$(> $GITHUB_STEP_SUMMARY || true exit ${TEST_EXIT_CODE:-0} - nightly-8-gpu-deepseek-v3-kv-fp8-rocm720: - name: ${{ format('nightly-8-gpu-deepseek-v3-kv-fp8 ({0}, linux-mi300-8gpu-sglang)', matrix.rocm_version) }} - strategy: - fail-fast: false - matrix: - rocm_version: ${{ fromJson(inputs.rocm_version && inputs.rocm_version != 'all' && format('["{0}"]', inputs.rocm_version) || '["rocm724", "rocm720"]') }} - if: (github.repository == 'sgl-project/sglang' || github.event_name == 'pull_request') && (!(inputs.job_filter || inputs.job_select) || (inputs.job_filter || inputs.job_select) == 'all' || contains(format(',{0},', inputs.job_filter || inputs.job_select), ',nightly-8-gpu-deepseek-v3-kv-fp8-rocm720,')) - runs-on: linux-mi300-8gpu-sglang - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - ref: ${{ inputs.ref || github.sha }} - - - name: Ensure VRAM is clear - run: bash scripts/ci/amd/ensure_vram_clear.sh rocm - - - name: Setup docker (${{ matrix.rocm_version }}) - run: | - touch github_summary.md - bash scripts/ci/amd/amd_ci_start_container.sh --rocm-version ${{ matrix.rocm_version }} - env: - GITHUB_WORKSPACE: ${{ github.workspace }} - ENABLE_CACHE_HOST: "1" - - - name: Install dependencies - run: bash scripts/ci/amd/amd_ci_install_dependency.sh --skip-test-time-deps - - - name: DeepSeek-V3 KV FP8 Test ROCm 7.2 (8-GPU Basic + MTP) - timeout-minutes: 120 - run: | - > github_summary.md # Clear summary file - bash scripts/ci/amd/amd_ci_exec.sh -w /sglang-checkout/test \ - -e GITHUB_STEP_SUMMARY="/sglang-checkout/github_summary.md" \ - python3 run_suite.py --hw amd --suite nightly-amd-8-gpu-deepseek-v3-kv-fp8 --nightly --timeout-per-file 3600 ${{ (github.event_name == 'schedule' || inputs.continue_on_error) && '--continue-on-error' || '' }} || TEST_EXIT_CODE=$? - echo "$(> $GITHUB_STEP_SUMMARY || true - exit ${TEST_EXIT_CODE:-0} - # ============================================================================== # 8-GPU DeepSeek-V3.2 (MI35x) # ============================================================================== @@ -2346,11 +2259,9 @@ jobs: # 8-GPU Grok2 (MI30x + MI35x) - nightly-8-gpu-grok2-rocm720 - nightly-8-gpu-mi35x-grok2-rocm720 - # 8-GPU DeepSeek-V3.x (MI30x) - - nightly-8-gpu-deepseek-v31-rocm720 + # 8-GPU DeepSeek-V3.2 (MI30x) - nightly-8-gpu-deepseek-v32-rocm720 - nightly-8-gpu-deepseek-v32-mtp-rocm720 - - nightly-8-gpu-deepseek-v3-kv-fp8-rocm720 # 8-GPU DeepSeek-V3.2 (MI35x) - nightly-accuracy-8-gpu-mi35x-deepseek-v32-rocm720 - nightly-accuracy-8-gpu-mi35x-deepseek-v32-mtp-rocm720 From 09dc24221fe6bb13a82c156bb240d85f712d3d8e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 23:46:05 +0000 Subject: [PATCH 2/6] [AMD][CI] Add a DeepSeek-V4-Flash FP8 accuracy job on MI30x DeepSeek-V4 has no gfx942 coverage anywhere today: every DSV4 job in this workflow, in pr-test-amd-rocm720.yml and in the MI355X disagg nightly runs on linux-mi35x-gpu-8, and the ROCm 7.0 nightly has no DSV4 job at all. #36390 reports DSV4-Flash FP8 degrading with context length on 8x MI300X, which no existing job could have caught. Adds test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py (GSM8K, the same 8-shot eval and 0.91 floor as the MI35x FP8 test so the two architectures are comparable) and schedules it as nightly-8-gpu-deepseek-v4-flash on linux-mi300-8gpu-sglang. Accuracy only: there is no gfx942 DSV4 perf baseline to regress against until this job is green, and the MI35x jobs already carry the 8k/1k numbers. The launch config is the gfx942 one from #36390, the only DSV4-Flash FP8 configuration observed to serve on MI300X. It differs from the MI35x test only where gfx942 forces it: aiter attention and DSA backends instead of dsv4, SGLANG_OPT_SWIGLU_CLAMP_FUSION=0 because the fusion dispatches a CUDA-only kernel, and --moe-runner-backend triton because the aiter fused MoE is non-deterministic on gfx942. The job is deliberately left out of check-all-jobs while #36390 is open, so a known-red job does not fail the whole nightly. Both the job section and the needs list say so; move it into needs once it passes. Co-authored-by: quitenode --- .../workflows/nightly-test-amd-rocm720.yml | 60 ++++++++- .../amd/test_deepseek_v4_flash_fp8_mi30x.py | 127 ++++++++++++++++++ test/run_suite.py | 1 + 3 files changed, 185 insertions(+), 3 deletions(-) create mode 100644 test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py diff --git a/.github/workflows/nightly-test-amd-rocm720.yml b/.github/workflows/nightly-test-amd-rocm720.yml index d11c05876b25..9a5aeb099ac5 100644 --- a/.github/workflows/nightly-test-amd-rocm720.yml +++ b/.github/workflows/nightly-test-amd-rocm720.yml @@ -73,7 +73,9 @@ on: - nightly-8-gpu-mi35x-deepseek-r1-mxfp4-ar-fusion-rocm720 - nightly-8-gpu-mi35x-deepseek-r1-mxfp4-tp4-rocm720 - nightly-8-gpu-mi35x-deepseek-r1-hicache-rocm720 - # 8-GPU DeepSeek-V4 (MI35x only) + # 8-GPU DeepSeek-V4-Flash (MI30x) + - nightly-8-gpu-deepseek-v4-flash-rocm720 + # 8-GPU DeepSeek-V4 (MI35x) - nightly-8-gpu-mi35x-deepseek-v4-flash-rocm720 - nightly-8-gpu-mi35x-deepseek-v4-pro-rocm720 - nightly-8-gpu-mi35x-deepseek-v4-pro-mtp-rocm720 @@ -1376,7 +1378,58 @@ jobs: exit ${TEST_EXIT_CODE:-0} # ============================================================================== - # 8-GPU DeepSeek-V4 (MI35x only) + # 8-GPU DeepSeek-V4-Flash (MI30x) + # + # Accuracy only. This is the first DSV4 coverage on gfx942; the MI35x jobs + # below carry the perf numbers, and there is no gfx942 DSV4 baseline to + # regress against until this job is green. + # + # Deliberately absent from check-all-jobs: #36390 reports DSV4-Flash FP8 + # output degrading with context length on MI300X, so this is expected red + # until that is fixed. Add it to the needs list once it passes. + # ============================================================================== + + nightly-8-gpu-deepseek-v4-flash-rocm720: + name: ${{ format('nightly-8-gpu-deepseek-v4-flash ({0}, linux-mi300-8gpu-sglang)', matrix.rocm_version) }} + strategy: + fail-fast: false + matrix: + rocm_version: ${{ fromJson(inputs.rocm_version && inputs.rocm_version != 'all' && format('["{0}"]', inputs.rocm_version) || '["rocm724", "rocm720"]') }} + if: (github.repository == 'sgl-project/sglang' || github.event_name == 'pull_request') && (!(inputs.job_filter || inputs.job_select) || (inputs.job_filter || inputs.job_select) == 'all' || contains(format(',{0},', inputs.job_filter || inputs.job_select), ',nightly-8-gpu-deepseek-v4-flash-rocm720,')) + runs-on: linux-mi300-8gpu-sglang + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref || github.sha }} + + - name: Ensure VRAM is clear + run: bash scripts/ci/amd/ensure_vram_clear.sh rocm + + - name: Setup docker (${{ matrix.rocm_version }}) + run: | + touch github_summary.md + bash scripts/ci/amd/amd_ci_start_container.sh --rocm-version ${{ matrix.rocm_version }} + env: + GITHUB_WORKSPACE: ${{ github.workspace }} + ENABLE_CACHE_HOST: "1" + + - name: Install dependencies + run: bash scripts/ci/amd/amd_ci_install_dependency.sh --skip-test-time-deps + + - name: Accuracy Test ROCm 7.2 (8-GPU DeepSeek-V4-Flash FP8) + timeout-minutes: 180 + run: | + > github_summary.md # Clear summary file + bash scripts/ci/amd/amd_ci_exec.sh -w /sglang-checkout/test \ + -e SGLANG_MOE_COPY_WEIGHT_VIEWS_BEFORE_H2D=1 \ + -e GITHUB_STEP_SUMMARY="/sglang-checkout/github_summary.md" \ + python3 run_suite.py --hw amd --suite nightly-amd-accuracy-8-gpu-deepseek-v4-flash --nightly --timeout-per-file 5400 ${{ (github.event_name == 'schedule' || inputs.continue_on_error) && '--continue-on-error' || '' }} || TEST_EXIT_CODE=$? + echo "$(> $GITHUB_STEP_SUMMARY || true + exit ${TEST_EXIT_CODE:-0} + + # ============================================================================== + # 8-GPU DeepSeek-V4 (MI35x) # ============================================================================== nightly-8-gpu-mi35x-deepseek-v4-flash-rocm720: @@ -2273,7 +2326,8 @@ jobs: - nightly-8-gpu-mi35x-deepseek-r1-mxfp4-ar-fusion-rocm720 - nightly-8-gpu-mi35x-deepseek-r1-mxfp4-tp4-rocm720 - nightly-8-gpu-mi35x-deepseek-r1-hicache-rocm720 - # 8-GPU DeepSeek-V4 (MI35x only) + # 8-GPU DeepSeek-V4 (MI35x). The MI30x nightly-8-gpu-deepseek-v4-flash job + # is excluded on purpose while #36390 is open; see its section comment. - nightly-8-gpu-mi35x-deepseek-v4-flash-rocm720 - nightly-8-gpu-mi35x-deepseek-v4-pro-rocm720 - nightly-8-gpu-mi35x-deepseek-v4-pro-mtp-rocm720 diff --git a/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py b/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py new file mode 100644 index 000000000000..30814bbafd8f --- /dev/null +++ b/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py @@ -0,0 +1,127 @@ +"""MI30x DeepSeek-V4-Flash FP8 Accuracy Test (8-GPU) + +GSM8K few-shot accuracy for DeepSeek-V4-Flash FP8 on MI30x (gfx942) ROCm 7.2. + +Accuracy only: gfx942 has no DSV4 perf baseline to regress against yet, and the +MI35x suite already carries the 8k/1k throughput numbers. The GSM8K threshold +matches the MI35x FP8 test so the two architectures are directly comparable on +the same eval. + +The launch config below is the gfx942 one from #36390, which is the only +DSV4-Flash FP8 configuration observed to serve on 8x MI300X. It differs from the +MI35x test in three places, each forced by gfx942: + +- ``aiter`` attention and DSA backends rather than ``dsv4``. +- ``SGLANG_OPT_SWIGLU_CLAMP_FUSION=0``: the fusion dispatches a CUDA-only kernel. +- ``--moe-runner-backend triton``: the aiter fused MoE returns different logprobs + for identical greedy requests on gfx942. + +Registry: nightly-amd-accuracy-8-gpu-deepseek-v4-flash suite +""" + +import os +import unittest +from types import SimpleNamespace + +from sglang.srt.utils import kill_process_tree +from sglang.test.ci.ci_register import register_amd_ci +from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k +from sglang.test.test_utils import ( + DEFAULT_URL_FOR_TEST, + CustomTestCase, + is_in_ci, + popen_launch_server, + write_github_step_summary, +) + +register_amd_ci( + est_time=5400, + suite="nightly-amd-accuracy-8-gpu-deepseek-v4-flash", + nightly=True, +) + +DEEPSEEK_V4_FP8_MODEL_PATH = os.environ.get( + "DEEPSEEK_V4_FP8_MODEL_PATH", "sgl-project/DeepSeek-V4-Flash-FP8" +) +SERVER_LAUNCH_TIMEOUT = 3600 + +ENV_VARS = { + "SGLANG_DEFAULT_THINKING": "1", + "SGLANG_DSV4_REASONING_EFFORT": "max", + "SGLANG_DSV4_FP4_EXPERTS": "false", + "SGLANG_USE_AITER": "1", + "SGLANG_OPT_SWIGLU_CLAMP_FUSION": "0", +} + + +class TestDeepseekV4FlashFp8Mi30x(CustomTestCase): + @classmethod + def setUpClass(cls): + cls.model = DEEPSEEK_V4_FP8_MODEL_PATH + cls.base_url = DEFAULT_URL_FOR_TEST + + env = os.environ.copy() + env.update(ENV_VARS) + + other_args = [ + "--trust-remote-code", + "--tp", + "8", + "--attention-backend", + "aiter", + "--dsa-prefill-backend", + "aiter", + "--dsa-decode-backend", + "aiter", + "--moe-runner-backend", + "triton", + "--disable-radix-cache", + "--disable-cuda-graph", + "--max-running-requests", + "256", + "--mem-fraction-static", + "0.75", + "--chunked-prefill-size", + "8192", + "--disable-shared-experts-fusion", + "--tool-call-parser", + "deepseekv4", + "--reasoning-parser", + "deepseek-v4", + ] + + cls.process = popen_launch_server( + cls.model, + cls.base_url, + timeout=SERVER_LAUNCH_TIMEOUT, + other_args=other_args, + env=env, + ) + + @classmethod + def tearDownClass(cls): + kill_process_tree(cls.process.pid) + + def test_gsm8k(self): + args = SimpleNamespace( + num_shots=8, + data_path=None, + num_questions=1319, + parallel=1319, + max_new_tokens=512, + host="http://127.0.0.1", + port=int(self.base_url.split(":")[-1]), + ) + metrics = run_eval_few_shot_gsm8k(args) + print(f"{metrics=}") + + if is_in_ci(): + write_github_step_summary( + f"### test_gsm8k (deepseek-v4-flash-fp8, mi30x)\n" + f'{metrics["accuracy"]=:.3f}\n' + ) + self.assertGreater(metrics["accuracy"], 0.91) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/run_suite.py b/test/run_suite.py index 754db79c82c9..1963b01b92e8 100644 --- a/test/run_suite.py +++ b/test/run_suite.py @@ -147,6 +147,7 @@ "nightly-amd-4-gpu", "nightly-amd-8-gpu", "nightly-amd-vlm", + "nightly-amd-accuracy-8-gpu-deepseek-v4-flash", "nightly-amd-8-gpu-mi35x-deepseek-v4-flash", # MI35x 8-GPU suite (different model configs) "nightly-amd-8-gpu-mi35x", From e9bf815e53af7eabf321fc044ea492e3a0b21809 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 26 Aug 2026 00:16:31 +0000 Subject: [PATCH 3/6] [AMD][CI] Use the cookbook's verified MI300X recipe for the DSV4 accuracy test The first revision built its launch config from the #36390 reproducer. That was wrong: the cookbook already publishes an MI300X Flash FP8 cell marked verified: true, and CI should gate on the configuration the docs tell users to run rather than on one assembled from a bug report. Replaces the config with that cell verbatim -- the low-latency single-node one, the only TP-only MI300X strategy published (balanced and high-throughput add DP attention and the prefill delayer). The two configs disagree on nearly everything that matters: dsv4 attention backend rather than aiter, page-size 256, mem-fraction 0.90 rather than 0.75, cuda graphs on, the default MoE runner, plus --kv-cache-dtype fp8_e4m3, --swa-full-tokens-ratio 0.1 and EAGLE, none of which the reproducer used. Two consequences worth noting: - The recipe runs KV-FP8, so this job restores the gfx942 MLA + KV-FP8 coverage that dropping nightly-8-gpu-deepseek-v3-kv-fp8 removed. That coverage gap is no longer open. - #36390 exercises the aiter attention path, which this recipe does not touch, so a green run here would not contradict that report -- it would localize it. Co-authored-by: quitenode --- .../workflows/nightly-test-amd-rocm720.yml | 9 +-- .../amd/test_deepseek_v4_flash_fp8_mi30x.py | 61 +++++++++---------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.github/workflows/nightly-test-amd-rocm720.yml b/.github/workflows/nightly-test-amd-rocm720.yml index 9a5aeb099ac5..8e5663b7e018 100644 --- a/.github/workflows/nightly-test-amd-rocm720.yml +++ b/.github/workflows/nightly-test-amd-rocm720.yml @@ -1384,9 +1384,10 @@ jobs: # below carry the perf numbers, and there is no gfx942 DSV4 baseline to # regress against until this job is green. # - # Deliberately absent from check-all-jobs: #36390 reports DSV4-Flash FP8 - # output degrading with context length on MI300X, so this is expected red - # until that is fixed. Add it to the needs list once it passes. + # Deliberately absent from check-all-jobs for its first landing: the cookbook + # marks this recipe verified on MI300X but #36390 reports DSV4-Flash FP8 + # degrading with context length there, and no CI run has ever settled which + # holds. Add it to the needs list once it has passed. # ============================================================================== nightly-8-gpu-deepseek-v4-flash-rocm720: @@ -2327,7 +2328,7 @@ jobs: - nightly-8-gpu-mi35x-deepseek-r1-mxfp4-tp4-rocm720 - nightly-8-gpu-mi35x-deepseek-r1-hicache-rocm720 # 8-GPU DeepSeek-V4 (MI35x). The MI30x nightly-8-gpu-deepseek-v4-flash job - # is excluded on purpose while #36390 is open; see its section comment. + # is excluded on purpose for its first landing; see its section comment. - nightly-8-gpu-mi35x-deepseek-v4-flash-rocm720 - nightly-8-gpu-mi35x-deepseek-v4-pro-rocm720 - nightly-8-gpu-mi35x-deepseek-v4-pro-mtp-rocm720 diff --git a/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py b/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py index 30814bbafd8f..7ec37bd97c32 100644 --- a/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py +++ b/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py @@ -2,19 +2,20 @@ GSM8K few-shot accuracy for DeepSeek-V4-Flash FP8 on MI30x (gfx942) ROCm 7.2. +The launch config is the cookbook's MI300X Flash FP8 low-latency single-node +recipe, verbatim -- the one the docs tell users to run, marked `verified: true` +in docs/src/snippets/configs/deepseek-ai/deepseek-v4.jsx. Of the three published +MI300X strategies it is the only TP-only one (balanced and high-throughput add +DP attention and the prefill delayer), so it is the narrowest cell that still +covers the gfx942 serving path. Keep this in sync with that cell. + Accuracy only: gfx942 has no DSV4 perf baseline to regress against yet, and the MI35x suite already carries the 8k/1k throughput numbers. The GSM8K threshold -matches the MI35x FP8 test so the two architectures are directly comparable on -the same eval. - -The launch config below is the gfx942 one from #36390, which is the only -DSV4-Flash FP8 configuration observed to serve on 8x MI300X. It differs from the -MI35x test in three places, each forced by gfx942: +matches the MI35x FP8 test so the two architectures are comparable on the same +eval. -- ``aiter`` attention and DSA backends rather than ``dsv4``. -- ``SGLANG_OPT_SWIGLU_CLAMP_FUSION=0``: the fusion dispatches a CUDA-only kernel. -- ``--moe-runner-backend triton``: the aiter fused MoE returns different logprobs - for identical greedy requests on gfx942. +Unlike the MI35x FP8 test this recipe also runs `--kv-cache-dtype fp8_e4m3` and +EAGLE, so it is the gfx942 MLA + KV-FP8 signal as well. Registry: nightly-amd-accuracy-8-gpu-deepseek-v4-flash suite """ @@ -46,11 +47,9 @@ SERVER_LAUNCH_TIMEOUT = 3600 ENV_VARS = { - "SGLANG_DEFAULT_THINKING": "1", - "SGLANG_DSV4_REASONING_EFFORT": "max", - "SGLANG_DSV4_FP4_EXPERTS": "false", - "SGLANG_USE_AITER": "1", - "SGLANG_OPT_SWIGLU_CLAMP_FUSION": "0", + "SGLANG_USE_ROCM700A": "0", + "SGLANG_HACK_FLASHMLA_BACKEND": "unified_kv_triton", + "AITER_BF16_FP8_MOE_BOUND": "0", } @@ -68,26 +67,26 @@ def setUpClass(cls): "--tp", "8", "--attention-backend", - "aiter", - "--dsa-prefill-backend", - "aiter", - "--dsa-decode-backend", - "aiter", - "--moe-runner-backend", - "triton", - "--disable-radix-cache", - "--disable-cuda-graph", - "--max-running-requests", + "dsv4", + "--page-size", "256", "--mem-fraction-static", - "0.75", + "0.90", + "--swa-full-tokens-ratio", + "0.1", + "--disable-shared-experts-fusion", + "--kv-cache-dtype", + "fp8_e4m3", "--chunked-prefill-size", "8192", - "--disable-shared-experts-fusion", - "--tool-call-parser", - "deepseekv4", - "--reasoning-parser", - "deepseek-v4", + "--speculative-algorithm", + "EAGLE", + "--speculative-num-steps", + "3", + "--speculative-eagle-topk", + "1", + "--speculative-num-draft-tokens", + "4", ] cls.process = popen_launch_server( From fba6dd60db544bf48ef1d01fa11ac944e2a74d33 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 26 Aug 2026 01:21:34 +0000 Subject: [PATCH 4/6] [AMD][CI] Set SGLANG_DSV4_FP4_EXPERTS=0 for the MI30x DSV4 accuracy test The first MI300X run crashed during weight load, before GSM8K: all eight ranks died in FusedMoE._load_w13 with 'The size of tensor a (2048) must match the size of tensor b (4096)'. The factor of two is mxfp4 packing -- the FP8 checkpoint was being read at mxfp4 expert shapes. The env var defaults to mxfp4 and the auto-detect fallback in model_config.py reads the safetensors header out of the local HF cache, so on a runner that has not pulled the weights yet it returns None and the wrong default wins. The run's log has no 'Auto-detected DSV4 routed-expert layout' line, confirming that path. Setting it explicitly also makes the job independent of whether the runner's cache is warm, which otherwise makes this failure look flaky. The cookbook cell this test mirrors has the same omission, along with the other eight AMD FP8 cells; that is fixed in its own PR. With that fix the test's env and flags are set-equal to the cell again. Co-authored-by: quitenode --- test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py b/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py index 7ec37bd97c32..ee40c8f57e03 100644 --- a/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py +++ b/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py @@ -9,6 +9,9 @@ DP attention and the prefill delayer), so it is the narrowest cell that still covers the gfx942 serving path. Keep this in sync with that cell. +The cell as published could not load this checkpoint; the fix is in the +cookbook PR and is the SGLANG_DSV4_FP4_EXPERTS entry below. + Accuracy only: gfx942 has no DSV4 perf baseline to regress against yet, and the MI35x suite already carries the 8k/1k throughput numbers. The GSM8K threshold matches the MI35x FP8 test so the two architectures are comparable on the same @@ -47,6 +50,12 @@ SERVER_LAUNCH_TIMEOUT = 3600 ENV_VARS = { + # The routed experts of this checkpoint are FP8, not mxfp4-packed. The env + # default is mxfp4 and the auto-detect fallback reads the safetensors header + # from the local HF cache, so it returns None on a runner that has not pulled + # the weights yet and the wrong default wins -- weight load then dies on a + # factor-of-2 shape mismatch. Set it rather than depend on cache state. + "SGLANG_DSV4_FP4_EXPERTS": "0", "SGLANG_USE_ROCM700A": "0", "SGLANG_HACK_FLASHMLA_BACKEND": "unified_kv_triton", "AITER_BF16_FP8_MOE_BOUND": "0", From 44f9f4dd8fb97c9348b5192688adb037f0b2505c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 26 Aug 2026 02:15:01 +0000 Subject: [PATCH 5/6] [AMD][CI] Gate on the MI30x DSV4-Flash FP8 accuracy job It passed on 8x MI300X: GSM8K 0.9174 against the 0.91 floor, invalid 0.000, 42 min wall (run 32918680921). That was the condition the section comment set for moving it into check-all-jobs, so move it and drop the caveat. Gating also makes the MLA + KV-FP8 coverage real rather than merely reported: the cookbook recipe runs --kv-cache-dtype fp8_e4m3, so with this job blocking, dropping nightly-8-gpu-deepseek-v3-kv-fp8 leaves no gap on gfx942. The only job still outside check-all-jobs is nightly-test-1-gpu-kernel-rocm720, which pre-dates this PR. Co-authored-by: quitenode --- .github/workflows/nightly-test-amd-rocm720.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/nightly-test-amd-rocm720.yml b/.github/workflows/nightly-test-amd-rocm720.yml index 8e5663b7e018..d3cfac1276d6 100644 --- a/.github/workflows/nightly-test-amd-rocm720.yml +++ b/.github/workflows/nightly-test-amd-rocm720.yml @@ -1380,14 +1380,9 @@ jobs: # ============================================================================== # 8-GPU DeepSeek-V4-Flash (MI30x) # - # Accuracy only. This is the first DSV4 coverage on gfx942; the MI35x jobs - # below carry the perf numbers, and there is no gfx942 DSV4 baseline to - # regress against until this job is green. - # - # Deliberately absent from check-all-jobs for its first landing: the cookbook - # marks this recipe verified on MI300X but #36390 reports DSV4-Flash FP8 - # degrading with context length there, and no CI run has ever settled which - # holds. Add it to the needs list once it has passed. + # Accuracy only: the MI35x jobs below carry the DSV4 perf numbers, and gfx942 + # has no DSV4 perf baseline to regress against yet. Runs the cookbook's + # MI300X Flash FP8 low-latency cell, so it also covers MLA + KV-FP8 on gfx942. # ============================================================================== nightly-8-gpu-deepseek-v4-flash-rocm720: @@ -2327,8 +2322,9 @@ jobs: - nightly-8-gpu-mi35x-deepseek-r1-mxfp4-ar-fusion-rocm720 - nightly-8-gpu-mi35x-deepseek-r1-mxfp4-tp4-rocm720 - nightly-8-gpu-mi35x-deepseek-r1-hicache-rocm720 - # 8-GPU DeepSeek-V4 (MI35x). The MI30x nightly-8-gpu-deepseek-v4-flash job - # is excluded on purpose for its first landing; see its section comment. + # 8-GPU DeepSeek-V4-Flash (MI30x) + - nightly-8-gpu-deepseek-v4-flash-rocm720 + # 8-GPU DeepSeek-V4 (MI35x) - nightly-8-gpu-mi35x-deepseek-v4-flash-rocm720 - nightly-8-gpu-mi35x-deepseek-v4-pro-rocm720 - nightly-8-gpu-mi35x-deepseek-v4-pro-mtp-rocm720 From 5699cf29cee7adbf8ea6a926c16fc91cdf4862c0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 27 Aug 2026 00:13:46 +0000 Subject: [PATCH 6/6] [AMD][CI] Lower the MI30x DSV4 GSM8K floor to 0.90 The 0.91 floor was inherited from the MI35x FP8 test for comparability, on a single MI300X observation of 0.9174. A second run scored 0.9257, so the two observations span 0.83 points -- wider than the MI35x per-test run-to-run sd of about 0.0019, which is unsurprising given this recipe adds KV-FP8 and EAGLE on top of what the MI35x test runs. At that spread 0.91 sits roughly 2 sd below the mean, i.e. about one spurious failure per forty nights on a job that now blocks check-all-jobs. 0.90 leaves about 2 points of headroom and is over 3.5 sd out under either sd estimate. It does not weaken the gate in any way that matters: the failure modes this exists to catch collapse output entirely rather than costing a point of GSM8K. Comparability with MI35x is preserved where it actually lives -- in the measured numbers, MI300X 0.9174/0.9257 against MI35x 0.9189-0.9310 -- rather than in a shared threshold. Co-authored-by: quitenode --- .../amd/test_deepseek_v4_flash_fp8_mi30x.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py b/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py index ee40c8f57e03..d52e41b88dee 100644 --- a/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py +++ b/test/registered/amd/test_deepseek_v4_flash_fp8_mi30x.py @@ -13,12 +13,16 @@ cookbook PR and is the SGLANG_DSV4_FP4_EXPERTS entry below. Accuracy only: gfx942 has no DSV4 perf baseline to regress against yet, and the -MI35x suite already carries the 8k/1k throughput numbers. The GSM8K threshold -matches the MI35x FP8 test so the two architectures are comparable on the same -eval. +MI35x suite already carries the 8k/1k throughput numbers. Unlike the MI35x FP8 test this recipe also runs `--kv-cache-dtype fp8_e4m3` and -EAGLE, so it is the gfx942 MLA + KV-FP8 signal as well. +EAGLE, so it is the gfx942 MLA + KV-FP8 signal as well. That extra quantization +is also why the threshold below is 0.90 rather than the 0.91 the MI35x FP8 test +uses: measured 0.9174 and 0.9257 here, a spread wide enough that 0.91 would sit +only ~2 sd off the mean and fail a good build roughly one night in forty. 0.90 +keeps ~2 points of headroom and still catches every regression worth gating on +-- the failure modes this guards against (see #36390) collapse output entirely +rather than shaving a point. Registry: nightly-amd-accuracy-8-gpu-deepseek-v4-flash suite """ @@ -128,7 +132,7 @@ def test_gsm8k(self): f"### test_gsm8k (deepseek-v4-flash-fp8, mi30x)\n" f'{metrics["accuracy"]=:.3f}\n' ) - self.assertGreater(metrics["accuracy"], 0.91) + self.assertGreater(metrics["accuracy"], 0.90) if __name__ == "__main__":