> 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%** 相比 FA2 配置（无精度损失）
* 我们修复了许多通用的 [Gemma 4 训练错误](#bug-fixes--tips) （并非源自 Unsloth）。
* Gemma 4 E2B 可在 **8GB 显存**上训练。E4B 需要 10GB 显存。

<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">错误修复 + 提示</a>

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

| [**E4B + E2B** （Studio）](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 %}
你可以在我们的以下界面中免费运行和训练 Gemma 4： [Unsloth Studio](/docs/zh/xin/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 %}

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

### :bug: 错误修复 + 提示

{% hint style="success" %}
如果你看到 **Gemma-4 E2B 和 E4B 的 loss 为 13-15，这是完全正常的** ——这是多模态模型的常见特性。这在 Gemma-3N、Llama Vision、Mistral vision 等模型上也发生过。

**Gemma 26B 和 31B 的 loss 更低，通常在 1-3 或更低。视觉任务会高 2 倍，因此约为 3-5**
{% endhint %}

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

{% 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 的 loss（比如 100 或 300），很可能是梯度累积没有被正确处理——我们已经 **在 Unsloth 和 Unsloth Studio 中修复了这个问题。**

要进一步了解梯度累积，请参阅我们的梯度累积错误修复博客： <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`-0 == 0 `layer_types[:-0]` 会退化为 `layer_types[:0] == []`。缓存会以零层槽位构建，而第一次 attention forward 就会在 `Cache.update`.

#### :no\_entry: `use_cache = True` E2B、E4B 的生成结果是乱码

[见问题](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 会变成垃圾，训练 loss 会发散。

**修复前（`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% 的推理）。否则你也可以让它完全输出。\
   \
   使用 `gemma-4` 用于非 thinking 聊天模板，使用 `gemma-4-thinking` 用于 thinking 变体。\
   较大的 26B 和 31B 建议使用 thinking 模板，小模型则使用非 thinking 模板。<br>

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

   已启用 thinking：

   <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>

   已禁用 thinking：

   ```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/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 %}

#### 监控训练进度

点击开始训练后，你将能够监控并观察模型的训练进度。训练 loss 应该会稳定下降。\
完成后，模型会自动保存。

<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)**，在 Unsloth 中是可行的，只要你禁用快速 vLLM 推理并改用 Unsloth 推理即可。请参考我们的** [**Vision 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/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, # [新功能！] 我们现在支持完整微调了！
    # 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, # 使用 GA 来模拟批大小！
        warmup_steps = 5,
        # num_train_epochs = 1, # 将此设置为 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` 方法，只在助手输出上训练，并忽略用户输入上的 loss。这有助于提高微调精度！"""

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
import 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
from unsloth import 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
from unsloth import FastVisionModel # LLM 使用 FastLanguageModel
import torch

model, processor = FastVisionModel.from_pretrained(
    "unsloth/gemma-4-26B-A4B-it",
    load_in_4bit = True, # 使用 4bit 以减少内存占用。16bit 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

dataset[2]["image"]

dataset[2]["text"]

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

from IPython.display import 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 指令聊天模板，并在我们的基础模型中使用它"""

from unsloth import 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`，它将帮助我们完成视觉微调设置。
"""

from unsloth.trainer import 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 OR object"},
        {"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 OR object"},
        {"type": "text", "text": "将以下英语语音片段转写为英文文本。只输出转写内容。"}
      ]
    },
    {
      "role": "assistant",
      "content": [
        {"type": "text", "text": "大家好，欢迎回来。"}
      ]
    }
  ]
}
```

{% endcode %}

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

你可以查看我们针对以下内容的专门推理 / 部署指南 [Unsloth Studio](/docs/zh/xin/studio/export.md), [llama.cpp](/docs/zh/ji-chu/inference-and-deployment/saving-to-gguf.md), [vLLM](/docs/zh/ji-chu/inference-and-deployment/vllm-guide.md), [llama-server](/docs/zh/ji-chu/inference-and-deployment/llama-server-and-openai-endpoint.md), [Ollama](/docs/zh/ji-chu/inference-and-deployment/saving-to-ollama.md) 或 [SGLang](/docs/zh/ji-chu/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/inference-and-deployment.md)
{% endcontent-ref %}

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

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

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

### Gemma 4 数据最佳实践

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

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

Gemma 4 使用标准的：

* `system`
* `user`
* `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.
