[AMD] Add GLM-5.2 MI35x nightly accuracy and perf benchmark (#32570)
This commit is contained in:
@@ -82,9 +82,10 @@ on:
|
|||||||
- nightly-8-gpu-qwen35-rocm720
|
- nightly-8-gpu-qwen35-rocm720
|
||||||
- nightly-8-gpu-mi35x-qwen35-rocm720
|
- nightly-8-gpu-mi35x-qwen35-rocm720
|
||||||
- nightly-8-gpu-mi35x-qwen35-triton-dcp-rocm720
|
- nightly-8-gpu-mi35x-qwen35-triton-dcp-rocm720
|
||||||
# 8-GPU GLM-5.1 (MI30x + MI35x)
|
# 8-GPU GLM-5.1 (MI30x)
|
||||||
- nightly-8-gpu-glm51-rocm720
|
- nightly-8-gpu-glm51-rocm720
|
||||||
- nightly-8-gpu-mi35x-glm51-rocm720
|
# 8-GPU GLM-5.2-FP8 (MI35x accuracy + performance)
|
||||||
|
- nightly-8-gpu-mi35x-glm52-fp8-rocm720
|
||||||
# 8-GPU GLM-5-MXFP4 (MI35x only)
|
# 8-GPU GLM-5-MXFP4 (MI35x only)
|
||||||
- nightly-8-gpu-mi35x-glm5-mxfp4-rocm720
|
- nightly-8-gpu-mi35x-glm5-mxfp4-rocm720
|
||||||
# 4-GPU MiniMax-M2.5 (MI35x)
|
# 4-GPU MiniMax-M2.5 (MI35x)
|
||||||
@@ -1852,8 +1853,12 @@ jobs:
|
|||||||
echo "$(<github_summary.md )" >> $GITHUB_STEP_SUMMARY || true
|
echo "$(<github_summary.md )" >> $GITHUB_STEP_SUMMARY || true
|
||||||
exit ${TEST_EXIT_CODE:-0}
|
exit ${TEST_EXIT_CODE:-0}
|
||||||
|
|
||||||
nightly-8-gpu-mi35x-glm51-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-mi35x-glm51-rocm720,'))
|
# 8-GPU GLM-5.2-FP8 (MI35x accuracy + performance)
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
nightly-8-gpu-mi35x-glm52-fp8-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-mi35x-glm52-fp8-rocm720,'))
|
||||||
runs-on: linux-mi35x-gpu-8
|
runs-on: linux-mi35x-gpu-8
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
@@ -1870,30 +1875,35 @@ jobs:
|
|||||||
bash scripts/ci/amd/amd_ci_start_container.sh --rocm-version rocm720
|
bash scripts/ci/amd/amd_ci_start_container.sh --rocm-version rocm720
|
||||||
env:
|
env:
|
||||||
GITHUB_WORKSPACE: ${{ github.workspace }}
|
GITHUB_WORKSPACE: ${{ github.workspace }}
|
||||||
|
ENABLE_CACHE_HOST: "1"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
bash scripts/ci/amd/amd_ci_install_dependency.sh --skip-test-time-deps
|
bash scripts/ci/amd/amd_ci_install_dependency.sh --skip-test-time-deps
|
||||||
bash scripts/ci/amd/amd_ci_exec.sh pip install tabulate
|
bash scripts/ci/amd/amd_ci_exec.sh pip install tabulate
|
||||||
|
|
||||||
- name: Accuracy Test MI35x ROCm 7.2 (8-GPU GLM-5.1 DSA)
|
# The ~700 GB FP8 checkpoint means weight download and load dominate wall
|
||||||
|
# time well before the eval itself starts.
|
||||||
|
- name: Accuracy Test MI35x ROCm 7.2 (8-GPU GLM-5.2-FP8 DSA)
|
||||||
timeout-minutes: 180
|
timeout-minutes: 180
|
||||||
run: |
|
run: |
|
||||||
> github_summary.md # Clear summary file
|
> github_summary.md # Clear summary file
|
||||||
bash scripts/ci/amd/amd_ci_exec.sh -w /sglang-checkout/test \
|
bash scripts/ci/amd/amd_ci_exec.sh -w /sglang-checkout/test \
|
||||||
-e GITHUB_STEP_SUMMARY="/sglang-checkout/github_summary.md" \
|
-e GITHUB_STEP_SUMMARY="/sglang-checkout/github_summary.md" \
|
||||||
python3 run_suite.py --hw amd --suite nightly-amd-8-gpu-mi35x-glm51 --nightly --timeout-per-file 7200 ${{ (github.event_name == 'schedule' || inputs.continue_on_error) && '--continue-on-error' || '' }} || TEST_EXIT_CODE=$?
|
python3 run_suite.py --hw amd --suite nightly-amd-8-gpu-mi35x-glm52-fp8 --nightly --timeout-per-file 7200 ${{ (github.event_name == 'schedule' || inputs.continue_on_error) && '--continue-on-error' || '' }} || TEST_EXIT_CODE=$?
|
||||||
echo "$(<github_summary.md )" >> $GITHUB_STEP_SUMMARY || true
|
echo "$(<github_summary.md )" >> $GITHUB_STEP_SUMMARY || true
|
||||||
exit ${TEST_EXIT_CODE:-0}
|
exit ${TEST_EXIT_CODE:-0}
|
||||||
|
|
||||||
- name: Performance Test MI35x ROCm 7.2 (8-GPU GLM-5.1)
|
# Run perf only after correctness passes. Keeping both steps in this job
|
||||||
|
# reuses the cached ~700 GB checkpoint and one scarce 8-GPU MI35x slot.
|
||||||
|
- name: Performance Test MI35x ROCm 7.2 (8-GPU GLM-5.2-FP8)
|
||||||
timeout-minutes: 120
|
timeout-minutes: 120
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
> github_summary.md # Clear summary file
|
> github_summary.md # Clear summary file
|
||||||
bash scripts/ci/amd/amd_ci_exec.sh -w /sglang-checkout/test \
|
bash scripts/ci/amd/amd_ci_exec.sh -w /sglang-checkout/test \
|
||||||
-e GITHUB_STEP_SUMMARY="/sglang-checkout/github_summary.md" \
|
-e GITHUB_STEP_SUMMARY="/sglang-checkout/github_summary.md" \
|
||||||
python3 run_suite.py --hw amd --suite nightly-perf-8-gpu-mi35x-glm51 --nightly --timeout-per-file 5400 ${{ (github.event_name == 'schedule' || inputs.continue_on_error) && '--continue-on-error' || '' }} || TEST_EXIT_CODE=$?
|
python3 run_suite.py --hw amd --suite nightly-perf-8-gpu-mi35x-glm52-fp8 --nightly --timeout-per-file 5400 ${{ (github.event_name == 'schedule' || inputs.continue_on_error) && '--continue-on-error' || '' }} || TEST_EXIT_CODE=$?
|
||||||
echo "$(<github_summary.md )" >> $GITHUB_STEP_SUMMARY || true
|
echo "$(<github_summary.md )" >> $GITHUB_STEP_SUMMARY || true
|
||||||
exit ${TEST_EXIT_CODE:-0}
|
exit ${TEST_EXIT_CODE:-0}
|
||||||
|
|
||||||
@@ -2175,9 +2185,10 @@ jobs:
|
|||||||
- nightly-8-gpu-qwen35-rocm720
|
- nightly-8-gpu-qwen35-rocm720
|
||||||
- nightly-8-gpu-mi35x-qwen35-rocm720
|
- nightly-8-gpu-mi35x-qwen35-rocm720
|
||||||
- nightly-8-gpu-mi35x-qwen35-triton-dcp-rocm720
|
- nightly-8-gpu-mi35x-qwen35-triton-dcp-rocm720
|
||||||
# 8-GPU GLM-5.1 (MI30x + MI35x)
|
# 8-GPU GLM-5.1 (MI30x)
|
||||||
- nightly-8-gpu-glm51-rocm720
|
- nightly-8-gpu-glm51-rocm720
|
||||||
- nightly-8-gpu-mi35x-glm51-rocm720
|
# 8-GPU GLM-5.2-FP8 (MI35x accuracy + performance)
|
||||||
|
- nightly-8-gpu-mi35x-glm52-fp8-rocm720
|
||||||
# 8-GPU GLM-5-MXFP4 (MI35x only)
|
# 8-GPU GLM-5-MXFP4 (MI35x only)
|
||||||
- nightly-8-gpu-mi35x-glm5-mxfp4-rocm720
|
- nightly-8-gpu-mi35x-glm5-mxfp4-rocm720
|
||||||
# 4-GPU MiniMax-M2.5 (MI35x)
|
# 4-GPU MiniMax-M2.5 (MI35x)
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
"""MI35x GLM-5.2-FP8 GSM8K Accuracy Evaluation Test (8-GPU)
|
||||||
|
|
||||||
|
Tests zai-org/GLM-5.2-FP8 with the DSA tilelang backend on MI35x (gfx950).
|
||||||
|
|
||||||
|
Server arguments track the GLM-5.2 cookbook's MI355X / FP8 / low-latency /
|
||||||
|
single-node cell: TP8, DSA tilelang prefill+decode, 131072 chunked prefill,
|
||||||
|
0.80 static memory fraction, and a 20-minute watchdog for weight loading.
|
||||||
|
That cell ships as `verified: true` with published benchmarks, but nothing in
|
||||||
|
CI re-checks it, so this nightly is what keeps it honest.
|
||||||
|
|
||||||
|
gfx950 is the arch that needs the guard. An earlier ROCm 7.2 miscompile of
|
||||||
|
aiter's block-FP8 `gemm_a8w8_blockscale_bpreshuffle` GEMM was small per layer
|
||||||
|
but compounded across all 78 layers: GSM8K collapsed to ~0 while short factual
|
||||||
|
prompts still looked fine. Only a multi-step reasoning eval catches that class
|
||||||
|
of regression, and MI300X/MI325X (gfx942) were never affected -- hence MI35x
|
||||||
|
only.
|
||||||
|
|
||||||
|
ROCm 7.2 only, and that is a measured decision rather than a cautious one. Both
|
||||||
|
lanes were run on current same-day images (`v0.5.16-rocm7{00,20}-mi35x-20260727`)
|
||||||
|
and 7.2 scored 0.931 while 7.0 scored 0.270. The 7.0 image ships Triton 3.4.0,
|
||||||
|
which is below the >=3.5.0 the aiter gluon DSA kernels need, so it logs
|
||||||
|
"falling back to legacy page_size=1 / KVBlockSize=1 path" and that fallback is
|
||||||
|
what loses the accuracy. Re-add a 7.0 job once its image ships Triton >=3.5.0,
|
||||||
|
or once the legacy DSA fallback is fixed on gfx950.
|
||||||
|
|
||||||
|
The eval matches the CUDA GLM-5.2-FP8 nightly (`test/registered/8-gpu-models/
|
||||||
|
test_glm52_fp8.py`): same dataset and same 0.92 baseline, so a red run here
|
||||||
|
means AMD diverged from CUDA rather than the harness diverging.
|
||||||
|
|
||||||
|
Headroom is thinner than the cookbook's ~0.96 suggests: this harness measured
|
||||||
|
0.931 against a 0.92 baseline. The cookbook number comes from a different GSM8K
|
||||||
|
setup, so the two are not directly comparable, but it does mean a ~1 point
|
||||||
|
regression trips this test. Treat a marginal failure as worth reading rather
|
||||||
|
than as noise to retry away.
|
||||||
|
|
||||||
|
Accuracy runs before the companion performance benchmark in the same workflow
|
||||||
|
job. A correctness failure therefore skips performance, while a green result
|
||||||
|
lets the benchmark reuse the cached checkpoint and the same scarce runner slot.
|
||||||
|
|
||||||
|
Registry: nightly-amd-8-gpu-mi35x-glm52-fp8 suite
|
||||||
|
"""
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from sglang.test.accuracy_test_runner import AccuracyTestParams
|
||||||
|
from sglang.test.ci.ci_register import register_amd_ci
|
||||||
|
from sglang.test.run_combined_tests import run_combined_tests
|
||||||
|
from sglang.test.test_utils import ModelLaunchSettings
|
||||||
|
|
||||||
|
# Register for AMD CI - MI35x GLM-5.2-FP8 accuracy test (~90 min: the ~700 GB
|
||||||
|
# FP8 checkpoint dominates startup, then GSM8K 5-shot at TP8)
|
||||||
|
register_amd_ci(
|
||||||
|
est_time=5400,
|
||||||
|
suite="nightly-amd-8-gpu-mi35x-glm52-fp8",
|
||||||
|
nightly=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
GLM_52_FP8_MODEL_PATH = "zai-org/GLM-5.2-FP8"
|
||||||
|
|
||||||
|
# Fetching and loading a ~700 GB checkpoint against a cold cache is what this
|
||||||
|
# budget has to cover; the default launch timeout is nowhere near enough.
|
||||||
|
SERVER_LAUNCH_TIMEOUT = 5400
|
||||||
|
|
||||||
|
|
||||||
|
class TestGLM52FP8EvalMI35x(unittest.TestCase):
|
||||||
|
"""GLM-5.2-FP8 GSM8K Accuracy Evaluation Test for MI35x."""
|
||||||
|
|
||||||
|
def test_glm_52_fp8(self):
|
||||||
|
"""Run accuracy test for GLM-5.2-FP8."""
|
||||||
|
cookbook_args = [
|
||||||
|
"--trust-remote-code",
|
||||||
|
"--reasoning-parser=glm45",
|
||||||
|
"--tool-call-parser=glm47",
|
||||||
|
"--dsa-prefill-backend=tilelang",
|
||||||
|
"--dsa-decode-backend=tilelang",
|
||||||
|
"--chunked-prefill-size=131072",
|
||||||
|
"--mem-fraction-static=0.80",
|
||||||
|
"--watchdog-timeout=1200",
|
||||||
|
# Not part of the cookbook cell; purely a load-time win on a
|
||||||
|
# checkpoint this large, with no effect on numerics.
|
||||||
|
"--model-loader-extra-config",
|
||||||
|
'{"enable_multithread_load": true}',
|
||||||
|
]
|
||||||
|
|
||||||
|
variants = [
|
||||||
|
ModelLaunchSettings(
|
||||||
|
GLM_52_FP8_MODEL_PATH,
|
||||||
|
tp_size=8,
|
||||||
|
extra_args=cookbook_args,
|
||||||
|
variant="TP8",
|
||||||
|
launch_timeout=SERVER_LAUNCH_TIMEOUT,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
run_combined_tests(
|
||||||
|
models=variants,
|
||||||
|
test_name="GLM-5.2-FP8 (MI35x)",
|
||||||
|
accuracy_params=AccuracyTestParams(dataset="gsm8k", baseline_accuracy=0.92),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
"""MI35x nightly performance benchmark for GLM-5.2-FP8 (8-GPU).
|
||||||
|
|
||||||
|
Benchmarks zai-org/GLM-5.2-FP8 at TP8 with the cookbook's MI355X / FP8 /
|
||||||
|
low-latency / single-node server configuration. At 8K-input / 1K-output,
|
||||||
|
batch 1 and 16 are the concurrency points the cookbook publishes, so drift from
|
||||||
|
the recipe shows up directly; 8 and 64 extend the sweep to keep the batch range
|
||||||
|
the retired GLM-5.1 MI35x benchmark used to cover.
|
||||||
|
|
||||||
|
This runs after the GLM-5.2 accuracy test in the same ROCm 7.2 job. The
|
||||||
|
checkpoint is therefore already cached, accuracy gates performance, and the
|
||||||
|
two tests consume one scarce 8-GPU MI35x slot rather than two.
|
||||||
|
|
||||||
|
Registry: nightly-perf-8-gpu-mi35x-glm52-fp8 suite
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from sglang.test.ci.ci_register import register_amd_ci
|
||||||
|
from sglang.test.nightly_bench_utils import generate_simple_markdown_report
|
||||||
|
from sglang.test.nightly_utils import NightlyBenchmarkRunner
|
||||||
|
from sglang.test.test_utils import DEFAULT_URL_FOR_TEST, _parse_int_list_env
|
||||||
|
|
||||||
|
register_amd_ci(
|
||||||
|
est_time=5400,
|
||||||
|
suite="nightly-perf-8-gpu-mi35x-glm52-fp8",
|
||||||
|
nightly=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
GLM_52_FP8_MODEL_PATH = os.environ.get("GLM52_FP8_MODEL_PATH", "zai-org/GLM-5.2-FP8")
|
||||||
|
RESULT_DIR = "performance_results_glm52_fp8_mi35x"
|
||||||
|
|
||||||
|
|
||||||
|
class TestGLM52FP8PerfMI35x(unittest.TestCase):
|
||||||
|
"""GLM-5.2-FP8 low-latency throughput on AMD MI35x."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
cls.base_url = DEFAULT_URL_FOR_TEST
|
||||||
|
# The leading 1 is repeated so the report helper drops it as a warmup
|
||||||
|
# run: this step launches its own server, so the first request pays for
|
||||||
|
# warmup and batch 1 is the row that distorts most.
|
||||||
|
cls.batch_sizes = [1, 1, 8, 16, 64]
|
||||||
|
cls.input_lens = tuple(_parse_int_list_env("NIGHTLY_INPUT_LENS", "8192"))
|
||||||
|
cls.output_lens = tuple(_parse_int_list_env("NIGHTLY_OUTPUT_LENS", "1024"))
|
||||||
|
cls.model_config = {
|
||||||
|
"name": "low-latency-tp8",
|
||||||
|
"model_path": GLM_52_FP8_MODEL_PATH,
|
||||||
|
"other_args": [
|
||||||
|
"--trust-remote-code",
|
||||||
|
"--reasoning-parser",
|
||||||
|
"glm45",
|
||||||
|
"--tool-call-parser",
|
||||||
|
"glm47",
|
||||||
|
"--tp",
|
||||||
|
"8",
|
||||||
|
"--dsa-prefill-backend",
|
||||||
|
"tilelang",
|
||||||
|
"--dsa-decode-backend",
|
||||||
|
"tilelang",
|
||||||
|
"--chunked-prefill-size",
|
||||||
|
"131072",
|
||||||
|
"--mem-fraction-static",
|
||||||
|
"0.80",
|
||||||
|
"--model-loader-extra-config",
|
||||||
|
'{"enable_multithread_load": true}',
|
||||||
|
"--watchdog-timeout",
|
||||||
|
"1200",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
os.environ.setdefault("SGLANG_BENCH_TIMEOUT", "3600")
|
||||||
|
cls.runner = NightlyBenchmarkRunner(RESULT_DIR, cls.__name__, cls.base_url)
|
||||||
|
cls.runner.setup_result_directory()
|
||||||
|
cls.runner.full_report = f"## {cls.__name__}\n"
|
||||||
|
|
||||||
|
def test_glm52_fp8_perf(self):
|
||||||
|
"""Run the GLM-5.2-FP8 batch-size sweep."""
|
||||||
|
try:
|
||||||
|
result_tuple = self.runner.run_benchmark_for_model(
|
||||||
|
model_path=self.model_config["model_path"],
|
||||||
|
batch_sizes=self.batch_sizes,
|
||||||
|
input_lens=self.input_lens,
|
||||||
|
output_lens=self.output_lens,
|
||||||
|
other_args=self.model_config["other_args"],
|
||||||
|
variant=self.model_config["name"],
|
||||||
|
extra_bench_args=["--trust-remote-code"],
|
||||||
|
timeout=5400,
|
||||||
|
)
|
||||||
|
results, success = result_tuple[0], result_tuple[1]
|
||||||
|
|
||||||
|
if results:
|
||||||
|
self.runner.full_report += (
|
||||||
|
generate_simple_markdown_report(results, default_gpu_config="MI35x")
|
||||||
|
+ "\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
success, f"Benchmark failed for {GLM_52_FP8_MODEL_PATH} on MI35x"
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
self.runner.write_final_report()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
@@ -141,6 +141,7 @@ NIGHTLY_SUITES = {
|
|||||||
"nightly-amd-2-gpu-mi35x-deepseek-r1-mxfp4-tp2",
|
"nightly-amd-2-gpu-mi35x-deepseek-r1-mxfp4-tp2",
|
||||||
"nightly-amd-8-gpu-mi35x-deepseek-r1-mxfp4-tp4",
|
"nightly-amd-8-gpu-mi35x-deepseek-r1-mxfp4-tp4",
|
||||||
"nightly-amd-accuracy-8-gpu-mi35x-kimi-k3",
|
"nightly-amd-accuracy-8-gpu-mi35x-kimi-k3",
|
||||||
|
"nightly-amd-8-gpu-mi35x-glm52-fp8",
|
||||||
"nightly-amd-4-gpu",
|
"nightly-amd-4-gpu",
|
||||||
"nightly-amd-8-gpu",
|
"nightly-amd-8-gpu",
|
||||||
"nightly-amd-vlm",
|
"nightly-amd-vlm",
|
||||||
|
|||||||
Reference in New Issue
Block a user