# Vision 強化学習（VLM RL）

Unsloth は現在、視覚/マルチモーダル強化学習を次のものでサポートしています [。](https://unsloth.ai/docs/jp/moderu/tutorials/qwen3-how-to-run-and-fine-tune/qwen3-vl-how-to-run-and-fine-tune), [Gemma 3](https://unsloth.ai/docs/jp/moderu/tutorials/gemma-3-how-to-run-and-fine-tune) およびその他。Unsloth の独自の [重み共有](https://unsloth.ai/docs/jp/meru/reinforcement-learning-rl-guide/..#what-unsloth-offers-for-rl) とカスタムカーネルにより、Unsloth は VLM 強化学習を可能にします **1.5–2× 速く、** 使用します **90% 少ない VRAM**、および有効にします **FA2 構成より 15× 長いコンテキスト** 長さを、精度低下なしで。このアップデートはまた Qwen の [や Dr. GRPO のような他のものに設定することもできる点に注意。](#gspo-rl) アルゴリズムも導入します。

Unsloth は GSPO/GRPO で Qwen3-VL-8B を無料の Colab T4 GPU で学習できます。他の VLM も動作しますが、より大きな GPU が必要な場合があります。Gemma は vLLM が [Bfloat16 に制限する](https://unsloth.ai/docs/jp/moderu/tutorials/gemma-3-how-to-run-and-fine-tune#unsloth-fine-tuning-fixes)ため T4 より新しい GPU を必要とし、Colab では NVIDIA L4 を推奨します。私たちのノートブックは画像や図を含む数値数学の問題を解きます：

* **Qwen-3 VL-8B** （vLLM 推論）**:** [Colab](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_VL_\(8B\)-Vision-GRPO.ipynb)
* **Qwen-2.5 VL-7B** （vLLM 推論）**:** [Colab](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen2_5_7B_VL_GRPO.ipynb) •[ Kaggle](https://www.kaggle.com/notebooks/welcome?src=https://github.com/unslothai/notebooks/blob/main/nb/Kaggle-Qwen2_5_7B_VL_GRPO.ipynb\&accelerator=nvidiaTeslaT4)
* **Gemma-3-4B** （Unsloth 推論）： [Colab](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma3_\(4B\)-Vision-GRPO.ipynb)

また、vLLM の VLM 統合を Unsloth にネイティブに追加したので、vLLM 推論を使用するにはモデル初期化時に単に `fast_inference=True` フラグを有効にするだけです。特別な感謝を [Sinoué GAD](https://github.com/unslothai/unsloth/pull/2752) に、 [最初のノートブック](https://github.com/GAD-cell/vlm-grpo/blob/main/examples/VLM_GRPO_basic_example.ipynb) を提供して VLM 強化学習の統合を容易にしてくれたことに！

この VLM サポートは、さらにメモリ効率が良く高速な RL に向けた最新のアップデートも統合しており、そこには私たちの [スタンバイ機能](https://unsloth.ai/docs/jp/meru/memory-efficient-rl#unsloth-standby)も含まれています。これは他の実装と比較して速度低下を独自に制限します。

{% hint style="info" %}
使用できるのは `fast_inference` のみで、vLLM がサポートする VLM に限られます。Llama 3.2 Vision のような一部モデルは vLLM なしでのみ動作しますが、Unsloth ではそれでも動作します。
{% endhint %}

```python
os.environ['UNSLOTH_VLLM_STANDBY'] = '1' # vLLM でメモリ効率の良い GRPO を有効にするため
model, tokenizer = FastVisionModel.from_pretrained(
    model_name = "Qwen/Qwen2.5-VL-7B-Instruct",
    max_seq_length = 16384, # 画像をコンテキストに収めるにはこのくらい大きくする必要があります
    load_in_4bit = True, # LoRA 16bit の場合は False
    fast_inference = True, # vLLM の高速推論を有効にする
    gpu_memory_utilization = 0.8, # メモリ不足の場合は下げてください
)
```

また、vLLM は視覚/エンコーダ層に対する LoRA をサポートしないことに注意することも重要です。したがって設定してください `finetune_vision_layers = False` LoRA アダプタを読み込むとき。\
ただし、transformers/Unsloth 経由の推論を使用する場合は視覚層を訓練することも可能です。

```python
# パラメータ効率の良い微調整のためにモデルに LoRA アダプタを追加
model = FastVisionModel.get_peft_model(
    model,

    finetune_vision_layers     = False,# fast_inference はまだ finetune_vision_layers をサポートしていません :(
    finetune_language_layers   = True, # 言語層を微調整しない場合は False
    finetune_attention_modules = True, # 注意層を微調整しない場合は False
    finetune_mlp_modules       = True, # MLP 層を微調整しない場合は False

    r = lora_rank, # 0 より大きい任意の数を選択！推奨は 8、16、32、64、128
    lora_alpha = lora_rank*2, # *2 は学習を高速化します
    use_gradient_checkpointing = "unsloth", # メモリ使用量を削減
    random_state = 3407,
)
```

## :butterfly:Qwen 2.5 VL 視覚強化学習の問題点と特異性

Qwen 2.5 VL の RL 中に、次のような推論出力が表示されることがあります：

{% code overflow="wrap" %}

```
 addCriterion
 <tool_call>\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n\n addCriterion\n\n 自动生成\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n addCriterion\n\n\n addCriterion\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
```

{% endcode %}

これは [報告されました](https://github.com/QwenLM/Qwen2.5-VL/issues/759) また、Qwen2.5-VL-7B-Instruct の出力で予期しない結果 "addCriterion" としても報告されています。実際、私たちもこれを確認しました！Unsloth 以外の環境や bfloat16、float16 のマシンなど様々な条件を試しましたが、それでも発生するようです。例えば項目 165、つまり `train_dataset[165]` からの [AI4Math/MathVista](https://huggingface.co/datasets/AI4Math/MathVista) データセットは以下の通りです：

{% code overflow="wrap" %}

```
図はレースカーの走行経路を上から見たもので、車がサーキットの壁に衝突します。衝突直前、彼は壁から 30° の直線上を速度 v_i=70 \mathrm{~m} / \mathrm{s} で移動しています。衝突直後、彼は壁から 10° の直線上を速度 v_f=50 \mathrm{~m} / \mathrm{s} で移動しています。彼の質量 m は 80 \mathrm{~kg} です。衝突は 14 \mathrm{ms} 続きます。衝突中のドライバーに対する平均力の大きさはいくらですか？
```

{% endcode %}

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-61a659529171fcc10ed6398a15912b21d6b1a076%2FUntitled.png?alt=media" alt="" width="128"><figcaption></figcaption></figure>

そして上記の意味不明な出力が得られます。addCriterion の追加を罰する報酬関数や、意味不明な出力を罰する報酬関数を追加することもできます。しかし別のアプローチとしては、より長く学習させることです。例えば大体 60 ステップ後にモデルが実際に RL で学習しているのが見られます：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-5f34f66f0ac6508fd28343b16592c59b889ec5ca%2Fimage.webp?alt=media" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
強制的に `<|assistant|>` を生成中に入れることで、これは指示型モデルであるため期待通りこれらの意味不明な結果の出現を減らしますが、次のセクションで述べるように悪い生成を罰する報酬関数を追加するのが最善です。
{% endhint %}

## :medal:意味不明な出力を減らすための報酬関数

を罰するために、 `addCriterion` および意味不明な出力を罰するように、報酬関数を編集して `addCriterion` と改行を過度に penalize するようにしました。

```python
def formatting_reward_func(completions,**kwargs):
    import re
    thinking_pattern = f'{REASONING_START}(.*?){REASONING_END}'
    answer_pattern = f'{SOLUTION_START}(.*?){SOLUTION_END}'

    for completion in completions:
    response = completion[0]["content"]
        score = 0
        thinking_matches = re.findall(thinking_pattern, completion, re.DOTALL)
        answer_matches = re.findall(answer_pattern, completion, re.DOTALL)
        if len(thinking_matches) == 1:
            score += 1.0
        if len(answer_matches) == 1:
            score += 1.0

        # addCriterion の問題を修正
        # 詳細は https://docs.unsloth.ai/new/vision-reinforcement-learning-vlm-rl#qwen-2.5-vl-vision-rl-issues-and-quirks を参照
        # 過度の addCriterion と改行を罰する
        if len(completion) != 0:
            removal = completion.replace("addCriterion", "").replace("\n", "")
            if (len(completion)-len(removal))/len(completion) >= 0.5:
                score -= 2.0

        scores.append(score)
    no_cheating
```

## :checkered\_flag:GSPO 強化学習

このアップデートではさらに GSPO（[Group Sequence Policy Optimization](https://arxiv.org/abs/2507.18071)）を追加します。これは Alibaba の Qwen チームが作った GRPO の変種です。彼らは GRPO が各トークンに対して重要度重みを暗黙に生じさせることに気づきましたが、明示的な優位度（advantages）は各トークンごとにスケールしたり変化したりしないことに着目しました。

これにより GSPO が作られ、各トークンの個別の尤度ではなくシーケンスの尤度に重要度を割り当てるようになりました。これら二つのアルゴリズムの違いは、Qwen と Alibaba の GSPO 論文でも以下のように示されています：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-45d743dd5dcd590626777ce09cfab61808aa8c24%2Fimage.png?alt=media" alt="" width="563"><figcaption><p>GRPO アルゴリズム、出典： <a href="https://arxiv.org/abs/2507.18071">Qwen</a></p></figcaption></figure>

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-ee755850cbe17482ce240dde227d55c62e9a3e64%2Fimage.png?alt=media" alt="" width="563"><figcaption><p>GSPO アルゴリズム、出典： <a href="https://arxiv.org/abs/2507.18071">Qwen</a></p></figcaption></figure>

式 1 では、優位度がテンソルを合計する前に各行をトークンの対数確率にスケーリングすることが見て取れます。本質的に、各トークンには同じスケーリングが与えられますが、そのスケーリングは個々のトークンではなくシーケンス全体に与えられていたものです。これの簡単な図は以下に示せます：

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-b3c944808a15dde0a7ff45782f9f074993304bf1%2FCopy%20of%20GSPO%20diagram%20(1).jpg?alt=media" alt="" width="286"><figcaption><p>優位度で行ごとにスケーリングされた GRPO の対数確率比</p></figcaption></figure>

式 2 は、各シーケンスの対数確率比が計算された後に合計・指数化され、その結果得られたシーケンス比のみが行ごとに優位度と乗算されることを示しています。

<figure><img src="https://735611837-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fgit-blob-62fc5b50921e79cce155d2794201c9b96faf941e%2FGSPO%20diagram%20(1).jpg?alt=media" alt="" width="313"><figcaption><p>優位度で行ごとにスケーリングされた GSPO のシーケンス比</p></figcaption></figure>

GSPO を有効にするのは簡単で、GRPO の設定で次の `importance_sampling_level = "sequence"` フラグを設定するだけです。

```python
training_args = GRPOConfig(
    output_dir = "vlm-grpo-unsloth",
    per_device_train_batch_size = 8,
    gradient_accumulation_steps = 4,
    learning_rate = 5e-6,
    adam_beta1 = 0.9,
    adam_beta2 = 0.99,
    weight_decay = 0.1,
    warmup_ratio = 0.1,
    lr_scheduler_type = "cosine",
    optim = "adamw_8bit",
    # beta = 0.00,
    epsilon = 3e-4,
    epsilon_high = 4e-4,
    num_generations = 8,    
    max_prompt_length = 1024,
    max_completion_length = 1024,
    log_completions = False,
    max_grad_norm = 0.1,
    temperature = 0.9,
    # report_to = "none", # ロギングを Weights & Biases に行いたい場合は "wandb" に設定
    num_train_epochs = 2, # 簡易テスト用。完全な学習には増やしてください
    report_to = "none"
    
    # GSPO は以下：
    importance_sampling_level = "sequence",
    
    # Dr GRPO / GAPO 等
    loss_type = "dr_grpo",
)
```

総じて、Unsloth は VLM vLLM 高速推論によりメモリ使用量を 90% 削減するとともに、GRPO と GSPO で 1.5–2× の高速化を実現します！

強化学習についてさらに読みたい場合は、私たちの RL ガイドをご覧ください：

[](https://unsloth.ai/docs/jp/meru/reinforcement-learning-rl-guide "mention")

***著者：** 心からの感謝を* [*Keith*](https://www.linkedin.com/in/keith-truongcao-7bb84a23b/) *および* [*Datta*](https://www.linkedin.com/in/datta0/) *この記事に貢献してくれたことに感謝します！*


---

# Agent Instructions: 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:

```
GET https://unsloth.ai/docs/jp/meru/reinforcement-learning-rl-guide/vision-reinforcement-learning-vlm-rl.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
