"""Liger Kernel — fused operations for faster, memory-efficient training. Liger Kernel provides fused CUDA kernels (RMSNorm, SwiGLU, CrossEntropy, RoPE, etc.) that replace standard HuggingFace operations with optimized fused versions. This can yield 20-60% memory savings and 20-40% throughput improvement. Requires: liger-kernel >= 0.3.0 """ from __future__ import annotations def check_liger_available() -> bool: """Check if liger-kernel is installed.""" try: import liger_kernel # noqa: F401 return True except ImportError: return False def get_liger_version() -> str | None: """Return liger-kernel version string, or None if not installed.""" try: import liger_kernel return getattr(liger_kernel, "__version__", "unknown") except ImportError: return None def apply_liger_kernel(model_name: str) -> bool: """Apply Liger Kernel fused operations for the given model architecture. Patches the model class in-place so that all subsequent model instantiations use fused kernels (RMSNorm, SwiGLU, CrossEntropy, RoPE, FusedLinearCrossEntropy). This must be called BEFORE loading the model. Args: model_name: HuggingFace model name/path (used to detect architecture). Returns: True if Liger Kernel was applied, False otherwise. """ if not check_liger_available(): return False model_lower = model_name.lower() try: from liger_kernel.transformers import ( AutoLigerKernelForCausalLM, ) # AutoLigerKernelForCausalLM handles architecture detection automatically AutoLigerKernelForCausalLM._apply_liger_kernel(model_name) return True except (ImportError, AttributeError, NotImplementedError): # Fallback: try manual patching for known architectures return _apply_liger_manual(model_lower) def _apply_liger_manual(model_lower: str) -> bool: """Manually apply Liger Kernel patches for known model architectures.""" try: if "llama" in model_lower or "codellama" in model_lower: from liger_kernel.transformers import apply_liger_kernel_to_llama apply_liger_kernel_to_llama() return True elif "mistral" in model_lower or "mixtral" in model_lower: from liger_kernel.transformers import apply_liger_kernel_to_mistral apply_liger_kernel_to_mistral() return True elif "gemma" in model_lower: from liger_kernel.transformers import apply_liger_kernel_to_gemma2 apply_liger_kernel_to_gemma2() return True elif "qwen" in model_lower: from liger_kernel.transformers import apply_liger_kernel_to_qwen2 apply_liger_kernel_to_qwen2() return True elif "phi" in model_lower: from liger_kernel.transformers import apply_liger_kernel_to_phi3 apply_liger_kernel_to_phi3() return True except (ImportError, AttributeError): pass return False def validate_liger_config(use_liger: bool, backend: str, device: str) -> list[str]: """Validate Liger Kernel configuration and return error messages. Args: use_liger: Whether Liger Kernel is requested. backend: Training backend (transformers/unsloth). device: Training device (cuda/cpu/mps). Returns: List of error messages. Empty list means valid. """ errors: list[str] = [] if not use_liger: return errors if not check_liger_available(): errors.append( "liger-kernel is not installed. " "Install it with: pip install 'soup-cli[liger]'" ) if backend == "unsloth": errors.append( "Liger Kernel is not compatible with the unsloth backend. " "Unsloth has its own fused kernels. Use backend: transformers." ) if device != "cuda": errors.append( "Liger Kernel requires CUDA. " f"Current device: {device}. Use a GPU for Liger Kernel." ) return errors