[XPU] Fix UVA weight offloading (non-pinned-tensor views and static Triton launcher) (#51770)

Signed-off-by: Chaojun Zhang <chaojun.zhang@intel.com>

Chaojun Zhang committed Aug 11, 2026 at 21:48 UTC f863387250cfc24c04d07b3593ea18a541ba2b8a
2 files changed +33 -1
vllm/platforms/xpu.py
+24
@@ -326,6 +326,30 @@ class XPUPlatform(Platform):
326 )
327 setattr(pass_config, flag, False)
328
329 + # UVA-offloaded weights are host USM allocations, which Inductor's
330 + # static Triton launcher rejects ("Pointer argument doesn't reference
331 + # XPU device memory"). Fall back to Triton's own launcher. Remove once
332 + # the released torch contains pytorch/pytorch#188240, which relaxes
333 + # that check to any memory type known by the driver.
334 + offload_config = vllm_config.offload_config
335 + uva_offloading = offload_config.offload_backend == "uva" or (
336 + offload_config.offload_backend == "auto"
337 + and offload_config.prefetch.offload_group_size == 0
338 + and offload_config.uva.cpu_offload_gb > 0
339 + )
340 + if (
341 + uva_offloading
342 + and not envs.VLLM_WEIGHT_OFFLOADING_DISABLE_UVA
343 + and compilation_config.mode != CompilationMode.NONE
344 + ):
345 + compilation_config.inductor_compile_config.setdefault(
346 + "use_static_cuda_launcher", False
347 + )
348 + logger.info_once(
349 + "Disabling Inductor's static Triton launcher because UVA "
350 + "weight offloading is enabled."
351 + )
352 +
353 # check and update parallel config
354 parallel_config = vllm_config.parallel_config
355 # Only override worker_cls if it's still the default "auto"
vllm/utils/torch_utils.py
+9 -1
@@ -887,7 +887,15 @@ def get_accelerator_view_from_cpu_tensor(cpu_tensor: torch.Tensor) -> torch.Tens
887 from vllm.platforms import current_platform
888
889 if current_platform.is_xpu():
890 - assert cpu_tensor.is_pinned(), "CPU tensor must be pinned"
890 + # Remove once the vllm-xpu-kernels fix for empty and non-pinned inputs
891 + # (vllm-project/vllm-xpu-kernels#513) is in a released package.
892 + if cpu_tensor.numel() == 0:
893 + return torch.empty(cpu_tensor.shape, dtype=cpu_tensor.dtype, device="xpu")
894 + if not cpu_tensor.is_pinned():
895 + contiguous_cpu = cpu_tensor.contiguous()
896 + pinned = torch.empty_like(contiguous_cpu, pin_memory=True)
897 + pinned.copy_(contiguous_cpu)
898 + cpu_tensor = pinned
899 return torch.ops._C.get_xpu_view_from_cpu_tensor(cpu_tensor)
900 elif current_platform.is_cuda_alike():
901 return torch.ops._C.get_cuda_view_from_cpu_tensor(cpu_tensor)