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
256 lines
8.4 KiB
Python
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})"
|