Guide GPU
CUDA out of memory : causes, correctifs, et quand passer à un GPU avec plus de VRAM
Mis à jour le
Réponse courte
Essaie d’abord de réduire la taille du batch, puis la précision mixte, le gradient checkpointing et la quantification : ces correctifs règlent souvent l’erreur sans changer de carte. Si le modèle ne tient toujours pas, loue plus de VRAM chez GPU Cloud, au Canada : 48 Go dès 0,67 $ CA/h, 80 Go dès 1,81 $ CA/h, 96 Go dès 2,48 $ CA/h.
Ce que veut dire l’erreur
torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate … veut dire que PyTorch demande plus de mémoire que ce qui reste libre sur la carte. Cette mémoire sert aux poids du modèle, aux gradients, à l’état de l’optimiseur et aux activations, qui grandissent avec la taille du batch et la longueur des séquences.
Avant de corriger, mesure : la ligne « pic » montre combien ton entraînement demande vraiment.
import torch
print(torch.cuda.get_device_name(0))
print(f"total : {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")
print(f"pic : {torch.cuda.max_memory_allocated() / 1e9:.1f} GB")
print(torch.cuda.memory_summary(abbreviated=True))Les correctifs, dans l’ordre
1.Réduis la taille du batch
Divise
batch_sizepar deux jusqu’à ce que l’erreur disparaisse. Pour garder le même batch effectif, accumule les gradients sur plusieurs pas.accumulation_steps = 4 # batch effectif = batch_size x 4 optimizer.zero_grad() for step, (inputs, targets) in enumerate(loader): loss = criterion(model(inputs), targets) / accumulation_steps loss.backward() if (step + 1) % accumulation_steps == 0: optimizer.step() optimizer.zero_grad()2.Passe en précision mixte
Les activations en 16 bits prennent environ la moitié de la mémoire du 32 bits.
torch.autocastchoisit la précision opération par opération.import torch # bf16 si la carte le permet, sinon fp16 avec un GradScaler dtype = torch.bfloat16 if torch.cuda.is_bf16_supported() else torch.float16 scaler = torch.amp.GradScaler("cuda", enabled=(dtype == torch.float16)) for inputs, targets in loader: optimizer.zero_grad() with torch.autocast(device_type="cuda", dtype=dtype): loss = criterion(model(inputs), targets) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()3.Active le gradient checkpointing
Les activations intermédiaires sont recalculées pendant la rétropropagation au lieu d’être gardées en mémoire : moins de VRAM, un peu plus de calcul.
# Modèle Hugging Face Transformers model.gradient_checkpointing_enable() # Module PyTorch maison from torch.utils.checkpoint import checkpoint def forward(self, x): x = checkpoint(self.block1, x, use_reentrant=False) return self.block2(x)4.Quantifie le modèle
Pour l’inférence ou un ajustement QLoRA, charger les poids en 4 bits divise leur taille par quatre par rapport au 16 bits.
# pip install transformers accelerate bitsandbytes import torch from transformers import AutoModelForCausalLM, BitsAndBytesConfig quantization = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16, ) model = AutoModelForCausalLM.from_pretrained( "Qwen/Qwen2.5-7B-Instruct", quantization_config=quantization, device_map="auto", )5.En inférence, coupe le calcul des gradients
Sans
torch.inference_mode(), PyTorch garde ce qu’il faut pour une rétropropagation qui n’arrivera jamais.model.eval() with torch.inference_mode(): outputs = model(inputs)6.Limite la fragmentation
Si le message indique beaucoup de mémoire « reserved but unallocated », laisse l’allocateur agrandir ses segments.
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True python train.py
Combien de VRAM prennent les poids d’un modèle
| Taille du modèle | 16 bits (fp16, bf16) | 8 bits | 4 bits |
|---|---|---|---|
| 7 milliards de paramètres | 14 Go | 7 Go | 3,5 Go |
| 8 milliards de paramètres | 16 Go | 8 Go | 4 Go |
| 13 milliards de paramètres | 26 Go | 13 Go | 6,5 Go |
| 34 milliards de paramètres | 68 Go | 34 Go | 17 Go |
| 70 milliards de paramètres | 140 Go | 70 Go | 35 Go |
Calcul : nombre de paramètres × octets par paramètre. C’est un minimum : les activations, le cache KV, les gradients et l’état de l’optimiseur s’y ajoutent, et un entraînement complet demande plusieurs fois la taille des poids.
Exemple : un modèle de 7 milliards de paramètres occupe 14 Go en 16 bits, 7 Go en 8 bits et 3,5 Go en 4 bits, avant les activations et le reste.
Quand passer à un GPU avec plus de VRAM
Si ton modèle ne tient toujours pas après ces correctifs, ou si la quantification dégrade trop les résultats, il te faut plus de mémoire. Chez GPU Cloud, la plus petite carte a 48 Go, et un serveur peut aller jusqu’à 8 GPU, soit 768 Go au total (8 × NVIDIA RTX PRO 6000).
| Mémoire par GPU | GPU | À la demande, par heure | Spot, par heure |
|---|---|---|---|
| 48 Go | NVIDIA RTX A6000 | 0,67 $ | 0,54 $ |
| 48 Go | NVIDIA L40 | 1,34 $ | 1,07 $ |
| 80 Go | NVIDIA A100 PCIe | 1,81 $ | 1,45 $ |
| 80 Go | NVIDIA H100 PCIe | 3,35 $ | 2,68 $ |
| 96 Go | NVIDIA RTX PRO 6000 | 2,48 $ | 1,98 $ |
Prix en dollars canadiens, taxes en sus, lus dans le catalogue au moment de la publication de la page.
Avec plusieurs GPU, le modèle doit être réparti entre les cartes (par exemple device_map="auto" avec Transformers, ou FSDP pour l’entraînement). Le guide pour lancer ton script sur un GPU montre comment copier ton projet et lancer l’entraînement sur le serveur.
Ce qu’il faut savoir avant de lancer
- La facturation se fait à l’heure, au tarif horaire du serveur, à partir d’un crédit prépayé. Il n’y a pas de facturation à la minute, et la première heure est prélevée au déploiement.
- Un serveur arrêté reste facturé au plein tarif horaire. Pour payer moins, hiberne-le (0,02 $ par heure (environ 14,60 $ par mois), disque conservé) ou supprime-le. Une machine Spot ne s’hiberne pas : supprime-la quand tu as fini.
- La recharge minimale est de 25,00 $ CA, payée par carte de crédit.
- Les serveurs et leurs disques restent au Canada (région canada-montreal, à Montréal). Les renseignements du compte (identité, facturation, courriels) peuvent être traités hors du Québec, comme l’explique la politique de confidentialité.
Questions fréquentes
Pourquoi CUDA out of memory alors que nvidia-smi montre de la mémoire libre ?
PyTorch garde en réserve la mémoire qu’il a déjà allouée, et cette réserve peut être fragmentée : une grosse demande échoue même s’il reste de petits blocs libres. Un autre processus peut aussi occuper la carte. expandable_segments:True limite la fragmentation.
Est-ce que torch.cuda.empty_cache() règle l’erreur ?
Rarement. Il rend au système la mémoire en réserve que plus aucun tenseur n’utilise, mais il ne libère pas les tenseurs encore référencés par ton code.
Combien de VRAM faut-il pour un modèle de 7 milliards de paramètres ?
Les poids seuls occupent 14 Go en 16 bits, 7 Go en 8 bits et 3,5 Go en 4 bits. Il faut ajouter les activations et le cache KV en inférence, et les gradients et l’état de l’optimiseur en entraînement.
Quelle est la plus grande quantité de VRAM disponible chez GPU Cloud ?
Par GPU, 96 Go. Par serveur, jusqu’à 8 GPU, soit 768 Go au total (8 × NVIDIA RTX PRO 6000).
Combien coûte une heure avec plus de VRAM ?
48 Go : dès 0,67 $ CA/h ; 80 Go : dès 1,81 $ CA/h ; 96 Go : dès 2,48 $ CA/h, en dollars canadiens, taxes en sus, facturé à l’heure sans engagement.
Tu veux du GPU ? On est là.
Lance un serveur GPU NVIDIA à l’heure au Canada, payé en dollars canadiens par carte de crédit, ou réserve un GPU pour une date précise.
Autres guides
- Ton IA te dit qu’il te faut un GPU ? Lance ton script Python sur un GPU en quelques minutes
- torch.cuda.is_available() renvoie False : causes et correctifs (Mac, PC sans NVIDIA, Docker)
- Combien coûte un GPU à l’heure au Canada, en dollars canadiens ?
- API OpenAI trop chère ? Héberge ton LLM sur un GPU à l’heure, au Canada
- Louer un GPU à l’heure au Canada : prix, étapes et facturation
- GPU cloud à Montréal, au Canada : serveurs GPU NVIDIA hébergés au pays
- Louer une H100 au Canada : PCIe, NVLink ou SXM, à l’heure
- Quel GPU pour fine-tuner un LLM ? Mémoire, machine et coût
- GPU cloud pas cher : comment payer le moins possible pour un GPU