SwiGLU
SwiGLU multiplica una proyección activada con SiLU por una segunda proyección lineal; forma la capa de alimentación hacia delante con compuerta de Llama, PaLM y Qwen. Incluye código.
SwiGLU (unidad lineal con compuerta Swish) es una variante con compuerta de la capa de propagación hacia delante en los transformers. Proyecta el vector de cada token dos veces, pasa una proyección por la función de activación SiLU (Swish), multiplica ambas elemento a elemento y vuelve a proyectar el producto al ancho del modelo: FFN(x) = (SiLU(xW) ⊙ xV)W₂. Noam Shazeer la presentó en el artículo de 2020 GLU Variants Improve Transformer, y desde entonces se ha convertido en el bloque de propagación hacia delante de modelos de lenguaje grandes (LLM) como PaLM, Llama, Mistral y Qwen. A diferencia de ReLU o GELU, que actúan de forma independiente sobre cada número, SwiGLU contiene pesos aprendidos, lo que la convierte en una pequeña capa propia.
Cómo funciona SwiGLU#
Una red estándar de propagación hacia delante de un transformer amplía cada vector de token con una matriz de pesos, aplica una activación y lo comprime de nuevo con una segunda matriz. SwiGLU sustituye la primera matriz y la activación por una unidad lineal con compuerta (GLU), que cuenta con dos proyecciones paralelas de la misma entrada:
- Proyección de compuerta: xW pasa por SiLU, x · σ(x), y produce valores próximos a cero para entradas muy negativas y cercanos a la entrada para las positivas.
- Proyección de valor: xV se mantiene lineal y transporta el contenido.
- Producto elemento a elemento: Al multiplicar ambas proyecciones, la compuerta puede aumentar, reducir o casi anular cada característica oculta según la entrada; la proyección de salida W₂ devuelve el resultado al ancho del modelo.
La idea de la compuerta procede de la GLU de Dauphin y sus colaboradores, que utilizaron una compuerta sigmoide en modelos de lenguaje convolucionales con compuerta en 2016. El artículo de Shazeer probó la misma estructura con distintas funciones de compuerta y dio a cada variante el nombre de su activación: GLU usa sigmoide, ReGLU usa ReLU, GEGLU usa GELU, SwiGLU usa Swish y una capa bilineal no usa activación. Siguiendo la base de código de T5, estas capas eliminan los términos de sesgo.
Por qué SwiGLU sustituyó a ReLU y GELU en los LLM#
Las capas de propagación hacia delante con compuerta tienen tres matrices de pesos en lugar de dos, así que Shazeer redujo el ancho oculto en un factor de 2/3 para mantener iguales el número de parámetros y el coste computacional: de 3072 a 2048 unidades en un modelo T5-base. Con el mismo tamaño, SwiGLU alcanzó una log-perplejidad de 1,636 en los datos reservados para evaluación tras 524 288 pasos de entrenamiento, frente a 1,677 para ReLU y 1,679 para GELU; también obtuvo puntuaciones medias más altas en los benchmarks de comprensión del lenguaje GLUE y SuperGLUE. El artículo no ofrece una teoría que explique la mejora; su conclusión atribuye el éxito de estas arquitecturas, «como todo lo demás, a la benevolencia divina».
El resultado también se mantuvo en los modelos grandes. PaLM de Google adoptó SwiGLU en 2022, y LLaMA de Meta sustituyó ReLU por SwiGLU en 2023, con un ancho oculto de 2/3 × 4d redondeado al múltiplo de 256 más próximo, lo que da 11 008 unidades ocultas para el modelo 7B de 4096 dimensiones. Llama 2, Llama 3, Mistral y Qwen mantuvieron el diseño, y en los modelos de mezcla de expertos (MoE), como Mixtral, cada experto es un bloque SwiGLU de propagación hacia delante.
Implementar SwiGLU en PyTorch#
El fragmento de PyTorch siguiente crea una capa estándar de propagación hacia delante con ReLU y una capa SwiGLU para un modelo de 512 dimensiones, y compara sus tamaños:
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")Imprime ReLU FFN: output (4, 512), 2,097,152 parameters y SwiGLU FFN: output (4, 512), 2,096,640 parameters. Con 1365 unidades ocultas, aproximadamente 2/3 de 2048, las tres matrices de SwiGLU tienen casi el mismo número de pesos que las dos matrices de ReLU, por lo que cualquier diferencia de calidad se debe a la compuerta. Muchas implementaciones fusionan las matrices de compuerta y de valor en una sola proyección y dividen su salida por la mitad, lo que permite ejecutar una multiplicación de matrices grande en lugar de dos más pequeñas.
SwiGLU frente a términos relacionados#
- SiLU (Swish): SiLU es la función elemento a elemento que forma parte de la compuerta. SwiGLU es la capa completa con compuerta y sus tres proyecciones.
- GLU y GEGLU: Variantes relacionadas que usan una compuerta sigmoide o GELU. GEGLU igualó a SwiGLU en las pruebas de Shazeer, con una log-perplejidad de 1,633, y los modelos Gemma de Google la utilizan.
- Atención: La atención también produce pesos que dependen de los datos, pero mezcla información entre tokens. SwiGLU aplica compuertas a las características de cada token por separado.
- Modelos de visión: Las capas de propagación hacia delante con compuerta también aparecen en modelos de visión y multimodales. YOLOE, el detector de vocabulario abierto de investigadores de la Universidad de Tsinghua que se ejecuta en el paquete Ultralytics, refina las representaciones vectoriales de texto de las indicaciones de clase con un bloque SwiGLU residual que se ejecuta una vez por llamada a
set_classes()y se elimina al exportar, por lo que no añade coste por fotograma.










