Chapter 04

核心概念:FastLanguageModel 与 patcher

📌 commit 1cf145c070ea "看不见的加速"是怎么实现的

Unsloth 的全部"魔法",本质上是monkey patch + Triton kernel 替换。 本章把 FastLanguageModel 这一个公开 API 背后发生的事拆开: 哪些函数被替换、什么时候发生、为什么这种设计能"对用户透明"。

4.1三件套:FastLanguageModel / FastVisionModel / Fast*Model

Unsloth 对外的核心 API 是几个 Fast*Model 类:

用途所在文件
FastLanguageModel LLM 微调(最常用) unsloth/models/loader.py
FastVisionModel VLM 微调 unsloth/models/vision.py
FastTextToSpeechModel TTS 微调
SentenceTransformerModel Embedding 模型 unsloth/models/sentence_transformer.py
FastMLXModel Apple Silicon (MLX) unsloth_zoo.mlx.loader

本章主要讲 FastLanguageModel,其他几个原理类似。

4.2FastLanguageModel.from_pretrained 做了什么

flowchart TB Call["FastLanguageModel.from_pretrained('unsloth/llama-3-8b-bnb-4bit', ...)"] Call --> Step1["1. 识别模型架构
llama / mistral / qwen / gemma / ..."] Step1 --> Step2["2. 加载预量化 base model
(若 model_name 是 *-bnb-4bit)"] Step2 --> Step3["3. monkey-patch 关键函数:
· LlamaAttention.forward
· LlamaMLP.forward
· LlamaRMSNorm.forward
· rotary_emb
· cross_entropy"] Step3 --> Step4["4. 把 nn.Linear 替换为
Unsloth fast_lora.Linear"] Step4 --> Step5["5. 设 tokenizer 的 padding_side='right'
等小修小补"] Step5 --> Return["返回 (model, tokenizer)"]

对调用者完全透明 —— 你拿到的还是一个普通 HF PreTrainedModel,可以接 TRL SFTTrainer、可以 model.generate()。 但内部所有 forward 调用都已经走 Triton kernel。

4.3哪些函数被 patch 了

unsloth/models/llama.py,能列出所有 patch 点:

原 HuggingFace 函数替换成 Unsloth 实现所在文件
LlamaAttention.forward fused attention + flash-attn 接入 unsloth/models/llama.py
LlamaMLP.forward fused SwiGLU unsloth/kernels/swiglu.py
LlamaRMSNorm.forward Triton fused RMSNorm unsloth/kernels/rms_layernorm.py
LlamaRotaryEmbedding.forward Triton fused RoPE unsloth/kernels/rope_embedding.py
CrossEntropyLoss chunked + fused cross entropy unsloth/kernels/cross_entropy_loss.py
peft.LoraLayer 的 forward / backward fused LoRA (Triton) unsloth/kernels/fast_lora.py
torch.utils.checkpoint.checkpoint "unsloth" 模式(更省显存) unsloth/models/_utils.py
Gemma / Phi-4 / GPT-OSS 等架构 各自的 unsloth/models/gemma.py 架构特定 patch

4.4patcher 的实现风格

unsloth/models/llama.pyFastLlamaModel.pre_patch() 大致结构:

class FastLlamaModel:
    @staticmethod
    def pre_patch():
        # 1. 把 LlamaAttention.forward 替换为自家实现
        from transformers.models.llama.modeling_llama import LlamaAttention
        LlamaAttention.forward = unsloth_attention_forward

        # 2. 把 RMSNorm 替换
        from transformers.models.llama.modeling_llama import LlamaRMSNorm
        LlamaRMSNorm.forward = unsloth_rms_forward

        # 3. 把 RoPE 替换
        ...

        # 4. 把 cross entropy 替换
        import transformers
        transformers.modeling_utils.cross_entropy_loss = unsloth_cross_entropy

        # 5. 修正一些 bug(gpt-oss, phi-4, qwen3 等)
        ...

这种替换类的方法,是 Python 动态语言的能力 —— 任何 import 之后的代码看到的都是被替换后的版本。不用改 transformers 源码

4.5为什么 patch 优于 fork transformers

方案优点缺点
Fork transformers(如 ColossalAI 部分模块) 实现自由 跟不上 HF 更新;用户要装定制版
Monkey patch(Unsloth) 不改 HF 源码;用户 pip install 就用 对 HF 版本极敏感(HF 升级会破坏 patch)
自家从头写模型(如 Megatron-LM) 完全可控 每加一种新架构要写一份

Unsloth 选 patch 路线 ≈ "对 HF 用户最友好 + 对 Unsloth 团队最痛苦" 的组合。每次 transformers 大版本更新都会破坏 patch,Unsloth 团队要紧跟修。

4.6FastLanguageModel.get_peft_model

第二步:加 LoRA。Unsloth 的 PEFT 接入是套 peft.get_peft_model 再 patch LoraLayer

def get_peft_model(model, r, target_modules, lora_alpha, ...):
    # 1. 先调 peft 标准 API
    from peft import LoraConfig, get_peft_model as peft_get_peft_model
    lora_cfg = LoraConfig(r=r, lora_alpha=lora_alpha, target_modules=target_modules, ...)
    model = peft_get_peft_model(model, lora_cfg)

    # 2. 把所有 peft 的 LoraLayer 替换为 unsloth fast_lora
    apply_fast_lora_patches(model)

    # 3. 处理 use_gradient_checkpointing = "unsloth" 这种特殊值
    if use_gradient_checkpointing == "unsloth":
        model = patch_unsloth_gradient_checkpointing(model)

    return model

4.7FastLanguageModel.for_inference 与 for_training

训练和推理模式的差异:

方法做什么
FastLanguageModel.for_inference(model) 开 eval 模式;禁 dropout;优化 KV cache;用更激进的 inference kernel
FastLanguageModel.for_training(model) 切回训练模式;开 dropout;用支持 backward 的 kernel

训练完跑 chat / 推理时必须切到 for_inference,否则会用训练 kernel 跑推理(慢 5 倍 + 浪费显存)。

4.8模型注册与扩展

unsloth/registry/ 维护了 Unsloth 支持的模型注册表。新加一种模型架构通常要:

  1. unsloth/models/ 新增一个文件(如 my_arch.py),写 FastMyArchModel.pre_patch()
  2. unsloth/registry/ 里注册 model_type → class 映射;
  3. unsloth/models/mapper.py 加 HF 模型名 → Unsloth 预量化版的映射。

当前已支持的架构(看 unsloth/models/):Llama 系(含 Llama-4)、Mistral、Mixtral、Qwen2/3、Qwen3-MoE、Gemma 1-3、Phi-3/4、Cohere(Command-R)、Falcon-H1、Granite、GLM4-MoE。 新架构通常发布几天内 Unsloth 团队会加上。

4.9tokenizer 也被 patch 了

除了模型,Unsloth 还会动 tokenizer:

4.10"看不见的加速"心智模型

一句话总结

用户写的代码看上去是 HF + PEFT + TRL, 但因为模型是用 FastLanguageModel.from_pretrained 起的, 内部所有 forward / backward / LoRA / norm / RoPE / cross-entropy 都已经被替换成 Triton 实现。

这意味着:

4.11查看哪些 patch 被应用

启动训练时 Unsloth 会打印一份"patcher report":

==((====))==  Unsloth 2026.5.4: Fast Llama patching.
   \\   /|    Transformers: 4.46.2. ★ patched
O^O/ \_/ \    SDPA = True (Flash-Attn 2)
\        /    RMSNorm = TRITON (fused)
 "-____-"     RoPE = TRITON (fused)
              CrossEntropy = TRITON (chunked)
              LoRA = TRITON (fused)
              Gradient Checkpointing = UNSLOTH (extra savings)

看到 = TRITON 说明 patch 生效;看到 = PYTORCH= DISABLED 说明回退到原版 —— 那就 grep stderr 看为什么 fallback。

4.12FastLanguageModel 源码定位

符号位置
FastLanguageModel.from_pretrained unsloth/models/loader.py:243
三条 dispatch 路(4bit / 8bit / full) loader.py:329-363
get_peft_model(Llama) models/llama.py:2833
get_peft_model(Vision) models/vision.py:1340
FastVisionModel models/vision.py(73KB)
FastModel(2026 统一入口) models/loader.py
FastSentenceTransformer models/sentence_transformer.py(98KB)
UnslothTrainer unsloth/trainer.py

4.132026 支持的模型家族

家族模型文件
Llama / Llama 3.x / Llama 4 models/llama.py(149KB)
Mistral / Ministral / Nemo models/mistral.py(含 patch_mistral_nemo_attention line 416)
Qwen2 / Qwen3 / Qwen3-MoE models/qwen2.py / qwen3.py / qwen3_moe.py
Gemma 1 / Gemma 2 models/gemma.py / gemma2.py
Granite / Granite-VL models/granite.py(line 135 VL 路径)
Cohere / Falcon H1 models/cohere.py / falcon_h1.py
Vision(Llama 3.2 Vision / Qwen2-VL / Llava)models/vision.py
RL(GRPO / DPO / ORPO / KTO) models/rl.py(98KB)
Embeddings models/sentence_transformer.py

4.14这章带走的