hiyouga/LlamaFactory · error · RuntimeError

LigerKernel requires CUDA or NPU, current accelerator is {cu

Error message

LigerKernel requires CUDA or NPU, current accelerator is {current}.

What it means

LigerKernel.check_device() gates the kernel to CUDA or NPU accelerators. On any other accelerator (CPU, XPU, MLP, HPU, MPS) it raises RuntimeError naming the current device type, before any patching is attempted.

Source

Thrown at src/llamafactory/v1/plugins/model_plugins/kernels/liger_kernel_ops.py:52

    "qwen3": "apply_liger_kernel_to_qwen3",
    "qwen3_moe": "apply_liger_kernel_to_qwen3_moe",
    "qwen3_next": "apply_liger_kernel_to_qwen3_next",
    "qwen3_5": "apply_liger_kernel_to_qwen3_5",
    "qwen3_5_text": "apply_liger_kernel_to_qwen3_5_text",
    "qwen3_5_moe": "apply_liger_kernel_to_qwen3_5_moe",
    "qwen3_5_moe_text": "apply_liger_kernel_to_qwen3_5_moe_text",
}


@KernelPlugin("liger_kernel").register()
class LigerKernel(BaseKernel):
    """Liger Kernel for optimized model training."""

    @staticmethod
    def check_device() -> None:
        current = get_current_accelerator().type
        if current not in (DeviceType.CUDA, DeviceType.NPU):
            raise RuntimeError(f"LigerKernel requires CUDA or NPU, current accelerator is {current}.")

    @staticmethod
    def check_deps() -> None:
        """Checks if the required dependencies for the kernel are available."""
        try:
            import liger_kernel  # noqa: F401
        except ImportError:
            raise RuntimeError("Liger kernel is not installed.") from None

    @staticmethod
    def _apply(**kwargs) -> "HFModel":
        """Applies the Liger kernel to the model.

        Args:
            **kwargs: Must include ``model``. Optional ``use_kernels`` is a list of Liger op
                names to enable exclusively, or the string ``"auto"`` to use each
                ``apply_liger_kernel_to_*`` function's signature defaults (same as calling
                upstream with only ``model``). Optional ``require_logits`` forces non-fused

View on GitHub (pinned to f28afaf635)

Solutions

  1. Run on a CUDA (or NPU) machine — Liger kernels are GPU-only.
  2. Remove liger_kernel from kernel_config.name for CPU runs, or make the config conditional per environment.
  3. Use "auto" kernel selection: _apply_auto_kernels picks kernels per device_type, skipping Liger on CPU.
  4. For NPU, ensure torch_npu is installed and initialized so the accelerator type is detected as NPU.

Example fix

# before (shared config)
kernel_config:
  name: "liger_kernel"   # fails on CPU CI

# after
kernel_config:
  name: "auto"           # auto selects only device-appropriate kernels
Defensive patterns

Strategy: validation

Validate before calling

from llamafactory.v1.core.accelerator import get_current_accelerator
assert get_current_accelerator().type in ('cuda', 'npu'), f'Liger needs CUDA/NPU, got {get_current_accelerator().type}'

Type guard

def liger_supported() -> bool:
    """True when the current accelerator is CUDA or NPU."""
    return get_current_accelerator().type in (DeviceType.CUDA, DeviceType.NPU)

Try / catch

try:
    model = KernelPlugin('liger_kernel').apply(model=model)
except RuntimeError as e:
    if 'requires CUDA or NPU' in str(e):
        logger.warning('skipping liger on %s', get_current_accelerator().type)
    else:
        raise

Prevention

When it happens

Trigger: kernel_config.name includes 'liger_kernel' while get_current_accelerator().type resolves to CPU (e.g. quick CPU smoke test), Apple Silicon MPS, or Intel XPU.

Common situations: Running the same training YAML on a laptop/CI CPU runner that worked on an A100; NPU images without correct torch_npu setup so the accelerator falls back to CPU; enabling kernels globally in shared configs.

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/827b27fd493ff562. Report an issue: GitHub.