> 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/blog/3x-faster-training-packing.md).

# Entraînement des LLM 3 fois plus rapide avec les noyaux Unsloth + le packing

Découvrez comment Unsloth augmente le débit d'entraînement et élimine le gaspillage dû au padding pour le fine-tuning.

Unsloth prend désormais en charge jusqu’à **5× plus rapide** (généralement 3x) l’entraînement avec nos nouveaux **kernels Triton RoPE et MLP**, plus notre nouveau packing automatique intelligent. Les nouveaux kernels + fonctionnalités d’Unsloth n’augmentent pas seulement la vitesse d’entraînement, mais réduisent également davantage **l’utilisation de la VRAM (30 % - 90 %)** sans perte de précision. [GitHub d’Unsloth](https://github.com/unslothai/unsloth)\
\
Cela signifie que vous pouvez désormais entraîner des LLM comme [Qwen3](/docs/fr/modeles/tutorials/qwen3-how-to-run-and-fine-tune.md)-4B non seulement sur **3 Go de VRAM**, mais aussi 3x plus rapidement.

Notre [**sans remplissage**](#padding-free-by-default) packing non contaminé est activé intelligemment pour toutes les exécutions d’entraînement sans aucune modification, ainsi que tous les backends d’attention rapides (FlashAttention 3, xFormers, SDPA). [Benchmarks](#analysis-and-benchmarks) montrent que les pertes d’entraînement correspondent aux exécutions sans packing **exactement**.

* **Embedding rotationnel QK 2,3x plus rapide** kernel Triton fusionné avec prise en charge du packing
* Kernels SwiGLU et GeGLU mis à jour avec **un indexage int64 pour les contextes longs**
* **packing non contaminé 2,5x à 5x plus rapide** avec les backends xformers, SDPA, FA3
* **sans remplissage 2,1x plus rapide, 50 % de VRAM en moins**, 0 % de changement de précision
* Unsloth dispose également désormais d’une meilleure stabilité de la perte SFT et d’une utilisation du GPU plus prévisible.
* Cette nouvelle mise à niveau fonctionne **pour toutes les méthodes d’entraînement** par ex. fine-tuning complet, préentraînement, etc.

### :drum:Kernel Triton QK RoPE fusionné avec packing

En décembre 2023, nous avons introduit un kernel RoPE codé en Triton dans le cadre du lancement d’Unsloth. En mars 2024, un membre de la communauté a rendu l’entraînement de bout en bout 1 à 2 % plus rapide en optimisant le kernel RoPE pour permettre de lancer un bloc pour un groupe de têtes. Voir [PR 238](https://github.com/unslothai/unsloth/pull/238).

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FewadBu05vK7zAmJRJcj6%2Frope_varlen_qk_rope_kernel_benchmark_v5.png?alt=media&amp;token=04d277d4-c289-4943-9312-e3d3e2d60bec" alt="" width="563"><figcaption></figcaption></figure>

Un problème est que pour chaque Q et K, il y a 2 kernels Triton. Nous les avons maintenant fusionnés en 1 kernel Triton, et activé RoPE à longueur variable, ce qui était indispensable pour la prise en charge du sans remplissage et du packing. Cela rend le kernel RoPE dans les micro-benchmarks **2,3x plus rapide sur des longueurs de contexte plus longues**, et 1,9x plus rapide sur des longueurs de contexte plus courtes.

Nous avons également éliminé tous les clones et les opérations de transposition contiguë, et donc **RoPE est désormais entièrement en place**, ce qui réduit encore la mémoire GPU. À noter que pour la passe arrière, on observe que `sin1 = -sin1` car :

```
Q * cos + rotate_half(Q) * sin
est équivalent à
Q * cos + Q @ R * sin
où R est une matrice de rotation [ 0,  I]
                             [-I,  0]
dC/dY = dY * cos + dY @ R.T * sin
où R.T est à nouveau le même  [ 0, -I]
mais le signe moins est transposé. [ I,  0]
```

### :railway\_car:Indexage int64 pour les kernels Triton

Lors de l’entraînement de contexte long à 500K que nous avons introduit dans [500K Context Training](/docs/fr/blog/500k-context-length-fine-tuning.md), nous obtenions des erreurs CUDA hors limites. C’était parce que les kernels MLP pour SwiGLU et GeGLU utilisaient un indexage int32, qui est la valeur par défaut dans Triton et CUDA.

Nous ne pouvons pas simplement faire `tl.program_id(0).to(tl.int64)` car l’entraînement sera légèrement plus lent en raison de l’indexage int64. Nous en faisons plutôt un `LONG_INDEXING: tl.constexpr` variable afin que le compilateur Triton puisse le spécialiser. Cela permet aux exécutions de contexte plus courtes et plus longues de toutes très bien fonctionner !

{% code overflow="wrap" %}

```python
block_idx = tl.program_id(0)
if LONG_INDEXING:
    offsets = block_idx.to(tl.int64) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE).to(tl.int64)
    n_elements = tl.cast(n_elements, tl.int64)
else:
    offsets = block_idx * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
```

{% endcode %}

### :abacus:Pourquoi le remplissage est-il nécessaire et gain de vitesse mathématique

Les ordinateurs et les GPU ne peuvent pas traiter des jeux de données de longueurs différentes, nous devons donc les remplir avec des 0. Cela entraîne du gaspillage. Supposons que nous ayons un jeu de données composé à 50 % de séquences courtes S et à 50 % de séquences longues L, alors dans le pire des cas, le remplissage fera que l’utilisation des jetons sera $$\text{batchsize} \times L$$ car la longueur de la séquence la plus longue domine.

En empaquetant plusieurs exemples dans un seul grand tenseur unidimensionnel, nous pouvons éliminer une quantité importante de remplissage. En fait, nous obtenons l’utilisation des jetons ci-dessous :

$$
\text{Token Usage} = \frac{\text{batchsize}}{2}L+\frac{\text{batchsize}}{2}S
$$

Grâce à quelques calculs et à de l’algèbre, nous pouvons déterminer le gain de vitesse via :

$$
\text{Speedup} = \frac{\text{batchsize} \times L}{\frac{\text{batchsize}}{2}L+\frac{\text{batchsize}}{2}S} = 2 \frac{L}{L + S}
$$

En supposant $$S\rightarrow0$$ alors nous obtenons un gain théorique de 2x puisque $$2 \frac{L}{L + 0} = 2$$

En modifiant le ratio à 50 % de séquences courtes, et en supposant que nous ayons PLUS de séquences courtes, par exemple 20 % de séquences longues et 80 % de séquences courtes, nous obtenons $$\frac{L}{0.2L + 0.8S}\rightarrow\frac{L}{0.2L}=5$$ donc un entraînement 5x plus rapide ! Cela signifie que le gain de vitesse du packing dépend du nombre de lignes courtes de votre jeu de données (plus il y en a, plus c’est rapide).

### :clapper:Sans remplissage par défaut

En plus des importants gains de débit disponibles lorsque l’on définit `packing = True` dans votre `SFTConfig` , nous allons **utiliser automatiquement un batching sans remplissage** afin de réduire le gaspillage de remplissage, d’améliorer le débit et d’augmenter le débit en jetons/s, tout en obtenant la ***perte exactement identique*** que dans la version précédente d’Unsloth.

Par exemple, pour Qwen3-8B et Qwen3-32B, on observe une diminution de 60 % de l’utilisation de la mémoire, une vitesse 2x plus rapide, et exactement les mêmes courbes de perte et de norme du gradient !

<div><figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FPATEJoJwIotXNPsYT1hu%2FW%26B%20Chart%2010_12_2025%2C%203_57_51%20am.png?alt=media&amp;token=e31ee2cd-cd6e-4fd2-9c59-7f2148179815" alt=""><figcaption></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FjjnXdgPSgUxL9WNzx9wc%2FW%26B%20Chart%2010_12_2025%2C%203_58_19%20am.png?alt=media&amp;token=54368c73-2ce1-4faa-a1f4-c82341638be3" alt=""><figcaption></figcaption></figure></div>

<div><figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FA61fgCtUj0K9dhrHCt0C%2FW%26B%20Chart%2010_12_2025%2C%203_54_40%20am.png?alt=media&amp;token=b8472635-4b05-430e-9df1-3820ed381c3f" alt="" width="563"><figcaption></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FPh0Xfaup0CTz8REL6P9F%2FW%26B%20Chart%2010_12_2025%2C%203_56_38%20am.png?alt=media&amp;token=86ed33c3-e5ac-4b71-82c3-f8f86ca79862" alt="" width="563"><figcaption></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F6FKM6pkRkQX3gzQLdcIP%2FW%26B%20Chart%2010_12_2025%2C%203_55_38%20am.png?alt=media&amp;token=48d2c1d3-e6f2-420c-8209-70ef247ce63d" alt="" width="563"><figcaption></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FxbhcPeELu78xh3M01xkf%2FW%26B%20Chart%2010_12_2025%2C%203_56_07%20am.png?alt=media&amp;token=375c3f27-5af8-43e5-93eb-3818cb401f95" alt="" width="563"><figcaption></figcaption></figure></div>

### :spades:Packing non contaminé : entraînement 2 à 5x plus rapide

Les jeux de données réels peuvent contenir différentes longueurs de séquence, donc augmenter la taille de lot à 32 par exemple entraînera du remplissage, rendant l’entraînement plus lent et utilisant plus de VRAM.

{% hint style="success" %}
Dans le passé, augmenter `batch_size` à des nombres élevés (>32) rendra l’entraînement PLUS LENT, pas plus rapide. C’était dû au remplissage - nous pouvons désormais éliminer ce problème via `packing = True`, et donc l’entraînement est PLUS RAPIDE !
{% endhint %}

Lorsque nous empaquetons plusieurs échantillons dans un seul tenseur unidimensionnel, nous conservons les métadonnées de longueur de séquence afin de masquer correctement les échantillons, sans fuite d’attention entre les échantillons. Nous avons également besoin du kernel RoPE décrit dans [#fused-qk-rope-triton-kernel-with-packing](#fused-qk-rope-triton-kernel-with-packing "mention") pour permettre la réinitialisation des identifiants de position.

{% columns %}
{% column width="41.66666666666667%" %}

<div align="center" data-full-width="false"><figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F508zS4YN2sYnYjYkt8ej%2Fimage.png?alt=media&amp;token=a05f917a-f593-4abd-a834-2f3f6652ca5a" alt="" width="563"><figcaption><p>4 exemples sans packing gaspillent de l’espace</p></figcaption></figure></div>

{% endcolumn %}

{% column width="58.33333333333333%" %}

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2F8azEy9wbeF2RWSWbNdma%2Fimage.png?alt=media&amp;token=a4b96567-244a-45ed-8b18-b16074bac88c" alt=""><figcaption><p>Le packing non contaminé crée un schéma d’attention correct</p></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

En modifiant le ratio à 50 % de séquences courtes, et en supposant que nous ayons PLUS de séquences courtes, par exemple 20 % de séquences longues et 80 % de séquences longues, nous obtenons $$\frac{L}{0.2L + 0.8S}\rightarrow\frac{L}{0.2L}=5$$ donc un entraînement 5x plus rapide ! Cela signifie que le gain de vitesse du packing dépend du nombre de lignes courtes de votre jeu de données (plus il y en a, plus c’est rapide).

### :beach:Analyse et benchmarks

Pour démontrer les différentes améliorations lors de l’entraînement avec nos nouveaux kernels et des données empaquetées, nous avons exécuté des runs de fine-tuning avec [Qwen3-32B](/docs/fr/modeles/tutorials/qwen3-how-to-run-and-fine-tune.md), Qwen3-8B, Llama 3 8B sur le `yahma/alpaca-cleaned` jeu de données et mesuré divers [perte d’entraînement](#padding-free-by-default) métriques de débit et d’efficacité. Nous avons comparé nos nouveaux runs à un run d’entraînement optimisé standard avec nos propres kernels/optimisations activés et des kernels comme Flash Attention 3 (FA3) activés. Nous avons fixé `max_length = 1024` et fait varier la taille de lot dans {1, 2, 4, 8, 16, 32}. Cela permet au nombre maximal de jetons par lot de varier dans {1024, 2048, 4096, 8192, 16K, 32K}.

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FFfmdok7AmeretPSGlZjg%2Fnew%20rope%20kernel%20graph.png?alt=media&amp;token=d890fd95-c8c0-4817-9ee3-18e3095cde5f" alt="" width="563"><figcaption></figcaption></figure>

Ce qui précède montre comment le débit d’entraînement en jetons par seconde (tokens/s) varie pour le nouvel Unsloth avec une taille de lot variable. Cela se traduit par l’entraînement de votre modèle sur une époque de votre jeu de données **1,7 à 3x plus rapide (parfois même 5x ou plus)**! Ces gains seront plus marqués s’il y a de nombreuses séquences courtes dans vos données et si vous avez des entraînements plus longs, comme décrit dans [#why-is-padding-needed-and-mathematical-speedup](#why-is-padding-needed-and-mathematical-speedup "mention")

<figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FReViERxLWBHnT8GOv0ql%2Fpacking_efficiency_by_per_device_train_batch_size.png?alt=media&amp;token=1c4a78c7-a611-4374-ac03-94aabb1d3184" alt="" width="563"><figcaption></figcaption></figure>

Ce qui précède montre le pourcentage moyen de jetons valides par lot (c.-à-d. non remplis). À mesure que la longueur de la taille de lot augmente, beaucoup plus de jetons de remplissage apparaissent dans le cas non empaqueté, tandis que nous obtenons une efficacité de packing élevée dans le cas empaqueté, quelle que soit la longueur maximale de séquence.

Notez que, puisque la logique de batching tronque les lots à la longueur maximale de séquence observée dans le lot, lorsque la taille de lot est 1, les données non empaquetées sont entièrement composées de jetons valides (c.-à-d. sans remplissage). Cependant, à mesure que davantage d’exemples sont ajoutés au lot, le remplissage augmente en moyenne, atteignant près de 50 % de remplissage avec une taille de lot de 8 ! Notre implémentation d’empaquetage d’échantillons élimine ce gaspillage.

<div><figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FRfzNZVz9uzDPhEe3frGe%2Funknown.png?alt=media&amp;token=e9fe893e-6b94-4c0d-b144-ef8315067c1e" alt="" width="563"><figcaption></figcaption></figure> <figure><img src="https://550366147-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FxhOjnexMCB3dmuQFQ2Zq%2Fuploads%2FTHtcpIdQ0z0mGRYYBfuF%2Funknown.png?alt=media&amp;token=ec52b2c1-1e60-4ed2-969a-d760af26be2a" alt="" width="563"><figcaption></figcaption></figure></div>

Le premier graphique (ci-dessus) trace la progression sur `yahma/alpaca-cleaned` par `max_length = 2048`, le nouvel Unsloth avec packing + kernels (bordeaux) vs. l’ancien Unsloth (gris). Les deux sont entraînés avec `max_steps = 500`, mais nous traçons l’axe des x en temps réel. Notez que nous entraînons près de 40 % d’une époque dans le cas empaqueté avec le même nombre d’étapes (et seulement un peu plus de temps réel) qu’il faut pour entraîner moins de 5 % d’une époque dans le cas non empaqueté.

De même, le deuxième graphique (ci-dessus) trace la perte des mêmes runs, cette fois avec les étapes d’entraînement sur l’axe des x. Notez que les pertes correspondent en échelle et en tendance, mais que la perte dans le cas du packing est moins variable, car le modèle voit davantage de jetons par étape d’entraînement.

### :sparkles:Comment activer le packing ?

**Mettez d’abord Unsloth à jour et le sans remplissage est activé par défaut**! Ainsi, tout l’entraînement est immédiatement 1,1 à 2x plus rapide, avec au moins 30 % d’utilisation mémoire en moins et 0 changement de la métrique de courbe de perte !

{% code overflow="wrap" %}

```bash
pip install --upgrade --force-reinstall --no-cache-dir --no-deps unsloth
pip install --upgrade --force-reinstall --no-cache-dir --no-deps unsloth_zoo
```

{% endcode %}

Nous prenons également en charge Flash Attention 3 via Xformers, la prise en charge de SDPA, Flash Attention 2, et cela fonctionne sur les anciennes GPU (Tesla T4, RTX 2080) et les nouvelles GPU comme les H100, B200, etc. ! L’empaquetage d’échantillons fonctionne *quelle que soit votre choix de backend d’attention ou de famille de modèle*, alors profitez des mêmes gains de vitesse qu’avec ces implémentations d’attention rapides !

Si vous souhaitez activer un packing explicite, ajoutez alors `packing = True` pour activer un entraînement jusqu’à 5x plus rapide !

{% hint style="warning" %}
Remarque `packing=True` modifiera la perte d’entraînement et tronquera le nombre de lignes du jeu de données, puisque plusieurs séquences courtes sont empaquetées en 1 séquence. Vous pourriez voir le nombre d’exemples dans le jeu de données diminuer.

Pour ne pas obtenir des valeurs de perte d’entraînement différentes, définissez simplement `packing=False` et nous activerons le sans remplissage automatique, ce qui accélère déjà l’entraînement !
{% endhint %}

```python
from unsloth import FastLanguageModel
from trl import SFTTrainer, SFTConfig

model, tokenizer = FastLanguageModel.from_pretrained(
    "unsloth/Qwen3-14B",
)

trainer = SFTTrainer(
    model = model,
    processing_class = tokenizer,
    train_dataset = dataset,
    args = SFTConfig(
        per_device_train_batch_size = 1,
        max_length = 4096,
        …,
        packing = True, # requis pour activer le packing d’échantillons !
    ),
)
trainer.train()
```

Tous nos notebooks sont automatiquement plus rapides (pas besoin de faire quoi que ce soit). Voir [Notebooks Unsloth](/docs/fr/commencer/unsloth-notebooks.md)

{% columns %}
{% column %}
Qwen3 14B plus rapide :

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen3_(14B)-Reasoning-Conversational.ipynb>" %}
{% endcolumn %}

{% column %}
Llama 3.1 Conversational plus rapide :

{% embed url="<https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Llama3.2_(1B_and_3B)-Conversational.ipynb>" %}
{% endcolumn %}
{% endcolumns %}

Merci ! Si cela vous intéresse, consultez notre [500K Context Training](/docs/fr/blog/500k-context-length-fine-tuning.md) blog, [RL économe en mémoire](/docs/fr/commencer/reinforcement-learning-rl-guide/memory-efficient-rl.md) blog et [Long Context gpt-oss](/docs/fr/modeles/gpt-oss-how-to-run-and-fine-tune/long-context-gpt-oss-training.md) blog pour davantage de sujets sur les kernels et les gains de performance !


---

# 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/blog/3x-faster-training-packing.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.
