SwiGLU
더 많은 작업
- SwiGLU; Swish-gated linear unit
- 입력을 두 갈래로 선형 변환해 한쪽에 Swish(SiLU) 활성화를 씌운 뒤 다른 쪽과 원소별로 곱하는 게이트형 활성화. 트랜스포머 피드포워드 층에 쓰인다
SwiGLU는 게이트 선형 유닛(Gated Linear Unit, GLU)의 시그모이드 게이트를 Swish 함수로 바꾼 변형이다. 2020년 2월 구글의 노엄 섀지어(Noam Shazeer)가 〈GLU Variants Improve Transformer〉에서 트랜스포머의 위치별 피드포워드 신경망(FFN)에 GLU 계열을 넣는 실험을 하며 이름 붙였다.[1] 매개변수와 연산량을 맞춘 비교에서 ReLU·GELU FFN보다 사전 학습 퍼플렉서티가 낮았고, 이후 구글 PaLM이 채택하고 메타 LLaMA가 따르면서 대형 언어 모델 FFN의 표준 구성 중 하나가 되었다.[2][3]
섀지어는 논문 결론에서 이 구조들이 왜 잘 되는지는 설명하지 못하며 "다른 모든 것과 마찬가지로 신의 은총 덕분"이라고 적었다.[1] 이론보다 실험으로 자리 잡은 부품이라는 점을 보여 주는 대목이다. 같은 계열의 GeGLU는 T5 1.1과 구글 젬마가 썼다.
Swish는 라마찬드란(Prajit Ramachandran) 등이 2017년 자동 탐색으로 찾은 활성화 함수다.[5]
인 경우 는 Swish보다 먼저 나왔다. 헨드릭스(Dan Hendrycks)와 김펠(Kevin Gimpel)이 2016년 GELU 논문에서 SiLU(Sigmoid Linear Unit)라는 이름으로 소개했고,[6] 2017년 2월 엘프윙(Stefan Elfwing) 등이 강화 학습용 활성화로 다시 제안했다.[7] PyTorch에서는 torch.nn.functional.silu다. GELU 와 모양이 비슷한 매끄러운 곡선이고, 음수 쪽에서 0에 가까워지되 완전히 0이 되지는 않는다.
섀지어는 게이트 쪽 함수를 바꿔 다음 변형들을 정의했다(편향 생략).[1]
| 이름 | 정의 | 게이트 함수 |
|---|---|---|
| GLU | 시그모이드 | |
| Bilinear | 없음(항등) | |
| ReGLU | ReLU | |
| GEGLU | GELU | |
| SwiGLU | Swish(SiLU) |
원 트랜스포머의 FFN은 행렬 두 개로 이루어진다. T5처럼 편향을 빼면
이다. GLU 계열은 첫 선형 변환과 활성화를 GLU로 바꾼다.
행렬이 두 개에서 세 개()로 늘어나므로, 매개변수와 연산량을 같게 맞추려면 은닉 차원 를 로 줄인다. 섀지어의 T5 기본 모델 실험에서는 를 3072에서 2048로 줄였다.[1]
T5 기본 크기(인코더·디코더 각 12층, ) 모델을 C4에서 스팬 채우기 목표로 학습한 뒤 따로 떼어 둔 데이터의 로그 퍼플렉서티를 쟀다. 모든 모델은 매개변수와 연산량을 맞췄고, 65,536단계 열은 4회 학습의 평균(괄호는 표준편차)이다.[1]
| FFN | 65,536단계 | 524,288단계 |
|---|---|---|
| ReLU(기준) | 1.997 (0.005) | 1.677 |
| GELU | 1.983 (0.005) | 1.679 |
| Swish | 1.994 (0.003) | 1.683 |
| GLU | 1.982 (0.006) | 1.663 |
| Bilinear | 1.960 (0.005) | 1.648 |
| GEGLU | 1.942 (0.004) | 1.633 |
| SwiGLU | 1.944 (0.010) | 1.636 |
| ReGLU | 1.953 (0.003) | 1.645 |
게이트가 있는 변형이 모두 기준보다 나았고 GEGLU와 SwiGLU가 가장 좋았다. 게이트 없이 활성화만 바꾼 GELU·Swish는 기준과 차이가 거의 없었으므로, 이 표에서 이득은 활성화 함수 모양보다 곱셈 게이트 구조에서 나온 것으로 보인다. GLUE·SuperGLUE·SQuAD 미세 조정에서도 GLU 계열이 대부분 과제에서 앞섰지만, 논문은 결과에 잡음이 많다고 단서를 달았다.[1]
| 모델 | FFN | 비고 |
|---|---|---|
| T5 1.1 | GEGLU | 원 T5의 ReLU를 교체[8] |
| PaLM (2022) | SwiGLU | 행렬 곱이 셋으로 늘지만 같은 연산량에서 품질이 좋아진다는 섀지어의 결과를 근거로 채택[2] |
| LLaMA (2023) | SwiGLU | 은닉 차원을 PaLM의 대신 로[3] |
| 라마 3 (2024) | SwiGLU | 8B: 모델 차원 4,096, FFN 14,336[9] |
| 젬마 (2024) | GeGLU(근사 GELU) | [10] |
메타 공식 코드는 은닉 차원을 로 잡은 뒤 하드웨어 효율을 위해 multiple_of(기본 256)의 배수로 올린다. 이면 10,922가 11,008로 올라간다. 라마 3 코드에는 여기에 곱하는 ffn_dim_multiplier 인자도 있다.[11]
import torch.nn as nn
import torch.nn.functional as F
class SwiGLUFFN(nn.Module):
def __init__(self, d_model, d_ff):
super().__init__()
self.w_gate = nn.Linear(d_model, d_ff, bias=False) # W (허깅 페이스: gate_proj, 메타: w1)
self.w_up = nn.Linear(d_model, d_ff, bias=False) # V (up_proj, w3)
self.w_down = nn.Linear(d_ff, d_model, bias=False) # W2 (down_proj, w2)
def forward(self, x):
return self.w_down(F.silu(self.w_gate(x)) * self.w_up(x))
def llama_ffn_dim(d_model, multiple_of=256, ffn_dim_multiplier=None):
h = int(2 * (4 * d_model) / 3)
if ffn_dim_multiplier is not None:
h = int(ffn_dim_multiplier * h)
return multiple_of * ((h + multiple_of - 1) // multiple_of)
print(llama_ffn_dim(4096)) # 11008
인 SwiGLU FFN의 매개변수는 억 개로, 인 ReLU FFN(억 개)과 거의 같다. 허깅 페이스 LlamaMLP는 위와 같은 gate_proj, up_proj, down_proj 세 층으로 되어 있다.[12] 추론 엔진에 따라서는 와 를 한 행렬로 이어 붙여 행렬 곱 한 번으로 계산한 뒤 반으로 나누기도 한다.
체크포인트를 옮길 때는 두 입력 행렬 중 어느 쪽에 활성화가 걸리는지 확인해야 한다. 메타 코드는 w2(silu(w1(x)) * w3(x))로, w1이 게이트 쪽이다.[11] 이름 순서만 보고 w1과 w3를 바꿔 넣으면 오류 없이 출력만 틀어진다.
- 활성값 메모리: 연산량은 맞췄어도 역전파를 위해 저장할 중간 텐서가 와 두 개라, 같은 기준으로 보면 활성값이 늘어난다. 메모리가 부족하면 활성값 재계산(그래디언트 체크포인팅)으로 줄인다.
- 계수 맞추기: "SwiGLU를 쓰면 좋아진다"는 비교는 매개변수·연산량을 맞춘 조건의 결과다. 를 그대로 두고 행렬만 하나 더하면 모델이 1.5배 가까이 커진 것이므로 공정한 비교가 아니다.
- 전문가 혼합: 전문가 혼합(MoE) 모델의 각 전문가도 보통 같은 SwiGLU FFN이다. 딥시크 V2의 전문가 은닉 차원 1536 같은 값은 이 세 행렬 구조를 전제로 한다.
- ↑ 1.0 1.1 1.2 1.3 1.4 1.5 Noam Shazeer, 〈GLU Variants Improve Transformer〉, 2020. arXiv:2002.05202
- ↑ 2.0 2.1 Aakanksha Chowdhery 외, 〈PaLM: Scaling Language Modeling with Pathways〉, 2022. arXiv:2204.02311
- ↑ 3.0 3.1 Hugo Touvron 외, 〈LLaMA: Open and Efficient Foundation Language Models〉, 2023. arXiv:2302.13971
- ↑ Yann N. Dauphin, Angela Fan, Michael Auli, David Grangier, 〈Language Modeling with Gated Convolutional Networks〉, ICML 2017. arXiv:1612.08083
- ↑ Prajit Ramachandran, Barret Zoph, Quoc V. Le, 〈Searching for Activation Functions〉, 2017. arXiv:1710.05941
- ↑ Dan Hendrycks, Kevin Gimpel, 〈Gaussian Error Linear Units (GELUs)〉, 2016. arXiv:1606.08415
- ↑ Stefan Elfwing, Eiji Uchibe, Kenji Doya, 〈Sigmoid-Weighted Linear Units for Neural Network Function Approximation in Reinforcement Learning〉, 2017. arXiv:1702.03118
- ↑ 허깅 페이스 문서, T5v1.1
- ↑ Llama Team, AI @ Meta, 〈The Llama 3 Herd of Models〉, 2024. arXiv:2407.21783
- ↑ Gemma Team, 〈Gemma: Open Models Based on Gemini Research and Technology〉, 2024. arXiv:2403.08295
- ↑ 11.0 11.1 meta-llama/llama-models, models/llama3/model.py
- ↑ huggingface/transformers, modeling_llama.py