언어 모델의 진화 - 모든 LLM의 돌파구는 단지 버그 수정이었다
요약
언어 모델의 발전 과정을 연구의 역사가 아닌 '버그 수정의 역사(changelog)'로 재해석합니다. 규칙 기반 모델에서 통계적 모델, 그리고 벡터 임베딩으로 진화하며 발생한 한계와 이를 극복해온 과정을 설명합니다.
핵심 포인트
- 언어 모델의 진화는 연구 타임라인보다 변경 로그(changelog)에 가깝다
- 규칙 기반 모델은 언어의 모호성과 예외를 처리하지 못하는 한계가 있었다
- 단어 임베딩(vector)의 도입으로 의미 간의 산술 연산이 가능해졌다
- 단일 벡터 방식은 문맥에 따른 다의어(polysemy) 문제를 해결하지 못한다
2017년에 아무도 제1원리(first principles)로부터 Transformer를 설계하기 위해 자리에 앉아 있었던 것은 아닙니다.
실제로 일어난 일은 더 무질서하고 훨씬 더 흥미롭습니다. 누군가 무언가를 만들었고, 그것이 특정하고 짜증 나는 방식으로 고장 났으며, 다른 누군가가 그 고장을 패치(patch)했고, 그 패치가 또 다른 곳을 고장 냈습니다. 이런 일이 20년 동안 반복되면서 ChatGPT가 탄생한 것입니다.
이는 언어 모델의 역사가 연구 타임라인이라기보다는 변경 로그(changelog)에 가깝다는 것을 의미합니다. 그러니 그런 방식으로 읽어봅시다.
미리 밝혀둡니다: 저는 이 분야를 가르치는 것이 아니라 배우고 있는 중입니다. 이것은 단어 계산(word-counting)에서 RAG로 어떻게 넘어오게 되었는지 이해하려고 노력하는 과정에서 스스로 그린 지도이며, 무언가를 설명하는 것이 제가 실제로 이해했는지 확인하는 방법이기 때문에 기록해 두었습니다. 수정 사항은 언제든 환영합니다.
v0.1: 그냥 규칙을 적어라
접근 방식: 언어학자들을 고용합니다. 문법 규칙을 작성합니다. "영어는 명사 앞에 형용사가 오고 → 프랑스어는 명사 뒤에 형용사가 온다." 이런 규칙을 수천 개 만듭니다.
🐛 버그: 언어에는 무한한 예외가 있으며, 규칙은 "아마도"를 표현할 수 없습니다.
"I saw the man with the telescope."
당신이 망원경을 사용한 것인가요, 아니면 그가 망원경을 가지고 있었던 것인가요? 어떤 문법 규칙도 이를 해결하지 못합니다. 문맥상 무엇이 _가능성(likely)_이 높은지 알아야 합니다. 규칙은 가능성을 다루지 못합니다.
남은 교훈: 언어를 수동으로 지정하는 것을 멈추세요. 예시로부터 학습하세요.
v0.2: 모든 것을 세어라
접근 방식: 엄청난 양의 텍스트를 가져옵니다. 무엇 다음에 무엇이 오는지 세어봅니다.
"the cat sat on the"를 백 번 보았는데, 그 다음에 `
이 버그가 바로 중요한 버그였습니다.
v0.3: 단어가 좌표가 되다
접근 방식: ID 사용을 중단합니다. 모든 단어에 숫자 리스트, 즉 **벡터 (vector)**를 부여하고 이 숫자들을 학습하도록 합니다.
cat → [ 0.21, -0.85, 0.44, ... ]
dog → [ 0.19, -0.79, 0.51, ... ] # 이웃 (neighbors)
car → [-0.63, 0.22, -0.90, ... ] # 다른 구역 (different neighborhood)
유사한 의미를 가진 것들이 서로 가까이 위치하는 지도를 상상해 보세요. 훈련 데이터 전반에 걸쳐 cat과 dog가 유사한 문장에 등장하기 때문에, 훈련 과정에서 이들의 좌표가 조용히 서로 가까워집니다. 이제 고양이에 대해 배우는 것은 개에 대해서도 공짜로 무언가를 가르쳐 주는 셈이 됩니다.
그 후 word2vec (2013)은 아무도 프로그래밍하지 않았던 무언가를 드러냈습니다:
king − man + woman ≈ queen
Paris − France + Italy ≈ Rome
"king"에서 "man"을 빼면, 왕족과 같은 무언가가 남습니다. 의미(Meaning)에 **산술 (arithmetic)**이 있다는 사실이 밝혀진 것입니다.
🐛 버그: 단어당 하나의 벡터. 영원히.
"I sat on the river bank." ┐
"I got a loan from the bank." ┘ 동일한 벡터
하나의 좌표 세트가 두 가지 의미를 모두 수행해야 하므로, 어느 쪽에도 맞지 않는 모호한 중간 지점에 위치하게 됩니다. play, run, light, _right_와 같은 흔한 영어 단어들의 상당수도 마찬가지입니다.
여러분이 원하는 것은 문장의 나머지 부분에 따라 달라지는 "bank"의 벡터입니다. 이를 위해서는 실제로 문장을 읽는 모델이 필요합니다.
v0.4: 순서대로 읽기 (RNN → LSTM)
접근 방식: 단어들을 한 번에 하나씩 루프(loop)를 돌며 처리하며, 지금까지 읽은 내용을 요약하는 숫자 메모장(scratchpad)을 들고 다닙니다.
🐛 버그: 이는 '전화기 게임(game of telephone)'과 같습니다.
메모장은 매 단계마다 새로 작성됩니다. 30단계쯤 가면, 첫 번째 단어는 소문(rumor)이 되어버립니다. 훈련은 더 심각합니다. 30번째 단어가 2번째 단어에 의존한다는 것을 배우려면, 학습 신호(learning signal)가 28단계를 거슬러 올라가야 하며, 이때 매번 곱해지게 됩니다. 만약 이 곱해지는 값들이 약 0.7이라면:
0.7 ^ 28 ≈ 0.0000002
이것이 바로 **기울기 소실 문제 (vanishing gradient problem)**입니다. 이는 단순히 "장기 패턴을 잘 학습하지 못한다"는 뜻이 아닙니다. _아예 학습하지 못한다_는 뜻입니다.
패치 (LSTM, 1997): 두 번째 경로를 추가합니다. 정보가 덮어쓰여지는 대신 **덧셈 (addition)**을 통해 업데이트되는 메모리 통로(memory lane)를 만드는 것입니다. 이 통로는 세 가지 학습된 디머 스위치(무엇을 잊을지, 무엇을 저장할지, 무엇을 노출할지)에 의해 보호됩니다.
이는 30명의 사람에게 줄을 서서 메시지를 속삭이는 것과, 전달할 **봉인된 봉투 (sealed envelope)**를 직접 건네주는 것의 차이와 같습니다. 이제 모델은 "주어는 복수형이다"라고 적은 뒤, 이를 봉인하여 8단어 뒤까지 가져갔다가, is 대신 _are_를 선택해야 할 시점에 봉투를 열 수 있습니다.
🐛 버그 (여전함): 구조적으로 순차적 (sequential)입니다. 단어 1 다음에 단어 2, 그 다음에 단어 3이 옵니다. GPU를 100개 사더라도, 모두가 서로를 기다리며 가만히 앉아 있게 될 것입니다.
🐛 버그 (새로운 것): 번역의 경우, 표준 설계는 전체 소스 문장을 하나의 고정된 크기의 벡터 (fixed-size vector)로 압축했습니다. 주말 여행을 위해 짐을 싸든 1년 치 여행을 위해 싸든 똑같은 크기의 여행 가방을 사용하는 것과 같습니다. 예상했던 대로, 긴 문장에서 품질이 급격히 떨어졌습니다.
v0.5: 어텐션 (Attention): 그냥 뒤를 돌아보세요
접근 방식 (2014): 왜 굳이 압축을 하나요? 인코더 (encoder)는 이미 모든 입력 단어에 대한 메모장 (scratchpad)을 생성했습니다. 그것들은 여전히 메모리에 남아 있습니다. 디코더 (decoder)가 그 모든 것을 살펴보게 하고, 지금 당장 어떤 것이 중요한지 학습하게 하세요.
_"le chat dort"_를 _"the cat sleeps"_로 번역할 때, "cat"을 쓰는 과정은 다음과 같습니다:
le ▍ 4%
chat ████████████████ 85%
dort ██ 11%
그다음 "sleeps"를 위해 초점이 dort로 이동합니다. 매 출력 단어마다 새롭게 재구성되는 맞춤형 요약인 셈입니다.
긴 문장에서의 성능 저하가 멈췄습니다. 백분율을 그래프로 그려 모델이 무엇을 사용하고 있는지 눈으로 확인할 수도 있었습니다. 둘 다 훌륭했습니다.
하지만 우연한 발견이 더 중요했습니다: 어텐션 (attention)은 단 한 번의 도약 (single hop)으로 임의의 두 위치를 연결합니다. RNN에서는 단어 3에서 단어 90으로 가려면 87단계를 힘들게 거쳐야 하며 그 과정에서 신호가 손실됩니다. 어텐션을 사용하면 단 한 단계면 충분하며, 아무것도 흐려지지 않습니다.
이는 한 가지 난처한 질문을 던집니다. 만약 어텐션이 무제한의 범위를 공짜로 제공하고, 순환 (recurrence)이 모든 것을 느리고 망각하게 만드는 주범이라면 - 왜 우리는 순환을 계속 유지하고 있는 걸까요?
v1.0: Transformer ⚠️ BREAKING CHANGE
접근 방식 (2017): 루프(loop)를 버려라. 어텐션 (attention) 부분만 남겨라.
이 논문의 제목은 _"Attention Is All You Need"_입니다. 저는 처음에 이것이 다소 발칙한 제목이라고 생각했습니다. 하지만 그렇지 않습니다. 이는 그들이 무엇을 삭제했는지를 문자 그대로 설명하고 있는 것입니다.
제가 이해하는 데 가장 오래 걸렸던 부분은 이것입니다. 저는 Transformer가 더 나은 답변을 제공하기 때문에 대단한 것이라고 가정했습니다. 실제로 그렇긴 하지만, 그것이 핵심은 아닙니다. 핵심은 이전 모델들이 결코 도달할 수 없었던 방식으로 빠르다는 점입니다.
LSTM이 어떻게 읽는지 생각해 보세요. 단어 1, 그다음 단어 2, 그다음 단어 3, 엄격하게 그 순서대로 읽습니다. 각 단계가 이전 단계의 결과값을 필요로 하기 때문입니다.
Transformer는 모든 단어를 동시에 바라봅니다. 순차적으로가 아니라 — 한꺼번에 말이죠. 그리고 "수천 가지 일을 동시에 수행"합니다.
셀프 어텐션 (self-attention)의 작동 방식
이제 모든 단어는 동일한 문장 내의 다른 모든 단어를 바라봅니다. 이 메커니즘은 룩업 (lookup) 방식입니다. 각 단어는 세 가지 요소를 가집니다:
| 포함 요소 | 의미 |
|---|---|
| 질문 (Query) | "내가 파악하려고 하는 것은 이것이다" |
| ... |
각 단어는 검색 쿼리 (search query)를 작성하고, 이를 모든 이의 레이블 (labels)과 대조하며, 일치하는 대상으로부터 콘텐츠의 혼합물을 수집합니다. 예를 들어:
"The animal didn't cross the street because it was too tired."
여기서 it은 동물(animal)일까요, 아니면 거리(street)일까요? it의 쿼리가 돌아오는 과정을 살펴보세요:
animal ████████████████████ 71%
tired ██████ 12%
street ██ 5%
...
이제 it의 새로운 표현 (representation)은 71%가 animal이 됩니다. 그것은 자신이 참조하는 대상을 _흡수 (absorbed)_한 것입니다. 다른 모든 단어가 동일한 작업을 수행하는 것과 병렬적으로, 단 한 단계 만에 이루어집니다.
그리고 주목하세요 — 이는 v0.3의 버그도 완전히 해결합니다. 이제 모든 단어의 벡터 (vector)는 실제 주변 맥락으로부터 구축되므로, river bank (강둑)와 bank account (은행 계좌)는 완전히 다르게 도출됩니다.
이러한 것들을 여러 개 병렬로 실행하면 (attention heads (어텐션 헤드)), 훈련 과정에서 각자 전문화됩니다. 훈련된 모델을 조사하던 사람들은 주어-동사 일치(subject-verb agreement)를 추적하는 헤드, 대명사를 따르는 헤드, 따옴표를 맞추는 헤드 등을 발견했습니다. 스스로를 고용한 전문가 위원회인 셈입니다.
🐛 버그 (Bug): 모든 단어가 모든 단어와 자신을 비교합니다. 100개의 단어 → 10,000번의 비교. 1,000개의 단어 → 1,000,000번의 비교. 텍스트가 10배 늘어나면, 작업량은 100배 늘어납니다. 이것이 컨텍스트 윈도우(context windows)가 희소한 자원인 이유이며, 이 곡선을 완만하게 만들기 위해 별도의 하위 분야가 존재하는 이유입니다.
v2.0: 그냥 엄청나게 크게 만들기
접근 방식 (2020): GPT-3는 새로운 아키텍처가 아니었습니다. 대략 100배 규모로 확장된 GPT-2였습니다.
그러다 이상한 현상이 나타났습니다:
English: sea otter → French: loutre de mer
English: cheese → French: fromage
English: peppermint → French: ___
모델이 빈칸을 정확하게 채웁니다. 가중치가 고정된 상태(frozen weights)에서 말이죠. 훈련도, 그래디언트 단계(gradient step)도, 아무것도 없이 — 프롬프트로부터 작업을 학습하고 그 이후에는 잊어버립니다. 이것이 **인컨텍스트 러닝 (in-context learning)**이며, 머신러닝(ML)을 사용하는 방식 자체를 뒤집어 놓았습니다. 이전에는 레이블이 지정된 데이터를 수집하고, 훈련하고, 배포하고, 작업마다 반복했습니다. 이후에는 프롬프트를 작성하면 됩니다.
🐛 버그 (Bug): 이것은 어시스턴트가 아니라 자동 완성 엔진입니다.
가공되지 않은 사전 훈련된(pretrained) 모델에게 물어보세요:
사용자: 집중력을 유지하기 위한 좋은 운동 세 가지는 무엇인가요?
모델: 좌골 신경통에 도움이 되는 스트레칭은 무엇인가요? 책상에서 자세를 어떻게 교정하나요?
모델이 까다롭게 구는 것이 아닙니다. 사용자가 FAQ 헤딩을 전달했기 때문에, 질문을 포함하는 문서에는 보통 더 많은 질문이 포함되어 있다는 사실을 모델이 정확하게 포착한 것입니다. 모델은 텍스트를 모델링하고 있을 뿐입니다. 자신이 당신을 도와야 한다는 사실을 전혀 모릅니다.
v3.0: 실제로 도움이 되도록 가르치기
접근 방식 (2022): 좋은 답변의 예시 수천 개를 보여주고 (미세 조정 (fine-tuning)), 그 다음 인간의 '취향'을 가르칩니다:
- 모델이 동일한 프롬프트에 대해 여러 답변을 작성합니다.
- 사람이 그 답변들의 순위를 매깁니다.
- 이러한 순위를 예측하도록 두 번째 모델을 훈련시킵니다. 이제 인간의 선호도를 대신할 자동화된 대리인이 생겼습니다.
- 메인 모델이 이 모델로부터 높은 점수를 받도록 훈련시킵니다.
그것이 바로 **RLHF (Reinforcement Learning from Human Feedback, 인간 피드백 기반 강화학습)**입니다. 3단계가 존재하는 이유는 순전히 비용 때문입니다. 수백만 개의 답변을 평가하도록 인간에게 비용을 지불할 수는 없지만, 수천 개를 평가하도록 비용을 지불한 뒤 그들의 취향을 모방하도록 무언가를 훈련시킬 수는 있기 때문입니다.
여러분의 직관을 재조정해야 할 수치가 있습니다. 1.3B (13억) 파라미터의 정렬된 (aligned) 모델이 정렬되지 않은 175B (1,750억) 파라미터의 GPT-3보다 인간 평가자들에게 더 선호되었습니다. 정렬 (Alignment)이 100배의 크기 증가를 이긴 것입니다.
v4.0: RAG: 책을 건네주기
접근 방식: 모델에게 기억하라고 요구하는 것을 멈추십시오. 질문이 들어올 때 정보를 찾아보고 이를 프롬프트 (prompt)에 붙여넣으십시오.
이는 폐쇄형 시험 (closed-book exam)이 오픈북 시험 (open-book exam)으로 변하는 것과 같습니다. 폐쇄형 시험을 치르는 학생은 모든 것을 암기해야 하고, 일부를 잘못 기억할 수도 있으며, 특정 사실이 몇 페이지에서 나왔는지 말할 수 없고, 여러분의 회사 핸드북을 본 적도 없을 것입니다. 관련 페이지를 건네주면, 그들이 실제로 잘하는 영역인 추론 (reasoning)과 명확한 글쓰기를 그대로 활용하면서도 네 가지 문제 모두가 한꺼번에 개선됩니다.
INDEX (한 번 수행 후, 계속 업데이트 유지)
docs → chunks로 분할 → 각 chunk를 임베딩 (embed) → 검색 가능한 인덱스 (index)
...
이러한 청크 (chunk) 임베딩은 v0.3에서 사용된 것과 정확히 같은 개념이며, 단지 더 발전했을 뿐입니다. 당시에는 단일 단어를 매핑하여 유사한 단어들이 서로 가까이 위치하게 했습니다. 이제는 전체 구절을 매핑하여 유사한 의미가 서로 가까이 위치하게 합니다. 여러분은 키워드를 매칭하는 것이 아니라, 의미의 지도 위에서 위치를 매칭하는 것입니다.
댓글을 통해 바라는 점이 하나 있습니다. 만약 위 내용 중 틀린 부분이 있다면 꼭 말씀해 주세요. 무언가를 구축하고 3주가 지난 뒤에 발견하는 것보다 여기서 바로 교정받는 것이 훨씬 좋습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기