> For the complete documentation index, see [llms.txt](https://unsloth.ai/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unsloth.ai/docs/zh/mo-xing/gemma-4/train.md).

# Gemma 4 微调指南

你现在可以训练 Google 的 [Gemma 4](https://unsloth.ai/docs/models/gemma-4) 12B、E2B、E4B、26B-A4B 和 31B，并配合 [**Unsloth**](https://github.com/unslothai/unsloth). Unsloth 支持 Gemma 4 的所有视觉、文本、音频和 RL 微调。

* Unsloth 将 Gemma 4 的训练速度提升 **\~1.5 倍** 并且 **\~60% 更少的 VRAM** 相比 FA2 配置（无精度损失）
* 我们修复了许多通用的 [Gemma 4 训练漏洞](#bug-fixes--tips) （并非源自 Unsloth）。
* Gemma 4 E2B 可在 **8GB VRAM**上训练。E4B 需要 10GB VRAM。

<a href="/pages/33fa9e3bb3ccf6a5c0011aa600e98abbe3a829e3#quickstart" class="button primary" data-icon="bolt">快速入门</a><a href="/pages/33fa9e3bb3ccf6a5c0011aa600e98abbe3a829e3#bug-fixes--tips" class="button secondary" data-icon="sparkle">Bug 修复 + 提示</a>

微调 Gemma 4 通过我们的 **免费** **Google Colab 笔记本**:

| [ （Unsloth）](https://colab.research.google.com/github/unslothai/unsloth/blob/main/studio/Unsloth_Studio_Colab.ipynb) | [**31B** （Kaggle）](https://www.kaggle.com/code/danielhanchen/gemma4-31b-unsloth) | [E4B **（视觉 + 文本）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Vision.ipynb) | [E4B **（音频）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Audio.ipynb) | [E2B **（RL GRPO）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)_Reinforcement_Learning_Sudoku_Game.ipynb) |
| -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |

{% columns %}
{% column %}
你可以通过我们带有 UI 的 [Unsloth Studio](/docs/zh/xin-de/studio.md)✨ 笔记本：

你还可以查看更多 [笔记本](#unsloth-core-code-based-guide).
{% endcolumn %}

{% column %}
{% embed url="<https://colab.research.google.com/github/unslothai/unsloth/blob/main/studio/Unsloth_Studio_Colab.ipynb>" %}
{% endcolumn %}
{% endcolumns %}

* 你也可以使用 [强化学习](#reinforcement-learning-rl) （RL）在 9GB VRAM 上训练 Gemma 4。
* Gemma 4 E2B LoRA 可在 8-10GB VRAM 上运行。E4B LoRA 需要 17GB VRAM。
* **31B QLoRA 可在 22GB** 上运行，而 26B-A4B LoRA 需要 >40GB
* **导出**/将模型保存为 GGUF 等格式。 和 全参数微调 **（FFT）** 也同样可行。

### :bug: Bug 修复 + 提示

{% hint style="success" %}
如果你看到 **Gemma-4 E2B 和 E4B 的损失在 13-15 左右，这完全正常** ——这是多模态模型的常见特性。这种情况也出现在 Gemma-3N、Llama Vision、Mistral vision 模型等。

**Gemma 26B 和 31B 的损失更低，在 1-3 或更低。视觉部分会高 2 倍，因此为 3-5**
{% endhint %}

#### :grapes:梯度累积可能会抬高你的损失

{% columns %}
{% column %}

<div data-with-frame="true"><figure><img src="/files/9dccd2ec361315ebfc342fc7a74f7f37af9da602" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="/files/27c627eb5ef78e283ed8831a6c6b2ceff9496e34" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

如果你看到损失高于 13-15（例如 100 或 300），很可能是梯度累积没有被正确计算——我们已经 **将此修复作为 Unsloth 和 Unsloth Studio 的一部分。**

想了解更多关于梯度累积的信息，请参阅我们的梯度累积 bug 修复博客： <https://unsloth.ai/blog/gradient>

#### :interrobang:Gemma-4 31B 和 26B-A4B 推理中的 IndexError

在对 31B 和 26B 进行推理时，你可能会看到此错误：

```python
文件 "/.../cache_utils.py"，第 937 行，在 update 中
    keys, values = self.layers[layer_idx].update(...)
IndexError: 列表索引超出范围
```

元凶如下：

```python
if hasattr(decoder_config, "num_kv_shared_layers"):
    layer_types = layer_types[: -decoder_config.num_kv_shared_layers]
```

Gemma-4 31B 和 26B-A4B 随附 `num_kv_shared_layers = 0`。在 Python 中， `-0 == 0`，因此 `layer_types[:-0]` 会退化为 `layer_types[:0] == []`。缓存被构建为零个层槽位，而第一步 attention 前向就在 `Cache.update`.

#### :no\_entry: `use_cache = True` 对 E2B、E4B 来说，生成结果是一堆乱码

[参见 issue](https://github.com/huggingface/transformers/issues/45242) "\[Gemma 4] `use_cache=False` 会破坏注意力计算，生成垃圾 logits #45242"

Gemma-4 E2B 和 E4B 在层之间共享 KV 状态（`num_kv_shared_layers = 20` 和 `18`）。缓存是唯一一个早期层为后续层复用而存放 KV 的地方。当 `use_cache=False` （正如每个 QLoRA 教程都会设置的那样，并且 `gradient_checkpointing=True` 强制如此）， `Gemma4TextModel.forward` 会跳过缓存构建，因此 KV 共享层会退回到基于当前隐藏状态在本地重新计算 K 和 V。logits 会变成乱码，训练损失会发散。

**修复前（`unsloth/gemma-4-E2B-it`，提示 “1+1 是多少？”）：**

```
use_cache=True  -> '1 + 1 = **2**'
use_cache=False -> 'BROAD\\肯. Specificallyboard K supposed\\_n통  \\'
max_abs_logit_diff: 48.937500
```

**修复后：**

```
use_cache=True  -> '1 + 1 = **2**'
use_cache=False -> '1 + 1 = **2**'
max_abs_logit_diff: 0.000000     （位级完全一致，全部 9 个 token 都相同）
```

#### :radio:音频 float16 溢出

`Gemma4AudioAttention` 使用 `config.attention_invalid_logits_value = -1e9` 在一次 `masked_fill` 调用中。在 fp16（Tesla T4）上，-1e9 会溢出 fp16 的最大值 65504，导致：

```python
RuntimeError: 值无法在不发生溢出的情况下转换为类型 c10::Half
```

这是由于 `self.config.attention_invalid_logits_value` :

```python
attn_weights = attn_weights.masked_fill(
    attention_mask.logical_not(), self.config.attention_invalid_logits_value
)
```

#### 💡Gemma-4 提示

1. 如果你想要 **保留推理** 能力，你可以将推理风格示例与直接回答混合使用（至少保留 75% 的推理）。否则你可以完整输出它。\n\n使用 `gemma-4` 用于非思考型聊天模板，以及 `gemma-4-thinking` 用于思考型变体。\n对更大的 26B 和 31B 模型使用思考型，对较小的模型使用非思考型。<br>

   ```python
   from unsloth.chat_templates import get_chat_template
   tokenizer = get_chat_template(
       tokenizer,
       chat_template = "gemma-4-thinking", # 或 "gemma-4"
   )
   ```
2. 要启用思考模式，请使用 `enable_thinking = True / False` 在 `tokenizer.apply_chat_template`<br>

   已启用思考：

   <pre class="language-python" data-overflow="wrap"><code class="lang-python">processor.tokenizer.apply_chat_template([
       {\"role\" : \"user\", \"content\" : \"2+2 等于多少？\"},
   ], tokenize = False, enable_thinking = True, add_generation_prompt = True)
   </code></pre>

   将打印 `<bos><|turn>system\n<|think|><turn|>\n<|turn>user\n2+2 等于多少？<turn|>\n<|turn>model\n`<br>

   思考已禁用：

   ```python
   processor.tokenizer.apply_chat_template([
       {\"role\" : \"user\", \"content\" : \"2+2 等于多少？\"},
   ], tokenize = False, enable_thinking = False, add_generation_prompt = True)
   ```

   将打印 `<bos><|turn>user\n2+2 等于多少？<turn|>\n<|turn>model\n<|channel>thought\n<channel|>`
3. Gemma 4 支持 140 种语言，因此非常适合多语言微调。
4. 建议训练 **E4B QLoRA** 而不是 **E2B LoRA** ，因为 E4B 更大，而量化精度差异微乎其微。Gemma 4 E4B LoRA 甚至更好。
5. 微调后，你可以导出为 [GGUF](#saving-export-your-fine-tuned-model) （用于 llama.cpp/Unsloth/Ollama 等）

### ⚡快速入门

#### 🦥 Unsloth Studio 指南

{% columns %}
{% column %}
Gemma 4 可以在 [Unsloth Studio](/docs/zh/xin-de/studio.md)中运行和微调，这是我们面向本地 AI 的新开源 Web UI。

使用 Unsloth Studio，你可以在以下平台本地运行模型： **MacOS、Windows**、Linux，并训练 NVIDIA GPU。本月还将支持 Intel、MLX 和 AMD 训练。
{% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="/files/50f000d1bf4775dd4acd552c14d38600cd6e8c39" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

{% stepper %}
{% step %}

#### 安装 Unsloth

在终端中运行：

**MacOS、Linux、WSL：**

```bash
curl -fsSL https://unsloth.ai/install.sh | sh
```

**Windows PowerShell：**

```bash
irm https://unsloth.ai/install.ps1 | iex
```

{% hint style="success" %}
**安装会很快，大约需要 1-2 分钟。**
{% endhint %}
{% endstep %}

{% step %}

#### 启动 Unsloth

**MacOS、Linux、WSL 和 Windows：**

```bash
unsloth studio -H 0.0.0.0 -p 8888
```

**然后在浏览器中打开 `http://localhost:8888` 在你的浏览器中。**
{% endstep %}

{% step %}

#### 训练 Gemma 4

首次启动时，你需要创建一个密码来保护你的账户，并在之后重新登录。随后你会看到一个简短的引导向导，用于选择模型、数据集和基本设置。你可以随时跳过它。

在搜索栏中搜索 Gemma 4，并选择你想要的模型和数据集。接着，按需调整你的超参数和上下文长度。

<div data-with-frame="true"><figure><img src="/files/50f000d1bf4775dd4acd552c14d38600cd6e8c39" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### 监控训练进度

点击开始训练后，你就可以监控并观察模型的训练进度。训练损失应当稳步下降。\n完成后，模型会自动保存。

<div data-with-frame="true"><figure><img src="/files/8307e19c6d02f6c28d84f5386706c3b37f958067" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### 导出你的微调模型

完成后，Unsloth Studio 允许你将模型导出为 GGUF、safetensor 等格式。

<div data-with-frame="true"><figure><img src="/files/d1130dc8880b70d1db60cadb771bd69c69088e90" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### 比较微调后模型与原始模型

点击 `比较模式` 来比较 LoRA 适配器和原始模型。

<div data-with-frame="true"><figure><img src="/files/80d70deeeeff75ab5fc4b65e9206475c99471833" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}
{% endstepper %}

#### 🦥 Unsloth Core（基于代码）指南

我们为 Gemma 4 制作了免费的笔记本：

| [E4B **（推理 + 文本）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Text.ipynb) | [E4B **（视觉 + 文本）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Vision.ipynb) | [E4B **（音频）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Audio.ipynb) |
| ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [**31B** （Kaggle）](https://www.kaggle.com/code/danielhanchen/gemma4-31b-unsloth)                                         | [E2B **（视觉 + 文本）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)-Vision.ipynb) | [E2B **（音频）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)-Audio.ipynb) |

以及用于强化学习（RL）的： [E2B **（RL GRPO）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)_Reinforcement_Learning_Sudoku_Game.ipynb)

我们还为更大的 Gemma 4 模型制作了笔记本，但它们需要 A100：

| [Gemma-4-26B-A4B](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(26B_A4B\)-Vision.ipynb) - A100 GPU | [Gemma-4-31B](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(31B\)-Vision.ipynb) - A100 GPU |
| --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |

{% hint style="info" %}
**如果你想进行** [**GRPO**](/docs/zh/kai-shi-shi-yong/reinforcement-learning-rl-guide.md)**，只要你禁用快速 vLLM 推理并改用 Unsloth 推理，它就能在 Unsloth 中工作。请参考我们的** [**视觉 RL**](/docs/zh/kai-shi-shi-yong/reinforcement-learning-rl-guide/vision-reinforcement-learning-vlm-rl.md) **笔记本示例。**
{% endhint %}

下面是一个独立的 Gemma-4-26B-A4B-it 文本 SFT 配方。这仅适用于文本——另请查看我们的 [视觉微调](/docs/zh/ji-chu-zhi-shi/vision-fine-tuning.md) 部分以了解更多细节。

{% code expandable="true" %}

````python
from unsloth import FastModel
import torch

model, tokenizer = FastModel.from_pretrained(
    model_name = "unsloth/gemma-4-26B-A4B-it", # 将此改为 unsloth/gemma-4-E2B-it 等
    dtype = None, # 自动检测时使用 None
    max_seq_length = 8192, # 长上下文可任选！
    load_in_4bit = True,  # 使用 4 位量化以减少内存
    full_finetuning = False, # [NEW!] 我们现在支持全参数微调！
    # token = "YOUR_HF_TOKEN", # 受限模型的 HF Token
)

"""# Gemma 4 可以处理文本、视觉和音频！

让我们先体验 Gemma 4 如何处理多模态输入。我们使用 Gemma 4 推荐的设置 `temperature = 1.0, top_p = 0.95, top_k = 64`
"""

from transformers import TextStreamer
# 推理辅助函数
def do_gemma_4_inference(messages, max_new_tokens = 128):
    _ = model.generate(
        **tokenizer.apply_chat_template(
            messages,
            add_generation_prompt = True, # 生成时必须添加
            tokenize = True,
            return_dict = True,
            return_tensors = "pt",
        ).to("cuda"),
        max_new_tokens = max_new_tokens,
        use_cache=True,
        temperature = 1.0, top_p = 0.95, top_k = 64,
        streamer = TextStreamer(tokenizer, skip_prompt = True),
    )

"""# Gemma 4 可以看到图像！

<img src="https://files.worldwildlife.org/wwfcmsprod/images/Sloth_Sitting_iStock_3_12_2014/story_full_width/8l7pbjmj29_iStock_000011145477Large_mini__1_.jpg" alt="替代文本" height="256">
"""

sloth_link = "https://files.worldwildlife.org/wwfcmsprod/images/Sloth_Sitting_iStock_3_12_2014/story_full_width/8l7pbjmj29_iStock_000011145477Large_mini__1_.jpg"

messages = [{
    "role" : "user",
    "content": [
        { "type": "image", "image" : sloth_link },
        { "type": "text",  "text" : "这个动物出演过哪些电影？" }
    ]
}]
# 你可能需要等待 1 分钟让 Unsloth 的自动编译器完成
do_gemma_4_inference(messages, max_new_tokens = 256)

"""让我们给树懒写一首诗！"""

messages = [{
    "role": "user",
    "content": [{ "type" : "text",
                  "text" : "写一首关于树懒的诗。" }]
}]
do_gemma_4_inference(messages)

"""# 让我们微调 Gemma 4！

现在可以通过选择来微调视觉和文本部分——音频部分也可以微调——我们正在努力让它也能被选择！

我们现在添加 LoRA 适配器，这样只需要更新少量参数！
"""

model = FastModel.get_peft_model(
    model,
    finetune_vision_layers     = False, # 仅文本时关闭！
    finetune_language_layers   = True,  # 应保持开启！
    finetune_attention_modules = True,  # 注意力对 GRPO 有帮助
    finetune_mlp_modules       = True,  # 应始终保持开启！

    r = 8,           # 越大 = 精度越高，但可能过拟合
    lora_alpha = 8,  # 建议 alpha 至少等于 r
    lora_dropout = 0,
    bias = "none",
    random_state = 3407,
)

"""<a name="Data"></a>
### 数据准备
我们现在使用 `Gemma-4` 格式来进行对话风格微调。我们使用 [Maxime Labonne 的 FineTome-100k](https://huggingface.co/datasets/mlabonne/FineTome-100k) 数据集，采用 ShareGPT 风格。Gemma-4 会像下面这样渲染多轮对话：

```
<bos><|turn>user
你好<turn|>
<|turn>model
嗨！<turn|>
```
我们使用 `get_chat_template` 函数来获取正确的聊天模板。我们支持 `zephyr, chatml, mistral, llama, alpaca, vicuna, vicuna_old, phi3, llama3, phi4, qwen2.5, gemma3, gemma-4` 等更多模板。
"""

from unsloth.chat_templates import get_chat_template
tokenizer = get_chat_template(
    tokenizer,
    chat_template = "gemma-4-thinking",
)

"""我们获取数据集的前 3000 行"""

from datasets import load_dataset
dataset = load_dataset("mlabonne/FineTome-100k", split = "train[:3000]")

"""我们现在使用 `standardize_data_formats` 尝试将数据集转换为适合微调的正确格式！"""

from unsloth.chat_templates import standardize_data_formats
dataset = standardize_data_formats(dataset)

"""让我们看看第 100 行长什么样！"""

dataset[100]

"""我们现在必须将 `Gemma-3` 的聊天模板应用到这些对话上，并将其保存到 `text`。由于我们在做微调，所以使用 removeprefix(`'<bos>'`) 去掉 `<bos>` token。Processor 会在训练前添加这个 token，而模型只期望有一个。"""

def formatting_prompts_func(examples):
   convos = examples["conversations"]
   texts = [tokenizer.apply_chat_template(convo, tokenize = False, add_generation_prompt = False).removeprefix('<bos>') for convo in convos]
   return { "text" : texts, }

dataset = dataset.map(formatting_prompts_func, batched = True)

"""让我们看看聊天模板的效果！注意这里没有 `<bos>` token，因为 processor tokenizer 会添加一个。"""

dataset[100]["text"]

"""<a name="Train"></a>
### 训练模型
现在让我们训练模型。我们做 60 步以加快速度，但你可以设置 `num_train_epochs=1` 进行完整运行，并关闭 `max_steps=None`。
"""

from trl import SFTTrainer, SFTConfig
trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    eval_dataset = None, # 可以设置评估！
    args = SFTConfig(
        dataset_text_field = "text",
        per_device_train_batch_size = 1,
        gradient_accumulation_steps = 4, # 使用梯度累积来模拟批大小！
        warmup_steps = 5,
        # num_train_epochs = 1, # 若要完整训练一轮就设置这个。
        max_steps = 60,
        learning_rate = 2e-4, # 长训练建议降到 2e-5
        logging_steps = 1,
        optim = "adamw_8bit",
        weight_decay = 0.001,
        lr_scheduler_type = "linear",
        seed = 3407,
        report_to = "none", # 使用 TrackIO/WandB 等
    ),
)

"""我们还使用 Unsloth 的 `train_on_completions` 方法，只训练助手输出，并忽略用户输入上的损失。这有助于提高微调精度！"""

from unsloth.chat_templates import train_on_responses_only
trainer = train_on_responses_only(
    trainer,
    instruction_part = "<|turn>user\n",
    response_part = "<|turn>model\n",
)

"""让我们验证一下是否已完成对指令部分的掩码！再打印一次第 100 行。注意样本如预期那样只包含一个 `<bos>`！"""

tokenizer.decode(trainer.train_dataset[100]["input_ids"])

"""现在让我们打印被掩码的示例——你应该会看到只有答案被保留："""

tokenizer.decode([tokenizer.pad_token_id if x == -100 else x for x in trainer.train_dataset[100]["labels"]]).replace(tokenizer.pad_token, " ")

"""# 让我们训练模型！

若要恢复训练，设置 `trainer.train(resume_from_checkpoint = True)`
"""

trainer_stats = trainer.train()
````

{% endcode %}

{% hint style="info" %}
如果你遇到 OOM：

* 降低 `per_device_train_batch_size` 改为 **1** 和/或减少 `max_seq_length`.&#x20;
* 保持 `use_`[`gradient_checkpointing`](/docs/zh/bo-ke/500k-context-length-fine-tuning.md#unsloth-gradient-checkpointing-enhancements)`="unsloth"` 开启（它旨在减少 VRAM 使用并延长上下文长度）。
  {% endhint %}

**MoE（bf16 LoRA）加载器示例：**

```python
导入 os
import torch
from unsloth import FastModel

model, tokenizer = FastModel.from_pretrained(
    model_name = "unsloth/Gemma-4-26B-A4B-it",
    max_seq_length = 2048,
    load_in_4bit = False,     # 不建议对 MoE 使用 QLoRA，稠密 31B 没问题
    load_in_16bit = True,     # bf16/16 位 LoRA
    full_finetuning = False,
)
```

加载完成后，您将添加 LoRA 适配器，并以与上面的 SFT 示例类似的方式进行训练。

### 强化学习（RL）

现在，您可以使用以下内容通过 RL、GSPO、GRPO 等训练 Gemma 4： [我们的免费笔记本](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_5_\(4B\)_Vision_GRPO.ipynb).

{% columns %}
{% column %}
Gemma 4 E2B RL 可在 9GB 显存上运行。

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_5_(4B)_Vision_GRPO.ipynb>" %}

该笔记本的目标是让 Gemma 4 学会使用以下内容解决数独谜题： [GRPO](/docs/zh/kai-shi-shi-yong/reinforcement-learning-rl-guide.md#from-rlhf-ppo-to-grpo-and-rlvr).

模型将设计一种填充空白单元格的策略，我们会根据正确填入数字和完成有效谜题来给予奖励。

即使 vLLM 不支持它，您仍可通过设置以下选项，使用 Unsloth 运行 Gemma 4 RL： `fast_inference=False` 加载模型时：
{% endcolumn %}

{% column %}

<figure><img src="/files/7d4bccab277c9bcd1776a34163650b1598f908ef" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

```python
从 unsloth 导入 FastLanguageModel

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="unsloth/gemma-4-E2B-it",
    fast_inference=False,
)
```

### MoE 微调（26B-A4B）

该 **26B-A4B** 模型在 Gemma 4 系列中兼顾速度与质量。由于它是一个 **MoE** 模型，每个 token 仅激活部分参数，因此建议采用保守的微调方法：

* 使用 **LoRA** 而非全量微调
* 优先选择 **16 位 / bf16 LoRA** 如果内存允许
* 先从较短的上下文和较小的秩开始
* 仅在流水线稳定后再进行扩展

如果您的目标是获得最高质量，并且拥有更多内存，请使用 **31B** 来替代。

### 多模态微调（E2B / E4B）

由于 **E2B** 和 **E4B** 支持 **图像** 和 **音频**，它们是用于多模态微调的主要 Gemma 4 变体。

* 使用以下内容加载多模态模型： `FastVisionModel`
* 保持 `finetune_vision_layers = False` 优先
* 仅微调语言、注意力和 MLP 层
* 如果任务需要，稍后再启用视觉或音频层

#### Gemma 4 多模态 LoRA 示例：

{% code expandable="true" %}

````python
从 unsloth 导入 FastVisionModel # 用于 LLM 的 FastLanguageModel
import torch

model, processor = FastVisionModel.from_pretrained(
    "unsloth/gemma-4-26B-A4B-it",
    load_in_4bit = True, # 使用 4 位以减少内存占用。16 位 LoRA 则设为 False。
    use_gradient_checkpointing = "unsloth", # 对于长上下文，使用 True 或 "unsloth"
)

"""现在我们为参数高效微调添加 LoRA 适配器，从而能够高效地仅训练全部模型参数中的 1%。

**[新增]** 我们还支持仅微调视觉组件、仅微调语言组件，或同时微调两者。此外，您可以选择微调注意力模块、MLP 层，或两者兼顾！
"""

model = FastVisionModel.get_peft_model(
    model,
    finetune_vision_layers     = True, # 如果不微调视觉层则设为 False
    finetune_language_layers   = True, # 如果不微调语言层则设为 False
    finetune_attention_modules = True, # 如果不微调注意力层则设为 False
    finetune_mlp_modules       = True, # 如果不微调 MLP 层则设为 False

    r = 32,                           # 越大准确率越高，但可能会过拟合
    lora_alpha = 32,                  # 建议 alpha 至少等于 r
    lora_dropout = 0,
    bias = "none",
    random_state = 3407,
    use_rslora = False,               # 我们支持秩稳定化 LoRA
    loftq_config = None,               # 以及 LoftQ
    target_modules = "all-linear",    # 现为可选！如有需要可指定列表
)

"""<a name="Data"></a>
### 数据准备
我们将使用一个手写数学公式的采样数据集。目标是将这些图像转换为计算机可读的格式——具体而言是 LaTeX——以便进行渲染。这对于复杂表达式尤其有用。

您可在[此处](https://huggingface.co/datasets/unsloth/LaTeX_OCR)访问该数据集。完整数据集在[此处](https://huggingface.co/datasets/linxy/LaTeX_OCR)。
"""

from datasets import load_dataset
dataset = load_dataset("unsloth/LaTeX_OCR", split = "train")

"""让我们概览一下数据集。我们将查看第二张图像及其对应的说明文字。"""

数据集

dataset[2]["image"]

dataset[2]["text"]

"""我们还可以直接在浏览器中渲染 LaTeX！"""

从 IPython.display 导入 display、Math、Latex

latex = dataset[3]["text"]
display(Math(latex))

"""为格式化数据集，所有视觉微调任务都应遵循以下格式：

```python
[
    {
        "role": "user",
        "content": [
            {"type": "text", "text": instruction},
            {"type": "image", "image": sample["image"]},
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "text", "text": instruction},
            {"type": "image", "image": sample["image"]},
        ],
    },
]
```
"""

instruction = "为此图像编写 LaTeX 表示。"

def convert_to_conversation(sample):
    conversation = [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": instruction},
                {"type": "image", "image": sample["image"]},
            ],
        },
        {"role": "assistant", "content": [{"type": "text", "text": sample["text"]}]},
    ]
    return {"messages": conversation}
pass

"""让我们将数据集转换为适用于微调的“正确”格式："""

converted_dataset = [convert_to_conversation(sample) for sample in dataset]

"""现在，第一个示例如下所示："""

converted_dataset[0]

"""让我们获取 Gemma 4 指令聊天模板，并将其用于基础模型"""

从 unsloth 导入 get_chat_template

processor = get_chat_template(
    processor,
    "gemma-4-thinking"
)

"""微调前，让我们评估基础模型的性能。由于它此前未接触过此聊天模板，我们不期待很好的结果。"""

image = dataset[2]["image"]
instruction = "为此图像编写 LaTeX 表示。"

messages = [
    {
        "role": "user",
        "content": [{"type": "image"}, {"type": "text", "text": instruction}],
    }
]
input_text = processor.apply_chat_template(messages, add_generation_prompt = True)
inputs = processor(
    image,
    input_text,
    add_special_tokens = False,
    return_tensors = "pt",
).to("cuda")

from transformers import TextStreamer

text_streamer = TextStreamer(processor, skip_prompt = True)
result = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 128,
                        use_cache = True, temperature = 1.0, top_p = 0.95, top_k = 64)

"""可以看到，它糟糕透顶！它完全不遵循指令

<a name="Train"></a>
### 训练模型
现在让我们训练模型。为加快速度，我们执行 60 步；但您可以将 `num_train_epochs=1` 用于完整运行，并关闭 `max_steps=None`。我们也支持用于强化学习的 `DPOTrainer` 和 `GRPOTrainer`！！

我们使用新的 `UnslothVisionDataCollator`，它将帮助我们进行视觉微调设置。
"""

从 unsloth.trainer 导入 UnslothVisionDataCollator
from trl import SFTTrainer, SFTConfig

trainer = SFTTrainer(
    model = model,
    train_dataset = converted_dataset,
    processing_class = processor.tokenizer,
    data_collator = UnslothVisionDataCollator(model, processor),
    args = SFTConfig(
        per_device_train_batch_size = 1,
        gradient_accumulation_steps = 4,
        max_grad_norm = 0.3,
        warmup_ratio = 0.03,
        max_steps = 60,
        # num_train_epochs = 2, # 完整训练运行时请设置此项，而非 max_steps
        learning_rate = 2e-4,
        logging_steps = 1,
        save_strategy = "steps",
        optim = "adamw_8bit",
        weight_decay = 0.001,
        lr_scheduler_type = "cosine",
        seed = 3407,
        output_dir = "outputs",
        report_to = "none", # 用于 Weights and Biases 或其他服务

        # 视觉微调时必须加入以下项目：
        remove_unused_columns = False,
        dataset_text_field = "",
        dataset_kwargs = {"skip_prepare_dataset": True},
        max_length = 2048,
    )
)

trainer_stats = trainer.train()
````

{% endcode %}

#### 图像示例格式

请记住：对于 Gemma 4 多模态提示，请将图像放在 **之前** 文本指令。

{% code expandable="true" %}

```json
{
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "image", "image": "/path/to/image 或对象"},
        {"type": "text", "text": "提取此收据中的所有文本。以 JSON 格式返回行项目、总额、商家和日期。"}
      ]
    },
    {
      "role": "assistant",
      "content": [
        {"type": "text", "text": "{\"merchant\": \"示例商店\", \"total\": \"19.99\"}"}
      ]
    }
  ]
}
```

{% endcode %}

#### 音频示例格式

音频仅适用于 **E2B / E4B** 。请保持音频片段简短且针对具体任务。

{% code expandable="true" %}

```json
{
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "audio", "audio": "/path/to/audio 或对象"},
        {"type": "text", "text": "将以下英语语音片段转录为英文文本。仅输出转录内容。"}
      ]
    },
    {
      "role": "assistant",
      "content": [
        {"type": "text", "text": "大家好，欢迎回来。"}
      ]
    }
  ]
}
```

{% endcode %}

### 保存 / 导出微调后的模型

您可以查看我们针对以下内容的推理 / 部署指南： [Unsloth Studio](/docs/zh/xin-de/studio/export.md), [llama.cpp](/docs/zh/ji-chu-zhi-shi/inference-and-deployment/saving-to-gguf.md), [vLLM](/docs/zh/ji-chu-zhi-shi/inference-and-deployment/vllm-guide.md), [llama-server](/docs/zh/ji-chu-zhi-shi/inference-and-deployment/llama-server-and-openai-endpoint.md), [Ollama](/docs/zh/ji-chu-zhi-shi/inference-and-deployment/saving-to-ollama.md) 或 [SGLang](/docs/zh/ji-chu-zhi-shi/inference-and-deployment/sglang-guide.md).

#### 保存为 GGUF

Unsloth 支持直接保存为 GGUF：

```python
model.save_pretrained_gguf("directory", tokenizer, quantization_method = "q4_k_m")
model.save_pretrained_gguf("directory", tokenizer, quantization_method = "q8_0")
model.save_pretrained_gguf("directory", tokenizer, quantization_method = "f16")
```

或者将 GGUF 推送到 Hugging Face：

```python
model.push_to_hub_gguf("hf_username/directory", tokenizer, quantization_method = "q4_k_m")
model.push_to_hub_gguf("hf_username/directory", tokenizer, quantization_method = "q8_0")
```

如果导出的模型在其他运行时中表现较差，Unsloth 会指出最常见的原因： **推理时使用了错误的聊天模板 / EOS token** （您必须使用与训练时相同的聊天模板）。

有关更多详情，请阅读我们的推理指南：

{% columns %}
{% column width="50%" %}
{% content-ref url="/pages/9a72670992feb75def412a693565c84a88c8a266" %}
[推理与部署](/docs/zh/ji-chu-zhi-shi/inference-and-deployment.md)
{% endcontent-ref %}

{% content-ref url="/pages/b83d88f106d75c3396c46f5342fb401501910093" %}
[GGUF & llama.cpp](/docs/zh/ji-chu-zhi-shi/inference-and-deployment/saving-to-gguf.md)
{% endcontent-ref %}
{% endcolumn %}

{% column width="50%" %}
{% content-ref url="/pages/f7c3389bdba9af3050e66a941596d827cdb11e0b" %}
[Model Export](/docs/zh/xin-de/studio/export.md)
{% endcontent-ref %}

{% content-ref url="/pages/9f0e22d200c9105481e4854b8473aba99ca44835" %}
[vLLM](/docs/zh/ji-chu-zhi-shi/inference-and-deployment/vllm-guide.md)
{% endcontent-ref %}
{% endcolumn %}
{% endcolumns %}

### Gemma 4 数据最佳实践

Gemma 4 有一些格式细节需要牢记。

#### 1. 使用标准聊天角色

Gemma 4 使用标准的：

* `系统`
* `用户`
* `assistant`

这意味着您的 SFT 数据集应使用常规聊天格式编写，而不是旧版 Gemma 专用角色格式。

#### 2. 思考模式是显式的

如果您想在 SFT 期间保留思考风格的行为：

* 保持格式一致
* 决定是否要针对以下内容进行训练： **可见的思考块** 或 **仅最终答案**
* 务必 **不要** 在同一数据集中混合多种不兼容的思考格式

对于大多数生产环境助手，最简单的设置是在以下内容上进行微调： **仅最终可见答案**.

#### 3. 多轮规则

对于多轮对话，仅保留 **最终可见答案** 在对话历史中。不要 **不要** 将先前的思考块反馈到后续轮次中。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://unsloth.ai/docs/zh/mo-xing/gemma-4/train.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
