
ATTRYEGRID vous est apporté par Agora, nous sommes une toute nouvelle organisation de recherche multi-modale d'IA open source consacrée à l'avancement de l'humanité.
Rejoignez-nous ici pour contribuer à ce projet ou recevoir un soutien!

ATTRYEGRID est un cadre de pointe conçu pour démocratiser l'incorporation de mécanismes d'attention avancés dans les modèles d'IA. Propulsé par les derniers développements dans les modèles de transformateurs basés sur l'attention, l'attention s'ouvre le monde des mécanismes d'attention aux praticiens de l'apprentissage automatique, aux chercheurs et aux amateurs.
Pour vous détendre avec Amplat-Grid, installez le package à l'aide de PIP:
pip install AttentionGridLa mise en œuvre d'un mécanisme d'attention ou d'un modèle de transformateur avec ATTRYEGRID est aussi simple que:
from AttentionGrid import BlockwiseParallelJax
import jax . numpy as jnp
# Initialize the class
bpjax = BlockwiseParallelJax (
q_chunk_size = 64 ,
k_chunk_size = 64 ,
hidden_size = 768 ,
num_heads = 12 ,
rotary_dim = 32 ,
intermediate_size = 3072
)
# Suppose we have hidden_states, attention_mask, and position_ids as input data
hidden_states = jnp . random . rand ( 1 , 100 , 768 )
attention_mask = jnp . random . rand ( 1 , 1 , 100 , 100 )
position_ids = jnp . arange ( 100 ). reshape ( 1 , 100 )
# You can now apply the attention mechanism to your input data
output = bpjax . forward ( hidden_states , attention_mask , position_ids )Nous vous encourageons à partager l'attention avec votre communauté! Voici des liens de partage rapide pour plusieurs plateformes de médias sociaux:
Partager sur Twitter
Partager sur LinkedIn
Partager sur Facebook
Partager sur Reddit
Partager sur WhatsApp
Merci de soutenir l'attention et de contribuer à la démocratisation de l'IA! Ensemble, nous pouvons repousser les limites de ce qui est possible.
Dans le vaste paysage de l'IA, les mécanismes d'attention ont révolutionné notre capacité à créer des modèles puissants qui peuvent discerner les subtilités des données, en se concentrant sur des aspects importants et en améliorant les performances globales. Notre vision avec l'attention est de combler l'écart entre ces mécanismes de pointe et leurs applications pratiques, fournissant un outil qui rend ces techniques accessibles et faciles à mettre en œuvre dans diverses applications d'IA.
ATTRYEGRID est conçu avec une architecture intuitive et flexible, partitionnée en quatre composantes principales:
Core : Il s'agit du fondement de notre cadre, des classes abstraites de logement qui disposent la structure de base pour les mécanismes d'attention et les modèles de transformateurs.
Attentions ?: Le répertoire dédié à divers mécanismes d'attention. Chaque mécanisme d'attention est mis en œuvre sur la base du plan fourni dans le noyau.
Transformers ?: C'est là que les modèles de transformateurs prennent vie, chacun sculpté après la conception définie dans le noyau.
Utils : une boîte à outils remplie de classes d'assistance pour les tâches essentielles comme le chargement du modèle, le prétraitement des données, etc.
Exemples : démystifier la mise en œuvre avec des exemples pratiques et des scénarios d'utilisation.
Structure modulaire : mélangez et associez différents mécanismes d'attention avec une variété de modèles de transformateurs.
Convivial : Documentation claire et exemples pour vous aider à démarrer rapidement.
Open source : Ouvert aux contributions, l'attention s'occupe des connaissances collectives et des progrès partagés.
Pour des exemples plus détaillés, veuillez vous référer au dossier «Exemples» de notre référentiel.
Nous invitons ouvertement des contributions à l'attention! Que vous ayez une nouvelle suggestion de fonctionnalités, un rapport de bogue ou que vous souhaitiez ajouter à notre code, n'hésitez pas à ouvrir un problème ou à soumettre une demande de traction.
ATTRYEGRID est fièrement des logiciels open-source, sous licence Apache.
Les mécanismes d'attention ont transformé l'IA, permettant aux machines de «se concentrer» sur des parties importantes des données d'entrée. Avec AmplatridGrid, nous visons à démocratiser l'accès à ces outils puissants. Nous pensons que l'avenir de l'IA réside dans le pouvoir de l'attention, et par l'attention, nous espérons accélérer ce voyage. Explorez notre référentiel, rejoignez notre cause et naviguons ensemble ce paysage passionnant!
"Les détails ne sont pas les détails. Ils font la conception." - Charles Eames
Intégrer l'attention du flash et les variantes
Intégrer l'attention historique
Intégrer l'attention parallèle en bloc
Intégrer l'attention dynamique du flash clairsemé
Intégrer l'attention de la transmission de ImageBind
Intégrer l'attention Colt-5
Intégrer l'attention multi-requer
Intégrer les emballages de Lucid Rains X_Transformateurs, Decoder, Attention, Encoder, Transformateur Wrapper
| Mécanisme | Méthode d'appel | Exemple d'importation |
|---|---|---|
| Auto-assurance | from AttentionGrid import SelfAttention | from AttentionGrid import SelfAttention |
| Attention mondiale | from AttentionGrid import GlobalAttention | from AttentionGrid import GlobalAttention |
| Attention locale | from AttentionGrid import LocalAttention | from AttentionGrid import LocalAttention |
| Attention hiérarchique | from AttentionGrid import HierarchicalAttention | from AttentionGrid import HierarchicalAttention |
| Attention clairsemée dynamique | from AttentionGrid import dynamic_sparse_attention | from AttentionGrid import dynamic_sparse_attention |
| Fonction compacte | from AttentionGrid import compact | from AttentionGrid import compact |
| Fonction d'index du pad | from AttentionGrid import pad_index | from AttentionGrid import pad_index |
| Attention parallèle en bloc | from AttentionGrid import BlockwiseParallelJax | from AttentionGrid import BlockwiseParallelJax |
| Attention flash | from AttentionGrid import FlashAttention | from AttentionGrid import FlashAttention |
| Attention historique | from AttentionGrid import LandmarkAttention | from AttentionGrid import LandmarkAttention |
| Colt-5 Attention | from AttentionGrid import Colt5Attention | from AttentionGrid import Colt5Attention |
| Attention multi-Quey | from AttentionGrid import MultiQueryAttention | from AttentionGrid import MultiQueryAttention |
| Attention dilatée | from AttentionGrid import DilatedAttention | from AttentionGrid import DilatedAttention |
La fonction dynamic_sparse_attention d'Agora permet la flexibilité de choisir entre l'implémentation de hash-sasse et l'implémentation QK-SSASSE. L'objectif de cette fonction est de diriger dynamiquement le mécanisme d'attention clairsemé basé sur le sparsity_mode sélectionné.
Les paramètres de fonction sont les suivants:
q : Tenseur de requête de forme (lot, N_CTX_Q, H, D_HEAD)k : Tenseur clé de forme (Lot, N_CTX_KV, H, D_HEAD)v : Valeur tenseur de forme (lot, n_ctx_kv, h, d_head)q_idx & k_idx : représentent soit l'indice de seau si Sparsity_Mode est 'hash' ou s'il faut garder une tête donnée si Sparsity_Mode est 'QK'. Les formes du tenseur sont (lot, n_ctx_q, h) et (lot, n_ctx_kv, h) respectivement.sm_scale : constante de normalisation, 1 / sqrt (d_head) sauf si spécifié.sparsity_mode : «Hash» pour sélectionner l'implémentation de hash-sasse et «QK» pour l'implémentation QK-SPASSE. Le sm_scale est calculé par défaut s'il n'est pas fourni, et si une sparsity_mode inconnue est donnée, elle lance une clé de vue.
La fonction vérifie ensuite le sparsity_mode et en fonction de sa valeur, il appelle hash_sparse_attention ou qk_sparse_attention .
La fonction compact construit une représentation compacte du tenseur d'entrée x en utilisant les informations de keep_tensor .
Les paramètres de fonction sont:
x : Tenseur d'entrée à compact, avec forme (lot, n_ctx, h, d_head).keep_tensor : tenseur flottant de forme (lot, n_ctx, h) contenant un 1 lorsque la tête est conservée et 0 autrement. La fonction calcule d'abord les indices_per_head qui calcule le nombre d'éléments non tués par tête. Il trie le keep_tensor dans un ordre décroissant tout en préservant l'ordre des éléments égaux (stable = true). Il rassemble ensuite les éléments de x en fonction du tenseur d'index. Le résultat est une représentation compacte de x avec le tenseur d'index et le tenseur représentant le nombre d'éléments non tués par tête.
La fonction pad_index remporte le tenseur d'index pour se conformer au noyau. Il prend les paramètres suivants:
index : Tenseur d'index d'origine donné par compact , avec forme (lot, buffer_size, h). Pour chaque lot et étapes horaire, il représente l'indice de tête dont il est originaire.indices_per_head : Pour chaque tête, contient le nombre d'indices qui n'ont pas été abandonnés. Il crée une copie du tenseur d'index et crée un masque basé sur la taille de indices_per_head . Ensuite, il modifie les indices de la copie qui correspondent à True dans le masque pour être égal à pad_idx .
La fonction qk_sparse_attention fait partie du mécanisme d'attention clairsemé dynamique. Il est utilisé lorsque sparsity_mode est défini sur «QK». Cette fonction implémente le mécanisme d'attention QK-SSAPS et nécessite que les paramètres q_keep et k_keep soient de type float.
Il construit d'abord des représentations compactes des tenseurs de requête, de clé et de valeur à l'aide de la fonction compact . Il remplit ensuite les tenseurs d'index à l'aide de la fonction pad_index . Les tenseurs sont ensuite transposés pour compatibilité avec le noyau. Enfin, la fonction appelle la fonction qk_sparse_attention_kernel et diffuse le tenseur résultant dans l'espace de dimension d'origine.
La fonction hash_sparse_attention fait partie du mécanisme d'attention rare dynamique. Il est utilisé lorsque sparsity_mode est défini sur «Hash». Cette fonction met en œuvre le mécanisme d'attention par hachage.
La fonction prend les mêmes paramètres d'entrée que qk_sparse_attention . Cependant, au lieu des paramètres q_keep et k_keep , la fonction hash_sparse_attention nécessite q_bucket_idx et k_bucket_idx qui représentent respectivement les indices de seau pour les requêtes et les touches.
La fonction hash_sparse_attention trie d'abord les tenseurs de requête, de clé et de valeur en fonction des indices de seau à l'aide de la fonction sort_bucketed_attention . Ensuite, il construit des représentations compactes des tenseurs de requête, de clé et de valeur triés à l'aide de la fonction compact . Il remplit ensuite les tenseurs d'index à l'aide de la fonction pad_index .
Les tenseurs sont ensuite transposés pour compatibilité avec le noyau. La fonction appelle ensuite la fonction hash_sparse_attention_kernel et diffuse le tenseur résultant dans l'espace de dimension d'origine.
La fonction sort_bucketed_attention est une fonction d'assistance utilisée dans hash_sparse_attention . Il trie les tenseurs d'entrée en fonction des indices de seau donnés.
Les paramètres de fonction sont:
qkv : requête, clé, tense de valeur de forme (lot, n_ctx, h, d_head)qkv_bucket_idx : Indices de godet pour les requêtes, les clés et les valeurs de forme (Lot, N_CTX, H) La fonction trie d'abord le tenseur qkv_bucket_idx et obtient les indices triés. Ensuite, il trie les tenseurs qkv en utilisant les indices triés. Il élargit également qkv_bucket_idx pour être la même forme que qkv pour la compatibilité.
La fonction qk_sparse_attention_kernel est une fonction de noyau utilisée dans qk_sparse_attention . Il calcule la somme pondérée des valeurs en fonction du softmax de la requête et du produit clé.
Les paramètres de fonction sont:
q : Tenseur de requête de forme (lot, N_CTX_Q, H, D_HEAD)k : Tenseur clé de forme (Lot, N_CTX_KV, H, D_HEAD)v : Valeur tenseur de forme (lot, n_ctx_kv, h, d_head)sm_scale : constante de normalisation, 1 / sqrt (d_head) sauf si spécifié. La fonction hash_sparse_attention_kernel est une fonction de noyau utilisée dans hash_sparse_attention . Il fonctionne de manière similaire à qk_sparse_attention_kernel mais gère le seau pour l'attention de Hash-Spars.
Les paramètres de fonction sont les mêmes que ceux de qk_sparse_attention_kernel . Cependant, q , k et v ont été triés et compactés en fonction des indices de seau.
Le noyau calcule le produit de la requête et de la clé, l'échelle par sm_scale , applique softmax pour obtenir les poids, puis calcule la somme pondérée des valeurs.
Veuillez noter qu'il s'agit d'une interprétation générale de la documentation, et la compréhension et la modification de ces fonctions dans la pratique peut nécessiter une connaissance approfondie des mécanismes d'attention clairsemés et des principes d'apprentissage en profondeur.
Fonction Blockwise_Compute_attn :
La fonction blockwise_compute_attn est une partie importante de la classe BlockwiseParallelJax et est utilisée pour calculer le mécanisme d'attention du modèle de manière bloc.
Paramètres:
query , key , value : ces paramètres sont les principales entrées pour le calcul de l'attention, représentant respectivement les requêtes, les clés et les valeurs.bias : paramètre facultatif utilisé pour ajouter un biais aux scores d'attention avant SoftMax.deterministic : un drapeau booléen utilisé pour décider de l'application ou non de décrochage.dropout_rng : le générateur de nombres aléatoires pour Dropout.attn_pdrop : La probabilité d'abandon pour l'attention.causal_mask : un drapeau booléen pour utiliser ou non un masque d'attention causal.query_chunk_size , key_chunk_size : la taille de chaque requête et morceau clé, respectivement.dtype : Le type de données du calcul. Sa valeur par défaut est jnp.float32 .policy : Ce paramètre définit la politique de point de contrôle de gradient.precision : ce paramètre est utilisé pour définir le niveau de précision du calcul. La valeur par défaut est lax.Precision.HIGHEST .prevent_cse : un drapeau booléen utilisé pour empêcher l'élimination commune de la sous-expression.Fonction Blockwise_Compute_ffn :
La fonction blockwise_compute_ffn est utilisée pour calculer le réseau d'alimentation du modèle de manière blockwise.
Paramètres:
cell : la cellule du réseau auquel la fonction est appliquée.inputs : les données d'entrée pour le réseau Feed-Forward.chunk_size : la taille de chaque morceau pour le calcul en bloc.deterministic : un drapeau booléen utilisé pour décider de l'application ou non de décrochage.policy : Ce paramètre définit la politique de point de contrôle de gradient.prevent_cse : un drapeau booléen utilisé pour empêcher l'élimination commune de la sous-expression.Classe Blockwise_LM_HEAD :
La classe Blockwise_LM_Head est un module qui applique une transformation linéaire suivie d'une fonction softmax pour produire une distribution sur le vocabulaire pour chaque position dans l'entrée.
vocab_size : la taille du vocabulaire, qui est également la taille de la dimension de sortie de la transformation linéaire.chunk_size : la taille de chaque morceau pour le calcul en bloc.policy : Ce paramètre définit la politique de point de contrôle de gradient.dtype : Le type de données du calcul. Sa valeur par défaut est jnp.float32 .prevent_cse : un drapeau booléen utilisé pour empêcher l'élimination commune de la sous-expression.Fonction Blockwise_Cross_entropy :
La fonction blockwise_cross_entropy calcule la perte de l'entropie croisée pour les prévisions du modèle de manière en bloc.
Paramètres:
logits : les prédictions de sortie du modèle.tokens : les vraies étiquettes.valid : un masque qui spécifie les positions valides dans l'entrée.chunk_size : la taille de chaque morceau pour le calcul en bloc.policy : Ce paramètre définit la politique de point de contrôle de gradient.prevent_cse : un drapeau booléen utilisé pour empêcher l'élimination commune de la sous-expression.Classe BlockWiseParalleljax :
BlockwiseParallelJax ( q_chunk_size , k_chunk_size , hidden_size , num_heads , rotary_dim , intermediate_size , layer_norm_epsilon = 1e-5 , activation_function = "gelu" , attn_pdrop = 0.0 , resid_pdrop = 0.0 , max_position_embeddings = 1024 , dtype = jnp . float32 , causal = True , policy = 'nothing_saveable' , prevent_cse = False , float32_logits = False )Paramètres
q_chunk_size : entier. Taille de morceaux pour la requête en auto-attention.k_chunk_size : entier. Taille des morceaux pour la clé de l'attention de soi.hidden_size : entier. Dimensionnalité de la couche cachée dans le transformateur.num_heads : entier. Nombre de têtes d'attention dans le mécanisme d'auto-agencement.rotary_dim : entier ou aucun. Nombre de dimensions à utiliser pour le codage de position rotatif.intermediate_size : entier. Taille de la couche intermédiaire dans le réseau d'alimentation.layer_norm_epsilon : float. Petite constante pour empêcher la division par zéro dans la normalisation de la couche. La valeur par défaut est 1e-5 .activation_function : chaîne. Fonction d'activation à utiliser dans le réseau alimentaire. La valeur par défaut est 'gelu' .attn_pdrop : float. Probabilité d'abandon pour le mécanisme d'attention. La valeur par défaut est 0.0 .resid_pdrop : float. Probabilité d'abandon pour les connexions résiduelles. La valeur par défaut est 0.0 .max_position_embeddings : entier. Nombre maximum d'incorporation de position à utiliser. La valeur par défaut est 1024 .dtype : JNP.DTYPE. Type de données à utiliser pour le calcul. La valeur par défaut est jnp.float32 .causal : booléen. Que ce soit pour utiliser le mode causal (auto-régressif) ou non. La valeur par défaut est True .policy : chaîne. Politique de contrôle des gradients de pointage. La valeur par défaut est 'nothing_saveable' .prevent_cse : Boolean. Sans empêcher l'élimination commune de la sous-expression (CSE). La valeur par défaut est False .float32_logits : booléen. Si vous devez utiliser Float32 pour le calcul des logits. La valeur par défaut est False .Méthodes
La méthode principale de la classe BlockwiseParallelJax est la méthode forward , qui effectue le passage avant du bloc transformateur.
forward ( hidden_states , attention_mask , position_ids , deterministic = True , init_cache = False )hidden_states : JNP.NDARRAY. Le tenseur d'entrée dans le bloc de transformateur. Il doit avoir une forme (batch_size, sequence_length, hidden_size) .attention_mask : jnp.ndarray. Le masque d'attention pour le mécanisme d'auto-agencement. Il doit avoir une forme (batch_size, 1, 1, sequence_length) .position_ids : jnp.ndarray. Les ID de position pour l'encodage positionnel. Il doit avoir une forme (1, sequence_length) .deterministic : booléen. Que ce soit pour utiliser le mode déterministe (pas d'abandon) ou non. La valeur par défaut est True .init_cache : booléen. S'il faut initialiser le cache pour le décodage rapide. La valeur par défaut est False . Cette méthode renvoie le tenseur de sortie du bloc de transformateur, qui a la même forme que hidden_states .
Exemple d'utilisation
L'exemple suivant montre comment utiliser la classe BlockwiseParallelJax .
# Initialize
from jax import random
import jax . numpy as jnp
from AttentionGrid import BlockwiseParallelJax
# Initialize transformer block
block = BlockwiseParallelJax (
q_chunk_size = 64 ,
k_chunk_size = 64 ,
hidden_size = 768 ,
num_heads = 12 ,
rotary_dim = 64 ,
intermediate_size = 3072 ,
)
# Create a batch of input tensors
key = random . PRNGKey ( 0 )
batch_size = 8
sequence_length = 128
hidden_states = random . normal ( key , ( batch_size , sequence_length , block . hidden_size ))
# Create attention mask
attention_mask = jnp . ones (( batch_size , 1 , 1 , sequence_length ))
# Create position ids
position_ids = jnp . arange ( sequence_length )[ None , :]
# Forward pass
output = block . forward ( hidden_states , attention_mask , position_ids )
print ( output . shape ) # prints: (8, 128, 768) FusedLandmarkAttention Il s'agit d'une classe Function Pytorch qui encapsule les fonctions avant et arrière du mécanisme d'attention de fond fusionné.
forward(ctx, q, k, v, n_prefix_q, sm_scale, block_size)Cette fonction effectue le passage avant de l'attention de la marque fusionnée.
ctx : un objet dans lequel nous pouvons enregistrer des variables à utiliser dans le passage arrière. Fourni par le système Autograd de Pytorch.q : Le tenseur des requêtes. Il est supposé être contigu et sa forme devrait être (lot, nheads, seqlen_q, d).k : Le tenseur des clés. Il est supposé être contigu, et sa forme doit correspondre à la forme de Q, c'est-à-dire (lot, nheads, seqlen_k, d).v : Le tenseur de valeurs. Il est supposé être contigu, et sa forme doit correspondre aux formes de Q et K, c'est-à-dire (lot, nheads, seqlen_k, d).n_prefix_q : le nombre de préfixes dans les requêtes.sm_scale : Le facteur de mise à l'échelle utilisé dans l'opération SoftMax.block_size : La taille du bloc pour effectuer des opérations en blocs. o : Le tenseur de sortie du collier du col du mécanisme d'attention de fond fusionné. backward(ctx, do)Cette fonction effectue le col en arrière de l'attention de la marque fondue, c'est-à-dire qu'il calcule les gradients.
ctx : un objet à partir duquel nous pouvons récupérer des variables enregistrées dans le passage avant. Fourni par le système Autograd de Pytorch.do : le gradient de la perte par rapport à la sortie de la fonction avant. None .fused_landmark_attention(q, k, v, is_mem, sm_scale=None, block_size=64) Cette fonction est un emballage pratique pour la classe FusedLandmarkAttention .
q : Le tenseur des requêtes.k : Le tenseur des clés.v : Le tenseur de valeurs.is_mem : un tenseur booléen indiquant si chaque paire de valeurs de clé doit être traitée comme de la mémoire. Il doit avoir la même longueur que la longueur de séquence des touches.sm_scale : Le facteur de mise à l'échelle utilisé dans l'opération SoftMax. Si None , il sera défini sur 1.0 / sqrt(d) .block_size : La taille du bloc pour effectuer des opérations en blocs. Voici un exemple de base de la façon d'utiliser la fonction fused_landmark_attention .
import torch
from AttentionGrid import fused_landmark_attention
# Initialize some tensors
batch = 8
nheads = 12
seqlen = 128
d = 64
q = torch . randn ( batch , nheads , seqlen , d )
k = torch . randn ( batch , nheads , seqlen , d )
v = torch . randn ( batch , nheads , seqlen , d )
is_mem = torch . zeros ( seqlen , dtype = torch . bool )
# Call the function
output = fused_landmark_attention ( q , k , v , is_mem )
print ( output . shape ) # prints: (8, 12, 128, 64)Cet exemple initialise d'abord certains tenseurs pour servir de requêtes, clés
et valeurs. Ensuite, il appelle la fonction fused_landmark_attention et imprime la forme du tenseur de sortie.
import torch
import torch . nn as nn
from AttentionGrid import DilatedAttention
# Replace this with your correct GPU device
device = "cuda:0"
dtype = torch . float16
# Create an instance of DilatedAttention
d_model = 512
num_heads = 8
dilation_rate = 2
segment_size = 64
dropout = 0.2 # Specify the dropout rate
attention = DilatedAttention (
d_model = d_model ,
num_heads = num_heads ,
dilation_rate = dilation_rate ,
segment_size = segment_size ,
dropout = dropout ,
). to ( device , dtype = dtype )
# Create some dummy input data
batch_size = 16
seq_len = 128
input_dim = d_model
inputs = torch . randn ( batch_size , seq_len , input_dim , device = device , dtype = dtype )
# Forward pass
outputs = attention ( inputs )
# Print the output shape
print ( outputs . shape ) # Expected: [batch_size, seq_len, d_model] Dans l'exemple ci-dessus, nous créons une instance de la classe DilatedAttention avec les hyperparamètres spécifiés. Nous générons ensuite des données d'entrée factice et les faisons passer par le mécanisme d'attention pour obtenir les sorties. Enfin, nous imprimons la forme du tenseur de sortie.
La classe DilatedAttention met en œuvre l'attention dilatée, qui élargit le champ attentif de façon exponentielle à mesure que la distance entre les jetons augmente. Il hérite de torch.nn.Module et peut être utilisé comme remplacement de dépassement pour les mécanismes d'attention standard dans les modèles de transformateurs.
d_model (int): la dimensionnalité des intégres d'entrée et de sortie.num_heads (int): le nombre de têtes d'attention.dilation_rate (INT): le taux de dilatation pour faire laraction de la séquence d'entrée.segment_size (int): la taille de chaque segment après la sparsification.dropout (Float, facultatif): la probabilité de dépôt pour s'appliquer à la sortie d'attention. Par défaut: 0,0 (pas de dépôt).x (tenseur): le tenseur d'entrée de forme (batch_size, seq_len, d_model) .output (tenseur): le tenseur de sortie de forme (batch_size, seq_len, d_model) . Veuillez noter que le tenseur d'entrée doit être sur le bon appareil (par exemple, GPU) et avoir le type de données approprié ( dtype ).