Repository navigation
fix(capture): Ascend NPU host publication hardening - #1070
Open
curnane-lab wants to merge 3 commits into
Open
curnane-lab wants to merge 3 commits into
curnane-lab wants to merge 3 commits into
Conversation
N1 of the Ascend NPU capture plan: make the plugin's platform decisions follow the model runner's actual device instead of CUDA-only detection. - gpu_put_enabled(device): auto mode selects host publication on non-CUDA runners; explicit SGLANG_SPEC_CAPTURE_GPU_PUT=1 or MOONCAKE_PROTOCOL= nvlink on a non-CUDA runner now fails at install time instead of crashing on torch.cuda.Event inside the first capture. - _model_device() fills a missing device index from the runner's gpu_id (the NPU fork reports device="npu" and gpu_id separately), so the sink worker binds the actual logical card instead of defaulting to index 0; an explicit index always wins. - SpecCaptureSink(device=...): Ascend CPU-segment mounting is keyed off the model device, with ASCEND_RT_VISIBLE_DEVICES kept only as a fallback hint; the mount semantics themselves are unchanged. - The sink writer thread binds its NPU device context (logical index) before Mooncake setup, fixing ACL_ERROR_RT_CONTEXT_NULL for capture producers that never ran init_distributed. Existing CUDA/CPU/ROCm behavior is preserved: auto mode keeps the historical torch.version.cuda backend check (ROCm stays on host publication), and an explicit GPU_PUT=1 on CUDA-type devices (ROCm included) keeps its old semantics — only a known non-CUDA runner is rejected. No public env or protocol renames. Tests use device stand-ins and localized mocks for NPU (torch.device "npu" does not resolve without torch_npu), plus one backend-gated real NPU test: 60 passed / 6 skipped with torch_npu, 59 passed / 7 skipped with TORCH_DEVICE_BACKEND_AUTOLOAD=0.
Add a patch-free native-plugin section to the existing Ascend NPU tutorial (prerequisites, install, launch, server_capture: plugin, built-in CPU mount, validated scope, required environment, known limits, migration/rollback) and mark the two-patch instructions as the legacy 0.5.18 route. The plugin README gains a short Ascend notes section linking to the guide. The full validation log and migration guide stay on the fork's archive branch npu/spec-capture-ascend.
…-ascend # Conflicts: # docs/sections/basic_usage/Ascend/ascend_npu.md
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ascend NPU enablement for the native
sglang-spec-captureplugin (host-publication route), plus a condensed native-plugin section in the existing Ascend NPU tutorial and short Ascend notes in the plugin README. Two implementation files, two test files, two existing-doc edits.Plugin changes
gpu_put_enabled(device): platform decisions follow the model runner's actual device instead of CUDA-only detection. Auto mode selects host publication on non-CUDA runners; explicitSGLANG_SPEC_CAPTURE_GPU_PUT=1orMOONCAKE_PROTOCOL=nvlinkon a non-CUDA runner fails at install time with a clear error, instead of crashing ontorch.cuda.Eventinside the first capture._model_device()fills a missing device index from the runner'sgpu_id(the NPU fork reportsdevice="npu"andgpu_idseparately), so the sink worker binds the actual card instead of defaulting to index 0. An explicit device index always wins.SpecCaptureSink(device=...): Ascend CPU-segment mounting (setup(0,0)+allocate_and_mount_segment(size, protocol, "cpu")) is keyed off the model device, withASCEND_RT_VISIBLE_DEVICESkept only as a fallback hint. Mount semantics unchanged.ACL_ERROR_RT_CONTEXT_NULLfor capture producers that never raninit_distributed. No-op on CUDA/CPU.CUDA/CPU/ROCm behavior is preserved. Auto mode keeps the historical
torch.version.cudabackend check (ROCm stays on host publication), and an explicitGPU_PUT=1on CUDA-type devices (ROCm included) keeps its old semantics — only a known non-CUDA runner is rejected. No public env or protocol renames.Tests
New unit tests in
tests/test_runtime/test_sglang_capture_plugin.pyandtests/test_runtime/test_sglang_capture_plugin_sink.py: 60 passed, 6 skipped under torch 2.10 + torch_npu, and 59 passed, 7 skipped withTORCH_DEVICE_BACKEND_AUTOLOAD=0(no NPU backend registered). NPU devices in tests are stand-ins/local mocks, so the suites also pass on plain CPU/CUDA hosts; one real-NPU parse test is backend-gated.black/isortclean.Testing on hardware (8x 910B3, Qwen3.5-4B GDN hybrid + DFlash, host publication + TCP)
Validated combination: SpecForge
pr/npu/spec-capture-ascend@67bb423(this PR); SGLang = NPU forknpu/capture-forward-observer@b462f44827(fork head88a0368750+ the already-merged #43450 cherry-pick; #43449 was already in the fork); torch 2.10.0+cpu + torch_npu 2.10.0, transformers 5.12.1, CANN 9.0.0,mooncake-transfer-engine 0.3.13.post1(TCP host path).Full verification log and migration guide live on the fork's archive branch, pinned:
scripts/npu/on the same branch)Highlights:
67bb423, visible3,4,base_gpu_id=1): trace showsmodel_runner.device='npu',gpu_id=1,_model_device()resolvingnpu:1; the sink is configured withnpu:1and its worker reportscurrent_device=1. Publication and read-back pass (VERIFY_E2E_OK).targetmatches a capture-off post-norm reference on the same logical card for 9/9 rows bit-exactly (max_abs=0, every per-row relative error 0), rather than merely checking finite values.MooncakeFeatureStore: CPU get bit-identical;npu:0receive + H2D intact;release()frees objects and a laterget()raisesKeyError.spec_capturerequests, test-only delayed sink): other requests kept executing (including graph replays) while capture A's publication was still pending, and A's read-back is consistent — published aux bit-identical to the eager reference, isolated repeat A2 bit-identical to A. The plainreturn_hidden_statesgraph path is verified separately.random.Random(seed + epoch)order, offline intorch.randperm(seed + epoch)order.Known limits (documented in the guide)
Notes
Related: #1063 #1064 #1065 #1066.
Checklist