- Le kernel d’attention a été refactoré sous une forme persistent, ce qui améliore les performances pour des longueurs de contexte faibles
- En fp16, avec de grands contextes, une baisse de performances apparaît à cause d’un problème d’ordonnancement des instructions par
ptxas dans la partition softmax
- En fp8, lorsqu’on inclut "cutlass" dans le nom du kernel, on observe un gain d’environ 100 TFLOPS
- Cette optimisation est analysée comme une astuce d’optimisation codée en dur via le nommage du kernel
- L’impact sur les performances et son origine relèvent d’un comportement particulier de l’implémentation interne de NVIDIA
ptxas
Résumé : refactorisation du kernel Persistent Attention et effet du nommage "cutlass"
Vue d’ensemble
- Cette Pull Request refactorise le kernel d’attention de Triton selon une approche persistent attention
- L’objectif principal est d’obtenir une optimisation des performances sur les faibles longueurs de contexte
- Cependant, pour le type fp16, on constate une dégradation des performances à mesure que la taille du contexte augmente, en raison d’un problème d’ordonnancement des instructions par
ptxas dans la partie softmax
Effet de l’adoption du nom "cutlass" en fp8
- Lorsqu’on utilise un modèle fp8, inclure "cutlass" dans le nom du kernel permet de mesurer un gain de performances pouvant atteindre environ 100 TFLOPS
- Cela vient du fait que le
ptxas de NVIDIA (assembleur PTX) applique en interne une optimisation spéciale lorsque le nom du kernel contient "cutlass"
- Dans le code réel, lorsque le dtype est
float8e5, le nom du kernel est défini comme cutlass_gluon_attention ou équivalent
- L’analyse de la désassemblage
ptxas montre qu’il existe effectivement dans le code interne une condition strstr(kernel_name, "cutlass")
Benchmarks de performance
- Les données de benchmark avant et après la refactorisation montrent une baisse relative des performances en D=64 par rapport à avant l’application de persistent attention
- Cela est attribué à un problème d’ordonnancement des instructions dans la partie softmax
- En revanche, en combinant le type fp8 et le nommage "cutlass", on obtient, pour certains contextes et certaines tailles, un débit nettement plus élevé
- Résumé de résultats représentatifs :
- Attention Z=4, H=32, D=64, causal=False :
- avant application de persistent : triton-fp16 env. 383, triton-fp8 env. 413, cudnn-fp16 env. 565
- après application de persistent : triton-fp16 env. 360, triton-fp8 env. 370
- Attention Z=4, H=32, D=128, causal=True :
- avant application de persistent : triton-fp16 env. 312, triton-fp8 env. 345, cudnn-fp16 env. 553
- après application de persistent : triton-fp16 env. 356, triton-fp8 env. 351
Découverte et analyse de l’astuce de nommage
- Lorsqu’une chaîne
"cutlass" est incluse dans le nom du kernel, l’analyse de la communauté a confirmé qu’une routine d’optimisation expérimentale est activée dans NVIDIA ptxas
ptxas contient une logique codée en dur de correspondance sur le nom (strstr(kernel_name, "cutlass"))
- Cette astuce correspond à une optimisation agressive et expérimentale, et son éventuel impact sur la précision peut varier selon le matériel et le contexte
Discussions de la communauté
- Plusieurs reviewers ont posé des questions et mené des analyses sur la comparaison des performances, la précision et la méthode d’optimisation
- Des échanges ont aussi porté sur le contenu du technical report de Deepseek, ainsi que sur les différences observées sur des architectures spécifiques comme les GPU Hopper
- La portée réelle de l’optimisation via changement de nom, ainsi que d’éventuels problèmes de stabilité, ont également été soulevés
Conclusion et implications
- Le fait que le simple nom d’un kernel puisse provoquer une variation de performances réelle au niveau matériel est un phénomène très inhabituel
- L’existence de triggers d’optimisation cachés dans la stack logicielle NVIDIA (
ptxas) suggère que, dans le développement de frameworks IA, les conventions de nommage peuvent aussi influencer les performances
- En pratique, l’utilisation de cette astuce impose de tester soigneusement la reproductibilité et la stabilité, tout en surveillant de près les politiques d’optimisation du fournisseur matériel
1 commentaires
Avis Hacker News
En désassemblant
ptxas, on a confirmé qu’il contient en dur une logique qui détecte les noms de kernel contenantcutlassJ’imagine que NVIDIA a appliqué ici une optimisation instable, expérimentale et agressive ; l’activer systématiquement pourrait introduire des bugs subtils
Les compilateurs GPU sont extrêmement difficiles à concevoir, et dès qu’on essaie d’aller au-delà des optimisations de base, on obtient presque toujours des résultats mitigés avec des problèmes en prime
Certains kernels deviennent plus rapides, d’autres plus lents, et il est très difficile d’obtenir un gain global de performances
Il est rare qu’une seule optimisation accélère systématiquement l’ensemble d’une suite de tests
Mon expérience porte sur des systèmes GPU autres que Nvidia, mais cette situation me paraît très familière
Nvidia semble aussi avoir trouvé des optimisations qui donnent des résultats remarquables sur certains ensembles de kernels et médiocres sur d’autres, sans réussir à définir un critère fiable pour les activer automatiquement
Merci pour ce contexte
Ce n’est pas mon domaine (et c’est même la première fois que j’entends parler de ce projet), donc ni le titre ni le contenu de la PR ne me parlaient vraiment
Ça m’a rappelé le cas d’ATI (AMD) il y a 25 ans, pris en flagrant délit de triche sur le benchmark Quake III quand le simple fait de renommer l’exécutable en
quackmodifiait les performancesLiens associés : test de techreport.com, test de hardocp.com, article de 3dcenter.de
Au cas où d’autres l’auraient mal compris comme moi, je récapitule
ATI détectait le nom d’exécutable
quakeet modifiait entre autres la qualité des textures pour gonfler le score du benchmarkLes gens ont découvert la supercherie en renommant l’exécutable en
quack: la qualité d’image augmentait et le score baissait, ce qui montrait que le pilote ATI dégradait volontairement la qualité pour gagner en vitesseDonc ce n’est pas ATI qui a renommé le fichier, ce sont les utilisateurs
Ou encore le problème avec Intel C++ Compiler qui vérifiait la présence de la chaîne
GenuineInteldans la sortieLe lien Wikipédia correspondant est ici
Tous les vendeurs font encore ce genre de choses aujourd’hui
Les pilotes interceptent la boucle de rendu de jeux populaires pour corriger des bugs, remplacer des shaders par des versions mieux optimisées ou ouvrir des chemins de code plus rapides, entre autres
En principe, ces changements ne devraient avoir qu’un impact minimal sur le résultat, mais parfois l’intervention est tellement agressive que la qualité en souffre fortement
Tout ça pour que le jeu tourne plus vite sur leur matériel
Il y a un fil de discussion plus approfondi sur ce sujet, à consulter ici
Fait amusant, il s’agit d’un ancien billet sur exactement la même optimisation
cutlassCe genre de cas est très courant
Les fabricants de chipsets pour téléphones ont triché sur les benchmarks (VW sur les émissions, Nvidia sur le benchmark 3DMark, Intel sur les benchmarks SPEC pour Xeon, etc.)
En infographie, c’est presque devenu une convention que les pilotes embarquent des tweaks, réglages et contournements spécifiques à chaque jeu
(Malheureusement, les bonnes sources disparaissent trop souvent aujourd’hui, ce qui oblige à passer par archive.org. À mon avis, ce genre de mémoire doit être préservé.)
Liens utiles : triche de benchmark chez Mediatek, scandale des émissions Volkswagen, controverse Nvidia 3DMark, impact du compilateur Intel sur SPEC
Du point de vue de quelqu’un qui travaille sur des compilateurs, il arrive que ce type d’optimisation dépende de noms (schéma, sous-chaîne, etc.)
Même si ça ne plaît pas, c’est parfois comme ça que les choses fonctionnent en pratique
Ce n’est pas forcément malveillant, et limiter l’optimisation à sa propre bibliothèque peut aussi être un choix plus sûr que de risquer de tout casser à l’échelle générale
Ou bien cela peut venir du fait que le frontend n’est pas capable de fournir des informations plus fiables, par exemple des informations structurelles
Je ne trouve pas ce genre de méthode très utile
À mon avis, il n’y a rien de très nouveau là-dedans
Ça me rappelle qu’il y a une dizaine d’années, dans une certaine version de Webpack, utiliser le nom de fichier
add.svgcassait le buildAu final, on avait résolu le problème en le renommant en
plus.svgCertaines personnes ont déjà cassé numpy sans le vouloir simplement en utilisant un fichier nommé
secret.pyJ’apprécie l’honnêteté du message de commit
Il y a eu des critiques sur la manière dont le diff du commit était structuré
Quelqu’un écrit qu’il a « rendu quelque chose environ 100 tflops plus rapide », et il se trouve quand même des gens pour répondre « le message de commit n’est pas terrible »… J’imagine qu’ils n’aimeraient pas non plus le style de commit de John Carmack
Personnellement, j’aime ce genre de message direct
Je trouve ça bien préférable à une avalanche de messages de commit générés par IA du type « refactored X » répétés à l’infini
Je pense qu’il vaudrait mieux squash l’historique de commits
Je ne comprends pas très bien pourquoi cela n’a pas été fait avant la mise en ligne sur GitHub
Ça me rappelle l’époque où j’apprenais à utiliser NVIDIA Jetson
J’avais découvert qu’une seule commande suffisait pour tout accélérer (lien associé)
D’après l’article, il y a deux modes, 5 W et 10 W, et 10 W est le mode par défaut ; on pourrait donc presque comprendre que cela ne « va plus vite » que lorsqu’on est passé du mode par défaut au 5 W, sauf si j’ai mal compris quelque chose
Il arrive qu’on écrive du code très fortement optimisé dans un langage de haut niveau (C++ ou autre), qu’on attende aussi un résultat très précis au niveau de l’assembleur GPU, et que le compilateur ne produise pas ce qu’on veut
Si l’on consulte l’équipe en charge du compilateur, elle proposera probablement plusieurs solutions, mais beaucoup sont difficiles à appliquer dans du code open source (par exemple des
#pragmapropriétaires, des intrinsics, etc.)Quand on développe une bibliothèque haute performance, ne pas atteindre le niveau de performances attendu peut tout simplement empêcher la livraison
Dans ce genre de situation, on finit parfois par devoir recourir à des astuces comme guider certaines transformations de code via le nom des fonctions
Ce type d’optimisation est courant dans le monde réel, et à mon avis on ne peut pas le mettre sur le même plan qu’une triche de benchmark consistant à réduire la qualité d’image
Ce point avait déjà été discuté lorsque cette PR a été publiée pour la première fois
Je n’ai pas l’impression qu’il y ait du nouveau
Discussion précédente
J’aimerais qu’il existe une structure économique qui facilite vraiment le partage du code
Au lieu de pilotes en blob binaire, de basebands et d’autres structures complexes, il serait bien que tout le monde puisse accéder facilement aux informations afin de réduire le temps et les efforts gaspillés
D’innombrables ingénieurs et chercheurs brillants passent déjà des mois, voire des années, à faire de la rétro-ingénierie et à décoder de la documentation, des schémas de circuits et du code binaire que quelqu’un possède déjà
CUDA et des entreprises comme NVIDIA sont particulièrement frustrantes
Pour une application desktop, le coût additionnel par utilisateur est pratiquement nul
Du coup, le logiciel a besoin d’une source de revenus récurrents, mais pas d’un modèle où les revenus continuent d’augmenter proportionnellement au nombre d’utilisateurs
Ceux qui investissent dans le développement d’un nouveau code doivent pouvoir récupérer leur mise quand le produit devient populaire, mais le financement participatif classique ne répond pas à cette contrainte
Plus le nombre d’utilisateurs augmente, plus la contribution individuelle nécessaire chute, si bien que même si chacun ne contribue qu’à hauteur de 100 %, 10 % ou même 1 %, la somme totale peut devenir astronomique
À mon avis, il faudrait donc un système d’engagements sous forme d’enchères
Ce modèle a aussi ses propres problèmes, notamment le passage d’un mode exclusif à un mode non exclusif, qui est particulièrement délicat
Si quelques grandes entreprises financent entièrement le développement puis publient le résultat en open source, alors pratiquement tous les autres particuliers et entreprises deviennent de fait des passagers clandestins