sgl-project/sglang · error · ImportError
{_METALLIB_NAME} not found next to the native Metal extensio
Error message
{_METALLIB_NAME} not found next to the native Metal extension at {_metallib_path} What it means
This ImportError is raised at import time of sgl_kernel.metal when the default.metallib Metal shader library file is not found next to the compiled native extension (_metal). The Python wrapper verifies the .metallib artifact exists before calling _metal.register_library, because the Metal kernels cannot run without the precompiled shader library. If missing, the module silently sets _metal = None (guarded at call time), so the error surfaces later as a call-time failure on Metal platforms.
Source
Thrown at python/sglang/kernels/aot/python/sgl_kernel/metal.py:18
"""Python entry points for the sgl_kernel Metal extension."""
from __future__ import annotations
from pathlib import Path
from typing import TYPE_CHECKING
if TYPE_CHECKING:
import mlx.core as mx
_METALLIB_NAME = "sgl_metal_kernels.metallib"
try:
from . import _metal
_metallib_path = Path(_metal.__file__).resolve().parent / _METALLIB_NAME
if not _metallib_path.is_file():
raise ImportError(
f"{_METALLIB_NAME} not found next to the native Metal extension "
f"at {_metallib_path}"
)
_metal.register_library(str(_metallib_path))
except ImportError as _exc: # pragma: no cover - import guarded at call time
_metal = None
_IMPORT_ERROR: Exception | None = _exc
else:
_IMPORT_ERROR = None
# Python wrappers for the compiled `_metal.*` entry points go below. Wrappers
# validate input shapes/dtypes and then invoke AOT C++ entry points. They do
# not force `mx.eval`, so MLX can keep these calls inside its lazy graph.
def rope_pool_fused(
q: mx.array,
k: mx.array,View on GitHub (pinned to 0132848349)
Solutions
- Reinstall the wheel: pip install --force-reinstall sgl-kernel (use a macOS/Metal-enabled build)
- If building from source, run the Metal AOT build step that produces default.metallib and place it next to the _metal extension .so
- Verify the file exists: ls $(python -c "import sgl_kernel.metal as m; import os; print(os.path.dirname(m.__file__))")
- If on Linux/CUDA, this path is irrelevant — ensure you are not accidentally importing the metal module on a CUDA build
Example fix
# before: import fails silently, _metal is None
from sgl_kernel import metal
metal.rope_pool_fused(...) # fails at call time
# after: guard at import time
from sgl_kernel import metal
if metal._metal is None:
raise RuntimeError("Metal kernels unavailable; reinstall sgl-kernel for macOS") Defensive patterns
Strategy: try-catch
Validate before calling
import importlib.util, pathlib
spec = importlib.util.find_spec("sgl_kernel._metal")
metallib_ok = spec is not None and (pathlib.Path(spec.origin).parent / "default.metallib").is_file() Type guard
def metal_available() -> bool:
try:
from sgl_kernel import metal
return metal._metal is not None
except Exception:
return False Try / catch
try:
from sgl_kernel import metal
except ImportError:
metal = None
if metal is None or metal._metal is None:
raise RuntimeError("Metal kernels unavailable; reinstall macOS sgl-kernel build") Prevention
- Install sgl-kernel from an official macOS/Metal wheel matching your version
- After install, verify default.metallib sits next to the _metal extension
- Guard Metal code paths behind an availability check before first use
When it happens
Trigger: Importing sgl_kernel.metal on macOS/Metal builds where the wheel or AOT build did not package default.metallib next to the _metal native extension; broken pip install; building from source without running the Metal AOT kernel build step; manually copying the extension without its .metallib.
Common situations: Installing an sgl-kernel wheel built without Metal support; upgrading sgl-kernel to a version with a changed packaging layout; running on non-Apple hardware where Metal artifacts are absent; source builds where CMAKE/BuildMetal step was skipped.
Related errors
- rope_pool_fused expects q/k/v to be 3-D
- rope_pool_fused expects positions/slots to be 1-D
- rope_pool_fused expects pool tensors to be 3-D
- q shape must be [num_tokens, num_qo_heads, head_dim], got {q
- k shape must be [num_tokens, num_kv_heads, head_dim], got {k
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/4e68ecc5f54abf84.
Report an issue: GitHub.