# Gemma 3n：如何运行与微调

Google 的 Gemma 3n 多模态模型处理图像、音频、视频和文本输入。提供 2B 和 4B 两种规模，支持 140 种语言的文本和多模态任务。您现在可以使用 本地 运行和微调 **Gemma-3n-E4B** 以及 **E2B** 在本地使用 运行 [Unsloth](https://github.com/unslothai/unsloth).

> **使用我们的 微调 Gemma 3n** [**免费 Colab 笔记本**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3N_\(4B\)-Conversational.ipynb)

Gemma 3n 具有 **32K 上下文长度**、30 秒音频输入、OCR、自动语音识别 (ASR) 和通过提示的语音翻译。

<a href="#running-gemma-3n" class="button primary">运行教程</a><a href="#fine-tuning-gemma-3n-with-unsloth" class="button secondary">微调教程</a><a href="#fixes-for-gemma-3n" class="button secondary">修复 + 技术分析</a>

**Unsloth Gemma 3n（Instruct）以上最佳配置上传：**

<table><thead><tr><th width="249">动态 2.0 GGUF（仅文本）</th><th width="285">动态 4-bit 指令（用于微调）</th><th>16-bit 指令</th></tr></thead><tbody><tr><td><ul><li><a href="https://huggingface.co/unsloth/gemma-3n-E2B-it-GGUF">2B</a></li><li><a href="https://huggingface.co/unsloth/gemma-3n-E4B-it-GGUF">4B</a></li></ul></td><td><ul><li><a href="https://huggingface.co/unsloth/gemma-3n-E2B-it-unsloth-bnb-4bit">2B</a></li><li><a href="https://huggingface.co/unsloth/gemma-3n-E4B-it-unsloth-bnb-4bit">4B</a></li></ul></td><td><ul><li><a href="https://huggingface.co/unsloth/gemma-3n-E2B-it">2B</a></li><li><a href="https://huggingface.co/unsloth/gemma-3n-E4B-it">4B</a></li></ul></td></tr></tbody></table>

**在 我们的合集 中查看我们所有的 Gemma 3n 上传，包括基础模型和更多格式，** [**在这里的集合**](https://huggingface.co/collections/unsloth/gemma-3n-685d3874830e49e1c93f9339)**.**

## 🖥️ 运行 Gemma 3n

当前 Gemma 3n 仅 在 推理中支持 **文本格式** 。

{% hint style="info" %}
我们已 [修复问题](#fixes-for-gemma-3n) 仅在 Ollama 中 GGUF 无法正常工作。若使用 Ollama 请重新下载。
{% endhint %}

### :gear: 官方推荐设置

根据 Gemma 团队，推理的官方推荐设置：

`temperature = 1.0, top_k = 64, top_p = 0.95, min_p = 0.0`

* Temperature 为 1.0
* Top\_K 为 64
* Min\_P 为 0.00（可选，但 0.01 表现良好，llama.cpp 默认是 0.1）
* Top\_P 为 0.95
* 重复惩罚（Repetition Penalty）为 1.0。（在 llama.cpp 和 transformers 中 1.0 表示禁用）
* 聊天模板：

  <pre data-overflow="wrap"><code><strong>&#x3C;bos>&#x3C;start_of_turn>user\nHello!&#x3C;end_of_turn>\n&#x3C;start_of_turn>model\nHey there!&#x3C;end_of_turn>\n&#x3C;start_of_turn>user\nWhat is 1+1?&#x3C;end_of_turn>\n&#x3C;start_of_turn>model\n
  </strong></code></pre>
* 带有 下列的聊天模板 `\n`呈现换行（除最后一行外）

{% code overflow="wrap" %}

```
<bos><start_of_turn>user
Hello!<end_of_turn>
<start_of_turn>model
Hey there!<end_of_turn>
<start_of_turn>user
What is 1+1?<end_of_turn>
<start_of_turn>model\n
```

{% endcode %}

{% hint style="danger" %}
llama.cpp 和其他推理引擎会自动添加一个 \<bos> - 切勿添加 两个 \<bos> 标记！在向模型提示时应忽略 \<bos>！
{% endhint %}

### :llama: 教程：如何在 Ollama 中运行 Gemma 3n

{% hint style="success" %}
请重新下载 Gemma 3N 量化文件或通过 Ollama 删除旧文件，因为有一些错误修复。您可以按下面操作删除旧文件并刷新：

```
ollama rm hf.co/unsloth/gemma-3n-E4B-it-GGUF:UD-Q4_K_XL

ollama run hf.co/unsloth/gemma-3n-E4B-it-GGUF:UD-Q4_K_XL
```

{% endhint %}

1. 安装 `ollama` 如果您尚未安装！

```bash
apt-get update
apt-get install pciutils -y
curl -fsSL https://ollama.com/install.sh | sh
```

2. 运行模型！注意如果失败您可以在另一个终端调用 `ollama serve`！我们在 我们的 Hugging Face 上传 中包含了所有修复和建议的参数（例如 temperature 等）！ `params` 在我们的 Hugging Face 上传 中！

```bash
ollama run hf.co/unsloth/gemma-3n-E4B-it-GGUF:UD-Q4_K_XL
```

### 📖 教程：如何在 llama.cpp 中运行 Gemma 3n

{% hint style="info" %}
我们首先要感谢 [Xuan-Son Nguyen](https://x.com/ngxson) 来自 Hugging Face， [Georgi Gerganov](https://x.com/ggerganov) 来自 llama.cpp 团队，使 Gemma 3N 在 llama.cpp 中工作！
{% endhint %}

1. 获取最新的 `llama.cpp` 在 [GitHub 在此处](https://github.com/ggml-org/llama.cpp)。您也可以按照下面的构建说明。将 `-DGGML_CUDA=ON` 更改为 `-DGGML_CUDA=OFF` 如果您没有 GPU 或只想进行 CPU 推理。 **对于 Apple Mac / Metal 设备**，设置 `-DGGML_CUDA=OFF` 然后照常继续 - 默认启用 Metal 支持。

```bash
apt-get update
apt-get install pciutils build-essential cmake curl libcurl4-openssl-dev -y
git clone https://github.com/ggml-org/llama.cpp
cmake llama.cpp -B llama.cpp/build \
    -DBUILD_SHARED_LIBS=ON -DGGML_CUDA=ON -DLLAMA_CURL=ON
cmake --build llama.cpp/build --config Release -j --clean-first --target llama-quantize llama-cli llama-gguf-split llama-mtmd-cli
cp llama.cpp/build/bin/llama-* llama.cpp
```

2. 如果您想 直接 使用 `llama.cpp` 来加载模型，您可以如下操作：（:Q4\_K\_XL）是量化类型。您也可以通过 Hugging Face 下载（见第 3 点）。这与 `ollama run`

```bash
./llama.cpp/llama-cli -hf unsloth/gemma-3n-E4B-it-GGUF:UD-Q4_K_XL -ngl 99 --jinja
```

3. **或** 通过 （安装后） 下载模型 `pip install huggingface_hub hf_transfer` ）。您可以选择 Q4\_K\_M，或其他量化版本（比如 BF16 全精度）。

```python
# !pip install huggingface_hub hf_transfer
import os
os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
from huggingface_hub import snapshot_download
snapshot_download(
    repo_id = "unsloth/gemma-3n-E4B-it-GGUF",
    local_dir = "unsloth/gemma-3n-E4B-it-GGUF",
    allow_patterns = ["*UD-Q4_K_XL*", "mmproj-BF16.gguf"], # 对于 Q4_K_XL
)
```

4. 运行模型。
5. 编辑 `--threads 32` 以设置 CPU 线程数， `--ctx-size 32768` 以设置上下文长度（Gemma 3 支持 32K 上下文长度！）， `--n-gpu-layers 99` 用于设置 GPU 卸载的层数。如果您的 GPU 出现内存不足，请尝试调整。若仅 CPU 推理，请移除该参数。
6. 对于对话模式：

```bash
./llama.cpp/llama-cli \
    --model unsloth/gemma-3n-E4B-it-GGUF/gemma-3n-E4B-it-UD-Q4_K_XL.gguf \
    --mmproj unsloth/gemma-3n-E4B-it-GGUF/mmproj-BF16.gguf \
    --ctx-size 32768 \
    --n-gpu-layers 99 \
    --seed 3407 \
    --prio 2 \
    --temp 1.0 \
    --repeat-penalty 1.0 \
    --min-p 0.00 \
    --top-k 64 \
    --top-p 0.95
```

7. 用于非对话模式以测试 Flappy Bird：

```bash
./llama.cpp/llama-cli \
    --model unsloth/gemma-3n-E4B-it-GGUF/gemma-3n-E4B-it-UD-Q4_K_XL.gguf \
    --mmproj unsloth/gemma-3n-E4B-it-GGUF/mmproj-BF16.gguf \
    --ctx-size 32768 \
    --n-gpu-layers 99 \
    --seed 3407 \
    --prio 2 \
    --temp 1.0 \
    --repeat-penalty 1.0 \
    --min-p 0.00 \
    --top-k 64 \
    --top-p 0.95 \
    -no-cnv \
    --prompt "<start_of_turn>user\nCreate a Flappy Bird game in Python. You must include these things:\n1. You must use pygame.\n2. The background color should be randomly chosen and is a light shade. Start with a light blue color.\n3. Pressing SPACE multiple times will accelerate the bird.\n4. The bird's shape should be randomly chosen as a square, circle or triangle. The color should be randomly chosen as a dark color.\n5. Place on the bottom some land colored as dark brown or yellow chosen randomly.\n6. Make a score shown on the top right side. Increment if you pass pipes and don't hit them.\n7. Make randomly spaced pipes with enough space. Color them randomly as dark green or light brown or a dark gray shade.\n8. When you lose, show the best score. Make the text inside the screen. Pressing q or Esc will quit the game. Restarting is pressing SPACE again.\nThe final game should be inside a markdown section in Python. Check your code for errors and fix them before the final markdown section.<end_of_turn>\n<start_of_turn>model\n"
```

{% hint style="danger" %}
记得移除 \<bos> 因为 Gemma 3N 会自动添加一个 \<bos>！
{% endhint %}

## 🦥 使用 Unsloth 微调 Gemma 3n

Gemma 3n，像 [Gemma 3](https://unsloth.ai/docs/zh/mo-xing/tutorials/gemma-3-how-to-run-and-fine-tune/..#unsloth-fine-tuning-fixes-for-gemma-3)，在 以下 环境 运行时存在问题 <mark style="background-color:yellow;">**如 Colab 中的 Tesla T4 等 Float16 GPU**</mark>。如果不为 Gemma 3n 的推理或微调打补丁，您会遇到 NaN 和无穷值。 [更多信息见下文](#infinities-and-nan-gradients-and-activations).

* 使用我们的 微调 Gemma 3n-E4B [免费 Colab 笔记本](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3N_\(4B\)-Conversational.ipynb)
* **音频：** 使用我们的 微调 Gemma 3n-E4B [**仅音频 笔记本**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3N_\(4B\)-Audio.ipynb)
* **视觉**： 使用我们的 微调 Gemma 3n-E4B [**仅视觉 笔记本**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3N_\(4B\)-Vision.ipynb)

我们还发现，由于 Gemma 3n 独特的架构在视觉编码器中重用隐藏状态，这在 以下 描述 的 [梯度检查点（Gradient Checkpointing）中 引出 另一个有趣的怪癖](#gradient-checkpointing-issues)

<mark style="background-color:purple;">**Unsloth 是唯一能在 float16 机器上用于 Gemma 3n 推理和训练的框架。**</mark> 这意味着带有免费 Tesla T4 GPU 的 Colab 笔记本也可工作！总体而言，Unsloth 使 Gemma 3n 训练快 1.5 倍、显存减少 50%、上下文长度延长 4 倍。

我们的免费 Gemma 3n Colab 笔记本默认微调文本层。如果您想也微调视觉或音频层，请注意这将需要更多显存——超出免费 Colab 或 Kaggle 提供的 15GB。您 *可以* 仍然可以微调包括音频和视觉在内的所有层，Unsloth 也允许仅微调特定区域，例如仅微调视觉层。只需根据需要调整：

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

#### :trophy:额外内容

我们也听到你们想要一个 <mark style="background-color:blue;">**Gemma 3（4B）的视觉 笔记本**</mark> 所以这里有一个：

* 使用我们的 支持视觉 的方式 微调 Gemma 3（4B） [免费 Colab 笔记本](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3_\(4B\)-Vision.ipynb)

{% hint style="info" %}
如果你喜欢 Kaggle，Google 正在举办一个比赛，使用 Gemma 3n 和 Unsloth 微调的最佳模型将赢得 1 万美元奖金！ [在此查看更多](https://www.kaggle.com/competitions/google-gemma-3n-hackathon).
{% endhint %}

## 🐛 Gemma 3n 的修复

### :sparkles:GGUF 问题与修复

感谢 来自 的讨论 [Michael](https://github.com/mxyng) 来自 Ollama 团队以及 [Xuan](https://x.com/ngxson) 来自 Hugging Face，我们必须针对 GGUF 修复两个特定问题：

1. 参数 `add_shared_kv_layers` 被错误地以 `float32` 编码，这本身没有问题，但在 Ollama 端解码时会变得略微复杂——将其简单改为 `uint32` 即可解决该问题。 [拉取请求（Pull request）](https://github.com/ggml-org/llama.cpp/pull/14450) 已解决此问题。
2. 参数 `per_layer_token_embd` 层的精度应为 Q8\_0。低于此的精度无法正常工作并在 Ollama 引擎中报错——为减少社区问题，我们在所有量化文件中将此项设置为 Q8\_0——不幸的是这会占用更多空间。
   1. 作为 一项 [更新](https://huggingface.co/unsloth/gemma-3n-E4B-it-GGUF/discussions/4), [Matt](https://huggingface.co/WBB2500) 提到我们也可以对嵌入使用 Q4\_0、Q4\_1、Q5\_0、Q5\_1——我们已确认这在 Ollama 中也可工作！这意味着更小的 2、3、4 bit 量化体积更小，不需要 Q8\_0！

## :infinity:无穷值和 NaN 的梯度与激活

{% columns %}
{% column %}
Gemma 3n 与 Gemma 3 一样，在 FP16 GPU（例如 Colab 中的 Tesla T4）上存在问题。

我们之前对 Gemma 3 的修复 已在 [此处 讨论](https://unsloth.ai/docs/zh/mo-xing/tutorials/gemma-3-how-to-run-and-fine-tune)。对于 Gemma 3，我们发现激活超过了 float16 的最大范围 **65504.**

**Gemma 3N 没有此激活问题，但我们仍然遇到过无穷值！**
{% endcolumn %}

{% column %}

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-3f1aa0661c7919f8ad830fcbdf85a074d6a54bdf%2FGemma%203%20activation.webp?alt=media" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

为查明这些无穷值的根源，我们绘制了 Gemma 3N 权重条目的绝对最大值，结果如下：

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-e9b01a20a0a1cfcc41ef47cb29c5188d52d6a79d%2Foutput2.webp?alt=media" alt="" width="563"><figcaption></figcaption></figure>

我们发现绿色叉号是 Conv2D 卷积权重。我们可以看到 Conv2D 层的幅值平均上更大。

下面是具有较大幅值的 Conv2D 权重表。我们的假设是，在 Conv2D 运算过程中，大的权重相乘并相加， **不幸的是偶然超过了 float16 的最大范围 65504。** Bfloat16 则没问题，因为其最大范围约为 10^38。

| 名称                                     | 最大值       |
| -------------------------------------- | --------- |
| msfa.ffn.pw\_proj.conv.weight          | 98.000000 |
| blocks.2.21.attn.key.down\_conv.weight | 37.000000 |
| blocks.2.32.pw\_exp.conv.weight        | 34.750000 |
| blocks.2.30.pw\_exp.conv.weight        | 33.750000 |
| blocks.2.34.pw\_exp.conv.weight        | 33.750000 |

### :sparkler:解决无穷大的方法

简单的解决方法是 `提升精度` 将所有 Conv2D 权重提升到 float32（如果没有 bfloat16 可用）。但那会增加显存使用。为了解决这个问题，我们改为利用 `自动类型转换` 即时将权重和输入提升到 float32，因此我们在矩阵乘法本身作为累加的一部分时以 float32 执行累加，而不必提前提升权重的精度。

{% hint style="success" %}
Unsloth 是唯一能在 float16 GPU 上实现 Gemma 3n 推理和训练的框架，所以带有免费 Tesla T4 的 Colab 笔记本也能工作！
{% endhint %}

### :checkered\_flag:梯度检查点问题

我们发现 Gemma 3N 的视觉编码器也相当独特，因为它会重复使用隐藏状态。不幸的是，这限制了 [Unsloth 的梯度检查点](https://unsloth.ai/blog/long-context)的使用，这本可以显著减少显存使用，因为它无法应用于视觉编码器。

然而，我们仍设法利用 **Unsloth 的自动编译器** 来优化 Gemma 3N！

### :cactus:微调期间的大损失

我们还发现微调开始时损失值有趣地非常大——在 6 到 7 的范围，但它们会很快随时间下降。我们推测这可能由两种可能性导致：

1. 可能存在某些实现问题，但这不太可能，因为推理似乎能正常工作。
2. <mark style="background-color:blue;">**多模态模型似乎总是表现出这种行为**</mark> ——我们发现 Llama 3.2 Vision 的损失从 3 或 4 开始，Pixtral 约为 8 左右，Qwen 2.5 VL 也大约为 4。因为 Gemma 3N 还包含音频，可能会放大初始损失。但这只是一个假设。我们还发现对 Qwen 2.5 VL 72B Instruct 进行量化后困惑度极高，约为 30 左右，但模型有趣地表现良好。

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-a37a8ce8ff2cfc3873a9f78acee3744c778692dc%2Foutput(3).png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

{% hint style="success" %}
**使用我们的 微调 Gemma 3n** [**免费 Colab 笔记本**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3N_\(4B\)-Conversational.ipynb)
{% endhint %}

## 🛠️ 技术分析

### Gemma 3n：MatFormer

那 Gemma 3n 有什么特别之处？它基于 [套娃变压器（Matryoshka Transformer）或 MatFormer](https://arxiv.org/abs/2310.07707) 架构，这意味着每个变压器层/块嵌入/嵌套了逐渐更小规模的前馈网络。可以把它想象成一组逐渐变小的杯子相互套在一起。训练方式使得在推理时你可以选择所需的规模并尽可能获得更大模型的性能。

还有每层嵌入（Per Layer Embedding），可在推理时缓存以减少内存使用。所以 2B 模型（E2B）是 4B（即 5.44B）模型内部的一个子网络，这是通过每层嵌入缓存并跳过音频和视觉组件，仅专注于文本来实现的。

MatFormer 架构通常使用呈指数间隔的子模型进行训练，即大小为 `S`, `S/2, S/4, S/8` 等在每一层。因此在训练时，输入会随机通过上述某个子块，使每个子块有相等的机会学习。现在优点是，在推理时，如果你想要模型为原始大小的 1/4，你可以选择 `S/4` 大小的子块在每一层。

你也可以选择 **混合搭配** 比如你选择， `S/4` 某一层的子块大小为， `S/2` 另一层的子块大小为并且 `S/8` 另一层的子块大小为。实际上，如果你愿意，你可以根据输入本身改变所选子模型。基本上就是在每一层选择你自己的结构。仅通过训练一个特定大小的模型，你就创建了指数级数量的更小模型。没有学习被浪费。相当巧妙，对吧。

<figure><img src="https://2657992854-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-0f2e2a7a9d652391166798dec37319252b399f8e%2Fimage.png?alt=media" alt="" width="563"><figcaption><p>图片来自 <a href="https://ai.google.dev/gemma/docs/gemma-3n">Gemma 3n 模型概览</a></p></figcaption></figure>

{% hint style="info" %}
**使用我们的工具微调并尝试多模态 Gemma 3n 推理** [**免费 Colab 笔记本**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3N_\(4B\)-Conversational.ipynb)
{% endhint %}
