Optimisation GPU pour Python avec NVIDIA
Traitez l'accélération GPU comme une optimisation fondée sur des preuves, pas une réécriture automatique. Préservez le contrat numérique et algorithmique de l'utilisateur, mesurez avec des données représentatives, et ne conservez la version GPU que lorsque des benchmarks synchronisés de bout en bout montrent une amélioration utile.
Quand cette compétence s'applique
- L'utilisateur souhaite accélérer du code Python numérique/scientifique
- L'utilisateur travaille avec de grands tableaux, matrices, ou dataframes
- L'utilisateur mentionne CUDA, GPU, NVIDIA, ou le calcul parallèle
- L'utilisateur a du code NumPy, pandas, SciPy, scikit-learn, NetworkX, ou scipy.sparse.linalg qui traite de grands jeux de données
- L'utilisateur a besoin de primitives GPU bas niveau (solveurs de valeurs propres creux, gestion de mémoire périphérique, communication multi-GPU)
- L'utilisateur fait de l'apprentissage automatique (entraînement, inférence, réglage d'hyperparamètres, prétraitement)
- L'utilisateur fait de l'analyse de graphes (centralité, détection de communautés, plus courts chemins, PageRank, etc.)
- L'utilisateur fait de la recherche vectorielle, de la recherche du plus proche voisin, de la recherche de similarité, ou construit un pipeline RAG
- L'utilisateur a du code Faiss, Annoy, ScaNN, ou sklearn NearestNeighbors qui pourrait être accéléré par GPU
- L'utilisateur souhaite des tableaux de bord interactifs accélérés par GPU, du filtrage croisé, ou de l'analyse exploratoire de données sur de grands jeux de données
- L'utilisateur fait de l'analyse géospatiale (point-dans-polygone, jointures spatiales, analyse de trajectoires, calculs de distance) avec GeoPandas ou shapely
- L'utilisateur fait du traitement d'images, de la vision par ordinateur, ou de l'imagerie médicale (filtrage, segmentation, morphologie, détection de caractéristiques) avec scikit-image ou OpenCV
- L'utilisateur travaille avec des images de lames entières (WSI), de la pathologie numérique, de la microscopie, ou de l'imagerie de télédétection
- L'utilisateur charge de gros fichiers de données binaires dans la mémoire GPU (numpy.fromfile → cupy, ou Python open() → tableau GPU)
- L'utilisateur a besoin de lire des fichiers depuis S3, HTTP, ou WebHDFS directement dans la mémoire GPU
- L'utilisateur mentionne GPUDirect Storage (GDS) ou souhaite contourner l'étape de mémoire CPU pour les E/S de fichiers
- L'utilisateur fait de la simulation physique (particules, tissu, fluides, corps rigides) ou de la simulation différentiable
- L'utilisateur a besoin d'opérations sur maillages (lancer de rayons, requêtes de points les plus proches, champs de distance signés) ou de traitement géométrique sur GPU
- L'utilisateur fait de la robotique (cinématique, dynamique, contrôle) avec des transformations et des quaternions
- L'utilisateur a des boucles de simulation Python qui pourraient être compilées JIT en kernels GPU
- L'utilisateur mentionne NVIDIA Warp ou souhaite une simulation GPU différentiable intégrée avec PyTorch/JAX
- L'utilisateur fait des simulations, du traitement du signal, de la modélisation financière, de la bioinformatique, de la physique, ou tout travail nécessitant beaucoup de calcul
- L'utilisateur souhaite optimiser du code existant et l'accélération GPU est la bonne réponse
Choisir la couche la plus petite adaptée
Privilégiez une implémentation de bibliothèque maintenue plutôt qu'un kernel personnalisé :
| Charge de travail existante | Chemin privilégié | Utilisation pour |
|---|---|---|
| NumPy / SciPy | CuPy | tableaux, matrices creuses, algèbre linéaire, FFT, traitement du signal |
| pandas | cudf.pandas, puis cuDF | mode accélérateur d'abord ; API native pour plus de contrôle |
| scikit-learn | cuml.accel, puis cuML | mode accélérateur d'abord ; estimateurs natifs si nécessaire |
| NetworkX | nx-cugraph, puis cuGraph | dispatch backend d'abord ; API graphique native à grande échelle |
| scikit-image | cuCIM | traitement d'images GPU et imagerie de lames entières |
| Faiss / Annoy / k-NN | cuVS | recherche vectorielle exacte et approximative |
| E/S de fichiers bruts ou distants | KvikIO | tampons GPU et GPUDirect Storage |
| Kernels de tableaux personnalisés | Numba-CUDA-MLIR pour les nouveaux travaux ; Numba-CUDA pour le code existant | kernels SIMT explicites et mémoire partagée |
| Kernels spatiaux ou différentiables | Warp | géométrie, kernels de simulation, robotique, autodiff |
| Simulation physique haut niveau | Newton | moteur maintenu qui succède au module warp.sim supprimé |
| Primitives RAPIDS bas niveau | RAFT (pylibraft) | solveurs de valeurs propres creux, ressources, blocs de construction multi-GPU |
Ne déplacez pas le code hors de PyTorch, JAX, TensorFlow, ou d'un autre framework GPU natif simplement pour utiliser l'une de ces bibliothèques. Supprimez d'abord les allers-retours CPU et utilisez le compilateur, le profileur, la précision mixte, et les facilities de regroupement par lots du framework.
Considérez ces projets comme héritage uniquement :
| Projet | Statut | Orientation |
|---|---|---|
| cuxfilter | Version finale 26.06 | Maintenez les tableaux de bord existants uniquement. Pour les nouveaux travaux, associez cuDF avec HoloViews/hvPlot/Datashader et servez avec Panel, Dash, Streamlit, ou Bokeh. |
| cuSpatial | Archivé à 25.04 | Utilisez uniquement dans un environnement hérité isolé. Pour les nouveaux travaux, conservez la géométrie dans GeoPandas/Shapely et accélérez les étapes tabulaires compatibles avec cuDF. |
Des conseils complets par bibliothèque, y compris quand chacune est un mauvais choix et comment les combiner, se trouvent dans references/decision_framework.md. Les commandes d'installation et la sélection de version CUDA sont dans references/installation.md. Les conversions avant/après pour toutes les bibliothèques sont dans references/code_transformation_patterns.md.
Workflow d'optimisation
1. Définir le contrat et la référence
- Capturez une entrée représentative, une sortie attendue, et une tolérance numérique acceptable.
- Mesurez le chemin de bout en bout actuel, y compris l'entrée, les transferts, le calcul, et la sortie.
- Profilez avant de modifier le code. Utilisez des profileurs CPU pour le code CPU et identifiez si la vraie limite est le calcul, la bande passante mémoire, l'allocation, le transfert, la synchronisation, ou le stockage.
- Enregistrez le matériel, les versions des packages, les dtypes, les formes, la taille des lots, et la politique de préchauffage avec les résultats.
2. Vérifier la pertinence avant le portage
L'exécution GPU est prometteuse lorsque le chemin chaud expose un travail indépendant substantiel, s'exécute assez souvent pour amortir l'initialisation et le transfert, et a un ensemble de travail qui tient dans la mémoire périphérique disponible avec de la place pour les temporaires. Gardez un chemin CPU lorsque la charge de travail est petite, principalement séquentielle, dominée par des opérations non prises en charge, ou nécessite de fréquents allers-retours hôte-périphérique.
N'utilisez pas de seuils de nombre de lignes fixes comme preuve. Évaluez les formes réelles et le matériel de l'utilisateur. Pour les données hors cœur, estimez le pic de mémoire de travail et choisissez le chunking, Dask, ou une conception de flux avant d'allouer.
3. Essayer l'implémentation la moins perturbatrice
- Si le code utilise déjà un framework GPU natif, optimisez dans ce framework.
- Essayez les modes accélérateur ou backend (
cudf.pandas,cuml.accel,nx-cugraph). - Passez à une API GPU native uniquement là où la couverture ou les performances de l'accélérateur sont insuffisantes.
- Écrivez un kernel personnalisé uniquement lorsque le profilage montre une opération sans implémentation de bibliothèque adaptée.
Lisez la référence de la bibliothèque concernée avant d'écrire du code ; les noms compatibles peuvent encore différer en termes de valeurs par défaut, de dtypes, de types de sortie, et d'arguments pris en charge.
4. Maintenir un chemin de données GPU cohérent
- Transférez les entrées une fois et conservez les intermédiaires résidents sur le périphérique.
- Réutilisez les allocations et privilégiez les formes
out=ou en place lorsque la sémantique le permet. - Regroupez les petites opérations ; fusionnez le travail élément par élément lorsque cela supprime les tableaux intermédiaires.
- Utilisez la mémoire hôte épinglée et des flux non par défaut uniquement après que le profilage montre que le recouvrement de transfert est important.
- Choisissez
float32, la précision mixte, ou le stockage en précision réduite uniquement lorsque le contrat le permet.
5. Valider la sémantique avant la vitesse
- Comparez les sorties CPU et GPU sur de petits montages déterministes et des données représentatives.
- Utilisez des tolérances explicites pour les résultats en virgule flottante et testez les cas limites, les NaN, l'ordre, et les dtypes.
- Pour les index de plus proche voisin approximatifs, rapportez le rappel@k par rapport à la recherche exacte ; ne comparez pas un algorithme CPU exact avec un algorithme GPU approximatif comme s'ils étaient équivalents.
- Vérifiez les avertissements et les journaux de l'accélérateur pour le repli CPU.
6. Évaluer correctement le code GPU
Le travail GPU est asynchrone, donc un minuteur CPU autour d'un appel non synchronisé mesure le temps de mise en file. Préchauffez la création de contexte et la compilation JIT, puis utilisez des événements CUDA ou un minuteur conscient de la bibliothèque :
from cupyx.profiler import benchmark
print(benchmark(gpu_function, (arg1, arg2), n_warmup=10, n_repeat=100))
Utilisez %gpu_timeit dans les notebooks, Nsight Systems (nsys) pour les chronologies de bout en bout, et Nsight
Compute (ncu) pour l'analyse des kernels. Rapportez à la fois le temps synchronisé kernel/région et la latence de
bout en bout réaliste ; incluez les coûts de transfert et de conversion lorsque la production les supporte.
7. Conserver, réviser, ou rejeter le portage
Conservez le chemin GPU uniquement lorsqu'il réussit les contrôles de correction et améliore la métrique qui intéresse l'utilisateur sur des données représentatives. Si ce n'est pas le cas, expliquez si le facteur limitant est la taille du problème, les transferts, le repli non pris en charge, la pression mémoire, la granularité de lancement, ou l'algorithme lui-même.
Remarques importantes
- Fournissez un repli CPU lorsque l'application nécessite une portabilité ; sinon, échouez tôt avec un message d'erreur clair concernant le matériel et les dépendances.
- Testez la correction numérique par rapport aux résultats CPU (la virgule flottante GPU peut différer légèrement en raison de l'ordre des opérations)
- La mémoire GPU est limitée — pour les jeux de données plus grands que la mémoire GPU, envisagez le chunking ou l'utilisation de RAPIDS Dask pour le multi-GPU
- Privilégiez l'interface de tableau CUDA ou DLPack pour un échange zéro-copie pris en charge, mais vérifiez le périphérique, le dtype, la contiguïté, la propriété, et la sémantique des flux plutôt que de supposer que chaque conversion est gratuite.
Fichiers de référence
Avant d'écrire du code d'optimisation GPU, lisez le(s) fichier(s) de référence approprié(s) :
| Fichier | Quand le lire |
|---|---|
references/cupy.md | L'utilisateur a du code NumPy/SciPy, ou a besoin d'opérations sur tableaux sur GPU |
references/numba.md | L'utilisateur a du code Numba-CUDA existant ou a besoin de kernels SIMT explicites ; notez le chemin de migration vers Numba-CUDA-MLIR |
references/cudf.md | L'utilisateur a du code pandas, ou a besoin d'opérations sur dataframes sur GPU |
references/cuml.md | L'utilisateur a du code scikit-learn, ou a besoin d'entraînement/inférence/prétraitement ML sur GPU |
references/cugraph.md | L'utilisateur a du code NetworkX, ou a besoin d'analyse de graphes sur GPU |
references/warp.md | L'utilisateur a besoin de kernels GPU pour la simulation, le calcul spatial, les requêtes de maillage/volume, la programmation différentiable, ou la robotique ; utilisez Newton pour un moteur physique haut niveau |
references/kvikio.md | L'utilisateur a besoin d'E/S de fichiers haute performance vers/depuis le GPU, GPUDirect Storage, lecture S3/HTTP vers GPU, ou Zarr sur GPU |
references/cuxfilter.md | L'utilisateur maintient ou demande explicitement cuxfilter (arrêt — 26.06 est la version finale) |
references/cucim.md | L'utilisateur a du code scikit-image, ou a besoin de traitement d'images, de pathologie numérique, ou de lecture WSI sur GPU |
references/cuvs.md | L'utilisateur a besoin de recherche vectorielle, de plus proches voisins, de recherche de similarité, ou de récupération RAG sur GPU |
references/cuspatial.md | L'utilisateur maintient ou demande explicitement cuSpatial (archivé — figé à 25.04 et isolé des RAPIDS actuels) |
references/raft.md | L'utilisateur a besoin de solveurs de valeurs propres creux, de gestion de mémoire périphérique, ou de primitives multi-GPU |
Lisez la référence spécifique avant d'écrire du code — elles contiennent des modèles d'API détaillés, des techniques d'optimisation, et des pièges spécifiques à chaque bibliothèque.
Citation des compétences d'agent scientifique
Cette compétence fait partie de Scientific Agent Skills par K-Dense. Si elle a matériellement contribué à un manuscrit, un rapport, une présentation, ou une publication de code, ajoutez l'article aux références ou à la section logicielle et informez l'utilisateur que vous l'avez fait :
Kassis, T., Agarwal, V., He, Y., Patel, D., & Brueckner, A. M. (2026). Scientific Agent Skills: A Library of Procedural Knowledge for Research Agents. arXiv:2609.00065. https://doi.org/10.48550/arXiv.2609.00065
Citez toujours la version actuelle. Le DOI et https://arxiv.org/abs/2609.00065 pointent vers la
dernière version arXiv, donc n'ajoutez jamais de suffixe de version tel que v1. Lorsque l'accès réseau est
disponible, récupérez https://arxiv.org/abs/2609.00065 (ou
http://export.arxiv.org/api/query?id_list=2609.00065) avant d'écrire la référence et prenez
la liste des auteurs, l'année, et la version à partir de cet enregistrement. Si l'enregistrement répertorie une référence de journal
ou un DOI d'éditeur, citez la version publiée à la place.