Skip to content

ckpt: support GLM-4.7-Flash test on ROCm (MI35x)#1620

Open
sreerohi wants to merge 1 commit into
radixark:mainfrom
sreerohi:ROCm-glm4.7-Flash-fixes
Open

ckpt: support GLM-4.7-Flash test on ROCm (MI35x)#1620
sreerohi wants to merge 1 commit into
radixark:mainfrom
sreerohi:ROCm-glm4.7-Flash-fixes

Conversation

@sreerohi

Copy link
Copy Markdown

Summary

Two ROCm-only changes in tests/e2e/ckpt/test_glm47_flash_ckpt.py, gated on IS_ROCM = torch.version.hip is not None. NVIDIA behavior is unchanged.

  1. extra_env_vars["SGLANG_USE_AITER"] = "0" — the rlsys/miles:MI350-355-latest image bakes in SGLANG_USE_AITER=1, which routes MoE topk, quantization, and the GLM4MoE forward through aiter's JIT-wrapped kernels. Those wrappers do Python-level work (allocations, torch.library registration, first-call JIT) inside the captured HIP graph and corrupt the stream — the visible symptom is a Fatal Python error in silu_and_mul, but the cause is the aiter calls upstream of it. Forcing =0 routes through SGLang's native Triton paths, which capture cleanly.
  2. --ci-disable-logprobs-checker — Megatron-flash ↔ SGLang-triton gives a small but non-zero train_rollout_logprob_abs_diff. This test verifies the checkpoint save/load round-trip (--ci-save-model-hash / --ci-check-model-hash), not cross-backend numerical consistency, so the logprob check is skipped on ROCm. MTP loss and KL checkers stay on.

External dependency: SGLang deepseek_v2.py patch (not in this PR)

This test also needs an upstream SGLang fix in sglang/srt/models/deepseek_v2.py. Without it, GLM-4.7-Flash crashes at model load on ROCm. See the commit message for the root cause and the patch.
Supersedes #1126

Two ROCm-only changes in tests/e2e/ckpt/test_glm47_flash_ckpt.py
(gated on IS_ROCM = torch.version.hip is not None):

1. Set extra_env_vars["SGLANG_USE_AITER"] = "0".
   The rlsys/miles:MI350-355-latest Docker image bakes in
   SGLANG_USE_AITER=1, which routes MoE topk, quantization, and the
   GLM4MoE model forward pass through aiter's JIT-wrapped kernels.
   Those wrappers (aiter/jit/utils/torch_guard.py) do Python-level
   work -- torch.library registration, tensor allocations, first-call
   JIT compilation -- on every dispatch, which corrupts the HIP stream
   during CUDA graph capture and aborts downstream kernels (the
   visible symptom is a Fatal Python error inside silu_and_mul during
   warmup, but the cause is upstream aiter calls in the same captured
   forward pass). Forcing the env var to "0" routes those paths
   through SGLang's native Triton-based implementations, which
   capture cleanly. EAGLE speculative decoding then works end-to-end.

2. Add --ci-disable-logprobs-checker on ROCm.
   The Megatron-flash <-> SGLang-triton boundary produces a small but
   non-zero training-vs-rollout log-probs delta on ROCm
   (train_rollout_logprob_abs_diff ~0.28, train_rollout_kl ~0.11).
   This test exists to verify the checkpoint save/load round-trip
   (--ci-save-model-hash / --ci-check-model-hash), not cross-backend
   numerical consistency, so the logprob check is gated off on ROCm.
   The MTP loss and KL checkers stay on.

The save/load round-trip mechanism is unchanged. NVIDIA behavior is
unchanged (both blocks are gated on IS_ROCM).

External dependency: SGLang deepseek_v2.py patch
------------------------------------------------
This test also needs an upstream SGLang fix in
sglang/srt/models/deepseek_v2.py (NOT included in this PR -- it is
not a miles file). Without it, GLM-4.7-Flash fails to load on ROCm
with:

    KeyError: 'original_max_position_embeddings'
    at /sgl-workspace/aiter/aiter/rotary_embedding.py:1849
    in get_rope_wrapper()

Root cause: at line ~1138 of deepseek_v2.py, the model init does an
unconditional truthy check on rope_scaling:

    if rope_scaling:
        rope_scaling["rope_type"] = "deepseek_yarn"

In transformers v5+, rope_parameters/rope_scaling is auto-populated
on every model config (including rope_type="default"), so this
truthy check misclassifies non-yarn models. GLM-4.7-Flash gets
stamped as deepseek_yarn, after which aiter's rope wrapper tries
to read rope_scaling["original_max_position_embeddings"] (a key
only yarn configs have) and crashes with KeyError.

The fix is to narrow the condition so it only fires for models that
already declare yarn scaling:

    if rope_scaling and rope_scaling.get("rope_type") in ("yarn", "deepseek_yarn"):
        rope_scaling["rope_type"] = "deepseek_yarn"

This needs to land upstream in sgl-project/sglang. Until then, the
fix has to be applied manually inside the running container at
/sgl-workspace/sglang/python/sglang/srt/models/deepseek_v2.py. A
permanent solution requires either an upstream SGLang PR or a
Docker image rebuild that includes the patch.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces ROCm support in the GLM-4.7-Flash checkpoint end-to-end test by conditionally disabling the logprobs checker and setting the SGLANG_USE_AITER environment variable. It also updates several configuration variables to be loaded from environment variables. However, the initial static assignments for ENABLE_EVAL and USE_DEEPEP were not removed, leading to redundant assignments and dead code.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +14 to +16
ENABLE_EVAL = bool(int(os.environ.get("MILES_TEST_ENABLE_EVAL", "1")))
TIGHT_HOST_MEMORY = bool(int(os.environ.get("MILES_TEST_TIGHT_HOST_MEMORY", "1")))
USE_DEEPEP = bool(int(os.environ.get("MILES_TEST_USE_DEEPEP", "0")))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The variables ENABLE_EVAL and USE_DEEPEP are redefined here using environment variables, but their initial static assignments (ENABLE_EVAL = 0 and USE_DEEPEP = 0 on lines 11 and 12) were not removed. This results in redundant assignments and dead code. Please remove the initial assignments on lines 11 and 12.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant