> 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/fr/modeles/gemma-4/train.md).

# Guide de fine-tuning Gemma 4

Entraînez Gemma 4 de Google avec Unsloth.

Vous pouvez désormais entraîner le modèle de Google [Gemma 4](https://unsloth.ai/docs/models/gemma-4) 12B, E2B, E4B, 26B-A4B et 31B avec [**Unsloth**](https://github.com/unslothai/unsloth). Unsloth prend en charge tous les réglages fins visuels, textuels, audio et RL pour Gemma 4.

* Unsloth entraîne Gemma 4 **\~1,5x plus vite** par **\~60 % de VRAM en moins** que les configurations FA2 (sans perte de précision)
* Nous avons corrigé de nombreux bugs [généraux pour l'entraînement de Gemma 4](#bug-fixes--tips) (non dérivés d'Unsloth).
* Gemma 4 E2B s'entraîne sur **8 Go de VRAM**. E4B nécessite 10 Go de VRAM.

<a href="/docs/fr/modeles/gemma-4/train.md#quickstart" class="button primary" data-icon="bolt">Démarrage rapide</a><a href="/docs/fr/modeles/gemma-4/train.md#bug-fixes--tips" class="button secondary" data-icon="sparkle">Corrections de bugs + conseils</a>

Ajustez finement Gemma 4 via nos **gratuits** **notebooks 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 **(Vision + Texte)**](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) | [E2B **(RL GRPO)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)_Reinforcement_Learning_Sudoku_Game.ipynb) |
| -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |

{% columns %}
{% column %}
Vous pouvez exécuter et entraîner Gemma 4 gratuitement avec une interface dans nos [Unsloth Studio](/docs/fr/nouveau/studio.md)✨ notebook :

Vous pouvez voir plus de [notebooks ici](#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 %}

* Vous pouvez aussi entraîner Gemma 4 avec [l'apprentissage par renforcement](#reinforcement-learning-rl) (RL) sur 9 Go de VRAM.
* Gemma 4 E2B LoRA fonctionne sur 8 à 10 Go de VRAM. E4B LoRA nécessite 17 Go de VRAM.
* **31B QLoRA fonctionne avec 22 Go** et 26B-A4B LoRA nécessite >40 Go
* **Exportation**/enregistrement des modèles au format GGUF, etc. et l'ajustement fin complet **(FFT)** fonctionne également.

### :bug: Corrections de bugs + conseils

{% hint style="success" %}
Si vous voyez **Gemma-4 E2B et E4B avec une perte de 13 à 15, c'est tout à fait normal** - c'est une particularité courante des modèles multimodaux. Cela s'est aussi produit sur Gemma-3N, les modèles vision de Llama Vision, Mistral et d'autres.

**Gemma 26B et 31B ont une perte plus faible, entre 1 et 3 ou moins. La vision sera 2x plus élevée, donc 3 à 5**
{% endhint %}

#### :grapes:L'accumulation de gradients peut gonfler vos pertes

{% columns %}
{% column %}

<div data-with-frame="true"><figure><img src="https://550366147-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&amp;token=0149149f-4d34-4bcb-a545-42e12d5127eb" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}

{% column %}

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

Si vous voyez des pertes supérieures à 13-15 (comme 100 ou 300), il est très probable que l'accumulation de gradients ne soit pas prise en compte correctement - nous avons **corrigé cela dans Unsloth et Unsloth Studio.**

Pour en savoir plus sur l'accumulation de gradients, consultez notre article sur la correction du bug d'accumulation de gradients : <https://unsloth.ai/blog/gradient>

#### :interrobang:IndexError lors de l'inférence de Gemma-4 31B et 26B-A4B

Vous pourriez voir cette erreur lors d'une inférence avec 31B et 26B :

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

Le coupable est ci-dessous :

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

Là où Gemma-4 31B et 26B-A4B sont livrés avec `num_kv_shared_layers = 0`. En Python, `-0 == 0`, donc `layer_types[:-0]` se réduit à `layer_types[:0] == []`. Le cache est construit avec zéro emplacement de couche et le tout premier passage avant d'attention plante dans `Cache.update`.

#### :no\_entry: `use_cache = True` la génération était incompréhensible pour E2B, E4B

[Voir le problème](https://github.com/huggingface/transformers/issues/45242) "\[Gemma 4] `use_cache=False` corrompt le calcul de l'attention, produisant des logits inutilisables #45242"

Gemma-4 E2B et E4B partagent l'état KV entre les couches (`num_kv_shared_layers = 20` et `18`). Le cache est le seul endroit où les couches précoces stockent le KV pour que les couches suivantes le réutilisent. Lorsque `use_cache=False` (comme le définissent tous les tutoriels QLoRA, et comme `gradient_checkpointing=True` l'impose), `Gemma4TextModel.forward` ignore la construction du cache, si bien que les couches KV partagées retombent sur le recalcul local de K et V à partir des états cachés courants. Les logits deviennent incohérents et la perte d'entraînement diverge.

**Avant (`unsloth/gemma-4-E2B-it`, invite "What is 1+1?" :**

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

**Après notre correction :**

```
use_cache=True  -> '1 + 1 = **2**'
use_cache=False -> '1 + 1 = **2**'
max_abs_logit_diff: 0.000000     (parité exacte au bit près, les 9 jetons sont identiques)
```

#### :radio:Dépassement de capacité en float16 pour l'audio

`Gemma4AudioAttention` utilise `config.attention_invalid_logits_value = -1e9` dans un appel `masked_fill` . Sur fp16 (Tesla T4), -1e9 dépasse le maximum fp16 de 65504, provoquant :

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

Cela était dû à `self.config.attention_invalid_logits_value` :

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

#### 💡Conseils pour Gemma-4

1. Si vous voulez **préserver la capacité** de raisonnement, vous pouvez mélanger des exemples de type raisonnement avec des réponses directes (gardez au minimum 75 % de raisonnement). Sinon, vous pouvez l'émettre entièrement.\
   \
   Utilisez `gemma-4` pour le chat-template sans réflexion et `gemma-4-thinking` pour la variante avec réflexion.\
   Utilisez celle avec réflexion pour les modèles plus grands 26B et 31B, et celle sans réflexion pour les petits modèles.<br>

   ```python
   from unsloth.chat_templates import get_chat_template
   tokenizer = get_chat_template(
       tokenizer,
       chat_template = "gemma-4-thinking", # Ou "gemma-4"
   )
   ```
2. Pour activer le mode réflexion, utilisez `enable_thinking = True / False` dans `tokenizer.apply_chat_template`<br>

   Réflexion activée :

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

   Va afficher `<bos><|turn>system\n<|think|><turn|>\n<|turn>user\nWhat is 2+2?<turn|>\n<|turn>model\n`<br>

   Réflexion désactivée :

   ```python
   processor.tokenizer.apply_chat_template([
       {"role" : "user", "content" : "What is 2+2?"},
   ], tokenize = False, enable_thinking = False, add_generation_prompt = True)
   ```

   Va afficher `<bos><|turn>user\nWhat is 2+2?<turn|>\n<|turn>model\n<|channel>thought\n<channel|>`
3. Gemma 4 est puissant pour l'ajustement fin multilingue, car il prend en charge 140 langues.
4. Il est recommandé d'entraîner **E4B QLoRA** plutôt que **E2B LoRA** car E4B est plus grand et la différence de précision de quantification est minuscule. Gemma 4 E4B LoRA est encore meilleur.
5. Après l'ajustement fin, vous pouvez exporter vers [GGUF](#saving-export-your-fine-tuned-model) (pour llama.cpp/Unsloth/Ollama/etc.)

### ⚡Démarrage rapide

#### 🦥 Guide d’Unsloth Studio

{% columns %}
{% column %}
Gemma 4 peut être exécuté et ajusté finement dans [Unsloth Studio](/docs/fr/nouveau/studio.md), notre nouvelle interface web open source pour l'IA locale.

Avec Unsloth Studio, vous pouvez exécuter des modèles localement sur **macOS, Windows**, Linux et entraîner des GPU NVIDIA. La prise en charge de l'entraînement sur Intel, MLX et AMD arrive ce mois-ci.
{% endcolumn %}

{% column %}

<div data-with-frame="true"><figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FpZlhqoILYOzznGpbudUk%2Funsloth%20studio%20gemma%20graphic.png?alt=media&amp;token=75e41585-e363-45cf-a87e-4d02960766ed" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

{% stepper %}
{% step %}

#### Installer Unsloth

Exécutez dans votre terminal :

**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" %}
**L'installation sera rapide et prendra environ 1 à 2 minutes.**
{% endhint %}
{% endstep %}

{% step %}

#### Lancer Unsloth

**MacOS, Linux, WSL et Windows :**

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

**Puis ouvrez `http://localhost:8888` dans votre navigateur.**
{% endstep %}

{% step %}

#### Entraîner Gemma 4

Au premier lancement, vous devrez créer un mot de passe pour sécuriser votre compte et vous reconnecter plus tard. Vous verrez ensuite un bref assistant d'intégration pour choisir un modèle, un jeu de données et des paramètres de base. Vous pouvez le passer à tout moment.

Recherchez Gemma 4 dans la barre de recherche et sélectionnez le modèle et le jeu de données souhaités. Ensuite, ajustez vos hyperparamètres, la longueur du contexte selon vos besoins.

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

{% step %}

#### Surveiller la progression de l'entraînement

Après avoir cliqué sur démarrer l'entraînement, vous pourrez surveiller et observer la progression de l'entraînement du modèle. La perte d'entraînement devrait diminuer régulièrement.\
Une fois terminé, le modèle sera automatiquement enregistré.

<div data-with-frame="true"><figure><img src="https://550366147-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&amp;token=dae77231-5020-4e8c-b2b8-cc49a98a9edf" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### Exporter votre modèle ajusté finement

Une fois terminé, Unsloth Studio vous permet d'exporter le modèle aux formats GGUF, safetensor, etc.

<div data-with-frame="true"><figure><img src="https://550366147-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&amp;token=05f05af2-5f7f-4b91-9c99-21d6a9b04935" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}

{% step %}

#### Comparer le modèle ajusté finement avec le modèle original

Cliquez sur `Mode comparaison` pour comparer l'adaptateur LoRA et le modèle original.

<div data-with-frame="true"><figure><img src="https://550366147-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&amp;token=8c9c159f-9d5b-4468-8984-681d19ebc427" alt="" width="563"><figcaption></figcaption></figure></div>
{% endstep %}
{% endstepper %}

#### 🦥 Guide Unsloth Core (basé sur le code)

Nous avons créé des notebooks gratuits pour Gemma 4 :

| [E4B **(Inférence + Texte)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E4B\)-Text.ipynb) | [E4B **(Vision + Texte)**](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 + Texte)**](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) |

Et pour l'apprentissage par renforcement (RL) : [E2B **(RL GRPO)**](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Gemma4_\(E2B\)_Reinforcement_Learning_Sudoku_Game.ipynb)

Nous avons aussi créé des notebooks pour les modèles Gemma 4 plus grands, mais ils nécessitent un A100 :

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

{% hint style="info" %}
**Si vous souhaitez faire** [**GRPO**](/docs/fr/commencer/reinforcement-learning-rl-guide.md)**, cela fonctionne dans Unsloth si vous désactivez l'inférence rapide vLLM et utilisez à la place l'inférence Unsloth. Suivez nos exemples de notebooks** [**de RL vision**](/docs/fr/commencer/reinforcement-learning-rl-guide/vision-reinforcement-learning-vlm-rl.md) **.**
{% endhint %}

Ci-dessous se trouve une recette autonome de SFT texte Gemma-4-26B-A4B-it. Ceci est du texte uniquement - voir aussi notre section de [d'ajustement fin vision](/docs/fr/notions-de-base/vision-fine-tuning.md) pour plus de détails.

{% code expandable="true" %}

````python
from unsloth import FastModel
import torch

model, tokenizer = FastModel.from_pretrained(
    model_name = "unsloth/gemma-4-26B-A4B-it", # Remplacez cela par unsloth/gemma-4-E2B-it etc
    dtype = None, # None pour la détection automatique
    max_seq_length = 8192, # Choisissez n'importe quelle valeur pour un long contexte !
    load_in_4bit = True,  # Quantification 4 bits pour réduire la mémoire
    full_finetuning = False, # [NOUVEAU !] Nous avons maintenant l'ajustement fin complet !
    # token = "VOTRE_JETON_HF", # Jeton HF pour les modèles protégés
)

"""# Gemma 4 peut traiter le texte, la vision et l'audio !

Commençons par voir comment Gemma 4 peut gérer des entrées multimodales. Nous utilisons les paramètres recommandés de Gemma 4 : `temperature = 1.0, top_p = 0.95, top_k = 64`
"""

from transformers import TextStreamer
# Fonction utilitaire pour l'inférence
def do_gemma_4_inference(messages, max_new_tokens = 128):
    _ = model.generate(
        **tokenizer.apply_chat_template(
            messages,
            add_generation_prompt = True, # Doit être ajouté pour la génération
            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 peut voir des images !

<img src="https://files.worldwildlife.org/wwfcmsprod/images/Sloth_Sitting_iStock_3_12_2014/story_full_width/8l7pbjmj29_iStock_000011145477Large_mini__1_.jpg" alt="Texte alternatif" 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" : "Quels films mettent en scène cet animal ?" }
    ]
}]
# Vous devrez peut-être attendre 1 minute pour le compilateur automatique d'Unsloth
do_gemma_4_inference(messages, max_new_tokens = 256)

"""Écrivons un poème sur les paresseux !"""

messages = [{
    "role": "user",
    "content": [{ "type" : "text",
                  "text" : "Écris un poème sur les paresseux." }]
}]
do_gemma_4_inference(messages)

"""# Ajustons Gemma 4 !

Vous pouvez désormais ajuster finement les parties vision et texte via la sélection - la partie audio peut aussi être ajustée finement - nous travaillons à la rendre sélectionnable également !

Nous ajoutons maintenant des adaptateurs LoRA afin de n'avoir à mettre à jour qu'une petite quantité de paramètres !
"""

model = FastModel.get_peft_model(
    model,
    finetune_vision_layers     = False, # Désactivez pour seulement le texte !
    finetune_language_layers   = True,  # Devrait rester activé !
    finetune_attention_modules = True,  # L'attention est bonne pour GRPO
    finetune_mlp_modules       = True,  # Devrait toujours rester activé !

    r = 8,           # Plus grand = meilleure précision, mais risque de surapprentissage
    lora_alpha = 8,  # alpha recommandé égal à r au minimum
    lora_dropout = 0,
    bias = "none",
    random_state = 3407,
)

"""<a name="Data"></a>
### Préparation des données
Nous utilisons maintenant le format `Gemma-4` pour les ajustements fins de type conversation. Nous utilisons le jeu de données [FineTome-100k de Maxime Labonne](https://huggingface.co/datasets/mlabonne/FineTome-100k) au format ShareGPT. Gemma-4 affiche des conversations à plusieurs tours comme ci-dessous :

```
<bos><|turn>user
Bonjour<turn|>
<|turn>model
Salut !<turn|>
```
Nous utilisons notre fonction `get_chat_template` pour obtenir le bon modèle de chat. Nous prenons en charge `zephyr, chatml, mistral, llama, alpaca, vicuna, vicuna_old, phi3, llama3, phi4, qwen2.5, gemma3, gemma-4` et plus encore.
"""

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

"""Nous récupérons les 3000 premières lignes du jeu de données"""

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

"""Nous utilisons maintenant `standardize_data_formats` pour essayer de convertir les jeux de données au bon format à des fins d'ajustement fin !"""

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

"""Voyons à quoi ressemble la ligne 100 !"""

dataset[100]

"""Nous devons maintenant appliquer le modèle de chat `Gemma-3` aux conversations, et l'enregistrer dans `text`. Nous supprimons le jeton `<bos>` en utilisant removeprefix(`'<bos>'`) puisque nous effectuons un ajustement fin. Le processeur ajoutera ce jeton avant l'entraînement et le modèle n'en attend qu'un seul."""

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)

"""Voyons maintenant ce que donne le modèle de chat ! Remarquez qu'il n'y a pas de jeton `<bos>` car le tokenizer du processeur en ajoutera un."""

dataset[100]["text"]

"""<a name="Train"></a>
### Entraîner le modèle
Maintenant, entraînons notre modèle. Nous effectuons 60 étapes pour aller plus vite, mais vous pouvez définir `num_train_epochs=1` pour une exécution complète, et désactiver `max_steps=None`.
"""

from trl import SFTTrainer, SFTConfig
trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = dataset,
    eval_dataset = None, # Peut être configuré pour l'évaluation !
    args = SFTConfig(
        dataset_text_field = "text",
        per_device_train_batch_size = 1,
        gradient_accumulation_steps = 4, # Utilisez l'accumulation de gradients pour imiter la taille du lot !
        warmup_steps = 5,
        # num_train_epochs = 1, # Définissez ceci pour un entraînement complet en une seule exécution.
        max_steps = 60,
        learning_rate = 2e-4, # Réduisez à 2e-5 pour les longues exécutions d'entraînement
        logging_steps = 1,
        optim = "adamw_8bit",
        weight_decay = 0.001,
        lr_scheduler_type = "linear",
        seed = 3407,
        report_to = "none", # Utilisez TrackIO/WandB etc.
    ),
)

"""Nous utilisons aussi la méthode `train_on_completions` d'Unsloth pour n'entraîner que sur les sorties de l'assistant et ignorer la perte sur les entrées de l'utilisateur. Cela aide à augmenter la précision des ajustements fins !"""

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",
)

"""Vérifions que le masquage de la partie instruction est effectué ! Réimprimons la 100e ligne. Remarquez que l'échantillon n'a bien qu'un seul `<bos>` comme prévu !"""

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

"""Imprimons maintenant l'exemple masqué - vous devriez voir uniquement la réponse :"""

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

"""# Entraînons le modèle !

Pour reprendre une exécution d'entraînement, définissez `trainer.train(resume_from_checkpoint = True)`
"""

trainer_stats = trainer.train()
````

{% endcode %}

{% hint style="info" %}
Si vous êtes en OOM :

* Réduisez `per_device_train_batch_size` à **1** et/ou réduisez `max_seq_length`.&#x20;
* Conservez `use_`[`gradient_checkpointing`](/docs/fr/blog/500k-context-length-fine-tuning.md#unsloth-gradient-checkpointing-enhancements)`="unsloth"` activé (il est conçu pour réduire l'utilisation de VRAM et étendre la longueur du contexte).
  {% endhint %}

**Exemple de chargeur pour MoE (LoRA bf16) :**

```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,     # Le QLoRA MoE n'est pas recommandé, le 31B dense va bien
    load_in_16bit = True,     # LoRA bf16/16 bits
    full_finetuning = False,
)
```

Une fois chargé, vous attacherez des adaptateurs LoRA et entraînerez de façon similaire à l'exemple SFT ci-dessus.

### Apprentissage par renforcement (RL)

Vous pouvez maintenant entraîner Gemma 4 avec RL, GSPO, GRPO etc. avec [notre notebook gratuit](https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_5_\(4B\)_Vision_GRPO.ipynb).

{% columns %}
{% column %}
Gemma 4 E2B RL fonctionne sur 9 Go.

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

Le but du notebook est de faire apprendre à Gemma 4 à résoudre des grilles de Sudoku en utilisant [GRPO](/docs/fr/commencer/reinforcement-learning-rl-guide.md#from-rlhf-ppo-to-grpo-and-rlvr).

Le modèle élaborera une stratégie pour remplir les cases vides, et nous le récompenserons pour les placements corrects et pour avoir complété des grilles valides.

Vous pouvez exécuter Gemma 4 RL avec Unsloth même s'il n'est pas pris en charge par vLLM, en définissant `fast_inference=False` lors du chargement du modèle :
{% endcolumn %}

{% column %}

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2Fw08jKlXDLJji37JZPYNx%2Fgemma%204%20rl%20sodoku%20nb.png?alt=media&amp;token=379c607d-60b1-4b35-bcdd-bf6a86911f85" 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,
)
```

### Ajustement fin MoE (26B-A4B)

Le **26B-A4B** est le compromis vitesse / qualité dans la gamme Gemma 4. Comme c'est un **MoE** modèle dont seul un sous-ensemble de paramètres est actif par jeton, une approche d'ajustement fin prudente consiste à :

* utiliser **LoRA** plutôt qu'un fine-tuning complet
* préférer **LoRA 16 bits / bf16** si la mémoire le permet
* commencer d'abord avec des contextes plus courts et des rangs plus petits
* monter en échelle uniquement une fois le pipeline stabilisé

Si votre objectif est la meilleure qualité et que vous disposez de plus de mémoire, utilisez **31B** à la place.

### Ajustement fin multimodal (E2B / E4B)

Parce que **E2B** et **E4B** prennent en charge **image** et **audio**, ce sont les principales variantes Gemma 4 pour l'ajustement fin multimodal.

* chargez le modèle multimodal avec `FastVisionModel`
* conserver `finetune_vision_layers = False` d'abord
* ajustez finement uniquement les couches de langage, d'attention et de MLP
* activez ensuite les couches de vision ou d'audio si votre tâche en a besoin

#### Exemple de LoRA multimodale Gemma 4 :

{% code expandable="true" %}

````python
from unsloth import FastVisionModel # FastLanguageModel pour les LLMs
import torch

model, processor = FastVisionModel.from_pretrained(
    "unsloth/gemma-4-26B-A4B-it",
    load_in_4bit = True, # Utilisez 4 bits pour réduire l'utilisation de la mémoire. False pour LoRA 16 bits.
    use_gradient_checkpointing = "unsloth", # True ou "unsloth" pour les contextes longs
)

"""Nous ajoutons maintenant des adaptateurs LoRA pour un ajustement fin efficace en paramètres, ce qui nous permet d'entraîner efficacement seulement 1 % de tous les paramètres du modèle.

**[NOUVEAU]** Nous prenons également en charge l'ajustement fin uniquement de la composante vision, uniquement de la composante langage, ou des deux. De plus, vous pouvez choisir d'ajuster finement les modules d'attention, les couches MLP, ou les deux !
"""

model = FastVisionModel.get_peft_model(
    model,
    finetune_vision_layers     = True, # False si vous n'ajustez pas finement les couches de vision
    finetune_language_layers   = True, # False si vous n'ajustez pas finement les couches de langage
    finetune_attention_modules = True, # False si vous n'ajustez pas finement les couches d'attention
    finetune_mlp_modules       = True, # False si vous n'ajustez pas finement les couches MLP

    r = 32,                           # Plus il est grand, plus la précision est élevée, mais il peut y avoir surapprentissage
    lora_alpha = 32,                  # Alpha recommandé : au moins égal à r
    lora_dropout = 0,
    bias = "none",
    random_state = 3407,
    use_rslora = False,               # Nous prenons en charge LoRA stabilisée en rang
    loftq_config = None,               # Et LoftQ
    target_modules = "all-linear",    # Optionnel maintenant ! Peut spécifier une liste si nécessaire
)

"""<a name="Data"></a>
### Préparation des données
Nous utiliserons un ensemble de données échantillonné de formules mathématiques manuscrites. L'objectif est de convertir ces images en un format lisible par ordinateur — plus précisément en LaTeX — afin qu'elles puissent être rendues. C'est particulièrement utile pour les expressions complexes.

Vous pouvez accéder à l'ensemble de données [ici](https://huggingface.co/datasets/unsloth/LaTeX_OCR). L'ensemble de données complet est [ici](https://huggingface.co/datasets/linxy/LaTeX_OCR).
"""

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

"""Passons en revue l'ensemble de données. Nous allons examiner la deuxième image et sa légende correspondante."""

dataset

dataset[2]["image"]

dataset[2]["text"]

"""Nous pouvons aussi afficher le LaTeX directement dans le navigateur !"""

from IPython.display import display, Math, Latex

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

"""Pour mettre en forme l'ensemble de données, toutes les tâches d'ajustement fin vision doivent suivre ce format :

```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 = "Écrivez la représentation LaTeX de cette image."

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

"""Convertissons l'ensemble de données au format « correct » pour l'ajustement fin :"""

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

"""Le premier exemple est désormais structuré comme ci-dessous :"""

converted_dataset[0]

"""Prenons le gabarit de chat d'instructions Gemma 4 et utilisons-le dans notre modèle de base"""

from unsloth import get_chat_template

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

"""Avant l'ajustement fin, évaluons les performances du modèle de base. Nous ne nous attendons pas à de très bons résultats, car il n'a pas encore vu ce gabarit de chat."""

image = dataset[2]["image"]
instruction = "Écrivez la représentation LaTeX de cette image."

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)

"""Vous voyez, c'est absolument terrible ! Il ne suit pas du tout les instructions

<a name="Train"></a>
### Entraîner le modèle
Maintenant, entraînons notre modèle. Nous effectuons 60 étapes pour accélérer les choses, mais vous pouvez définir `num_train_epochs=1` pour une exécution complète, et désactiver `max_steps=None`. Nous prenons également en charge `DPOTrainer` et `GRPOTrainer` pour l'apprentissage par renforcement !!

Nous utilisons notre nouveau `UnslothVisionDataCollator` qui nous aidera dans notre configuration d'ajustement fin vision.
"""

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, # Définissez ceci à la place de max_steps pour des entraînements complets
        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", # Pour Weights and Biases ou autres

        # Vous DEVEZ inclure les éléments ci-dessous pour l'ajustement fin vision :
        remove_unused_columns = False,
        dataset_text_field = "",
        dataset_kwargs = {"skip_prepare_dataset": True},
        max_length = 2048,
    )
)

trainer_stats = trainer.train()
````

{% endcode %}

#### Format d'exemple d'image

Rappelez-vous : pour les prompts multimodaux Gemma 4, placez l'image **avant** l'instruction textuelle.

{% code expandable="true" %}

```json
{
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "image", "image": "/path/to/image OU objet"},
        {"type": "text", "text": "Extrayez tout le texte de ce reçu. Retournez les articles, le total, le commerçant et la date sous forme de JSON."}
      ]
    },
    {
      "role": "assistant",
      "content": [
        {"type": "text", "text": "{\"merchant\": \"Exemple de magasin\", \"total\": \"19.99\"}"}
      ]
    }
  ]
}
```

{% endcode %}

#### Format d'exemple audio

L'audio est réservé à **E2B / E4B** uniquement. Gardez les extraits courts et spécifiques à la tâche.

{% code expandable="true" %}

```json
{
  "messages": [
    {
      "role": "user",
      "content": [
        {"type": "audio", "audio": "/path/to/audio OU objet"},
        {"type": "text", "text": "Transcrivez le segment de discours suivant, en anglais, en texte anglais. N'affichez que la transcription."}
      ]
    },
    {
      "role": "assistant",
      "content": [
        {"type": "text", "text": "Bonjour à toutes et à tous et bon retour."}
      ]
    }
  ]
}
```

{% endcode %}

### Sauvegarde / export du modèle ajusté finement

Vous pouvez consulter nos guides spécifiques d'inférence / de déploiement pour [Unsloth Studio](/docs/fr/nouveau/studio/export.md), [llama.cpp](/docs/fr/notions-de-base/inference-and-deployment/saving-to-gguf.md), [vLLM](/docs/fr/notions-de-base/inference-and-deployment/vllm-guide.md), [llama-server](/docs/fr/notions-de-base/inference-and-deployment/llama-server-and-openai-endpoint.md), [Ollama](/docs/fr/notions-de-base/inference-and-deployment/saving-to-ollama.md) ou [SGLang](/docs/fr/notions-de-base/inference-and-deployment/sglang-guide.md).

#### Enregistrer au format GGUF

Unsloth prend en charge l'enregistrement direct au format 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")
```

Ou envoyer les GGUF sur 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")
```

Si le modèle exporté se comporte moins bien dans un autre environnement d'exécution, Unsloth signale la cause la plus fréquente : **mauvais gabarit de chat / jeton EOS au moment de l'inférence** (vous devez utiliser le même gabarit de chat que celui avec lequel vous avez entraîné le modèle).

Pour plus de détails, consultez nos guides d'inférence :

{% columns %}
{% column width="50%" %}
{% content-ref url="/pages/44b6f06033c7dbf3b6521a33337058e295acc604" %}
[Inférence et déploiement](/docs/fr/notions-de-base/inference-and-deployment.md)
{% endcontent-ref %}

{% content-ref url="/pages/0ce33fc68eed069d43cdcfb76b9793ce71c64c1f" %}
[GGUF & llama.cpp](/docs/fr/notions-de-base/inference-and-deployment/saving-to-gguf.md)
{% endcontent-ref %}
{% endcolumn %}

{% column width="50%" %}
{% content-ref url="/pages/817a1275219e1e8d86fe100d223ac4b0862ab3a1" %}
[Model Export](/docs/fr/nouveau/studio/export.md)
{% endcontent-ref %}

{% content-ref url="/pages/682151c53afcf1f6d611eb29ad62b7182b5187ea" %}
[vLLM](/docs/fr/notions-de-base/inference-and-deployment/vllm-guide.md)
{% endcontent-ref %}
{% endcolumn %}
{% endcolumns %}

### Bonnes pratiques de données Gemma 4

Gemma 4 comporte quelques détails de formatage à garder à l'esprit.

#### 1. Utilisez les rôles de chat standards

Gemma 4 utilise les éléments standards :

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

Cela signifie que votre ensemble de données SFT doit être rédigé au format de chat standard plutôt qu'aux anciens formats de rôles spécifiques à Gemma.

#### 2. Le mode de réflexion est explicite

Si vous souhaitez préserver un comportement de type réflexion pendant le SFT :

* gardez le format cohérent
* décidez si vous souhaitez entraîner le modèle sur **des blocs de pensée visibles** ou sur **uniquement les réponses finales**
* faites **ne** mélangez pas plusieurs formats de pensée incompatibles dans le même ensemble de données

Pour la plupart des assistants de production, la configuration la plus simple consiste à ajuster finement sur la **réponse finale visible uniquement**.

#### 3. Règle multi-tour

Pour les conversations à plusieurs tours, ne conservez que la **réponse finale visible** dans l'historique de conversation. Ne **ne** réinjectez pas les blocs de pensée précédents dans les tours suivants.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://unsloth.ai/docs/fr/modeles/gemma-4/train.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
