Uma biblioteca autônoma para adicionar embeddings rotativos a transformadores em Pytorch, após seu sucesso como codificação posicional relativa. Especificamente, tornará a rotação de informações em qualquer eixo de um tensor fácil e eficiente, sejam elas posicionais fixas ou aprendidas. Esta biblioteca fornecerá resultados de última geração para incorporação posicional, com custos baixos.
Meu instinto também me diz que há algo mais nas rotações que pode ser explorado em redes neurais artificiais.
$ pip install rotary-embedding-torch
import torch
from rotary_embedding_torch import RotaryEmbedding
# instantiate the positional embedding in your transformer and pass to all your attention layers
rotary_emb = RotaryEmbedding ( dim = 32 )
# mock queries and keys - dimensions should end with (seq_len, feature dimension), and any number of preceding dimensions (batch, heads, etc)
q = torch . randn ( 1 , 8 , 1024 , 64 ) # queries - (batch, heads, seq len, dimension of head)
k = torch . randn ( 1 , 8 , 1024 , 64 ) # keys
# apply the rotations to your queries and keys after the heads have been split out, but prior to the dot product and subsequent softmax (attention)
q = rotary_emb . rotate_queries_or_keys ( q )
k = rotary_emb . rotate_queries_or_keys ( k )
# then do your attention with your queries (q) and keys (k) as usual
Se você seguir todas as etapas acima corretamente, verá uma melhora dramática durante o treinamento.
Ao lidar com caches de chave/valor na inferência, a posição da consulta precisa ser compensada com key_value_seq_length - query_seq_length
Para facilitar isso, use o método rotate_queries_with_cached_keys
q = torch . randn ( 1 , 8 , 1 , 64 ) # only one query at a time
k = torch . randn ( 1 , 8 , 1024 , 64 ) # key / values with cache concatted
q , k = rotary_emb . rotate_queries_with_cached_keys ( q , k )
Você também pode fazer isso manualmente assim
q = rotary_emb . rotate_queries_or_keys ( q , offset = k . shape [ - 2 ] - q . shape [ - 2 ])
Para fácil uso de incorporação posicional relativa axial n-dimensional, ou seja. transformadores de vídeo
import torch
from rotary_embedding_torch import (
RotaryEmbedding ,
apply_rotary_emb
)
pos_emb = RotaryEmbedding (
dim = 16 ,
freqs_for = 'pixel' ,
max_freq = 256
)
# queries and keys for frequencies to be rotated into
# say for a video with 8 frames, and rectangular image (feature dimension comes last)
q = torch . randn ( 1 , 8 , 64 , 32 , 64 )
k = torch . randn ( 1 , 8 , 64 , 32 , 64 )
# get axial frequencies - (8, 64, 32, 16 * 3 = 48)
# will automatically do partial rotary
freqs = pos_emb . get_axial_freqs ( 8 , 64 , 32 )
# rotate in frequencies
q = apply_rotary_emb ( freqs , q )
k = apply_rotary_emb ( freqs , k )
Neste artigo, eles foram capazes de corrigir o problema de extrapolação de comprimento com embeddings rotativos, dando-lhes um decaimento semelhante ao ALiBi. Eles chamaram essa técnica de XPos, e você pode usá-la definindo use_xpos = True
na inicialização.
Isso só pode ser usado para transformadores autorregressivos
import torch
from rotary_embedding_torch import RotaryEmbedding
# instantiate the positional embedding in your transformer and pass to all your attention layers
rotary_emb = RotaryEmbedding (
dim = 32 ,
use_xpos = True # set this to True to make rotary embeddings extrapolate better to sequence lengths greater than the one used at training time
)
# mock queries and keys - dimensions should end with (seq_len, feature dimension), and any number of preceding dimensions (batch, heads, etc)
q = torch . randn ( 1 , 8 , 1024 , 64 ) # queries - (batch, heads, seq len, dimension of head)
k = torch . randn ( 1 , 8 , 1024 , 64 ) # keys
# apply the rotations to your queries and keys after the heads have been split out, but prior to the dot product and subsequent softmax (attention)
# instead of using `rotate_queries_or_keys`, you will use `rotate_queries_and_keys`, the rest is taken care of
q , k = rotary_emb . rotate_queries_and_keys ( q , k )
Este artigo da MetaAI propõe simplesmente o ajuste fino nas interpolações das posições da sequência para estender para um comprimento de contexto mais longo para modelos pré-treinados. Eles mostram que isso tem um desempenho muito melhor do que simplesmente fazer o ajuste fino nas mesmas posições da sequência, mas estendido ainda mais.
Você pode usar isso definindo interpolate_factor
na inicialização para um valor maior que 1.
(por exemplo, se o modelo pré-treinado foi treinado em 2048, definir interpolate_factor = 2.
permitiria o ajuste fino para 2048 x 2. = 4096
)
Atualização: alguém da comunidade relatou que não funciona bem. por favor me envie um e-mail se você ver um resultado positivo ou negativo
import torch
from rotary_embedding_torch import RotaryEmbedding
rotary_emb = RotaryEmbedding (
dim = 32 ,
interpolate_factor = 2. # add this line of code to pretrained model and fine-tune for ~1000 steps, as shown in paper
)
@misc { su2021roformer ,
title = { RoFormer: Enhanced Transformer with Rotary Position Embedding } ,
author = { Jianlin Su and Yu Lu and Shengfeng Pan and Bo Wen and Yunfeng Liu } ,
year = { 2021 } ,
eprint = { 2104.09864 } ,
archivePrefix = { arXiv } ,
primaryClass = { cs.CL }
}
@inproceedings { Sun2022ALT ,
title = { A Length-Extrapolatable Transformer } ,
author = { Yutao Sun and Li Dong and Barun Patra and Shuming Ma and Shaohan Huang and Alon Benhaim and Vishrav Chaudhary and Xia Song and Furu Wei } ,
year = { 2022 }
}
@inproceedings { Chen2023ExtendingCW ,
title = { Extending Context Window of Large Language Models via Positional Interpolation } ,
author = { Shouyuan Chen and Sherman Wong and Liangjian Chen and Yuandong Tian } ,
year = { 2023 }
}
@misc { bloc97-2023
title = { NTK-Aware Scaled RoPE allows LLaMA models to have extended (8k+) context size without any fine-tuning and minimal perplexity degradation. } ,
author = { /u/bloc97 } ,
url = { https://www.reddit.com/r/LocalLLaMA/comments/14lz7j5/ntkaware_scaled_rope_allows_llama_models_to_have/ }
}