인덕션 헤드
더 많은 작업
- Induction head; 인덕션 헤드
- 시퀀스에서 지금 토큰이 앞서 나온 자리를 찾아, 그때 바로 뒤에 왔던 토큰을 다음 토큰으로 복사해 내는 어텐션 헤드 회로. [A][B] … [A] → [B]
인덕션 헤드(induction head)는 트랜스포머 안에서 "앞에서 A 다음에 B가 왔으니, 지금 A가 나왔으면 다음은 B일 것"이라는 패턴 완성을 하는 어텐션 헤드, 또는 그런 헤드 두 개로 이루어진 회로를 말한다. 앤트로픽의 해석 가능성 연구진이 2021년 12월 〈A Mathematical Framework for Transformer Circuits〉에서 작은 어텐션 전용 모델을 역설계하다 찾아 이름 붙였고,[1] 2022년 3월 후속 논문 〈In-context Learning and Induction Heads〉에서 이것이 인컨텍스트 러닝(문맥 내 학습)의 상당 부분을 만드는 메커니즘일 수 있다는 근거 여섯 가지를 제시했다.[2]
인덕션 헤드는 언어 모델 내부에서 사람이 이해할 수 있는 알고리즘을 개별 헤드와 가중치 수준까지 찾아낸 사례로, 기계적 해석 가능성 연구의 출발점 가운데 하나다. 국내 기술 블로그에서는 "인덕션 헤드"라는 음차가 보이며, "유도 헤드", "귀납 헤드"라는 번역도 일부 쓰인다.
시퀀스 "… 해리 포터 … 해리"에서 다음 토큰 "포터"를 맞히는 경우를 보자. 위치 에 "해리", 에 "포터"가 있었고, 지금 위치 의 토큰이 "해리"다.
- 앞 토큰 헤드(previous token head, 앞 층): 각 위치가 바로 앞 위치에 어텐션해 "내 앞 토큰은 무엇이었다"는 정보를 자기 잔차 스트림(residual stream)에 써 넣는다. 그러면 위치 ("포터")의 표현에 "앞 토큰 = 해리"가 기록된다.
- 인덕션 헤드(뒤 층): 위치 의 쿼리는 "지금 토큰 = 해리"를 담고, 각 위치의 키는 1단계에서 기록된 "앞 토큰 = ○○"를 담는다. 둘이 맞는 위치 에 어텐션이 몰린다(접두 일치, prefix matching).
- 인덕션 헤드의 값·출력 회로(OV 회로)는 그 위치의 토큰 "포터"를 그대로 출력 로짓 쪽으로 옮겨, "포터"의 확률을 높인다(복사, copying).
올슨(Catherine Olsson) 등은 이 회로가 A와 B가 무엇이든 같은 규칙을 적용하며, 고정된 n-gram 표를 외우는 것이 아니라 단순한 알고리즘을 구현한다고 설명했다.[2] 논문은 이 두 성질, 곧 접두 일치 어텐션 패턴과 복사 효과를 점수로 재는 방식으로 인덕션 헤드를 실증적으로 정의한다.
〈A Mathematical Framework〉의 저자들(Nelson Elhage 외)은 잔차 스트림을 모든 층이 읽고 쓰는 공용 통로로 보고, 뒤 층 헤드가 앞 층 헤드의 출력을 어디서 읽느냐에 따라 합성을 세 가지로 나눴다.[1]
| 합성 | 뒤 층 헤드가 앞 층 출력을 읽는 곳 | 영향 |
|---|---|---|
| Q-합성 | 쿼리 | 어텐션 패턴(어디를 볼지) |
| K-합성 | 키 | 어텐션 패턴 |
| V-합성 | 값 | 옮기는 정보(가상 어텐션 헤드) |
인덕션 헤드는 K-합성의 대표 사례다. 키가 "그 위치 토큰"뿐 아니라 "그 앞 토큰"의 함수여야 하는데, 한 층의 어텐션만으로는 키에 앞 토큰 정보를 넣을 방법이 없으므로 최소 두 층이 필요하다. 논문은 층 수별로 이렇게 정리했다.[1]
- 0층(임베딩→언임베딩만): 바로 앞 토큰으로 다음 토큰을 맞히는 바이그램(N-gram) 통계
- 1층 어텐션 전용: 바이그램과 "A … B C" 꼴의 스킵 트라이그램(skip-trigram)의 앙상블. 아주 단순한 문맥 내 학습은 가능
- 2층 어텐션 전용: 헤드 합성으로 인덕션 헤드 같은 훨씬 복잡한 알고리즘 구현
뒤집어 보면, 키를 만들 때 앞 토큰의 키를 섞도록 구조를 바꾸면 1층 모델도 인덕션 헤드를 만들 수 있어야 한다. 올슨 등은 헤드마다 학습되는 비율로 현재 키와 앞 키를 섞는 "번진 키"(smeared key) 구조로 이를 시험했다.[2]
올슨 등은 문맥 내 학습의 양을 "문맥 속 500번째 토큰의 손실에서 50번째 토큰의 손실을 뺀 값"(평균)으로 쟀다. 문맥이 길어질수록 다음 토큰 예측이 얼마나 쉬워지는지를 보는 지표다.[2]
- 층이 둘 이상인 모델은 크기와 관계없이 학습 초반(약 25억~50억 토큰 사이) 좁은 구간에서 문맥 내 학습 점수가 급격히 늘었다. 그 전에는 0.15내트 미만, 그 뒤에는 약 0.4내트로, 이후 학습 끝까지와 모델 크기에 상관없이 거의 일정했다. 대형 모델에서 이 구간은 전체 학습의 1~2% 지점이다.
- 같은 구간에 학습 손실 곡선에 혹(bump)이 생기고, 인덕션 헤드가 갑자기 형성되었다. 1층 모델에서는 인덕션 헤드도, 큰 문맥 내 학습도 생기지 않았다.
- 논문은 이 급변을 상전이(phase change)라 부르고, 얼음이 녹는 것처럼 거시적(손실 곡선)·미시적(헤드) 양쪽에서 동시에 나타나는 변화에 비유했다.[2]
연구는 34개 모델을 학습 과정에 걸쳐 분석하고 어텐션 헤드 제거 실험을 5만 회 넘게 했다. 모델은 어텐션 전용 소형 모델, MLP가 있는 소형 모델, 4층 1,300만~40층 130억 매개변수의 대형 모델로 나뉜다.[2]
논문은 인덕션 헤드가 문맥 내 학습 대부분의 원천일 수 있다는 주장을 다음 여섯 근거로 뒷받침했다.[2]
| 논거 | 내용 | 증거 성격 |
|---|---|---|
| 1. 거시적 동시 발생 | 상전이 구간에 인덕션 헤드 형성과 문맥 내 학습 급증이 함께 일어남 | 상관 |
| 2. 거시적 동시 교란 | 구조를 바꿔(번진 키) 인덕션 헤드가 생기는 시점을 옮기면 문맥 내 학습의 급증도 정확히 같이 옮겨 감 | 개입 |
| 3. 직접 제거 | 소형 모델에서 시험 시점에 인덕션 헤드를 제거하면 문맥 내 학습이 크게 줄어듦 | 개입(소형 모델만) |
| 4. 일반성의 사례 | 대형 모델의 인덕션 헤드가 글자 그대로의 복사뿐 아니라 번역, 추상적 패턴 일치 같은 "흐릿한" [A*][B*] … [A] → [B] 행동도 함 | 사례 |
| 5. 메커니즘 타당성 | 소형 모델에서는 작동 원리를 수식으로 설명할 수 있고, 그 원리가 더 일반적인 문맥 내 학습으로 확장될 자연스러운 경로가 있음 | 설명 |
| 6. 소형-대형 연속성 | 관련 현상이 작은 모델에서 큰 모델까지 매끄럽게 이어짐 | 정황 |
저자들은 이 근거들이 정황 증거(circumstantial case)이며, 대형 모델에 대해서는 소형 모델보다 약하고, 여러 교란 요인과 대안 가설이 가능하다고 명시했다.[2]
아래는 어텐션 전용 1층·2층 모델을 같은 조건으로 학습해 인덕션 헤드가 2층에서만 생기는지 보는 최소 실험이다. 무작위 토큰 개를 한 번 더 반복한 시퀀스로 학습하며, 을 표본마다 바꿔 "항상 칸 앞을 보라"는 위치 지름길을 막는다. 인덕션 점수는 반복 구간의 각 위치가 "직전 등장 위치의 다음 칸"에 주는 어텐션 평균이다.
import torch
import torch.nn as nn
import torch.nn.functional as F
V, T, D, H = 64, 64, 64, 4 # 어휘, 시퀀스 길이, 모델 차원, 헤드 수
def batch(n):
"""[무작위 L개][같은 L개 반복][무작위 채움]. L을 표본마다 바꾼다."""
x = torch.randint(0, V, (n, T))
L = torch.randint(8, T // 2 + 1, (n,))
for b in range(n):
x[b, L[b]:2 * L[b]] = x[b, :L[b]]
return x, L
class Attn(nn.Module):
def __init__(self):
super().__init__()
self.qkv, self.o = nn.Linear(D, 3 * D), nn.Linear(D, D)
def forward(self, x):
B, T, _ = x.shape
q, k, v = (t.view(B, T, H, D // H).transpose(1, 2) for t in self.qkv(x).split(D, -1))
s = (q @ k.transpose(-1, -2)) / (D // H) ** 0.5
s = s.masked_fill(torch.ones(T, T, dtype=torch.bool).triu(1), float("-inf"))
self.pattern = s.softmax(-1) # 분석용으로 저장
return self.o((self.pattern @ v).transpose(1, 2).reshape(B, T, D))
class AttnOnly(nn.Module): # MLP 없는 어텐션 전용 트랜스포머
def __init__(self, n_layers):
super().__init__()
self.emb, self.pos = nn.Embedding(V, D), nn.Embedding(T, D)
self.layers = nn.ModuleList(Attn() for _ in range(n_layers))
self.unemb = nn.Linear(D, V)
def forward(self, idx):
x = self.emb(idx) + self.pos(torch.arange(idx.shape[1]))
for layer in self.layers:
x = x + layer(x) # 잔차 스트림
return self.unemb(x)
def second_copy(L):
"""반복 구간 위치 t와, 그 토큰이 처음 나온 곳의 '다음' 위치 t-L+1."""
b = torch.cat([torch.full((l - 1,), i) for i, l in enumerate(L.tolist())])
t = torch.cat([torch.arange(l + 1, 2 * l) for l in L.tolist()])
return b, t, t - L[b] + 1
def induction_score(model, layer):
x, L = batch(256)
with torch.no_grad():
model(x)
p = model.layers[layer].pattern # (B, H, T, T)
b, t, src = second_copy(L)
return p[b, :, t, src].mean(0) # 헤드별 점수
for n_layers in (1, 2):
torch.manual_seed(0)
model = AttnOnly(n_layers)
opt = torch.optim.AdamW(model.parameters(), lr=1e-3)
for step in range(2000):
x, _ = batch(64)
loss = F.cross_entropy(model(x)[:, :-1].reshape(-1, V), x[:, 1:].reshape(-1))
opt.zero_grad(); loss.backward(); opt.step()
with torch.no_grad():
x, L = batch(512)
lp = F.cross_entropy(model(x)[:, :-1].transpose(1, 2), x[:, 1:], reduction="none")
b, t, _ = second_copy(L)
print(n_layers, "layers | 반복 구간 loss %.2f" % lp[b, t - 1].mean(),
"| 마지막 층 induction score", induction_score(model, n_layers - 1).numpy().round(2))
PyTorch 2.5, CPU에서 돌린 결과는 다음과 같다. 무작위 추측의 손실은 이다.
| 모델 | 반복 구간 손실 | 마지막 층 헤드별 인덕션 점수 |
|---|---|---|
| 1층 어텐션 전용 | 3.63 | 0.08, 0.08, 0.08, 0.08 |
| 2층 어텐션 전용 | 0.60 | 0.79, 0.79, 0.78, 0.78 |
1층 모델은 반복을 거의 이용하지 못했고, 2층 모델은 둘째 층 헤드가 직전 등장 위치의 다음 칸에 어텐션을 몰아주며 반복 구간을 거의 맞혔다. 2층 모델의 첫 층 어텐션을 보면 바로 앞 위치에 어텐션을 많이 주는 앞 토큰 헤드가 생겨 있다(이 실행에서는 바로 앞 위치에 평균 0.47, 0.28을 주는 헤드 둘). 위치 거리를 고정( 고정)하면 1층 모델도 위치 임베딩만으로 같은 거리를 보는 지름길을 배워 버리므로, 인덕션 헤드를 시험할 때는 이런 지름길을 막아야 한다.
- 형성 과정: 레디(Gautam Reddy)는 단순화한 문맥 내 분류 과제에서 문맥 내 학습이 인덕션 헤드의 급작스러운 출현으로 시작되며, 이 급변을 중첩된 세 로짓이 차례로 학습되는 과정으로 설명하는 현상론적 모델을 냈다(ICLR 2024).[3] 싱(Aaditya K. Singh) 등은 학습 중 활성값 일부를 고정하는 광유전학식 인과 실험으로, 인덕션 헤드가 여러 개 생기며 서로 더해지는 관계이고 세 개의 하위 회로가 상호작용해 상전이를 만든다는 것을 보였다(ICML 2024).[4]
- 현대 LLM에서의 역할: 크로스비(Joy Crosbie)와 슈토바(Ekaterina Shutova)는 Llama-3-8B와 InternLM2-20B에서 인덕션 헤드를 조금만 제거해도 추상 패턴 인식 과제의 퓨샷 성능이 최대 약 32% 떨어져 무작위 수준에 가까워지고, 자연어 과제에서는 퓨샷 성능이 제로샷 수준으로 내려간다고 보고했다.[5]
- 효율적 구조의 약점과 연결: 어텐션 없는 효율적 언어 모델이 트랜스포머에 뒤지는 이유의 대부분이 문맥 속 정보를 다시 꺼내는 연상 회상 능력이라는 분석(Zoology)은, 인덕션 헤드가 하는 일이 바로 이 연상 회상이라는 점과 맞닿는다. 선형 어텐션·상태 공간 모델 계열이 소프트맥스 어텐션 층을 섞는 하이브리드로 가는 배경이다.[6]
인덕션 헤드는 "모델이 문맥에서 배운다"는 블랙박스 현상을 구체적인 가중치 회로로 설명한 사례이고, 학습 곡선의 혹이라는 관측 가능한 신호와 내부 구조 변화를 연결했다는 점에서 의미가 크다. 동시에 대형 모델에 대한 증거는 주로 상관과 사례다. 문맥 내 학습 전체를 인덕션 헤드로 환원할 수 있는지는 원 논문 저자들도 열어 둔 질문이다.[2]
- ↑ 1.0 1.1 1.2 Nelson Elhage 외, 〈A Mathematical Framework for Transformer Circuits〉, Transformer Circuits Thread, 2021-12-22. transformer-circuits.pub
- ↑ 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 Catherine Olsson 외, 〈In-context Learning and Induction Heads〉, Transformer Circuits Thread, 2022-03-08. transformer-circuits.pub, arXiv:2209.11895
- ↑ Gautam Reddy, 〈The mechanistic basis of data dependence and abrupt learning in an in-context classification task〉, ICLR 2024. arXiv:2312.03002
- ↑ Aaditya K. Singh 외, 〈What needs to go right for an induction head? A mechanistic study of in-context learning circuits and their formation〉, ICML 2024. arXiv:2404.07129
- ↑ Joy Crosbie, Ekaterina Shutova, 〈Induction Heads as an Essential Mechanism for Pattern Matching in In-context Learning〉, 2024. arXiv:2407.07011
- ↑ Simran Arora 외, 〈Zoology: Measuring and Improving Recall in Efficient Language Models〉, 2023. arXiv:2312.04927