Назад
1731

Краткая история механизма внимания в NLP

1731

Введение

Attention ‘внимание’ — одна из ключевых концепций современного AI, которая обеспечила прорывные результаты современных нейросетей во многих отраслях: от робототехники (Decision Transformer) до генерации изображений (DALL-E).

В рамках статьи расскажем, как появились и развивались механизмы внимания, какие они бывают и как работают на практике. Также разберём ряд нюансов, которые часто встречаются в качестве вопросов на собеседованиях:

  • Что такое механизм внимания?
  • Чем self-attention отличается от cross-attention?
  • Зачем нужны головы?
  • Как работают маски и позиционное кодирование?

Итак, давайте начинать! 🙂

Как появилось современное внимание?

Биологические основы

Идея ‘внимания’ в нейронных сетях приходит из попытки описать биологические процессы, которые происходят в мозге человека при восприятии информации: текста, изображений или звуков.

Даже когда мы смотрим на какой-то объект (пример на рисунке ниже), на самом деле наши глаза и мозг фокусируются только на отдельных деталях, а остальные элементы для нас оказываются не важными и остаются не в фокусе внимания.

Рисунок 1. Пример работы выборочного внимания при анализе изображения

Проверить на себе работу человеческого мозга можно в достаточно коротком, но очень показательном тесте на внимание.

Такие процессы работают при анализе мозгом не только изображений, но и текста или музыки. Слушая песню, мы всегда можем сконцентрироваться на вокале или ударных, а остальные инструменты окажутся в такой же «слепой зоне», как и горилла на видео.

Внимание, рождённое в переводах

Задача перевода текста с одного языка на другой оказалась основным полигоном для тестирования механизмов внимания в нейронных сетях. Здесь есть изначальный текст, который необходимо привести к совершенно новому виду.

Математически входное предложение можно обозначить вектором х, а выходное — вектором y. Необходимо уточнить — данные вектора могут быть разной длины.

\(\begin{align} \mathbf{x} &= [x_1, x_2, \ldots, x_n], \nonumber \\ \mathbf{y} &= [y_1, y_2, \ldots, y_m], \\ {m}&!= {n} \nonumber \end{align}\)

Архитектура, оказавшая заметное влияние на появление трансформера, — рекуррентная энкодер-декодер архитектура (Sutskever, et al. 2014). Она состоит их двух частей:

  • энкодер — часть модели, которая принимает и кодирует информацию в скрытый вектор;
  • декодер — часть модели, принимающая скрытый вектор и декодирующая его для получения желаемого перевода.
Рисунок 2. RNN-энкодер и декодер для перевода последовательностей на другой язык. Источник

В такой архитектуре энкодер кодирует всё переводимое предложение в один скрытый вектор, из которого в дальнейшем декодер должен извлечь информацию и предоставить перевод. Специальный токен <EOS> (End of Sentence) используется, чтобы дать сигнал декодеру завершить генерацию, как только он его предсказывает.

Математически работу рекуррентной нейронной сети можно выразить через функцию кодирования:

\(\begin{align} \ h_t &= f\!\left(x_t,\, h_{t-1}\right), \qquad t=1,\ldots,n \end{align}\)

где \(t\) — шаг обработки рекуррентной сети, \(x_t\) — входящий токен, \(h_{t-1}\) — результат работы рекуррентной сети на предыдущем шаге \(t-1\), \(n\) — количество входных токенов.

В случае начала предложения \(h_{t-1}\) назначается нулевым вектором \([0,0,..0]\), либо заполняется константным выражением.

Формула получаемого вектора скрытого состояния, который отправится в декодер:

\(\begin{align} c = q\!\left(\{\,h_1,\, \cdots,\, h_{T_x}\,\}\right),\qquad T_x=1,\ldots,n \end{align}\)

где \(h_t∈{R}^{n}\) — вектора скрытых состояний отдельных токенов.

Однако в реальности оказывается невозможным точно переводить из-за ограниченной выразительности вектора скрытого состояния. Такой недостаток особенно ярко выражается в эффекте забывания при переводе достаточно длинных предложений.

Чтобы нейронная сеть сама принимала решение, какой токен надо переводить в данный момент, придумали «механизм внимания» (Bahdanau et al., 2015).

Новая архитектура представляет собой энкодер-декодер, но меняется само правило заполнения контекстного вектора, а также структура работы нейронной сети.

Рисунок 3. Архитектура двунаправленной RNN с механизмом внимания

В представленном выше рисунке 3 используются следующие обозначения:

\(x_i — i\text{-тый входной токен}, \\ h_i \text{- представление энкодера токена } x_i, \\ a_{t,i} \text{ — веса внимания для каждого входного токена от } x_i \text{ до } x_T, \\S_t, S_{t-1} \text{- скрытые состояния декодера на текущем и предыдущих шагах}, \\ Y_t, Y_{t-1} \text{- выходные токены на текущем и предыдущем шагах}\)

Энкодер с механизмом внимания

В новой схеме энкодера появляется двунаправленная рекуррентная нейронная сеть (BiRNN, Schuster and Paliwal, 1997, Dive into Deep Learning). Такая сеть позволяет обрабатывать каждый токен с учётом не только предыдущих, но и будущих токенов. Часть сети прямого прохода читает предложение, как оно и было, и формирует скрытые состояния:

\(\begin{align} \left(\overrightarrow{h}_1,\, \cdots,\, \overrightarrow{h}_{T_x}\right) \qquad T_x=1,\ldots,n \end{align}\)

Часть сети обратного прохода читает предложение наоборот и формирует вектор:

\(\begin{align}\left(\overleftarrow{h}_1,\, \cdots,\, \overleftarrow{h}_{T_x}\right)\qquad T_x=1,\ldots,n \end{align}\)

В дальнейшем эти векторы конкатенируется по каждому из обработанных токенов. С учётом свойства RNN создавать лучшее представление именно последних входов, конкатенированное представление будет сконцентрировано на суммаризации представления текущего токена, а также ближайшего окружения вокруг него.

\(\begin{align} \mathbf{h}_i = \big[\,\overrightarrow{\mathbf{h}}_i^{\top}\ ;\ \overleftarrow{\mathbf{h}}_i^{\top}\,\big]^{\top},\qquad i=1,\ldots,n \end{align}\)

Контекстный вектор

Вместо одного фиксированного вектора для каждого шага декодирования (для каждого токена на выходе) вычисляется свой контекстный вектор \(c_i\) — взвешенная сумма всех обработанных токенов:

\(\begin{align} c_i = \sum_{j=1}^{T_x} \alpha_{ij}\, h_j, \qquad T_x=1,\ldots,n \end{align}\)

где веса \(a_{ij}\) определяют, на какие токены входного предложения нужно обратить внимание при генерации \(y_i\).

Сами веса \(a_{ij}\)  вычисляются с помощью alignment-модели (механизма выравнивания), которая реализована в виде небольшой нейронной сети:

\(\begin{align} \alpha_{t,i} = \mathrm{align}(y_t, x_i)= \frac{\exp\!\big(\mathrm{score}(s_{t-1}, h_i)\big)}{\sum_{i’=1}^{n} \exp\!\big(\mathrm{score}(s_{t-1}, h_{i’})\big)} \qquad t=1,\ldots,n \end{align}\)

Здесь \(s_{t-1}\) — скрытое состояние декодера на предыдущем шаге, а \(h_i\)— представление для \(i\)-го токена входа.

\(\begin{align} \mathrm{score}(s_t, h_i) = \mathbf{v}_a^{\top}\,\tanh\!\big(\mathbf{W}_a[\,s_t\,;\,h_i\,]\big) \end{align}\)

В этом случае мы получаем мягкое внимание, где веса \(a_{ij}\) представляют важность. Она определяет, насколько важен каждый входной токен для текущего выходного слова.

Получаемая матрица \(a_{ij}\) визуализирует корреляцию между предсказываемыми и входящими словами.

Рисунок 4. Пример корреляции слов на основе получаемых \(a_{jx}\) . Bahdanau et al., 2015

Декодер

Декодер — рекуррентная нейронная сеть (RNN, чаще всего — GRU или LSTM), которая на каждом шаге обновляет своё скрытое состояние и предсказывает следующий токен в целевом языке.

На каждом шаге декодер получает:

  • скрытое состояние с предыдущего шага или специальный токен, обозначающий начало последовательности <start>;
  • предыдущий сгенерированный токен (или специальный стартовый символ на первом шаге);
  • контекстный вектор (вычисленный с помощью механизма внимания, который «смотрит» на релевантные части входного предложения).

В отличие от классических seq2seq-моделей, где энкодер выдаёт один фиксированный вектор, здесь декодер на каждом шаге получает свой «контекстный вектор». Он вычисляется как взвешенная сумма скрытых состояний энкодера. Веса определяются механизмом внимания, который позволяет декодеру «фокусироваться» на разных частях входного предложения при генерации каждого токена.

Так как контекстный вектор имеет доступ к всему входному предложению, нейросеть больше не теряет смысл изначального предложения. Здесь обученные веса механизма внимания работают на основе информации из энкодера о токенах, а также информации из декодера (на каком этапе перевода мы находимся).

Такой подход позволяет:

  • улучшить качество перевода (особенно для длинных предложений) за счёт динамического фокуса на релевантных частях входной последовательности;
  • снизить эффект забывания, характерный для классических seq2seq-моделей, где информация о начале предложения часто теряется при обработке длинных текстов;
  • обеспечить гибкость в обработке последовательностей разной длины, поскольку механизм внимания адаптируется к каждому шагу декодирования;
  • повысить интерпретируемость модели, так как матрица весов внимания визуально показывает, какие слова входного предложения наиболее важны для генерации каждого выходного слова.

В дальнейшем такой подход был взят Google для решения задач онлайн-переводчика, где архитектура с вниманием была масштабирована с использованием нескольких слоёв и параллельных вычислений. Это значительно улучшило производительность и скорость перевода.

Рисунок 5. Архитектура нейронного переводчика со внедрённым контекстным вниманием. Источник

В предложенной архитектуре вместо одного слоя двунаправленной рекуррентной сети использовали 8 слоёв, работающих параллельно на разных графических вычислителях. Но ключевой элемент в виде слоя внимания, определяющего важность того или иного токена в переводе, остался прежним.

Intra-Attention

Intra-Attention (внутреннее внимание) — механизм, который связывает различные позиции одной последовательности для создания её представления. Он доказал свою эффективность в задачах машинного чтения, абстрактного реферирования и генерации описаний изображений.

В работе Cheng et al., 2016 Intra-Attention использовалось для машинного чтения. Оно позволяло модели устанавливать аддитивные связи между текущими токенами и предыдущими частями текста и применялось в связке с RNN энкодер-декодер архитектурой.

Формально аддитивную оценку внимания можно выразить с помощью формулы ниже:

\(\begin{align} a_i^{(t)} = \mathbf{v}^{\top}\,\tanh\!\big(\mathbf{W}_h \mathbf{h}_i \;+\; \mathbf{W}_x \mathbf{x}_t \;+\; \mathbf{W}_{\tilde h}\,\tilde{\mathbf{h}}_{t-1}\big) \qquad t=1,\ldots,n \end{align}\)

\(\begin{align} s_i^{(t)} = \mathrm{softmax}\!\big(a_i^{(t)}\big) \end{align}\)

\(\begin{aligned} &\textbf{Где:}\\ &\mathbf{x}_t \in \mathbb{R}^{d_x}\ \text{— входной вектор (эмбеддинг) на шаге } t;\\ &\mathbf{h}_i,\,\mathbf{c}_i \in \mathbb{R}^{d}\ \text{— скрытое состояние и память на шаге } i,\ \\ &\tilde{\mathbf{h}}_{t},\,\tilde{\mathbf{c}}_{t} \in \mathbb{R}^{d}\ \text{— взвешенные суммирования прошлых } \mathbf{h}_i,\mathbf{c}_i \text{ по весам } s_i^{(t)};\\ &s_i^{(t)} \in [0,1],\ \sum_{i=1}^{t-1}s_i^{(t)}=1\ \text{— веса интра-внимания для шага } t;\\ &\mathbf{v}\in\mathbb{R}^{d_a},\ \mathbf{W}_h\in\mathbb{R}^{d_a\times d},\ \mathbf{W}_x\in\mathbb{R}^{d_a\times d_x},\ \mathbf{W}_{\tilde h}\in\mathbb{R}^{d_a\times d}\ \text{— параметры скоринга }a_i^{(t)}. \end{aligned}\)

Например, визуализация этого механизма показывает, как модель фокусируется на ключевых словах: более жирные линии соответствуют более сильным связям.

Рисунок 6. Пример визуализации интра-внимания в задачах перевода. Чем толще линия, тем более высокое внимание

Intra-Attention в RNN-моделях показало, что представлению токена полезно смотреть на другие позиции внутри той же последовательности. Эта идея подготовила почву для Self-Attention в Transformer. Внутреннее внимание можно считать ранней разновидностью Self-attention, представленной в статье ““Attention is all you need” (Vaswani et al., 2017).

Появление трансформера

Работа «Attention Is All You Need» представила архитектуру Transformer, которая полностью отказалась от рекуррентных связей в пользу увеличения количества механизмов внимания. Эти новшества привели к революционным изменениям в области обработки естественного языка и других сферах машинного обучения.

Вместо последовательного чтения текста (токен за токеном), как делают RNN, трансформер может одновременно обрабатывать все токены в предложении, устанавливая связи между любыми позициями.

Давайте далее рассмотрим разные варианты механизма внимания, а детали работы трансформера пока оставим за рамками текущей статьи 🙂

Self-Attention (Single-Head Self-Attention)

Это базовый механизм внимания, предложенный в статье “Attention Is All You Need”. Для понимания его работы можно использовать аналогию — систему информационного поиска.

Упрощённо система работает по следующему принципу:

  • в систему приходит внешний запрос (Query, Q);
  • в системе хранятся данные / ресурсы. Каждый доступный ресурс в системе описан своим индексом или ключом (Key, K). Ключ содержит метаинформацию о содержимом ресурса. По запросу Q выбираются соответствующие ему ключи K;
  • по полученным ключам K извлекается содержимое ресурса (Value, V).

Задача self-attention — определить наилучшее соответствие запроса Q ключам K, чтобы выбрать наиболее подходящие значения V. В контексте self-attention Q, K, V — матрицы, которые являются линейными проекциями входящей последовательности.

Формально механизм self-attention можно описать формулой:

\(\begin{align} {Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V\\ Q∈{R}^{n \times d_k} — матрица\ запросов,\nonumber \\ K∈{R}^{n \times d_k} — матрица\ ключей,\nonumber \\ V∈{R}^{n \times d_v} — матрица\ значений, \nonumber \\ \sqrt{d_k} — размерность\ матрицы\ Q,K. \nonumber \end{align}\)

Рисунок 7. Схема работы self-attention. Understanding Deep Learning, Simon J.D. Prince.

Деление на \(\sqrt{d_k}\) в формуле выше удерживает масштаб произведения \(QK^T\), которое может получиться слишком большим. Такие логиты внимания перенасыщают softmax, делая его распределение непроходимым для градиентов. В этом случае обучение будет проходить нестабильно.

В Self-Attention все токены обрабатываются параллельно: для последовательности длины \(L\) сразу считаются \(Q,K,V\) и матрица внимания. Это позволяет достичь параллелизма обработки (в отличие от RNN, где обработка идёт последовательно), но делает её дороже относительно длины контекста.

Сложность работы self-attention — \(L^2\) по причине умножения матрицы запросов на матрицу ключей \(K\).

\(\begin{align} Q,K \in \mathbb{R}^{L\times d_k} \;\Rightarrow\; S=\frac{QK^\top}{\sqrt{d_k}} \in \mathbb{R}^{L\times L} \end{align}\)

В RNN обработка происходит параллельно, поэтому сложность линейна от длины L:

\(\text{time}=\mathcal{O}(L d_{\text{model}}),\qquad \text{memory}=\mathcal{O}(L).\)

Self-Attention масштабируется квадратично по длине последовательности, при этом даёт полную параллельность по токенам.

Подробнее про схему работы от входящей последовательности слов до генерируемого слова можно прочитать в рамках данной статьи.

Multi-Head Self-Attention

Single-Head Self-Attention вычисляет внимание один раз для всей входной последовательности. Такой подход имеет недостаток: он ограничен в способности параллельно учитывать различные аспекты и контексты входных данных. Для преодоления этого недостатка был разработан механизм Multi-Head Self-Attention, где используется несколько голов.

Представьте тёмную сцену, на которую направлено несколько прожекторов: один выделяет взаимодействия актёров, другой — эмоции, третий — детали реквизита. Multi-head attention делает похожее: несколько «голов» параллельно смотрят на вход, каждая — через свою проекцию, подмечая разные зависимости. Затем их результаты объединяются и смешиваются в общее представление.

Использование нескольких голов позволяет модели совместно обрабатывать информацию из различных подпространств репрезентаций и учитывать несколько аспектов одновременно. Это увеличивает способность нейронной сети анализировать входные данные.

Рисунок 8. Схема работы Multi-Head Self-Attention. Understanding Deep Learning, Simon J.D. Prince

В Multi-Head Self-Attention вычисления происходят параллельно в нескольких независимых «головах». Полный алгоритм работы выглядит следующим образом:

  • входящая последовательность токенов X линейно проецируется для создания матриц Q, K, V с помощью весов \(W^K, W^V, W^Q\);
  • каждая из матриц Q, K, V размерностью \((L, d_{model})\) делится на \(h\) частей по размерности \(d_{model}\), где \(h\) — количество голов. Например, если \(d_{model}=12\), \(h = 3\), то \(d_k = 4\). Первая голова берёт столбцы 1-4, вторая — 5-8, третья — 9-12;
  • каждая матрица получает свои \(Q_i,K_i,V_i\), где \(i\) — номер головы. Такое деление позволяет головам фокусироваться на разных подпространствах признаков;
  • далее каждая голова считает собственное self-attention независимо друг от друга:

\(\begin{align} head_i={Attention}(Q_i, K_i, V_i) \end{align} \qquad i=1,\ldots,h\)

  • результаты внимания от каждой головы конкатенируются и умножаются на матрицу весов \(W^O\) для передачи результата на следующие слои:

\(\begin{align} MultiHead(Q,K,V)=Concat(head_1,…,head_h)W^O \end{align}\)

\(W^O∈{R}^{hd_v \times d_{model}} — обучаемая\ матрица\ весов,\ объединяющая\ выходы\ всех\ голов\)

Cross-attention: соединяем разные модальности

Когда запросы Queries, (Q) формируются из одной последовательности, а ключи Keys, (K) и значения Values, (V) — из другой, возникает механизм, известный как cross-attention.

Изначально подход был предложен в архитектуре Transformer (Vaswani et al., 2017) для задачи перевода, где декодер, генерирующий выходное предложение, напрямую получает информацию из энкодера, кодирующего входное предложение.

Рисунок 9. Схема работы cross-attention слоя. Understanding Deep Learning, Simon J.D. Prince

Рассмотрим подробнее, как выглядит cross-attention.

Каждый запрос \(q_i\) из последовательности запросов Q сравнивается с ключами \(k_j\) из последовательности K. Результатом сравнения становится весовая матрица, определяющая важность каждого ключа для конкретного запроса, идентичная формуле self-attention (12), с учётом гетерогенности Q и K, V согласно рисунку 9.

Каждый элемент весовой матрицы \(A_{ij}\) вычисляется как:

\(\begin{align} A_{ij} = \text{softmax}\left(\frac{q_i \cdot k_j^{T}}{\sqrt{d_k}}\right) = \frac{\exp\left(\frac{q_i \cdot k_j^{T}}{\sqrt{d_k}}\right)}{\sum_{l=1}^{m} \exp\left(\frac{q_i \cdot k_l^{T}}{\sqrt{d_k}}\right)}, \end{align}\)

где \(q_i\) — это \(i\)-ый запрос из матрицы (Q), \(k_j\) — это \(j\)-ый ключ из матрицы (K).

Важно отметить: последовательности Q, K и V в формуле выше разной длины и модальности.

После того, как веса внимания вычисляются, формируется итоговый выходной вектор. Он представляет собой новую репрезентацию запросов с учётом релевантных значений (V):

\(\begin{align} \text{CrossAttention}(q_i, K, V) = \sum_{j=1}^{m} A_{ij} v_j, \end{align}\)

где \(v_j\) — \(j\)-ый вектор значения из матрицы (V).

Пример применения cross-attention можно найти в той же статье “Attention is all you need” (Vaswani et al., 2017).

Рисунок 10. Переход векторов ключей и значений в многоголовое внимание декодера

Именно благодаря механизму сross-attention модель получает возможность «заглядывать» в скрытое пространство другой последовательности и использовать её для формирования качественного вывода. В результате мы имеем мощный инструмент, который связывает между собой разные модальности (например, текст и изображения или текст на разных языках), эффективно извлекая из них информацию и сохраняя её смысловую структуру.

Позиционное кодирование

Self-attention по своей природе не чувствителен к порядку: если просто подать на вход набор векторов, модель не отличит «кот ест рыбу» от «рыбу ест кот». Поэтому необходимо «подсказать» сети перед слоём внимания, в каком месте стоит каждый токен и как далеко токены находятся друг от друга. Это помогает:

  • правильно интерпретировать порядок токенов;
  • улавливать зависимости «на расстоянии»;
  • стабильнее обучаться на длинных / коротких примерах.

Позиционирование для attention может быть определяемым или обучаемым. В случае обычного определения позиции идея простая: к эмбеддингу каждого токена мы прибавляем детерминированный (необучаемый) позиционный вектор.

Работает дёшево, без дополнительных параметров. К таким видам необучаемых позиционных эмбеддингов можно отнести:

Позиционные эмбеддинги смешиваются с эмбеддингами следующим образом:

\(\begin{align} H_i = X_i + \mathrm{PE}_i,\qquad H \in \mathbb{R}^{L\times d_{\text{model}}} \end{align}\)

\(\begin{aligned}\text{где }\;&X_i \in \mathbb{R}^{d_{\text{model}}}\; \text{— эмбеддинг $i$-го токена},\\&\mathrm{PE}_i \in \mathbb{R}^{d_{\text{model}}}\; \text{— позиционный вектор для позиции $i$},\\&H_i \in \mathbb{R}^{d_{\text{model}}}\; \text{— суммарный вход на слой внимания для позиции $i$}.\end{aligned}\)

Позиционирование не перезаписывает смысл токена, а только немного смещает в многомерном пространстве, поэтому смысл токенов не меняется. Сеть обучается понимать, что первая часть суммы кодирует «что», а вторая — «где».

Вместо эвристик можно завести отдельные обучаемые параметры. Такой подход даёт больше гибкости: модель сама «найдёт» удобные координаты для начала, середины, конца последовательности и далее.

Маскирование во внимании

Одним из важных элементов, позволяющих вниманию достигать высокой точности, является маскирование.

Маски решают две задачи:

  1. В реальных данных длины предложений разные, поэтому в батче появляются служебные <PAD>-токены. Padding-маска скрывает паддинги, которые появляются при выравнивании последовательностей до общей длины. Модель видит только реальные токены; пустые места не влияют ни на предсказания, ни на градиенты.
  2. При авторегрессивной генерации модель не должна смотреть в будущее. Causal (look-ahead) маска запрещает смотреть вперёд по времени. Каждый токен может опираться на себя и прошлые позиции, но не на будущие. Это сохраняет причинность при генерации текста.

Как это работает? Перед тем, как превратить логиты внимания в вероятности, недопустимым позициям добавляют большой отрицательный штраф. После нормализации их вклад становится нулевым. Разрешённые позиции остаются без штрафа, и внимание распределяется только между ними. Один и тот же механизм применяется и на обучении, и на инференсе.

Важно: не путаем с dropout. Dropout — это случайная регуляризация на обучении, стохастически во время обучения зануляет:

  • часть вероятностей внимания или активаций;
  • входящие токены.

Заключение

Современные механизмы внимания хоть и отличаются от процессов в человеческом мозге, но также решают задачу эффективной обработки длинных последовательностей данных различных модальностей.

Сегодня внимание решает проблему ограниченной выразительности фиксированных представлений. А развитие концепций (self-attention, multi-head self-attention и cross-attention) обеспечивает гибкость и масштабируемость, необходимые для обработки больших объёмов данных с высокой точностью.

Актуальными задачами остаются:

  • упрощение вычислительной сложности трансформерного внимания;
  • устойчивость к шумам и возможным атакам;
  • повышение интерпретируемости весов внимания.

Эти задачи стимулируют дальнейшие исследования, направленные на создание более эффективных и надёжных архитектур, которые продолжат развивать возможности искусственного интеллекта 🙂

Полезные ссылки

https://blog.deepschool.ru/cv/attention-in-cv-spatial-attention/

https://kevinbinz.com/2015/10/03/an-introduction-to-the-attentional-spotlight/

https://lilianweng.github.io/posts/2018-06-24-attention/

https://lena-voita.github.io/nlp_course/seq2seq_and_attention.html

https://jalammar.github.io/illustrated-transformer

https://d2l.ai/

https://www.youtube.com/watch?v=Pkslk_ohTy8&list=PLwdBkWbW0oHF0p5eYDDiQrVlUObBsTl8n&index=8

https://blog.deepschool.ru/architecture/moh-multi-head-attention-as-mixture-of-head-attention/

Старт — Октябрь 2025
Large Language Models

Научитесь использовать LLM в приложениях: обучать, деплоить, ускорять и многое другое на нашем курсе

Старт — ноябрь 2025
LLM Pro

Уже профессионально работаете с LLM? Соберите полноценные LLM-системы с учётом требований к качеству и нагрузке, разберите сложные кейсы и дизайны NLP-решений у нас на курсе

0/0

Телеграм-канал

DeepSchool

Короткие посты по теории ML/DL, полезные
библиотеки и фреймворки, вопросы с собеседований
и советы, которые помогут в работе

Открыть Телеграм

Увидели ошибку?

Напишите нам в Telegram!