|
| 1 | +"""AMD 4-GPU variant of test_mtp1_spec_v2_r3.py. |
| 2 | +
|
| 3 | +Qwen3.5-35B-A3B: 1 MTP layer + speculative-v2 + R3, on 4 GPUs. |
| 4 | +
|
| 5 | +Standalone rather than an IS_HIP branch in the original: the MI300X fleet is |
| 6 | +split into two 4-GPU runners, so the 8-GPU CUDA case cannot run there as |
| 7 | +written, and keeping the variant separate means neither side's parallelism |
| 8 | +constrains the other. |
| 9 | +
|
| 10 | +Difference from the CUDA case: num_gpus_per_node 8 -> 4, which drops data |
| 11 | +parallelism from 2 to 1. The tp2/pp2/cp1 shape is kept exactly -- TP=4 hits a |
| 12 | +Qwen3.5 attention-output-gate sharding bug, CP=1 avoids the memory-heavy |
| 13 | +GatedDeltaNet CP backward kernel, and PP=2 halves the resident layers. Because |
| 14 | +TP/PP/CP are unchanged, the per-rank shard is identical to the CUDA case; the |
| 15 | +original comment notes it fits 8x80GB, and MI300X carries 192GB per GPU, so 4 |
| 16 | +of them hold more total HBM than the node this was tuned for. The rollout |
| 17 | +engine and SGLang EP follow the world size down from 8 to 4. |
| 18 | +""" |
| 19 | + |
| 20 | +import os |
| 21 | + |
| 22 | +from tests.ci.ci_register import register_rocm_ci |
| 23 | +from tests.ci.metric_history import register_ci_gate |
| 24 | +from tests.e2e.megatron.test_qwen3_5_35B_A3B_mtp._common import CaseConfig, execute, prepare |
| 25 | + |
| 26 | +register_rocm_ci( |
| 27 | + est_time=1600, |
| 28 | + suite="stage-c-4-gpu-mi300x", |
| 29 | + labels=["megatron", "qwen35", "amd"], |
| 30 | +) |
| 31 | + |
| 32 | +register_ci_gate(metric_key="train/grad_norm") |
| 33 | +register_ci_gate(metric_key="train/ppo_kl") |
| 34 | +register_ci_gate(metric_key="train/train_rollout_logprob_abs_diff") |
| 35 | +register_ci_gate(metric_key="train/train_rollout_kl") |
| 36 | +register_ci_gate(metric_key="rollout/raw_reward") |
| 37 | + |
| 38 | +CASE = CaseConfig( |
| 39 | + num_gpus_per_node=4, |
| 40 | + cp_size=1, |
| 41 | + pp_size=2, |
| 42 | + tp_size=2, |
| 43 | + ep_size=4, |
| 44 | + rollout_num_gpus_per_engine=4, |
| 45 | + sglang_ep_size=4, |
| 46 | + enable_mtp_training=True, |
| 47 | + use_r3=True, |
| 48 | + # miles has no VLM/vision implementation on the training side, so vision weights are |
| 49 | + # never synced; exclude them from the weight-equality check. |
| 50 | + check_weight_update_skip_list=("visual",), |
| 51 | +) |
| 52 | + |
| 53 | + |
| 54 | +if __name__ == "__main__": |
| 55 | + for proxy_var in ("http_proxy", "https_proxy", "HTTP_PROXY", "HTTPS_PROXY"): |
| 56 | + os.environ.pop(proxy_var, None) |
| 57 | + prepare(CASE) |
| 58 | + execute(CASE, wandb_file=__file__) |
0 commit comments