Attention и transformer блокът, изведени от средно
От най-евтиното обобщение на context — средното — измерете провала му и оставете формулата за attention да излезе от поправката.
На тази страница
Пристигате тук с tokenizer от Глава 7, embedding таблица от Глава 8 и целта, която върви с тях: при дадените досегашни token-и да се зададе вероятност за следващия.
Липсва средата. За да предскаже token , моделът се нуждае от един вектор, който обобщава всичко преди него, а нищо от построеното досега не произвежда такъв. embedding-ът на token не е това — това е bigram модел и той не може да знае, че изречението е започнало с въпрос. Конкатенация на всички предишни embeddings също не е това: броят им се променя на всяка стъпка, а фиксирана матрица с тегла не може да приема вход с променлива дължина.
И така: един вектор с фиксиран размер, който обобщава променлив брой вектори. Това е целият проблем, а attention е това, което се получава, когато го решите по възможно най-мързеливия начин и после поправите двете неща, които се чупят.
Отговорът, който областта имаше, и защо не го изграждаме
Връзка към раздела: Отговорът, който областта имаше, и защо не го изграждамеОт 1997 до около 2017 обобщението беше рекурентно състояние: поддържайте вектор и го обновявайте при всеки token, . Фиксиран размер, променлив вход, точно правилната форма.
То се провали по три начина, а архитектурата в тази глава отговаря и на трите. Backpropagation през стъпки умножава Якобиани, така че gradient изчезва или експлодира — болестта, която Глава 5 измери вътре в един възел. LSTM1 беше проектиран точно срещу това и разшири използваемия диапазон от десетки стъпки до стотици, без да променя факта, че информацията от token 5 достига token 500 само ако оцелее през 495 последователни обновявания. Целият източник трябваше да се побере в един вектор: при sequence-to-sequence превод2 encoder компресира входа в крайното си състояние. Bahdanau, Cho и Bengio назоваха това тясно място и го поправиха през 2014 г., три години преди transformer, като позволиха на decoder да взема претеглена сума от всички състояния на encoder с тегла, които сам изчислява.3 Всичко по-долу е тази идея, приложена от една последователност към самата себе си, с премахната рекурентност. И обновяването е последователно по конструкция: се нуждае от , а GPU с десет хиляди ядра не може да направи нищо с това. Архитектурата, която спечели, не е очевидно по-умна; тя е тази, чиято скъпа стъпка е умножение на матрици.
Другото класическо индуктивно предположение, конволюцията — плъзнете един малък филтър по целия вход, така че feature, открита някъде, да се открива навсякъде — също не се изгражда тук; тя е почти точно правилна за изображения и е оставена на курс по компютърно зрение. Нито рекурентността, нито конволюцията се появяват отново след тази страница, затова нито една не получава глава: Глава 1 обеща пропуските да бъдат обявявани, а не премълчавани.
Най-евтиното възможно обобщение
Връзка към раздела: Най-евтиното възможно обобщениеНай-очевидната функция, която приема променлив брой вектори и връща един вектор, е средното:
Произволен брой входове, фиксиран размер на изхода, диференцируема, безплатна. embedding таблица плюс това средно плюс линеен слой към речника е пълен езиков модел в петнайсет реда. Той също е ужасен, а начинът, по който е ужасен, е цялото извеждане.
Корпусът по-долу е един мегабайт Shakespeare, 1 115 394 знака, през byte-level BPE tokenizer от вида, построен в Глава 7, с речник 1024: 459 760 token-а по 2,43 знака всеки, разделени 90/10. Всеки модел е с ширина 128, вижда 128 token-а и се обучава 3000 стъпки с AdamW при с batch 64. Perplexity е върху заделения validation split.4
| модел | параметри | validation perplexity |
|---|---|---|
| само текущият token, без никакъв context | 263 168 | 59.71 |
| плюс равномерното средно на всичко преди него | 263 168 | 248.07 |
| плюс научени position embeddings | 279 552 | 245.93 |
| равномерно средно, добавено към token-а, вместо да го заменя | 263 168 | 60.45 |
Прочетете втория ред два пъти. Осредняването на context не помага малко; то прави модела четири пъти по-лош от пълното игнориране на context. Причините са две, и двете доказуеми, а не емпирични.
Средното не може да вижда реда. Събирането е комутативно, така че разбъркването на прозореца оставя обобщението непроменено — не приблизително:
A = torch.tril(torch.ones(T, T))
A = A / A.sum(1, keepdim=True) # rows of the averaging matrix
y = x[torch.randperm(T)] # the same tokens, shuffled
print((A[-1] @ x - A[-1] @ y).abs().max().item())2.9802322387695312e-08Floating-point шум при пренаредена сума: двете обобщения са един и същ вектор. Модел, чийто единствен поглед към context е средно, не може да различи кучето ухапа човека от човекът ухапа кучето. Третият ред доказва, че това не се поправя чрез добавяне на позиции към входовете — научен position embedding върху всеки token преди осредняване донесе 2,14 пункта от 188. Позициите влизат в сумата, а сумата ги забравя.
А средното удавя настоящето. На позиция 100 текущият token е една стотна от обобщението. Това има евтина поправка, която вече притежавате: запазете token-а и добавете обобщението към него — residual connection от Глава 6, а четвъртият ред показва какво прави тя. След като разреждането е поправено, равномерното средно не допринася нищо: 60.45 срещу baseline 59.71. Всеки token е вътре, претеглен еднакво, а еднаквото претегляне е същото като никаква информация.
Проблемът не е осредняването. Проблемът са теглата.
Средното е умножение на матрици, а маската е softmax
Връзка към раздела: Средното е умножение на матрици, а маската е softmaxОсредняването върху растящ prefix изглежда като цикъл. То е едно умножение с долнотриъгълна матрица, чиито редове имат сума едно — и също така, точно, softmax:
loop = torch.stack([x[:t + 1].mean(0) for t in range(T)]) # the obvious version
A = torch.tril(torch.ones(T, T))
A = A / A.sum(1, keepdim=True)
mat = A @ x # the same thing
S = torch.zeros(T, T).masked_fill(torch.tril(torch.ones(T, T)) == 0, float("-inf"))
soft = F.softmax(S, dim=-1) @ x # and the same thing againloop vs matmul max |diff| = 5.960464477539063e-08
loop vs softmax max |diff| = 5.960464477539063e-08
the averaging matrix A (rows sum to 1, upper triangle is zero):
1.000 0.000 0.000 0.000 0.000 0.000
0.500 0.500 0.000 0.000 0.000 0.000
0.333 0.333 0.333 0.000 0.000 0.000
0.250 0.250 0.250 0.250 0.000 0.000
0.200 0.200 0.200 0.200 0.200 0.000
0.167 0.167 0.167 0.167 0.167 0.167Три именувани компонента на transformer вече са на екрана. Триъгълникът е causal mask, наложена от целта: ако позиция можеше да вижда позиция , отговорът щеше да е във входа — leakage-ът, за който Глава 6 ви каза да проверявате, само че вътре в архитектурата. softmax е начинът, по който маската се реализира: задаването на забранените елементи на ги праща точно в нула и нормализира останалото, така че маскирането и нормализирането са една операция. (Използвайте , не -1e9: това е стойността, която маскирането означава, тя оцелява при cast към float16 като и ви спестява решението дали избраната константа е достатъчно голяма за диапазона, в който случайно се намирате — което е floating-point кутията от Глава 2, задаваща въпрос, на който не е нужно да отговаряте.) А scores са свободният параметър. Равномерното средно е това, което получавате, когато всеки позволен score е едно и също число; сложете там каквито и да е числа и softmax ги превръща във валидни тегла.
Останалата част от тази глава е един въпрос: откъде идват тези числа?
Query, key, value
Връзка към раздела: Query, key, valueТе не могат да бъдат обикновени параметри. Научена матрица би била идентична за всяко изречение — може да кодира „погледни четири token-а назад“, но никога „погледни съществителното, към което това местоимение се отнася“. Теглото, което свързва позиция с позиция , трябва да зависи от това, което е и на двете позиции, защото релевантността е отношение, не свойство: думата то не е вътрешно релевантна, тя е релевантна към нещо.
Най-евтината функция от два вектора, която връща число, е скаларното произведение от Глава 1. Оценете позиция за позиция като и механизмът работи — зле, по два начина, които налагат всичко останало. Скаларното произведение на вектор със самия себе си е квадратът на нормата му, така че всеки token би attend-вал най-вече към себе си. И отношението би било симетрично: ако то attend-ва силно към животно, тогава животно attend-ва силно към то, което е невярно за езика, където прилагателното се нуждае от съществителното си много повече, отколкото съществителното се нуждае от прилагателното.
Затова дайте на всеки token две роли, като две научени линейни трансформации на него: какво тази позиция търси, , query; и какво тя предлага, за да бъде намерена чрез него, , key. Оценете и симетрията изчезва, защото : token може да рекламира едно нещо и да търси друго.
Едно нещо все още е грешно. Претеглената сума беше върху самите , което принуждава нещото, което се копира, да бъде същото като нещото, което се съпоставя. Съпоставянето иска features, които идентифицират token; копирането иска features, които са полезни надолу по веригата. Затова научете трета трансформация, , value, и сумирайте тях.
Формулата вече е счетоводство:
с като causal mask, нула върху и под диагонала и над него. В код това са трийсет реда, двайсет от които са форми:
class Head(nn.Module):
"""One head of causal self-attention."""
def __init__(self, d_model, d_head, block):
super().__init__()
self.q = nn.Linear(d_model, d_head, bias=False)
self.k = nn.Linear(d_model, d_head, bias=False)
self.v = nn.Linear(d_model, d_head, bias=False)
self.d_head = d_head
self.register_buffer("mask", torch.tril(torch.ones(block, block)).bool())
def forward(self, x):
T = x.shape[1]
q, k, v = self.q(x), self.k(x), self.v(x)
s = q @ k.transpose(-2, -1) / math.sqrt(self.d_head)
s = s.masked_fill(~self.mask[:T, :T], float("-inf"))
w = F.softmax(s, dim=-1)
return w @ v Оценка, маска, нормализация, смесване. Всичко останало е проекция.
Делението на квадратния корен и от какво защитава
Връзка към раздела: Делението на квадратния корен и от какво защитаваПочти всяко обяснение на казва „за да не се насити softmax“, което е вярно и не обяснява нищо. Аргументът е два реда variance от Глава 2. Ако елементите на и са независими със средна стойност нула и variance едно, всеки продукт има variance едно, а variances на независими величини се събират:
Така scores имат стандартно отклонение . Измерено върху двайсет хиляди случайни двойки:
d Var(q.k) std sqrt(d)
4 3.975 1.994 2.000
16 16.071 4.009 4.000
64 64.249 8.016 8.000
256 253.065 15.908 16.000
1024 1015.562 31.868 32.000Защо това има значение: softmax е чувствителен към мащаба по начин, по който линейният слой не е. Удвояването на входа на линеен слой удвоява изхода му; умножаването на scores по десет преди softmax превръща мека смес в твърд избор. Един ред от 64 scores, със и без делението:
| най-голямо тегло, без деление | entropy | ефективни tokens | най-голямо тегло, с деление | entropy | ефективни tokens | |
|---|---|---|---|---|---|---|
| 4 | 0.205 | 2.944 | 19.0 | 0.081 | 3.758 | 42.9 |
| 16 | 0.438 | 1.692 | 5.4 | 0.075 | 3.849 | 46.9 |
| 64 | 0.489 | 0.874 | 2.4 | 0.085 | 3.673 | 39.4 |
| 256 | 0.9999 | 0.0007 | 1.0 | 0.143 | 3.547 | 34.7 |
| 1024 | 1.0000 | 0.0000 | 1.0 | 0.132 | 3.644 | 38.3 |
„Ефективни tokens“ е експонентата на entropy: върху колко позиции редът реално осреднява. Без деление, при , току-що инициализирана head attend-ва към точно един token от 64, избран единствено от случайното теглене.
Това е лошо напред и още по-лошо назад, във форма, която Глава 5 вече измери върху . softmax, отдаден на един елемент, има почти нулева производна: диагоналът на неговия Якобиан е , нула и в двата края. Върху две хиляди случайни реда:
| без деление | с деление | наситени редове (най-голямо тегло над 0.99) | |
|---|---|---|---|
| 4 | 0.8427 | 0.9568 | 0.2 % → 0.0 % |
| 64 | 0.2940 | 0.9609 | 17.9 % → 0.0 % |
| 256 | 0.1406 | 0.9609 | 49.1 % → 0.0 % |
| 1024 | 0.0681 | 0.9611 | 70.4 % → 0.0 % |
При седем реда от десет са замръзнали още преди обучението да започне, а head, която започва замръзнала, не може да научи къде да гледа. С деление величината е равна на 0,96 при всяка ширина и нищо не се насища.
Сега частта, която никой не публикува: променя ли това крайния perplexity? Изтрийте делението и обучете, при четири ширини на head:
| ширина на head | без деление | делено на | делено на |
|---|---|---|---|
| четири heads, | 37.29 | 38.07 | 37.89 |
| една head, | 48.51 | 46.10 | 45.99 |
| една head, | 65.37 | 47.53 | — |
| една head, | 67.06 | 49.15 | — |
| една head, | 76.69 | 59.17 | — |
Първите два реда идват от бюджета 3000 стъпки по-горе; последните три са по-кратък run — 1500 стъпки, batch 32, една head, без нормализация преди проекциите — с двата варианта при идентични настройки.
При делението не струва нищо и run-ът без него е съвсем леко напред. Това не е лиценз да го махнете, защото при 256 то струва 18 пункта perplexity, а при 1024 — 17. Механизмът се вижда в самите scores:
| std на score при init | след 1500 стъпки, без деление | след 1500 стъпки, с деление | наситени редове, без деление | с деление | |
|---|---|---|---|---|---|
| 256 | 10.49 | 121.67 | 2.13 | 91.9 % | 0.8 % |
| 512 | 15.13 | 836.85 | 2.66 | 98.7 % | 1.3 % |
| 1024 | 21.15 | 5147.46 | 3.44 | 99.9 % | 16.5 % |
Head без деление не се възстановява. Тя избягва: стандартното отклонение на scores ѝ отива от 21 при инициализация до 5147, attention entropy пада до нула и 99,9 % от редовете поставят повече от 0,99 от теглото си върху един token. Щом една head стане твърд селектор, нейният gradient е почти нулев и нищо не я дърпа обратно, така че колапсът е стабилен. Head с деление стои при стандартно отклонение на score 3,44 след същото обучение, което е мека смес, която все още може да бъде променяна.
Vaswani et al. казват точно това и нищо повече — подозират, че произведенията „стават големи по величина при големи стойности на “ и делят.5 Думата големи носи тежест, а таблиците показват къде започва голямото: нищо при 32, всичко при 256.
Повече от едно мнение и двете трети, за които никой не говори
Връзка към раздела: Повече от едно мнение и двете трети, за които никой не говориЕдна head е един softmax ред за позиция, така че държи един отговор на „кое е релевантно тук“. Предсказването на думата след the в the animal that crossed the wet street се нуждае едновременно от синтактичния слот, подлога и предишния token, а едно вероятностно разпределение не може да бъде концентрирано на три места. Затова пуснете няколко heads паралелно, всяка с ширина , конкатенирайте и смесете с още една матрица : разделили сте ширината, не сте добавили към нея.
Attention също прави точно едно нещо — мести информация между позиции. Всяка операция в кода по-горе е линейна по оста на features, а Глава 5 доказа какво е стек от линейни трансформации. Затова всеки block носи и малък MLP, приложен към всяка позиция независимо, разширяващ ширината четири пъти и връщащ се обратно, с GELU по средата. Разпределението на труда си струва да се запомни: attention смесва между позиции, feed-forward мрежата изчислява вътре в позиция.
Пълната стълба, като всеки ред добавя по един елемент към реда над него:
| модел | параметри | validation perplexity |
|---|---|---|
| равномерно средно, добавено | 279 552 | 60.45 |
| една attention head, заменяща token-а | 328 704 | 55.47 |
| една attention head, добавена | 328 704 | 46.10 |
| четири heads вместо една | 345 216 | 43.21 |
| плюс feed-forward мрежата | 476 928 | 39.87 |
| плюс LayerNorm — пълният block | 477 696 | 38.07 |
Научените тегла бият равномерните с 14 пункта perplexity, което е целият аргумент на тази глава в един ред. Четири heads купуват още 3 срещу 16 512 допълнителни параметъра. И същата head струва 9 пункта повече, когато е добавена, отколкото когато заменя: attention внася информация, то не решава какво е една позиция.
Сега къде всъщност се намират параметрите, което изненадва хора, виждали само диаграмата:
| ширина | heads | attention | feed-forward | общо на block |
|---|---|---|---|---|
| 128 | 4 | 65 664 (33.2 %) | 131 712 (66.6 %) | 197 888 |
| 768 | 12 | 2 360 064 (33.3 %) | 4 722 432 (66.6 %) | 7 085 568 |
| 4096 | 32 | 67 112 960 (33.3 %) | 134 238 208 (66.7 %) | 201 367 552 |
Две трети от всеки transformer block са feed-forward мрежата, при всеки мащаб, защото attention има четири матрици , а MLP има еквивалента на осем. Каквото и да знае един модел, повечето параметри, които го държат, са в MLP за отделна позиция.
Residuals и LayerNorm, наследени от Глава 6
Връзка към раздела: Residuals и LayerNorm, наследени от Глава 6LayerNorm беше построен и измерен в Глава 6, а тази глава го използва така, както беше оставен там; residual connections бяха назовани и ablate-нати там и тук са изградени. Редовете „добавено, не заменящо“ по-горе са residual connections, струващи 188 пункта perplexity за средното и 9 за една head. LayerNorm7 нормализира всеки пример по неговите features, а Глава 6 даде причините именно той, а не BatchNorm, да оцелее тук — няма зависимост от batch, няма running statistics, идентичен е при обучение и inference, безразличен е към дължината на последователността — всяка от които се превръща в изискване, когато генерирате по един token наведнъж за един потребител, докъдето стига Глава 13. Струва 768 параметъра и купува 1,8 пункта perplexity.
class Block(nn.Module):
def forward(self, x):
x = x + self.att(self.ln1(x))
x = x + self.ff(self.ln2(x))
return xПогледнете къде стои нормализацията: на входа на всеки sub-layer, като residual пътят от вход към изход никога не се нормализира. Това е pre-norm. Статията от 2017 прави обратното, x = LayerNorm(x + Att(x)) — post-norm, което поставя LayerNorm върху самия residual път.
Xiong et al. обясниха разликата чрез gradient при инициализация, който в post-norm мрежа е зле мащабиран с дълбочината — причината оригиналният transformer изобщо да се нуждае от learning-rate warmup, за да се обучава.8 Дванайсет blocks, 1000 стъпки, learning rate :
gradient norm per block at initialisation, before any step
pre-norm block 1 0.0498 ... block 12 0.0657 ratio last/first 1.32
post-norm block 1 0.0977 ... block 12 0.1613 ratio last/first 1.65
pre-norm, no warmup perplexity 37.82
pre-norm, 200-step warmup perplexity 37.62
post-norm, no warmup perplexity 308.05
post-norm, 200-step warmup perplexity 37.88Post-norm без warmup е осем пъти по-лош, а post-norm с warmup съвпада точно с pre-norm. Warmup не е обща добра практика тук; то е кръпка за конкретно разположение на нормализацията, а преместването на LayerNorm премахва нуждата от него. Затова практически всеки модел след 2019 е pre-norm и затова диаграмата от 2017 трябва да се чете като история, а не като спецификация.
Къде е един token?
Връзка към раздела: Къде е един token?Изтрийте position embeddings и моделът пак се обучава; той просто не може да различи къде е какво, а това е симетрия, не провал на обучението. Нищо в attention score не споменава самите или , така че пермутирането на входа пермутира изхода: self-attention е permutation-equivariant. Това е слепотата към реда на средното в по-добра маскировка — causal mask възстановява част от реда, тъй като всяка позиция вижда различен prefix, но вътре в prefix всички подредби са еднакви.
Четири начина за инжектиране на позиция, обучени върху 64-token прозорци и оценени при 64, 128 и 256 — отвъд всяка дължина, която са виждали:
| позиции | perplexity при 64 | при 128 | при 256 |
|---|---|---|---|
| никакви | 48.79 | 52.63 | 57.52 |
| научени абсолютни embeddings | 38.63 | 108.47 | 181.94 |
| фиксирани синусоиди | 42.96 | 95.26 | 152.25 |
| RoPE | 44.12 | 50.52 | 84.84 |
| ALiBi | 44.95 | 43.51 | 42.49 |
Научени абсолютни embeddings — по един вектор за позиция, добавен към token-а — печелят при обучената дължина и после падат от скала, защото позиция 100 никога не е била в batch и нейният embedding все още е случайният вектор, с който е започнала. Синусоидите, първоначалният избор, се изчисляват, вместо да се учат, от синуси и косинуси при геометрично разположени честоти; статията от 2017 се надяваше, че това ще екстраполира, а таблицата казва, че не — функцията е дефинирана при позиция 200, но моделът никога не се е научил да я чете там. RoPE9 не добавя нищо и вместо това завърта query и key с ъгъл, пропорционален на позицията, в двумерни срезове; понеже еднаквото завъртане на двете страни на скаларно произведение го оставя непроменено, score накрая зависи само от , така че позицията става относителна безплатно и няма таблица, която да се изчерпи. Влошава се, но се влошава постепенно. ALiBi10 е най-простият и най-странният резултат тук: линейно наказание върху score, пропорционално на разстоянието, с различен наклон за всяка head. Неговият perplexity се подобрява, когато прозорецът расте отвъд обучаващата дължина, от 44.95 до 42.49, защото наказанието е дефинирано при всяко разстояние и всяка head продължава да прави това, за което е обучена.
Урокът надживява таблицата: архитектура, която не може да представи нещо, е различен проблем от такава, която никога не е научила този диапазон, а вторият е този, който хапе. Това е и механизмът зад всяко съобщение „разширихме context до 128K“ — почти винаги това са пре-мащабирания на rotary encoding, и затова Глава 16 казва, че context лимитът се мести, вместо да изчезва.
Dropout се наследява по същия начин: появява се върху attention теглата след softmax, върху изхода на всеки sub-layer преди residual добавянето и върху сумата на embeddings, правейки точно това, което Глава 6 описа. В големи pretraining run-ове често е зададен на нула, защото модел, който вижда всеки token веднъж, не е в позиция да overfit-не.
Колко струва
Връзка към раздела: Колко струваДва tensors в layer имат форма , където е броят token-и: scores и теглата след softmax. Всичко останало — всяка проекция, целият MLP — е линейно в .
Един attention layer, ширина 512, 8 heads, batch от един, float32, на лаптоп GPU. Четете двете колони с милисекунди само за техните съотношения: това е wall clock на 8 GB лаптоп карта, която throttles от 1 785 MHz до под 300 MHz, когато се загрее, така че студен run на същия код се връща седем до десет пъти по-бързо, а зает — още по-бавно. Колоните с мегабайти са брой байтове на allocator и не се движат.
tokens ms total ms x4 ms projections attn matrix MB peak MB MB x4
128 2.246 - 1.324 0.5 14.6 -
256 2.855 1.27 2.113 2.0 19.2 1.31
512 5.761 2.02 3.105 8.0 34.4 1.79
1024 16.414 2.85 4.008 32.0 89.1 2.59
2048 51.573 3.14 9.989 128.0 296.1 3.32
4096 225.432 4.37 20.176 512.0 1100.1 3.72
8192 832.838 3.69 40.106 2048.0 4300.1 3.91
16384 OUT OF MEMORY 8192.0
fitted exponent (log-log slope, last four rows): time ~ n^1.91 memory ~ n^1.87Колоните x4 са съотношението към реда над тях, а удвояване на клони точно към 4 и за време, и за памет — 3,91 на последната стъпка срещу теоретични 4. Колоната с проекциите е контролата: 4,0 ms при 1024 token-а до 40,1 ms при 8192, фактор десет за фактор осем. Линейно, както беше обещано.
След това последният ред. Един attention layer, една последователност, без модел около него, изчерпва паметта на 8 GB GPU при 16 384 token-а — само матрицата със scores би била 8 GB, като 8 heads по 16 384 по 16 384 по 4 байта. Не моделът; един междинен tensor в един layer.
Това е физическият факт под три по-късни глави. Той е причината context window изобщо да има лимит, който Глава 16 превръща в цена. Той е причината FlashAttention да съществува, изчислявайки същия резултат на tiles, без някога да съхранява матрицата — memory оптимизация, преди да е speed оптимизация.11 И той е аритметиката зад цената на дълъг prompt, която Глава 24 плаща в agent loop — отделен въпрос от другото откритие на тази глава, че моделът също използва дълъг context по-зле, което тя измерва и отказва да обвинява тази формула.
Покажи подробности
Двата варианта, които свиват cache, назовани тук и платени в Глава 13.
Генерирането cache-ва keys и values на вече обработените token-и — по един key и една value за token, за head за layer. Multi-query attention12 запазва query проекции, но една key и една value проекция, споделени от всички heads, делейки този cache на . Grouped-query attention13 интерполира: heads се групират, всяка група споделя един key и една value, така че е обикновено attention, а е multi-query. Почти всеки отворен модел след 2023 го използва с 4 или 8 групи. Нито едното не съществува за качество; и двете съществуват заради размера на този cache, а Глава 13 прави аритметиката, която го превръща в „кой модел се побира във вашия GPU“.
Две форми и размерът на едната
Връзка към раздела: Две форми и размерът на еднатаСтатията от 2017 описва encoder-decoder: един stack, който чете източника с немаскирано attention, втори, който генерира целта causal, и трети вид attention по средата, където queries на decoder срещат keys на encoder. Това е правилно за превод, където входът и изходът са две последователности.
Това, което спечели, беше половината decoder-only — един stack, causal навсякъде, вход и изход в една и съща последователност — и причината не е елегантност. „Предскажи следващия token“ работи върху всякакъв текст, така че обучителният набор е интернетът, а не паралелен корпус, и всичко става тази една задача: преводът е документ, съдържащ източник и после цел, въпрос и неговият отговор са документ, разговор с tool call по средата е документ. Глава 11 е за това как се произвежда последното. Encoders не изчезнаха — един encoder вижда целия вход наведнъж, което искате, когато задачата е да представите текст, а не да го продължите, и затова retrieval embeddings в Глава 19 идват от encoders, а не от модела, който води чата.
След като block е дефиниран, размерът на модела е аритметика. За block, с ширина и четирикратно разширение: за с biases върху всичките четири, както GPT-2 ги има — таблицата по-горе оставя bias извън три от тях, следователно 2304 по-малко на block при ; за MLP; за два LayerNorm — , плюс token таблица от и, за абсолютни позиции, . За формата на GPT-2 small — , 12 blocks, речник 50 257, context 1024, изходният слой споделя теглата на embedding-а:
token embeddings 50,257 x 768 = 38,597,376
position embeddings 1,024 x 768 = 786,432
one block 7,087,872
12 blocks 85,054,464
final LayerNorm 2 x 768 = 1,536
total (weights tied) 124,439,808Което е публикуваният размер на този модел. Формулата не е приближение; тя е моделът. Забележете също, че почти една трета от малък модел е embedding таблицата, поради което размерът на речника е архитектурно решение, а не preprocessing решение — trade-off-ът, който Глава 7 постави.
Къде всъщност гледа една head
Връзка към раздела: Къде всъщност гледа една headPerplexity е число за корпус. Какво прави една head е различен въпрос, а модел, обучен върху един мегабайт Shakespeare, е грешният инструмент за него: честното нещо, което може да се каже за attention map на 500 000-параметров модел, е, че тя най-вече не е интерпретируема. Затова: език, в който въпросът има правилен отговор.
Класическата илюстрация е the animal did not cross the street because it was too tired, където it е animal, срещу …because it was too wet, където една дума премества референта към street. Това са Winograd schemas14 — двойки изречения, идентични освен една дума, при които тази дума решава към какво се отнася местоимението.
Те също са решими чрез измама, което е частта, която tutorials пропускат. Ако двамата кандидати са животно и място, tired и wet идентифицират референта по категория, и модел, който знае само кои думи присъстват, го познава правилно, без да знае нищо за реда. Измерено върху тази версия на задачата, със заделени двойки animal/place:
uniform causal average held-out referent accuracy 100.0 %
one transformer block held-out referent accuracy 91.7 %Bag of words бие transformer. Всяка демонстрация, построена върху това изречение, не доказва нищо за attention.
Затова затворете дупката: изтеглете и двамата кандидати от един pool от шестнайсет съществителни, всяко от които може да се появи във всеки от двата slot-а, и разделете прилагателните по роля, вместо по категория — четири, които правят it пресичащия (tired, scared, slow, weak), четири, които го правят пресичаното (wet, wide, busy, steep).
the {x} did not cross the {y} because it was too {adj} , so the {ref} waited .Обучете като обикновен next-token predictor, оценете една позиция — думата след so the — и построете held-out набора от двойки съществителни, чийто обърнат ред е бил в обучението, така че всичко, което знае кои две съществителни присъстват, но не и кое е било първо, трябва да отговори обратно.
| модел | параметри | held-out | назовава другото съществително |
|---|---|---|---|
| само текущият token | 5 796 | 5.2 % | 5.2 % |
| равномерно causal средно | 5 796 | 27.9 % | 50.0 % |
| една head с learned attention | 18 084 | 35.4 % | 64.6 % |
| четири heads | 22 244 | 75.0 % | 15.6 % |
| един transformer block | 55 716 | 92.7 % | 4.2 % |
| два transformer blocks | 105 508 | 100.0 % | 0.0 % |
Шансът между двете присъстващи съществителни е 50 %. Равномерното средно стига до 27,9 % и отговаря с грешното съществително от двойката точно половината пъти — подписът на нещо, което знае кои думи са там и нищо за реда им, както shuffle тестът предсказа преди три секции.
Сега картата: attention на позицията, която трябва да назове референта, осреднено върху четирите heads на всеки block, за двете изречения, които се различават с една дума. Равномерно средно би поставило 0,067 върху всеки от петнайсетте видими token-а.
the animal did not cross the street because it was too tired , so the animal waited .
blk 1 the:0.00 animal:0.70 did:0.00 not:0.00 cross:0.00 the:0.00 street:0.06
because:0.00 it:0.00 was:0.00 too:0.00 tired:0.00 ,:0.05 so:0.00 the:0.19
blk 2 the:0.00 animal:0.00 did:0.00 not:0.00 cross:0.00 the:0.00 street:0.00
because:0.00 it:0.00 was:0.00 too:0.00 tired:1.00 ,:0.00 so:0.00 the:0.00
the animal did not cross the street because it was too wet , so the street waited .
blk 1 the:0.00 animal:0.70 did:0.00 not:0.00 cross:0.00 the:0.00 street:0.06
because:0.00 it:0.00 was:0.00 too:0.00 wet:0.00 ,:0.05 so:0.00 the:0.19
blk 2 the:0.00 animal:0.00 did:0.00 not:0.00 cross:0.03 the:0.00 street:0.49
because:0.00 it:0.00 was:0.00 too:0.20 wet:0.03 ,:0.00 so:0.00 the:0.25Block 1 е идентичен и в двете изречения — 0,70 върху първото съществително, независимо какво е прилагателното. Това не е провал, а доказателство: в първия layer query на позиция е функция от собствения token и индекс на тази позиция, а the на позиция 14 е същият token и в двете изречения. Head от първия layer не може да condition-ва върху дума, която още не е fetched. Затова block 1 прави единственото полезно нещо, достъпно за него, и издърпва първото съществително напред.
Block 2 е мястото, където изреченията се разделят, а същият ред през всичките осем прилагателни показва правилото, което моделът е намерил:
| прилагателно | block 2 върху animal | върху street | върху прилагателното | отговор |
|---|---|---|---|---|
| tired, scared, slow, weak | 0.000 | 0.000 | 1.000 | animal |
| wet, wide, busy, steep | 0.000 | 0.491 | 0.00–0.03 | street |
За прилагателно на пресичащия вторият block изразходва цялото си тегло върху прилагателното, защото отговорът вече е в residual stream — block 1 го е поставил там — и всичко, от което се нуждае, е потвърждение. За прилагателно на пресичаното той отива и fetch-ва другото съществително вместо това. Това е two-hop circuit: една head премества кандидат напред, head в по-късен layer чете token, който решава дали да го запази. Композицията през layers е механизмът и затова един block достигна 92,7 %, а два достигнаха 100 %.
Това е и формата на най-добре документирания circuit в реални модели. Induction heads — previous-token head, която захранва head в следващия layer, завършваща шаблона [A][B] … [A] → [B] — са това, което работата на Anthropic по interpretability идентифицира зад голяма част от in-context learning, и те се формират в разпознаваем момент по време на pretraining. Тази глава не се опитва да прави този анализ: той е делегиран, с двете статии в източниците, защото четенето на circuits от реален модел е изследователска област, а не секция.
Накрая, имплементацията. Трийсетте реда по-горе, с техните тегла, копирани от собствените на PyTorch:
ours vs nn.MultiheadAttention max |diff| = 1.7881393432617188e-07
ours vs F.scaled_dot_product_attention max |diff| = 1.7881393432617188e-07върху изходи, чиято средна величина е 0,159: същата аритметика в различен ред, при float32 точност.
Накъде продължава това
Връзка към раздела: Накъде продължава товаВече имате архитектурата, от която е построен всеки модел в останалата част от този курс, и тя е по-малка от репутацията си: претеглено средно, чиито тегла се научават, MLP за позиция, който държи две трети от параметрите, две нормализации и две събирания, stacked.
Това, което нямате, е модел, който знае нещо, а stacking сам по себе си няма да го поправи. Два blocks върху този корпус достигат training perplexity 14,49 и validation perplexity 40,57 срещу 18,77 и 38,07 за един block — повече capacity, по-добре върху видяното, по-зле върху невидяното, което е таблицата от Глава 6 с transformer в нея. Разстоянието между този модел и онези, с които говорят Глави 14 до 30, не е архитектурно. Това е същият block, повторен повече пъти, върху несравнимо повече текст.
Което го превръща в счетоводен проблем, а счетоводството е по-странно, отколкото изглежда. Колко текст и откъде някой го взема? Колко аритметика и как се оценява тя преди парите да бъдат похарчени? При фиксиран бюджет по-добре ли е моделът да стане по-голям, или да му се покаже повече data — и има ли правилен отговор, или само мода? Глава 10 отговаря и на трите чрез измерване и поставя цена на най-евтината полезна форма на въпроса: колко струва днес да обучите модел като GPT-2 от нулата?
Източници и метод
Връзка към раздела: Източници и методТри обяснения на този материал са по-добри от това за своите цели и тази глава е написана така, че да се чете заедно с тях. The Illustrated Transformer на Jay Alammar е най-добрата картина на потока от data, рисувана някога. The Annotated Transformer на Harvard NLP е статията от 2017 с работещ код, вплетен ред по ред. Let's build GPT: from scratch, in code, spelled out на Andrej Karpathy изгражда същия модел на живо за два часа, а стълбата от ablations по-горе е същият гръбнак, измерен върху различен корпус. За въпроса за interpretability, който тази глава само докосва, първичните източници са Elhage et al., A Mathematical Framework for Transformer Circuits (2021) и Olsson et al., In-context Learning and Induction Heads (2022), и двете от interpretability групата на Anthropic.
Препратки
Връзка към раздела: Препратки-
Hochreiter, S. and Schmidhuber, J. Long Short-Term Memory. Neural Computation 9(8), pp. 1735–1780 (1997). ↩
-
Sutskever, I., Vinyals, O. and Le, Q. V. Sequence to Sequence Learning with Neural Networks. arXiv:1409.3215 (2014). Encoder-decoder, чийто единствен context вектор е тясното място. ↩
-
Bahdanau, D., Cho, K. and Bengio, Y. Neural Machine Translation by Jointly Learning to Align and Translate. arXiv:1409.0473 (2014). Attention, три години преди transformer. ↩
-
Perplexity е експонентата на средната cross-entropy за token от Глава 8. Всяко число тук използва същия tokenizer и същия validation split, което е единственото условие, при което два perplexity резултата изобщо могат да бъдат сравнявани. ↩
-
Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł. and Polosukhin, I. Attention Is All You Need. arXiv:1706.03762 (2017). Секция 3.2.1 е едното изречение за , което тази глава прекарва цяла секция в измерване. ↩
-
Shazeer, N., Mirhoseini, A., Maziarz, K., Davis, A., Le, Q., Hinton, G. and Dean, J. Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer. arXiv:1701.06538 (2017). ↩
-
Ba, J. L., Kiros, J. R. and Hinton, G. E. Layer Normalization. arXiv:1607.06450 (2016). Въведен и измерен в Глава 6; използван тук без промяна. ↩
-
Xiong, R., Yang, Y., He, D., Zheng, K., Zheng, S., Xing, C., Zhang, H., Lan, Y., Wang, L. and Liu, T.-Y. On Layer Normalization in the Transformer Architecture. arXiv:2002.04745 (2020). Gradient анализът зад pre-norm и аргументът, че warmup е симптом. ↩
-
Su, J., Lu, Y., Pan, S., Murtadha, A., Wen, B. and Liu, Y. RoFormer: Enhanced Transformer with Rotary Position Embedding. arXiv:2104.09864 (2021). ↩
-
Press, O., Smith, N. A. and Lewis, M. Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation. arXiv:2108.12409 (2021). Резултатът за екстраполация, възпроизведен по-горе. ↩
-
Dao, T., Fu, D. Y., Ermon, S., Rudra, A. and Ré, C. FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness. arXiv:2205.14135 (2022). ↩
-
Shazeer, N. Fast Transformer Decoding: One Write-Head is All You Need. arXiv:1911.02150 (2019). ↩
-
Ainslie, J., Lee-Thorp, J., de Jong, M., Zemlyanskiy, Y., Lebrón, F. and Sanghai, S. GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints. arXiv:2305.13245 (2023). ↩
-
Levesque, H. J., Davis, E. and Morgenstern, L. The Winograd Schema Challenge. KR (2012). Конструкцията зад изречението animal / street, което всеки attention tutorial използва. ↩