Шпаргалка формул нейросетей · Следующий уровень

SiLU / Swish: вход, который сам себя пропускает

Активация современных языковых моделей: вход умножается на сигмоиду от самого себя. Разбираем по косточкам, почему у неё есть минимум −0,278 и производная больше единицы, как она связана с ReLU и GELU, откуда берётся семейство Swish-β и как SiLU работает внутри блока SwiGLU в LLaMA и Qwen.

Javharbek Abdulatipov · 35 мин чтения
$$\operatorname{SiLU}(x)=x\cdot\sigma(x)=\frac{x}{1+e^{-x}}$$

Зачем она нужна

У ReLU два недостатка: в нуле у неё излом, а слева она выбрасывает весь сигнал вместе с градиентом. SiLU (Sigmoid Linear Unit) устроена иначе: вход $x$ умножается на сигмоиду от самого себя. Большой положительный вход проходит почти целиком, большой отрицательный почти полностью гасится, а около нуля пропускается «частично» — плавно, без изломов.

Ту же функцию с параметром, $x\,\sigma(\beta x)$, называют Swish. При $\beta=1$ это ровно SiLU; в PyTorch и других библиотеках так и пишут: nn.SiLU.

Где она встречается:

  • большие языковые модели — LLaMA, Qwen, Mistral и PaLM используют SiLU внутри блока SwiGLU (раздел 7); в конфигурациях моделей это строка hidden_act = "silu";
  • компьютерное зрение — EfficientNet (2019) построен на Swish, детекторы YOLOv5 и YOLOv8 — на SiLU;
  • мобильные сети — MobileNetV3 использует «жёсткий» Swish, дешёвое кусочно-полиномиальное приближение $x\cdot\operatorname{ReLU6}(x+3)/6$;
  • обучение с подкреплением — Элфвинг, Утибе и Дойя (2017) применили её для аппроксимации функций ценности под именем SiLU.
Главное за минуту

$\operatorname{SiLU}(x)=x\,\sigma(x)$. Далеко справа она почти равна $x$, далеко слева — почти 0, как ReLU, но гладкая. Она немонотонна: минимум $\approx-0{,}278$ в точке $x\approx-1{,}278$. Производная $\sigma(x)\bigl(1+x(1-\sigma(x))\bigr)$ равна $0{,}5$ в нуле и превышает 1 при $x>1{,}278$ (максимум $\approx1{,}100$). В LLM SiLU работает вентилем в SwiGLU: $\operatorname{SiLU}(W_1x)\odot W_3x$.

Интуиция: вход сам решает, сколько себя пропустить

Представьте кран, ручку которого крутит сам поток. Сигмоида $\sigma(x)$ — это степень открытия крана, от 0 до 1. Если вход большой и положительный, кран открыт почти полностью ($\sigma\approx1$) и выход почти равен входу. Если вход сильно отрицательный, кран почти закрыт, и выход близок к нулю. Такой механизм называют самовентилем (self-gating): вход одновременно и сигнал, и решение о том, сколько сигнала пропустить.

Потяните синюю точку. Бирюзовая кривая — вентиль $\sigma(x)$, синяя — произведение $x\cdot\sigma(x)$. Обратите внимание на область около $x=-1$: вентиль уже прикрыт, но не до конца, а вход отрицательный — и выход проваливается ниже нуля.

Рисунок 1. SiLU как произведение сигнала и вентиля. При $x=-1$ вентиль открыт на $\sigma(-1)=0{,}2689$, и выход равен $-1\cdot0{,}2689=-0{,}2689$. Кружок отмечает минимум $(-1{,}278;\,-0{,}278)$. Серый пунктир — ReLU, точечная линия — $y=x$.
Что заметить

Справа синяя кривая прижимается к прямой $y=x$, слева — к нулю: в этих областях SiLU почти не отличается от ReLU. Вся разница сосредоточена в полосе примерно $-5<x<5$, где вентиль открыт частично. Именно там ReLU делает резкий излом, а SiLU — плавный изгиб с небольшой «ямкой» слева.

Формула по косточкам

Соберём SiLU из двух знакомых деталей и посмотрим на неё в нескольких записях.

$$\operatorname{SiLU}(x)=\underbrace{x}_{\text{сигнал}}\cdot\underbrace{\sigma(x)}_{\text{вентиль}}=\frac{x}{1+e^{-x}}$$
$x$
вход нейрона (пре-активация); он же — сигнал, который нужно пропустить;
$\sigma(x)=\frac{1}{1+e^{-x}}$
сигмоида, число из $(0;\,1)$ — доля сигнала, которая пройдёт;
$x\cdot\sigma(x)$
результат: при $\sigma\approx1$ выход $\approx x$, при $\sigma\approx0$ выход $\approx0$.

Через гиперболический тангенс ($\sigma(x)=\tfrac12(1+\tanh\tfrac x2)$) получается запись, которая многое объясняет:

$$\operatorname{SiLU}(x)=\frac{x}{2}\Bigl(1+\tanh\frac{x}{2}\Bigr)=\underbrace{\frac{x}{2}}_{\text{нечётная часть}}+\underbrace{\frac{x}{2}\tanh\frac{x}{2}}_{\text{чётная часть}}$$

Сравните с ReLU: $\operatorname{ReLU}(x)=\frac{x}{2}+\frac{|x|}{2}$. Нечётные части у них одинаковые, а чётная часть SiLU, $\frac x2\tanh\frac x2$, — это сглаженный модуль $\frac{|x|}{2}$: при больших $|x|$ тангенс равен $\pm1$, и они совпадают, а около нуля вместо угла получается парабола $\approx\frac{x^2}{4}$.

$x$$\sigma(x)$$\operatorname{SiLU}(x)$$\operatorname{SiLU}'(x)$
−50,0067−0,0335−0,0265
−30,0474−0,1423−0,0881
−1,27850,2178−0,27850,0000
−10,2689−0,26890,0723
00,50000,00000,5000
10,73110,73110,9277
20,88081,76161,0908
30,95262,85771,0881
50,99334,96651,0265

В таблице видны три особенности: отрицательные значения слева (самое глубокое — $-0{,}2785$), производная $0{,}5$ в нуле и производная больше 1 при $x=2$ и $x=3$.

Свойства

  • Гладкость: SiLU бесконечно дифференцируема — нет ни одного излома.
  • Асимптоты: $\operatorname{SiLU}(x)-x\to0$ при $x\to+\infty$ и $\operatorname{SiLU}(x)\to0$ при $x\to-\infty$, причём в обоих случаях экспоненциально быстро.
  • Немонотонность: функция убывает на $(-\infty;\,x^*)$ и возрастает на $(x^*;\,+\infty)$, где $x^*\approx-1{,}2785$.
  • Ограниченность снизу: область значений $[-0{,}2785;\,+\infty)$. Сверху не ограничена.
  • Связь с ReLU: $\operatorname{ReLU}(x)-\operatorname{SiLU}(x)=|x|\,\sigma(-|x|)$ — чётная функция от 0 до $0{,}2785$. SiLU всегда лежит ниже ReLU, но не дальше чем на $0{,}2785$.
  • Антисимметрия разности: $\operatorname{SiLU}(x)-\operatorname{SiLU}(-x)=x$, потому что $\sigma(x)+\sigma(-x)=1$.
  • Выпуклость: функция выпукла на интервале $(-2{,}3994;\,2{,}3994)$ и вогнута вне его; концы интервала $\pm2{,}3994$ — точки перегиба.

Минимум: где и почему −0,278

Минимум находится там, где производная равна нулю. Результат удобно записать через W-функцию Ламберта — решение уравнения $We^{W}=c$:

$$x^*=-1-W\!\left(e^{-1}\right)\approx-1{,}2785,\qquad \operatorname{SiLU}(x^*)=x^*+1=-W\!\left(e^{-1}\right)\approx-0{,}2785$$
Вывод через W-функцию Ламберта

Производная (раздел 5) равна $\sigma(x)\bigl(1+x(1-\sigma(x))\bigr)$. Сигмоида положительна, поэтому ноль даёт только скобка: $1+x(1-\sigma)=0$, то есть $1-\sigma(x)=-1/x$.

Сразу получаем значение минимума: $\sigma(x^*)=1+1/x^*$, и $\operatorname{SiLU}(x^*)=x^*\sigma(x^*)=x^*+1$.

Теперь найдём $x^*$. Так как $1-\sigma(x)=\sigma(-x)=\frac{1}{1+e^{x}}$, уравнение принимает вид $1+e^{x}=-x$. Положим $u=-x-1$; тогда $x=-u-1$ и

$$1+e^{-u-1}=u+1\;\Longleftrightarrow\;e^{-u}e^{-1}=u\;\Longleftrightarrow\;u\,e^{u}=e^{-1}\;\Longleftrightarrow\;u=W(e^{-1})\approx0{,}2785$$

Отсюда $x^*=-1-W(e^{-1})\approx-1{,}2785$ и $\operatorname{SiLU}(x^*)=x^*+1=-W(e^{-1})\approx-0{,}2785$. Красивое совпадение: глубина ямы и её расстояние от точки $x=-1$ — одно и то же число.

Семейство Swish-β

Если добавить в вентиль крутизну $\beta$, получится семейство Swish:

$$\operatorname{Swish}_\beta(x)=x\,\sigma(\beta x),\qquad \lim_{\beta\to\infty}\operatorname{Swish}_\beta(x)=\operatorname{ReLU}(x),\qquad \operatorname{Swish}_0(x)=\frac{x}{2}$$

При $\beta=0$ вентиль всегда открыт наполовину, и функция линейна. При $\beta\to\infty$ сигмоида превращается в ступеньку, и получается ReLU. Swish-β — это мост между линейной функцией и ReLU, а SiLU — точка $\beta=1$ на этом мосту. Замена $u=\beta x$ показывает, что все члены семейства — один и тот же график в другом масштабе: $\operatorname{Swish}_\beta(x)=\frac{1}{\beta}\operatorname{SiLU}(\beta x)$.

Рисунок 2. $x\,\sigma(\beta x)$ и её производная. При $\beta=1$ минимум $(-1{,}278;\,-0{,}278)$, наклон в нуле $0{,}5$, максимум производной $1{,}0998$. Подвигайте $\beta$: минимум перемещается в $(-1{,}278/\beta;\,-0{,}278/\beta)$, а наклон в нуле и максимум производной не меняются. При $\beta=1{,}702$ функция почти совпадает с GELU.
Одна функция — два имени

Название SiLU (Sigmoid Linear Unit) впервые появилось в статье Хендрикса и Гимпела о GELU (2016). Элфвинг, Утибе и Дойя (2017) применили $x\,\sigma(x)$ в обучении с подкреплением. Рамачандран, Зоф и Ле (2017) независимо нашли $x\,\sigma(\beta x)$ автоматическим поиском по пространству формул-кандидатов и назвали Swish; обучаемое $\beta$ мало что добавило, и на практике закрепилось $\beta=1$. Отсюда два имени одной функции: silu в PyTorch и Hugging Face, swish в Keras.

Производная: больше единицы и меньше нуля

По правилу произведения производная SiLU складывается из двух частей: вентиля и того, как быстро вентиль открывается.

$$\operatorname{SiLU}'(x)=\underbrace{\sigma(x)}_{\text{вентиль}}+\underbrace{x\,\sigma'(x)}_{\text{открытие вентиля}}=\sigma(x)\bigl(1+x\,(1-\sigma(x))\bigr)$$
Вывод по шагам

Правило произведения: $(x\cdot\sigma(x))'=1\cdot\sigma(x)+x\cdot\sigma'(x)$.

Производная сигмоиды известна: $\sigma'(x)=\sigma(x)(1-\sigma(x))$ (вывод — на странице сигмоиды). Подставляем и выносим $\sigma(x)$:

$$\operatorname{SiLU}'(x)=\sigma(x)+x\,\sigma(x)\bigl(1-\sigma(x)\bigr)=\sigma(x)\bigl(1+x(1-\sigma(x))\bigr)$$

Ещё одна полезная форма — через значение самой функции $f=\operatorname{SiLU}(x)$: раскрыв скобки, получим $\sigma+x\sigma-x\sigma^2=f+\sigma(1-f)$. Её используют реализации: на обратном проходе нужны только уже посчитанные $f$ и $\sigma$.

$$\operatorname{SiLU}'(x)=\operatorname{SiLU}(x)+\sigma(x)\bigl(1-\operatorname{SiLU}(x)\bigr)$$

Свойства производной:

  • $\operatorname{SiLU}'(0)=\sigma(0)=\tfrac12$ — в нуле наклон ровно половина;
  • $\operatorname{SiLU}'(x)+\operatorname{SiLU}'(-x)=1$ — это производная тождества $\operatorname{SiLU}(x)-\operatorname{SiLU}(-x)=x$;
  • производная отрицательна при $x<-1{,}2785$ (левее минимума) с наименьшим значением $\approx-0{,}0998$ при $x\approx-2{,}3994$;
  • производная больше 1 при $x>1{,}2785$ — по симметрии из предыдущего пункта — с максимумом $\approx1{,}0998$ при $x\approx2{,}3994$; затем она стремится к 1 сверху.

Точки $\pm2{,}3994$ — корни уравнения $x\tanh\frac{x}{2}=2$: там обращается в ноль вторая производная

$$\operatorname{SiLU}''(x)=\sigma(x)\bigl(1-\sigma(x)\bigr)\Bigl(2-x\tanh\frac{x}{2}\Bigr),\qquad \operatorname{SiLU}''(0)=\frac12$$
Рисунок 3. Производная SiLU (оранжевая) — сумма вентиля $\sigma(x)$ и слагаемого $x\sigma'(x)$. В точке $x=2{,}399$ вентиль даёт $0{,}9168$, второе слагаемое — $0{,}1831$, вместе $1{,}0998$; это максимум, и вторая производная (нижний график) здесь равна нулю. Слева производная опускается до $-0{,}0998$.
Почему производная больше 1 — это нормально

Наклон больше 1 значит, что на участке $x>1{,}28$ SiLU «догоняет» прямую $y=x$, от которой отстала около нуля. Выход SiLU никогда не превышает вход при $x>0$ ($\sigma<1$), так что взрыва нет: наклон лишь ненамного больше 1 и быстро возвращается к 1.

Гладкость и родственники: ReLU и GELU

Три функции на одном графике: ReLU, SiLU и GELU $=x\,\Phi(x)$, где $\Phi$ — функция распределения стандартного нормального закона. Посмотрите не только на сами функции, но и на первую и вторую производные: именно там видна разница в гладкости.

Рисунок 4. ReLU, SiLU и GELU: функции, первые и вторые производные. При $x=-1$: SiLU $=-0{,}269$, GELU $=-0{,}159$; первые производные $0{,}072$ и $-0{,}083$ (GELU в этой точке ещё убывает, её минимум $-0{,}170$ при $x\approx-0{,}752$); вторые производные $0{,}302$ и $0{,}242$. Вторая производная ReLU — дельта-функция в нуле: вся кривизна собрана в одной точке.
  • ReLU: первая производная — ступенька, вторая — дельта-функция. Для оптимизатора поверхность ошибки состоит из плоских кусков с резкими рёбрами.
  • SiLU и GELU: производные непрерывны, вторые производные — гладкие «горбы» с максимумом в нуле ($0{,}5$ у SiLU, $2\varphi(0)\approx0{,}798$ у GELU). Ландшафт ошибки становится гладким, и градиент меняется постепенно.
  • GELU ≈ Swish с $\beta=1{,}702$: $x\,\Phi(x)\approx x\,\sigma(1{,}702x)$ с наибольшей ошибкой около $0{,}02$. Поэтому GELU похожа на уменьшенную в $1{,}702$ раза копию SiLU: минимум мельче и ближе к нулю ($-0{,}170$ при $x\approx-0{,}752$ против $-0{,}278$ при $x\approx-1{,}278$; у самой Swish-1,702 было бы $-0{,}164$). А вот максимум производной у GELU выше ($1{,}129$ против $1{,}100$), и масштабом это не объяснить: у всех Swish-β он один и тот же, $1{,}0998$. Это уже разница между нормальным и логистическим законом (см. ниже).

Вероятностный смысл: случайный вентиль

У SiLU и GELU есть общее объяснение. Пусть нейрон пропускает вход целиком, если вход больше случайного шума $\varepsilon$, и полностью блокирует, если меньше: $y=x\cdot[\varepsilon\le x]$. Тогда среднее значение выхода

$$\mathbb E[y]=x\cdot P(\varepsilon\le x)=x\cdot F_\varepsilon(x)=\begin{cases}x\,\sigma(x)=\operatorname{SiLU}(x), & \varepsilon\sim\text{Logistic}(0,1),\\ x\,\Phi(x)=\operatorname{GELU}(x), & \varepsilon\sim N(0,1).\end{cases}$$

Сигмоида — функция распределения логистического закона, $\Phi$ — нормального. Значит, SiLU — это «усреднённый ReLU со случайным порогом»: вместо того чтобы резать ровно в нуле, нейрон режет в случайной точке около нуля, а в среднем получается гладкая кривая.

Рисунок 5. Нажмите «Пуск». Для 33 значений $x$ разыгрывается логистический шум $\varepsilon$, и выход равен либо $x$, либо 0 (серые точки на пунктирах). Оранжевые точки — средние выходы; через 2000 розыгрышей на точку они отходят от кривой SiLU не больше чем на $0{,}031$. Переключите шум на нормальный: средние соберутся на кривой GELU (отклонение $0{,}015$).

SwiGLU: SiLU в больших языковых моделях

В трансформере после блока внимания стоит полносвязный блок (feed-forward network, FFN). Классический вариант — $W_2\,\operatorname{ReLU}(W_1x)$ (или GELU вместо ReLU). Шазир (2020) предложил заменить его на вентильный блок (gated linear unit), где одна ветка решает, сколько пропустить из другой:

$$\operatorname{FFN}_{\text{SwiGLU}}(x)=W_2\bigl(\operatorname{SiLU}(W_1x)\odot W_3x\bigr)$$
$x\in\mathbb R^{d}$
вектор токена размерности $d$ (у LLaMA-7B $d=4096$);
$W_1x$
ветка вентиля: через SiLU решает, какие компоненты пропускать и насколько;
$W_3x$
ветка значения: линейная, без активации — то, что пропускается;
$\odot$
поэлементное произведение двух векторов размерности $h$ (скрытый размер);
$W_2$
проекция обратно в размерность $d$.

Для одной компоненты это функция двух чисел: $g(a,b)=\operatorname{SiLU}(a)\cdot b$, где $a$ — компонента ветки вентиля, $b$ — ветки значения. Её и стоит увидеть в 3D.

Рисунок 6. Поверхность $\operatorname{SiLU}(a)\cdot b$ (её можно вращать) и вид сверху. При $a<0$ вентиль почти закрыт ($|\operatorname{SiLU}(a)|\le0{,}278$), и поверхность почти плоская; при больших $a>0$ она приближается к седлу $a\cdot b$. В точке $(1{,}5;\,2)$: вентиль $\operatorname{SiLU}(1{,}5)=1{,}226$, выход $2{,}453$, $\partial/\partial a=\operatorname{SiLU}'(1{,}5)\cdot b=2{,}083$, $\partial/\partial b=1{,}226$. Переключите вентиль на ReLU, GELU, сигмоиду или уберите его совсем.

Градиенты здесь простые и поучительные: $\frac{\partial g}{\partial b}=\operatorname{SiLU}(a)$ — ветка значения учится пропорционально тому, насколько открыт вентиль; $\frac{\partial g}{\partial a}=\operatorname{SiLU}'(a)\cdot b$ — вентиль учится, только если через него есть что пропускать.

Почему скрытый размер 8/3·d

В SwiGLU три матрицы вместо двух. Чтобы число параметров осталось как у обычного FFN с $h=4d$ ($2\cdot d\cdot4d=8d^2$), скрытый размер уменьшают до $h=\frac{2}{3}\cdot4d=\frac83 d$: тогда $3\cdot d\cdot\frac83d=8d^2$. У LLaMA-7B $\frac83\cdot4096\approx10923$ округлено вверх до кратного 256: $h=11008$. Получается $3\cdot4096\cdot11008=135\,266\,304$ параметра на блок против $134\,217\,728$ у FFN с $h=4d$ — всего на $0{,}8\%$ больше.

Откуда это пришло

Вентильные линейные блоки (GLU, $\sigma(W_1x)\odot W_3x$) предложили Дофин и др. (2017) для свёрточных языковых моделей. Шазир (2020) сравнил варианты с разными вентилями — ReGLU, GEGLU, SwiGLU — и все они обошли обычный FFN. SwiGLU выбрали для PaLM (2022), затем для LLaMA (2023), и с тех пор он стал стандартом открытых LLM: Qwen, Mistral и многие другие.

SiLU в обучении

Чем гладкая активация помогает на практике? Сеть из нейронов ReLU собирает функцию из отрезков прямых, сеть из SiLU — из гладких «изгибов». Если целевая зависимость гладкая, SiLU-нейронам проще её повторить. Кроме того, у SiLU нет «мёртвой» зоны: производная обращается в ноль лишь в одной точке $x^*\approx-1{,}278$, а при остальных отрицательных входах она маленькая, но не нулевая, так что нейрон не «умирает», как ReLU с отрицательным входом.

Эксперимент: сеть $1\to6\to1$ приближает кривую $y=\sin1{,}5x+0{,}3x$ по 40 точкам. Две сети стартуют с одинаковых весов, отличаются только активацией; обучение — Adam с шагом $0{,}03$, 2000 шагов.

Рисунок 7. Нажмите «Пуск». Синяя кривая — сеть с SiLU, чёрный пунктир — с ReLU. При инициализации №1 через 2000 шагов ошибка SiLU $0{,}00139$, ReLU — $0{,}00406$, почти втрое больше. Включите «Показать нейроны»: у ReLU каждый нейрон — «уголок», у SiLU — гладкий изгиб. Редкие всплески на графике ошибки — обычные колебания Adam с постоянным шагом.

Чтобы не делать выводов по одному запуску, мы повторили опыт для восьми разных инициализаций. SiLU оказалась точнее во всех восьми, с выигрышем от $1{,}4$ до $5{,}2$ раза. Но это свойство гладкой цели: на кусочно-линейной зависимости ReLU может оказаться не хуже. Поэтому выбор активации — эмпирический вопрос, и в больших моделях его решают экспериментом.

Цена гладкости

SiLU дороже ReLU: нужна экспонента (или tanh), а для обратного прохода приходится хранить вход. На GPU это обычно незаметно на фоне матричных умножений, но на мобильных устройствах используют «жёсткий» Swish $x\cdot\operatorname{ReLU6}(x+3)/6$ — кусочно-полиномиальное приближение без экспонент.

В коде

Наивная запись x / (1 + np.exp(-x)) при $x=-1000$ вычисляет $e^{1000}$ и выдаёт предупреждение о переполнении (результат всё равно $-0$). Аккуратнее считать сигмоиду через $\tanh$: $\sigma(x)=\tfrac12(1+\tanh\tfrac x2)$ — тангенс никогда не переполняется.

pythonimport numpy as np

def sigmoid(x):
    # σ(x) = (1 + tanh(x/2)) / 2 — без переполнения при любом x
    return 0.5 * (1.0 + np.tanh(0.5 * x))

def silu(x):
    return x * sigmoid(x)

def silu_grad(x):
    s = sigmoid(x)
    return s * (1.0 + x * (1.0 - s))      # = SiLU(x) + σ(x)·(1 − SiLU(x))

def swish(x, beta=1.0):
    return x * sigmoid(beta * x)

np.set_printoptions(precision=4, suppress=True)
x = np.array([-1000.0, -1.0, 0.0, 1.0, 2.3994])
print(silu(x))        # [-0.     -0.2689  0.      0.7311  2.1997]
print(silu_grad(x))   # [-0.      0.0723  0.5     0.9277  1.0998]
pythonimport torch
import torch.nn as nn
import torch.nn.functional as F

z = torch.tensor([-2.0, 0.0, 2.0], requires_grad=True)
y = F.silu(z)                    # tensor([-0.2384, 0.0000, 1.7616])
y.sum().backward()
print(z.grad)                    # tensor([-0.0908, 0.5000, 1.0908])

class SwiGLU(nn.Module):
    """FFN-блок LLaMA и Qwen: W2 · (SiLU(W1 x) ⊙ W3 x)."""
    def __init__(self, d, hidden):
        super().__init__()
        self.w1 = nn.Linear(d, hidden, bias=False)   # ветка вентиля
        self.w3 = nn.Linear(d, hidden, bias=False)   # ветка значения
        self.w2 = nn.Linear(hidden, d, bias=False)   # обратно в размер d
    def forward(self, x):
        return self.w2(F.silu(self.w1(x)) * self.w3(x))

ffn = SwiGLU(4096, 11008)                          # размеры LLaMA-7B
print(sum(p.numel() for p in ffn.parameters()))   # 135266304
Имена в библиотеках

PyTorch: nn.SiLU, F.silu. TensorFlow/Keras: tf.nn.silu, activation="swish" (это та же функция с $\beta=1$). В конфигурациях Hugging Face: hidden_act="silu". Встроенная функция инициализации nn.init.calculate_gain не знает SiLU: обычно берут инициализацию по умолчанию или как для ReLU.

Частые ошибки

  1. «SiLU неотрицательна, как ReLU». Нет: при $x<0$ она отрицательна, минимум $-0{,}278$. Если дальше идёт что-то, что требует неотрицательного входа (например, логарифм или корень), это важно.
  2. «SiLU монотонна». Нет: левее $x\approx-1{,}278$ она убывает, и её производная там отрицательна. Обратной функции на всей прямой нет.
  3. Путаница SiLU и GELU. Это разные функции: $x\sigma(x)$ и $x\Phi(x)$. Подменять одну другой в предобученной модели нельзя — веса подобраны под конкретную активацию.
  4. Активация на обеих ветках SwiGLU. SiLU стоит только на ветке вентиля $W_1x$; ветка значения $W_3x$ линейна. Лишняя активация меняет модель.
  5. Скрытый размер $4d$ в SwiGLU. С тремя матрицами это даёт в $1{,}5$ раза больше параметров, чем у обычного FFN. Для честного сравнения берут $h\approx\frac83d$.
  6. Наивная формула с exp(-x) в самописных ядрах: переполнение при больших отрицательных $x$ и потеря точности в половинной точности. Пользуйтесь F.silu или формой через tanh.
  • Сигмоида: вентиль SiLU; производная $\sigma'=\sigma(1-\sigma)$ входит в $\operatorname{SiLU}'$.
  • ReLU: предел $x\sigma(\beta x)$ при $\beta\to\infty$; $\operatorname{ReLU}-\operatorname{SiLU}=|x|\sigma(-|x|)\le0{,}2785$.
  • GELU: $x\Phi(x)\approx x\sigma(1{,}702x)$ — тот же самовентиль с нормальным шумом вместо логистического.
  • Leaky ReLU: другой способ не обнулять отрицательную часть — прямая $\alpha x$ вместо гладкой «ямки».
  • tanh: $\operatorname{SiLU}(x)=\frac x2\bigl(1+\tanh\frac x2\bigr)$.
  • Softmax и Adam: соседи SwiGLU в трансформере — механизм внимания и оптимизатор, которым такие модели обучают.

Итоги

1) $\operatorname{SiLU}(x)=x\,\sigma(x)=\frac x2\bigl(1+\tanh\frac x2\bigr)$ — самовентиль: вход решает, какую долю себя пропустить. 2) Гладкая, немонотонная, минимум $-W(e^{-1})\approx-0{,}278$ в точке $\approx-1{,}278$; всегда ниже ReLU не более чем на $0{,}278$. 3) $\operatorname{SiLU}'=\sigma(1+x(1-\sigma))$: $0{,}5$ в нуле, больше 1 при $x>1{,}278$, максимум $\approx1{,}100$. 4) Swish-β связывает линейную функцию ($\beta=0$) и ReLU ($\beta\to\infty$); GELU $\approx$ Swish-1,702. 5) Вероятностно — ReLU со случайным логистическим порогом, усреднённый. 6) В LLM — вентиль SwiGLU: $W_2(\operatorname{SiLU}(W_1x)\odot W_3x)$ со скрытым размером $\approx\frac83d$.

Проверь себя

1. Чему примерно равно $\operatorname{SiLU}(-1)$?
2. Какое наименьшее значение принимает SiLU?
3. Чему равна производная SiLU в нуле?
4. В блоке SwiGLU $W_2\bigl(\operatorname{SiLU}(W_1x)\odot W_3x\bigr)$ сколько весовых матриц и какая активация на ветке $W_3x$?
5. Во что превращается $x\,\sigma(\beta x)$ при $\beta=0$?