Sobes.tech
Назад к вопросам
Middle — Senior
11

Что такое FFN-слой в трансформере и зачем нужна нелинейность между attention-блоками?

Компании, где спрашивали
ПАО Газпром нефть

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

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

Определение:

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

Пример использования:

В блоке энкодера после self-attention выход для каждого токена подаётся в FFN. Например, если attention собрал контекст для слова "bank" из соседних слов, то FFN может преобразовать этот контекст в более полезное внутреннее представление, чтобы дальше слой нормализации и следующий блок работали с более выразительными признаками.

import torch
import torch.nn as nn

class FFN(nn.Module):
    def __init__(self, d_model, d_hidden):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(d_model, d_hidden),
            nn.ReLU(),
            nn.Linear(d_hidden, d_model)
        )

    def forward(self, x):
        # x: [batch, seq_len, d_model]
        return self.net(x)

x = torch.randn(2, 5, 512)
ffn = FFN(d_model=512, d_hidden=2048)
y = ffn(x)
print(y.shape)  # torch.Size([2, 5, 512])

Пояснение кода:

В этом примере вход x имеет форму [batch, seq_len, d_model], то есть набор последовательностей с признаками для каждого токена. Первый Linear увеличивает размерность до скрытого пространства, чтобы модель могла выделить более богатые комбинации признаков. ReLU вносит нелинейность, а второй Linear возвращает размерность обратно к d_model, чтобы результат можно было сложить с residual-подключением в блоке трансформера. Код показывает ключевую идею: FFN применяется одинаково к каждому токену, но не смешивает токены между собой — это делает attention.

Ключевые моменты:

  • FFN в трансформере — это position-wise MLP, работающий отдельно над каждым токеном.
  • Attention смешивает информацию между токенами, FFN преобразует признаки внутри токена.
  • Нелинейность нужна, чтобы модель могла аппроксимировать сложные зависимости, а не только линейные преобразования.
  • Обычно FFN состоит из двух линейных слоёв и активации между ними.
  • Часто скрытая размерность FFN больше d_model, что повышает выразительность модели.
  • Без FFN трансформер теряет значительную часть мощности и становится ближе к линейной модели поверх attention.