[Perf] Split xdrope_positions H2D copy into per-row transfers (#53412)
Signed-off-by: Keyi Li <likey6688@gmail.com> Co-authored-by: Keyi Li <likey6688@gmail.com>
Keyi Li committed
Aug 28, 2026 at 10:28 UTC
6f91e3d9537ea45128534ba9a234b81d6c843281
1 file changed
+12
-5
vllm/v1/worker/gpu_model_runner.py
+12
-5
@@ -2227,11 +2227,18 @@ class GPUModelRunner(
2227
non_blocking=True,
2228
)
2229
elif self.uses_xdrope_dim > 0:
2230
- # Only relevant for models using XD-RoPE (e.g, HunYuan-VL)
2231
- self.xdrope_positions.gpu[:, :total_num_scheduled_tokens].copy_(
2232
- self.xdrope_positions.cpu[:, :total_num_scheduled_tokens],
2233
- non_blocking=True,
2234
- )
2230
+ # Only relevant for models using XD-RoPE (e.g, HunYuan-VL).
2231
+ # xdrope_positions is allocated as [uses_xdrope_dim, max_num_tokens
2232
+ # + 1] with the same trailing-column trick as mrope_positions above,
2233
+ # so cpu[:, :N] is a strided view of the pinned buffer and the
2234
+ # single-slice copy_() runs into the same pageable-fallback silent
2235
+ # sync described in PR #51841. Split into per-row copies for the
2236
+ # same reason.
2237
+ for row in range(self.xdrope_positions.gpu.shape[0]):
2238
+ self.xdrope_positions.gpu[row, :total_num_scheduled_tokens].copy_(
2239
+ self.xdrope_positions.cpu[row, :total_num_scheduled_tokens],
2240
+ non_blocking=True,
2241
+ )
2242
if self.use_async_spec_decode and (self.uses_mrope or self.uses_xdrope_dim > 0):
2243
drift = self.num_computed_tokens[req_indices_gpu].to(
2244
torch.int64