Repository navigation
[Bugfix][DP] Synchronize the device on pause completion - #52914
Merged
Merged
Conversation
aoshen02
requested review from
ProExpertProg,
WoosukKwon,
houseroad,
mgoin,
robertgshaw2-redhat,
tlrmchlsmth,
yewentao256 and
youkaichao
as code owners
August 19, 2026 10:03
aoshen02
force-pushed
the
fix/pause-device-barrier
branch
2 times, most recently
from
August 19, 2026 14:45
1a21733 to
868e5a5
Compare
Contributor
Author
|
/ci run |
|
✅ Triggered Buildkite CI #84723 for commit |
aoshen02
force-pushed
the
fix/pause-device-barrier
branch
2 times, most recently
from
August 20, 2026 02:18
75e326c to
d2ae48c
Compare
Contributor
Author
|
/ci run |
|
✅ Triggered Buildkite CI #84728 for commit |
A completed pause promises an idle device, not just an idle scheduler: the pause future resolves off CPU-side state while the last dummy batch an idle DP rank launched is still executing, with nothing waiting on it. Callers that run their own kernels between pause_generation() and sleep() race that in-flight work. The default synchronize_device goes through the device-generic torch.accelerator API so any registered backend gets the barrier without an override. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Codex <noreply@openai.com> Signed-off-by: Ao Shen <aoshen524@gmail.com> Signed-off-by: aoshen02 <aoshen@inferact.ai>
aoshen02
force-pushed
the
fix/pause-device-barrier
branch
from
August 20, 2026 06:53
d2ae48c to
7abd953
Compare
Same contract as the pause barrier: wake_up's tail work (buffer restores, post_kv_cache_wake_up's async re-init kernels) was unwaited, so callers could launch same-device work (e.g. RLHF weight sync) racing it. Co-authored-by: Claude <noreply@anthropic.com> Signed-off-by: aoshen <aoshen524@gmail.com> Signed-off-by: aoshen02 <aoshen@inferact.ai>
Contributor
Author
|
/ci run |
|
✅ Triggered Buildkite CI #84838 for commit |
Contributor
Author
|
/ci run |
|
✅ Triggered Buildkite CI #84995 for commit |
Contributor
Author
|
/ci run |
|
✅ Triggered Buildkite CI #85010 for commit |
njhill
approved these changes
Aug 26, 2026
pawel-olejniczak
added a commit
to pawel-olejniczak/vllm-gaudi
that referenced
this pull request
Aug 28, 2026
…de synchronize_device for HPU Root cause: vllm#52914 added WorkerBase.synchronize_device() defaulting to torch.accelerator.synchronize() plus an EngineCore._finish_pause() that collective_rpc's it on every pause, and HPU rejects a device-wide wait. Upstream: vllm-project/vllm#52914 Fix: HPUWorker.synchronize_device() waits via torch.hpu.synchronize(). Signed-off-by: Paweł Olejniczak <pawelx.olejniczak@intel.com>
iboiko-habana
pushed a commit
to vllm-project/vllm-gaudi
that referenced
this pull request
Aug 28, 2026
…PU HunYuan, Import cli_args from (+3 more) (#1759) This PR consolidates 5 hourly-CI fixes against vllm@`17da48596c98946d3e3e6896e2ebd341e809f3bd` per the single-rolling-PR rule (invariant I9). ## Bug 1: Drop HPU HunYuan V1 overrides deleted upstream - **State machine id**: hunyuan_v1_model_module_removed_plugin_reg - **Commit**: c352fb7 ### Root cause vllm#53615 (48d7132) migrated HunYuan V1/VL to the Transformers modeling backend and deleted vllm/model_executor/models/hunyuan_v1.py, so the eager import in vllm_gaudi/models/__init__.py aborted plugin registration and killed 48 of 51 jobs in CI run 32990520142 before any test could run. ### Culprit Regression introduced by [PR #53615](vllm-project/vllm#53615). ### Fix remove vllm_gaudi/models/hunyuan_v1.py and its two register_model calls; upstream's registry now serves both architectures via the Transformers backend and the HPU subclass only specialized the now-deleted HunYuanAttention. ## Bug 2: Import cli_args from vllm.entrypoints.launchers - **State machine id**: entrypoints_openai_cli_args_module_moved - **Commit**: 935d821 ### Root cause upstream moved vllm/entrypoints/openai/cli_args.py to vllm/entrypoints/launchers/cli_args.py with no compatibility re-export, so multi_model_api_server.py raised ModuleNotFoundError at import time and took down run_unit_tests plus e2e run_online_model_swap_test. ### Culprit Regression introduced by [PR #53659](vllm-project/vllm#53659). ### Fix import make_arg_parser and validate_parsed_serve_args from the new vllm.entrypoints.launchers.cli_args path; both symbols are unchanged there. ## Bug 3: Rename group_mm_kwargs_by_modality to group_and_batch_mm_kwargs - **State machine id**: group_mm_kwargs_by_modality_import_removed - **Commit**: 0988519 ### Root cause vllm#53559 (4f686e1) deleted the deprecated group_mm_kwargs_by_modality alias, so importing HPUModelRunner raises ImportError. ### Culprit Regression introduced by [PR #53559](vllm-project/vllm#53559). ### Fix import and call group_and_batch_mm_kwargs, the signature- and yield-identical replacement upstream renamed it to in vllm#36158. ## Bug 4: Index flattened LoRA _embeddings_indices - **State machine id**: hpu_lora_embeddings_indices_zero_dim_indexerror - **Commit**: fb5e4b0 ### Root cause vLLM PR #53843 flattened PunicaWrapperBase._embeddings_indices from [2, max_num_batched_tokens] to 1-D, so the HPU override's [1] select yielded a 0-dim tensor and slicing it raised IndexError. ### Culprit Regression introduced by [PR #53843](vllm-project/vllm#53843). ### Fix drop the stale row select and slice the 1-D indices directly, mirroring upstream's own forward update. ## Bug 5: Override synchronize_device for HPU - **State machine id**: synchronize_device_torch_accelerator_unsupported - **Commit**: e01570f ### Root cause vllm#52914 added WorkerBase.synchronize_device() defaulting to torch.accelerator.synchronize() plus an EngineCore._finish_pause() that collective_rpc's it on every pause, and HPU rejects a device-wide wait. ### Culprit Regression introduced by [PR #52914](vllm-project/vllm#52914). ### Fix HPUWorker.synchronize_device() waits via torch.hpu.synchronize(). --------- Signed-off-by: Paweł Olejniczak <pawelx.olejniczak@intel.com>
am-cohere
pushed a commit
to am-cohere/vllm
that referenced
this pull request
Sep 1, 2026
…#52914) Signed-off-by: aoshen02 <aoshen@inferact.ai>
mikeshawcode
pushed a commit
to mikeshawcode/vllm
that referenced
this pull request
Sep 1, 2026
…#52914) Signed-off-by: aoshen02 <aoshen@inferact.ai> Signed-off-by: mikeshawcode <michaelwshaw2@gmail.com>
mylibrar
pushed a commit
to tanyuqian/vllm
that referenced
this pull request
Sep 3, 2026
…#52914) Signed-off-by: aoshen02 <aoshen@inferact.ai>
yfw
added a commit
to NVIDIA-NeMo/RL
that referenced
this pull request
Sep 11, 2026
…e extension vLLM 0.29 adds `WorkerBase.synchronize_device` (vllm-project/vllm#52914, used by the pause-completion path) and `WorkerBase.init_worker` asserts that a worker extension never carries an attribute the Worker already has. `VllmInternalWorkerExtension.synchronize_device`, which the sparse-delta refit invokes through `collective_rpc` to drain peers before cleaning up staged batch files, therefore killed every vLLM engine at init on the first 0.29 nightly: AssertionError: Worker class <class 'vllm.v1.worker.gpu_worker.Worker'> already has an attribute synchronize_device, which conflicts with the worker extension class <class '...VllmInternalWorkerExtension'>. Rename the extension method to `synchronize_sparse_refit_device` (the applier's own `synchronize_device` is untouched; it is not on the worker class) and update the RPC caller and its test. Add a `vllm`-marked unit test that mirrors vLLM's collision predicate over both extension classes so the next upstream name clash fails in CI instead of on a GPU job. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Yi-Fu Wu <yifu.wu@gmail.com>
4 tasks done
yfw
added a commit
to NVIDIA-NeMo/RL
that referenced
this pull request
Sep 14, 2026
…e extension vLLM 0.29 adds `WorkerBase.synchronize_device` (vllm-project/vllm#52914, used by the pause-completion path) and `WorkerBase.init_worker` asserts that a worker extension never carries an attribute the Worker already has. `VllmInternalWorkerExtension.synchronize_device`, which the sparse-delta refit invokes through `collective_rpc` to drain peers before cleaning up staged batch files, therefore killed every vLLM engine at init on the first 0.29 nightly: AssertionError: Worker class <class 'vllm.v1.worker.gpu_worker.Worker'> already has an attribute synchronize_device, which conflicts with the worker extension class <class '...VllmInternalWorkerExtension'>. Rename the extension method to `synchronize_sparse_refit_device` (the applier's own `synchronize_device` is untouched; it is not on the worker class) and update the RPC caller and its test. Add a `vllm`-marked unit test that mirrors vLLM's collision predicate over both extension classes so the next upstream name clash fails in CI instead of on a GPU job. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Yi-Fu Wu <yifu.wu@gmail.com>
wangxiyuan
pushed a commit
to vllm-project/vllm-ascend
that referenced
this pull request
Oct 13, 2026
…and wakeup (#17766) ### What this PR does / why we need it? Ports the Ascend backend requirement from vLLM vllm-project/vllm#52914: a resolved pause promises an idle device, and backends outside `torch.accelerator` must provide their own wait. For main branch, there is also a PR #17666 working on this issue. Without this synchronize, in RL scenario, if we sleep exactly when dummy_batch executes, will cause the following issues: ``` [36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] Traceback (most recent call last): ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm/vllm/v1/executor/multiproc_executor.py", line 982, in worker_busy_loop ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] output = func(*args, **kwargs) ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] ^^^^^^^^^^^^^^^^^^^^^ ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm-ascend/vllm_ascend/worker/worker.py", line 228, in sleep ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] allocator.sleep(offload_tags=("weights",) if level == 1 else tuple()) ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm-ascend/vllm_ascend/device_allocator/camem.py", line 220, in sleep ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] torch.npu.empty_cache() ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] File "/usr/local/lib/python3.12/site-packages/torch_npu/npu/memory.py", line 180, in empty_cache ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] torch_npu._C._npu_emptyCache() ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] RuntimeError: npuSynchronizeDevice:../torch_npu/csrc/core/npu/NPUStream.cpp:714 NPU function error: AclrtSynchronizeDeviceWithTimeout, error code is 507015 ``` ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? Tested on A3 platform, using following Qwen3.5-397B script: ```sh # master node: export VLLM_SERVER_DEV_MODE=1 vllm serve /data/LLM/mindSpeed_mm/mm_qwen3_5/grpo/ckpt_hf/Qwen3.5-397B-A17B --tensor-parallel-size 8 --data-parallel-size 4 --data-parallel-size-local 2 --data-parallel-start-rank 0 --data-parallel-address 80.5.21.123 --data-parallel-rpc-port 12345 --max-num-seqs 96 --max-model-len 71680 --max-num-batched-tokens 16384 --enable_expert_parallel --port 20002 --gpu-memory-utilization 0.9 --compilation_config '{"cudagraph_capture_sizes":[4,8,16,32,64,128,192,256,384],"cudagraph_mode": "FULL_DECODE_ONLY"}' --enable-sleep-mode --additional-config '{"weight_nz_mode": 0}' # slave node: export VLLM_SERVER_DEV_MODE=1 vllm serve /data/LLM/mindSpeed_mm/mm_qwen3_5/grpo/ckpt_hf/Qwen3.5-397B-A17B --tensor-parallel-size 8 --data-parallel-size 4 --data-parallel-size-local 2 --data-parallel-start-rank 2 --headless --data-parallel-address 80.5.21.123 --data-parallel-rpc-port 12345 --max-num-seqs 96 --max-model-len 71680 --max-num-batched-tokens 16384 --enable_expert_parallel --port 20002 --gpu-memory-utilization 0.9 --compilation_config '{"cudagraph_capture_sizes":[4,8,16,32,64,128,192,256,384],"cudagraph_mode": "FULL_DECODE_ONLY"}' --enable-sleep-mode --additional-config '{"weight_nz_mode": 0}' ``` and curl this sleep command: ```sh curl -X POST "http://127.0.0.1:20002/sleep?level=1" ``` #### Before this fix The testing case will reply these following error messages without this patch: ``` (ApiServer_1 pid=779773) INFO: Started server process [779773] (ApiServer_1 pid=779773) INFO: Waiting for application startup. (ApiServer_0 pid=779772) INFO: Application startup complete. (ApiServer_1 pid=779773) INFO: Application startup complete. (EngineCore_DP0 pid=779770) INFO 09-29 19:59:07 [core.py:761] Waiting for in-flight requests to complete before sleeping... (EngineCore_DP1 pid=779771) INFO 09-29 19:59:07 [core.py:761] Waiting for in-flight requests to complete before sleeping... (Worker_DP1_TP0_EP8 pid=780969) INFO 09-29 19:59:07 [acl_graph.py:243] Replaying aclgraph (Worker_DP0_TP0_EP0 pid=780976) INFO 09-29 19:59:07 [acl_graph.py:243] Replaying aclgraph (EngineCore_DP0 pid=779770) INFO 09-29 19:59:08 [block_pool.py:490] Successfully reset prefix cache (EngineCore_DP1 pid=779771) INFO 09-29 19:59:08 [block_pool.py:490] Successfully reset prefix cache (Worker_DP0_TP7_EP7 pid=780984) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP1_EP1 pid=780977) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP5_EP5 pid=780981) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP4_EP4 pid=780980) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP3_EP3 pid=780979) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP0_EP0 pid=780976) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP2_EP2 pid=780978) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP4_EP12 pid=780975) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP7_EP15 pid=780986) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP3_EP11 pid=780974) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP0_EP8 pid=780969) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP1_EP9 pid=780970) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP5_EP13 pid=780982) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP6_EP6 pid=780983) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP6_EP14 pid=780985) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP2_EP10 pid=780972) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] WorkerProc hit an exception. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] Traceback (most recent call last): (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm/vllm/v1/executor/multiproc_executor.py", line 982, in worker_busy_loop (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] output = func(*args, **kwargs) (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] ^^^^^^^^^^^^^^^^^^^^^ (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm-ascend/vllm_ascend/worker/worker.py", line 229, in sleep (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] allocator.sleep(offload_tags=("weights",) if level == 1 else tuple()) (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm-ascend/vllm_ascend/device_allocator/camem.py", line 220, in sleep (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] torch.npu.empty_cache() (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] File "/usr/local/lib/python3.12/site-packages/torch_npu/npu/memory.py", line 178, in empty_cache (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] torch_npu._C._npu_emptyCache() (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] RuntimeError: npuSynchronizeDevice:../torch_npu/csrc/core/npu/NPUStream.cpp:714 NPU function error: AclrtSynchronizeDeviceWithTimeout, error code is 507011 (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] [ERROR] 2026-09-29-19:59:10 (PID:780977, Device:1, RankID:-1) ERR00100 PTA call acl api failed (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] [Error]: Model execution failed. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] Rectify the fault based on the error information in the ascend log. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] [PID: 780977] 2026-09-29-19:59:10.232.584 Invalid_Argument(EL0003): The argument is invalid. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] Solution: Try again with a valid argument. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] TraceBack (most recent call last): (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] An error occurs on the device(chipId:0, dieId:1), the serial number is 8, the error is aivec error, core id is 5, error code = 0x800000, dump info: pc start: 0x1242001f8074, current: 0x1242001f8294, vec error info: 0x601d9073df, mte error info: 0xe003000077, ifu error info: 0x22da8102081c0, ccu error info: 0xde118eb01d540ea3, cube error info: 0, biu error info: 0, aic error mask: 0x6500020bd00028c, para base: 0x12c103cf5000, aic cond: 0. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] The extend info: errcode:(0x800000, 0, 0) errorStr: MTE accesses an invalid GM address or the cross-device memory access times out. fixp_error0 info: 0x3000077, fixp_error1 info: 0xe0, fsmId:0, tslot:7, thread:0, ctxid:0, blk:0, sublk:0, subErrType:4. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] For details, see the troubleshooting document on the Ascend official website. Search for the keyword "AI Core Error".[FUNC:PrintCoreInfo][FILE:device_error_core_proc.cc][LINE:1227] (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] The argument is invalid. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] rtMemGetInfoByType execution failed, reason=driver error:invalid handle[FUNC:FuncErrorReason][FILE:error_message_manage.cc][LINE:72] (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] rtDeviceSynchronizeWithTimeout execution failed, reason=the model stream execute failed[FUNC:FuncErrorReason][FILE:error_message_manage.cc][LINE:72] (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] ``` #### After this fix After adding this patch, server can sleep correctly: ```sh (ApiServer_1 pid=987951) INFO: Started server process [987951] (ApiServer_1 pid=987951) INFO: Waiting for application startup. (ApiServer_1 pid=987951) INFO: Application startup complete. (EngineCore_DP0 pid=987948) INFO 09-29 20:14:51 [core.py:761] Waiting for in-flight requests to complete before sleeping... (EngineCore_DP1 pid=987949) INFO 09-29 20:14:51 [core.py:761] Waiting for in-flight requests to complete before sleeping... (Worker_DP1_TP0_EP8 pid=989150) INFO 09-29 20:14:51 [acl_graph.py:243] Replaying aclgraph (Worker_DP0_TP0_EP0 pid=989149) INFO 09-29 20:14:51 [acl_graph.py:243] Replaying aclgraph (EngineCore_DP0 pid=987948) INFO 09-29 20:14:52 [block_pool.py:490] Successfully reset prefix cache (EngineCore_DP1 pid=987949) INFO 09-29 20:14:52 [block_pool.py:490] Successfully reset prefix cache (Worker_DP1_TP1_EP9 pid=989151) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP0_EP8 pid=989150) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP7_EP15 pid=989164) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP3_EP3 pid=989157) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP2_EP2 pid=989156) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP2_EP10 pid=989153) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP7_EP7 pid=989161) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP1_EP1 pid=989152) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP3_EP11 pid=989154) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP6_EP14 pid=989163) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP6_EP6 pid=989160) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP4_EP12 pid=989155) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP5_EP5 pid=989159) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP0_EP0 pid=989149) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP5_EP13 pid=989162) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP4_EP4 pid=989158) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP0_EP8 pid=989150) INFO 09-29 20:14:57 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (Worker_DP0_TP5_EP5 pid=989159) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.96 GiB memory is still in use. (Worker_DP1_TP4_EP12 pid=989155) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (Worker_DP1_TP1_EP9 pid=989151) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.97 GiB memory is still in use. (Worker_DP0_TP1_EP1 pid=989152) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.97 GiB memory is still in use. (Worker_DP0_TP3_EP3 pid=989157) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.97 GiB memory is still in use. (Worker_DP1_TP6_EP14 pid=989163) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.19 GiB memory is still in use. (Worker_DP0_TP6_EP6 pid=989160) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (Worker_DP0_TP7_EP7 pid=989161) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.95 GiB memory is still in use. (Worker_DP1_TP5_EP13 pid=989162) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.95 GiB memory is still in use. (Worker_DP0_TP2_EP2 pid=989156) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (Worker_DP0_TP4_EP4 pid=989158) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.19 GiB memory is still in use. (Worker_DP1_TP7_EP15 pid=989164) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.96 GiB memory is still in use. (Worker_DP0_TP0_EP0 pid=989149) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (EngineCore_DP0 pid=987948) INFO 09-29 20:14:59 [abstract.py:327] It took 6.552437 seconds to fall asleep. (Worker_DP1_TP2_EP10 pid=989153) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.19 GiB memory is still in use. (Worker_DP1_TP3_EP11 pid=989154) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.96 GiB memory is still in use. (EngineCore_DP1 pid=987949) INFO 09-29 20:14:59 [abstract.py:327] It took 7.087198 seconds to fall asleep. (ApiServer_1 pid=987951) INFO: 127.0.0.1:47916 - "POST /sleep?level=1 HTTP/1.1" 200 OK ``` - vLLM main: vllm-project/vllm@ee0da84 Signed-off-by: YuhanBai <yuhan.bai0830@gmail.com>
ZT-AIA
pushed a commit
to vllm-project/vllm-ascend
that referenced
this pull request
Oct 15, 2026
### What this PR does / why we need it? Ports the Ascend backend requirement from vLLM [#52914](vllm-project/vllm#52914): a resolved pause promises an idle device, and backends outside `torch.accelerator` must provide their own wait. Ascend provided none. `pause_generation()` could return while the last dummy batch a DP rank launched was still executing, and `wake_up()` left its tail work (the level-2 buffer restores and the sleep-mode cleanup) unwaited -- so a caller starting a weight sync right after wake-up raced it. This adds `NPUWorker.synchronize_device()`, which blocks on `torch.npu.synchronize()`, and ends `wake_up()` with it. The method stays on the worker rather than relying on inheritance because `wake_up` calls it unconditionally, while vLLM releases predating #52914 define no `WorkerBase.synchronize_device`. Verified against the vLLM tree (`vllm/v1/worker/worker_base.py`): the method is **absent in v0.28.0** and **present from v0.29.0 onward**. v0.28.0 is in the support matrix, so on that line the override is the only barrier that exists -- there is nothing to inherit, and `wake_up()` would otherwise raise `AttributeError`. `sleep()` gets the same treatment, bracketing the memory transition with a barrier on each side: one before the baseline `mem_get_info()` snapshot that the freed-bytes assertion depends on, and one after the optional RL extra cleanup -- whose `destroy_hccl()`/aclgraph work is the last thing that can touch memory before the allocator unmaps it. Without them, `sleep()` racing an in-flight dummy batch fails inside `CaMemAllocator.sleep()`'s `empty_cache()` (`AclrtSynchronizeDeviceWithTimeout`, `507011`/`507015`) -- the same failure the `releases/v0.30.0` fix in #18338 addresses. ### Does this PR introduce _any_ user-facing change? No. Control-plane only; no effect on model output. ### How was this patch tested? Unit tests (`tests/ut/worker/test_worker_v1.py`): every `wake_up` test now patches the barrier and asserts it is reached, `synchronize_device()` delegates to `torch.npu.synchronize()`, and the method is asserted to live on `NPUWorker` itself. Unit tests (`tests/ut/worker/test_kv_cache_allocation_scope.py`) and `test_sleep_uses_rl_extra_cleanup`: the sleep tests now patch the barrier and assert both sleep barriers fire, covering the cleanup-enabled and cleanup-disabled paths. They also stop executing a real `torch.npu.synchronize()` on NPU hosts, which previously made these specs behave differently on hardware versus CPU runners. NPU system tests: - `tests/e2e/pull_request/one_card/rlhf/state_transitions/test_npu_device_synchronize.py` -- on real hardware, `synchronize_device()` and `wake_up()` must leave the NPU stream idle. - `tests/e2e/pull_request/two_card/rlhf/state_transitions/test_pause_device_idle.py` -- the Ascend port of upstream's `test_dp_pause_completion_implies_device_idle`. In DPLB the pause path itself launches the dummy batch whose completion the pause promise covers, so the test inflates the dummy batches the pause consensus manufactures and requires an idle device the moment `pause_generation()` returns. It skips (rather than passing vacuously) on vLLM without the #52914 barrier. - `tests/e2e/pull_request/one_card/rlhf/state_transitions/npu_stream_busy.py` -- the device-busy helper both files share. `torch.cuda._sleep(200_000_000)`, which the upstream test uses to keep a CUDA stream busy, cannot run on NPU: `torch.npu` exposes no `_sleep`, and `torch.cuda._sleep` raises `AttributeError: module 'torch._C' has no attribute '_cuda_sleep'`. `enqueue_npu_busy_work()` queues real matmuls without waiting instead, and `torch.npu.current_stream().query()` reports the same "is the stream quiet" fact as `torch.cuda.current_stream().query()`. Re-verified on Ascend 910B3 (2 chips) against the vLLM main lane (`0.30.0`, the pinned `.github/vllm-main-verified.commit`), i.e. after the sleep barriers were added -- 84 passed: | suite | result | |---|---| | `tests/ut/worker/test_worker_v1.py` + `tests/ut/worker/test_kv_cache_allocation_scope.py` | 81 passed | | `tests/e2e/pull_request/one_card/rlhf/state_transitions/test_npu_device_synchronize.py` | 2 passed | | `tests/e2e/pull_request/two_card/rlhf/state_transitions/test_pause_device_idle.py` | 1 passed (DP=2 engine, not skipped) | The DP pause test uses `Qwen/Qwen2.5-0.5B-Instruct`, a small text-only checkpoint the a3 runners already pre-download. CI runs with `VLLM_USE_MODELSCOPE=1` and `HF_HUB_OFFLINE=1`, so an unlisted checkpoint cannot be fetched on the runners. An earlier A/B check of the pause barrier itself, run on the vLLM 0.29.0 line before the sleep barriers were added, kept a DP=2 engine busy for ~200 ms and then called `pause_generation()`: | | fixed | barrier neutralised | |---|---|---| | `pause_generation()` wall time | 0.229 s | 0.036 s | | device idle when it returned | True | **False** | ### Upstream context Ports the Ascend backend requirement from vLLM [#52914](vllm-project/vllm#52914). - vLLM main: vllm-project/vllm@8cc9aa5 Signed-off-by: SeaAsters <keine214@qq.com> Co-authored-by: OpenAI Codex <codex@openai.com>
zzzzwwjj
pushed a commit
to vllm-project/vllm-ascend
that referenced
this pull request
Oct 15, 2026
…18338) ### What this PR does / why we need it? Ports the Ascend backend requirement from vLLM vllm-project/vllm#52914: a resolved pause promises an idle device, and backends outside `torch.accelerator` must provide their own wait. For main branch, there is also a PR #17666 working on this issue. Without this synchronize, in RL scenario, if we sleep exactly when dummy_batch executes, will cause the following issues: ``` [36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] Traceback (most recent call last): ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm/vllm/v1/executor/multiproc_executor.py", line 982, in worker_busy_loop ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] output = func(*args, **kwargs) ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] ^^^^^^^^^^^^^^^^^^^^^ ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm-ascend/vllm_ascend/worker/worker.py", line 228, in sleep ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] allocator.sleep(offload_tags=("weights",) if level == 1 else tuple()) ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm-ascend/vllm_ascend/device_allocator/camem.py", line 220, in sleep ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] torch.npu.empty_cache() ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] File "/usr/local/lib/python3.12/site-packages/torch_npu/npu/memory.py", line 180, in empty_cache ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] torch_npu._C._npu_emptyCache() ^[[36m(vLLMHttpServer pid=3455188, ip=80.5.21.123)^[[0m (Worker_DP6_TP11_EP107 pid=3455539) ERROR 09-29 15:05:09 [multiproc_executor.py:987] RuntimeError: npuSynchronizeDevice:../torch_npu/csrc/core/npu/NPUStream.cpp:714 NPU function error: AclrtSynchronizeDeviceWithTimeout, error code is 507015 ``` ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? Tested on A3 platform, using following Qwen3.5-397B script: ```sh # master node: export VLLM_SERVER_DEV_MODE=1 vllm serve /data/LLM/mindSpeed_mm/mm_qwen3_5/grpo/ckpt_hf/Qwen3.5-397B-A17B --tensor-parallel-size 8 --data-parallel-size 4 --data-parallel-size-local 2 --data-parallel-start-rank 0 --data-parallel-address 80.5.21.123 --data-parallel-rpc-port 12345 --max-num-seqs 96 --max-model-len 71680 --max-num-batched-tokens 16384 --enable_expert_parallel --port 20002 --gpu-memory-utilization 0.9 --compilation_config '{"cudagraph_capture_sizes":[4,8,16,32,64,128,192,256,384],"cudagraph_mode": "FULL_DECODE_ONLY"}' --enable-sleep-mode --additional-config '{"weight_nz_mode": 0}' # slave node: export VLLM_SERVER_DEV_MODE=1 vllm serve /data/LLM/mindSpeed_mm/mm_qwen3_5/grpo/ckpt_hf/Qwen3.5-397B-A17B --tensor-parallel-size 8 --data-parallel-size 4 --data-parallel-size-local 2 --data-parallel-start-rank 2 --headless --data-parallel-address 80.5.21.123 --data-parallel-rpc-port 12345 --max-num-seqs 96 --max-model-len 71680 --max-num-batched-tokens 16384 --enable_expert_parallel --port 20002 --gpu-memory-utilization 0.9 --compilation_config '{"cudagraph_capture_sizes":[4,8,16,32,64,128,192,256,384],"cudagraph_mode": "FULL_DECODE_ONLY"}' --enable-sleep-mode --additional-config '{"weight_nz_mode": 0}' ``` and curl this sleep command: ```sh curl -X POST "http://127.0.0.1:20002/sleep?level=1" ``` #### Before this fix The testing case will reply these following error messages without this patch: ``` (ApiServer_1 pid=779773) INFO: Started server process [779773] (ApiServer_1 pid=779773) INFO: Waiting for application startup. (ApiServer_0 pid=779772) INFO: Application startup complete. (ApiServer_1 pid=779773) INFO: Application startup complete. (EngineCore_DP0 pid=779770) INFO 09-29 19:59:07 [core.py:761] Waiting for in-flight requests to complete before sleeping... (EngineCore_DP1 pid=779771) INFO 09-29 19:59:07 [core.py:761] Waiting for in-flight requests to complete before sleeping... (Worker_DP1_TP0_EP8 pid=780969) INFO 09-29 19:59:07 [acl_graph.py:243] Replaying aclgraph (Worker_DP0_TP0_EP0 pid=780976) INFO 09-29 19:59:07 [acl_graph.py:243] Replaying aclgraph (EngineCore_DP0 pid=779770) INFO 09-29 19:59:08 [block_pool.py:490] Successfully reset prefix cache (EngineCore_DP1 pid=779771) INFO 09-29 19:59:08 [block_pool.py:490] Successfully reset prefix cache (Worker_DP0_TP7_EP7 pid=780984) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP1_EP1 pid=780977) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP5_EP5 pid=780981) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP4_EP4 pid=780980) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP3_EP3 pid=780979) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP0_EP0 pid=780976) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP2_EP2 pid=780978) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP4_EP12 pid=780975) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP7_EP15 pid=780986) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP3_EP11 pid=780974) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP0_EP8 pid=780969) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP1_EP9 pid=780970) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP5_EP13 pid=780982) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP6_EP6 pid=780983) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP6_EP14 pid=780985) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP2_EP10 pid=780972) INFO 09-29 19:59:08 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] WorkerProc hit an exception. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] Traceback (most recent call last): (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm/vllm/v1/executor/multiproc_executor.py", line 982, in worker_busy_loop (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] output = func(*args, **kwargs) (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] ^^^^^^^^^^^^^^^^^^^^^ (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm-ascend/vllm_ascend/worker/worker.py", line 229, in sleep (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] allocator.sleep(offload_tags=("weights",) if level == 1 else tuple()) (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] File "/autotest/pytorch/torch_autotest/model/run/Qwen35_VL_397B_GRPO/acc_/vllm-ascend/vllm_ascend/device_allocator/camem.py", line 220, in sleep (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] torch.npu.empty_cache() (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] File "/usr/local/lib/python3.12/site-packages/torch_npu/npu/memory.py", line 178, in empty_cache (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] torch_npu._C._npu_emptyCache() (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] RuntimeError: npuSynchronizeDevice:../torch_npu/csrc/core/npu/NPUStream.cpp:714 NPU function error: AclrtSynchronizeDeviceWithTimeout, error code is 507011 (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] [ERROR] 2026-09-29-19:59:10 (PID:780977, Device:1, RankID:-1) ERR00100 PTA call acl api failed (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] [Error]: Model execution failed. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] Rectify the fault based on the error information in the ascend log. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] [PID: 780977] 2026-09-29-19:59:10.232.584 Invalid_Argument(EL0003): The argument is invalid. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] Solution: Try again with a valid argument. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] TraceBack (most recent call last): (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] An error occurs on the device(chipId:0, dieId:1), the serial number is 8, the error is aivec error, core id is 5, error code = 0x800000, dump info: pc start: 0x1242001f8074, current: 0x1242001f8294, vec error info: 0x601d9073df, mte error info: 0xe003000077, ifu error info: 0x22da8102081c0, ccu error info: 0xde118eb01d540ea3, cube error info: 0, biu error info: 0, aic error mask: 0x6500020bd00028c, para base: 0x12c103cf5000, aic cond: 0. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] The extend info: errcode:(0x800000, 0, 0) errorStr: MTE accesses an invalid GM address or the cross-device memory access times out. fixp_error0 info: 0x3000077, fixp_error1 info: 0xe0, fsmId:0, tslot:7, thread:0, ctxid:0, blk:0, sublk:0, subErrType:4. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] For details, see the troubleshooting document on the Ascend official website. Search for the keyword "AI Core Error".[FUNC:PrintCoreInfo][FILE:device_error_core_proc.cc][LINE:1227] (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] The argument is invalid. (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] rtMemGetInfoByType execution failed, reason=driver error:invalid handle[FUNC:FuncErrorReason][FILE:error_message_manage.cc][LINE:72] (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] rtDeviceSynchronizeWithTimeout execution failed, reason=the model stream execute failed[FUNC:FuncErrorReason][FILE:error_message_manage.cc][LINE:72] (Worker_DP0_TP1_EP1 pid=780977) ERROR 09-29 19:59:10 [multiproc_executor.py:987] ``` #### After this fix After adding this patch, server can sleep correctly: ```sh (ApiServer_1 pid=987951) INFO: Started server process [987951] (ApiServer_1 pid=987951) INFO: Waiting for application startup. (ApiServer_1 pid=987951) INFO: Application startup complete. (EngineCore_DP0 pid=987948) INFO 09-29 20:14:51 [core.py:761] Waiting for in-flight requests to complete before sleeping... (EngineCore_DP1 pid=987949) INFO 09-29 20:14:51 [core.py:761] Waiting for in-flight requests to complete before sleeping... (Worker_DP1_TP0_EP8 pid=989150) INFO 09-29 20:14:51 [acl_graph.py:243] Replaying aclgraph (Worker_DP0_TP0_EP0 pid=989149) INFO 09-29 20:14:51 [acl_graph.py:243] Replaying aclgraph (EngineCore_DP0 pid=987948) INFO 09-29 20:14:52 [block_pool.py:490] Successfully reset prefix cache (EngineCore_DP1 pid=987949) INFO 09-29 20:14:52 [block_pool.py:490] Successfully reset prefix cache (Worker_DP1_TP1_EP9 pid=989151) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP0_EP8 pid=989150) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP7_EP15 pid=989164) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP3_EP3 pid=989157) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP2_EP2 pid=989156) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP2_EP10 pid=989153) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP7_EP7 pid=989161) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP1_EP1 pid=989152) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP3_EP11 pid=989154) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP6_EP14 pid=989163) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP6_EP6 pid=989160) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP4_EP12 pid=989155) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP5_EP5 pid=989159) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP0_EP0 pid=989149) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP5_EP13 pid=989162) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP0_TP4_EP4 pid=989158) INFO 09-29 20:14:52 [camem.py:198] CaMem sleep: offloading 138/154 allocations (tags=('weights',)) (Worker_DP1_TP0_EP8 pid=989150) INFO 09-29 20:14:57 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (Worker_DP0_TP5_EP5 pid=989159) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.96 GiB memory is still in use. (Worker_DP1_TP4_EP12 pid=989155) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (Worker_DP1_TP1_EP9 pid=989151) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.97 GiB memory is still in use. (Worker_DP0_TP1_EP1 pid=989152) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.97 GiB memory is still in use. (Worker_DP0_TP3_EP3 pid=989157) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.97 GiB memory is still in use. (Worker_DP1_TP6_EP14 pid=989163) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.19 GiB memory is still in use. (Worker_DP0_TP6_EP6 pid=989160) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (Worker_DP0_TP7_EP7 pid=989161) INFO 09-29 20:14:58 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.95 GiB memory is still in use. (Worker_DP1_TP5_EP13 pid=989162) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.95 GiB memory is still in use. (Worker_DP0_TP2_EP2 pid=989156) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (Worker_DP0_TP4_EP4 pid=989158) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.19 GiB memory is still in use. (Worker_DP1_TP7_EP15 pid=989164) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.96 GiB memory is still in use. (Worker_DP0_TP0_EP0 pid=989149) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.20 GiB memory is still in use. (EngineCore_DP0 pid=987948) INFO 09-29 20:14:59 [abstract.py:327] It took 6.552437 seconds to fall asleep. (Worker_DP1_TP2_EP10 pid=989153) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 4.19 GiB memory is still in use. (Worker_DP1_TP3_EP11 pid=989154) INFO 09-29 20:14:59 [worker.py:235] Sleep mode (level=1) freed 51.30 GiB memory, 3.96 GiB memory is still in use. (EngineCore_DP1 pid=987949) INFO 09-29 20:14:59 [abstract.py:327] It took 7.087198 seconds to fall asleep. (ApiServer_1 pid=987951) INFO: 127.0.0.1:47916 - "POST /sleep?level=1 HTTP/1.1" 200 OK ``` - vLLM main: vllm-project/vllm@ced6857 --------- Signed-off-by: YuhanBai <yuhan.bai0830@gmail.com>
tangdafu
pushed a commit
to tangdafu/vllm-ascend
that referenced
this pull request
Oct 16, 2026
### What this PR does / why we need it? Ports the Ascend backend requirement from vLLM [#52914](vllm-project/vllm#52914): a resolved pause promises an idle device, and backends outside `torch.accelerator` must provide their own wait. Ascend provided none. `pause_generation()` could return while the last dummy batch a DP rank launched was still executing, and `wake_up()` left its tail work (the level-2 buffer restores and the sleep-mode cleanup) unwaited -- so a caller starting a weight sync right after wake-up raced it. This adds `NPUWorker.synchronize_device()`, which blocks on `torch.npu.synchronize()`, and ends `wake_up()` with it. The method stays on the worker rather than relying on inheritance because `wake_up` calls it unconditionally, while vLLM releases predating #52914 define no `WorkerBase.synchronize_device`. Verified against the vLLM tree (`vllm/v1/worker/worker_base.py`): the method is **absent in v0.28.0** and **present from v0.29.0 onward**. v0.28.0 is in the support matrix, so on that line the override is the only barrier that exists -- there is nothing to inherit, and `wake_up()` would otherwise raise `AttributeError`. `sleep()` gets the same treatment, bracketing the memory transition with a barrier on each side: one before the baseline `mem_get_info()` snapshot that the freed-bytes assertion depends on, and one after the optional RL extra cleanup -- whose `destroy_hccl()`/aclgraph work is the last thing that can touch memory before the allocator unmaps it. Without them, `sleep()` racing an in-flight dummy batch fails inside `CaMemAllocator.sleep()`'s `empty_cache()` (`AclrtSynchronizeDeviceWithTimeout`, `507011`/`507015`) -- the same failure the `releases/v0.30.0` fix in vllm-project#18338 addresses. ### Does this PR introduce _any_ user-facing change? No. Control-plane only; no effect on model output. ### How was this patch tested? Unit tests (`tests/ut/worker/test_worker_v1.py`): every `wake_up` test now patches the barrier and asserts it is reached, `synchronize_device()` delegates to `torch.npu.synchronize()`, and the method is asserted to live on `NPUWorker` itself. Unit tests (`tests/ut/worker/test_kv_cache_allocation_scope.py`) and `test_sleep_uses_rl_extra_cleanup`: the sleep tests now patch the barrier and assert both sleep barriers fire, covering the cleanup-enabled and cleanup-disabled paths. They also stop executing a real `torch.npu.synchronize()` on NPU hosts, which previously made these specs behave differently on hardware versus CPU runners. NPU system tests: - `tests/e2e/pull_request/one_card/rlhf/state_transitions/test_npu_device_synchronize.py` -- on real hardware, `synchronize_device()` and `wake_up()` must leave the NPU stream idle. - `tests/e2e/pull_request/two_card/rlhf/state_transitions/test_pause_device_idle.py` -- the Ascend port of upstream's `test_dp_pause_completion_implies_device_idle`. In DPLB the pause path itself launches the dummy batch whose completion the pause promise covers, so the test inflates the dummy batches the pause consensus manufactures and requires an idle device the moment `pause_generation()` returns. It skips (rather than passing vacuously) on vLLM without the #52914 barrier. - `tests/e2e/pull_request/one_card/rlhf/state_transitions/npu_stream_busy.py` -- the device-busy helper both files share. `torch.cuda._sleep(200_000_000)`, which the upstream test uses to keep a CUDA stream busy, cannot run on NPU: `torch.npu` exposes no `_sleep`, and `torch.cuda._sleep` raises `AttributeError: module 'torch._C' has no attribute '_cuda_sleep'`. `enqueue_npu_busy_work()` queues real matmuls without waiting instead, and `torch.npu.current_stream().query()` reports the same "is the stream quiet" fact as `torch.cuda.current_stream().query()`. Re-verified on Ascend 910B3 (2 chips) against the vLLM main lane (`0.30.0`, the pinned `.github/vllm-main-verified.commit`), i.e. after the sleep barriers were added -- 84 passed: | suite | result | |---|---| | `tests/ut/worker/test_worker_v1.py` + `tests/ut/worker/test_kv_cache_allocation_scope.py` | 81 passed | | `tests/e2e/pull_request/one_card/rlhf/state_transitions/test_npu_device_synchronize.py` | 2 passed | | `tests/e2e/pull_request/two_card/rlhf/state_transitions/test_pause_device_idle.py` | 1 passed (DP=2 engine, not skipped) | The DP pause test uses `Qwen/Qwen2.5-0.5B-Instruct`, a small text-only checkpoint the a3 runners already pre-download. CI runs with `VLLM_USE_MODELSCOPE=1` and `HF_HUB_OFFLINE=1`, so an unlisted checkpoint cannot be fetched on the runners. An earlier A/B check of the pause barrier itself, run on the vLLM 0.29.0 line before the sleep barriers were added, kept a DP=2 engine busy for ~200 ms and then called `pause_generation()`: | | fixed | barrier neutralised | |---|---|---| | `pause_generation()` wall time | 0.229 s | 0.036 s | | device idle when it returned | True | **False** | ### Upstream context Ports the Ascend backend requirement from vLLM [#52914](vllm-project/vllm#52914). - vLLM main: vllm-project/vllm@8cc9aa5 Signed-off-by: SeaAsters <keine214@qq.com> Co-authored-by: OpenAI Codex <codex@openai.com>
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.
Addresses the third problem in #51476:
pause_generation()resolves before the device is idle — and in DP, the pause path is itself what makes the device busy. Companion PR #52957 (independent, no shared commits) removes the DP dummy-batch burst; this PR makes the pause completion contract correct regardless of how much work is in flight.Purpose
1. Pause completion is a CPU-side predicate. The pause future resolves off
has_work()and the DP consensus is a gloo CPU all-reduce; nothing on the pause path touches a CUDA stream.sleep()is safe only becauseGPUWorker.sleepsynchronizes before unmapping — bare pause is sleep minus the synchronizing half. RL callers pause, run their own weight-sync kernels/NCCL, then sleep; that work races whatever the engine launched last. Reported from production, surviving today only on the incidental ~0.5s between pause and sleep.2. The pause path launches unwaited GPU work.
DPEngineCoreProc._pause_completekick-startsengines_running = Trueso every rank reaches the consensus all-reduce in_has_global_unfinished_reqs— and the fixed every-32-step cadence then forces 32 dummy forwards per rank per pause call on an idle engine. The final dummy batch is launched in the consensus iteration itself, is not inbatch_queue, and is invisible tohas_work(); one iteration later the future resolves while it can still be executing.wait_for_requests_to_drain()cannot compensate: the coordinator only tracks request-driven waves, so during the burst it publishes "not running" and drain returns instantly.Measured (DP=2 + EP, PowerMoE-3b, dummy batch inflated to ~110ms to model a large-MoE step):
pause_generation()on an idle engine takes 3.40s and returns with the device still busy.Change
A device barrier at pause completion.
WorkerBase.synchronize_device()synchronizes through the device-generictorch.acceleratorAPI whenever an accelerator is registered — the same barriersleep()relies on — so CUDA, XPU and any othertorch.acceleratorbackend get it without an override, and it stays a no-op only where there is genuinely no accelerator (CPU); backends outsidetorch.acceleratormust override with their own wait.EngineCore._finish_pause():collective_rpc("synchronize_device"), then cache reset — synchronizing first also stopsclear_cache=Truefrom resetting state the last launched batch may still be using. Called from all three completion paths (in-proc, fast path, deferred idle callback).collective_rpcwaits for all workers, which also closesexecute_dummy_batchwaiting only for the output rank.The barrier does not shrink the burst itself: an idle-engine DP pause still runs 32 dummy forwards, it just waits for them honestly. #52957 cuts the burst to a single step with a one-condition cadence change; the two PRs compose but neither depends on the other.
The same contract is applied to the mirror transition:
GPUWorker.wake_upnow ends withtorch.accelerator.synchronize().sleepsynchronizes on both sides of the memory transition,wake_upon neither — its tail work (buffer restores after level-2 sleep,post_kv_cache_wake_up's re-init kernels) was unwaited, so a caller could start same-device work (e.g. RLHF weight sync right after wake) racing it. Covered by the existing sleep/wake e2e cases in the regression suite below.Reproduction (scripts included)
Requires 2 GPUs and
vllm/vllm-openai:nightly. Save the three files below into a directory$W, then:(If NCCL fails at init on a CUDA-13.1 driver, add
-e NCCL_NVLS_ENABLE=0.)gpupatch.py — instrumentation only: inflates the dummy batch to ~110ms to model a large-MoE step, and adds a
device_idle()probe RPCrepro_gpu.py — the scenario: pause / drain / probe
gpurepro.sh — container entrypoint
pause_generation()returnspause_generation()wall time on an idle enginepause_done=False, device busyTest Plan
Three unit tests in
tests/v1/engine/test_engine_core.py(no GPU): the pause-ordering contracts — fast path and deferred path run synchronize → cache reset → future resolution, and overlapping pause calls each complete behind their own barrier.Two adversarial DP tests for edges the pause path crosses that had no coverage:
mode="wait"draining through the DP consensus path, and pausing a sleeping engine — whose ranks skip dummy batches yet must still reach consensus, with the barrier running against unmapped memory.Regression:
tests/v1/distributed/test_async_llm_dp.py -k "dp_pause or dp_sleep or prefill_schedule"— includes the anti-#38009 staggered-race and barrier-deadlock guards and the #51481 late-request pair.Test Result
vllm/vllm-openai:nightly(0.26.1rc1.dev942), A/B on H200s,before= unpatched image:LLMsleep/wake smoke, MPClient and in-procEssential Elements
/pause/stepfast pause + barrier for online weight update #31741 adds a different, step-bounded pause endpoint and does not synchronize the device). Filed under [RFC]: DP pause/sleep correctness: coordinator latch, request admission, device-idle completion, and sleep/pause layering #51476; [Core] Sync DP state on the first step of a wave #52957 is the independent cadence companion.torch.acceleratorbackend hole fixed in the base implementation). The submitter has reviewed each changed line and the runs above.