Accélérez Llama 2 70B avec NVIDIA H100

Le voyage de l'inférence LLM accélérée

The journey of accelerated LLM inference

La recherche de performance dans le moteur de réponse de Perplexity nous pousse à adopter les dernières technologies proposées par NVIDIA et AWS. Dans cet article de blog, nous sommes ravis de partager les résultats de nos dernières expériences : une comparaison de l'inférence Llama 2 70B sur diverses configurations matérielles et logicielles.

Notre plateforme d'inférence LLM, pplx-api, repose sur une architecture de pointe alimentée par des bibliothèques open source. Depuis le lancement de la version bêta publique de pplx-api en octobre, nous avons relevé des défis de mise à l'échelle et appris à optimiser au mieux notre configuration pour atteindre une envergure massive. Cela nous a conduits à mener des expériences basées sur les questions directrices suivantes :

Quel est le gain de performance brut en remplaçant nos GPU NVIDIA A100 par des NVIDIA H100, toutes les autres configurations restant identiques ?

Quel est le gain d'efficacité de la quantification en virgule flottante 8 bits (fp8), pour laquelle le H100 offre une prise en charge native ? Quel est le coût de cette quantification en termes de précision ?

Comment le parallélisme de tenseurs et la taille des lots affectent-ils la latence et le débit de jetons ?

Compte tenu de ce qui précède, quelle configuration permet d'obtenir l'équilibre le plus évolutif entre performance et rentabilité ?

Configuration expérimentale

Nous avons mené l'expérience suivante sous forme de série de tests de performance locaux afin d'éviter la latence réseau.

Mesures clés :

Latence : Temps total nécessaire au serveur d'inférence pour générer sa réponse complète.

Débit : Nombre de jetons de sortie par seconde et par GPU que le serveur d'inférence peut générer pour l'ensemble des utilisateurs et des requêtes.

Constantes :

Les facteurs suivants influençant les mesures clés, nous les avons maintenus constants au cours des différents essais de l'expérience.

Modèle d'IA

Les performances évoluent avec la taille du LLM. Davantage de paramètres nécessitent plus de calculs, ce qui ralentit l'inférence. Par exemple, Llama 2 13B est plus rapide que Llama 2 70B à paramètres égaux. Nous avons choisi Llama 2 70B pour cette expérience afin d'optimiser l'utilisation des modèles open source les plus performants.

Jeu de données de jetons d'entrée/sortie

La quantité de jetons d'entrée et de sortie dans chaque paire requête/réponse échantillonnée peut influencer les mesures de performance. En règle générale, la génération de jetons de sortie domine le temps de réponse global. Lorsque les données d'échantillonnage n'induisent que des réponses « oui/non » de la part du LLM, la réponse est plus rapide que pour des échantillons demandant la rédaction d'essais. Notre jeu de données est composé de requêtes synthétiques avec 1024 jetons d'entrée induisant 512 jetons de sortie. Cette distribution a été choisie pour correspondre à la distribution du trafic observée sur notre déploiement public de Llama2 70B.

Version du logiciel

NVIDIA TensorRT-LLM (version v0.5.0) est une bibliothèque open source destinée à optimiser l'inférence LLM. Sortie fin 2023, elle synthétise de nombreuses optimisations d'inférence de NVIDIA et offre une couche flexible de personnalisation pour les paramètres clés de cette expérience : taille des lots, quantification et parallélisme de tenseurs.

Variables

Nous avons expérimenté sur 4 axes de configuration : parallélisme de tenseurs, architecture GPU, quantification et taille maximale des lots. Ces axes sont interconnectés car ils représentent chacun un compromis concernant la ressource critique limitante qu'est la mémoire GPU.

Architecture GPU

L'architecture GPU Hopper de neuvième génération (H100-HBM3-80GB / p5.48xlarge) offre une vaste liste d'améliorations par rapport à son prédécesseur, Ampere (A100-SXM4-80GB / p4de.24xlarge), notamment des vitesses de calcul multipliées par 2 à 6 et une bande passante mémoire GPU presque doublée. La bande passante mémoire du GPU est une mesure critique pour l'inférence, car l'un des principaux goulots d'étranglement de la latence dans les multiplications de matrices provient du chargement des gigaoctets de données du modèle depuis la mémoire GPU vers les registres de calcul. Sur la base de ces statistiques, nous avons émis l'hypothèse qu'une comparaison directe entre NVIDIA H100 et A100 montrerait une amélioration de 2x tant en termes de latence que de débit.

Une autre différence clé entre les NVIDIA H100 et A100 réside dans le fait que le cœur de tenseur H100 prend nativement en charge les instructions en virgule flottante 8 bits (fp8), ce qui ouvre la voie à d'autres optimisations détaillées ci-dessous. C'est pourquoi nous utilisons spécifiquement le fp8 et le fp16 pour le H100.

Pour maintenir une mémoire par GPU constante dans cette expérience, nous avons utilisé des nœuds dotés de 8x80 Go de mémoire GPU pour nos NVIDIA A100 et H100. En plus de permettre des tailles de lots plus importantes, la mémoire GPU est cruciale car les paramètres du modèle y sont chargés au démarrage du serveur pour un accès rapide. Par exemple, si chacun des 70 milliards de paramètres de notre modèle est un nombre en virgule flottante 16 bits, alors le modèle pèse environ 140 Go, ce qui ne tient pas sur un seul GPU. D'où la nécessité du parallélisme de tenseurs, que nous expliquons ci-dessous.

Parallélisme de tenseurs

Le parallélisme de tenseurs fait référence au nombre de périphériques GPU utilisés pour exécuter le serveur d'inférence. Lorsque nous allouons un certain nombre de GPU, TensorRT-LLM met en commun leurs ressources pour nous aider à atteindre le budget mémoire minimum requis pour faire fonctionner Llama2 70B. Notre hypothèse est qu'un parallélisme de tenseurs plus faible entraînera une latence plus élevée (en raison du nombre réduit de ressources consommées pour satisfaire chaque lot), mais un débit par GPU plus élevé (grâce à une meilleure utilisation) par rapport à un parallélisme de tenseurs plus élevé.

Quantification

La quantification consiste à réduire la précision des poids et des activations utilisés par les réseaux neuronaux. Nous utilisons cette technique pour réduire de moitié la consommation de mémoire GPU lors du passage du fp16 au fp8. Cela permet d'exécuter le même modèle avec une consommation globale de mémoire GPU moindre, ce qui autorise un parallélisme de tenseurs plus faible, augmentant ainsi le débit.

Les implémentations de quantification peuvent potentiellement dégrader la précision. Par conséquent, nous avons évalué la précision pour différentes précisions en comparant leur statistique de perplexité, une mesure de la capacité du LLM à prédire le jeton suivant dans une phrase, sur le corpus WikiText. Pour la virgule flottante 8 bits et le poids 8 bits avec activation 8 bits et SmoothQuant (w8a8 SQ), il n'y a eu aucun changement significatif de la perplexité (< 1 %) par rapport au fp16 sur WikiText, nous avons donc décidé de poursuivre. Cependant, w4a16 a montré un changement substantiel de 7 % de la perplexité, potentiellement attribuable à la précision encore plus faible et aux conversions dynamiques nécessaires entre int4 et fp16.

Taille des lots

Le parallélisme par lots est une stratégie classique pour optimiser les performances d'un système aux ressources contraintes. En traitant plusieurs requêtes à chaque passage direct dans le réseau neuronal, le traitement par lots augmente le débit au prix d'une certaine latence. Il entraîne également une consommation de mémoire GPU plus élevée, car la taille du cache KV qui gère le mécanisme d'attention augmente linéairement avec la taille des lots.

Dans le cas de Llama 2 70B (qui compte 80 couches), fp16 avec une taille de lot de 32 pour une taille de contexte de 4096, la taille du cache KV atteint un volume substantiel de 40 Go. Cela empêche Llama 2 70B fp16, dont les poids occupent à eux seuls 140 Go, de tenir confortablement dans les 160 Go de mémoire GPU disponibles avec un parallélisme de tenseurs 2 (TP-2).

Résultats

Nous avons balayé les combinaisons compatibles des 4 variables de l'expérience et présentons ci-dessous les tendances les plus révélatrices.

Figure 1 - La latence des requêtes avec une taille de lot variable sur cinq configurations différentes, toutes avec un parallélisme de tenseurs 8, ce qui donne la meilleure latence avec 8 GPU disponibles. Au sein de chaque configuration, la latence double généralement lors du passage d'une taille de lot de 1 à 32, et double encore de 32 à 128. Pour des tailles de lots suffisamment grandes, le H100 réduit approximativement de moitié la latence par rapport à l'A100. L'A100 utilise une précision mixte car l'architecture ne prend pas nativement en charge le fp8. Le w8a8 avec SmoothQuant (SQ) est destiné à ressembler au fp8.

L'amélioration de la latence due à la quantification est de l'ordre de 10 % lorsque l'on compare H100 fp16 → fp8 et A100 fp16 → w8a8 avec SmoothQuant. Cependant, la précision mixte w4a16 est en fait plus performante avec de petites tailles de lots et moins performante avec des tailles de lots plus grandes par rapport au fp16. Cela peut être dû à plusieurs facteurs, notamment des noyaux de calcul moins optimisés, le temps de conversion entre int4 et fp16, et le fait que w4a16 utilise toujours des virgules flottantes 16 bits pour les activations, n'entraînant aucune économie sur les dimensions du cache KV. Étant donné que w4a16 a également démontré une précision inférieure, nous concluons que nous devrions nous en tenir à w8a8 SQ pour les A100 et au fp8 pour les H100.

Figure 2 - Le débit sur les configurations TP-8 avec différentes architectures, quantifications et tailles de lots. Pour chaque architecture et quantification, la taille de lot choisie était la plus élevée respectant une exigence de latence de 25 600 ms (20 jetons par seconde pour 512 jetons), afin de comparer des configurations ayant une latence similaire. Sous cette exigence, le H100 avec BS-128 atteint 228 % du débit par rapport à l'A100 BS-64 utilisant la même quantification (fp16) et présente même une latence de réponse plus faible malgré le doublement de la taille du lot. La quantification avec fp8 améliore ce facteur à 251 %.

Dans nos deux premières figures, nous ne présentons que des configurations TP-8. Le H100 atteint 54 % de latence et 184 % de débit par rapport à l'A100 lorsque les deux utilisent fp16 / BS-128 / TP-8, ce qui s'améliore à 49 % de latence et 202 % de débit lors de l'utilisation de fp8 sur le H100. Cette amélioration des performances peut être attribuée à l'augmentation de la puissance de calcul et de la bande passante mémoire entre le H100 et l'A100. Notamment, la différence est moins prononcée avec des tailles de lots plus petites où l'utilisation peut être inférieure.

À mesure que nous développons notre plateforme, nous souhaitons respecter certaines exigences de latence pour nos utilisateurs tout en maximisant le débit. Par conséquent, plutôt que de comparer A100 et H100 avec la même taille de lot, il est plus judicieux de comparer leur débit uniquement dans des configurations où ils satisfont une exigence de latence. Nous avons fixé un seuil à 25 600 ms de latence pour l'achèvement des 512 jetons de sortie et avons constaté que H100 / TP-8 / fp8 / BS-128 donne 251 % de débit par rapport à A100 / TP-8 / fp16 / BS-64, car il est capable de traiter le double de la taille de lot avec une latence inférieure. Étant donné que la quantification permet des économies de mémoire GPU, nous devons maintenant évaluer comment le parallélisme de tenseurs peut ajouter une nouvelle couche d'optimisation.

Figure 3 - La latence à travers des tailles de lots et un parallélisme de tenseurs variables pour H100 fp8. La latence double généralement lors du passage d'une taille de lot de 1 à 32, et double encore de 32 à 128. Le TP-2 est systématiquement environ deux fois plus lent que le TP-8 lorsque les tailles de lots sont égales. Le fait de doubler le parallélisme de tenseurs tout en doublant la taille du lot maintient la latence relativement stable, car le nombre de lots traités par GPU reste égal.

En ce qui concerne la quantification et l'architecture, il y a des gagnants évidents : le H100 domine l'A100 et la quantification à précision réduite améliore l'utilisation de la mémoire, la latence et le débit. Cependant, la taille des lots et le parallélisme de tenseurs présentent un compromis dans nos mesures clés. Une taille de lot plus grande optimise le débit au prix d'une latence accrue et d'une consommation mémoire supérieure. D'un autre côté, un parallélisme de tenseurs plus élevé augmente le réservoir global de mémoire disponible et optimise la latence, mais se fait au détriment du débit en raison des coûts de synchronisation des multiplications de matrices distribuées et de l'immobilisation de davantage de ressources GPU.

Figure 4 - Le débit à travers des tailles de lots et un parallélisme de tenseurs variables pour H100 fp8. Le débit le plus élevé provient de TP-2 BS-128, à 460 % par rapport à la référence A100/TP-8/fp16/BS-64. Cependant, TP-2 BS-128 est également le résultat le plus lent de la Figure 3.

La configuration maximisant le débit de notre expérience est H100 / fp8 / TP-2 / BS-128, à 767 jetons de sortie par seconde et par GPU. Il s'agit d'une amélioration de 460 % par rapport à A100 / fp16 / TP-8 / BS-64. Cependant, cela se fait au prix d'une latence doublée (proche de 42 000 ms pour 512 jetons de sortie), elle peut donc ne pas convenir comme configuration de production. Les résultats de TP-4 BS-128 (626 jetons/sec/gpu à 26 188 ms de temps de réponse) et TP-2 BS-32 (435 jetons/sec/gpu à 18 821 ms de temps de réponse) peuvent représenter de meilleurs compromis sur nos mesures clés.

Conclusion

Nos résultats démontrent que :

Nous atteignons 54 % de latence et 184 % de débit en utilisant le H100 par rapport à l'A100 avec la même configuration, ce qui s'améliore à 49 % et 202 % respectivement lorsque le H100 tire parti de sa prise en charge native du fp8.

Lors de la maximisation du débit sous contrainte de latence, H100 / fp8 / TP-8 / BS-128 donne 251 % de débit par rapport à A100 / fp16 / TP-8 / BS-64, car il peut traiter le double de la taille de lot à une vitesse supérieure.

En profitant du H100 avec TP-2 et fp8, nous pouvons atteindre 373 % du débit de A100 / fp16 / TP-8 / BS-128, avec une augmentation de latence inférieure à 10 %.

La taille des lots et le parallélisme de tenseurs présentent un compromis entre débit et latence pour l'opérateur d'un système d'inférence LLM.

Ces résultats nous donnent confiance dans la transition complète vers les GPU H100 dans notre pile matérielle précédemment alimentée par des A100. Nous sommes ravis de pouvoir confirmer les gains de performance annoncés par NVIDIA et attendons avec impatience leurs prochaines avancées en matière de matériel accéléré.

Et après ?

Notre prochaine frontière pour l'optimisation consiste à examiner l'impact sur la précision et les performances de la dispersion structurée et de la précision int4, qui pourraient réduire considérablement l'empreinte mémoire GPU de Llama 2 70B et offrir jusqu'à 2x d'amélioration en termes de latence. Nous sommes enthousiastes à l'idée de poursuivre ce parcours vers une inférence ultra-rapide et espérons permettre à nos utilisateurs de créer des applications puissantes sur notre plateforme.

À court terme, pplx-api supprimera les limites de débit et proposera davantage de LLM Perplexity personnalisés, y compris un LLM alimenté par Internet avec ancrage de faits.

Inscrivez-vous à Perplexity Pro sur perplexity.ai/pro. Accédez à notre pplx-api de pointe et tirez parti de ces fonctionnalités avancées dans vos projets. Découvrez-en plus sur pplx-api sur notre blog.

Intéressé par le futur de l'IA ? Nous recrutons ! Faites partie d'une équipe qui développe une infrastructure LLM générative à grande échelle. Explorez les opportunités sur Perplexity Careers.

Auteurs :

Aarash Heydari, Grigorii Alekseev, Kevin Hu, Denis Yarats