Files
wehub-resource-sync a203934033
Lint test / lint (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:34:58 +08:00

92 lines
3.5 KiB
Python

# Copyright (c) ModelScope Contributors. All rights reserved.
"""Small vLLM-Ascend memory API compatibility patches.
This module intentionally avoids colocate memory-policy changes. It only
normalizes API differences that are safe for both standalone vLLM-Ascend
inference and SWIFT GRPO rollout.
"""
from __future__ import annotations
import torch
from contextlib import contextmanager
from functools import partial
_ORIGIN_TORCH_NPU_MEM_GET_INFO = None
_BOUND_TORCH_NPU_MEM_GET_INFO_DEVICE = None
def _patch_vllm_ascend_mem_get_info() -> None:
"""Patch ``NPUPlatform.mem_get_info`` for torch-npu binding differences.
vLLM-Ascend calls ``current_platform.mem_get_info(device)`` during worker
initialization. Without this wrapper, some versions expose
``NPUPlatform.mem_get_info`` in a way that gets Python method binding plus
the explicit device argument at the same time, producing:
TypeError: mem_get_info() got multiple values for argument 'device'
Defining a classmethod here gives vLLM-Ascend one stable call surface. It
keeps the device-aware torch-npu query when available and falls back to the
no-argument query only when torch-npu rejects the keyword. This does not
change memory profiling policy.
"""
try:
from vllm_ascend.platform import NPUPlatform
except (ImportError, AttributeError):
return
if getattr(NPUPlatform, '_swift_mem_get_info_patched', False):
return
@classmethod
def mem_get_info(cls, device=None):
if device is None:
return torch.npu.mem_get_info()
try:
return torch.npu.mem_get_info(device=device)
except TypeError:
return torch.npu.mem_get_info()
NPUPlatform.mem_get_info = mem_get_info
NPUPlatform._swift_mem_get_info_patched = True
def patch_vllm_ascend_memory_runtime() -> None:
"""Apply memory patches that do not depend on colocated training."""
_patch_vllm_ascend_mem_get_info()
@contextmanager
def vllm_ascend_mem_get_info_context(vllm_device: str):
"""Bind bare ``torch.npu.mem_get_info()`` calls to vLLM's device.
Most vLLM memory accounting goes through ``NPUPlatform.mem_get_info`` and is
handled by ``patch_vllm_ascend_memory_runtime`` above. Some vLLM-Ascend
paths still call ``torch.npu.mem_get_info()`` directly, or assign it to
``torch.cuda.mem_get_info`` for CUDA-compatible worker code.
Keep this binding for the process lifetime after the context exits. vLLM
sleep/wake paths can call bare ``torch.npu.mem_get_info()`` after engine
construction, so restoring here would regress the original behavior in
``swift.infer_engine.utils.patch_npu_vllm``. Re-entering with another device
rebinds from the original function instead of stacking nested partials.
"""
global _ORIGIN_TORCH_NPU_MEM_GET_INFO, _BOUND_TORCH_NPU_MEM_GET_INFO_DEVICE
if (_ORIGIN_TORCH_NPU_MEM_GET_INFO is None
or getattr(torch.npu.mem_get_info, '_swift_bound_mem_get_info_device', None) is None):
_ORIGIN_TORCH_NPU_MEM_GET_INFO = torch.npu.mem_get_info
if _BOUND_TORCH_NPU_MEM_GET_INFO_DEVICE != vllm_device:
mem_get_info = partial(_ORIGIN_TORCH_NPU_MEM_GET_INFO, device=vllm_device)
mem_get_info._swift_bound_mem_get_info_device = vllm_device
torch.npu.mem_get_info = mem_get_info
_BOUND_TORCH_NPU_MEM_GET_INFO_DEVICE = vllm_device
yield
__all__ = [
'patch_vllm_ascend_memory_runtime',
'vllm_ascend_mem_get_info_context',
]