Skip to content

[AMD] DSv4: bring HIP compress-state pool into the memory_saver KV_CACHE region - #31747

Merged
HaiShaw merged 2 commits into
sgl-project:mainfrom
XinyuJiangCMU:amd/miles-ci-mi35x
Jul 29, 2026
Merged

HaiShaw merged 2 commits into
sgl-project:mainfrom
XinyuJiangCMU:amd/miles-ci-mi35x

Conversation

@XinyuJiangCMU

@XinyuJiangCMU XinyuJiangCMU commented Jul 20, 2026 •

Copy link
Copy Markdown
Contributor

Co-authored-by: @JessicaJiang-123

On gfx950, the DeepSeek-V4 compress-state pool allocated kv_score_buffer outside the torch_memory_saver region. As a result, pause() could not reclaim this memory during colocated RL training.

For a 16k, 4-node DeepSeek-V4-Flash run, this left approximately 52 GiB per GPU allocated throughout the training phase. This PR moves the HIP allocation into region(GPU_MEMORY_TYPE_KV_CACHE), matching the existing CUDA behavior.

The compute path is unchanged. This PR only changes how the buffer is allocated and registered with torch_memory_saver.

Root cause

_alloc_kv_score_buffer used a separate HIP path that allocated the buffer with a plain torch.empty(), outside any torch_memory_saver region:

if _is_hip:
    self.kv_score_buffer = KVAndScore(
        torch.empty((self._size, self.last_dim), dtype=dtype, device=device)
    )  # Not registered inside region(GPU_MEMORY_TYPE_KV_CACHE)
else:
    ... with region(...): with use_mem_pool(...): torch.empty(...)

torch_memory_saver can only unmap physical GPU memory for allocations registered inside a region. Because the HIP allocation was outside the region, the compress-state pool remained allocated after pause().

In addition, DeepSeekV4TokenToKVPool explicitly passed enable_memory_saver=False to _init_paged_compress_states on HIP, preventing the memory-saver allocation path from being used.

Change

Use the same allocation path for HIP and CUDA by allocating kv_score_buffer inside region(GPU_MEMORY_TYPE_KV_CACHE) through the custom memory pool and removing the HIP-specific enable_memory_saver=False behavior in DeepSeekV4TokenToKVPool. Both platforms now use the allocation path previously used only by CUDA.

Validation

Hardware: 8× MI355X GPUs (gfx950)
Model: DeepSeek-V4-Flash-FP8

Memory reclaimed

I constructed one ratio-128 compress-state pool with enable_memory_saver=True on gfx950 and measured physical GPU memory with mem_get_info before and after pause().

On the current main branch, DeepSeekV4TokenToKVPool forces enable_memory_saver=False on HIP. With this PR, the flag is enabled and the allocation is registered with torch_memory_saver.

Version Pool allocation Memory freed by pause()
main 2.02 GiB 0.000 GiB
This PR 1.87 GiB 1.873 GiB

With this PR, resume() correctly remaps the released memory.

Each ratio-128 pool uses approximately 1.87 GiB. Across roughly 20 ratio-128 attention pools, this accounts for the approximately 52 GiB per GPU that previously remained allocated during training.

In the full colocated run, the SGLang GPU-memory footprint during the training phase decreased from approximately 143 GiB to 87 GiB.

Correctness (GSM8K, 1319 questions, 8-shot, TP8)

Version memory_saver=False memory_saver=True
This PR 0.928 0.922
main 0.924 N/A

All three accuracy results are at least 0.91. The fix does not change model outputs. With memory_saver=True, the server starts successfully and serves requests correctly, validating the region and custom-memory-pool allocation path added by this PR.

Stability

A 4-node 16k colocate GRPO run on the fixed build: cold start and first resume with 0 SIGSEGV, and train/infer logprob drift ~0.04 matching the pre-fix baseline over 40+ steps.

Notes

  • Scope: does not touch the compressor compute or the CUDA path.
  • CUDA behavior is unchanged (both platforms now run the former else branch).

CI States

Latest PR Test (Base): ❌ Run #29718179112
Latest PR Test (Extra): ✅ Run #29723719042

…CHE region

On gfx950 the DSv4 compress-state kv_score_buffer was allocated outside the
torch_memory_saver region -- the _is_hip branch used a bare torch.empty(), so
pause() could not reclaim it during colocate RL. It stayed resident (~52 GiB on
a 16k 4-node run), inflating the train-phase sglang footprint and defeating the
point of pausing the KV cache.

Unify the HIP path with the CUDA path: allocate kv_score_buffer inside
region(GPU_MEMORY_TYPE_KV_CACHE) with the custom mem pool, and drop the HIP
carve-out in DeepSeekV4TokenToKVPool that passed enable_memory_saver=False to
_init_paged_compress_states.
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@1am9trash 1am9trash left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. Only effect hip code path.

@HaiShaw
HaiShaw merged commit f5bcd00 into sgl-project:main Jul 29, 2026
124 of 140 checks passed
XinyuJiangCMU added a commit to XinyuJiangCMU/sglang that referenced this pull request Aug 1, 2026
Unify the KV-score buffer allocation to always go through
memory_saver_adapter + custom_mem_pool, removing the HIP-only branch in
both CompressStatePool and the paged compress-state memory pool. Matches
upstream sgl-project#31747.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GpJi4wXZerKrVfm8virsnc
XinyuJiangCMU added a commit to XinyuJiangCMU/sglang that referenced this pull request Aug 1, 2026
The original commit removed the is_hip import and the _is_hip module global
along with the branch it gated. That was safe on the tree it was written
against, but this branch is a fresh cherry-pick onto current sglang-miles,
where line 132 still reads _is_hip for the ratio == 128 case. Every scheduler
died with NameError: name '_is_hip' is not defined before the first step.

Upstream main, which took the same change as sgl-project#31747, keeps both the definition
and the ratio == 128 use and drops only the pool branch. Match that.

py_compile does not catch this; the name is only resolved when the line runs.
saturn-acc pushed a commit to saturn-acc/sglang that referenced this pull request Aug 16, 2026
…CHE region (sgl-project#31747)

Co-authored-by: Zhiyao Jiang <jessicajiang324@gmail.com>
Atituiset pushed a commit to Atituiset/sglang that referenced this pull request Sep 10, 2026
…CHE region (sgl-project#31747)

Co-authored-by: Zhiyao Jiang <jessicajiang324@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants