Études de cas ou références montrant des gains de performance avec la corde et l'alibi
Position rotative Incorporation (corde):
- Étude de cas 1: Dans l'article «Roformer: Position rotative L'intégration pour les modèles de transformateurs», les auteurs ont démontré que la corde améliorait considérablement les performances sur des tâches à longue séquence comme la modélisation du langage. La capacité de la corde à généraliser mieux sur de longues séquences sans nécessiter de ressources de calcul supplémentaires en fait un choix plus efficace par rapport aux intérêts traditionnels.
- Gain de performance: la corde a fourni jusqu'à 4 à 6% une meilleure précision dans les séquences de manipulation de plus de 512 jetons, par rapport aux modèles utilisant des codages de position traditionnels.
Alibi (attention aux biais linéaires):
- Étude de cas 2: Dans «Alibi: Attention avec des biais linéaires pour une modélisation efficace de séquences à longue portée», l'introduction du biais linéaire dans le mécanisme d'attention a permis au modèle de traiter efficacement les séquences sans s'appuyer sur le codage de position. Alibi a réduit la surcharge de mémoire et a amélioré l'évolutivité du modèle pour les tâches comme la traduction automatique et la résumé.
- Gain de performance: Alibi a démontré jusqu'à 8% de temps de formation plus rapides et des réductions significatives de l'utilisation de la mémoire tout en maintenant ou en améliorant les performances du modèle sur des références à longue séquence.
Ces avancées montrent comment les techniques d'intégration de position modernes comme la corde et l'alibi traitent non seulement les limites des méthodes traditionnelles, mais améliorent également l'évolutivité et l'efficacité des modèles de gros langues, en particulier lorsqu'ils traitent de longues entrées.
Exploitant le pouvoir de la plus faible précision
Les LLM sont composées de vastes matrices et vecteurs représentant leurs poids. Ces poids sont généralement stockés dans Float32, BFLOAT16 ou Float16. Les exigences de mémoire peuvent être estimées comme suit:
- Float32 Précision: mémoire requise = 4 * x gb, où x est le nombre de paramètres du modèle (en milliards).
- BFLOAT16 / Float16 Précision: mémoire requise = 2 * x gb.
Exemples d'utilisation de la mémoire dans la précision BFLOAT16:
- GPT-3: 175 milliards de paramètres, ~ 350 Go VRAM.
- Bloom: 176 milliards de paramètres, ~ 352 Go VRAM.
- LLAMA-2-70B: 70 milliards de paramètres, ~ 140 Go vram.
- FALCON-40B: 40 milliards de paramètres, ~ 80 Go VRAM.
- MPT-30B: 30 milliards de paramètres, ~ 60 Go de vram.
- Starcoder: 15,5 milliards de paramètres, ~ 31 Go vram.
Étant donné que le GPU NVIDIA A100 a un maximum de 80 Go de VRAM, les modèles plus grands ont besoin d'un parallélisme du tenseur ou d'un parallélisme du pipeline pour fonctionner efficacement.
Exemple pratique
Chargement de la floraison sur un nœud A100 8 x 80 Go:
! PIP installe les transformateurs accélérer les bitsandbytes optimum
# De Transformers Importer AutomodelforcUsallm
# modèle = AutomodelforCausallm.from_pretraind ("bigScience / Bloom", device_map = "Auto")
à partir de Transformers Import AutomodelforcUsallm, Autotokenzer, Pipeline
Importer une torche
Model = AutomodelforCauSallm.From_pretraind ("bigcode / octocoder", torch_dtype = torch.bfloat16, device_map = "auto", pad_token_id = 0)
tokenizer = autotokenizer.from_pretraind ("bigcode / octocoder")
tuyau = pipeline ("Génération de texte", modèle = modèle, tokenizer = tokenizer)
prompt = "Question: veuillez écrire une fonction en python qui transforme les octets en octets giga. \ n \ nanswer:"
result = tuy (invite, max_new_tokens = 60) [0] ["généré_text"] [Len (invite):]
résultat
def bytes_to_giga_bytes (octets):
RETOUR les octets / 1024/1024/1024
bytes_to_giga_bytes (torch.cuda.max_memory_allocated ())
modèle.to ("CPU")
tuyau del
modèle del
Importer GC
Importer une torche
def flush ():
GC.Collect ()
torch.cuda.empty_cache ()
torch.cuda.reset_peak_memory_stats ()
flush()
Il existe diverses techniques de quantification, dont nous ne discuterons pas en détail ici, mais en général, toutes les techniques de quantification fonctionnent comme suit:
- Quantisez tous les poids à la précision cible.
- Chargez les poids quantifiés et passez la séquence d'entrée des vecteurs dans la précision BFLOAT16.
- Débantisez dynamiquement les poids en BFLOAT16 pour effectuer le calcul avec leurs vecteurs d'entrée dans la précision BFLOAT16.
- Quantisez à nouveau les poids à la précision cible après calcul avec leurs entrées.
En un mot, cela signifie que les imputations matriciels de poids, avec des instructions, avec une matrice de poids et la sortie:
Y = x ∗ w est modifié en y = x ∗ déquantiser (w); quantifier (w) pour chaque multiplication matricielle. La déshabantidation et la requantification sont effectuées séquentiellement pour toutes les matrices de poids lorsque les entrées exécutent le graphique réseau.
#! PIP installe des bitsandbytes
modèle = automodelforcusallm.from_pretraind ("bigcode / octocoder", load_in_8bit = true, low_cpu_mem_usage = true, pad_token_id = 0)
tuyau = pipeline ("Génération de texte", modèle = modèle, tokenizer = tokenizer)
result = tuy (invite, max_new_tokens = 60) [0] ["généré_text"] [Len (invite):]
résultat
bytes_to_giga_bytes (torch.cuda.max_memory_allocated ())
Model.cpu ()
modèle del
tuyau del
flush()
modèle = automodelforcusallm.from_pretraind ("bigcode / octocoder", load_in_4bit = true, low_cpu_mem_usage = true, pad_token_id = 0)
tuyau = pipeline ("Génération de texte", modèle = modèle, tokenizer = tokenizer)
result = tuy (invite, max_new_tokens = 60) [0] ["généré_text"] [Len (invite):]
résultat
bytes_to_giga_bytes (torch.cuda.max_memory_allocated ())
Model.cpu ()
modèle del
tuyau del
Model.cpu ()
modèle del
tuyau del
flush()
modèle = automodelforcusallm.from_pretraind ("bigcode / octocoder", load_in_4bit = true, low_cpu_mem_usage = true, pad_token_id = 0)
tuyau = pipeline ("Génération de texte", modèle = modèle, tokenizer = tokenizer)
result = tuy (invite, max_new_tokens = 60) [0] ["généré_text"] [Len (invite):]
résultat
bytes_to_giga_bytes (torch.cuda.max_memory_allocated ())
Model.cpu ()
modèle del
tuyau del
flush()
Mécanisme d'attention Flash
L'attention du flash optimise le mécanisme d'attention en améliorant l'efficacité de la mémoire et en tirant parti d'une meilleure utilisation de la mémoire GPU. Cette approche permet:
- Empreinte de la mémoire réduite: minimise considérablement les frais généraux de mémoire en gérant le calcul de l'attention plus efficacement.
- Performances plus élevées: améliorations significatives de la vitesse pendant l'inférence.
System_Prompt = "" "Vous trouverez ci-dessous une série de dialogues entre diverses personnes et un assistant technique d'IA.
L'assistant essaie d'être utile, poli, honnête, sophistiqué, émotionnellement conscient et humble mais compétent.
L'assistant est heureux d'aider aux questions du code et fera de son mieux pour comprendre exactement ce qui est nécessaire.
Il essaie également d'éviter de donner des informations fausses ou trompeuses, et elle se trouve lorsqu'elle n'est pas tout à fait sûre de la bonne réponse.
Cela dit, l'assistant est pratiquement fait de son mieux et ne laisse pas la prudence devenir trop utile.
Les modèles Starcoder sont une série de modèles de paramètres 15,5b formés sur 80 langages de programmation de la pile (v1.2) (à l'exclusion des demandes de désactivation).
Le modèle utilise l'attention multi-requêtes, a été formé à l'aide de l'objectif de remplissage du milieu et avec une fenêtre de contexte de 8 192 jetons pour un billion de jetons de données fortement dédupliquées.
-----
Question: Écrivez une fonction qui prend deux listes et renvoie une liste qui a des éléments alternés de chaque liste d'entrée.
Réponse: Bien sûr. Voici une fonction qui fait cela.
def alternative (list1, list2):
résultats = []
pour i dans la gamme (len (list1)):
résultats.APPEND (list1 [i])
results.append (list2 [i])
Résultats de retour
Question: Pouvez-vous rédiger des cas de test pour cette fonction?
Réponse: Bien sûr, voici quelques tests.
affirmer en alternance ([10, 20, 30], [1, 2, 3]) == [10, 1, 20, 2, 30, 3]
affirmer en alternance ([true, false], [4, 5]) == [true, 4, false, 5]
affirmer en alternance ([], []) == []
Question: Modifiez la fonction afin qu'il renvoie tous les éléments d'entrée lorsque les listes ont une longueur inégale. Les éléments de la liste plus longue doivent être à la fin.
Réponse: Voici la fonction modifiée.
def alternative (list1, list2):
résultats = []
pour i dans la gamme (min (len (list1), Len (list2))):
résultats.APPEND (list1 [i])
results.append (list2 [i])
Si Len (list1)> Len (list2):
results.extend (list1 [i 1:])
autre:
results.extend (list2 [i 1:])
Résultats de retour
-----
"" "
long_prompt = 10 * System_prompt invite
modèle = automodelforcusallm.from_pretraind ("bigcode / octocoder", torch_dtype = torch.bfloat16, device_map = "auto")
tokenizer = autotokenizer.from_pretraind ("bigcode / octocoder")
tuyau = pipeline ("Génération de texte", modèle = modèle, tokenizer = tokenizer)
heure d'importation
start_time = time.time ()
result = tuy (long_prompt, max_new_tokens = 60) [0] ["généré_text"] [len (long_prompt):]
print (f "généré dans {time.time () - start_time} secondes.")
résultat
bytes_to_giga_bytes (torch.cuda.max_memory_allocated ())
Sortir:

flush()
modèle = modèle.to_betterTransFormer ()
start_time = time.time ()
result = tuy (long_prompt, max_new_tokens = 60) [0] ["généré_text"] [len (long_prompt):]
print (f "généré dans {time.time () - start_time} secondes.")
résultat
bytes_to_giga_bytes (torch.cuda.max_memory_allocated ())
flush()
Sortir:

Science derrière LLM Architectures
Jusqu'à présent, nous avons exploré des stratégies pour améliorer l'efficacité de calcul et de mémoire, notamment:
- Casting des poids à un format de précision inférieur.
- Implémentation d'une version plus efficace de l'algorithme d'auto-agencement.
Maintenant, nous tournons notre attention sur la façon dont nous pouvons modifier l'architecture des modèles de grande langue (LLM) pour les optimiser pour les tâches nécessitant de longues entrées de texte, telles que:
- Question de la récupération Répondre à la réponse,
- Récapitulation,
- Applications de chat.
Notamment, les interactions de chat nécessitent que les LLM ne traitent pas seulement les entrées de texte longs, mais gèrent également efficacement le dialogue dynamique et allongé entre l'utilisateur et le modèle, similaire à ce que Chatgpt accomplit.
Étant donné que la modification de l'architecture fondamentale d'un post-formation LLM est difficile, il est essentiel de prendre des décisions de conception bien considérées. Deux composants principaux dans les architectures LLM qui deviennent souvent des goulots d'étranglement de performance pour les grandes séquences d'entrée sont:
- Incorporation de position
- Cache de valeur clé
Approfondissons ces composants.
Amélioration des intérêts positionnels dans les LLM
Le mécanisme d'auto-atténuation relie chaque jeton à d'autres au sein d'une séquence de texte. Par exemple, la matrice SoftMax (QKT) pour la séquence d'entrée «Hello», «I», «Love», «You» pourrait apparaître comme suit:
|
Bonjour |
je |
Amour |
Toi |
Bonjour |
0,2 |
0.4 |
0.3 |
0.1 |
je |
0.1 |
0,5 |
0,2 |
0,2 |
Amour |
0,05 |
0.3 |
0,65 |
0.0 |
Toi |
0,15 |
0,25 |
0,35 |
0,25 |
Chaque jeton de mot a une distribution de probabilité indiquant combien il s'occupe des autres jetons. Par exemple, le mot «amour» s'occupe de «Hello» avec 0,05 probabilité, «i» avec 0,3, et lui-même avec 0,65.
Cependant, sans incorporer de position, un LLM a du mal à comprendre les positions relatives des jetons, ce qui rend difficile la distinction de séquences comme "Hello I Love You" de "You Love I Hello". Le calcul QKT relie les jetons sans considérer la distance de position, traitant chacun comme équidistant.
Pour résoudre ce problème, des encodages de position sont introduits, fournissant des indices numériques qui aident le modèle à comprendre l'ordre des jetons.
Incorporation positionnelle traditionnelle
Dans l'attention d'origine est tout ce dont vous avez besoin de papier, des incorporations de positionnelles sinusoïdales ont été proposées, où chaque vecteur est défini comme une fonction sinusoïdale de sa position. Ces intérêts sont ajoutés aux vecteurs de séquence d'entrée comme:
Certains modèles, comme Bert, ont introduit des intérêts de position apprises, qui sont apprises pendant la formation.
Défis avec des incorporations positionnelles absolues
Les incorporations de positionnelles sinusoïdales et apprises sont absolues, codant pour des positions uniques. Cependant, comme l'a noté Huang et al. et Su et al., Les intérêts absolus peuvent entraver les performances pour les séquences longues. Les problèmes clés comprennent:
- Longue limitation d'entrée: les incorporations absolues fonctionnent mal lors de la manipulation de longues séquences car elles se concentrent sur des positions fixes au lieu de distances relatives.
- Longueur de formation fixe: les intérêts apprises lient le modèle à une longueur de formation maximale, limitant sa capacité à généraliser à des entrées plus longues.
Avancements: intégres de position relative
Pour relever ces défis, des intérêts de position relatifs ont gagné du terrain. Deux méthodes notables comprennent:
- Position rotative Incorporation (corde)
- Alibi (attention avec les biais linéaires)
Les deux méthodes modifient le calcul QKT pour incorporer l'ordre des phrases directement dans le mécanisme d'auto-attention, améliorant la façon dont les modèles gèrent les longues entrées de texte.
Position rotative L'intégration (corde) code les informations de position par la requête rotative et les vecteurs clés par des angles et, respectivement, où indiquent les positions:
Voici une matrice de rotation et est prédéfinie en fonction de la longueur d'entrée maximale de la formation.
Ces approches permettent aux LLM de se concentrer sur des distances relatives, d'améliorer la généralisation pour des séquences plus longues et de faciliter des optimisations efficaces spécifiques aux tâches.
input_ids = tokenizer (invite, return_tensers = "pt") ["input_ids"]. à ("cuda")
pour _ dans la gamme (5):
next_logits = modèle (input_ids) ["Logits"] [:, -1:]
next_token_id = torch.argmax (next_logits, dim = -1)
input_ids = torch.cat ([input_ids, next_token_id], dim = -1)
print ("Forme de Input_ids", Input_ids.shape)
généré_text = tokenizer.batch_decode (input_ids [:, -5:])
généré_text

Past_key_values = Aucun # Past_key_Values est le cache de valeur clé
généré_tokens = []
next_token_id = tokenizer (invite, return_tensers = "pt") ["input_ids"]. à ("cuda")
pour _ dans la gamme (5):
next_logits, passant_key_values = modèle (next_token_id, passant_key_values = passant_key_values, use_cache = true) .to_tuple ()
next_logits = next_logits [:, -1:]
next_token_id = torch.argmax (next_logits, dim = -1)
print ("Forme de Input_ids", next_token_id.shape)
print ("Longueur du cache de valeur clé", Len (Past_key_Values [0] [0])) # Past_key_Values est de forme [num_layers, 0 pour k, 1 pour v, batch_size, longueur, HIDDEN_DIM]
généré_tokens.append (next_token_id.item ())
généré_text = tokenizer.batch_decode (généré_tokens)
généré_text

config = Model.config
2 * 16_000 * config.n_layer * config.n_head * config.n_embd // config.n_head
Sortir
7864320000
Conclusion
L'optimisation des architectures LLM pour les longues entrées de texte et les applications de chat dynamique est essentielle pour faire progresser leur applicabilité réelle. Les défis de la gestion des contextes d'entrée importants, de la maintenance de l'efficacité informatique et de la fourniture d'interactions conversationnelles significatives nécessitent des solutions innovantes au niveau architectural. Des techniques telles que l'attention de la position rotative (corde), l'alibi et l'attention du flash illustrent le potentiel transformateur des composants centraux à affinage comme les incorporations de position et l'auto-admission.
Au fur et à mesure que le champ avance, un centre sur le mélange de l'efficacité informatique avec l'inventivité de l'ingénierie entraînera la vague de percées suivante. En comprenant et en actualisant ces procédures, les concepteurs peuvent s'attaquer au contrôle total des LLM, garantissant qu'ils ne sont pas très bien mais trop adaptables, réactifs et communs pour différentes applications du monde réel.
Principaux à retenir
- Des techniques comme la corde et l'alibi améliorent la capacité des LLMS à traiter des textes plus longs sans sacrifier les performances.
- Des innovations telles que l'attention du flash et l'attention des fenêtres coulissantes réduisent l'utilisation de la mémoire, ce qui rend les grands modèles pratiques pour les applications du monde réel.
- L'optimisation des LLM pour les longues entrées de texte améliore leur capacité à maintenir le contexte et la cohérence dans les conversations étendues et les tâches complexes.
- Les LLM évoluent pour soutenir les tâches telles que les dialogues de résumé, de récupération et de multi-tours avec une meilleure évolutivité et réactivité.
- La réduction de la précision du modèle améliore l'efficacité informatique tout en maintenant la précision, ce qui permet une adoption plus large.
- L'équilibrage de la conception d'architecture et de l'optimisation des ressources garantit que les LLM restent efficaces pour les cas d'utilisation divers et croissants.
Questions fréquemment posées
Q1. 1. Que sont les LLM et pourquoi sont-ils significatifs? A. Les modèles de grands langues (LLM) sont des modèles d'IA décrits pour l'obtenir et créer un contenu humain. Ils sont essentiels en raison de leur capacité à effectuer une large étendue de missions, de la réponse aux questions à la composition imaginative, ce qui en fait des appareils flexibles pour différentes entreprises.
Q2. Comment la corde et l'alibi améliorent-ils les LLM? A. La corde (codage de position rotative) et l'alibi (attention aux biais linéaires) améliorent les LLM en améliorant leur capacité à gérer de longs contextes, assurant un traitement efficace du texte étendu sans perdre la cohérence.
Q3. Qu'est-ce que l'attention du flash et comment optimiserait-il l'utilisation de la mémoire? A. L'attention du flash est un algorithme qui calcule l'attention plus efficacement, réduisant considérablement la consommation de mémoire et accélérant le traitement pour les modèles à grande échelle.
Q4. Pourquoi la quantification est-elle importante pour les LLM? A. La quantification diminue la précision des poids de démonstration (par exemple, de 32 bits à 8 bits), ce qui fait baisser les nécessités de calcul et l'utilisation de la mémoire tandis que le suivi montre l'exécution, l'autonomisation des arrangements sur les gadgets plus petits.
Q5. Quels défis demeurent davantage pour la mise à l'échelle des LLM? A. Les défis majeurs comprennent la gestion des coûts de calcul et de mémoire, de répondre aux préoccupations éthiques comme les biais et les abus, et la garantie des modèles peut généraliser efficacement dans diverses tâches et langues.
Q6. Comment optimiser les LLM pour le traitement efficacement des entrées de texte longs? A. L'optimisation des LLM pour les longues entrées de texte implique des techniques telles que l'expansion de la fenêtre de contexte, les mécanismes de mémoire et le traitement efficace des jetons pour s'assurer qu'ils maintiennent la cohérence et les performances lors de conversations étendues ou d'analyse de documents.