Ответ
До революционной работы "Attention Is All You Need" (2017) в NLP преобладали три основных класса архитектур:
-
Рекуррентные нейронные сети (RNN) и их варианты (LSTM, GRU):
- Принцип: Последовательная обработка текста, где скрытое состояние обновляется на каждом шаге.
- Недостатки:
- Плохой параллелизм из-за последовательной природы, что замедляет обучение.
- Проблемы с запоминанием долгосрочных зависимостей (частично решены LSTM).
- Пример кода LSTM для классификации на PyTorch:
import torch.nn as nn
class TextClassifierLSTM(nn.Module): def init(self, vocab_size, embedding_dim, hidden_dim, output_dim): super().init() self.embedding = nn.Embedding(vocab_size, embedding_dim) self.lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True, bidirectional=True) self.fc = nn.Linear(hidden_dim 2, output_dim) # 2 для bidirectional
def forward(self, text): embedded = self.embedding(text) # [batch_size, seq_len, emb_dim] output, (hidden, cell) = self.lstm(embedded) # Объединяем скрытые состояния для bidirectional LSTM hidden = torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim=1) return self.fc(hidden) -
Сверточные нейронные сети (CNN):
- Применяли одномерные свертки к матрице эмбеддингов слов для выделения локальных n-граммных паттернов.
- Быстрее RNN, но хуже справлялись с глобальными контекстными зависимостями в длинных текстах.
-
Модели на основе механизма внимания (Attention) в архитектурах Encoder-Decoder:
- Ключевой прорыв — работа Bahdanau (2015) по выравнивающему вниманию (alignment) для машинного перевода.
- Декодер "заглядывал" в скрытые состояния энкодера, взвешивая их важность для генерации каждого следующего слова.
- Ограничение: Attention использовался как дополнение к RNN/CNN, а не как самостоятельный механизм.
Трансформер кардинально изменил парадигму, полностью отказавшись от рекуррентности и сверток в пользу самовнимания (self-attention), что позволило беспрецедентно параллелизовать обработку последовательностей и эффективно моделировать зависимости любой длины.
Ответ 18+ 🔞
Давайте разберем эту историю, как всё было до того, как все с ума посходили по этим вашим трансформерам. Ситуация, если честно, была пиздец как запущенная.
Раньше в NLP царили, по сути, три банды, и у каждой свои косяки были овердохуища.
Первая банда — Рекуррентные сети (RNN, LSTM, GRU). Принцип у них был простой, как три копейки: жуют текст слово за словом, как корова жвачку, и пытаются что-то запомнить. LSTM, конечно, чуть поумнее были — пытались долгосрочные связи ловить. Но проблема-то в чём? Всё это дело было нихуя не параллельным. Представь: чтобы обработать предложение, надо пройти его целиком, шаг за шагом, как будто ты в очереди в совке стоишь. Обучение растягивалось на века, терпения ноль ебать. Код, конечно, писали, но каждый раз это был какой-то ритуал с бубном.
import torch.nn as nn
class TextClassifierLSTM(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True, bidirectional=True)
self.fc = nn.Linear(hidden_dim * 2, output_dim) # *2 для bidirectional
def forward(self, text):
embedded = self.embedding(text) # [batch_size, seq_len, emb_dim]
output, (hidden, cell) = self.lstm(embedded)
# Объединяем скрытые состояния для bidirectional LSTM
hidden = torch.cat((hidden[-2,:,:], hidden[-1,:,:]), dim=1)
return self.fc(hidden)
Смотришь на это и думаешь: "Ну ёпта, и кто это всё придумал?" Работало, но медленно, будь здоров.
Вторая банда — Сверточные сети (CNN). Эти подошли с другой стороны: начали по тексту скользящими окнами шастать, как менты по району, выискивая местные словесные паттерны, типа "хороший отзыв" или "полный пиздец". Быстрее, да. Но глобальный контекст они теряли на раз. Длинный отзыв прочитает — а в конце уже забыл, о чём в начале речь шла. Хитрая жопа, но не идеальная.
Третья банда — Attention в связке Encoder-Decoder. Вот тут уже запахло жареным. Где-то в 2015-м какой-то умный чувак (Bahdanau, если по-паспорту) догадался: а давайте, когда декодер слово генерит, он будет не просто в своё прошлое пялиться, а ещё и "заглядывать" на всё, что энкодер насочинял. И смотреть, на какие куски исходного текста внимание обращать. Идея — огонь! Но был нюанс, ёперный театр. Attention был как дополнительная примочка, как спойлер на жигули. Основной движок-то всё равно был RNN или CNN. То есть костыль к костылю, а воз и ныне там.
И все так жили, мучались, модели по неделе обучали, пока в 2017-м не пришли ребята и не сказали: "А давайте нахуй выбросим всю эту рекуррентную и сверточную муть. Attention — это всё, что вам нужно". И представили Трансформер. Который взял этот самый механизм внимания, да сделал его самовниманием, чтобы слова в предложении друг на друга смотрели, а не на прошлые шаги. Всё стало параллельным, быстрым, и зависимости любой длины ловились на ура. После этого все просто сам от себя охуели. Вся прежняя архитектура накрылась медным тазом. Вот так-то, малята.