17장. 문맥이라는 문제 — RNN에서 어텐션으로
이 장의 질문: 문장 속 각 단어의 의미를, 멀리 떨어진 단어까지 참조해서 어떻게 계산하는가? 순서대로 읽는 접근(RNN)의 시도와 좌절을 통해, 현대 AI를 만든 아이디어 — 어텐션 — 가 왜 그런 모양일 수밖에 없는지를 이해한다.
전제: 3장(내적=닮음), 10장(민감도의 곱), 16장(임베딩).
첫 시도: 사람처럼 순서대로 읽기
문맥을 다루는 가장 자연스러운 발상은 사람의 독서를 흉내내는 것이다 — 왼쪽부터 한 단어씩 읽으며, 지금까지 읽은 내용의 요약을 머릿속에 유지하기.
순환 신경망(RNN)이 정확히 이것이다. 요약을 담는 벡터
읽는 법: 새 요약(
그리고 두 개의 벽에 부딪혔다.
벽 1: 먼 기억이 죽는다. "내가 어릴 적 파리에서 자란 덕분에, 어른이 되어서도 유창하게 하는 언어는 ___"를 생각하라. 빈칸을 맞추려면 30 단어 전의 "파리"가 필요하다. 그런데 학습 신호가 "파리"까지 도달하려면 역전파가 30단계의 갱신을 거슬러야 하고 — 10장에서 배운 그대로 — 민감도 30개의 곱은 소실되거나 폭발한다. RNN은 구조적으로 건망증 환자다. 은닉 상태에 "지울 것과 간직할 것을 배우는 게이트"를 단 개량형(LSTM, GRU)이 기억 수명을 크게 늘렸고 한 시대를 지배했지만, 근본 구조 — 모든 과거를 고정 크기 벡터 하나에 욱여넣고 단계마다 변환을 통과시키는 것 — 의 한계는 남았다.
벽 2: 병렬화가 불가능하다.
발상의 전환: 요약하지 말고, 직접 바라보라
두 벽의 공통 원인을 짚어 보자 — 정보가 이웃한 단계들을 사슬처럼 통과해서만 전달된다는 것. 먼 단어의 정보는 긴 사슬을 지나며 죽고(벽 1), 사슬은 직렬이라 느리다(벽 2).
그렇다면 사슬을 끊어 버리면 어떤가. 모든 단어가 모든 단어를 직접 바라보게 하라. "언어는"이 30단계 전달을 기다릴 게 아니라, "파리"를 한 걸음에 참조하게 하는 것이다.
이것이 어텐션(attention)이다. 구체적 절차를 보자. 문맥 속에서 갱신하고 싶은 단어(16장의 마지막 문제!)를 하나 잡는다 — 예컨대 "나는 강가 은행에 앉아"의 "은행". 이 단어의 새 벡터를 이렇게 만든다.
- 관련도 측정: "은행"의 벡터와 문장 내 모든 단어 벡터의 내적(3장의 "닮음의 측정"이 드디어 주인공이 된다)을 계산한다 — "강가"와는 높고, "나는"과는 낮게 나올 것이다.
- 가중치화: 그 점수들에 소프트맥스(5장)를 씌워 합이 1인 주목 가중치로 만든다 — 예: 강가 0.6, 앉아 0.25, 나는 0.1, …
- 가중 평균: 모든 단어의 벡터를 이 가중치로 섞는다. 결과 — "은행" 자리의 새 벡터는 "강가" 성분을 듬뿍 머금은, 문맥이 반영된 벡터다.
이 세 단계에는 관용적 이름이 붙어 있다. 정보를 찾는 쪽의 벡터가 쿼리(query, "은행"의 질문), 검색 대상이 되는 각 단어의 벡터가 키(key, 색인), 실제로 가져오는 내용이 밸류(value)다. 도서관 비유 그대로다 — 질문(Q)을 들고 서가의 색인(K)들과 대조해 관련도를 매기고, 관련도만큼 책 내용(V)을 섞어 온다. 실제 구현에서는 임베딩에서 Q, K, V를 각각 학습되는 행렬로 변환해 만든다 — "무엇을 물을지, 무엇으로 색인될지, 무엇을 건네줄지"를 데이터가 배우게 하는 것이다. 수식 한 줄로 쓰면:
(
두 벽이 어떻게 무너졌는지 확인하라. 거리가 사라졌다 — 30 단어 전이든 3000 단어 전이든 모든 참조는 한 단계다. 민감도의 긴 곱셈 사슬도 없다. 그리고 완전히 병렬이다 —
여러 눈으로 보기, 그리고 순서의 회복
실전 어텐션에는 마무리 부품이 둘 더 붙는다.
멀티헤드(multi-head): 단어 사이의 관계는 한 종류가 아니다 — "은행"은 "강가"와는 의미로, "앉아"와는 문법(주어-서술 구조)으로 얽힌다. 그래서 Q·K·V 변환을 여러 벌(예: 8~64개의 "헤드") 두어 각자 다른 관점의 어텐션을 병렬로 수행하고 결과를 이어 붙인다. 13장에서 필터를 64종 두어 여러 패턴을 동시에 찾던 것과 같은 사상이다. 실제 학습된 모델을 열어 보면 특정 헤드가 대명사-선행사를 잇고, 다른 헤드가 인접 단어를 보는 식의 분업이 관찰된다.
위치 인코딩: 어텐션에는 치명적 맹점이 하나 있다 — 가중 평균은 순서를 모른다. "개가 사람을 물었다"와 "사람이 개를 물었다"의 단어 집합은 같으므로, 순서 정보를 따로 주입하지 않으면 어텐션은 둘을 구별하지 못한다. RNN은 순서대로 읽으니 공짜로 얻던 것을, 어텐션은 명시적으로 넣어야 한다. 방법은 각 위치마다 "위치 표식" 벡터를 임베딩에 더하거나(고전적 방식), Q·K 벡터를 위치에 비례한 각도로 회전시켜 내적이 상대 거리를 반영하게 만드는 것(RoPE — 현대 LLM의 주류)이다. 세부는 달라도 목적은 하나 — "몇 번째 단어인가"를 벡터에 새기는 것이다.
이렇게 완성된 그림을 정리하자. 16장의 임베딩이 각 단어의 사전적 의미를 놓으면, 어텐션이 문장 전체를 한꺼번에 참조해 각 단어의 벡터를 그 문맥에서의 의미로 갱신한다 — "은행"의 다의어 문제가 풀렸다. 거리에 무관하고, 병렬이고, 무엇을 주목할지조차 학습된다.
남은 질문은 하나다. 이 어텐션을 부품 삼아 완성된 건물은 어떻게 짓는가 — 몇 번을 겹치고, 사이에 무엇을 끼우고, 어떻게 학습시키는가. 그 답이 2017년의 논문 제목이자 다음 장의 주인공, "Attention Is All You Need" — Transformer다.
핵심 요약
- RNN은 "요약을 들고 순서대로 읽기" — 시간의 가중치 공유는 우아했지만, 먼 기억의 소실(민감도의 곱)과 직렬성(병렬화 불가)이라는 두 벽에 막혔다.
- 어텐션은 사슬을 끊고 모든 단어가 모든 단어를 직접 참조한다: 쿼리·키의 내적으로 관련도 → 소프트맥스로 가중치 → 밸류의 가중 평균. Q/K/V 변환 자체가 학습된다.
- 거리 소멸 + 완전 병렬이 대가로 지불하는 것은 길이 제곱의 비용. 멀티헤드는 여러 관계를 동시에, 위치 인코딩은 가중 평균이 잃은 순서를 회복한다.
- 임베딩(사전적 의미) + 어텐션(문맥 갱신) — 언어 이해의 두 기둥이 모두 섰다.
스스로 점검
- RNN의 두 벽(기억, 병렬성)이 모두 "정보가 사슬을 통과한다"는 하나의 원인에서 나옴을 설명해 보라.
- 단어 벡터가
일 때, 를 쿼리로 한 어텐션 가중치(소프트맥스 전 점수)를 내적으로 계산해 보라. 의 새 벡터에는 누구 성분이 많이 섞이는가? - 위치 인코딩을 빼면 "개가 사람을 물었다"에서 무슨 일이 생기는지, 가중 평균의 성질로 설명해 보라.
- 문장 길이를 10배로 늘리면 어텐션 계산량은 몇 배가 되는가? 이것이 LLM 제품의 어떤 제약으로 나타나는가?
다음 장에서
부품이 다 모였다 — 임베딩, 어텐션, 잔차 연결(11장), 층 정규화(11장), 소프트맥스 출구(5장). 이들을 조립한 단 하나의 설계도가 지난 몇 년간 언어·이미지·소리·단백질 구조까지 집어삼켰다. Transformer를 블록 단위로 완전히 해부하고, GPT가 정확히 무엇인지를 그 위에서 정의한다.