От классического ML к Трансформерам: архитектура, механизмы внимания и математическое обоснование
От классического ML к Трансформерам: архитектура, механизмы внимания и математическое обоснование
До 2017 года обработка естественного языка (NLP) упиралась в фундаментальный физический предел: время. Чтобы нейросеть (RNN или LSTM) поняла длинный медицинский эпикриз, она должна была «прочитать» его строго последовательно, слово за словом. Обучение таких моделей занимало последовательных шагов, где — длина текста. Распараллелить этот процесс по видеокартам (GPU) было математически невозможно, так как состояние сети на шаге зависело от шага . В 2017 году исследователи из Google предложили архитектуру Transformer, которая совершила революцию, заменив рекуррентность на механизм внимания. Они свели количество последовательных операций к , открыв дорогу к созданию современных LLM.
Для инженера, пришедшего из классического ML, понимание Трансформеров требует сдвига парадигмы: мы отказываемся от статических признаков в пользу динамических контекстных представлений, вычисляемых на лету.
Проблема статических признаков
В классическом машинном обучении (например, при обучении Random Forest на табличных данных) признак всегда имеет фиксированное значение. В раннем NLP этот подход отразился в алгоритмах вроде TF-IDF или Word2Vec. Каждому слову сопоставлялся один статический вектор (embedding).
В медицинском домене это приводит к катастрофическим ошибкам. Возьмем слово «выписка». Вектор Word2Vec для этого слова всегда будет одинаковым, независимо от того, идет ли речь о «выписке из стационара» (административное действие) или о «гнойной выписке» (клинический симптом).
Трансформер решает эту проблему элегантно: он не хранит готовые векторы слов. Вместо этого он хранит базовые представления токенов и правила их смешивания. Вектор слова «выписка» в Трансформере формируется динамически, вбирая в себя математические признаки окружающих слов. Этот процесс смешивания и есть механизм Self-Attention (самовнимание).
Self-Attention: База данных внутри нейросети
Чтобы понять, как слова обмениваются контекстом, полезно использовать аналогию из бэкенд-разработки — поиск по реляционной базе данных или key-value хранилищу.
Когда вы пишете SQL-запрос, у вас есть:
- Query (Запрос) — то, что вы ищете.
- Key (Ключ) — индексы или метаданные строк в базе, с которыми сравнивается запрос.
- Value (Значение) — фактическое содержимое строк, которые возвращаются при совпадении.
В механизме Self-Attention каждое слово в предложении одновременно выступает во всех трех ролях. Нейросеть умножает исходный вектор каждого токена на три разные обучаемые матрицы весов (, , ), получая для каждого токена три новых вектора: (Query), (Key) и (Value).
Self-Attention — это процесс, при котором каждый токен формирует «поисковый запрос» (Q), чтобы найти релевантный контекст среди «ключей» (K) других токенов, и забирает их «значения» (V) пропорционально степени совпадения.
Математически это выражается формулой Scaled Dot-Product Attention:
Разберем каждый элемент этой формулы, так как это излюбленная тема на System Design интервью:
- — матричное умножение запросов на ключи. По сути, это вычисление скалярного произведения (dot product) между вектором-запросом одного слова и векторами-ключами всех остальных слов. Чем больше векторы сонаправлены, тем выше скалярное произведение, а значит, сильнее смысловая связь.
- — масштабирующий фактор, где — размерность вектора ключа. Почему мы делим на корень из размерности? Без этого деления, при больших размерностях векторов (например, 512 или 4096 в современных LLM), значения скалярного произведения становятся огромными. Функция softmax при больших входных значениях выдает распределение, где одно значение близко к 1, а остальные к 0. В этих областях градиент softmax стремится к нулю (vanishing gradient), и модель перестает обучаться. Деление на стабилизирует дисперсию до 1.
- — нормализует результаты в вероятностное распределение от 0 до 1. Сумма весов внимания для каждого слова становится равна единице.
- Умножение на — итоговое взвешивание. Мы берем векторы значений всех слов и умножаем их на полученные вероятности. Слово забирает максимум смысла из тех токенов, на которые обратило наибольшее внимание.
Multi-Head Attention: Ансамблирование признаков
В классическом ML одно дерево решений (Decision Tree) часто переобучается или улавливает только одну закономерность. Поэтому мы используем Random Forest — ансамбль деревьев.
Тот же принцип работает в Трансформерах. Если использовать только один набор матриц , токен сможет сфокусироваться только на одном аспекте контекста. В реальности связи слов многомерны: одно слово связано с другим грамматически (подлежащее и сказуемое), семантически (синонимы) или логически (причина и следствие).
Поэтому архитектура использует Multi-Head Attention (многоголовое внимание). Исходные векторы проецируются в различных подпространств (голов). Каждая голова имеет свои собственные матрицы весов и вычисляет внимание независимо. Затем результаты работы всех голов конкатенируются (склеиваются) и умножаются на финальную матрицу , возвращая вектор к исходной размерности. Это позволяет модели одновременно анализировать текст с разных «точек зрения».
Инъекция порядка: Positional Encoding
Если вы посмотрите на формулу внимания, вы заметите одну критическую деталь: в ней нет понятия последовательности. Операция матричного умножения коммутативна по отношению к строкам. Для механизма Self-Attention фразы «врач вылечил пациента» и «пациент вылечил врача» абсолютно идентичны — это просто мешок слов (bag-of-words).
Чтобы модель понимала порядок, перед подачей токенов в первый слой внимания к их векторам (embeddings) прибавляются векторы позиционного кодирования (Positional Encoding). В оригинальной статье использовались комбинации синусов и косинусов разных частот. Современные модели часто используют обучаемые позиционные эмбеддинги или относительное кодирование (RoPE — Rotary Position Embedding), о котором мы подробно поговорим в главе про оптимизацию LLM. Главное правило: Трансформер не читает текст слева направо, он видит все токены сразу, а порядок понимает только благодаря искусственно добавленным пространственным координатам.
Анатомия Transformer Block
Механизм внимания — это сердце модели, но чтобы оно работало стабильно и могло наслаиваться в глубокие архитектуры (сотни слоев), его оборачивают во вспомогательные компоненты, образуя Transformer Block.
Каждый блок состоит из нескольких обязательных этапов:
- Layer Normalization (LayerNorm). В отличие от классического Computer Vision, где популярен Batch Normalization (нормализация по батчу), в NLP длина последовательностей в одном батче сильно варьируется, а статистика батча нестабильна. LayerNorm нормализует активации внутри одного вектора токена, делая среднее значение равным 0, а дисперсию 1. Это стабилизирует градиенты при обучении глубоких сетей.
- Residual Connections (Остаточные связи). Вокруг каждого подслоя (внимания и полносвязной сети) добавляется обходной путь: . Введенные в архитектуре ResNet, эти связи позволяют градиентам беспрепятственно течь от верхних слоев к нижним во время backpropagation, решая проблему затухающего градиента.
- Feed-Forward Network (FFN). После того как токены обменялись информацией через Self-Attention, каждый токен независимо от других проходит через двухслойную полносвязную нейросеть (обычно с активацией ReLU или GELU). Если Attention отвечает за маршрутизацию и сбор контекста, то FFN выступает в роли «базы знаний» модели, где паттерны, собранные вниманием, обрабатываются и трансформируются в высокоуровневые признаки.
Практический кейс: Разрешение зависимостей в медицине
Объединим все концепции на примере сложного клинического предложения: «Пациент отрицает прием аспирина, но регулярно использует ибупрофен для купирования боли.»
Как Трансформер обрабатывает это на уровне архитектуры?
- Токены получают свои базовые векторы и векторы позиций.
- В слое Self-Attention токен «аспирина» формирует Query.
- Токен «отрицает» формирует Key.
- Скалярное произведение между «аспирина» и «отрицает» дает высокий скор (attention weight), так как эти слова часто встречаются в связке в обучающей выборке.
- Токен «ибупрофен» также формирует свой Query, но его скалярное произведение с Key слова «отрицает» будет низким (благодаря позиционному кодированию и смыслу), а с токеном «использует» — высоким.
- В результате вектор слова «аспирина» обогащается контекстом отрицания, а вектор «ибупрофен» — контекстом подтвержденного приема.
- FFN слой обрабатывает эти обновленные векторы, фиксируя факт: аспирин = False, ибупрофен = True. В классическом NLP на базе LSTM модель могла бы просто «забыть» слово «отрицает» к моменту, когда дошла бы до конца длинного предложения.
Мы увидели, как Трансформеры решили проблему последовательного узкого горлышка, заменив рекуррентность на параллельные матричные вычисления. Однако это решение породило новый вызов: размер матрицы равен , где — длина контекста. Мы обменяли времени на вычислительной сложности и потребления памяти. Именно эта квадратичная зависимость заставляет нас применять сложнейшие инженерные решения (квантование, FlashAttention, KV-кэширование) при развертывании современных LLM в продакшене.