mirror of
https://github.com/deepseek-ai/DeepEP.git
synced 2026-11-05 00:47:32 +00:00
[PR #798] [CLOSED] [HybridEP] Release fabric memory handles after map/export/import #792
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
deepseek-ai/DeepEP#792
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/deepseek-ai/DeepEP/pull/798
Author: @jerryhong21
Created: 10/26/2026
Status: ❌ Closed
Base:
hybrid-ep← Head:hybridep-fabric-handle-release📝 Commits (1)
14360b3[HybridEP] Release fabric memory handles after map/export/import📊 Changes
2 files changed (+8 additions, -0 deletions)
View changed files
📝
csrc/deep_ep.cpp(+4 -0)📝
csrc/hybrid_ep/allocator/allocator.cu(+4 -0)📄 Description
Problem
On the fabric (MNNVL) path,
ExtendedMemoryAllocatornever releases three handle references:allocate: the handle returned bycuMemCreate(allocator.cu:91).get_handle: the reference taken bycuMemRetainAllocationHandlebefore export (:124).open_handle: the handle returned bycuMemImportFromShareableHandle(:139).freeretains a reference and releases it once, so its net effect on the count is zero.close_handleonly unmaps. The CUDA driver frees physical memory only after every mapping is unmapped and every handle reference is released, so this memory is never returned.HybridEPBuffer::update_buffercallsrelease_buffer()and thenallocate_buffer()whenever a call needs more capacity than the current reservation. With variable-length batches, every new tokens-per-rank high therefore leaks the entire previous buffer set on the exporting rank, and every peer's import keeps it pinned. On GB300 NVL72 with variable-length long-context MoE training, we saw device memory climb stepwise over a ~2h run, never released, untilcuMemCreatefailed without of memoryatallocator.cu:91mid-step. PyTorch's allocator stats did not show the growth, because this memory is allocated outside PyTorch.The
cudaMalloc/IPC path, used when fabric is unavailable, is not affected. The legacySharedMemoryAllocatorincsrc/deep_ep.cpphas the same three sites.Fix
Release each reference once the mapping or export holds what it needs:
cuMemMapinallocate;cuMemExportToShareableHandleinget_handle;cuMemMapinopen_handle.The mapping keeps the memory alive, so
freeandclose_handlenow actually return it.csrc/deep_ep.cppgets the same fix.Testing
A GB300 regrow-loop measurement (device memory per reallocation, before vs. after) is in progress. I'll post the numbers here when it finishes.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.