Мадэлі на аснове трансфарматараў славяцца сваёй здольнасцю разбіраць і інтэрпрэтаваць складаны тэкст. Яны абапіраюцца на разуменне парадку і кантэксту слоў - задачы, у якіх традыцыйныя метады пазіцыйнага кадавання паказалі свае межы. Устараняючы гэты прабел, мадэль ROFORMER на аснове Rotary Position Embedding (RoPE) перавызначае наш падыход да пазіцыйнага кадавання.
Традыцыйнае пазіцыйнае кадаванне
Transformers разглядаюць тэкст як шэраг токенаў і дазваляюць паралельную апрацоўку паслядоўнасцяў для большай эфектыўнасці. Аднак гэтая сіла прынесла сваю праблему: уласцівы мадэлі агнастыцызм да сімвалічнага парадку. Пазіцыйнае кадзіраванне было адказам, забяспечваючы кожны токен унікальнай сігнатурай, якая пазначае яго пазіцыю ў паслядоўнасці.
Убудовы абсалютнай пазіцыі
Першапачаткова такія мадэлі, як BERT, выкарыстоўвалі абсалютныя ўбудовы пазіцый, прысвойваючы фіксаваны вектар кожнай пазіцыі ў паслядоўнасці. Гэтаму метаду, хоць і простаму, па сваёй сутнасці не хапае здольнасці адаптавацца да варыяцый даўжыні паслядоўнасці або падкрэсліваць адносныя адлегласці паміж лексемамі, што мае вырашальнае значэнне для разумення многіх лінгвістычных канструкцый.
Убудовы адноснага становішча
Каб выявіць дынамічную прыроду мовы, былі ўведзены ўбудовы адноснай пазіцыі, арыентаваныя на адлегласць паміж лексемамі, а не на іх абсалютныя пазіцыі. Нягледзячы на сваю канцэптуальную перавагу, гэтыя ўбудовы ўвялі складанасць вылічэнняў і не змаглі бесперашкодна інтэгравацца ў механізм самаканцэнтрацыі Трансформераў, што абмяжоўвае іх эфектыўнасць.
ROFORMER і паваротнае ўбудаванне
Прызнаючы абмежаванні існуючых стратэгій пазіцыйнага кадавання, ROFORMER прадстаўляе Rotary Position Embedding (RoPE), падыход, які спалучае ў сабе перавагі інфармацыі аб абсалютнай і адноснай пазіцыі без адпаведных недахопаў.
Убудаванне паваротнай пазіцыі
RoPE кадуе пазіцыйную інфармацыю з дапамогай матрыц кручэння, што дазваляе мадэлі разумець не толькі тое, дзе знаходзіцца токен, але і тое, як ён суадносіцца з кожным іншым токенам у паслядоўнасці.
Credit: ArXiv
Ён працуе праз геаметрычную лінзу, разглядаючы пазіцыі токенаў як кропкі ў шматмернай прасторы, якія паварочваюцца, каб адзначыць іх паслядоўныя адносіны. Такое паварот дазваляе мадэлі захоўваць і выкарыстоўваць як абсалютныя, так і адносныя пазіцыйныя сігналы ў сваім механізме ўвагі да сябе.
Укараненне RoPE
Рэалізацыя RoPE прадугледжвае кадзіраванне пазіцыі кожнага токена ў матрыцу кручэння і прымяненне гэтай матрыцы ў механізме самакіравання Transformer. Гэты працэс дазваляе гнуткую, дынамічную інтэрпрэтацыю пазіцыйнай інфармацыі, улічваючы розныя даўжыні паслядоўнасці і фіксуючы сутнасць узаемасувязяў токенаў без значных вылічальных выдаткаў.
Спачатку вам спатрэбіцца функцыя для генерацыі паваротных убудоў, а потым вы інтэграваеце гэтыя ўбудовы ў сваю мадэль. У прыкладзе ніжэй мяркуецца, што вы знаёмыя са стварэннем уласных слаёў у Keras.
Крок 1: Вызначце функцыю паваротнага ўбудавання
Гэтая функцыя стварае паваротныя ўбудовы з улікам максімальнай даўжыні паслядоўнасці і памернасці ўкладанняў.
from tensorflow.keras.layers import Layer
import numpy as np
def get_rotary_embedding(dim, max_seq_len):
inv_freq = 1.0 / (10000 ** (tf.range(0, dim, 2, dtype=tf.float32) / dim))
t = tf.range(max_seq_len, dtype=tf.float32)
freqs = tf.einsum('i,j->ij', t, inv_freq)
emb = tf.concat((tf.cos(freqs), tf.sin(freqs)), axis=-1)
return emb
inv_freq = 1.0 / (10000 ** (tf.range(0, dim, 2, dtype=tf.float32) / dim))
Гэты радок вылічвае адваротную экспанентна маштабаваную частату на аснове індэксаў пазіцыі. Гэтыя частоты выкарыстоўваюцца для генерацыі сінусоідных шаблонаў для паваротных убудоўванняў, што дапамагае ў кадзіраванні адноснай пазіцыйнай інфармацыі ў паслядоўнасцях. Гэты механізм асабліва карысны ў задачах, дзе разуменне парадку і адноснага размяшчэння элементаў мае вырашальнае значэнне, напрыклад, пры апрацоўцы натуральнай мовы або аналізе часовых шэрагаў.
Падрабязней:
-
tf.range(0, dim, 2, dtype=tf.float32)
стварае дыяпазон значэнняў, пачынаючы ад 0 даdim
(выключна), з крокам 2. Аргументdtype=tf.float32
вызначае што элементы гэтага тэнзара з'яўляюцца 32-бітнымі лікамі з плаваючай коскай. Напрыклад, калі "dim" роўна 8, атрымаецца "[0, 2, 4, 6]". -
Тэнзар, атрыманы
tf.range
, потым дзеліцца на памернасць (dim
) укладанняў. Гэтая аперацыя памяншае гэтыя індэксы да дыяпазону ад 0 да 1 (за выключэннем, калі "dim" цотны, крыху ўключна, калі "dim" няцотны, таму што крок дыяпазону прапускае ўсе астатнія значэнні). Працягваючы прыклад з "dim" = 8, дзяленне на 8 дае "[0.0, 0.25, 0.5, 0.75]". -
Аперацыя
10000 ** (...)
ўзводзіць 10 000 у ступень кожнага элемента ў раней маштабаваным тэнзары. База ў 10 000 з'яўляецца ў пэўнай ступені адвольнай, але выбрана для таго, каб частоты змяняліся ў шырокім дыяпазоне, што дапамагае мадэлі больш эфектыўна адрозніваць розныя пазіцыі. Для "[0.0, 0.25, 0.5, 0.75]" ён будзе прымяняць аперацыю ступені да кожнага, што прывядзе да значна большых значэнняў для вышэйшых элементаў. -
Нарэшце, адваротная частата атрымліваецца шляхам узяцця зваротнай (1/x) значэнняў з папярэдняга кроку. Зваротныя частоты меншыя для больш высокіх індэксаў, гэта значыць, што элементы далей у паслядоўнасці будуць мець меншыя частоты, што ўплывае на тое, як іх пазіцыі кадуюцца ў мадэлі. Гэта дазваляе ўбудаванням маштабавацца такім чынам, што адноснае становішча можа быць выведзена праз механізмы ўвагі мадэлі.
Радок:
freqs = tf.einsum('i,j->ij', t, inv_freq)
выкарыстоўвае функцыю tf.einsum
TensorFlow, інструмент, які дазваляе сціслае і эфектыўнае выражэнне тэнзарных аперацый з выкарыстаннем абазначэння сумавання Эйнштэйна.
Гэтая аперацыя эфектыўна вылічвае знешні здабытак вектараў "t" і "inv_freq", у выніку чаго атрымліваецца матрыца, дзе кожны элемент "(i, j)" з'яўляецца здабыткам "i"-га элемента з "t" і " j-ы элемент inv_freq
. Гэтая матрыца (freqs
) прадстаўляе частоты, якія выкарыстоўваюцца для генерацыі сінусоідных малюнкаў для паваротных убудоў.
Крок 2: Карыстальніцкі пласт Keras для паваротных убудоў
Зараз давайце створым уласны пласт Keras, які прымяняе паваротныя ўбудовы да ўваходнага тэнзара. Гэты ўзровень мяркуе, што ўваходны тэнзар мае форму "(batch_size, sequence_length, embedding_dim)".
class RotaryEmbeddingLayer(Layer):
def __init__(self, dim, max_seq_len, **kwargs):
super().__init__(**kwargs)
self.dim = dim
self.max_seq_len = max_seq_len
self.rotary_embeddings = get_rotary_embedding(dim, max_seq_len)
def call(self, inputs):
seq_len = tf.shape(inputs)[1]
embeddings = self.rotary_embeddings[:seq_len]
cos_emb = embeddings[:, None, :self.dim // 2]
sin_emb = embeddings[:, None, self.dim // 2:]
# Decompose inputs into sine and cosine components
inputs_cos = inputs[..., :self.dim // 2]
inputs_sin = inputs[..., self.dim // 2:]
# Apply rotary embeddings
rotated_cos = inputs_cos * cos_emb - inputs_sin * sin_emb
rotated_sin = inputs_sin * cos_emb + inputs_cos * sin_emb
return tf.concat([rotated_cos, rotated_sin], axis=-1)
def get_config(self):
config = super().get_config()
config.update({
"dim": self.dim,
"max_seq_len": self.max_seq_len
})
return config
Радок embeddings = self.rotary_embeddings[:seq_len]
выбірае адпаведнае падмноства папярэдне вылічаных паваротных укладанняў на аснове бягучай даўжыні ўваходнай паслядоўнасці. Паколькі даўжыня паслядоўнасцей можа вар'іравацца ад адной партыі да іншай, гэтая аперацыя нарэзкі гарантуе, што выкарыстоўваюцца толькі ўбудовы, якія адпавядаюць фактычнай даўжыні паслядоўнасці.
Пераменная embeddings
цяпер утрымлівае тэнзар формы (seq_len, embedding_dim)
, дзе seq_len
— даўжыня паслядоўнасцей у бягучым пакете, а embedding_dim
— памернасць убудоўванняў. Гэты тэнзар утрымлівае паваротныя пазіцыйныя ўбудовы для кожнай пазіцыі ў паслядоўнасці да "seq_len".
emb = tf.concat((tf.cos(freqs), tf.sin(freqs)), axis=-1)
аб'ядноўвае пераўтварэнні сінуса і косінуса пазіцыйных частот у адзін тэнзар:
-tf.cos(freqs)
і tf.sin(freqs)
прымяняюць пераўтварэнні косінуса і сінуса адпаведна да тэнзара "freqs". Тэнзар "freqs" змяшчае значэнні частот для кожнай пазіцыі ва ўваходнай паслядоўнасці і кожнага вымярэння прасторы ўбудавання, разлічаныя на аснове пазіцый паслядоўнасці і адваротных частот вымярэнняў убудавання. Функцыі сінус і косінус прымяняюцца паэлементна, што прыводзіць да двух тэнзараў такой жа формы, што і "freqs". Гэтыя пераўтварэнні дапамагаюць кадзіраваць пазіцыю такім чынам, каб адлюстраваць цыклічны характар пазіцыйных адносін, палягчаючы здольнасць мадэлі разумець адносныя пазіцыі.
-tf.concat((tf.cos(freqs), tf.sin(freqs)), axis=-1)
аб'ядноўвае трансфармаваныя тэнзары косінуса і сінуса ўздоўж апошняй восі (пазначаецца axis=-1
). Аб'яднанне гэтых тэнзараў побач эфектыўна падвойвае памернасць тэнзара "freqs", прычым першая палова ўяўляе значэнні, трансфармаваныя ў косінус, а другая палова ўяўляе значэнні, трансфармаваныя ў сінус, для кожнай пазіцыі. Канкатэнацыя гарантуе, што кожнае пазіцыйнае кадзіраванне змяшчае як сінусную, так і косінусную інфармацыю, што дазваляе захаваць інфармацыю як аб амплітудзе, так і аб фазе пазіцыйных сігналаў.
- Злучаны тэнзар
emb
цяпер змяшчае поўныя паваротныя ўбудовы для пазіцый уводу. Форма "emb" будзе такой жа, як і "freqs" у першых двух вымярэннях (адпаведных пазіцыям паслядоўнасці і ўбудаваным вымярэнням), але апошняе вымярэнне будзе ўдвая большым, улічваючы як сінус, так і косінус. Гэтыя ўбудовы выкарыстоўваюцца для мадуляцыі ўваходных убудоў шляхам дадання пазіцыйнай інфармацыі ратацыйна-эквіварыянтным спосабам.
-cos_emb = убудовы[:, Няма, :self.dim // 2]
:
-
Першае двукроп'е
:
азначае «выбраць усе элементы ў гэтым вымярэнні», што ў дадзеным выпадку адносіцца да ўсіх пазіцый у паслядоўнасці. -
"Няма" выкарыстоўваецца для дадання дадатковага вымярэння, што робіць тэнзар трохмерным. Гэта часта робіцца для забеспячэння сумяшчальнасці з пэўнымі аперацыямі, якія чакаюць уводу пэўнай колькасці вымярэнняў. Напрыклад, пры выкананні паэлементнага множання з іншым 3-мерным тэнзарам фігуры павінны выраўноўвацца ў адпаведнасці з правіламі трансляцыі.
-
:self.dim // 2
, выбірае першую палову памераў на апошняй восі. Паколькі "вымярэнне_ўбудавання" падвойваецца, каб уключыць значэнні як сінуса, так і косінуса, дзяленне на 2 эфектыўна выбірае толькі кампаненты косінуса ўкладанняў.
Крок 3: Інтэграцыя з мадэллю Keras
Пасля вызначэння RotaryEmbeddingLayer
вы можаце інтэграваць яго ў сваю мадэль Keras. Гэты пласт трэба прымяніць да вашых убудаванняў перад тым, як уключыць іх у пласты ўвагі або любыя наступныя пласты мадэлі.
Вось спрошчаны прыклад таго, як інтэграваць паваротныя ўбудовы ў мадэль:
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Embedding, Dense
max_seq_len = 512
embedding_dim = 64
inp = Input(shape=(max_seq_len,))
x = Embedding(input_dim=10000, output_dim=embedding_dim)(inp)
x = RotaryEmbeddingLayer(dim=embedding_dim, max_seq_len=max_seq_len)(x)
# Add your model's layers here, e.g., Transformer blocks
x = Dense(1, activation='sigmoid')(x)
model = Model(inputs=inp, outputs=x)
model.summary()