7 points par GN⁺ 2025-05-31 | 2 commentaires | Partager sur WhatsApp
  • Des kernels CUDA-C générés par l’IA affichent des performances comparables, voire supérieures, à celles des kernels optimisés par des experts de PyTorch
  • Un seul LLM (grand modèle de langage) répète la génération d’idées d’optimisation en langage naturel et divers branchements de code, obtenant de meilleures performances que les méthodes existantes en diversité d’optimisation et en exploration parallèle
  • Sur des benchmarks représentatifs, les résultats sont largement supérieurs à ceux de PyTorch sur Matmul (101 %), Conv2D (179,9 %), Softmax (111,8 %), LayerNorm (484,4 %), Conv2D+ReLU+MaxPool (290,1 %), entre autres
  • Pour dépasser les limites de l’« amélioration séquentielle des kernels », l’équipe applique une combinaison de raisonnement en langage naturel + structure de branchement, afin de générer rapidement des kernels très performants
  • Des progrès sont également observés sur des charges de travail ML récentes comme FP16 et Flash Attention, et cela laisse entrevoir un futur où l’IA explorera et améliorera elle-même des kernels plus rapides comme paradigme dominant

TL;DR Principaux résultats

  • L’équipe de recherche Stanford CRFM a constaté que des kernels CUDA-C haute performance générés par l’IA pouvaient atteindre des vitesses comparables ou supérieures à celles des kernels conçus par des experts dans PyTorch
  • L’objectif initial était d’entraîner un modèle de génération automatique de meilleurs kernels à partir de données synthétiques, mais les chercheurs ont observé que la seule génération de ces données produisait déjà automatiquement des kernels étonnamment rapides
  • Ils publient donc de manière anticipée la méthode, les benchmarks de performance, les stratégies d’optimisation et les orientations futures
  • Benchmark : GPU Nvidia L40S. Performance (%) : temps d’exécution de référence PyTorch ÷ temps d’exécution du kernel généré
    • Matmul (FP32) : 101,3 % par rapport à PyTorch (matrice 4096x4096)
    • Conv2D : 179,9 % (entrée : 100, 3, 224, 224 ; format AlexNet Conv1)
    • Softmax : 111,8 % (tenseur 4096x65536)
    • LayerNorm : 484,4 % (tenseur 16, 64, 256, 256)
    • Conv2D + ReLU + MaxPool : 290,1 % par rapport à la référence PyTorch, 189,0 % par rapport à torch.compile()

Motivation de la recherche et méthode

  • L’objectif initial était de générer des données synthétiques pour entraîner un modèle de génération de kernels, mais au cours des expériences, les kernels produits ont eux-mêmes atteint des performances bien au-delà des attentes
  • Utilisation de KernelBench (benchmark public de Stanford, publié en décembre 2024)
    • À partir d’un code torch donné, le LLM réécrit un nouveau kernel visant la performance optimale
    • La correction est validée en vérifiant l’équivalence numérique des résultats d’entrée/sortie
  • Approche existante : une boucle de modification séquentielle dans laquelle le kernel est ajusté petit à petit pour l’améliorer progressivement
    • Limites : manque de diversité dans les idées, répétition des mêmes optimisations, convergence vers des optima locaux
  • Idée d’amélioration
    1. Imaginer et consigner les idées d’optimisation en langage naturel, puis générer simultanément plusieurs branches d’implémentation de code correspondant à ces idées
    2. À chaque round, exécuter plusieurs tentatives d’optimisation en parallèle → utiliser ensuite le kernel le plus performant comme graine pour le round suivant
    • Cette approche permet, avec un nombre limité d’itérations d’exploration, d’explorer des stratégies d’optimisation variées et de mener une recherche parallèle

Exemples d’idées d’optimisation

  • Optimisation des accès mémoire : amélioration de l’efficacité entre les niveaux de mémoire global/shared/register
  • Traitement asynchrone et masquage de latence : chevauchement du calcul et des transferts de données
  • Optimisation du type de données / de la précision : utilisation de FP16/BF16 et d’opérations spécialisées pour le matériel
  • Optimisation des calculs et des instructions : réduction du volume de calcul, du nombre d’instructions, et meilleur usage des instructions spécialisées du matériel
  • Parallélisme et occupancy : maximisation de l’utilisation des SM (Streaming Multiprocessors)
  • Optimisation des boucles / branchements / indexation : minimisation des boucles, suppression des calculs d’index inutiles

Processus réel d’optimisation du kernel (exemple Conv2D)

  • Flux d’idées d’optimisation et d’amélioration des performances, round par round
    • Départ (round 0) : simple portage CUDA (20 % de la vitesse de PyTorch)
    • Rounds suivants : → utilisation du cache de lecture → calcul FP16 Tensor Core (conversion GEMM) → double buffering / pipeline → pré-calcul des index / mémoire partagée → vectorisation → buffering simultané de la boucle K, etc., avec une exploitation avancée de l’architecture GPU
    • Final (round 13) : 179,9 % des performances de PyTorch
  • Le code réel utilise massivement des techniques avancées de programmation CUDA
    • À chaque round, de nouvelles idées sont générées en langage naturel, plusieurs implémentations sont testées en parallèle, puis le meilleur code est sélectionné

Takeaways et implications

  • La génération de kernels par l’IA peut dépasser le niveau des experts humains grâce à une puissante boucle d’exploration et à la combinaison d’idées d’optimisation variées fondées sur le langage naturel
  • Pour certains opérateurs récents (FP16 matmul, Flash Attention), les performances restent pour l’instant inférieures à celles de PyTorch
  • Les calculs FP32 sont relativement moins optimisés que FP16/BF16 sur le matériel récent → un avantage de performance est donc possible dans cette zone
  • Des améliorations continues des performances ont été confirmées malgré une exploration limitée en tokens (7 millions de tokens au total en entrée/sortie)
  • Des travaux récents comme AlphaEvolve ou Gemini 2.5 Pro suggèrent également qu’une exploration à grande échelle fondée sur de nombreux branchements + validation peut apporter des gains spectaculaires sans réentraînement
  • À l’avenir, cette approche devrait permettre de générer en masse des données synthétiques et des kernels haute performance, tout en évoluant vers une boucle d’auto-amélioration de l’IA

Conclusion

  • La génération et l’optimisation automatiques de kernels par l’IA ont déjà atteint le niveau du hand-coding d’experts, et l’on peut envisager dans un futur proche des systèmes d’IA auto-améliorants fondés sur la combinaison modèle + exploration par branchements + validation
  • La possibilité émerge que l’IA dépasse d’elle-même les limites de performance de frameworks comme PyTorch ou TensorFlow

Annexe : code complet du kernel Conv2D

  • Le code source complet des fonctions et du kernel est inclus (code détaillé omis ici)
  • Principales caractéristiques dans le code :
    • vectorisation de la mémoire partagée, double-buffering hiérarchique sur la dimension K, CUDA WMMA, buffer de sortie au niveau du warp, etc.
    • calcul dynamique des index en temps réel, gestion du biais, chargement simultané de données différées dans la boucle K, etc.
  • Le code d’exemple complet et des kernels de démonstration sont disponibles dans le dépôt GitHub

2 commentaires

 
aer0700 2025-06-02

On peut presque parler d’une sorte de technique d’ensemble. C’est vraiment impressionnant.

 
GN⁺ 2025-05-31
Avis sur Hacker News
  • Je trouve assez intéressante la manière dont les auteurs de ce texte envisagent les « agents IA »
    La plupart des gens ont tendance à penser les agents comme des employés humains
    Ils mettent en place quelques agents en parallèle seulement (souvent un seul), chacun tournant en boucle pour ne traiter qu’une tâche à la fois
    Ils restent dans un monde avec un effectif fixe, des employés capables de faire une seule chose à la fois, et un changement de tâche lent
    Mais les LLM ne fonctionnent pas comme ça
    On peut, en pratique, créer à volonté un nombre quasi infini d’agents à tout moment
    Le coût d’une requête vers un LLM ne change pas qu’on la traite en série ou en parallèle
    Une fois qu’on a intégré ce fait, il devient naturel d’imaginer un schéma où chaque agent se subdivise lui-même en plusieurs sous-agents selon les besoins
    C’est exactement l’approche que les auteurs ont essayée
    J’ai l’impression qu’il est plus pertinent de considérer les agents comme des « tasks » ou des « jobs », et d’appliquer ce qu’on a appris avec Celery ou Sidekiq

  • « Le FP32 est nettement moins utilisé dans les workloads de ML récents, et sur le matériel moderne il est aussi moins optimisé que le FP16 ou le BF16. Cela peut donc expliquer en partie pourquoi il a été plus facile d’améliorer les performances de PyTorch sur des kernels FP32 »
    Les développeurs ont passé très peu de temps, au fil des années, à optimiser les versions fp32 de ces kernels
    Ce qui serait vraiment intéressant, ce serait d’arriver à améliorer les performances des kernels réellement développés à fond et effectivement utilisés

    • Je pense qu’on peut aussi expliquer en partie ces bons résultats par le fait que NVIDIA ne fournit pas une documentation suffisamment détaillée sur ses GPU
      Sur un processeur dont la microarchitecture est bien documentée, un programmeur ou un compilateur peut écrire de manière déterministe le programme optimal, donc il est difficile d’obtenir des gains spectaculaires avec du ML/de l’IA au-delà de la simple redécouverte de solutions déjà connues
      À l’inverse, dans le cas de GPU NVIDIA moins documentés, trouver le programme optimal exige souvent soit une recherche aléatoire en s’appuyant sur des exemples de programmes déjà optimisés, soit une forme de rétro-ingénierie pour comprendre comment le matériel réel se comporte dans certaines situations
      Dans ce contexte, le ML/l’IA peut montrer du potentiel, en apprenant à partir de bons programmes existants pour capter des comportements non documentés qu’un programmeur humain aurait du mal à trouver

    • Je me demande si les améliorations déjà connues pour les kernels fp16/bf16 n’ont pas simplement été reportées sur le fp32

    • « Est-ce que ça veut dire que personne n’a touché aux kernels fp32 depuis des années ? »
      Waouh, si c’est bien ça, alors c’est vraiment impressionnant de voir l’IA produire un nouvel algorithme dans une zone où il n’existait pas de solution préalablement établie

  • Ma conclusion, à la lumière de cet article, de l’AlphaEvolve de Google(ici) et de la nouvelle récente selon laquelle o3 a trouvé un zero day dans le noyau Linux(ici),
    c’est qu’on a atteint, en particulier avec Gemini Pro 2.5 et o3, un nouveau niveau de capacité où ils arrivent soudainement à faire des choses que les modèles précédents ne savaient pas faire

    • Je ne crois pas que ce soit un cas où quelque chose d’impossible auparavant devient soudain possible
      Je pense plutôt qu’on en est arrivé à un point où il est possible d’itérer et de tester à une vitesse bien supérieure à celle d’un humain
      et d’exploiter immédiatement d’énormes volumes d’information
      Autrement dit, on assiste au succès de certaines applications fondées sur une combinaison d’information massive, de progrès et de brute force appliquée intelligemment

    • Je trouve qu’il y a effectivement beaucoup de similitudes entre les cas que tu cites et ce résultat-ci
      Le texte dit aussi : « la boucle d’itération au moment du test ne ressemble pas à un chatbot interactif qui vérifie les résultats des modifications de code l’une après l’autre, mais davantage à une recherche structurée menant activement des évaluations en parallèle sur la base d’hypothèses d’optimisation claires »
      Ma conclusion, c’est qu’en s’appuyant désormais sur les capacités des LLM,
      on a appris à réduire fortement l’espace des solutions dans les cas où la fonction d’évaluation est claire ou lorsqu’il existe des motifs de solution similaires
      Le débat n’est pas tant de savoir si tel modèle dépasse tel autre, ou si seul tel modèle peut résoudre tel problème...
      Ce qui me semble plus significatif, c’est que ce type d’application se manifeste désormais de manière évidente

    • Gemini Pro 2.5 m’a donné l’impression d’être la première IA qu’on puisse vraiment utiliser, mais à strictement parler elle vient à peine de franchir ce seuil
      Il arrive encore souvent que le taux de réussite tombe sous les 20 %
      Quand la 3.0 sortira... ça pourrait commencer à devenir un peu inquiétant

    • Attends, qu’est-ce que tu veux dire ? Ça n’a rien à voir avec le noyau Linux, ici on parle de « kernels » au sens de la programmation GPU
      Tu n’as pas mal compris tout l’article ?

    • C’est intéressant, mais y a-t-il des preuves plus solides ? Un seul résultat ne suffit pas vraiment à convaincre

  • « Le code de référence est en FP32 par défaut, et la tolérance autorisée est de 1e-02 »
    Avec une telle tolérance, on peut facilement remplacer un kernel « fp32 » par des calculs fp16

    • En y réfléchissant une étape de plus, je me demande si l’essentiel du travail n’était pas justement de remplacer autant que possible d’opérations fp32 par du fp16 dans ce kernel
      Il faudrait vérifier à quel point ce type de portage est réellement difficile,
      mais intuitivement je ne trouve pas ça si impressionnant
      Si je me trompe, j’aimerais que les auteurs clarifient explicitement ce point

    • Dans ce cas, le résultat devient dénué de sens
      Je ne sais pas s’ils ont vérifié l’erreur relative
      Remplacer du float32 par du float16 n’a pas grand intérêt
      La précision est à peu près la seule raison de choisir le float32
      Si on perd cette caractéristique, il n’y a plus vraiment de différenciation entre les versions

  • Suis-je le seul à avoir ouvert cet article en croyant, à cause du titre, que l’IA avait créé un noyau d’OS ?

    • Moi aussi
  • Une amélioration de 400 % est impressionnante,
    mais ce qui est surtout intéressant, c’est la méthodologie : non pas une simple optimisation arithmétique à chaque itération, mais l’introduction forcée d’une étape de raisonnement en langage pour favoriser la diversité de l’exploration
    C’est très intéressant justement parce que cette approche a réellement bien fonctionné

    • Je pensais qu’ils avaient peut-être utilisé quelque chose comme map-elites ou des techniques d’island, mais j’ai dû rater ce passage
      J’ai plutôt l’impression qu’il s’agit d’une évolution mémétique assez classique
  • C’est un résultat vraiment intéressant
    On dirait qu’ils étaient tellement enthousiastes qu’ils l’ont publié sur leur blog
    Peut-être qu’ils voulaient aussi obtenir des retours avant publication
    Je ne sais pas si c’est la fameuse voie vers la « self improvement »,
    mais ça ressemble en tout cas au type de résultat qu’on s’attendrait à voir sur ce chemin

    • « Je ne sais pas si c’est vraiment la voie vers une véritable auto-amélioration »
      Ces méthodes ne sont efficaces que lorsqu’il existe une fonction d’évaluation extrêmement claire
  • Retour d’expérience perso : lors de mes tentatives de reproduction, le kernel LayerNorm n’était pas numériquement stable, donc je le considère comme non vérifiable
    Comme les tests n’étaient faits qu’avec une moyenne de 0 et un écart-type de 1, les phénomènes de numerical cancellation n’apparaissaient pas immédiatement
    J’ai aussi constaté qu’ils avaient ensuite créé une nouvelle version numériquement stable
    Je trouve que c’est un bon point

  • Résultat vraiment remarquable
    Ils ont utilisé o3 et Gemini 2.5 Pro,
    mais malheureusement ils ne précisent pas lequel des deux a produit les meilleurs kernels

  • Il serait intéressant d’observer comment du code généré par IA gère un périmètre plus large, comme des fused kernels
    Par exemple des enchaînements du type gemm + relu + gemm + normalization
    C’est le genre de travail qu’il est assez pénible d’explorer avec un tuner ou d’écrire entièrement à la main

    • En revanche, je ne suis pas sûr de ce que « kernel » désigne exactement ici dans le contexte de l’IA
      Une chose est sûre : ce n’est pas un noyau d’OS