3-7의 순서 모델은 지나온 모든 것을 은닉 상태 하나에 눌러 담고 한 칸씩 걸었다. 어텐션은 발상을 바꾼다. 필요할 때마다 앞의 모든 칸을 다시 찾아보고, 관련 있는 칸에 더 많이 주의를 준다. 질의(Q)·키(K)·값(V)의 숫자를 손으로 따라가고, 이 부품을 쌓은 트랜스포머가 오늘날 언어 모델의 뼈대가 된 이유와 그 비용까지 본다.
인코더–디코더 RNN은 문장 전체를 고정 길이 벡터 하나에 담고, 칸을 하나씩 차례로 처리한다. 문장이 길어지면 두 가지가 문제가 된다.
"초파리가 사과를 먹었다"를 "The fly ate the apple"로 옮긴다. 영어 단어 하나를 만들 때마다 한국어 단어들에 주의를 나눠 준다. 굵은 선일수록 주의가 크다.
한국어는 "초파리가 · 사과를 · 먹었다", 영어는 "The fly · ate · the apple" 순서다. 동사의 자리가 다르다. 그래서 "ate"를 만들 때는 맨 끝의 "먹었다"를 크게 봐야 한다. 이 그림의 주의 값은 설명을 위해 정한 숫자다. 실제 번역 모델은 이런 대응을 학습으로 스스로 찾으며, Bahdanau 등은 학습된 주의가 사람의 직관과 잘 맞는다고 보고했다 [R1]. 주의는 모두 0~1이고 합이 1이다(소프트맥스).
어텐션(Q, K, V) = softmax(Q·Kᵀ / √dk) · VVaswani 외, 2017
| 기호 | 도서관에서는 | 신경망에서는 |
|---|---|---|
| Q 질의 | 내가 찾는 것을 적은 쪽지 | 지금 칸이 "무엇이 필요한가"를 나타낸 벡터. 입력 × WQ |
| K 키 | 책마다 붙은 색인 카드 | 각 칸이 "나는 이런 정보다"를 나타낸 벡터. 입력 × WK |
| V 값 | 책의 실제 내용 | 각 칸이 실제로 건네줄 정보. 입력 × WV |
| Q·K | 쪽지와 카드가 얼마나 맞나 | 두 벡터의 내적. 방향이 비슷할수록 크다 |
| ÷ √dk | — | 벡터가 길어질수록 내적이 커져 소프트맥스가 한 칸에만 쏠리는 것을 막는다 [R2] |
| softmax | 읽을 시간을 책마다 나눠 주기 | 점수를 합이 1인 주의로 바꾼다 |
| × V | 읽은 시간만큼 내용을 섞어 정리 | 주의를 가중치로 값들을 더한다. 이것이 출력이다 |
섹션 3에서는 질문과 책이 따로 있었다. 셀프 어텐션에서는 문장의 모든 단어가 질의이자 키이자 값이다. 단어마다 다른 모든 단어에 주의를 나눠 준다.
단어 벡터는 [동물, 음식, 동작, 지시어] 네 칸으로 손으로 정했다. 질의 변환 WQ는 "지시어는 음식을 찾고, 동작은 동물을 찾는다"가 되도록 정했다. 키·값 변환은 그대로 둔다. 실제 트랜스포머는 단어 벡터도, WQ·WK·WV도 모두 학습으로 정하고, 폭도 수백 칸이다. 계산식은 이 예와 똑같다. 코드 1이 같은 숫자를 낸다.
한 문장에는 관계가 여러 겹 있다. "누가 먹었나"와 "무엇을 먹었나"는 서로 다른 질문이다. 헤드마다 다른 WQ·WK·WV를 써서 다른 관계를 보고, 결과를 이어 붙인다.
어텐션은 모든 칸을 한꺼번에 비교한다. 그래서 단어 순서를 섞어도 각 단어의 결과가 똑같다. 순서를 알려 주려면 자리마다 다른 "위치 부호"를 단어 벡터에 더한다.
원 논문은 위치 pos의 짝수 칸에 sin(pos / 100002i/d), 홀수 칸에 cos(…)을 넣었다 [R2]. 앞쪽 칸은 빠르게, 뒤쪽 칸은 느리게 출렁여서 자리마다 다른 무늬가 생긴다. 시계의 초침·분침·시침을 함께 보면 시각이 하나로 정해지는 것과 같다. 위치 부호를 학습으로 정하는 방법도 널리 쓴다. 코드 2의 작은 트랜스포머는 학습하는 위치 임베딩을 썼다.
트랜스포머의 블록 하나는 멀티헤드 어텐션과 피드포워드 신경망(3-2의 MLP)으로 이루어진다. 각각에 입력을 그대로 더하는 지름길(잔차 연결)과 정규화를 붙이고, 이 블록을 여러 층 쌓는다.
같은 블록도 "어느 칸이 어느 칸을 볼 수 있나"(마스크)를 바꾸면 쓰임이 달라진다.
트랜스포머가 널리 쓰이게 된 이유는 세 가지로 정리된다. 그만큼의 비용도 있다. 가장 큰 비용은 길이의 제곱으로 늘어나는 주의 계산이다.
3-7 코드 2와 같은 과제(모든 칸이 ±1, 정답은 첫 칸)와 같은 학습 설정(Adam 0.005, 30에폭, 학습 2,000개·시험 1,000개, 시드 2개). 트랜스포머는 셀프 어텐션 블록 하나(폭 16, 헤드 2개)와 학습하는 위치 임베딩을 썼다. "첫 칸에 주는 주의"는 모든 칸이 첫 칸에 준 주의의 평균이다.
이 편은 트랜스포머의 구조까지 다룬다. 그 구조로 글·그림을 만들어 내는 생성 모델(대규모 언어 모델의 사전 학습, 지시 따르기 학습, 확산 모델 등)은 이 시리즈의 범위 밖이다. 다음 편들(3-4 음성, 3-6 시계열·주가, 3-5 텍스트)은 데이터를 숫자로 바꾸는 과정에 집중한다.
두 코드 모두 Colab에 기본으로 설치된 라이브러리만 쓴다. "노트북(.ipynb) 내려받기" 후 Colab에서 파일 → 노트북 업로드로 열거나, 복사해서 새 노트북 칸에 붙여 넣는다.
도서관 예시, 다섯 단어 셀프 어텐션, 헤드 두 개, 순서 섞기와 위치 부호를 같은 숫자로 계산한다. 내 데이터로 바꾸려면 BOOK_K·BOOK_V·QUERIES 또는 단어 벡터 X를 바꾼다.
3-7에서 LSTM이 긴 길이에서 실패한 과제를 셀프 어텐션 블록 하나짜리 트랜스포머로 다시 푼다. 학습한 트랜스포머가 정답이 있는 첫 칸에 주의를 얼마나 주는지도 잰다. 섹션 9 아래의 표가 이 출력에서 바로 만들어진다.
ChatGPT, Qwen, Claude 같은 AI 도우미에 붙여 넣는 프롬프트다. "복사"를 누르면 프롬프트 뒤에 고른 코드가 함께 붙는다. 〔 〕 안을 내 상황으로 바꿔 쓰면 된다.
AI의 답은 출발점일 뿐이다. 제안된 논문·수치·라이브러리 함수는 반드시 원문과 공식 문서로 확인한다. 공모전·논문에 AI 도움을 받았다면 주최 측과 학술지의 규정에 따라 사용 사실과 범위를 밝힌다.
본문의 노란 점선 밑줄과 같은 사전이다. 시리즈 전체에서 같은 표기를 쓴다. 섹션 이름을 누르면 처음 나온 곳으로 간다.
비유는 이해의 첫걸음이지만 오해의 씨앗도 된다. 초파리·뇌 비유에는 강도를 표시했다. 직접 실제로 같은 일을 한다는 근거가 있음 · 부분 일부 성질만 닮음 · 없음 대응하는 것이 알려지지 않음
| 개념 | 일상 비유 | 초파리·뇌 비유 | 비유가 틀리는 지점 |
|---|---|---|---|
| 어텐션 | 시험 공부할 때 중요한 쪽에 형광펜 칠하기 | 부분 사람의 선택적 주의(시끄러운 곳에서 한 목소리에 집중하기) | 뇌의 주의는 감각·의도·피로 등이 얽힌 현상이다. 모델의 어텐션은 내적과 소프트맥스로 정한 가중 평균일 뿐이다 |
| Q·K·V | 도서관의 질문 쪽지·색인 카드·책 내용 | 없음 | 도서관은 책 한 권을 골라 오지만, 어텐션은 모든 책을 비율대로 섞는다 |
| 소프트맥스 주의 | 읽을 시간을 책마다 나눠 주기 | 없음 | 시간은 아무리 나눠도 다 쓰지만, 주의 0.01인 칸도 계산은 빠짐없이 한다(그래서 n²이 든다) |
| 멀티헤드 | 같은 문서를 편집자 여러 명이 다른 관점으로 읽기 | 없음 | 헤드의 "관점"은 사람이 정하지 않는다. 학습 뒤 해석해 보면 뚜렷한 역할이 보이지 않는 헤드도 많다 |
| 위치 부호 | 시계의 초침·분침·시침을 함께 보면 시각이 정해진다 | 없음 | 시계는 하루가 지나면 되돌아오지만, 위치 부호는 학습한 길이 안에서만 익숙하다 |
| 잔차 연결 | 고친 원고 옆에 원본을 늘 함께 붙여 두기 | 없음 | 원본을 "그대로 더한다"는 점이 핵심이다. 고친 정도가 작으면 원본이 거의 그대로 다음 층으로 간다 |
| 마스크 (GPT형) | 답안지를 가리고 앞 문제만 보며 다음 문제 풀기 | 없음 | 학습할 때는 모든 칸을 한꺼번에 계산한다. 가리는 것은 "볼 수 있는 범위"뿐이다 |
E-1 저자 소개 · E-2 학술 레퍼런스 · E-3 그림 참고 자료
강사, 실무 OJT 담당자, 튜터를 위한 운영 안내다. 시간은 예상치이므로 실제 수업에 맞춰 조정한다.
| 대상 | 3-7을 마친 대학생·직장인. 언어 모델이 "어떤 부품으로 만들어졌는지" 알고 싶은 실무자 |
|---|---|
| 선수 지식 | 벡터의 내적(같은 자리끼리 곱해 더하기), 3-2의 소프트맥스와 MLP, 3-7의 인코더–디코더 |
| 학습 목표 | ① 어텐션 식 softmax(QKᵀ/√d_k)V를 숫자로 계산한다 ② 셀프 어텐션·멀티헤드·위치 부호가 각각 왜 필요한지 설명한다 ③ 트랜스포머가 기반이 된 이유와 n² 비용을 함께 설명한다 |
| 예상 시간 | 읽기 45~55분 · 애니메이션 시연 25분 · Colab 실습 30분 (코드 1 10분, 코드 2 실행 8분 + 해석 12분) |
도입 5분(섹션 1 병목) → 섹션 2·3 도서관 15분 → 섹션 4·5 10분 → 섹션 6 순서 섞기 10분 → 섹션 9 n²과 코드 2 결과 5분 → 확인 문제 5분.
섹션 1·3 15분 → 섹션 8 세 구조를 업무 사례(분류·요약·번역)에 연결 20분 → 섹션 9 비용 계산(우리 문서 길이로) 15분 → 코드 2 실행·해석 25분 → 프롬프트 카드 15분.
입문자는 섹션 1·2·3·9만. 중급자는 섹션 3의 결과 벡터를 손으로 계산하게 한 뒤 코드 1과 대조하고, 섹션 7의 4d² + 4d를 직접 유도하게 한다.
| 섹션 | 멈춰서 물어볼 질문 | 조작 팁 |
|---|---|---|
| 1 남은 문제 | "40단어 문장을 8칸 벡터에 담으면 단어 하나당 몇 칸일까?" | 5 → 40단어로 바꿔 숫자 변화를 본다 |
| 2 어텐션 | "ate를 만들 때 왜 맨 끝 단어를 볼까?" | "ate" 버튼에서 멈춘다 |
| 3 Q·K·V | "주의가 가장 큰 책만 가져오면 안 될까?" | "둘 다 궁금하다"에서 결과가 [5.5, 5.5]로 섞이는 것을 본다 |
| 4 셀프 어텐션 | "'그것은'은 무엇을 가리킬까? 모델은 어떻게 알았을까?" | 그것은 → 달았다 순서로 눌러 손으로 정한 규칙의 한계도 본다 |
| 5 멀티헤드 | "헤드를 8개로 늘리면 파라미터가 8배가 될까?" | 모델 폭 512에서 파라미터 숫자를 확인한다 |
| 6 위치 정보 | "순서를 섞어도 결과가 같다면 무엇이 문제일까?" | 위치 부호 없음 → 섞은 순서 → 더하기 순서로 누른다 |
| 7 블록 | "블록 파라미터의 대부분은 어텐션일까, 피드포워드일까?" | 기본형에서 "피드포워드의 몫"을 읽는다 |
| 8 인코더·디코더 | "GPT형은 왜 미래 칸을 가려야 할까?" | 디코더만을 눌러 마스크의 × 칸을 짚는다 |
| 9 기반과 한계 | "문서 길이가 2배가 되면 주의 계산은 몇 배가 될까?" | 4,096 → 32,768로 바꿔 메모리를 비교하고, 아래 실험표로 넘어간다 |
| 오해 | 바른 설명 | 보여 줄 장면 |
|---|---|---|
| 어텐션은 가장 중요한 단어 하나를 고른다 | 모든 단어를 비율대로 섞는다. 주의가 작은 단어도 결과에 들어간다 | 섹션 3 "둘 다 궁금하다" |
| 트랜스포머는 순서를 저절로 안다 | 위치 부호가 없으면 순서를 섞어도 결과가 같다 | 섹션 6 |
| 헤드마다 사람이 역할을 정해 준다 | 역할은 학습으로 생긴다. 이 페이지의 두 헤드는 설명을 위해 손으로 정했다 | 섹션 5와 그 아래 설명 |
| 트랜스포머가 RNN보다 모든 면에서 낫다 | 긴 연결과 병렬 계산에 강하지만, 길이의 제곱 비용이 들고 작은 데이터에서는 불리할 수 있다 | 섹션 9 |
| 주의 그림이 모델이 판단한 이유다 | 어디를 보고 계산했는지일 뿐, 판단이 옳은 이유를 보장하지 않는다 | 섹션 4의 "달았다" |
q·k = 2×2 + 0.4×0 = 4. 4 / √2 ≈ 2.828. 섹션 3의 책 A 점수와 같다.
주의 ≈ [0.238, 0.238, 0.525]. 결과 = 0.238×[10,0] + 0.238×[0,10] + 0.525×[6,6] ≈ [5.53, 5.53]. 코드 1의 출력은 [5.525, 5.525]다.
똑같다. 각 단어의 출력은 "다른 모든 단어와의 비교"로만 정해지고, 비교 대상의 집합은 순서와 상관없이 같기 때문이다. 코드 1에서 차이는 1e-16(계산 오차 수준)이었다.
W_Q·W_K·W_V·W_O 네 개가 각각 512 × 512, 편향 512개씩: 4 × 262,144 + 4 × 512 = 1,050,624개. 헤드 수를 바꿔도 헤드 폭이 줄 뿐 행렬 크기는 같아서 그대로다.
4배. (2n)² = 4n². 4,096² = 16,777,216개에서 8,192² = 67,108,864개가 된다.
코드 1에서 √d_k로 나누지 않으면 도서관 예시의 주의가 어떻게 바뀌는지 계산한다. 벡터를 10배로 키웠을 때 나누기의 효과가 어떻게 커지는지 두 문장으로 설명한다.
코드 2에서 트랜스포머의 위치 임베딩(AddPosition)을 빼고 다시 학습한다. 결과와 "첫 칸에 주는 주의"가 어떻게 바뀌는지 시드 3개 이상으로 보고하고, 섹션 6과 연결해 이유를 쓴다.
| 입문자 | 섹션 5·7은 건너뛰어도 흐름이 끊기지 않는다. 섹션 3의 도서관 하나만 확실히 손으로 계산해 본다 |
|---|---|
| 심화 | 섹션 9의 n² 비용을 줄이는 방법(구간을 나눠 보기, 저차원 근사 등)을 조사해 발표하게 한다. 조사한 논문은 원문으로 확인한다 |
| 더 배우기 | 안상선, 「비즈니스를 위한 데이터 과학」 강의안 (데이터 과학 전반) · STEP [K-디지털] 인공지능 자연어 처리 (3-5·3-8과 연결) · STEP [K-디지털] 핀테크 데이터 분석 기초 (3-6과 연결) |
| 강사용 자료 | 확인 문제의 채점 기준과 과제 예시 답안은 교육자용 정답 페이지 (3-8)에서 볼 수 있다 |
「3-8 어텐션·트랜스포머」 편을 끝까지 읽었어요. 연구실 식구들이 한마디씩 정리해 드립니다.