Files
wehub-resource-sync 94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:38:16 +08:00

256 lines
8.4 KiB
Python

"""
Shared device abstraction for SGLang platforms.
DeviceMixin provides the common device identity queries and operations
shared between the SRT (LLM inference) and Multimodal (diffusion)
platform hierarchies. Concrete per-device mixins (e.g. MyDeviceMixin)
implement the abstract operations; subsystem-specific platforms
(SRTPlatform, MMPlatform) inherit DeviceMixin and add their own methods.
Hierarchy example (OOT plugin)::
DeviceMixin
├── MyDeviceMixin(DeviceMixin) # vendor-specific device operations
├── SRTPlatform(DeviceMixin) # + graph runner, KV pool, …
│ └── MySRTPlatform(SRTPlatform, MyDeviceMixin)
└── MMPlatform(DeviceMixin) # + attention backend, VAE, …
└── MyMMPlatform(MMPlatform, MyDeviceMixin)
Method status annotations:
- ``[Active]`` — SGLang core calls this method through ``current_platform``.
OOT implementations take effect immediately.
- ``[Planned]`` — Reserved interface. SGLang core still uses hardcoded calls
(e.g. ``torch.cuda.empty_cache()``). OOT implementations will NOT take
effect until the core is migrated in a future PR.
"""
import enum
import random
from typing import NamedTuple, Optional
import numpy as np
import torch
from sglang.srt.environ import envs
class PlatformEnum(enum.Enum):
"""Enumeration of known platform types.
Superset of both SRT and MM enums so that a single PlatformEnum can
be shared across subsystems.
"""
CUDA = enum.auto()
ROCM = enum.auto()
CPU = enum.auto()
XPU = enum.auto()
MUSA = enum.auto()
NPU = enum.auto()
TPU = enum.auto()
MPS = enum.auto()
OOT = enum.auto() # Out-of-tree (external plugin)
UNSPECIFIED = enum.auto()
class CpuArchEnum(enum.Enum):
"""CPU architecture enumeration."""
X86 = enum.auto()
ARM = enum.auto()
UNSPECIFIED = enum.auto()
class DeviceCapability(NamedTuple):
"""Device compute capability (major, minor).
Uses NamedTuple for built-in comparison support:
``DeviceCapability(9, 0) >= DeviceCapability(8, 9)`` works naturally.
"""
major: int
minor: int
def as_version_str(self) -> str:
return f"{self.major}.{self.minor}"
def to_int(self) -> int:
"""Express capability as ``<major><minor>`` (minor is single digit)."""
assert 0 <= self.minor < 10
return self.major * 10 + self.minor
_DEVICE_TO_DISTRIBUTED_BACKEND: dict[str, str] = {
"cuda": "nccl",
"xpu": "xccl",
"hpu": "hccl",
"cpu": "gloo",
"npu": "hccl" if not envs.SGLANG_ZBAL_LOCAL_MEM_SIZE.get() > 0 else "zbal",
"musa": "mccl",
}
class DeviceMixin:
"""Mixin providing device identity queries and basic device operations.
Class-level attributes (override in subclasses):
_enum: PlatformEnum identifying this platform.
device_name: Human-readable short name (e.g. "cuda", "npu").
device_type: ``torch.device`` type string (e.g. "cuda", "npu").
"""
_enum: PlatformEnum = PlatformEnum.UNSPECIFIED
device_name: str = "unknown"
device_type: str = "cpu"
# ------------------------------------------------------------------
# Platform identity queries
# ------------------------------------------------------------------
def is_cuda(self) -> bool:
return self._enum == PlatformEnum.CUDA
def is_rocm(self) -> bool:
return self._enum == PlatformEnum.ROCM
def is_cpu(self) -> bool:
return self._enum == PlatformEnum.CPU
def is_xpu(self) -> bool:
return self._enum == PlatformEnum.XPU
def is_musa(self) -> bool:
return self._enum == PlatformEnum.MUSA
def is_npu(self) -> bool:
return self._enum == PlatformEnum.NPU
def is_tpu(self) -> bool:
return self._enum == PlatformEnum.TPU
def is_mps(self) -> bool:
return self._enum == PlatformEnum.MPS
def is_cuda_alike(self) -> bool:
"""True for CUDA, ROCm, or MUSA (all expose CUDA-like APIs)."""
return self._enum in (
PlatformEnum.CUDA,
PlatformEnum.ROCM,
PlatformEnum.MUSA,
)
def is_out_of_tree(self) -> bool:
"""True for externally-registered OOT platforms."""
return self._enum == PlatformEnum.OOT
# ------------------------------------------------------------------
# Active methods — core calls these through current_platform.
# OOT implementations take effect immediately.
# ------------------------------------------------------------------
def get_device_total_memory(self, device_id: int = 0) -> int:
"""[Active] Get total device memory in bytes."""
raise NotImplementedError
def get_current_memory_usage(
self, device: Optional["torch.device"] = None
) -> float:
"""[Active] Get current peak memory usage in bytes."""
raise NotImplementedError
# ------------------------------------------------------------------
# Planned methods — reserved interface. Core still uses hardcoded
# calls (e.g. torch.cuda.*). OOT implementations will NOT take
# effect until the core is migrated in a future PR.
# ------------------------------------------------------------------
# ---- Device management ----
def get_device(self, device_id: int = 0) -> str:
"""[Planned] Return ``torch.device`` for the given device id."""
raise NotImplementedError
def set_device(self, device: "torch.device") -> None:
"""[Planned] Set the current device."""
raise NotImplementedError
def get_device_name(self, device_id: int = 0) -> str:
"""[Planned] Get human-readable device name."""
raise NotImplementedError
def get_device_uuid(self, device_id: int = 0) -> str:
"""[Planned] Get unique device identifier string."""
raise NotImplementedError
def get_device_capability(self, device_id: int = 0) -> Optional["DeviceCapability"]:
"""[Planned] Get device compute capability. None if N/A."""
raise NotImplementedError
def empty_cache(self) -> None:
"""[Planned] Release cached device memory. No-op for CPU-like platforms."""
pass
def synchronize(self) -> None:
"""[Planned] Synchronize device operations. No-op for CPU-like platforms."""
pass
# ---- Memory ----
def get_available_memory(self, device_id: int = 0) -> tuple[int, int]:
"""[Planned] Return ``(free_bytes, total_bytes)``."""
raise NotImplementedError
# ---- Distributed ----
def get_torch_distributed_backend_str(self) -> str:
"""Return the torch.distributed backend string (e.g. "nccl", "hccl").
Default: lookup ``self.device_type`` in ``_DEVICE_TO_DISTRIBUTED_BACKEND``,
falling back to ``"gloo"``. Subclasses override only when they need a
non-default backend (e.g. mooncake, or a brand-new device).
"""
return _DEVICE_TO_DISTRIBUTED_BACKEND.get(self.device_type, "gloo")
def get_communicator_class(self) -> type | None:
"""[Planned] Return platform-specific communicator class, or None for default."""
return None
# ---- Misc ----
@classmethod
def inference_mode(cls):
"""[Planned] Return inference mode context manager."""
return torch.inference_mode(mode=True)
@classmethod
def seed_everything(cls, seed: int | None = None) -> None:
"""[Planned] Set random seeds for reproducibility across all libraries."""
if seed is not None:
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
def verify_quantization(self, quant: str) -> None:
"""[Planned] Validate that a quantization method is supported. No-op by default."""
pass
@classmethod
def get_cpu_architecture(cls) -> "CpuArchEnum":
"""[Planned] Detect CPU architecture."""
import platform as _platform
machine = _platform.machine().lower()
if machine in ("x86_64", "amd64", "i386", "i686"):
return CpuArchEnum.X86
elif machine in ("arm64", "aarch64"):
return CpuArchEnum.ARM
return CpuArchEnum.UNSPECIFIED
# ------------------------------------------------------------------
# Dunder helpers
# ------------------------------------------------------------------
def __repr__(self) -> str:
return f"{self.__class__.__name__}(device={self.device_name})"