3 · Données et bases de données¶
Le domaine où le GPU gagne le plus spectaculairement et échoue le plus discrètement, pour la même raison : la capacité mémoire.
3.1 Pourquoi ça marche¶
Les opérations analytiques de base sont massivement parallèles :
| Opération SQL | Primitive GPU |
|---|---|
WHERE (filtrage) |
prédicat + compaction de flux (scan) |
GROUP BY |
tri ou table de hachage |
SUM, AVG, COUNT |
réduction segmentée |
ORDER BY |
tri par base |
JOIN |
jointure par hachage ou par tri-fusion |
Toutes reposent sur les primitives de la partie 2 : réduction, scan, tri. Et toutes sont limitées par la bande passante mémoire, ce qui joue en faveur du GPU : 3,35 To/s sur H100 contre ~400 Go/s pour un nœud CPU bi-socket.
Un tri par base sur GPU (cub::DeviceRadixSort) atteint la bande passante
mémoire. Un GROUP BY sur un milliard de lignes prend moins d'une seconde.
3.2 RAPIDS¶
La suite NVIDIA d'analyse de données GPU.
import cudf
df = cudf.read_parquet("evenements.parquet") # lecture directe sur GPU
resultat = (df[df["montant"] > 100]
.groupby("client")
.agg({"montant": "sum", "id": "count"})
.sort_values("montant", ascending=False))
L'API reproduit celle de pandas. Depuis 2023, cudf.pandas accélère du code
pandas existant sans modification :
%load_ext cudf.pandas # dans un notebook
import pandas as pd # ← devient cudf sous le capot, avec repli CPU
Les autres composants :
| Composant | Équivalent |
|---|---|
| cuDF | pandas |
| cuML | scikit-learn (forêts, k-means, PCA, régressions, UMAP) |
| cuGraph | NetworkX (PageRank, composantes, plus courts chemins) |
| cuSpatial | GeoPandas |
| cuVS | recherche vectorielle (CAGRA, IVF-PQ, IVF-Flat) |
Accélérations typiques : 10× à 50× sur les jointures et agrégations de volumes importants.
3.3 La contrainte qui domine tout¶
La capacité mémoire est le mur
Un H100 a 80 Go, un B200 192 Go, un MI355X 288 Go. Un serveur d'analyse a couramment 1 à 4 To de RAM.
Si vos données ne tiennent pas en VRAM, tout change : il faut découper, diffuser en flux, ou passer par la mémoire unifiée — et le PCIe (64 Go/s) devient le goulot, soit 52 fois moins que la HBM.
Les réponses possibles :
1. Traitement en flux par morceaux. Découper le fichier, traiter morceau par morceau, agréger. Fonctionne pour les agrégations, mal pour les jointures qui ont besoin de vues globales.
2. Multi-GPU. Dask-cuDF distribue sur plusieurs cartes. 8 × 80 Go = 640 Go utilisables, avec le coût de la communication.
3. GPUDirect Storage. Lecture directe du NVMe vers la VRAM sans passer par la RAM du CPU. Élimine une copie et le goulot du CPU.
4. Compression. Blackwell embarque un moteur de décompression matériel. Les mesures publiées sur 100 Mo :
| Format | Débit d'entrée | Débit de sortie | Latence |
|---|---|---|---|
| LZ4 | 173,2 Go/s | 172,6 Go/s | 0,608 ms |
| Bitcomp | 154,0 Go/s | 462,4 Go/s | 0,227 ms |
| Zstandard | 77,5 Go/s | 154,9 Go/s | 0,677 ms |
Source : arXiv:2512.02189. Garder les données compressées en VRAM et les décompresser à la volée multiplie la capacité effective — c'est précisément le but de ce moteur.
3.4 Les bases de données GPU¶
Plusieurs systèmes utilisent le GPU comme moteur d'exécution principal :
| Système | Positionnement |
|---|---|
| HeavyDB (ex-OmniSci/MapD) | analytique + géospatial + visualisation |
| BlazingSQL | SQL sur RAPIDS (projet largement absorbé par cuDF) |
| Kinetica | analytique temps réel, géospatial |
| PG-Strom | extension GPU pour PostgreSQL |
| Theseus / Voltron Data | moteur de requêtes distribué GPU, basé sur Arrow |
Ils excellent sur : agrégations sur des milliards de lignes, géospatial, séries temporelles, tableaux de bord interactifs.
Ils sont mauvais sur : transactionnel (OLTP), requêtes très sélectives (peu de lignes retournées), jointures dépassant la VRAM, et tout ce qui manipule intensivement des chaînes de caractères.
Le traitement des chaînes est le point faible structurel
Les chaînes de longueur variable impliquent des accès indirects, de la divergence, et des allocations dynamiques — les trois choses que le GPU fait mal.
cuDF les gère avec une représentation en colonnes (offsets + tampon de caractères, format Arrow), ce qui aide beaucoup. Mais une expression régulière sur un milliard de chaînes reste un cas où le GPU n'a pas d'avance décisive.
3.5 La recherche vectorielle¶
Un cas d'usage devenu majeur avec les systèmes de génération augmentée par récupération (RAG).
Le problème : trouver les \(k\) vecteurs les plus proches d'une requête, parmi des millions ou des milliards, en grande dimension (768 à 4 096).
Pourquoi le GPU convient : c'est un produit matriciel suivi d'une réduction top-\(k\). La recherche exhaustive sur \(N\) vecteurs de dimension \(d\) est une GEMM \(1 \times d \times N\) — exactement ce que fait bien un GPU.
Les index approximatifs :
| Index | Principe | Compromis |
|---|---|---|
| Flat | exhaustif | exact, \(O(N)\) |
| IVF | partition en cellules, ne visiter que les proches | rappel/vitesse |
| IVF-PQ | + quantification par produit | compression 10-50× |
| CAGRA | graphe de proximité, conçu pour GPU | très rapide, mémoire élevée |
| HNSW | graphe hiérarchique | référence CPU, moins adapté GPU |
CAGRA (dans cuVS et FAISS-GPU) mérite l'attention : c'est un index conçu pour le GPU dès le départ, dont le parcours de graphe est structuré pour rester parallèle — contrairement à HNSW, dont le parcours séquentiel est hostile.
C'est encore un exemple du principe : l'algorithme optimal sur CPU n'est pas l'algorithme optimal sur GPU.
3.6 Le format des données¶
Un point souvent négligé et déterminant.
| Format | Adaptation GPU |
|---|---|
| Apache Arrow | excellent — colonnaire, sans copie, c'est le format natif de RAPIDS |
| Parquet | très bon — colonnaire, compressé, lisible directement par cuDF |
| ORC | bon |
| CSV | mauvais — le parsage est séquentiel et irrégulier |
| JSON | mauvais — idem, structure imbriquée |
| Ligne (row-oriented) | mauvais — c'est de l'AoS |
La règle
Colonnaire, toujours. Un format colonnaire est un SoA : chaque colonne est un tableau contigu, donc coalescé. Un format par lignes est un AoS, avec la perte de coalescence correspondante.
Corollaire : si votre pipeline lit du CSV, la conversion en Parquet est souvent l'optimisation la plus rentable — avant même de penser au GPU.
Résumé du chapitre¶
À retenir
- Les opérations analytiques se ramènent aux primitives GPU : réduction, scan, tri. Toutes limitées par la mémoire, où le GPU a 8× d'avance.
- RAPIDS (cuDF, cuML, cuGraph, cuVS) reproduit les APIs pandas et scikit-learn. 10-50× sur les gros volumes.
- La capacité VRAM est le mur. Au-delà, PCIe est 52× plus lent que la HBM.
- Réponses : traitement par morceaux, multi-GPU (Dask), GPUDirect Storage, et le moteur de décompression matériel de Blackwell (LZ4 à 173 Go/s).
- Le traitement de chaînes est le point faible structurel.
- La recherche vectorielle est un bon cas GPU ; CAGRA est un index conçu pour GPU, contrairement à HNSW.
- Format colonnaire obligatoire : Arrow ou Parquet, jamais CSV ni orienté lignes.
Vérifiez que vous avez compris¶
Une jointure entre une table de 500 Go et une de 2 Go, sur un H100 (80 Go). Comment procéder ?
C'est le cas classique de la jointure par diffusion (broadcast join) :
- charger entièrement la petite table (2 Go) en VRAM et y construire une table de hachage ;
- diffuser la grande table par morceaux de ~50 Go, sonder la table de hachage pour chaque morceau, écrire les résultats ;
- agréger.
Le facteur limitant devient le débit de lecture depuis le stockage. GPUDirect Storage est ici essentiel : il évite un aller-retour par la RAM du CPU.
Si les deux tables dépassent la VRAM, il faut partitionner les deux par clé de jointure (shuffle) et traiter partition par partition — beaucoup plus coûteux, et c'est là que le GPU perd souvent son avantage.
Pourquoi HNSW, la référence CPU en recherche vectorielle, est-il mal adapté au GPU ?
Parce que son parcours est séquentiel et dépendant des données : on part d'un point d'entrée, on examine ses voisins, on se déplace vers le meilleur, on recommence. Chaque étape dépend de la précédente.
Sur GPU, cela signifie : aucun parallélisme au sein d'une requête, accès mémoire dispersés, divergence maximale entre requêtes qui prennent des chemins différents.
CAGRA restructure le problème : un graphe de degré fixe, où chaque étape examine tous les voisins d'un ensemble de candidats en parallèle. Le parallélisme est dans la largeur de l'exploration, pas dans le nombre de requêtes.
Votre pipeline cuDF est 3× plus lent que pandas sur un fichier de 200 Mo. Normal ?
Oui, très probablement. 200 Mo est trop petit pour amortir :
- le transfert PCIe (~4 ms) ;
- le lancement des noyaux ;
- l'initialisation du contexte CUDA (plusieurs centaines de millisecondes au premier appel).
Le seuil de rentabilité de RAPIDS se situe généralement autour du gigaoctet, et il monte si le pipeline fait beaucoup d'allers-retours vers le CPU.
Vérifiez aussi qu'aucune opération ne retombe silencieusement sur le CPU —
c'est fréquent avec cudf.pandas, dont le repli est transparent et donc
invisible.
Chapitre suivant : 4 · Signal et image
Sources de ce chapitre¶
- RAPIDS · cuDF · cuVS
- GPUDirect Storage
- Microbenchmarking NVIDIA's Blackwell Architecture, arXiv:2512.02189 — moteur de décompression matériel.
- CAGRA / cuVS
- Apache Arrow