RL économe en mémoire
Nous sommes ravis de présenter un apprentissage par renforcement (RL) plus efficace dans Unsloth grâce à plusieurs avancées algorithmiques :
longueurs de contexte multipliées par 1,2 à 1,7 sans ralentissement et sans consommation de mémoire supplémentaire !
exécutions d’entraînement RL 10 % plus rapides avec des kernels remaniés et des transferts de données asynchrones
2x plus rapide
torch.compilefois lors du chargement du modèle
Unsloth déjà augmente la vitesse d’entraînement RL, la fenêtre de contexte et réduit l’utilisation de VRAM de 50 à 90 % par rapport à toutes les autres configurations avec FA2, mais maintenant la veille d’Unsloth améliore encore davantage cela. Notre fonctionnalité Standby limite de manière unique la dégradation des performances par rapport aux autres implémentations et rend parfois l’entraînement encore plus rapide !
Désormais, le LoRA 16 bits de Qwen3-32B peut atteindre des longueurs de contexte de 6 144 contre 3 600 (1,7x plus long) auparavant sur un GPU 1xH100 80 Go. Le QLoRA 4 bits de Llama-3.1-8B peut atteindre 47 500 longueurs contre 42 000 auparavant (1,13x plus long).
Nous avons rendu les exécutions RL 10 % plus rapides grâce à diverses optimisations de kernels, et supprimé le canal de communication LoRA entre le CPU et le GPU lors du passage du mode entraînement au mode inférence. Enfin, nous avons utilisé des torch.compile indicateurs personnalisés pour accélérer de 10 % le rollout de vLLM, et réduit le temps de compilation d’un facteur 2.
✨Comment activer les optimisations
Pour activer la veille d’Unsloth fonctionnalité, définissez la variable d’environnement UNSLOTH_VLLM_STANDBY avant toute importation d’Unsloth. Puis définissez gpu_memory_utilization = 0.95 et c’est tout !
import os
os.environ["UNSLOTH_VLLM_STANDBY"] = "1"
from unsloth import FastLanguageModel
import torch
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/Qwen3-8B-Base",
max_seq_length = 2048, # Peut être augmenté pour des traces de raisonnement plus longues
load_in_4bit = False, # False pour LoRA 16 bits
fast_inference = True,
max_lora_rank = 32, # Rang plus élevé = plus intelligent, mais plus lent
gpu_memory_utilization = 0.95,
)🎓Plus besoin de gpu_memory_utilization!
Avec les nouvelles améliorations RL d’Unsloth, vous n’avez JAMAIS à vous soucier d’ajuster ou de définir gpu_memory_utilization à nouveau — il suffit de le régler à 90 % ou 95 % d’utilisation du GPU - 100 % ne fonctionnera malheureusement pas, car un peu d’espace est nécessaire pour de petits tenseurs. Auparavant, il fallait l’ajuster de 30 % à 95 % - ce n’est plus nécessaire maintenant ! Réglez-le au maximum et Unsloth s’occupe du reste !
⁉️Pourquoi le RL utilise-t-il autant de mémoire ?
GRPO (et de nombreuses variantes de RL) s’appuie fortement sur la génération, principalement assurée par vLLM. Mais cela a un coût élevé, car cela nécessite en permanence de la mémoire GPU pour les poids, les activations et le KV Cache.
L’inférence consomme beaucoup de VRAM

Alors que l’entraînement utilise aussi de la VRAM !

Cela signifie que le RL doit conserver 2 ensembles de VRAM / mémoire sur le GPU en même temps :
Moteur d’inférence (contient les poids du modèle, le KV cache)
Moteur d’entraînement (contient les poids du modèle, les activations, les gradients, les états de l’optimiseur)
Les frameworks RL actuels doivent répartir 50/50 sur un GPU de 80 Go, avec 50 % pour l’inférence et 50 % pour l’entraînement. Et déplacer les poids du mode entraînement au mode inférence peut prendre un certain temps.
Poids du modèle
16 Go
16 Go
KV Cache
24 Go
Activations, gradients, états de l’optimiseur
24 Go
Les anciennes versions d’Unsloth optimisent déjà intelligemment ce qui précède, car nous partageons directement l’espace mémoire des poids de vLLM, ce qui supprime la double utilisation mémoire des poids du modèle. Cela libère par exemple 16 Go d’espace qui peuvent être utilisés pour augmenter la longueur du contexte ou la vitesse de génération. De plus, nous n’avons pas besoin d’effectuer de transferts de mémoire, ce qui accélère l’entraînement.
Poids du modèle
16 Go PARTAGÉS
<<< PARTAGÉ
KV Cache
24 Go + 8 Go = 32 Go
Activations, gradients, états de l’optimiseur
24 Go + 8 Go =32 Go
🦥Veille Unsloth
Mais nous pouvons aller plus loin — nous notons d’abord que le RL fait de l’inférence puis de l’entraînement puis de l’inférence puis de l’entraînement, etc.

Cela signifie que l’espace mémoire pour l’inférence et l’entraînement peut en théorie être réutilisé, puisque l’inférence et l’entraînement sont des modes séparés — c’est là qu’intervient la fonctionnalité de mode veille de vLLM qui propose 2 options :
niveau = 1copie les poids vers le CPU et supprime le KV cacheniveau = 2supprime les poids et supprime le KV cache
Mais rappelons qu’avec Unsloth, nous partageons l’espace mémoire de vLLM pour les poids — cela signifie que nous devons trouver une nouvelle façon de supprimer le KV cache, tout en ignorant la suppression des poids, et nous appelons cela la veille Unsloth.
Poids du modèle
16 Go PARTAGÉS
<<< PARTAGÉ
Polyvalent
64 Go d’espace
KV Cache
Activations, gradients, états de l’optimiseur
Pour activer cela, ajoutez simplement ce qui suit à toutes les exécutions d’entraînement RL / GRPO avant toute importation d’Unsloth :
🧪Expériences de performance
Vous trouverez ici comment nous avons mesuré la consommation mémoire et la longueur de contexte pour GRPO. Notez que nous effectuons 2 générations par invite, car pour que GRPO fonctionne, nous avons besoin d’au moins 2 générations pour calculer la moyenne et la variance de l’échantillon. Sans 2 générations, l’écart-type d’un échantillon est 0. Cela rend les avantages qui utilisent ceci : (récompense - moyenne)/écart-type indéfinis.
Cela signifie que, spécifiquement pour GRPO, une longueur de contexte maximale de 6 144 pour Qwen-3 32B correspond en réalité à 6 144 multiplié par 2 générations, soit 12 288 en longueur.
Nous fournissons ci-dessous des expériences pour Llama-3.1 8B à la fois en LoRA (16 bits) et en QLoRA (4 bits) :

Si vous remarquez des différences de temps d’entraînement, elles ne sont pas importantes. Dans notre comparaison à paramètres équivalents, nous avons observé des ralentissements de moins de 1 % du temps d’entraînement, voire des accélérations, ce qui peut être attribué à la marge d’erreur.
Nous pensons également que des accélérations sont possibles grâce à une pression mémoire réduite, ce qui pourrait entraîner moins de nettoyage mémoire côté allocateur mémoire CUDA.

Dans l’image ci-dessus, vous voyez la différence entre la version de base et le mode standby sur un seul GPU T4 pour Qwen 3 4B. Nous pouvons pousser l’ gpu_memory_utilisation de vLLM jusqu’à 0,95 sans craindre que cela affecte l’entraînement. Cela signifie que vous pouvez intégrer des séquences de plus grande longueur de contexte et traiter davantage de séquences. Dans le premier cas, par exemple, nous disposons de suffisamment de mémoire pour intégrer et traiter des séquences de 32K, à condition que l’entraînement le permette, alors qu’auparavant, toute entrée de plus de 2K risquait de ne pas tenir et de provoquer des OOM (out of memory).
standby True
vllm_gpu_util 0.95
num_gen 2
grad_acc_steps 2
Fonctionne pendant 40 étapes / 40 minutes
14,5 Gio (défini par vllm_gpu_util)
Assez pour intégrer un KVCache de 32K avec un bloc de 2 à 4K ou, par exemple, un KVCache de 16K + des blocs de 16K
standby True
vllm_gpu_util 0.9
num_gen 2
grad_acc_steps 2
Fonctionne pendant 32 étapes en 40 min
13,8 Gio (défini par…)
Suffisant approximativement pour intégrer un KVCache d’environ 28K avec un bloc de 2 à 4K ou, par exemple, un KVCache de 15K + des blocs de 15K
standby False
vllm_gpu_util 0.9
num_gen 2
grad_acc_steps 2
le modèle se charge mais ne peut pas s’entraîner car même un batch size de 1 ne tient pas
OOM
standby False
vllm_gpu_util 0.8
num_gen 2
grad_acc_steps 2
le modèle se charge mais ne peut pas s’entraîner car même un batch size de 1 ne tient pas
OOM
standby False
vllm_gpu_util 0.7
num_gen 2
grad_acc_steps 2
S’entraîne correctement
28 étapes prennent 39 min
~15,1 Gio
toute entrée légèrement plus longue entraînera un OOM sur colab
standby True
vllm_gpu_util 0.7
num_gen 2
grad_acc_steps 2
S’entraîne correctement
29 étapes prennent 40 min
13 Gio mais la plupart du temps autour de 10 à 11 Go
Avec la même configuration, nous économisons ici 2 Gio, soit 15 % de mémoire. Peut être plus élevé pour des séquences plus longues
Expériences H100
Qwen2.5-14B-Instruct
NVIDIA H100 80GB PCIe
32,768
8
4
Dans nos résultats repliables ci-dessous, vous pouvez voir qu’il y a une différence de 9 Gio dans la mémoire de pointe utilisée (notez que 90 % du temps, l’utilisation de la mémoire GPU est, dans notre cas, égale à la mémoire de pointe). Pour donner un ordre de grandeur, avec TRL et LoRA nous n’avons pu affiner qu’un modèle de 8 milliards de paramètres avec une longueur de contexte maximale de 1024 (32x moins). Tout ce qui a une longueur de séquence plus élevée (avec une configuration similaire) entraîne l’échec du processus avec OOM.
L’image ci-dessous montre comment le mode veille se compare à l’entraînement sans veille avec Unsloth. Les résultats sont moyennés sur 3 exécutions afin de s’assurer que les métriques ne sont pas bruitées. En fait, si vous zoomez suffisamment, vous verrez que l’activation du mode veille le rend également plus rapide, probablement en raison d’une pression mémoire plus faible comme discuté précédemment.

Expériences précédentes sur A100 40 Go
Dans nos expériences précédentes sur un GPU A100 40 Go avec Qwen-2.5-3b-instruct et 8 générations par échantillon, nous avons observé que sans veille, l’entraînement GRPO (modèle chargé en 16 bits, LoRA, seuls les poids entraînables), nous ne pouvions faire tenir que des longueurs de séquence de 6K. Avec notre fonctionnalité de veille, nous avons pu faire tenir 10K et au-delà ! À titre de comparaison, TRL ne peut vous offrir que des longueurs de contexte allant jusqu’à 1K tout en conservant la même taille de lot.

🎉Autres optimisations
Nous choisissons désormais de meilleurs indicateurs de compilation et réduisons les temps de compilation de 50 % ou plus. Nous avons également réussi à corriger dynamiquement toute version de vLLM pour gérer gc.collect mieux, pour des raisons de compatibilité ascendante, en nous inspirant de cette pull request vLLM. Cela réduit les temps de compilation de 2 minutes à moins de 40 secondes.
Nous avons également optimisé torch.compile les indicateurs et essayé d’activer certains indicateurs - malheureusement combo_kernels et multi_kernel n’a pas pu fonctionner correctement sur vLLM 0.10 et Torch 2.8/2.9 nightly et coordinate_descent_tuning a rendu l’autotuning de tous les kernels considérablement plus lent. La compilation prenait auparavant moins d’une minute, mais l’activer prenait plus de 13 minutes, voire davantage, avec des gains de performance minimes.
📚Notebooks GRPO
Tous nos notebooks GRPO ont Unsloth Standby activé par défaut ainsi que toutes les optimisations ! Voir https://docs.unsloth.ai/get-started/unsloth-notebooks pour tous nos notebooks GRPO, ou essayez ceux ci-dessous :
Qwen3 (4B) - LoRA GRPO avancé
DeepSeek-R1-0528-Qwen3 (8B) (pour des cas d’usage multilingues)
Llama 3.2 (3B) - LoRA GRPO avancé
Mis à jour
Ce contenu vous a-t-il été utile ?

