언어 모델 · Transformer · 3Blue1Brown DL5–7

GPT는 어떻게 다음 단어를 고르는가

토큰 하나가 벡터가 되어 어텐션과 MLP를 96번 지나고 확률 분포가 되어 나오기까지, GPT 한 모델을 입력에서 출력까지 따라갑니다. 3Blue1Brown 딥러닝 시리즈 5~7장을 정리하고, 영상 속 장면을 브라우저에서 직접 계산해 보는 데모를 붙였습니다.

▶ DL5 트랜스포머 · 26:53 ▶ DL6 어텐션 · 25:49 ▶ DL7 MLP와 사실 저장 · 22:24

먼저, 전체 그림

  1. 토큰화 — 입력을 단어나 단어 조각으로 자른다. §1
  2. 임베딩 — 토큰마다 12,288차원 벡터를 붙인다. §2
  3. 어텐션 블록 — 벡터끼리 정보를 주고받으며 문맥을 반영한다. §4–5
  4. MLP 블록 — 벡터마다 따로, 학습된 사실을 꺼내 더한다. §6–7
  5. 3–4를 96번 반복한다.
  6. 언임베딩 + 소프트맥스 — 마지막 벡터를 다음 토큰의 확률 분포로 바꾼다. §3
  7. 분포에서 하나를 뽑아 입력 끝에 붙이고 1로 돌아간다. §1

세 편을 관통하는 생각은 하나입니다. 단어는 고차원 공간의 벡터이고, 의미는 그 공간의 방향이다. 어텐션은 문맥을 보고 벡터를 옮기고, MLP는 아는 사실을 보고 벡터를 옮깁니다. 계산은 전부 행렬 곱입니다.

LEVEL 1 · 입문
다음 토큰 하나만 맞히면 된다

▶ DL5 00:00 ▶ DL5 01:35

GPT는 Generative Pre-trained Transformer의 약자입니다. 새 텍스트를 생성하고, 방대한 데이터로 미리 학습되었으며(이후 파인튜닝 가능), 핵심 구조는 트랜스포머입니다. 트랜스포머는 2017년 구글의 「Attention Is All You Need」에서 번역용으로 처음 나왔지만, 지금은 음성 인식·음성 합성·이미지 생성(DALL·E, Midjourney) 모델의 기반이기도 합니다.

이 모델이 실제로 내놓는 것은 "다음 단어"가 아니라 다음에 올 수 있는 모든 토큰에 대한 확률 분포입니다. 다음 단어 하나 맞히는 기계로 어떻게 긴 글을 쓸까요? 분포에서 하나를 뽑아서 입력 끝에 붙이고, 늘어난 입력으로 다시 예측하기를 반복하면 됩니다. ChatGPT의 답이 한 단어씩 "따다닥" 나오는 이유가 이것입니다.

데모 1 — 한 토큰씩 생성하기

막대는 지금 문장 다음에 올 토큰의 확률입니다. 한 토큰 생성을 누를 때마다 이 분포에서 하나를 뽑아 문장 끝에 붙입니다. 이 장난감 모델은 마지막 토큰 하나만 보고 다음을 고르는 바이그램이라 금방 어색해집니다. 진짜 GPT는 앞의 문맥 전부를 봅니다(How N-gram Works 참고). 온도는 §3에서 설명합니다.

모델이 크면 이 단순한 방식으로도 그럴듯한 글이 나옵니다. 영상에서 같은 방식으로 이야기를 생성시켜 보면 GPT-2는 금방 엉뚱한 이야기로 새고, GPT-3는 꽤 그럴듯한 이야기를 씁니다. 채팅봇은 여기에 시스템 프롬프트, 즉 "사용자와 AI 비서가 대화하는 장면"을 담은 텍스트를 앞에 깔아 두고 AI 쪽 대사를 예측하게 만든 것입니다.

LEVEL 1 · 입문
단어는 벡터, 의미는 방향

▶ DL5 07:24 딥러닝의 규칙 ▶ DL5 12:28 임베딩

딥러닝 모델에는 지켜야 할 형식이 있습니다. 입력도, 중간 층도, 출력도 전부 실수 배열(텐서)이어야 하고, 학습되는 파라미터(가중치)는 데이터와 가중합, 즉 행렬–벡터 곱으로만 만납니다. 그 사이사이에 파라미터 없는 비선형 함수가 끼어듭니다. 그래야 모든 모델이 같은 학습 알고리즘인 역전파로 대규모 학습을 할 수 있습니다. GPT-3의 가중치 1,750억 개는 약 28,000개의 행렬로 나뉘고, 이 행렬들은 몇 가지 종류로 묶입니다. 이 글은 §8에서 그 표를 끝까지 채웁니다.

첫 번째 행렬은 임베딩 행렬 WE입니다. 어휘(GPT-3는 50,257개 토큰)마다 열이 하나씩 있고, 그 열이 그 토큰의 벡터입니다. 처음엔 랜덤이고 학습으로 다듬어집니다. GPT-3의 임베딩 차원은 12,288이라 WE만으로 50,257 × 12,288 ≈ 6억 1,700만 개입니다.

학습이 끝난 임베딩에서는 놀랍게도 공간의 방향이 의미를 갖습니다. 영상의 유명한 예시들입니다.

물론 완벽하진 않습니다. queen은 학습 데이터에서 "여자 왕" 말고도 여러 뜻으로 쓰이니까요. 아래 데모는 12,288차원을 2차원으로 줄인 장난감입니다. 가로는 "성별", 세로는 "왕족·나이" 비슷한 축으로 단어를 손으로 배치했습니다.

데모 2 — 벡터 산술: A − B + C

세 단어를 골라 A − B + C를 계산합니다. 회색 화살표는 B → A의 차이 벡터이고, 그 화살표를 C에서 다시 그은 끝(★)에 가장 가까운 단어를 찾습니다. word2vec처럼 입력 세 단어는 후보에서 뺍니다.

방향이 얼마나 맞는지는 내적으로 잽니다. 대응하는 성분끼리 곱해서 더한 값이고, 기하학적으로는 |a||b|cos θ입니다. 같은 방향이면 양수, 직교하면 0, 반대 방향이면 음수가 됩니다. 영상에서는 cats − cat을 "복수 방향"으로 보고 다른 단어와 내적해 보는데, 복수 명사가 단수 명사보다 일관되게 큰 값이 나오고 one, two, three…에 대 보면 수가 커질수록 값도 커집니다.

데모 3 — 내적의 부호

파란 벡터 a는 고정입니다. 주황 벡터 b의 끝을 끌어서 돌려 보세요. 어텐션(§4)과 MLP(§6)에서 일어나는 일은 결국 이 내적을 엄청나게 많이 계산하는 것입니다.

a · b—
각도 θ—
cos θ—

트랜스포머에서 이 벡터는 단어 하나의 뜻으로 끝나지 않습니다. 처음 임베딩은 단어 뜻(과 위치 정보)만 담지만, 블록을 지날수록 주변 문맥을 흡수합니다. 영상의 예로, "king"이라는 벡터가 층을 지나며 "스코틀랜드에 살았고, 선왕을 죽이고 왕좌를 차지했고, 셰익스피어 문체로 묘사된 왕(맥베스)"을 가리키는 벡터로 바뀌어 갑니다. 한 번에 볼 수 있는 토큰 수, 즉 컨텍스트 길이는 GPT-3에서 2,048입니다. 그래서 GPT-3 안을 흐르는 데이터는 늘 12,288 × 2,048 모양의 배열이고, 초기 ChatGPT가 긴 대화에서 앞 내용을 잊어버린 이유도 여기 있습니다.

LEVEL 2 · 학부
마지막 벡터에서 확률로

▶ DL5 20:25 언임베딩 ▶ DL5 22:21 소프트맥스 ▶ DL5 23:56 온도

모든 블록을 지난 뒤 마지막 벡터에 언임베딩 행렬 WU를 곱하면 어휘 크기만큼의 점수 50,257개가 나옵니다. WU는 WE를 뒤집은 모양이라 역시 약 6억 1,700만 개입니다. 이 날것의 점수를 로짓(logit)이라 부릅니다.

왜 마지막 벡터만?

생성할 때는 마지막 벡터 하나로 다음 토큰을 고릅니다. 하지만 학습할 때는 모든 위치의 벡터가 각자 "자기 바로 다음 토큰"을 동시에 예측합니다. 문장 하나에서 학습 예제를 여러 개 뽑아내는 효율적인 방법인데, 그 대가로 §4의 마스킹이 필요해집니다.

로짓은 음수도 있고 1보다 큰 값도 있어서 그대로는 확률이 아닙니다. 소프트맥스는 아무 실수 나열이나 확률 분포로 바꾸는 표준적인 방법입니다. 각 값에 ex를 씌워 전부 양수로 만들고, 합으로 나눠 총합을 1로 맞춥니다. 여기에 온도 T를 넣으면 분포의 날카로움을 조절할 수 있습니다.

pi = exi/T / Σj exj/T T가 크면 분포가 평평해지고(의외의 단어), 작으면 최댓값에 쏠린다. T = 0이면 늘 최댓값만 고른다.

데모 4 — 소프트맥스와 온도

"해리 포터가 가장 싫어하는 교수는 ___". 해리 포터를 읽은 모델이라면 스네이프에 가장 높은 로짓을 줄 겁니다. 로짓과 온도를 움직여 보세요. 로짓이 하나만 조금 커도 ex 때문에 그 항목이 분포를 지배합니다.

영상에서는 "Once upon a time"으로 시작하는 이야기를 온도만 바꿔 생성해 봅니다. T = 0이면 늘 뻔한 단어만 골라 평범한 이야기가 나오고, 온도를 올리면 의외의 단어가 섞이다가 결국 말이 안 되는 문장으로 무너집니다. 서비스에서 온도 상한을 두는 건 수학적 이유가 아니라 이런 출력을 막으려는 제한일 뿐입니다.

LEVEL 2 · 학부
어텐션 — 질문(Q)과 견출지(K)

▶ DL6 01:56 문맥과 의미 ▶ DL6 04:31 Q·K ▶ DL6 11:04 마스킹

같은 단어도 문맥에 따라 뜻이 다릅니다. mole은 두더지(American shrew mole)일 수도, 몰(one mole of carbon dioxide)일 수도, 점(take a biopsy of the mole)일 수도 있습니다. 처음 임베딩은 문맥을 모르니 셋 다 같은 벡터입니다. 어텐션은 주변을 보고 "이 벡터를 어느 방향으로 얼마나 옮길지"를 계산합니다. tower 앞에 Eiffel이 오면 파리·프랑스·철 구조물 쪽으로, miniature가 오면 "크다"에서 멀어지는 쪽으로 옮깁니다. 정보는 멀리서도 옵니다. 추리소설 끝의 "그래서 범인은 ___"을 맞히려면 마지막 벡터가 책 전체를 흡수해야 합니다.

영상은 "a fluffy blue creature roamed the verdant forest"(복슬복슬한 파란 생명체가 푸른 숲을 돌아다녔다)라는 문장으로, 형용사가 명사의 뜻을 바꾸는 헤드 하나를 따라갑니다. 실제 헤드가 이렇게 깔끔하게 한 가지 일만 하진 않지만, 행렬이 무엇을 하는지 상상하는 데는 큰 도움이 됩니다.

Attention(Q, K, V) = softmax( QK⊤ / √dk ) V √dk로 나누는 건 수치 안정성 때문(dk = key·query 차원 = 128). V는 §5에서.
마스킹

학습 때는 모든 위치가 동시에 자기 다음 토큰을 맞힙니다(§3). 그런데 뒤 토큰이 앞 토큰에 정보를 주면 정답을 미리 보는 셈입니다. 그래서 그 칸들을 소프트맥스 전에 −∞로 바꿉니다. 0을 넣으면 e0 = 1이라 여전히 가중치를 받지만, −∞는 소프트맥스 뒤 정확히 0이 되고 열 합도 1로 유지됩니다.

데모 5 — 어텐션 맵

영상과 같이 열 = query(묻는 토큰), 행 = key(답하는 토큰)이고, 각 열에 소프트맥스를 걸었습니다. 원이 클수록 가중치가 큽니다. 열을 클릭하면 그 토큰이 어디에 주목하는지 숫자로 보여 줍니다. 헤드를 바꿔 보고, 특히 다음 토큰 엿보기 헤드에서 마스킹을 꺼 보세요.

← 좌우로 스크롤 →

어텐션 맵의 크기는 컨텍스트 길이의 제곱입니다. 컨텍스트를 두 배로 늘리면 맵은 네 배가 됩니다. 컨텍스트를 키우기 어려운 이유이고, 긴 문맥을 다루는 기법들이 지금도 연구되는 이유입니다.

LEVEL 2 · 학부
Value와 멀티헤드 — 실제로 무엇을 옮기나

▶ DL6 13:09 Value ▶ DL6 15:58 파라미터 ▶ DL6 19:26 멀티헤드

어텐션 맵은 "누가 누구와 관련 있나"만 알려 줍니다. 실제로 벡터를 옮기려면 무엇을 더할지가 필요합니다. 그게 Value vj = WV ej입니다. "이 단어가 관련 있다면 상대 벡터에 무엇을 더해 줘야 하나"를 뜻하고, 임베딩과 같은 12,288차원 공간에 삽니다. creature 열의 가중치로 value들을 가중합하면 변화량 Δe가 되고, 이걸 원래 임베딩에 더하면 "복슬복슬한 파란 생명체"를 가리키는 벡터가 됩니다.

e′creature = ecreature + Σj wj vj wj = creature 열의 어텐션 가중치 · 모든 토큰에 대해 똑같이 동시에 계산한다

문맥이 뜻을 바꾸는 방식은 수없이 많습니다. 사고 난 car, wizard와 함께 나온 Harry(해리 포터)와 Queen·Sussex와 함께 나온 Harry(해리 왕자)처럼요. 그래서 헤드 하나가 아니라 여러 헤드를 병렬로 돌립니다. GPT-3는 블록마다 96개입니다. 각 헤드가 자기 Q·K·V로 자기 어텐션 맵을 만들고, 각자 제안한 Δe를 전부 더해 원래 임베딩에 더합니다.

데모 6 — Δe 따라가기: 헤드 하나 vs 둘

가로축은 "파란색", 세로축은 "복슬복슬함" 방향입니다. creature의 임베딩(●)이 어텐션을 지나 어디로 옮겨 가는지 봅니다. 헤드 하나로 두 형용사를 모두 맡기면 소프트맥스 가중치를 둘이 나눠 가져서 각각 덜 반영됩니다. 헤드 둘(색 담당, 질감 담당)로 나누면 각 헤드가 자기 형용사에 거의 전부를 줍니다.

파라미터를 아끼는 Value 분해

WQ, WK는 각각 128 × 12,288 ≈ 157만 개입니다. 그런데 WV를 12,288 × 12,288 정사각으로 두면 약 1억 5,100만 개로 혼자 100배 커집니다. 그래서 저랭크(low-rank) 분해를 합니다. Value↓로 12,288 → 128로 줄였다가 Value↑로 128 → 12,288로 되돌립니다. 그러면 헤드 하나의 네 행렬(Q, K, V↓, V↑)이 모두 같은 크기가 되고 합쳐서 약 630만 개입니다. 실제 구현에서는 헤드별 Value↑를 모아 하나의 출력 행렬 WO로 합쳐 두기 때문에, 보통 "value 행렬"이라 하면 Value↓ 쪽만 가리킵니다.

630만 × 96헤드 × 96층 ≈ 580억. 전체 1,750억의 약 1/3입니다. 제목은 "Attention Is All You Need"지만, 나머지 2/3는 다음 절의 MLP에 있습니다.

셀프 어텐션 vs 크로스 어텐션

지금까지 본 건 query와 key가 같은 시퀀스에서 나오는 셀프 어텐션입니다. 크로스 어텐션은 query와 key가 서로 다른 데이터에서 옵니다. 번역(원문 ↔ 번역문)이나 음성 → 텍스트 같은 경우죠. 앞뒤 순서 개념이 없으니 마스킹도 하지 않습니다. 원 논문의 인코더–디코더 구조는 How Transformer Works에서 다룹니다.

어텐션이 이렇게 널리 쓰이게 된 가장 큰 이유는 GPU로 대량 병렬 계산이 된다는 점입니다. 지난 10~20년 동안 "모델을 키우면 성능이 오른다"는 사실이 거듭 확인되었고, 키우려면 병렬화되는 구조가 필요했습니다.

LEVEL 2 · 학부
MLP — 사실을 꺼내는 AND 게이트

▶ DL7 00:00 ▶ DL7 06:13 MLP 따라가기 ▶ DL7 10:08 ReLU

"Michael Jordan plays the sport of ___"을 넣으면 모델은 basketball에 높은 확률을 줍니다. 이런 사실은 파라미터 어디에 있을까요? Google DeepMind 연구자들의 분석에 따르면 주로 MLP(다층 퍼셉트론) 블록에 있습니다. MLP 계산은 어텐션보다 훨씬 단순합니다. 행렬 곱 두 번이 전부입니다. 어려운 건 그게 무슨 뜻인지 해석하는 일입니다.

영상은 장난감 가정을 하나 둡니다. 공간에 first name Michael, last name Jordan, basketball 방향이 있고 서로 직교한다고 합시다. 그러면 어떤 벡터를 Michael 방향과 내적한 값이 1이면 "Michael을 담고 있다", 0이면 "아니다"로 읽을 수 있습니다. "Michael"과 "Jordan"은 다른 토큰이므로 Jordan 위치의 벡터가 Michael 정보까지 가지려면 앞선 어텐션이 옮겨 줬어야 합니다.

e′ = e + W↓ · ReLU( W↑ e + b↑ ) + b↓ W↑: 12,288 → 49,152 · W↓: 49,152 → 12,288 · 토큰마다 독립적으로, 똑같이, 병렬로
  1. W↑의 행 하나 = 질문 하나. 첫 행이 M + J(Michael + Jordan 방향)라면 결과는 M·e + J·e. e가 "Michael Jordan"이면 2, 하나만 맞으면 1, 둘 다 아니면 0.
  2. 바이어스 b↑ = −1을 더하면 "둘 다 맞을 때만 양수"가 된다.
  3. ReLU(음수 → 0)를 거치면 둘 다 맞을 때만 1, 아니면 0. AND 게이트처럼 동작한다. 실제로는 모양이 비슷한 GELU를 많이 쓴다. 이 값 하나하나가 흔히 말하는 뉴런이고, 양수면 켜짐이다.
  4. W↓의 열 하나 = 방향 하나. 첫 열이 basketball 방향이면, 첫 뉴런이 켜질 때 basketball이 그대로 더해진다.
  5. 잔차 연결로 결과를 입력에 더한다. "Michael Jordan" 벡터가 "Michael Jordan + basketball" 벡터가 된다.

데모 7 — 뉴런 네 개짜리 MLP

W↑에 질문 4개(Michael Jordan? LeBron James? Lionel Messi? Michael Phelps?)를, W↓에 답 방향(농구·농구·축구·수영)을 손으로 심었습니다. 이름을 바꿔 보고, 바이어스를 0으로 올리거나 활성화 함수를 끄면 어떻게 망가지는지 확인해 보세요.

← 좌우로 스크롤 →

W↑의 행 수, 즉 질문(뉴런)의 수는 GPT-3에서 4 × 12,288 = 49,152입니다. W↑는 49,152 × 12,288 ≈ 6억 400만, W↓도 같아서 블록당 약 12억, 96층이면 약 1,160억입니다. 전체의 2/3가 여기 있습니다. 손글씨 숫자를 알아보던 시리즈 1장의 그 신경망과 구조가 똑같습니다. 다만 이건 개념적 설명이고, 실제 모델이 정말 이렇게 깔끔하게 동작한다는 뜻은 아닙니다.

LEVEL 3 · 심화
중첩 — 차원보다 많은 개념을 담는 법

▶ DL7 17:06 중첩 ▶ DL7 19:01 100차원 실험

실제 연구에서는 뉴런 하나가 "Michael Jordan"처럼 깔끔한 특징 하나를 맡는 경우가 거의 없습니다. 해석 가능성 연구자들은 이를 중첩(superposition)으로 설명합니다. 이 개념은 모델을 해석하기가 왜 그렇게 어려운지, 그리고 모델이 왜 그렇게 잘 작동하는지를 동시에 설명해 줍니다.

N차원 공간에서 서로 완전히 직교하는 방향은 최대 N개입니다. 특징 하나를 방향 하나에 두면 N개가 한계입니다. 그런데 조건을 "거의 직교", 예를 들어 85°~95°로 풀면 이야기가 완전히 달라집니다. 2·3차원에서는 별 차이가 없지만 고차원에서는 폭발적으로 늘어납니다. 존슨–린덴스트라우스 보조정리에 따르면 거의 직교하는 벡터를 넣을 수 있는 개수는 차원에 대해 지수적으로 늘어납니다.

데모 8 — 랜덤 벡터는 고차원에서 저절로 거의 직교한다

브라우저가 d차원 랜덤 벡터 N개를 만들고, 모든 쌍(많으면 표본)의 각도를 히스토그램으로 그립니다. d를 2 → 1000으로 올려 보세요. 최악의 쌍 밀어내기는 가장 덜 직교한 쌍부터 조금씩 벌려서, 그 각도를 이론 한계(웰치 경계)까지 끌어올립니다(N ≤ 1,000, d ≤ 300에서만).

85°–95° 안의 쌍—
가장 덜 직교한 쌍—
이론 한계 (웰치)—
N ÷ d—
영상의 숫자 하나 바로잡기

영상은 100차원에 벡터 10,000개를 넣고 최적화하면 거의 모든 쌍이 89°~91°에 들어온다고 말합니다. 하지만 이건 수학적으로 불가능합니다. 웰치 경계에 따르면 d차원 단위 벡터 N개 중 가장 덜 직교한 쌍의 |cos θ|는 적어도 √((N−d) / (d(N−1)))입니다. d = 100, N = 10,000이면 약 0.0995, 각도로는 84.3°보다 직교에 가까울 수 없습니다. 그래도 핵심 결론은 그대로입니다. 허용 오차 ε을 정해 두면 넣을 수 있는 벡터 수는 대략 ec·d·ε², 즉 차원에 대해 지수적으로 늘어납니다. ±1°처럼 아주 빡빡한 오차는 100차원으로는 부족하고 훨씬 큰 차원이 필요할 뿐입니다.

이것을 언어 모델에 연결하면 이렇습니다.

중첩된 특징을 다시 풀어내는 도구로 희소 오토인코더(sparse autoencoder)가 연구되고 있습니다. 영상에서는 Welch Labs의 관련 영상을 함께 추천합니다.

종합
1,750억을 끝까지 세기

▶ DL5 11:06 28,000개의 행렬 ▶ DL6 24:16 ▶ DL7 15:40

시리즈는 DL5에서 빈 표를 하나 그려 두고, 편마다 칸을 채워 DL7에서 완성합니다. 아래 계산기는 그 표를 그대로 계산합니다. 영상의 셈법을 따라 정규화 층과 바이어스처럼 비중이 작은 파라미터는 뺐고, 임베딩과 언임베딩은 따로 셉니다. 프리셋을 바꾸거나 값을 움직여 보세요.

데모 9 — 파라미터 계산기

GPT-3 프리셋에서 합계는 영상과 같은 175,181,291,520이 나옵니다. 행렬 개수는 영상처럼 헤드별 Q·K·V↓와 층별 출력 행렬 하나로 셉니다.

핵심 정리

단계하는 일GPT-3 숫자
임베딩 WE토큰 → 벡터. 방향이 의미를 가진다50,257 × 12,288
어텐션Q·K 내적으로 누가 누구를 볼지, V로 무엇을 더할지. 벡터끼리 정보 교환96헤드 × 96층, dk = 128
마스킹뒤 토큰이 앞 토큰에 영향 못 주게 −∞컨텍스트 2,048
MLPW↑ 질문 → ReLU(AND) → W↓ 답 방향. 벡터마다 독립49,152 뉴런 × 96층
언임베딩 + 소프트맥스마지막 벡터 → 로짓 → 확률. 온도로 날카로움 조절12,288 → 50,257
합계어텐션 ≈ 1/3, MLP ≈ 2/3약 1,750억

이해도 퀴즈