SwiGLU
SwiGLU перемножает проекцию, активированную с помощью SiLU, и вторую линейную проекцию; этот слой с гейтами используется в Llama, PaLM и Qwen. Включает код.
SwiGLU (линейный блок с вентилем Swish) — вариант слоя прямого распространения с вентилем в трансформерах. Он дважды проецирует вектор каждого токена, пропускает одну проекцию через функцию активации SiLU (Swish), перемножает две проекции поэлементно и проецирует результат обратно до ширины модели: FFN(x) = (SiLU(xW) ⊙ xV)W₂. Noam Shazeer представил этот подход в статье 2020 года GLU Variants Improve Transformer; с тех пор он стал блоком прямого распространения в больших языковых моделях (LLM), таких как PaLM, Llama, Mistral и Qwen. В отличие от ReLU или GELU, которые действуют на каждое число независимо, SwiGLU содержит обучаемые веса, образующие отдельный небольшой слой.
Как работает SwiGLU#
Стандартная сеть прямого распространения трансформера (FFN) расширяет каждый вектор токена одной матрицей весов, применяет функцию активации и сжимает его обратно второй матрицей. В SwiGLU первая матрица и функция активации заменены линейным блоком с вентилем (GLU), в котором один и тот же вход проходит через две параллельные проекции:
- Проекция вентиля: xW проходит через SiLU, x · σ(x), и дает значения, близкие к нулю для сильно отрицательных входов и близкие к самому входу для положительных.
- Проекция значения: xV остается линейной и передает содержимое.
- Поэлементное произведение: Перемножение позволяет вентилю усиливать, ослаблять или почти обнулять каждый скрытый признак в зависимости от входа, а выходная проекция W₂ преобразует результат обратно до ширины модели.
Идея гейтирования восходит к GLU из работы Dauphin и коллег: в 2016 году они использовали сигмоидный вентиль в сверточных языковых моделях с вентильным механизмом. В статье Shazeer проверялась та же структура с разными функциями вентиля, а каждый вариант получил название по используемой функции активации: GLU использует сигмоиду, ReGLU — ReLU, GEGLU — GELU, SwiGLU — Swish, а в билинейном слое функция активации вообще не используется. В соответствии с кодовой базой T5 в этих слоях опущены смещения.
Почему в LLM SwiGLU заменил ReLU и GELU#
В слоях прямого распространения с вентилем три матрицы весов вместо двух, поэтому Shazeer уменьшил ширину скрытого слоя в 2/3 раза, чтобы сохранить одинаковое число параметров и объем вычислений: с 3 072 до 2 048 единиц в модели T5-base. При одинаковом размере SwiGLU достиг логарифмической перплексии 1,636 после 524 288 шагов обучения, тогда как у ReLU она составила 1,677, а у GELU — 1,679. Кроме того, он показал более высокие средние результаты на бенчмарках понимания языка GLUE и SuperGLUE. В статье не предлагается теоретическое объяснение улучшения; автор заключает, что успех этих архитектур объясняется, «как и всё остальное, божественным благоволением».
Этот результат сохранился и для больших моделей. В 2022 году Google добавила SwiGLU в PaLM, а в 2023 году Meta заменила ReLU на SwiGLU в LLaMA, задав ширину скрытого слоя 2/3 × 4d с округлением вверх до кратного 256. Для модели 7B с размерностью 4 096 это дает 11 008 скрытых единиц. В Llama 2, Llama 3, Mistral и Qwen сохранили эту конструкцию; в моделях со смесью экспертов (MoE), таких как Mixtral, каждый эксперт представляет собой блок прямого распространения SwiGLU.
Реализация SwiGLU в PyTorch#
В приведенном ниже фрагменте кода на PyTorch создаются стандартный слой прямого распространения с ReLU и слой SwiGLU для модели размерностью 512, а затем сравниваются их размеры:
import torch
import torch.nn.functional as F
from torch import nn
d_model = 512
x = torch.randn(4, d_model) # four token vectors
# Standard transformer FFN: two matrices around a 4x wider ReLU hidden layer
relu_ffn = nn.Sequential(nn.Linear(d_model, 2048, bias=False), nn.ReLU(), nn.Linear(2048, d_model, bias=False))
# SwiGLU FFN: three matrices, hidden width cut to about 2/3 of 2048
w_gate = nn.Linear(d_model, 1365, bias=False)
w_value = nn.Linear(d_model, 1365, bias=False)
w_out = nn.Linear(1365, d_model, bias=False)
y = w_out(F.silu(w_gate(x)) * w_value(x)) # (SiLU(xW) * xV) W2
relu_params = sum(p.numel() for p in relu_ffn.parameters())
swiglu_params = sum(m.weight.numel() for m in (w_gate, w_value, w_out))
print(f"ReLU FFN: output {tuple(relu_ffn(x).shape)}, {relu_params:,} parameters")
print(f"SwiGLU FFN: output {tuple(y.shape)}, {swiglu_params:,} parameters")Выводятся ReLU FFN: output (4, 512), 2,097,152 parameters и SwiGLU FFN: output (4, 512), 2,096,640 parameters. При 1 365 скрытых единицах — примерно 2/3 от 2 048 — три матрицы SwiGLU содержат почти столько же весов, сколько две матрицы ReLU, поэтому различия в качестве обусловлены вентилем. Во многих реализациях матрицы вентиля и значения объединяют в одну проекцию, а ее выход делят пополам; так вместо двух небольших умножений матриц выполняется одно более крупное.
SwiGLU и связанные термины#
- SiLU (Swish): SiLU — поэлементная функция внутри вентиля. SwiGLU — весь слой с вентилем и тремя проекциями.
- GLU и GEGLU: Родственные варианты с вентилем на основе сигмоиды или GELU. В тестах Shazeer GEGLU не уступал SwiGLU: логарифмическая перплексия составила 1,633. Эту функцию также используют модели Gemma от Google.
- Внимание: Механизм внимания тоже создает зависящие от данных веса, но смешивает информацию между токенами. SwiGLU управляет признаками независимо внутри каждого токена.
- Модели компьютерного зрения: Слои прямого распространения с вентилем используются и в моделях компьютерного зрения и мультимодальных моделях. YOLOE — детектор с открытым словарем от исследователей Университета Цинхуа, работающий в пакете Ultralytics; он уточняет векторные представления текстовых подсказок классов с помощью остаточного блока SwiGLU, который выполняется один раз за вызов
set_classes()и удаляется при экспорте, поэтому не увеличивает затраты на каждый кадр.










