# Gemma 4 ファインチューニングガイド

これで Google の [Gemma 4](https://unsloth.ai/docs/jp/moderu/qwen3.5) E2B、E4B、26B-A4B、31B を [**Unsloth**](https://github.com/unslothai/unsloth)で学習できるようになりました。Unsloth は Gemma 4 のすべてのビジョン、テキスト、音声、RL のファインチューニングをサポートしています。

* Unsloth は Gemma 4 を **約1.5倍高速に** 、 **約60%少ない VRAM** で学習します（精度低下なし）
* 私たちは多くの汎用的な [Gemma 4 学習のバグ](#bug-fixes--tips) を修正しました（Unsloth 由来ではありません）。
* Gemma 4 E2B の学習は **8GB の VRAM**で動作します。E4B には 10GB の VRAM が必要です。

<a href="#quickstart" class="button primary" data-icon="bolt">クイックスタート</a><a href="#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 **（Vision + Text）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Vision.ipynb) | [E4B **（Audio）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Audio.ipynb) |
| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |

{% columns %}
{% column %}
私たちの [Unsloth Studio](https://unsloth.ai/docs/jp/xin-zhe/studio)✨ ノートブックでは、UI 付きで Gemma 4 を無料で実行および学習できます:

さらに多くの [ノートブックをこちらで見られます](#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 E2B LoRA は 8〜10GB の VRAM で動作します。E4B LoRA には 17GB の VRAM が必要です。
* **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 は 1〜3 またはそれ以下のより低い loss になります。Vision はその 2 倍高くなるため 3〜5 です**
{% endhint %}

#### :grapes:Gradient accumulation により loss が膨らむ可能性があります

{% columns %}
{% column %}

<div data-with-frame="true"><figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FET1GgLeZanVHDpPXLkM9%2FTransformers%20%2B%20TRL%20%2B%20Gemma-4.png?alt=media&#x26;token=0149149f-4d34-4bcb-a545-42e12d5127eb" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FZZola3h7ujfqz87VdnQm%2FUnsloth%20%2B%20Gemma-4.png?alt=media&#x26;token=37fc2b61-ae5b-4203-b9a7-388439aefae5" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

もし loss が 13〜15 より高い値（100 や 300 など）になっている場合、ほとんどは gradient accumulation が適切に考慮されていないことが原因です - 私たちはこれを **Unsloth と Unsloth Studio の一部として修正しました。**

gradient accumulation についてさらに読むには、gradient accumulation のバグ修正ブログをご覧ください: <https://unsloth.ai/blog/gradient>

#### :interrobang:Gemma-4 31B と 26B-A4B 推論時の IndexError

31B と 26B で推論を行う際に、このエラーが表示されることがあります:

```python
File "/.../cache_utils.py", line 937, in update
    keys, values = self.layers[layer_idx].update(...)
IndexError: list index out of range
```

原因は以下です:

```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 forward が `Cache.update`.

#### :no\_entry: `use_cache = True` E2B、E4B では生成結果が意味不明になっていました

[issue を参照してください](https://github.com/huggingface/transformers/issues/45242) "\[Gemma 4] `use_cache=False` は attention 計算を壊し、ゴミの logits を生成する #45242"

Gemma-4 E2B と E4B はレイヤー間で KV 状態を共有します（`num_kv_shared_layers = 20` および `18`）。キャッシュは、後続レイヤーが再利用するために初期レイヤーが KV を保存しておく唯一の場所です。 `use_cache=False` （すべての QLoRA チュートリアルが設定しているように、また `gradient_checkpointing=True` が強制するように）では、 `Gemma4TextModel.forward` はキャッシュの構築をスキップするため、KV 共有レイヤーは現在の hidden states からローカルに K と V を再計算することになります。logits はゴミになり、学習 loss は発散します。

**修正前（`unsloth/gemma-4-E2B-it`、プロンプト "What is 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 トークンすべて同一）
```

#### :radio:音声の float16 オーバーフロー

`Gemma4AudioAttention` は `config.attention_invalid_logits_value = -1e9` を `masked_fill` 呼び出しで使用しています。fp16（Tesla T4）では、-1e9 は fp16 の最大値 65504 をオーバーフローし、次を引き起こします:

```python
RuntimeError: value cannot be converted to type c10::Half without overflow
```

これは `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 の chat-template 用で、 `gemma-4-thinking` thinking バリアント用です。\
   26B と 31B の大きいモデルには thinking の方を使い、小さいモデルには non 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>

   で使用してください

   <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](https://unsloth.ai/docs/jp/xin-zhe/studio)、私たちの新しいローカル AI 向けオープンソース Web UI で実行およびファインチューニングできます。

Unsloth Studio を使うと、モデルをローカルで **MacOS、Windows**、Linux で実行し、NVIDIA GPU で学習できます。Intel、MLX、AMD の学習サポートは今月中に登場予定です。
{% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FpZlhqoILYOzznGpbudUk%2Funsloth%20studio%20gemma%20graphic.png?alt=media&#x26;token=75e41585-e363-45cf-a87e-4d02960766ed" 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="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FpZlhqoILYOzznGpbudUk%2Funsloth%20studio%20gemma%20graphic.png?alt=media&#x26;token=75e41585-e363-45cf-a87e-4d02960766ed" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### 学習の進行状況を監視

学習開始をクリックすると、モデルの学習進行状況を監視して確認できるようになります。学習 loss は安定して減少していくはずです。\
完了すると、モデルは自動的に保存されます。

<div data-with-frame="true"><figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FeBrnu9zxARIkhOHzd0pq%2FScreenshot%202026-04-07%20at%205.53.32%E2%80%AFAM.png?alt=media&#x26;token=dae77231-5020-4e8c-b2b8-cc49a98a9edf" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### ファインチューニングしたモデルをエクスポート

完了すると、Unsloth Studio はモデルを GGUF、safetensor などの形式にエクスポートできます。

<div data-with-frame="true"><figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FBtpx58zCdrOD4zB4DPSC%2FScreenshot%202026-04-07%20at%206.12.41%E2%80%AFAM.png?alt=media&#x26;token=05f05af2-5f7f-4b91-9c99-21d6a9b04935" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### ファインチューニング済みモデルと元のモデルを比較

をクリックしてください `比較モード` して LoRA アダプターと元のモデルを比較します。

<div data-with-frame="true"><figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fvm2CBSg7QBkKwTMKutyr%2FScreenshot%202026-04-07%20at%206.14.50%E2%80%AFAM.png?alt=media&#x26;token=8c9c159f-9d5b-4468-8984-681d19ebc427" 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 **（Vision + Text）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Vision.ipynb) | [E4B **（Audio）**](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 **（Vision + Text）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)-Vision.ipynb) | [E2B **（Audio）**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)-Audio.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**](https://unsloth.ai/docs/jp/meru/reinforcement-learning-rl-guide)**をやりたい場合、fast vLLM inference を無効にして代わりに Unsloth inference を使えば、Unsloth で動作します。私たちの** [**Vision RL**](https://unsloth.ai/docs/jp/meru/reinforcement-learning-rl-guide/vision-reinforcement-learning-vlm-rl) **ノートブックの例に従ってください。**
{% endhint %}

以下はスタンドアロンの Gemma-4-26B-A4B-it テキスト SFT レシピです。これはテキスト専用です - 詳細については私たちの [vision ファインチューニング](https://unsloth.ai/docs/jp/ji-ben/vision-fine-tuning) セクションも参照してください。

{% 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", # gated モデル用 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" : "この動物はどの映画に登場しますか？" }
    ]
}]
# Unsloth の自動コンパイラのために 1 分待つ必要があるかもしれません
do_gemma_4_inference(messages, max_new_tokens = 256)

"""ナマケモノについて詩を作りましょう!"""

messages = [{
    "role": "user",
    "content": [{ "type" : "text",
                  "text" : "ナマケモノについて詩を書いてください。" }]
}]
do_gemma_4_inference(messages)

"""# Gemma 4 をファインチューニングしましょう!

今のところ、選択によって vision と text の部分をファインチューニングできます - audio の部分もファインチューニング可能で、これも選択できるように作業中です!

ここで LoRA アダプターを追加するので、少量のパラメータだけ更新すればよくなります!
"""

model = FastModel.get_peft_model(
    model,
    finetune_vision_layers     = False, # テキストだけならオフ!
    finetune_language_layers   = True,  # オンのままにすべき!
    finetune_attention_modules = True,  # Attention は GRPO に良い
    finetune_mlp_modules       = True,  # 常にオンのままにすべき!

    r = 8,           # 大きいほど高精度ですが、過学習する可能性あり
    lora_alpha = 8,  # 推奨 alpha は少なくとも r == alpha
    lora_dropout = 0,
    bias = "none",
    random_state = 3407,
)

"""<a name="Data"></a>
### データ準備
会話スタイルのファインチューニングには、現在 `Gemma-4` 形式を使用します。ShareGPT スタイルの [Maxime Labonne's FineTome-100k](https://huggingface.co/datasets/mlabonne/FineTome-100k) データセットを使用します。Gemma-4 は複数ターンの会話を次のようにレンダリングします:

```
<bos><|turn>user
こんにちは<turn|>
<|turn>model
やあ！<turn|>
```
正しい chat template を取得するために、私たちの `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` の chat template を適用し、それを `text` に保存する必要があります。ファインチューニング中なので、removeprefix(`'<bos>'`) を使って `<bos>` トークンを削除します。Processor は学習前にこのトークンを追加し、モデルは 1 つだけを期待するためです。"""

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)

"""chat template がどう機能したか見てみましょう! processor tokenizer が追加するので、`<bos>` トークンがないことに注意してください。"""

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 などを使用
    ),
)

"""また、アシスタントの出力に対してのみ学習し、ユーザー入力に対する loss を無視するために、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",
)

"""instruction 部分のマスキングが行われていることを確認しましょう! 100 行目をもう一度表示します。サンプルには期待通り `<bos>` が 1 つだけあることに注意してください!"""

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`](https://unsloth.ai/docs/jp/burogu/500k-context-length-fine-tuning#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 は非推奨、dense 31B は問題なし
    load_in_16bit = True,     # bf16/16-bit LoRA
    full_finetuning = False,
)
```

ロード後は、LoRA アダプターを取り付けて、上記の SFT 例と同様に学習します。

### MoE ファインチューニング（26B-A4B）

この **26B-A4B** モデルは Gemma 4 ラインナップにおける速度と品質の中間点です。これは **MoE** モデルであり、トークンごとにアクティブになるパラメータは一部だけなので、保守的なファインチューニングのアプローチは次のとおりです:

* 使用する **LoRA** 完全ファインチューニングではなく
* 優先する **16-bit / bf16 LoRA** メモリに余裕があれば
* まずは短いコンテキストと小さな rank から始める
* パイプラインが安定してからのみスケールアップする

最高品質が目標で、より多くのメモリがあるなら、 **31B** を代わりに使ってください。

### マルチモーダル ファインチューニング（E2B / E4B）

なぜなら **E2B** および **E4B** サポートしている **画像** および **音声**、これらはマルチモーダル ファインチューニングの主な Gemma 4 バリアントだからです。

* マルチモーダル モデルを `FastVisionModel`
* でロードする `finetune_vision_layers = False` をまず
* 言語、attention、MLP レイヤーのみをファインチューニングする
* タスクに必要なら後で vision または audio レイヤーを有効化する

#### 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% だけを効率よく学習できるようにします。

**[NEW]** vision コンポーネントのみ、language コンポーネントのみ、または両方のファインチューニングもサポートしています。さらに、attention モジュール、MLP レイヤー、またはその両方をファインチューニングすることも選べます!
"""

model = FastVisionModel.get_peft_model(
    model,
    finetune_vision_layers     = True, # vision レイヤーをファインチューニングしないなら False
    finetune_language_layers   = True, # language レイヤーをファインチューニングしないなら False
    finetune_attention_modules = True, # attention レイヤーをファインチューニングしないなら False
    finetune_mlp_modules       = True, # MLP レイヤーをファインチューニングしないなら False

    r = 32,                           # 大きいほど高精度ですが、過学習する可能性あり
    lora_alpha = 32,                  # 推奨 alpha は少なくとも r == alpha
    lora_dropout = 0,
    bias = "none",
    random_state = 3407,
    use_rslora = False,               # rank stabilized 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")

"""データセットの概要を見てみましょう。2 番目の画像と対応するキャプションを確認します。"""

dataset

dataset[2]["image"]

dataset[2]["text"]

"""LaTeX をブラウザ上で直接レンダリングすることもできます!"""

from IPython.display import display, Math, Latex

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

"""データセットを整形するには、すべての vision ファインチューニング タスクがこの形式に従う必要があります:

```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 の instruction chat template を取得して、ベースモデルで使いましょう"""

from unsloth import get_chat_template

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

"""ファインチューニング前に、ベースモデルの性能を評価してみましょう。この chat template にはまだ遭遇していないため、強い結果は期待していません。"""

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 など向け

        # 視覚のファインチューニングでは、以下の項目を MUST 設定してください:
        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\": \"Example Store\", \"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](https://unsloth.ai/docs/jp/xin-zhe/studio/export), [llama.cpp](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment/saving-to-gguf), [vLLM](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment/vllm-guide), [llama-server](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment/llama-server-and-openai-endpoint), [Ollama](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment/saving-to-ollama) または [SGLang](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment/sglang-guide).

#### 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 に push できます:

```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 トークンの誤り** （学習時と同じチャットテンプレートを使用しなければなりません）。

詳細は推論ガイドをご覧ください:

{% columns %}
{% column width="50%" %}
{% content-ref url="../../ji-ben/inference-and-deployment" %}
[inference-and-deployment](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment)
{% endcontent-ref %}

{% content-ref url="../../ji-ben/inference-and-deployment/saving-to-gguf" %}
[saving-to-gguf](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment/saving-to-gguf)
{% endcontent-ref %}
{% endcolumn %}

{% column width="50%" %}
{% content-ref url="../../xin-zhe/studio/export" %}
[export](https://unsloth.ai/docs/jp/xin-zhe/studio/export)
{% endcontent-ref %}

{% content-ref url="../../ji-ben/inference-and-deployment/vllm-guide" %}
[vllm-guide](https://unsloth.ai/docs/jp/ji-ben/inference-and-deployment/vllm-guide)
{% endcontent-ref %}
{% endcolumn %}
{% endcolumns %}

### Gemma 4 のデータのベストプラクティス

Gemma 4 には、注意しておくべきいくつかの書式上の詳細があります。

#### 1. 標準のチャットロールを使用する

Gemma 4 は標準の以下を使用します:

* `system`
* `user`
* `assistant`

つまり、SFT データセットは、古い Gemma 固有のロール形式ではなく、通常のチャット形式で書くべきです。

#### 2. 思考モードは明示的です

SFT 中に思考スタイルの振る舞いを保持したい場合:

* 形式を一貫させる
* どちらで学習させるかを決める **可視の思考ブロック** または **最終回答のみ**
* 行う **行わない** 同じデータセット内で互換性のない複数の思考形式を混在させない

多くの本番向けアシスタントでは、最も簡単な設定は、以下についてファインチューニングすることです **最終の可視回答のみ**.

#### 3. マルチターンのルール

マルチターン会話では、会話履歴に残すのは **最終の可視回答のみ** にしてください。以前の思考ブロックを **行わない** 後続のターンに戻して入力しないでください。
