Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: musa <musa@local>
Date: Mon, 28 Sep 2026 12:00:00 +0800
Subject: [PATCH] MUSA: rotate V2 runner output copy streams

On MUSA, once a later step's copy-stream wait is queued, an earlier step's
output copy event completes only after that later step finishes, so each
sampled token is published one step late and the host launches every other
step after the GPU has drained. Give each in-flight step its own output copy
stream, sized by max_concurrent_batches, for both the sampling and pooling
outputs.
---
vllm/v1/worker/gpu/model_runner.py | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/vllm/v1/worker/gpu/model_runner.py b/vllm/v1/worker/gpu/model_runner.py
index 79953a7..aa11c25 100644
--- a/vllm/v1/worker/gpu/model_runner.py
+++ b/vllm/v1/worker/gpu/model_runner.py
@@ -192,6 +192,15 @@ class GPUModelRunner(LoRAModelRunnerMixin):
self.is_encoder_decoder = self.model_config.is_encoder_decoder

self.output_copy_stream = torch.cuda.Stream(self.device)
+ # MUSA: a copy-stream wait queued for a later step delays an earlier step's
+ # copy event until that later step finishes, so each in-flight step gets
+ # its own stream.
+ self._output_copy_streams = [self.output_copy_stream]
+ self._output_copy_streams.extend(
+ torch.cuda.Stream(self.device)
+ for _ in range(max(1, vllm_config.max_concurrent_batches - 1))
+ )
+ self._output_copy_stream_idx = 0

# Pipeline parallelism.
self.use_pp = self.parallel_config.pipeline_parallel_size > 1
@@ -1818,7 +1827,7 @@ class GPUModelRunner(LoRAModelRunnerMixin):
sampler_output=sampler_output,
num_sampled_tokens=num_sampled,
main_stream=self.main_stream,
- copy_stream=self.output_copy_stream,
+ copy_stream=self._next_output_copy_stream(),
check_ep_fault=self.check_ep_fault,
routed_experts=routed_experts,
)
@@ -1894,6 +1903,12 @@ class GPUModelRunner(LoRAModelRunnerMixin):

return async_output

+ def _next_output_copy_stream(self) -> torch.cuda.Stream:
+ streams = self._output_copy_streams
+ stream = streams[self._output_copy_stream_idx]
+ self._output_copy_stream_idx = (self._output_copy_stream_idx + 1) % len(streams)
+ return stream
+
def take_draft_token_ids(self) -> DraftTokenIds | None:
return self.draft_tokens_handler.get_draft_tokens()

@@ -1935,7 +1950,7 @@ class GPUModelRunner(LoRAModelRunnerMixin):
pooler_output=pooler_output,
finished_mask=finished_mask,
main_stream=self.main_stream,
- copy_stream=self.output_copy_stream,
+ copy_stream=self._next_output_copy_stream(),
)

self.postprocess_num_computed_tokens(input_batch)
6 changes: 4 additions & 2 deletions vllm_musa/patches/series/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ is pre-patched.
Author headers are normalized to the synthetic
`musa <musa@local>` identity.

Currently **171 patches**. This branch includes the Qwen3.6 patches for common
Currently **172 patches**. This branch includes the Qwen3.6 patches for common
GDN decode metadata reuse, uniform-decode SSM slot-mapping removal, and the
BF16 W1 tile specialization, plus the contract-bound DeepSeek-V4 MTP
sparse-prefill headroom and mixed-prefill queue-fence patches. It additionally
Expand Down Expand Up @@ -46,7 +46,9 @@ shape fallback. On that same native path the compressor also writes
packed kv/score+ape into the state cache so Triton `save_partial_states`
is skipped. Interleaved MRoPE rebuilds the T/H/W frequency layout with a
strided copy rather than per-channel index arithmetic, which keeps the
per-layer launch count off the eager prefill path. The fused TileLang `hc_head` is
per-layer launch count off the eager prefill path. Model Runner V2 gives each
in-flight step its own output copy stream so a step's sampled tokens are not
held back by a later step's copy-stream wait. The fused TileLang `hc_head` is
enabled on MUSA by importing TileLang before the eager JIT decorators capture
their module globals. DeepEP shutdown now drops cached handles before native
teardown and supports both explicit `destroy()` and legacy destructor-only
Expand Down