Au cœur de cuda-convnet : les couches d'AlexNet sur deux GPU et l'ère ImageNet

Le jalon posé par AlexNet en 2012 reposait sur une ingénierie GPU de bas niveau (cuda-convnet) et une architecture répartie sur deux GPU. Il a directement déclenché une course rapide vers des modèles de vision par ordinateur plus profonds et plus efficaces.
1. Le fonctionnement interne de cuda-convnet
Avant que NVIDIA ne crée cuDNN, Alex Krizhevsky a écrit cuda-convnet directement en CUDA C++ pour tirer une vitesse maximale des premiers GPU à architecture Fermi (les GTX 580). Les bibliothèques modernes déploient généralement les convolutions en gigantesques multiplications matricielles (im2col), ce qui consomme énormément de mémoire. Chaque GTX 580 ne disposant que de 3 Go de VRAM, Krizhevsky a conçu des routines GPU directes économes en mémoire.
- Disposition mémoire privilégiant le lot (CHWN). Les frameworks modernes utilisent par défaut NCHW (lot, canaux, hauteur, largeur), qui place tous les pixels d'une même image côte à côte en mémoire. Krizhevsky stockait les tenseurs dans l'ordre CHWN, en plaçant la dimension du lot (N) en dernier. Lorsque les 32 threads GPU d'un warp traitaient 32 images différentes exactement au même emplacement de pixel, leurs lectures mémoire étaient entièrement contiguës (coalescentes), maximisant la bande passante de la VRAM.
- Découpage en tuiles dans la mémoire partagée. Une lecture dans la VRAM globale prend des centaines de cycles d'horloge, contre quelques cycles seulement pour la mémoire partagée sur puce (seulement 48 Ko par Streaming Multiprocessor sur le GTX 580). Les blocs de threads chargeaient de petites zones 2D de pixels et des poids de filtres dans la mémoire partagée, puis calculaient des dizaines de produits scalaires avant de réécrire les résultats finaux dans la VRAM.
- Réutilisation des registres au niveau du warp. Krizhevsky attribuait à chaque bloc de threads le calcul d'une tuile de pixels de sortie pour plusieurs filtres simultanément. En conservant les poids des filtres dans les registres rapides du GPU, une même zone d'image chargée depuis la mémoire partagée était réutilisée pour de nombreux filtres à la fois, réduisant considérablement le trafic mémoire.
2. Les couches d'AlexNet et leur répartition sur deux GPU
AlexNet contenait 8 couches apprises (5 convolutives et 3 entièrement connectées), totalisant environ 60 millions de paramètres. Comme un seul GTX 580 ne disposait pas des plus de 3 Go de VRAM nécessaires aux activations, aux poids et aux gradients, Krizhevsky a divisé le réseau verticalement en deux flux parallèles.
| Couche | Type | Nombre total de filtres / neurones | Répartition par GPU | Communication entre GPU |
|---|---|---|---|---|
| Entrée | Image RVB | 224 × 224 × 3 | Copiée sur les deux GPU | Aucune |
| Conv 1 | Conv 11×11 (pas 4) + MaxPool | 96 filtres | 48 filtres par GPU | Isolée (sans synchronisation) |
| Conv 2 | Conv 5×5 + MaxPool | 256 filtres | 128 filtres par GPU | Isolée (lit uniquement Conv 1 de son propre GPU) |
| Conv 3 | Conv 3×3 | 384 filtres | 192 filtres par GPU | Synchronisation complète (lit les 256 cartes des deux GPU) |
| Conv 4 | Conv 3×3 | 384 filtres | 192 filtres par GPU | Isolée (lit uniquement Conv 3 de son propre GPU) |
| Conv 5 | Conv 3×3 + MaxPool | 256 filtres | 128 filtres par GPU | Isolée (lit uniquement Conv 4 de son propre GPU) |
| FC 6 | Entièrement connectée + Dropout | 4 096 neurones | 2 048 neurones par GPU | Synchronisation complète (connexion à toutes les sorties de Conv 5) |
| FC 7 | Entièrement connectée + Dropout | 4 096 neurones | 2 048 neurones par GPU | Synchronisation complète (connexion à tous les neurones de FC 6) |
| FC 8 | Entièrement connectée (Softmax) | 1 000 classes | 1 000 classes (combinées) | Synchronisation complète (produit les prédictions ImageNet finales) |
- Spécialisation naturelle des caractéristiques. Fait intéressant, comme les couches 1 et 2 ne communiquaient jamais entre GPU, les deux cartes développaient systématiquement des rôles spécialisés. Un GPU apprenait des détecteurs de contours et de textures indépendants de la couleur (filtres en niveaux de gris semblables à ceux de Gabor), tandis que l'autre se spécialisait dans les taches et les teintes propres à certaines couleurs.
- Réduction des goulots d'étranglement PCIe. Le transfert de données sur le bus PCIe de la carte mère était lent. En limitant strictement la communication entre GPU à Conv 3 et aux couches entièrement connectées, Krizhevsky permettait aux GPU de calculer à pleine vitesse sans attendre les transferts de données.
3. La suite de l'ère ImageNet
La victoire d'AlexNet a lancé une course annuelle lors de la compétition ImageNet, faisant passer les réseaux de 8 couches à plus de 150 en seulement trois ans.
- 2013 - ZFNet (visualisation et ajustement). Matthew Zeiler et Rob Fergus ont introduit des techniques de déconvolution pour visualiser ce qu'AlexNet voyait réellement dans ses couches cachées. En ramenant la taille des filtres de la première couche d'AlexNet de 11×11 à 7×7 et en réduisant le pas, ZFNet a abaissé le taux d'erreur top-5 sur ImageNet de 15,3 % à 14,8 %.
- 2014 - VGGNet (la profondeur grâce à des filtres 3×3 uniformes). Des chercheurs d'Oxford ont démontré qu'empiler de nombreuses petites convolutions 3×3 (jusqu'à 16 ou 19 couches) fonctionnait mieux qu'utiliser de grands filtres isolés (comme 11×11 ou 5×5). Deux couches 3×3 empilées couvrent la même zone de vision 5×5 avec moins de paramètres et des activations ReLU non linéaires supplémentaires, faisant chuter les taux d'erreur à 7,3 %.
- 2014 - GoogLeNet / Inception (efficacité multi-échelle). Google a introduit le module Inception, qui exécutait des convolutions 1×1, 3×3 et 5×5 en parallèle dans une même couche et fusionnait les sorties. En utilisant des convolutions 1×1 peu coûteuses pour réduire la profondeur des canaux avant les calculs coûteux, GoogLeNet atteignait 22 couches et un taux d'erreur de 6,7 % avec 12 fois moins de paramètres qu'AlexNet.
- 2015 - ResNet (connexions de saut et 152 couches). Le simple empilement de couches supplémentaires finissait par dégrader la précision de l'entraînement, car les gradients disparaissaient pendant la rétropropagation. Microsoft Research a résolu ce problème grâce aux connexions résiduelles (connexions de saut), permettant aux données de contourner des couches par des raccourcis d'identité directs. Cela a rendu possibles des réseaux de 152 couches, avec un taux d'erreur top-5 de 3,57 %, dépassant pour la première fois les performances humaines sur ce test de référence (~5 %).