Как устроена архитектура Transformers и зачем ей скалярное произведение

MIT OpenCourseWare 11,8 тыс. 1 ч 16 мин 14 мин 07.01.2026
Главное

В лекции профессора Рамы Рамакришнана из Массачусетского технологического института (MIT OpenCourseWare) подробно разбирается революционная архитектура трансформеров, изменившая подход к обработке естественного языка (NLP). На примере практической задачи извлечения сущностей из авиазапросов с использованием набора данных ATIS объясняется эволюция моделей от простых векторных представлений к механизмам самовнимания и многоголового внимания. Занятие завершается пошаговым разбором реализации полноценного энкодера трансформера на базе Keras и TensorFlow в среде Google Colab.

🌍 Введение в мир трансформеров: революция в глубоком обучении 0:16

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

Эта архитектура буквально захватила все сферы ИТ. Трансформеры полностью трансформировали машинный перевод, поиск Google, извлечение информации, распознавание речи, синтез текста и даже компьютерное зрение. Появление трансформеров в компьютерном зрении стало неожиданностью для индустрии, так как изначально они вообще не проектировались для работы с изображениями.

Сегодня на трансформерах работает все передовое глубокое обучение: обучение с подкреплением, большие языковые модели (LLM), мультимодальные системы и генеративный ИИ. Более того, на базе стека трансформеров строятся сложнейшие специализированные системы, такие как AlphaFold — искусственный интеллект от DeepMind для предсказания сворачивания белков. Профессор Рамакришнан отмечает, что нам повезло жить в эпоху, когда было создано столь гибкое и удивительное технологическое решение.

✈️ Практический кейс: извлечение сущностей в авиаперелетах 1:47

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

Если пользователь запрашивает список рейсов из Бостона в ЛаГвардию на завтрашнее утро между 8 и 9 часами, система обязана выдать абсолютно корректный результат. Аналогичные бизнес-задачи высокой точности включают:

В рамках лекции подробно разбирается один конкретный туристический запрос: «Найди мне все рейсы из Бостона в ЛаГвардию завтра утром». Исторически в таких сценариях применялся подход, при котором запрос на естественном языке сначала конвертировался в структурированный вид. Текст парсился, из него извлекались ключевые сущности, после чего они пересобирались в строгий запрос — например, на языке SQL. После этого база данных возвращала результат, который красиво форматировался для пользователя. Главная сложность здесь заключается в автоматизации процесса извлечения этих сущностей (таких как коды аэропортов BOS, LGA или временные маркеры).

📊 Набор данных ATIS и задача классификации слов 3:52

Для решения этой задачи используется классический датасет Airline Travel Information Systems (ATIS). Исследователи, создавшие этот набор данных, вручную разметили несколько тысяч реальных пользовательских запросов. Они прошли по каждому слову и присвоили ему тег, определяющий тип авиационной сущности, к которой оно относится. Каждое место для переменной в строке принято называть термином «слот» (slot).

Если фраза начинается со слов «I want to fly from» («Я хочу улететь из»), то каждое из этих пяти слов разметчики отнесли к категории O (от англ. other — другой). Эти токены не несут полезной смысловой нагрузки для базы данных. Однако следующее слово «Boston» является особенным, поскольку указывает на город вылета. Ему присваивается метка B-fromloc.city_name. Процесс разметки превращает задачу в проблему многоклассовой классификации.

Для сущностей, состоящих из нескольких токенов (например, время «7:00 AM»), используется специальная BIO-схема разметки. Токен «7:00» получает тег B-depart_time (Beginning — начало сущности), а токен «AM» получает тег I-depart_time (Intermediate — продолжение сущности). Буква B сигнализирует о старте описания departure time, а I указывает, что мы находимся в середине этого описания. Слово «morning» в запросе классифицируется как период прибытия — B-arrive_time.period.

Всего исследователи предусмотрели 123 возможных класса разметки для слов, включая:

Отвечая на вопрос из аудитории, Рама Рамакришнан поясняет, что разметчики-люди легко определяли роль города (вылет или прилет) благодаря контексту всей фразы. При этом текущая модель обучается только на изолированных одиночных запросах, а сложные составные конструкции (например, одновременный поиск билетов из Бостона и Денвера) в данном случае не рассматриваются. Таким образом, задача сводится к word-to-slot многоклассовой классификации, где каждое из условных 18 слов в предложении должно быть отнесено к одному из 123 типов слотов.

🛠️ Требования к идеальной нейросети для обработки текста 9:45

Если пропустить текстовый запрос через абстрактную глубокую нейросеть, на выходе нам нужно получить слой с точно таким же количеством узлов, сколько слов было на входе (например, 18 входов и 18 выходов). К каждому из этих 18 выходных узлов необходимо прикрепить 123-канальный Softmax. Профессор иронично замечает, что сама возможность обыденно рассуждать в современной аудитории о навешивании 123-канального Softmax на каждый из 18 параллельных узлов уже вызывает у него искреннее восхищение технологическим прогрессом.

К архитектуре такой нейросети предъявляются три жестких требования. Во-первых, входящие предложения могут обладать совершенно разной длиной, но сеть должна гибко подстраиваться под этот диапазон, сохраняя на выходе то же количество элементов, что и на входе. Во-вторых, модель обязана учитывать окружающий контекст каждого слова: невозможно понять, является ли «Бостон» городом вылета или прилета, пока мы не проанализируем соседние предлоги «из» или «в». В-третьих, критически важен порядок слов, так как перелет «из Бостона в ЛаГвардию» кардинально отличается от маршрута «из ЛаГвардии в Бостон».

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

🧠 Механизм самовнимания (Self-Attention): концепция и математика 13:04

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

Внедрение этой технологии компанией Google в свой поисковый движок через модель BERT привело к драматическому росту качества поиска. Обычно улучшения алгоритмов поиска приносят лишь маргинальные доли процента, так как система уже сильно оптимизирована. Но трансформеры дали мощный скачок: например, на старый запрос «нужна ли виза бразильцу для поездки в США» поиск раньше ошибочно выдавал информацию о визах для граждан США, летящих в Бразилию, игнорируя порядок слов. После интеграции BERT первым результатом стала ссылка на посольство США в Бразилии с четкой инструкцией. Примечательно, что сами авторы оригинальной статьи 2017 года изначально фокусировались исключительно на машинном переводе и не осознавали масштаб своего открытия, пока остальное научное сообщество не начало применять его повсеместно.

Чтобы понять, как слово впитывает контекст своего окружения, Рамакришнан предлагает разобрать фразу «Поезд медленно покинул станцию». Каждому слову изначально сопоставляется автономный вектор ($w_1$–$w_6$). Если мы сфокусируемся на слове «станция» ($w_6$), нам нужно изменить его вектор так, чтобы в нем отразился тот факт, что речь идет именно о железнодорожной станции, а не о радиостанции. Для этого необходимо придать определенный вес другим словам в предложении. В литературе эти веса называют «вниманием» (attention) — они показывают, сколько внимания нужно уделить окружающим токенам. Слово «поезд» должно получить огромный вес, слова «медленно» и «покинул» — чуть меньше, а артикль «the» — практически нулевой.

Лектор приводит условный числовой пример весов, которые в сумме дают 1:

Для контекстуализации вектора $w_6$ вычисляется обычное взвешенное среднее всех векторов предложения с использованием этих коэффициентов. Результатом становится новый вектор $\hat{w}_6$, представляющий собой контекстуальное эмбеддинг-представление слова «станция». Этот процесс параллельно запускается для каждого слова в предложении, превращая исходный набор векторов в цепочку контекстуализированных векторов.

Связь между словами математически рассчитывается через скалярное произведение (dot product) их векторов. Скалярное произведение векторов $A$ и $B$ равно произведению их длин на косинус угла между ними:

$$A \cdot B = |A| |B| \cos(\theta)$$

Если условно принять длины векторов за единицу, вся динамика сосредоточится в косинусе. Если векторы близки по смыслу, угол между ними мал, а косинус близок к 1. Если они ортогональны (не связаны), косинус равен 0. Если противоположны — минус 1.

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

Описанный алгоритм называется механизмом самовнимания (self-attention). Его фундаментальное преимущество заключается в том, что по мере прохождения через стек трансформера размерность данных не теряется, сохраняя гибкость для последующей агрегации или суммаризации на самом верхнем уровне сети.

🔀 Многоголовое внимание (Multi-Head Attention) и нелинейность 36:49

Поскольку в одном предложении скрыто множество различных паттернов — от грамматических правил и временных форм до тональности и разделения на факты и мнения, — одного механизма самовнимания оказывается недостаточно. Архитектуру усложняют, создавая параллельные каналы, называемые «головами внимания» (attention heads). Это работает аналогично набору фильтров в сверточных нейросетях (CNN), где один фильтр может учиться распознавать вертикальные линии, а другой — изгибы. Сеть инициализируется случайными весами, и в процессе обратного распространения ошибки (backpropagation) алгоритм сам решает, какие паттерны будет отслеживать каждая конкретная голова.

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

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

Технически выходы всех параллельных голов внимания (например, векторы $Z_1$ и $Z_2$ для одного токена) объединяются с помощью конкатенации в один сверхдлинный вектор. Поскольку архитектура требует сохранения исходной длины и размерности векторов на всех этапах, этот длинный конкатенированный вектор пропускается через проекционный шаг — классический полносвязный (dense) слой, который сжимает его обратно до базовой размерности.

После этого на выходе из блока внимания необходимо добавить нелинейность, так как все предыдущие операции были строго линейными. Для этого данные направляются в полносвязный слой с активацией ReLU. Существует общепринятое эмпирическое правило: если входящий вектор имеет размерность 100, скрытый слой ReLU делают в 4 раза шире (400 нейронов), а затем с помощью еще одного линейного слоя проецируют обратно в размерность 100. Несмотря на то, что на этапе разработки в 2017 году многие из этих шагов казались исследователям чистой эвристикой, архитектура показала колоссальную устойчивость к изменениям и попыткам ее оптимизировать.

📍 Позиционное кодирование (Positional Encoding) 47:51

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

Этим фиксом выступает позиционное кодирование (positional encoding). Каждая позиция слова в строке (от 0 до 29 для максимальной длины в 30 слов) начинает рассматриваться как отдельная категориальная переменная. Для каждой позиции создается своя таблица векторных представлений (embeddings) такой же длины, как и у обычных слов. Значения в этой таблице изначально заполняются случайными числами и настраиваются в процессе backpropagation по ходу обучения модели. Перед подачей в блок внимания статический вектор слова и вектор его текущей позиции просто складываются.

Рамакришнан демонстрирует это на примере игрушечного словаря (cat, mat, sat, I, love...) с вектором размерности 2. Пусть слово «cat» имеет статический эмбеддинг $[0.5, 7.1]$. В предложении «Cat sat mat» слово «cat» занимает позицию 0. Из таблицы позиций извлекается вектор для нулевого индекса — $[1.3, 3.9]$. В результате сложения получается итоговый позиционно-кодированный вектор:

$$[0.5, 7.1] + [1.3, 3.9] = [1.8, 11.0]$$

Если бы фраза звучала как «Mat sat cat», то слово «cat» оказалось бы на позиции 2. Его собственный вектор остался бы прежним ($[0.5, 7.1]$), но к нему прибавился бы вектор второй позиции (например, $[0.6, 8.1]$). На выходе получились бы совершенно иные числа, что позволяет трансформеру четко улавливать пространственную структуру предложения, даже если одно и то же слово встречается в тексте трижды. Данная позиционная таблица полностью независима от словаря и завязана исключительно на зафиксированную программистом максимальную длину строки.

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

Полная схема классического энкодера трансформера выглядит следующим образом: токены текста переводятся в эмбеддинги, суммируются с позиционными эмбеддингами, проходят через многоголовое внимание, слои нормализации (Add & Norm) и полносвязную сеть с ReLU. Поскольку на входе и выходе соблюдается идеальное равенство размеров, блоки трансформеров можно собирать в глубокие стопки, как блины. Например, модель GPT-3 содержит 96 таких последовательных блоков, что позволяет ей оперировать высочайшими уровнями абстракции при наличии колоссальных объемов обучающих данных.

💻 Реализация в Google Colab на Keras 1:01:32

Практическая часть занятия посвящена применению энкодера трансформера к задаче разметки слотов в авиаперелетах. В среде Google Colab загружается тестовый набор данных, содержащий разнообразные кастомные вопросы пользователей, начиная от «Я хочу полететь из Бостона...» до комплексных вопросов о стоимости аренды лимузинов в Питтсбурге или названиях аэропортов в Орландо. Столбец с текстом запроса выступает в качестве входного параметра, а колонка со слотами (разметкой BIO) — в качестве целевой переменной.

Для написания кода под Keras используется учебная библиотека HODL, из которой импортируются готовые классы TransformerEncoder и PositionalEmbedding. Векторизация входных запросов показывает, что словарь уникальных слов в данных составляет всего 888 токенов. Пустая строка резервируется в качестве служебного токена паддинга (выравнивания длины), также выделяется тег UNK для незнакомых слов. Самым частым токеном города в датасете внезапно оказывается Бостон.

При векторизации выходных тегов-слотов необходимо соблюдать предельную осторожность. Стандартные методы векторизации текста в Keras по умолчанию приводят символы к нижнему регистру и удаляют пунктуацию. В данной задаче этого делать категорически нельзя, ведь точки и нижние подчеркивания в тегах вида B-fromloc.city_name несут строгий семантический смысл, и их удаление разрушит логику меток. Поэтому в настройках слоя Keras в явном виде отключается стандартизация: standardization=None. Общее количество выходных классов с учетом паддинга составляет 125.

Параметры создаваемой нейросети конфигурируются следующим образом:

Архитектура собирается воедино: данные проходят через слой позиционных эмбеддингов (объединяющий две таблицы: $888 \times 512$ для слов и $30 \times 512$ для позиций), затем через объект TransformerEncoder, принимающий три вышеуказанных параметра. На выходе из синих контекстуальных векторов формируется классическая глубокая сеть: полносвязный слой на 128 нейронов с активацией ReLU, слой Dropout для предотвращения переобучения и финальный полносвязный слой на 125 выходов с активацией Softmax для пословесной классификации.

Суммарно модель содержит около 5,3 миллиона обучаемых параметров. Профессор Рамакришнан предлагает студентам в качестве домашнего задания на дополнительный балл вручную рассчитать формулу количества весов внутри блоков трансформера и сверить её с системным выводом Keras. Напрямую заглянуть в веса любого слоя до начала обучения можно с помощью атрибута .weights. Лекция завершается на этапе запуска обучения модели, которое требует нескольких минут, а разбор остаточных связей и слоев нормализации откладывается до следующей встречи.

💬 Цитаты

«Трансформеры стали настолько эффективной архитектурой нейросетей, что если вы работаете над конкретной задачей, вы почти рефлекторно попробуете трансформер первым.»

Рама Рамакришнан 0:29

«Поскольку на входе и выходе соблюдается идеальное равенство размеров, blocks трансформеров можно собирать в глубокие стопки, как блины.»

Рама Рамакришнан 1:00:23
👥 Спикер
📖 Термины
Самовнимание (Self-Attention)
Механизм нейросети, позволяющий каждому слову в последовательности динамически оценивать степень своей связи с другими словами для обновления собственного вектора.
Позиционное кодирование (Positional Encoding)
Технология добавления пространственной информации о расположении слова в предложении к его исходному семантическому вектору.
Многоголовое внимание (Multi-Head Attention)
Параллельное использование нескольких независимых механизмов самовнимания для одновременного отслеживания разных типов паттернов в тексте.
Разметка слотов (Slot Filling)
Задача извлечения смысловых аргументов и сущностей из текста на естественном языке для перевода их в структурированный формат.
📊 Цифры
🗓 Хронология
  1. 2017 Публикация статьи с описанием оригинальной архитектуры Transformer для машинного перевода.
⚖️ Другая сторона
Искусственный интеллект Transformers Self-Attention Keras BERT ATIS