Maison > Article > Périphériques technologiques > Déchirage manuel de la couche 1 de Llama3 : implémentation de Llama3 à partir de zéro
Dans cette série d'articles, nous implémentons Llama3 à partir de zéro.
L'architecture globale de Llama3 :
Photos
Les paramètres du modèle de Llama3 :
Jetons un coup d'œil aux valeurs réelles de ces paramètres dans le modèle LlaMa 3.
Pictures
Lors de l'instanciation de la classe LlaMa, la variable max_seq_len définit la fenêtre contextuelle. Il existe d'autres paramètres dans la classe, mais ce paramètre est le plus directement lié au modèle de transformateur. Le max_seq_len ici est de 8K.
Images
La classe Transformer est un modèle qui définit le vocabulaire et le nombre de couches. Le vocabulaire fait ici référence à l'ensemble de mots (et de jetons) que le modèle est capable de reconnaître et de traiter. Les couches d'attention font référence au bloc de transformation (une combinaison de couches d'attention et de rétroaction) utilisé dans le modèle.
Photos
Selon ces chiffres, LlaMa 3 a un vocabulaire de 128K, ce qui est assez large. De plus, il dispose de 32 blocs transformateurs.
[3] Dimension-caractéristique et têtes d'attention
La dimension-caractéristique et les têtes d'attention sont introduites dans le module Auto-Attention. La dimension des fonctionnalités fait référence à la taille vectorielle des jetons dans l'espace d'intégration (la dimension des fonctionnalités fait référence à la taille des données d'entrée ou au vecteur d'intégration), tandis que les têtes d'attention incluent le module QK qui pilote le mécanisme d'auto-attention dans les transformateurs.
Images
Les dimensions cachées font référence à la taille de la couche cachée dans le réseau neuronal à rétroaction (Feed Forward). Les réseaux de neurones Feedforward contiennent généralement une ou plusieurs couches cachées, et les dimensions de ces couches cachées déterminent la capacité et la complexité du réseau. Dans le modèle Transformer, la dimension de la couche cachée du réseau neuronal à action directe est généralement un multiple de la dimension des fonctionnalités pour augmenter la capacité de représentation du modèle. Dans LLama3, la dimension cachée est 1,3 fois la dimension caractéristique. Il convient de noter que les couches cachées et les dimensions cachées sont deux concepts.
Un nombre plus élevé de couches cachées permet au réseau de créer et de manipuler en interne des représentations plus riches avant de les projeter dans des dimensions de sortie plus petites.
Picture
La première matrice est la matrice des fonctionnalités d'entrée, qui est traitée par la couche Attention pour générer des fonctionnalités pondérées par l'attention. Dans cette image, la matrice des caractéristiques d'entrée n'a qu'une taille de 5 x 3, mais dans le modèle réel Llama 3, elle atteint 8K x 4096, ce qui est énorme.
Vient ensuite les couches cachées du réseau Feed-Forward, passant à 5325 puis retombant à 4096 dans la dernière couche.
Photos
LlaMa 3 combine les 32 blocs transformateurs ci-dessus, et la sortie passe d'un bloc au suivant jusqu'à ce qu'elle atteigne le dernier.
Photos
Une fois que nous avons commencé toutes les parties ci-dessus, il est temps de les assembler et de voir comment elles créent l'effet LlaMa.
Images
Étape 1 : Nous avons d'abord notre matrice d'entrée de taille 8K (fenêtre contextuelle) x 128K (taille vocabulaire). Cette matrice subit un processus d'intégration pour convertir cette matrice de haute dimension en une matrice de basse dimension.
Étape 2 : Dans ce cas, ce résultat de faible dimension devient 4096, qui est la dimension spécifiée des caractéristiques dans le modèle LlaMa que nous avons vu plus tôt.
Dans les réseaux de neurones, l'amélioration et la réduction de la dimensionnalité sont des opérations courantes, et elles ont chacune des objectifs et des effets différents.
L'amélioration des dimensions consiste généralement à augmenter la capacité du modèle afin qu'il puisse capturer des caractéristiques et des modèles plus complexes. Lorsque les données d'entrée sont mappées dans un espace de dimension supérieure, différentes combinaisons de caractéristiques peuvent être plus facilement distinguées par le modèle. Ceci est particulièrement utile lorsqu’il s’agit de problèmes non linéaires, car cela peut aider le modèle à connaître des limites de décision plus complexes.
La réduction de dimensionnalité consiste à réduire la complexité du modèle et le risque de surajustement. En réduisant la dimensionnalité de l'espace des fonctionnalités, le modèle peut être contraint d'apprendre des représentations de fonctionnalités plus raffinées et généralisées. De plus, la réduction de dimensionnalité peut être utilisée comme méthode de régularisation pour contribuer à améliorer la capacité de généralisation du modèle. Dans certains cas, la réduction de la dimensionnalité peut également réduire les coûts de calcul et améliorer l’efficacité opérationnelle du modèle.
Dans les applications pratiques, la stratégie d'augmentation de dimensionnalité puis de réduction de dimensionnalité peut être considérée comme un processus d'extraction et de transformation de caractéristiques. Dans ce processus, le modèle explore d'abord la structure intrinsèque des données en augmentant la dimensionnalité, puis extrait les caractéristiques et les modèles les plus utiles en réduisant la dimensionnalité. Cette approche peut aider le modèle à éviter le surajustement des données d'entraînement tout en conservant une complexité suffisante.
Étape 3 : Cette fonctionnalité est traitée via le bloc Transformer, d'abord par la couche Attention, puis par la couche FFN. La couche Attention traite les entités horizontalement, tandis que la couche FFN traite les dimensions verticalement.
Étape 4 : L'étape 3 est répétée pour 32 couches du bloc Transformer. Enfin, les dimensions de la matrice résultante sont les mêmes que celles utilisées pour les dimensions des fonctionnalités.
Étape 5 : Enfin, cette matrice est reconvertie à la taille de la matrice de vocabulaire d'origine, qui est de 128 Ko, afin que le modèle puisse sélectionner et cartographier les mots disponibles dans le vocabulaire.
C'est ainsi que LlaMa 3 obtient des scores élevés dans ces critères et crée l'effet LlaMa 3.
Nous résumerons plusieurs termes facilement confus en langage bref :
Il s'agit du nombre maximum de jetons que le modèle peut accepter en un seul traitement.
Dans le modèle LlaMa 3-8B, ce paramètre est défini sur 8 000 jetons, soit une taille de fenêtre contextuelle = 8K. Cela signifie que le nombre maximum de jetons que le modèle peut prendre en compte en un seul traitement est de 8 000. Ceci est essentiel pour comprendre de longs textes ou maintenir le contexte de conversations à long terme.
C'est le nombre de tous les jetons différents que le modèle peut reconnaître. Cela inclut tous les mots, signes de ponctuation et caractères spéciaux possibles. Le vocabulaire du modèle est de 128 000, exprimé sous la forme Vocabulary-size = 128K. Cela signifie que le modèle est capable de reconnaître et de traiter 128 000 jetons différents, qui incluent divers mots, signes de ponctuation et caractères spéciaux.
Un composant principal du modèle Transformer. Il est principalement responsable du traitement des données d'entrée en apprenant quelles parties des données d'entrée sont les plus importantes (c'est-à-dire quels jetons sont « surveillés »). Un modèle peut comporter plusieurs couches de ce type, chacune essayant de comprendre les données d'entrée sous un angle différent.
Le modèle LlaMa 3-8B contient 32 couches de traitement, soit un nombre de couches = 32. Ces couches comprennent plusieurs couches d'attention et d'autres types de couches réseau, chacune traitant et comprenant les données d'entrée sous un angle différent.
Contient des modules de plusieurs couches différentes, comprenant généralement au moins une couche d'attention et un réseau Feed-Forward. Un modèle peut avoir plusieurs blocs de transformateur. Ces blocs sont connectés séquentiellement et la sortie de chaque bloc est l'entrée du bloc suivant. Le bloc transformateur peut également être appelé couche de décodeur.
Dans le contexte du modèle Transformer, on dit généralement que le modèle a "32 couches", ce qui peut équivaloir à dire que le modèle a "32 blocs Transformer". Chaque bloc Transformer contient généralement une couche d'auto-attention et une couche de réseau neuronal à action directe. Ces deux sous-couches forment ensemble une unité de traitement complète ou « couche ».
Ainsi, lorsque nous disons que le modèle comporte 32 blocs Transformer, nous décrivons en fait que le modèle est composé de 32 unités de traitement de ce type, chacune étant capable de traiter l'auto-attention et de traiter les données en réseau par anticipation. Cette présentation met l'accent sur la structure hiérarchique du modèle et ses capacités de traitement à chaque niveau.
En résumé, « 32 couches » et « 32 blocs Transformer » sont fondamentalement synonymes lorsqu'ils décrivent la structure du modèle Transformer. Ils signifient tous deux que le modèle contient 32 cycles de traitement de données indépendants, et chaque cycle inclut l'auto-attention et le fonctionnement du réseau Feedforward.
Il s'agit de la dimension de chaque vecteur lorsque le jeton d'entrée est représenté comme un vecteur dans le modèle.
Chaque jeton est converti en un vecteur contenant 4096 caractéristiques dans le modèle, c'est-à-dire Feature-dimension = 4096. Cette dimension élevée permet au modèle de capturer des informations sémantiques et des relations contextuelles plus riches.
Dans chaque couche d'attention, il peut y avoir plusieurs têtes d'attention, et chaque tête analyse indépendamment les données d'entrée sous différents angles.
Chaque couche d'attention contient 32 têtes d'attention indépendantes, c'est-à-dire un nombre de têtes d'attention = 32. Ces responsables analysent les données d'entrée sous différents aspects et fournissent conjointement des capacités d'analyse de données plus complètes.
Cela fait généralement référence à la largeur de la couche dans le réseau Feed-Forward, c'est-à-dire le nombre de neurones dans chaque couche. En règle générale, les dimensions cachées seront plus grandes que la dimension caractéristique, ce qui permet au modèle de créer une représentation des données plus riche en interne.
Dans les réseaux Feed-Forward, la dimension de la couche cachée est de 5325, c'est-à-dire Dimensions cachées = 5325. Cette dimension est plus grande que la dimension des fonctionnalités, ce qui permet au modèle d'effectuer une traduction et un apprentissage plus approfondis des fonctionnalités entre les couches internes.
Relation entre les couches d'attention et les têtes d'attention : chaque couche d'attention peut contenir plusieurs têtes d'attention.
Relation numérique : un modèle peut avoir plusieurs blocs de transformation, chaque bloc contient une couche d'attention et une ou plusieurs autres couches. Chaque couche d'attention peut avoir plusieurs têtes d'attention. De cette manière, l’ensemble du modèle effectue un traitement de données complexe dans différentes couches et têtes.
Téléchargez le script de lien officiel du modèle Llama3 : https://llama.meta.com/llama-downloads/
Le code suivant montre comment utiliser la bibliothèque tiktoken pour charger et utiliser un Tokenizer basé sur des paires d'octets pour l'encodage (BPE). Ce tokenizer est conçu pour traiter des données textuelles, en particulier pour une utilisation dans les modèles de traitement du langage naturel et d'apprentissage automatique.
Nous entrons dans Hello World et voyons comment le segmenteur de mots effectue la segmentation des mots.
from pathlib import Pathimport tiktokenfrom tiktoken.load import load_tiktoken_bpeimport torchimport jsonimport matplotlib.pyplot as plttokenizer_path = "Meta-Llama-3-8B/tokenizer.model"special_tokens = ["<|begin_of_text|>","<|end_of_text|>","<|reserved_special_token_0|>","<|reserved_special_token_1|>","<|reserved_special_token_2|>","<|reserved_special_token_3|>","<|start_header_id|>","<|end_header_id|>","<|reserved_special_token_4|>","<|eot_id|>",# end of turn] + [f"<|reserved_special_token_{i}|>" for i in range(5, 256 - 5)]mergeable_ranks = load_tiktoken_bpe(tokenizer_path)tokenizer = tiktoken.Encoding(name=Path(tokenizer_path).name,pat_str=r"(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s*[\r\n]+|\s+(?!\S)|\s+",mergeable_ranks=mergeable_ranks,special_tokens={token: len(mergeable_ranks) + i for i, token in enumerate(special_tokens)},)tokenizer.decode(tokenizer.encode("hello world!"))
Photos
Afficher les noms des 20 premiers paramètres ou poids contenus dans le fichier modèle chargé.
model = torch.load("Meta-Llama-3-8B/consolidated.00.pth")print(json.dumps(list(model.keys())[:20], indent=4))
Pictures
Pictures
Dans l'ensemble, cette sortie révèle les composants clés d'un modèle d'apprentissage en profondeur basé sur l'architecture Transformer. Ce modèle est largement utilisé dans les tâches de traitement du langage naturel, telles que la classification de textes, la traduction automatique, les systèmes de questions-réponses, etc. La structure de chaque couche est presque la même, y compris le mécanisme d'attention, le réseau de rétroaction et la couche de normalisation, ce qui aide le modèle à capturer les caractéristiques complexes de la séquence d'entrée.
Voir la configuration des paramètres du modèle Llama3 :
with open("Meta-Llama-3-8B/params.json", "r") as f:config = json.load(f)config
图片
我们使用这个配置来推断模型的细节,比如:
dim = config["dim"]n_layers = config["n_layers"]n_heads = config["n_heads"]n_kv_heads = config["n_kv_heads"]vocab_size = config["vocab_size"]multiple_of = config["multiple_of"]ffn_dim_multiplier = config["ffn_dim_multiplier"]norm_eps = config["norm_eps"]rope_theta = torch.tensor(config["rope_theta"])
图片
代码如下:
prompt = "the answer to the ultimate question of life, the universe, and everything is "tokens = [128000] + tokenizer.encode(prompt)print(tokens)tokens = torch.tensor(tokens)prompt_split_as_tokens = [tokenizer.decode([token.item()]) for token in tokens]print(prompt_split_as_tokens)
[128000, 1820, 4320, 311, 279, 17139, 3488, 315, 2324, 11, 279, 15861, 11, 323, 4395, 374, 220]['<|begin_of_text|>', 'the', ' answer', ' to', ' the', ' ultimate', ' question', ' of', ' life', ',', ' the', ' universe', ',', ' and', ' everything', ' is', ' ']
截止到目前,我们的[17x1]令牌现在变成了[17x4096],即长度为4096的17个嵌入(每个令牌一个)。
下图是为了验证我们输入的这句话,是17个token。
图片
代码如下:
embedding_layer = torch.nn.Embedding(vocab_size, dim)embedding_layer.weight.data.copy_(model["tok_embeddings.weight"])token_embeddings_unnormalized = embedding_layer(tokens).to(torch.bfloat16)token_embeddings_unnormalized.shape
图片
我们接着使用 RMS 归一化对嵌入进行归一化,也就是图中这个位置:
图片
使用公式如下:
图片
代码如下:
# def rms_norm(tensor, norm_weights):# rms = (tensor.pow(2).mean(-1, keepdim=True) + norm_eps)**0.5# return tensor * (norm_weights / rms)def rms_norm(tensor, norm_weights):return (tensor * torch.rsqrt(tensor.pow(2).mean(-1, keepdim=True) + norm_eps)) * norm_weights
这段代码定义了一个名为 rms_norm 的函数,它实现了对输入张量(tensor)的RMS(Root Mean Square,均方根)归一化处理。这个函数接受两个参数:tensor 和 norm_weights。tensor 是需要进行归一化处理的输入张量,而 norm_weights 是归一化时使用的权重。
函数的工作原理如下:
在进行归一化处理后,我们的数据形状仍然保持为 [17x4096],这与嵌入层的形状相同,只不过数据已经过归一化。
token_embeddings = rms_norm(token_embeddings_unnormalized, model["layers.0.attention_norm.weight"])token_embeddings.shape
图片
图片
接下来,我们介绍注意力机制的实现,也就是下图中的红框标注的位置:
图片
图片
计算 ( Q ) 和 ( K ) 的点积。
对点积结果进行缩放。
应用softmax函数得到注意力权重。
用注意力权重乘以值矩阵 ( V ) 得到输出矩阵 ( Z )。
这张图展示了Transformer模型中多头注意力机制的实现过程,从输入句子的嵌入开始,经过多头分割、注意力计算,最后拼接结果并生成输出。每个步骤都详细说明了如何从输入矩阵 ( X ) 生成最终的输出矩阵 ( Z )。
当我们从模型中加载查询(query)、键(key)、值(value)和输出(output)向量时,我们注意到它们的形状分别是 [4096x4096]、[1024x4096]、[1024x4096]、[4096x4096]
乍一看这很奇怪,因为理想情况下我们希望每个头的每个q、k、v和o都是单独的
print(model["layers.0.attention.wq.weight"].shape,model["layers.0.attention.wk.weight"].shape,model["layers.0.attention.wv.weight"].shape,model["layers.0.attention.wo.weight"].shape)
Image
La forme de la matrice de poids de requête (wq.weight) est [4096, 4096]. La forme de la matrice de poids clé (wk.weight) est [1024, 4096]. La forme de la matrice de pondération des valeurs (wv.weight) est [1024, 4096]. La forme de la matrice de poids de sortie (Output) (wo.weight) est [4096, 4096]. Les résultats de sortie montrent que les formes des matrices de poids de requête (Q) et de sortie (O) sont les mêmes [4096, 4096]. Cela signifie que la fonctionnalité d'entrée et la fonctionnalité de sortie ont des dimensions de 4 096 pour la requête et la sortie. Les formes des matrices de poids clé (K) et valeur (V) sont également les mêmes, toutes deux [1024, 4096]. Cela montre que les dimensions des fonctionnalités d'entrée pour les clés et les valeurs sont 4096, mais que les dimensions des fonctionnalités de sortie sont compressées à 1024. La forme de ces matrices de poids reflète la manière dont le concepteur du modèle définit les dimensions des différentes parties du mécanisme d'attention. En particulier, les dimensions des clés et des valeurs sont probablement réduites pour réduire la complexité de calcul et la consommation de mémoire, tandis que conserver les requêtes et les sorties en dimensionnalité plus élevée peut permettre de conserver plus d'informations. Ce choix de conception dépend de l'architecture du modèle spécifique et du scénario d'application
Utilisons la phrase « J'admire Li Hongzhang » comme exemple pour simplifier le processus de mise en œuvre consistant à expliquer le mécanisme d'attention dans cette figure. Entrez la phrase : Tout d'abord, nous avons la phrase « J'admire Li Hongzhang ». Avant de traiter cette phrase, nous devons convertir chaque mot de la phrase en une forme mathématiquement traitable, c'est-à-dire un vecteur de mots. Ce processus est appelé intégration de mots.
Intégration de mots : chaque mot, tel que "Je", "appréciation", "Li Hongzhang", sera converti en un vecteur de taille fixe. Ces vecteurs contiennent les informations sémantiques des mots.
Divisé en plusieurs têtes : Afin de permettre au modèle de comprendre la phrase sous différentes perspectives, nous divisons le vecteur de chaque mot en plusieurs parties, voici 8 têtes. Chaque tête se concentre sur un aspect différent de la phrase.
Calculer l'attention : Pour chaque tête, nous calculons quelque chose appelé attention. Ce processus comporte trois étapes : Prenons l'exemple de « J'apprécie Li Hongzhang ». Si nous voulons nous concentrer sur le mot « appréciation », alors « appréciation » est la requête, et d'autres mots tels que « Je » et « Li Hongzhang ». sont des clés. Le vecteur de est la valeur.
Requête (Q) : C'est la partie où nous voulons trouver des informations. Clé (K) : C'est la partie qui contient l'information. Valeur (V) : Il s'agit du contenu réel de l'information. Épissage et sortie : Après avoir calculé l'attention de chaque tête, nous concaténons ces résultats et générons la sortie finale via une matrice de poids Wo. Cette sortie sera utilisée dans la couche de traitement suivante ou dans le cadre du résultat final.
Le problème de forme mentionné dans les commentaires sur la figure concerne la manière de stocker et de traiter efficacement ces vecteurs dans un ordinateur. Dans l'implémentation réelle du code, afin d'améliorer l'efficacité, les développeurs peuvent regrouper les vecteurs de requête, de clé et de valeur de plusieurs en-têtes ensemble au lieu de traiter chaque en-tête individuellement. Cela permet de tirer parti des capacités de traitement parallèle des ordinateurs modernes pour accélérer les calculs.
Les résultats de sortie montrent que :
La forme de ces matrices de poids reflète la façon dont le concepteur du modèle définit les dimensions des différentes parties du mécanisme d'attention. En particulier, les dimensions des clés et des valeurs sont probablement réduites pour réduire la complexité de calcul et la consommation de mémoire, tandis que conserver les requêtes et les sorties en dimensionnalité plus élevée peut permettre de conserver plus d'informations. Ce choix de conception dépend de l'architecture du modèle spécifique et du scénario d'application
Utilisons la phrase « J'admire Li Hongzhang » comme exemple pour simplifier le processus de mise en œuvre consistant à expliquer le mécanisme d'attention dans cette figure.
Requête (Q) : C'est la partie où nous voulons trouver des informations.
Clé (K) : C'est la partie qui contient des informations.
Valeur (V) : Il s'agit du contenu réel de l'information.
Le problème de forme mentionné dans les commentaires sur la figure concerne la manière de stocker et de traiter efficacement ces vecteurs dans un ordinateur. Dans l'implémentation réelle du code, afin d'améliorer l'efficacité, les développeurs peuvent regrouper les vecteurs de requête, de clé et de valeur de plusieurs en-têtes ensemble au lieu de traiter chaque en-tête individuellement. Cela permet de tirer parti des capacités de traitement parallèle des ordinateurs modernes pour accélérer les calculs.
Nous continuons à utiliser la phrase « J'apprécie Li Hongzhang » pour expliquer le rôle des matrices de poids WQ, WK, WV et WO.
Dans le modèle Transformer, chaque mot est converti en vecteur grâce à l'intégration de mots. Ces vecteurs subissent ensuite une série de transformations linéaires pour calculer les scores d’attention. Ces transformations linéaires sont implémentées à travers les matrices de poids WQ, WK, WV et WO.
Dans l'ensemble du processus, WQ, WK, WV et WO sont appris grâce à la formation. Ils déterminent comment le modèle convertit les vecteurs de mots d'entrée en différentes représentations et comment combiner ces représentations pour obtenir le résultat final. Ces matrices constituent l'élément central du mécanisme d'attention dans le modèle Transformer et permettent au modèle de capturer la relation entre les différents mots de la phrase.
WQ (matrice de poids Q), WK (matrice de poids K), WV (matrice de poids V) et WO (matrice de poids O). Ces matrices sont des paramètres du modèle Transformer. Elles sont transmises par rétro-propagation pendant le processus de formation du modèle. . Cela s'apprend des méthodes d'optimisation telles que les algorithmes et la descente de gradient.
Voyons comment fonctionne ce processus d'apprentissage :
在本小节中,我们将从多个注意力头中展开查询向量,得到的形状是 [32x128x4096] 这里,32 是 llama3 中注意力头的数量,128 是查询向量的大小,而 4096 是令牌嵌入的大小。
q_layer0 = model["layers.0.attention.wq.weight"]head_dim = q_layer0.shape[0] // n_headsq_layer0 = q_layer0.view(n_heads, head_dim, dim)q_layer0.shape
图片
这段代码通过对模型中第一层的查询(Q)权重矩阵进行重塑(reshape),将其分解为多个注意力头的形式,从而揭示了32和128这两个维度。
之所以在这段代码中出现了32和128这两个维度,而在之前的代码段中没有,是因为这段代码通过重塑操作明确地将查询权重矩阵分解为多个注意力头,每个头具有自己的维度。32代表了模型中注意力头的数量,而128代表了分配给每个头的特征维度大小。这种分解是为了实现多头注意力机制,其中每个头可以独立地关注输入的不同部分,最终通过组合这些头的输出来提高模型的表达能力。
访问了第一层第一个头的查询(query)权重矩阵,这个查询权重矩阵的大小是 [128x4096]。
q_layer0_head0 = q_layer0[0]q_layer0_head0.shape
图片
在这里,你可以看到结果形状是 [17x128],这是因为我们有17个令牌,每个令牌都有一个长度为128的查询(每个令牌在一个头上方的查询)。
br
Picture
Ce code effectue une opération de multiplication matricielle, en comparant les intégrations de jetons (token_embeddings) avec la transposition (.T) de la matrice de poids de requête (q_layer0_head0) de la première tête de la première couche Multipliez pour générer un par -vecteur de requête de jeton (q_per_token).
torch.matmul est la fonction de multiplication matricielle de PyTorch, qui peut gérer la multiplication de deux tenseurs.
token_embeddings doit être un tenseur de forme [17, 4096], représentant 17 jetons, chacun représenté par un vecteur d'intégration de 4096 dimensions.
q_layer0_head0 est la matrice de poids de requête de la première tête de la première couche, et sa forme originale est [128, 4096]. .T est l'opération de transposition dans PyTorch, qui transpose la forme de q_layer0_head0 en [4096, 128].
De cette façon, la multiplication matricielle de token_embeddings et q_layer0_head0.T est la multiplication de [17, 4096] et [4096, 128], et le résultat est un tenseur de forme [17, 128].
Cette ligne de code imprime la forme du tenseur q_per_token, confirmant qu'il s'agit bien de [17, 128].
Cela signifie que pour chaque jeton saisi (17 au total), nous disposons désormais d'un vecteur de requête à 128 dimensions. Ce vecteur de requête à 128 dimensions est obtenu en multipliant l'intégration de jetons et la matrice de poids de requête et peut être utilisé pour les calculs ultérieurs du mécanisme d'attention.
En résumé, ce code convertit le vecteur d'intégration de chaque jeton en un vecteur de requête par multiplication matricielle, préparant ainsi la prochaine étape de mise en œuvre du mécanisme d'attention. Chaque jeton possède désormais un vecteur de requête qui lui correspond, et ces vecteurs de requête seront utilisés pour calculer les scores d'attention avec d'autres jetons.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!