La construction des grands modèles de langage (LLM)
27 août 2024
Intelligence Artificielle
Introduction aux LLM
Commençons. Je vais parler aujourd'hui de la construction des LLM. Je pense que beaucoup d'entre vous ont déjà entendu parler des LLM, mais pour un rappel rapide, les LLM — signifiant grands modèles de langage — sont essentiellement tous les chatbots dont vous avez entendu parler récemment : ChatGPT d'OpenAI, Claude d'Anthropic, Gemini, Llama, et d'autres modèles de ce genre. Aujourd'hui, nous allons parler de la manière dont ils fonctionnent réellement. Ce sera une vue d'ensemble car il n'y a qu'un seul cours et il est difficile de tout condenser, mais j'espère aborder tous les composants nécessaires pour entraîner certains de ces LLM. De plus, si vous avez des questions, n'hésitez pas à m'interrompre. Si vous avez une question, il est fort probable que d'autres personnes dans la salle ou sur Zoom se posent la même, alors n'hésitez pas à la poser.
Les composants clés de l'entraînement
Excellent. Qu'est-ce qui compte lors de l'entraînement des LLM ? Il y a quelques composants clés. L'un est l'architecture. Comme vous le savez probablement tous, les LLM sont des réseaux de neurones, vous devez donc réfléchir à l'architecture que vous utilisez. Un autre composant vraiment important est la perte d'entraînement et l'algorithme d'entraînement — comment vous entraînez réellement ces modèles. Ensuite, il y a les données — sur quoi vous entraînez ces modèles. Vient ensuite l'évaluation : comment savoir si vous progressez réellement vers l'objectif des LLM ? Enfin, il y a la composante système : comment faire fonctionner concrètement ces modèles sur du matériel moderne ? C'est vraiment important car ces modèles sont volumineux. Aujourd'hui plus que jamais, les systèmes sont un sujet crucial pour les LLM.
Concernant ces cinq composants, vous savez probablement que les LLM sont tous basés sur des transformers, ou du moins sur une certaine version des transformers. En fait, je ne vais pas parler de l'architecture aujourd'hui. D'abord, parce que j'ai donné un cours sur les transformers il y a quelques semaines, et ensuite, parce que vous pouvez trouver énormément d'informations en ligne sur les transformers. Je pense qu'il y a beaucoup moins d'informations sur les quatre autres sujets, donc je veux vraiment parler de ceux-là.
Une autre chose à dire est que la majeure partie du monde académique se concentre sur l'architecture, les algorithmes d'entraînement et les pertes. En tant qu'universitaires — et je l'ai fait pendant une grande partie de ma carrière — nous aimons penser que c'est très important. Mais en réalité, ce qui compte en pratique, ce sont surtout les trois autres sujets : les données, l'évaluation et les systèmes, qui sont les points sur lesquels l'industrie se concentre majoritairement. C'est aussi l'une des raisons pour lesquelles je ne veux pas trop parler de l'architecture, car le reste est super important.
Le pré-entraînement et la modélisation du langage
Pour un aperçu du cours, je vais parler du pré-entraînement. C'est le terme général pour le paradigme classique de modélisation du langage où vous entraînez essentiellement un modèle de langage pour modéliser virtuellement tout l'internet. Ensuite, il y a le post-entraînement, qui est un paradigme plus récent consistant à prendre ces grands modèles de langage et à en faire essentiellement des assistants IA. C'est une tendance plus récente depuis ChatGPT. Si vous avez déjà entendu parler de GPT-2 ou GPT-3, on est vraiment dans le domaine du pré-entraînement. Si vous avez entendu parler de ChatGPT, on est dans le domaine du post-entraînement. Je parlerai des deux, mais je commencerai par le pré-entraînement et plus précisément par la tâche et la perte que les gens utilisent réellement.
La modélisation du langage est un rappel rapide. À haut niveau, les modèles de langage sont simplement des modèles de distribution de probabilité sur des séquences de jetons ou de mots. C'est fondamentalement un modèle de P de X1 à XL, où X1 est le mot un et XL est le dernier mot de la séquence. Concrètement, si vous avez une phrase comme « la souris a mangé le fromage », ce que le modèle de langage vous donne est simplement la probabilité que cette phrase soit prononcée par un humain ou trouvée en ligne. Si vous avez une autre phrase comme « la souris mangé fromage » avec des fautes de grammaire, le modèle devrait avoir une certaine connaissance syntaxique et savoir que cela a moins de probabilité d'apparaître. Si vous avez une phrase comme « le fromage a mangé la souris », le modèle devrait idéalement savoir que le fromage ne mange pas habituellement les souris, ce qui implique une certaine connaissance sémantique. C'est en gros ce que sont les modèles de langage à haut niveau.
Un terme que vous avez probablement beaucoup entendu aux informations est « modèles génératifs ». Ce sont simplement des modèles capables de générer des phrases ou des données. La raison pour laquelle nous disons que les modèles de langage sont des modèles génératifs est qu'une fois que vous avez un modèle de distribution, vous pouvez y effectuer un échantillonnage et générer des phrases.
Le type de modèles que les gens utilisent actuellement sont ce qu'on appelle des modèles de langage autorégressifs. L'idée clé est de prendre cette distribution sur les mots et de la décomposer en la distribution du premier mot, multipliée par la probabilité du second mot étant donné le premier, et ainsi de suite. C'est juste la règle de probabilité en chaîne, sans approximation. C'est juste une façon de modéliser une distribution. De manière un peu plus concise, on peut l'écrire comme le produit des probabilités du mot suivant étant donné tout ce qui s'est passé dans le contexte passé. C'est ce que nous appelons les modèles de langage autorégressifs. Ce n'est pas la seule façon de modéliser une distribution, mais c'est le paradigme actuel. Un inconvénient est que lors de l'échantillonnage, on a une boucle « for » qui génère le mot suivant puis se conditionne sur celui-ci. Une phrase plus longue prend plus de temps à générer. Je vais parler de ce paradigme.
Fonctionnement des modèles autorégressifs
À haut niveau, la tâche d'un modèle de langage autorégressif est simplement de prédire le mot suivant. Si nous avons une phrase comme « elle préfère probablement », un mot suivant potentiel pourrait être « les chiens ». Nous commençons par segmenter ces mots ou sous-mots en jetons et attribuons un identifiant à chaque jeton. Ensuite, vous le passez dans ce modèle « boîte noire » et obtenez une distribution de probabilité sur le jeton suivant. Vous échantillonnez à partir de cette distribution pour obtenir un nouveau jeton, puis vous convertissez l'identifiant en texte. Les deux dernières étapes ne sont nécessaires que pendant l'inférence. Pendant l'entraînement, vous prédisez le jeton le plus probable et le comparez au jeton réel qui est apparu en pratique, puis vous modifiez les poids de votre modèle pour augmenter cette probabilité.
Pour être un peu plus spécifique sur les modèles de langage neuronaux autorégressifs sans encore parler d'architecture — oui ?
Sur la diapositive précédente, quand vous prédisez la probabilité du prochain jeton, est-ce que cela signifie que votre vecteur de sortie final doit avoir la même dimensionnalité que le nombre de jetons que vous possédez ?
Oui.
Comment gérez-vous l'ajout de nouveaux jetons à votre corpus au fil du temps ? Comment cela fonctionne-t-il ?
Nous parlerons de la tokenisation plus tard. On ne peut pas facilement gérer l'ajout de nouveaux jetons ; il existe des méthodes pour le faire, mais essentiellement les gens ne le font pas. Il est vraiment important de réfléchir à la manière dont vous segmentez votre texte en jetons. La taille du vocabulaire — le nombre de jetons que vous possédez — est essentiellement la sortie de votre modèle de langage, elle est donc en réalité assez importante.
Dans les modèles de langage neuronaux autorégressifs, la première chose que vous faites est de prendre chaque jeton et de le plonger pour obtenir une représentation vectorielle. Vous les passez à travers un réseau de neurones — un transformer — et obtenez une représentation de tout le contexte de la phrase. Vous le passez à travers une couche linéaire pour le projeter afin que la sortie corresponde au nombre de jetons. Vous le passez ensuite dans un softmax et obtenez une distribution de probabilité sur les mots suivants étant donné chaque mot du contexte.
La perte que vous utilisez est essentiellement une tâche de classification du jeton suivant. C'est une tâche simple d'apprentissage automatique utilisant la perte d'entropie croisée où vous regardez la distribution cible réelle, qui est un encodage « one-hot ». Par exemple, si le mot réel est « chat », c'est une distribution « one-hot » sur « chat », et vous faites une entropie croisée pour augmenter la probabilité de générer ce jeton et diminuer les autres. Minimiser cette perte équivaut à maximiser la log-vraisemblance du texte. Quelqu'un a-t-il des questions ?
L'importance de la tokenisation
Les tokeniseurs sont extrêmement importants, et il est essentiel de comprendre au moins ce qu'ils font à haut niveau. Pourquoi en avons-nous besoin ? Premièrement, ils sont plus généraux que les mots. Si vous n'utilisez que des mots, une faute de frappe pourrait donner un mot sans jeton associé, ce qui signifie que vous ne pouvez pas le passer au modèle. De plus, bien que les « mots » conviennent aux langues d'origine latine, une langue comme le thaï n'a pas d'espaces entre les mots, on ne peut donc pas segmenter par espaces. Deuxièmement, vous pourriez penser à segmenter caractère par caractère, ce qui fonctionne bien, mais alors votre séquence devient super longue. Comme vous vous en souvenez, la complexité des transformers croît de manière quadratique avec la longueur de la séquence. Les tokeniseurs essaient de gérer ces deux problèmes en attribuant un certain jeton aux sous-séquences courantes. En moyenne, chaque jeton fait environ trois à quatre lettres.
Il existe de nombreux algorithmes de tokenisation, tels que le « byte pair encoding ». Pour entraîner un tokeniseur, on commence par un très large corpus de texte. On associe chaque caractère de ce corpus à un jeton différent, puis on fusionne les paires courantes. Par exemple, si vous voyez « T » et « O » souvent ensemble, cela devient un nouveau jeton. Vous continuez ce processus pour « tok », « toke » et « token ». En réalité, on fait cela sur des corpus bien plus vastes. C'est le véritable tokeniseur utilisé par GPT-3 ou ChatGPT, où « token » devient son propre jeton et « tokenizer » est divisé en « token » et « izer ». Des questions là-dessus ?
Comment gérez-vous les espaces et la nécessité de distinguer les mots ?
Il y a une étape avant les tokeniseurs appelée pré-tokeniseurs. En théorie, chaque espace et signe de ponctuation pourrait simplement avoir son propre jeton, mais l'entraînement des tokeniseurs prend beaucoup de temps. Donc, par souci d'efficacité, les pré-tokeniseurs — qui sont souvent spécifiques à l'anglais — empêchent la fusion de jetons à travers les espaces. C'est juste une optimisation de calcul ; on pourrait théoriquement les traiter comme n'importe quel autre caractère.
Lorsque vous fusionnez des jetons, supprimez-vous les jetons que vous avez fusionnés ou gardez-vous les jetons plus petits que vous avez fusionnés ?
En fait, on garde les jetons plus petits. Sur un grand corpus, vous aurez tout. Vous gardez les petits pour qu'en cas de fautes de grammaire ou de frappe, vous puissiez toujours représenter ces mots caractère par caractère.
Les jetons sont-ils uniques ? Pour « TOKEN », n'y a-t-il qu'une seule occurrence, ou avez-vous besoin de plusieurs occurrences pour qu'elles puissent prendre des significations différentes ?
Chaque jeton a son propre identifiant unique. Un mot comme « bank » — se référant à l'argent ou à la rive — aura le même jeton. Le transformer apprend des mots environnants à associer ce jeton à la bonne représentation. C'est le transformer qui fait cela, pas le tokeniseur.
Vous avez mentionné que pendant la tokenisation, vous gardez les plus petits jetons avec lesquels vous avez commencé. Si vous commencez par un « T », vous le gardez puis construisez jusqu'à pouvoir encoder « token ». Si vous n'avez pas été entraîné sur « token » mais qu'il est dans vos données, comment le tokeniseur sait-il s'il doit utiliser « token » ou « T » ?
Lorsque vous appliquez le tokeniseur, vous choisissez toujours le plus grand jeton possible. Si vous pouvez utiliser « token », vous n'utiliserez jamais « T ». Certaines personnes pensent que nous devrions nous éloigner des tokeniseurs et utiliser des caractères ou des octets, mais il y a actuellement un problème de longueur de séquence. Peut-être qu'à l'avenir, les architectures ne seront plus à échelle quadratique et que nous pourrons nous en passer.
Pourriez-vous partager les inconvénients ? Pourquoi les gens veulent-ils s'éloigner du tokeniseur ?
Les mathématiques sont un bon exemple ; les nombres ne sont pas tokenisés de manière idéale. Par exemple, « 327 » pourrait avoir son propre jeton, de sorte que le modèle ne voie pas les chiffres séparément pour la composition. Un autre exemple est le code ; GPT-4 a changé la façon de tokeniser le code parce que les retraits de quatre espaces en Python étaient auparavant gérés bizarrement, ce qui rendait la compréhension difficile pour le modèle. Les tokeniseurs comptent beaucoup, mais je vais passer à autre chose pour l'instant.
Évaluation : Perplexité et Benchmarks
Les LLM sont généralement évalués à l'aide de la perplexité, qui est essentiellement votre perte de validation. La perplexité est un peu plus interprétable : c'est la perte moyenne par jeton mise à l'exponentielle. Nous utilisons l'exponentielle parce que les humains ont du mal à penser en espace logarithmique, et cela remet tout en unités de taille de vocabulaire. La perplexité est indépendante de la longueur de la séquence et varie entre un et la taille du vocabulaire. Une perplexité de un signifie que vous prédisez chaque mot parfaitement. Si vous n'avez aucune idée, vous obtenez une perplexité égale à la taille du vocabulaire. Essentiellement, la perplexité est le nombre de jetons entre lesquels votre modèle « hésite ».
La perplexité s'est considérablement améliorée ; sur un jeu de données standard entre 2017 et 2023, elle est passée d'environ 70 jetons à moins de 10. La perplexité n'est plus couramment utilisée dans les tests de référence académiques car elle dépend du tokeniseur et des données d'évaluation spécifiques, mais elle reste très importante pour le développement interne des LLM.
Une évaluation académique plus courante consiste à agréger les résultats à travers des benchmarks de NLP classiques comme Helm ou le classement Hugging Face Open LLM. Helm inclut des tâches comme le jeu des questions-réponses, où la réponse réelle est connue. Vous évaluez les modèles en regardant quelle est leur probabilité de générer la réponse réelle par rapport aux alternatives.
Par exemple, MMLU est le benchmark académique le plus courant, collectant des questions et des réponses dans des domaines tels que la médecine universitaire, la physique et l'astronomie. En astronomie, vous pourriez demander ce qui est vrai pour une supernova de type 1A et proposer quatre réponses potentielles. Vous pouvez examiner la probabilité que le modèle génère ces réponses ou contraindre le modèle pour voir si le jeton suivant est A, B, C ou D. Oui ?
Étant donné que nous créons du texte libre en sortie, comment évaluez-vous un modèle s'il donne quelque chose de sémantiquement identique mais qui n'est pas la liste exacte de jetons attendue ?
Dans ce cas, nous ne faisons pas d'évaluation libre. Pour évaluer MMLU, soit vous regardez la probabilité que le modèle génère A, B, C et D, soit vous demandez au modèle lequel est le plus probable et vérifiez si le jeton suivant est l'une de ces quatre options.
Quand vous dites que vous contraignez le modèle, voulez-vous dire que vous contraignez l'invite ou voulez-vous dire que sur toute cette distribution de probabilité à vos sorties, vous ne comparez que le jeton A et le jeton B ?
Dans le second cas, vous incitez le modèle par une invite et le contraignez à ne regarder que ces quatre jetons. Dans le premier cas, vous n'avez même pas besoin d'échantillonner à partir du modèle ; vous utilisez simplement P de X1 à XL pour voir si la phrase la plus probable est la réponse réelle. L'évaluation des questions ouvertes est difficile, et nous en reparlerons plus tard.
Plus tôt, vous avez mentionné que des mesures comme la perplexité ne sont pas habituellement utilisées car cela dépend de la façon dont vous effectuez votre tokenisation et de certains choix de conception. Pourriez-vous en dire plus ?
La perplexité se situe entre un et la taille du vocabulaire. Si ChatGPT utilise un tokeniseur avec 10 000 jetons mais que Gemini en utilise 100 000, la limite supérieure pour Gemini est pire que pour ChatGPT. C'est un peu plus complexe, mais cela montre pourquoi le tokeniseur compte. Très bien.
L'évaluation présente de nombreux défis. Les entreprises et les organisations utilisent différentes manières d'évaluer MMLU, ce qui conduit à des résultats incohérents. Par exemple, Llama 65B avait une précision de 63,7 % sur Helm mais seulement 48,8 % sur un autre benchmark. C'est uniquement dû à la méthode d'évaluation, et l'ingénierie des invites est un autre problème. Ce n'est pas aussi simple qu'il n'y paraît.
Comment pouvons-nous nous assurer que tous ces modèles ne sont pas entraînés sur le benchmark ?
La contamination entre l'entraînement et le test est un véritable problème dans le milieu académique. Des chercheurs du laboratoire de Tatsunori Hashimoto ont trouvé une astuce : comme la plupart des jeux de données en ligne ne sont pas randomisés, on peut voir si le modèle trouve les exemples du jeu de test plus probables dans leur ordre d'origine que dans un ordre randomisé. Si c'est le cas, ils étaient probablement dans le jeu d'entraînement. La contamination train-test est très importante pour le benchmarking académique.
La gestion des données de pré-entraînement
En ce qui concerne les données, les gens disent s'entraîner sur « tout l'internet », mais l'internet est sale et peu représentatif. D'abord, on utilise des robots d'indexation comme Common Crawl, qui ajoute chaque mois de nouveaux sites web trouvés par Google. Il contient actuellement environ 250 milliards de pages et environ un pétaoctet de données. Si vous regardez une page HTML aléatoire de Common Crawl, le contenu est souvent désordonné — les phrases sont inachevées ou remplies de texte de remplissage. Il n'est pas utile d'entraîner un grand modèle de langage à générer du contenu de ce type.
Plusieurs étapes sont nécessaires. D'abord, on extrait le texte du HTML, ce qui est difficile à cause des mathématiques ou des éléments répétitifs comme les en-têtes et les pieds de page. Ensuite, on filtre les contenus indésirables comme le matériel pornographique, les contenus préjudiciables ou les informations personnelles identifiables (PII). Les entreprises ont de longues listes noires et utilisent de petits modèles pour supprimer les PII. C'est une quantité de travail considérable.
Vient ensuite la déduplication. On veut supprimer les en-têtes et pieds de page identiques, les URL dupliquées et les paragraphes de livres communs qui apparaissent des milliers de fois. La déduplication à grande échelle est un défi. Une fois cela fait, on utilise un filtrage basé sur des règles heuristiques pour supprimer les documents de faible qualité basés sur des distributions de jetons aberrantes, des longueurs de mots excessives ou des tailles de documents très petites ou très grandes.
Pourquoi filtrons-nous les contenus indésirables de notre jeu de données au lieu de les intégrer comme une perte supervisée ? Ne pouvons-nous pas pénaliser activement le modèle pour la génération de discours de haine ?
Nous ferons cela pendant le post-entraînement. Le pré-entraînement sert juste à modéliser la façon dont les humains parlent en général tout en supprimant le superflu. Mais c'est une bonne idée, et nous ferons exactement cela plus tard.
Vient ensuite le filtrage basé sur des modèles. Une astuce élégante consiste à prendre tout Wikipédia et à regarder ses liens externes. Si quelque chose est référencé par Wikipédia, c'est probablement un site web de haute qualité. On entraîne un classifieur pour prédire si un document ressemble à une référence Wikipédia ou à un contenu web aléatoire, puis on surpondère le contenu de haute qualité.
Ensuite, vous classez les données dans des domaines comme le divertissement, les livres ou le code, et vous les surpondérez ou les sous-pondérez. Surpondérer le code aide souvent les capacités de raisonnement d'un modèle. Les livres sont généralement surpondérés, tandis que le divertissement est sous-pondéré. De nos jours, les pipelines font cela de manière plus automatique.
À la fin de l'entraînement, vous utilisez des données de haute qualité comme Wikipédia tout en diminuant le taux d'apprentissage, ce qui revient essentiellement à faire du surapprentissage sur des données humaines de haute qualité. S'entraîner sur l'internet représente beaucoup de travail que nous n'avons pas encore totalement résolu.
Collecter des données est une part énorme de la modélisation pratique des grands modèles de langage ; certains disent que c'est en fait la clé. Oui ?
Quand vous commencez avec un pétaoctet de données, quelle est la quantité typique de données qu'il vous reste à la fin ? Et quelle taille d'équipe faut-il pour gérer ces étapes de filtration ?
Votre question est de savoir quelle est la taille des données après filtrage ?
Oui, après filtrage. Et de quelle taille d'équipe avez-vous besoin pour les étapes de filtration ?
Combien de personnes auriez-vous besoin pour cela ?
Je répondrai à la taille des données dans une seconde. Concernant l'équipe, le côté données représente souvent un effort plus important que le côté modélisation. Par exemple, dans l'équipe Llama d'environ 70 personnes, peut-être 15 travaillent sur les données. Vous n'avez pas besoin d'une équipe immense, mais vous avez besoin de beaucoup de puissance de calcul — spécifiquement des CPU — pour traiter les données.
Nous n'avons pas encore résolu la question des données de pré-entraînement. Des recherches sont nécessaires sur le traitement efficace, l'équilibrage des domaines et la génération de données synthétiques puisque nous n'avons pas assez de données internet. Il y a beaucoup de secret car les données sont un avantage concurrentiel clé, et les entreprises veulent éviter toute responsabilité en matière de droit d'auteur pour l'entraînement sur des livres.
En ce qui concerne les benchmarks académiques courants, les premiers modèles étaient entraînés sur environ 150 milliards de jetons, ce qui représente environ 800 gigaoctets. Les modèles modernes utilisent environ 15 billions de jetons, soit environ 80 000 gigaoctets.
Un benchmark célèbre est « The Pile », qui comprend arXiv, Wikipédia, GitHub et des livres. Mais même à 825 gigaoctets, c'est 100 fois plus petit que les jeux de données actuels, on ne peut donc pas compter uniquement sur Wikipédia et GitHub. Llama 3 a été entraîné sur 15 billions de jetons. Nous ne savons pas pour GPT-4, mais les fuites suggèrent environ 13 billions de jetons.
Les lois d'échelle (Scaling Laws)
Excellent. Les lois d'échelle. D'autres questions sur les données avant de passer aux lois d'échelle ?
Je vous donne beaucoup d'informations, mais l'entraînement de ces modèles implique énormément de choses.
Lois d'échelle : la découverte empirique depuis 2020 est que plus de données et des modèles plus grands entraînent de meilleures performances. C'est différent du surapprentissage habituellement enseigné dans ce cours — bien que pour l'examen, le surapprentissage existe. Les modèles plus grands sont systématiquement plus performants.
Étant donné que plus de données et des modèles plus grands donnent de meilleures performances, pouvons-nous prédire à quel point la performance sera meilleure à mesure que nous augmentons ces facteurs ?
Étonnamment, cela fonctionne. Ces graphiques d'OpenAI montrent que sur une échelle log-log, la loi d'échelle est linéaire. Vous pouvez prédire de combien la perte de test diminuera en fonction du calcul, des données ou des paramètres. C'est fou parce que nous pouvons prédire comment les modèles se comporteront des années à l'avance en fonction de la puissance de calcul ajoutée. Oui ?
Quelle perte utilisent-ils ici ? Est-ce la perplexité ?
La perplexité est deux à la puissance de la perte, donc ceci est le logarithme de la perplexité.
Lorsque vous augmentez les paramètres du modèle ou la taille du jeu de données, cela n'augmente-t-il pas intrinsèquement votre calcul ? Est-ce que tout se résume au calcul total ?
Le calcul est un facteur à la fois des données et des paramètres. Si vous augmentez les paramètres, vous devriez augmenter les données. Personne ne fait actuellement plusieurs époques car nous avons encore assez de données. C'est la même tendance : augmentez le calcul, diminuez la perte. Oui ?
Avons-nous vu des chiffres pour les deux dernières années ? Est-ce que cela tient toujours ?
Cela tient toujours étonnamment bien. Oui ?
N'y a-t-il aucune preuve empirique d'un éventuel plateau ? Théoriquement, nous nous y attendrions.
Il n'y a pas encore de preuve empirique d'un plateau. La plupart des gens pensent que cela finira par arriver, mais nous ne savons pas quand. Mathématiquement, il n'y a pas d'obligation de plateau sur une échelle logarithmique.
Je vais maintenant parler davantage des lois d'échelle.
Pourquoi les lois d'échelle sont-elles cool ? Imaginez que vous ayez 10 000 GPU pendant un mois. Quel modèle entraîneriez-vous ? Dans l'ancien pipeline, vous ajusteriez les hyperparamètres sur de grands modèles. Si vous aviez 30 jours, vous pourriez entraîner 30 modèles pendant un jour chacun et choisir le meilleur. Mais ce modèle n'aurait été entraîné que pendant un jour.
Le nouveau pipeline consiste à trouver une recette de mise à l'échelle — comme diminuer le taux d'apprentissage à mesure que l'on augmente la taille du modèle — et à ajuster les hyperparamètres sur des modèles plus petits de différentes tailles. Ensuite, vous ajustez une loi d'échelle pour extrapoler quelle configuration serait la meilleure pour un modèle plus grand et entraînez ce modèle géant pendant 27 jours. Vous faites l'ajustement des hyperparamètres à des échelles plus petites et prédisez la performance pour le plus grand.
Par exemple, pour décider entre les transformers et les LSTM, vous pouvez entraîner les deux à différentes échelles. Vous verrez que les transformers passent mieux à l'échelle. Les lois d'échelle ont deux facteurs importants : le taux de mise à l'échelle (la pente) et l'ordonnée à l'origine. Un modèle peut commencer moins bien mais s'améliorer avec le temps. Les lois d'échelle sont vraiment utiles pour faire ces prédictions.
Des questions là-dessus ? Oui ?
À quel point sont-elles sensibles aux petites différences architecturales ? Devez-vous ajuster votre propre courbe et extrapoler pour votre architecture spécifique ?
Pour proposer une nouvelle fonction d'activation, vous ajusteriez une loi d'échelle et montreriez qu'elle est meilleure que quelque chose comme GeLU. Mais les petites différences architecturales ne font souvent que modifier légèrement l'ordonnée à l'origine, ce qui est secondaire par rapport au simple fait d'entraîner plus longtemps. C'est pourquoi les gens passent trop de temps sur l'architecture ; la qualité des données compte beaucoup plus pour les lois d'échelle.
Les lois d'échelle aident également à allouer les ressources de manière optimale : faut-il entraîner un modèle plus grand sur moins de données, ou un modèle plus petit sur plus de données ?
L'article « Chinchilla » a tracé des « isoflops » — des courbes où le calcul est constant mais la taille du modèle et le nombre de jetons varient. En choisissant le meilleur modèle pour chaque niveau de calcul et en le traçant sur une échelle log-log, on trouve une loi d'échelle qui prédit le nombre optimal de paramètres pour n'importe quelle quantité de calcul. Si vous faites cela bien, les tendances se maintiennent.
Chinchilla a trouvé que le ratio optimal est de 20 jetons pour chaque paramètre. Cependant, ce n'est que pour l'entraînement. Les entreprises se soucient également du coût d'inférence, ce qui favorise les modèles plus petits. Si vous tenez compte de l'inférence, le ratio est plus proche de 150 jetons par paramètre. C'est ce que les modèles de production actuels utilisent.
Des questions sur Chinchilla ?
Excellent.
Quel est le coût de l'inférence par rapport à l'entraînement ?
C'est très cher. Par exemple, ChatGPT a des centaines de millions d'utilisateurs. Bien que je ne parle pas de l'optimisation de l'inférence aujourd'hui, c'est un sujet énorme.
Les lois d'échelle aident à décider quels mélanges de données utiliser, s'il faut rendre les modèles plus larges ou plus profonds, et s'il faut investir dans plus de GPU ou plus de données.
« The Bitter Lesson » de Richard Sutton note qu'à mesure que le calcul s'améliore, les architectures qui exploitent simplement le calcul gagneront. Cela signifie que les systèmes et les données comptent plus que les différences architecturales mineures. C'est pourquoi OpenAI s'est concentré sur des choses simples, les a bien faites et les a mises à l'échelle.
Analyse des coûts et ressources
Je vais vous donner quelques calculs de coin de table pour le coût de l'entraînement. Prenons Llama 3 400B comme exemple.
Il a été entraîné sur 15,6 billions de jetons et possède 405 milliards de paramètres — environ 40 jetons par paramètre. Cela privilégie l'optimalité de l'entraînement.
Les flops peuvent être approximés par six fois les paramètres multipliés par le nombre de jetons. Pour ce modèle, c'est 3,8 x 10^25 flops. C'est notable car un décret américain exige un examen spécial pour les modèles dépassant 10^26 flops, et Meta est resté juste en dessous de cette limite.
Est-ce l'unité NP ?
« P » représente les paramètres et « N » le nombre de jetons. C'est juste une approximation.
Concernant le calcul, ils ont utilisé 16 000 H100. D'après le débit annoncé, cela représente environ 70 jours, soit 26 à 30 millions d'heures GPU.
Si vous louez des H100 à une borne inférieure de 2 $ l'heure, 26 millions d'heures coûtent 52 millions de dollars. L'ajout de 50 employés à 500 000 $ par an ajoute 25 millions de dollars supplémentaires. Au total, l'entraînement a coûté environ 75 millions de dollars.
Le carbone émis était d'environ 4 400 tonnes d'équivalent CO2 — soit environ 2 000 vols aller-retour JFK-Londres. C'est énorme, mais pas encore significatif dans l'ensemble. Cela pourrait devenir un vrai problème pour GPT-6 ou GPT-7 si cela centuple.
Chaque nouvelle génération vise une augmentation par 10 des flops, à condition qu'il y ait assez d'énergie et de GPU disponibles.
Des questions sur ces calculs rapides ? D'accord.
Le post-entraînement et l'alignement
Nous avons discuté du pré-entraînement. Je voulais discuter des systèmes, mais je garderai cela pour la fin. Je vais passer au post-entraînement pour le moment.
Le post-entraînement transforme les modèles en assistants IA. Si vous demandez à un modèle non aligné comme GPT-3 d'expliquer l'alunissage à un enfant de 6 ans, il pourrait répondre par une autre question sur la gravité parce qu'il a appris que sur internet, les questions sont souvent suivies d'autres questions, pas de réponses. Ce n'est pas ce que vous attendez d'un assistant.
Le but de l'alignement est de faire en sorte que les LLM suivent les instructions et les contraintes du concepteur, comme la modération pour éviter le contenu toxique.
Un modèle aligné fournit une réponse réelle et refusera d'écrire du contenu préjudiciable. C'est cela, l'alignement.
Les données de type questions-réponses écrites par des humains que nous voulons pour l'entraînement sont coûteuses et difficiles à trouver. En revanche, les données de pré-entraînement sont abondantes. L'idée est de prendre un modèle pré-entraîné sur tout l'internet et d'ajuster finement ses poids sur une petite quantité de données souhaitées. Comme il connaît déjà la syntaxe du langage, il s'ajuste avec très peu de données.
Le réglage fin supervisé (SFT) consiste à entraîner le LLM sur des réponses souhaitées collectées auprès d'humains. Il est dit « supervisé » parce que vous effectuez une prédiction du mot suivant sur des réponses fournies par des humains.
Dans le projet OpenAssistant, des humains ont écrit des questions et des réponses idéales, qui ont été utilisées pour le réglage fin. Cet alignement a été la percée clé qui a transformé GPT-3 en ChatGPT.
Comme les données humaines coûtent cher, nous pouvons utiliser des LLM pour intensifier la collecte de données. Avec « Alpaca », nous avons utilisé 175 exemples humains et demandé à un meilleur modèle d'en générer 52 000 de plus, puis nous avons affiné Llama sur ces données synthétiques. Cela a lancé un domaine consistant à utiliser les LLM pour accélérer le développement.
Les données générées étaient assez bonnes même en utilisant des LLM plus anciens.
Le SFT ne nécessite pas beaucoup de données. L'article « LIMA » a montré que faire passer les données SFT de 2 000 à 32 000 exemples n'aide pas beaucoup. Le SFT apprend simplement au modèle comment formater les réponses et quel type d'utilisateur optimiser — il n'enseigne rien de nouveau. La connaissance est déjà dans le modèle pré-entraîné. Des questions sur le SFT ? Oui ?
On ne peut pas multiplier indéfiniment les données synthétiques en générant à partir de la même distribution. Existe-t-il de meilleures façons d'amorcer, ou devrions-nous simplement demander à des humains de générer un petit nombre d'exemples de très haute qualité ?
Si vous utilisez uniquement du texte généré par LLM sur plusieurs générations, vous ne vous améliorerez probablement pas beaucoup. Je pense que l'avenir réside dans la collaboration avec l'humain dans la boucle, où les modèles génèrent du texte et les humains font des modifications rapides. Nous évoluerons vers l'apprentissage actif, en ne demandant l'intervention humaine que pour les exemples les plus importants. Oui ?
Entraînons-nous avec la même fonction de perte pour le SFT que pour le pré-entraînement ?
Oui, c'est la même perte. Le SFT est juste une modélisation du langage sur les réponses souhaitées. On l'appelle post-entraînement parce que la collecte de données est différente. Oui ?
Pourquoi ces 2 000 exemples auraient-ils une influence aussi disproportionnée lors du réglage fin ?
Nous utilisons des hyperparamètres différents. Alors que le taux d'apprentissage à la fin du pré-entraînement est proche de zéro, nous l'augmentons pour le SFT à environ 1e-5, ce qui donne plus de poids à ces exemples.
RLHF et DPO
La deuxième partie du post-entraînement est le RLHF (apprentissage par renforcement à partir de commentaires humains). Le SFT pose des problèmes, comme être limité par les capacités humaines et contribuer aux hallucinations. Si un humain fournit une réponse factuellement correcte que le modèle n'a pas vue lors du pré-entraînement, le SFT demande au modèle d'inventer des informations plausibles. De plus, demander à des humains d'écrire des réponses idéales entières coûte très cher.
En RLHF, nous maximisons la préférence humaine au lieu de cloner des comportements. Le modèle génère deux réponses pour une instruction, et un humain sélectionne celle qu'il préfère. Nous affinons ensuite le modèle pour qu'il génère plus souvent la réponse préférée. Parlons des algorithmes.
Il existe deux méthodes principales de RL. La première utilise des récompenses binaires — si la sortie est meilleure qu'une référence, elle reçoit +1, sinon -1. Mais les récompenses binaires sont rares et ne vous disent pas à quel point une réponse était meilleure.
L'option deux consiste à entraîner un « modèle de récompense » — un classifieur qui évalue à quel point un humain préférerait une sortie à une autre. Vous utilisez une perte softmax pour entraîner ce large classifieur sur les préférences humaines. Le modèle de récompense produit des scores qui indiquent la probabilité qu'une sortie soit meilleure qu'une autre. C'est le modèle de Bradley-Terry. Oui ?
Ce modèle de récompense évalue-t-il l'intégralité de la sortie ou procède-t-il jeton par jeton ?
Il prend l'intégralité de l'entrée et de la sortie d'un coup et donne un nombre unique. Oui ?
Si nous utilisons un modèle de récompense, où se place l'humain ?
Vous entraînez le modèle de récompense pour qu'il corresponde aux préférences humaines. Au lieu d'une récompense humaine binaire, vous utilisez les scores continus du modèle de récompense. Cela capture l'ampleur de la préférence.
Enfin, vous utilisez le RL pour optimiser les générations du modèle par rapport à cette récompense en utilisant un terme de régularisation pour éviter le « sur-optimisation » du modèle de récompense. Nous utilisons le PPO (optimisation de politique proximale). Notez que les modèles entraînés ainsi agissent comme des politiques plutôt que comme des distributions de probabilité, de sorte que leurs vraisemblances textuelles ne sont plus significatives. Rien n'incite le modèle à maintenir une distribution diversifiée.
PPO est ce que ChatGPT a utilisé : d'abord le SFT, puis l'entraînement d'un modèle de récompense, puis plusieurs étapes de PPO. Ce fut la percée entre GPT-3 et ChatGPT. Cependant, PPO est complexe en pratique à cause des déploiements et de l'écrêtage.
Une nouvelle méthode appelée DPO (optimisation directe des préférences) simplifie cela. Au lieu du RL, vous maximisez simplement la probabilité de générer du contenu préféré et minimisez la probabilité de contenu non préféré.
La fonction de perte maximise la probabilité des réponses préférées. À haut niveau, il s'agit simplement de maximiser ce que vous aimez et de minimiser ce que vous n'avez pas aimé.
Mathématiquement, les minima globaux de PPO et DPO sont équivalents sous certaines hypothèses. DPO est beaucoup plus simple car il utilise directement le maximum de vraisemblance plutôt que le RL. Oui ?
Le DPO semble bien plus simple et intuitif. Pourquoi n'ont-ils pas commencé par cela au lieu d'un modèle de récompense ?
L'équipe d'OpenAI était experte en RL, le PPO était donc intuitif pour eux. Un avantage théorique du PPO est que vous pouvez utiliser le modèle de récompense pour étiqueter des données non étiquetées supplémentaires. En pratique, le DPO est tout aussi performant et est désormais la norme.
Le DPO est désormais la norme dans la communauté open-source et l'industrie car il est plus simple et performant autant que le PPO.
Le RLHF améliore considérablement les performances sur les tâches de résumé et les benchmarks comme AlpacaFarm. Le saut du pré-entraînement au SFT est significatif, et le saut vers le RLHF est encore plus grand. PPO et DPO donnent des performances similaires, mais DPO est plus simple.
Collecter des données de préférence humaine est difficile. Les humains préfèrent souvent la plus longue de deux réponses similaires, quelle que soit la qualité. Les défis incluent des coûts élevés, un biais pour la longueur au détriment de l'exactitude — rendant les réponses de ChatGPT de plus en plus verbeuses — et l'éthique de la sous-traitance de contenus toxiques.
Pour remédier à cela, nous pouvons remplacer la préférence humaine par la préférence des LLM. Les humains ne sont d'accord sur les tâches de préférence binaire qu'environ 66 % du temps. Les modèles sont 50 fois moins chers et montrent souvent un accord plus élevé avec la préférence humaine que les humains eux-mêmes car ils ont moins de variance. C'est maintenant la norme pour améliorer la collecte de données RLHF.
Évaluation du post-entraînement
Évaluer le post-entraînement est difficile. On ne peut pas utiliser la perte de validation ou la perplexité car des méthodes comme PPO ne sont pas calibrées pour des distributions de probabilité. Il y a aussi une diversité de questions ouvertes qui sont difficiles à automatiser.
La solution est de poser aux modèles le type de questions que les utilisateurs posent en pratique et de faire évaluer par des annotateurs quelle sortie est la meilleure. Oui ?
Je ne comprends pas pourquoi la perplexité ne peut pas être utilisée. Le LLM fait toujours de la prédiction du prochain jeton, n'est-ce pas ?
Les modèles entraînés par PPO considèrent effectivement qu'une phrase a une probabilité de un et les autres de zéro. Bien que ce soit techniquement toujours une distribution, ces modèles sont entraînés comme des politiques, et non comme des modèles de maximum de vraisemblance, la perplexité est donc erronée.
Chatbot Arena est un benchmark populaire où les utilisateurs parlent à deux chatbots à l'aveugle et les notent. Il compte des centaines de milliers de notes, mais les utilisateurs sont souvent férus de technologie, orientant les questions vers les logiciels et les outils d'IA. C'est aussi trop lent et coûteux pour un développement itératif.
Nous pouvons utiliser un LLM comme juge pour une évaluation plus rapide. Dans AlpacaEval, nous comparons la sortie d'un modèle à une référence et demandons à GPT-4 de choisir le gagnant, ce qui nous donne un « taux de victoire » pour classer les modèles.
AlpacaEval a une corrélation de 98 % avec Chatbot Arena et est très peu coûteux. Cependant, il souffre de corrélations fallacieuses, comme le biais envers les sorties plus longues. Si les modèles sont biaisés par la longueur, ils continueront à préférer les réponses verbeuses.
Les humains comme les modèles préfèrent les sorties plus longues. Si vous incitez GPT-4 à être verbeux, son taux de victoire contre lui-même bondit à 64 % ; si vous l'incitez à être concis, il tombe à 20 %. Cette variance est un problème.
Nous avons utilisé l'inférence causale et l'analyse de régression pour contrôler la longueur. Désormais, le fait d'être verbeux offre des gains bien plus faibles en termes de taux de victoire.
Cela couvre le post-entraînement. Pour les huit prochaines minutes, je vais parler des systèmes ou répondre à des questions. Oui ?
Comment de si petites quantités de données de réglage fin peuvent-elles avoir un effet si important ? Modifiez-vous tous les poids ou seulement les derniers ?
Dans l'industrie, tous les poids sont généralement modifiés. Dans le monde de l'open-source, les gens utilisent des techniques comme LoRA pour ajouter des différences à chaque couche. Le RLHF implique environ un million d'exemples — plus que le SFT, mais toujours bien moins que le pré-entraînement.
Le pré-entraînement représente 15 billions de jetons ; les données de réglage fin sont une goutte d'eau dans l'océan, et pourtant elles influencent considérablement les poids.
Considérez le pré-entraînement comme l'initialisation des poids. Si vous vous entraînez même sur une seule phrase de manière répétée avec un taux d'apprentissage assez élevé, le modèle finira par surapprendre et ne générera que cette phrase. Le post-entraînement utilise un taux d'apprentissage spécifique pour spécialiser le modèle, en s'appuyant sur cette initialisation.
Est-ce que le fait de relancer plusieurs fois les données de réglage fin est ce qui se passe réellement pour déplacer la préférence ?
Pour Alpaca, nous avons effectué trois époques, mais le nombre de passages compte moins que le taux d'apprentissage effectif.
Optimisation des systèmes et matériel
Il me reste cinq minutes, je vais donc donner un aperçu général de quelques astuces système.
Le calcul est le principal goulot d'étranglement. Les GPU sont chers et rares, et il existe des limites physiques à la communication entre GPU. L'allocation des ressources et l'optimisation des pipelines sont critiques.
Les GPU sont optimisés pour le débit, alors que les CPU sont optimisés pour la latence. Les GPU utilisent de nombreux cœurs (multiprocesseurs de streaming) pour exécuter une commande sur plusieurs points de données simultanément.
Les GPU sont optimisés pour la multiplication de matrices rapide. Si vous pouvez formuler une opération comme une multiplication de matrice, elle sera beaucoup plus rapide. Nous sommes souvent limités par cette exigence.
La capacité de calcul s'améliore plus vite que la mémoire et la communication. Sans optimisation, les GPU sont souvent inactifs car les données ne peuvent pas être envoyées assez vite aux processeurs. Cette tendance va se poursuivre.
Les GPU ont une hiérarchie de mémoire : la mémoire plus proche des cœurs est plus rapide mais a une capacité plus petite.
La mesure que nous utilisons est l'utilisation des FLOP du modèle (MFU) — le débit observé divisé par le maximum théorique. Des entreprises comme Meta atteignent environ 45 % ; atteindre 50 % est excellent. Cela souligne le goulot d'étranglement des données.
Une astuce est la basse précision. L'utilisation de flottants 16 bits au lieu de 32 ou 64 bits réduit le temps de communication et la consommation de mémoire. L'apprentissage profond est résilient à ce bruit.
Nous utilisons la précision mixte automatique : les poids sont stockés en 32 bits mais le calcul est effectué en 16 bits pour la vitesse. Nous effectuons la mise à jour en 32 bits pour accommoder les petits ajustements du taux d'apprentissage.
La fusion d'opérateurs s'attaque à la lenteur de la communication. Envoyer naïvement des données entre la mémoire globale et les processeurs pour chaque opération est un gaspillage.
La fusion d'opérateurs, ou noyaux fusionnés, consiste à envoyer les données une seule fois, effectuer toutes les opérations et les renvoyer. L'application de « torch.compile » peut rendre un modèle deux fois plus rapide en réécrivant le code en CUDA pour minimiser la communication.
Je n'ai pas le temps de couvrir le pavage, la parallélisation ou le mélange d'experts (Mixture of Experts), bien qu'ils soient importants.
Nous n'avons pas abordé les architectures, l'inférence, les interfaces utilisateur, la multimodalité, la sécurité, la rareté des données ou la légalité de la collecte de données.
Pour approfondir, je recommande CS224N pour le contexte historique, CS324 pour des cours approfondis sur ces sujets, et CS336 pour construire un LLM à partir de zéro. CS336 est excellent mais demande une charge de travail très lourde. Merci.