Repository navigation
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
56f777f to
a4d09fd
Compare
|
We hit the exact same We have an Ascend 910B environment and are glad to validate this on real NPU (which I understand neither @ronhuafeng nor @tech-cow could do from a CUDA-only setup). One note on full end-to-end validation: once this import fix lets SGLang start, inference on Ascend also trips a separate FlagGems bug in Re @ronhuafeng's second point (an explicit error when symmetric memory is actually requested on a non-CUDA backend): the current |
Fixes sgl-project#28999. Alternative to sgl-project#29100. `pynccl_allocator` imported four names from `torch.cuda.memory` at module scope, two of which (`_cuda_beginAllocateCurrentThreadToPool`, `_cuda_endAllocateToPool`) were added in torch 2.8 -- torch 2.7 spelled the latter `_cuda_endAllocateCurrentStreamToPool`. A `from ... import (a, b, c)` statement is all-or-nothing, so on Ascend NPU (torch 2.7 via torch_npu) the whole statement raised ImportError. The module is imported eagerly across the codebase (model_runner, linear, dp_attention, fp8, ... and the NPU graph runners), so startup aborted before any device dispatch. `torch.cuda.memory` re-exports these straight from `torch._C`, and three of the four call sites in this file already went through `torch._C.` -- two of them inside the same methods. Routing the remaining calls the same way is a runtime no-op that removes the import-time dependency entirely, so no try/except and no None sentinels are needed. `CUDAPluggableAllocator` stays a plain import: it is a Python class present since torch 2.0 and was only collateral damage of the shared import statement. Two guards make the unsupported paths explicit instead of incidental, which is what the issue asked for: - `--enable-symm-mem` is now disabled with a warning on non CUDA/HIP devices, matching the existing `--debug-cuda-graph` handling. NCCL symmetric memory compiles a CUDA plugin and links -lnccl, so on NPU it could only fail deep in a build step. Previously nothing rejected the flag there; the path was safe only because nobody passed it. - `get_nccl_mem_pool` asserts torch>=2.8 rather than failing with a bare AttributeError mid-context-manager. The test is a static AST check that no torch>=2.8-only symbol is imported at module scope. It detects the regression on any torch version, needs no GPU/NPU, and does not mutate shared torch module state. Verified that it reports the offending names on both main and sgl-project#29100, and passes here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Setting |
c1fecb8 to
624097e
Compare
|
Agreed, your branch is the better fix. I've pushed it onto this PR as your commit and updated the title and description to match. What convinced me: The two guards also close @ronhuafeng's and @JosephNew's second point here instead of deferring it. On a non CUDA/HIP device, One small note, not a blocker. With that assert in place, the @JosephNew, the 910B validation offer is still welcome and it carries over unchanged: this fixes the same import path either way, so a run against the new commit is just as valid. Watching flagos-ai/FlagGems#4467 for the argmax side. |
Conflict: the symm-mem device guard this branch added to `ServerArgs._handle_gpu_memory_settings` collided with main's move of argument resolution into `arg_groups/` hooks, which deleted that method. Resolved by re-homing the guard as `handle_symm_mem_device_support` in `arg_groups/platform_hook.py`, next to `handle_nccl_pre_warm` -- the same shape: a device-gated disable of a comm flag. Resolution no longer assigns fields, so it declares `enable_symm_mem=False` via `declare_resolution` instead of the old `self.enable_symm_mem = False`, which the strict mutation guard now rejects. It is dispatched before `handle_gpu_memory_settings` so the symm-mem prealloc default does not fire for a flag being turned off. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Conflict: main extracted `ServerArgs._run_resolution_pipeline` into `arg_groups/pipeline.py:run_resolution_pipeline`, deleting the method that dispatched this branch's `handle_symm_mem_device_support`. Resolved by taking main's extraction and re-registering the hook in `pipeline.py`, keeping its slot with the other platform hooks and ahead of `handle_gpu_memory_settings` so the symm-mem prealloc default does not fire for a flag being turned off. `server_args.py` is no longer touched by this branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Cut restatement, caller enumeration, and change rationale, keeping only what a reader cannot recover from the code: the torch 2.8 version constraint and why the call sites go through torch._C, the -lnccl/CUDA-plugin reason symm mem needs a CUDA/HIP device, and the hook's ordering requirement against handle_gpu_memory_settings. The allocator's import note goes from ten lines to two, and the test's module docstring from thirteen to two. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…sgl-project#29100) Co-authored-by: Alex Nails <alex.nails@radixark.ai> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Motivation
Fixes #28999.
SGLang won't start on Ascend NPU (
torch 2.7.0 + torch_npu):pynccl_allocator.pypulls four privatetorch.cuda.memorymemory-pool names in at module scope. Two of them (_cuda_beginAllocateCurrentThreadToPool,_cuda_endAllocateToPool) only landed in torch 2.8 — 2.7 spelled the second one_cuda_endAllocateCurrentStreamToPool. Afrom ... import (a, b, c)is all-or-nothing, so one missing name takes the whole statement down with it. And this module gets imported eagerly all over the place —model_runner,linear,dp_attention,fp8, the MoE/quant layers, even the NPU graph runners — so the ImportError fires long before anything gets a chance to dispatch on device.Modifications
Turns out we didn't need a guarded import at all.
torch.cuda.memoryre-exports these straight fromtorch._C, and this same file was already reaching two of them that way, inside the very methods that were using the imported bindings. So the remaining call sites just go throughtorch._C.<name>like their siblings, and the import-time dependency disappears. No try/except, and noNonesentinels that could quietly turn a genuinely broken CUDA install into a confusingNoneType is not callablesomewhere further down.CUDAPluggableAllocatorstays a plain import — it's a Python class that's been there since torch 2.0, and it was only collateral damage of sharing an import statement with the private names.Two guards on top, so the unsupported paths fail on purpose instead of by accident:
--enable-symm-memnow warns and turns itself off on non CUDA/HIP devices, the same way--debug-cuda-graphalready does. NCCL symmetric memory compiles a CUDA plugin and links-lnccl, so on NPU it could only ever have blown up deep inside a build step. Nothing rejected the flag there before — that path was "safe" purely because nobody passed it.get_nccl_mem_poolasserts torch>=2.8 up front, instead of letting you find out via a bareAttributeErrorhalfway through a context manager.The test is now a static AST check that no torch>=2.8-only symbol appears in a module-scope import. It catches the regression on any torch version, needs no GPU or NPU, and doesn't mutate shared torch module state.
This version is @alexnails' — it replaces the try/except +
Nonefallback the PR originally carried.Accuracy Tests
N/A — import-time only. Every CUDA call site invokes the exact same C function it did before, just looked up on
torch._Cinstead of through a module-scope binding.Speed Tests and Profiling
N/A — no runtime or critical-path change.
Checklist
test/registered/unit/distributed/test_pynccl_allocator_import.py).CI States
Latest PR Test (Base): ❌ Run #33275009508
Latest PR Test (Extra): ❌ Run #33275009302
Latest PR Test (AMD ROCm 7.2): ⏳ Run #33275009607