diff --git a/.github/workflows/pr-test-amd.yml b/.github/workflows/pr-test-amd.yml index a94b1ee73..a8fde9567 100644 --- a/.github/workflows/pr-test-amd.yml +++ b/.github/workflows/pr-test-amd.yml @@ -796,6 +796,43 @@ jobs: run: | bash scripts/ci/amd_ci_exec.sh -e SGLANG_USE_AITER_AR=0 -e SGLANG_USE_AITER=0 -e HF_HUB_ENABLE_HF_TRANSFER=0 python3 test_moe_eval_accuracy_large.py + dllm-test-1-gpu-amd: + needs: [check-changes, stage-a-test-1-amd] + if: | + always() && + ( + (inputs.target_stage == 'dllm-test-1-gpu-amd') || + ( + !inputs.target_stage && + (!failure() && !cancelled()) && + ((needs.check-changes.outputs.main_package == 'true') || (needs.check-changes.outputs.sgl_kernel == 'true')) + ) + ) + strategy: + fail-fast: false + matrix: + runner: [linux-mi325-gpu-1] + runs-on: ${{matrix.runner}} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Ensure VRAM is clear + run: bash scripts/ensure_vram_clear.sh rocm + + - name: Start CI container + run: bash scripts/ci/amd_ci_start_container.sh + env: + GITHUB_WORKSPACE: ${{ github.workspace }} + + - name: Install dependencies + run: bash scripts/ci/amd_ci_install_dependency.sh + + - name: Test DLLM (LLaDA2) + timeout-minutes: 30 + run: | + bash scripts/ci/amd_ci_exec.sh python3 dllm/test_llada2_mini_amd.py + pr-test-amd-finish: needs: [ @@ -814,7 +851,8 @@ jobs: performance-test-1-gpu-part-2-amd, performance-test-2-gpu-amd, accuracy-test-1-gpu-amd, - accuracy-test-2-gpu-amd, # Temporarily disabled + accuracy-test-2-gpu-amd, + dllm-test-1-gpu-amd, ] if: always() runs-on: ubuntu-latest diff --git a/python/sglang/srt/model_executor/forward_batch_info.py b/python/sglang/srt/model_executor/forward_batch_info.py index b1b6b66ec..94fb8a545 100644 --- a/python/sglang/srt/model_executor/forward_batch_info.py +++ b/python/sglang/srt/model_executor/forward_batch_info.py @@ -53,7 +53,7 @@ from sglang.srt.layers.dp_attention import ( set_is_extend_in_batch, ) from sglang.srt.server_args import get_global_server_args -from sglang.srt.utils import get_compiler_backend, is_npu, support_triton +from sglang.srt.utils import get_compiler_backend, is_hip, is_npu, support_triton from sglang.srt.utils.common import ceil_align if TYPE_CHECKING: @@ -490,13 +490,15 @@ class ForwardBatch: # Override the positions with diffusion LLM or spec_info if batch.dllm_config is not None: block_size = batch.dllm_config.block_size + # Use int64 for AMD rotary embedding kernel compatibility + positions_dtype = torch.int64 if is_hip() else torch.int32 ret.positions = torch.tensor( [ i for block_offset in batch.dllm_block_offsets for i in range(block_offset, block_offset + block_size) ], - dtype=torch.int32, + dtype=positions_dtype, ).to(device, non_blocking=True) elif ( ret.spec_info is not None diff --git a/python/sglang/srt/server_args.py b/python/sglang/srt/server_args.py index 54d4e415a..43bbea6c3 100644 --- a/python/sglang/srt/server_args.py +++ b/python/sglang/srt/server_args.py @@ -2425,7 +2425,19 @@ class ServerArgs: def _handle_dllm_inference(self): if self.dllm_algorithm is None: return - if not self.disable_cuda_graph: + # On AMD/HIP, disable cuda graph for DLLM and use triton backend + if is_hip(): + if not self.disable_cuda_graph: + logger.warning( + "Cuda graph is disabled for diffusion LLM inference on AMD GPUs" + ) + self.disable_cuda_graph = True + if self.attention_backend not in ["triton", "aiter"]: + logger.warning( + "Attention backend is set to triton for diffusion LLM inference on AMD GPUs" + ) + self.attention_backend = "triton" + elif not self.disable_cuda_graph: if self.cuda_graph_bs != [1]: logger.warning( "Cuda graph bs is set to [1] because of using diffusion LLM inference" diff --git a/test/srt/dllm/test_llada2_mini_amd.py b/test/srt/dllm/test_llada2_mini_amd.py new file mode 100644 index 000000000..fc0392392 --- /dev/null +++ b/test/srt/dllm/test_llada2_mini_amd.py @@ -0,0 +1,87 @@ +""" +Test LLaDA2 (Diffusion Language Model) on AMD GPUs. + +This test verifies that DLLM works on AMD with triton attention backend. +""" + +import unittest +from types import SimpleNamespace + +from sglang.srt.utils import kill_process_tree +from sglang.test.few_shot_gsm8k import run_eval as run_eval_few_shot_gsm8k +from sglang.test.send_one import BenchArgs, send_one_prompt +from sglang.test.test_utils import ( + DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH, + DEFAULT_URL_FOR_TEST, + CustomTestCase, + is_in_ci, + popen_launch_server, + write_github_step_summary, +) + + +class TestLLaDA2MiniAMD(CustomTestCase): + @classmethod + def setUpClass(cls): + cls.model = "inclusionAI/LLaDA2.0-mini" + cls.base_url = DEFAULT_URL_FOR_TEST + + other_args = [ + "--trust-remote-code", + "--mem-fraction-static", + "0.9", + "--max-running-requests", + "1", + "--attention-backend", + "triton", # Use triton for AMD instead of flashinfer + "--dllm-algorithm", + "LowConfidence", + ] + + cls.process = popen_launch_server( + cls.model, + cls.base_url, + timeout=DEFAULT_TIMEOUT_FOR_SERVER_LAUNCH, + other_args=other_args, + ) + + @classmethod + def tearDownClass(cls): + kill_process_tree(cls.process.pid) + + def test_gsm8k(self): + """Test GSM8K accuracy with DLLM on AMD.""" + args = SimpleNamespace( + num_shots=5, + data_path=None, + num_questions=200, + max_new_tokens=512, + parallel=128, + host="http://127.0.0.1", + port=int(self.base_url.split(":")[-1]), + ) + metrics = run_eval_few_shot_gsm8k(args) + print(f"{metrics=}") + + # Relaxed thresholds for AMD - may need adjustment + self.assertGreater(metrics["accuracy"], 0.80) + self.assertGreater(metrics["output_throughput"], 50) + + def test_bs_1_speed(self): + """Test single batch inference speed.""" + args = BenchArgs(port=int(self.base_url.split(":")[-1]), max_new_tokens=2048) + acc_length, speed = send_one_prompt(args) + + print(f"{speed=:.2f}") + + if is_in_ci(): + write_github_step_summary( + f"### test_bs_1_speed (llada2-mini AMD) with tp1\n" + f"{speed=:.2f} token/s\n" + ) + # Relaxed threshold for AMD + self.assertGreater(speed, 10) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/srt/run_suite.py b/test/srt/run_suite.py index 4553714f0..a826122a5 100644 --- a/test/srt/run_suite.py +++ b/test/srt/run_suite.py @@ -203,6 +203,7 @@ suite_amd = { # TestFile("lora/test_lora_backend.py", 99), # Disabled temporarily, see https://github.com/sgl-project/sglang/issues/13107 # TestFile("lora/test_lora_cuda_graph.py", 250), # Disabled temporarily, see https://github.com/sgl-project/sglang/issues/13107 # TestFile("lora/test_lora_qwen3.py", 97), # Disabled temporarily, see https://github.com/sgl-project/sglang/issues/13107 + TestFile("dllm/test_llada2_mini_amd.py", 520), TestFile("models/test_compressed_tensors_models.py", 42), TestFile("models/test_cross_encoder_models.py", 150), TestFile("models/test_qwen_models.py", 82),