한 줄 정의

어텐션의 세 벡터 — 찾는 것(Q), 이름표(K), 내용물(V)


1. 비유로 이해하기

도서관에서 책을 찾는 장면이다.

Q (Query, 검색어)   : "공룡에 대해 알고 싶어"      ← 내가 원하는 것
K (Key, 책등 제목)  : 각 책 옆면에 붙은 제목        ← 훑어보는 이름표
V (Value, 내용)     : 책을 펼쳤을 때 나오는 글      ← 실제로 얻는 것
검색어를 들고 책등 제목을 훑어 점수를 매기고 그 비율만큼 책 내용을 섞어 오는 구조가 어텐션이며, 그것이라는 대명사가 사과의 뜻을 85퍼센트 흡수하는 과정도 같다
그림 1. 한 권만 고르는 게 아니라, 비율대로 섞어 온다

순서는 이렇다.

  1. 검색어(Q)를 들고 서가를 훑는다
  2. 책들의 제목(K)과 하나하나 맞춰 본다 → 얼마나 맞는지 점수를 매긴다
  3. 점수를 비율로 바꾼다 → 『공룡백과』 70%, 『파충류』 20%, 『요리책』 1%
  4. 그 비율만큼 각 책의 내용(V)을 섞어서 가져온다

3번이 바로 소프트맥스다.

그리고 여기서 중요한 게 하나 있다. 한 권만 고르는 게 아니라 여러 권을 비율대로 섞는다. 공룡백과를 70%, 파충류 책을 20%만큼 겹쳐 읽는 셈이다.

K와 V를 왜 나눠 놨을까? 책등 제목과 책 내용은 다르기 때문이다. 제목은 찾기 좋게 짧게 적혀 있고, 내용은 실제로 쓸모 있는 정보다. 찾는 용도(K)와 쓰는 용도(V)를 분리한 것이 이 구조의 핵심 아이디어다.


2. 왜 필요한가

무슨 문제를 푸는가

"민수가 사과를 떨어뜨렸는데, 그것이 굴러갔다."

“그것”이 무엇인지 우리는 안다. 사과다. 민수가 굴러간 게 아니다.

그런데 컴퓨터에게 “그것”이라는 토큰은 그냥 숫자 뭉치다. 앞의 어떤 단어를 가리키는지 알 방법이 없다. 어텐션이 이 문제를 이렇게 푼다.

"그것"의 Q: "나는 앞의 명사 중 무언가를 가리키는 대명사야.
             굴러갈 수 있는 물체를 찾아."
                        ↓ 각 단어의 K와 비교
민수의 K:    "사람, 주어"             → 점수 낮음  (0.05)
사과의 K:    "물체, 둥글고 작음"       → 점수 높음  (0.85)
떨어뜨의 K:  "동사, 행위"             → 점수 낮음  (0.10)
                        ↓ 소프트맥스
"그것"의 새 임베딩 = 0.85×사과V + 0.10×떨어뜨V + 0.05×민수V

“그것”의 벡터 안에 사과의 의미가 85% 섞여 들어간다. 문맥을 이해한다는 게 바로 이것이다.

임베딩은 문맥 없는 기본 뜻이다. 어텐션을 거치면 그 숫자들이 문맥에 맞게 갱신된다. 그리고 이 과정이 수십 층 반복된다.

셋 다 같은 곳에서 나온다

각 토큰의 임베딩 하나에 행렬 세 개를 곱해서 Q, K, V를 만든다.

Q = embedding @ W_q    # (768,) × (768, 64) → (64,)
K = embedding @ W_k
V = embedding @ W_v

같은 단어에서 출발했는데 곱하는 행렬이 달라서 셋이 서로 다른 벡터가 된다. 하나의 단어가 세 가지 역할을 동시에 맡는 것이다.

계산은 네 줄이다

                    ┌   Q · Kᵀ   ┐
Attention = softmax │ ───────── │ · V
                    └    √d_k    ┘
단계 하는 일 그릇 모양
Q · Kᵀ 모든 단어쌍의 관련도 점수 행렬 (n × n)
÷ √d_k 점수 크기 조절 행렬 (n × n)
softmax 점수 → 확률 (각 행의 합 = 1) 행렬 (n × n)
× V 확률만큼 내용물 섞기 행렬 (n × d)
def attention(Q, K, V):
    d_k = K.shape[-1]
    scores = Q @ K.T / np.sqrt(d_k)   # 점수 + 크기 조절
    weights = softmax(scores)          # 확률로
    return weights @ V                 # 비율대로 섞기

÷√d_k가 왜 있을까 — 스케일러의 원리

임베딩 차원이 768이면 Q·K 값이 아주 커진다. 그 상태로 소프트맥스에 넣으면 이렇게 된다.

점수가 작을 때  [2, 1, 0.5]    → softmax → [0.6, 0.2, 0.1]   부드럽다
점수가 클 때    [20, 10, 5]    → softmax → [1.0, 0.0, 0.0]   한 곳만 본다

한 단어만 100% 보고 나머지를 완전히 무시하면 학습이 안 된다. 그래서 √d_k로 나눠 적당한 크기로 되돌린다.

숫자들의 크기를 맞춰 주는 이 작업이 스케일러가 하는 일과 같은 원리다. 이 방식의 정식 이름이 Scaled Dot-Product Attention인 이유가 여기 있다.

KV 캐시 — 에이전트 비용의 핵심

하네스 루프를 돌 때마다 대화 전체를 처음부터 다시 보낸다. 그런데 이미 계산한 K와 V는 바뀌지 않는다. 그래서 저장해 두고 재사용한다. 이게 KV 캐시다.

1번째 턴:  [시스템 프롬프트 + 도구 설명]  → K,V 계산 (비싸다)
2번째 턴:  [같은 앞부분] + 새 질문
           └─ 캐시에서 꺼내 쓴다 ─┘   └ 이것만 계산

API의 프롬프트 캐싱 기능이 바로 이것이다. 여기서 실무 요령이 하나 나온다.

프롬프트를 짤 때 안 바뀌는 것을 앞에, 바뀌는 것을 뒤에 둔다. 앞부분이 고정돼야 캐시가 먹힌다.

컨텍스트가 길수록 왜 비싼가 — n² 문제

Q · Kᵀ모든 단어가 모든 단어와 짝지어 비교하는 계산이다.

토큰 1,000개  →  100만 번 비교
토큰 2,000개  →  400만 번 비교   (2배가 아니라 4배)
토큰 10,000개 →  1억 번 비교

컨텍스트를 2배 늘리면 계산은 4배가 된다. 긴 컨텍스트가 비싸고 느린 근본 이유이고, 컨텍스트 관리가 에이전트 개발의 핵심 과제인 이유다.

멀티헤드 어텐션

Q/K/V를 한 세트만 쓰지 않고 여러 세트를 동시에 돌린다. 보통 12~96개다.

헤드 1: 문법 관계에 주목 (주어-동사)
헤드 2: 대명사가 가리키는 대상에 주목
헤드 3: 멀리 떨어진 단어 관계에 주목
  ...
→ 전부 이어붙여서 사용

한 명이 책을 찾는 게 아니라 사서 여러 명이 각자 다른 기준으로 찾아와 합치는 것과 같다.


3. 어디서 만났나

이 용어는 수업에서 정식으로 다루기 전에 따로 정리한 것이다.

다만 7회차에서 “컨텍스트가 길면 왜 비싼가”라는 질문을 만났는데, 그 답이 위의 n² 문제다. 토큰을 줄이라는 조언의 바닥에 이 계산이 있었다.

7회차 — 에이전트, MCP, 스킬 — 범용 AI를 내 전용 조수로

6회차의 데이터베이스와도 이어진다. WHERE user = '민수'가 Q/K/V의 조상 격이기 때문인데, 아래 4번에서 이어서 본다.

6회차 — 데이터베이스, 서비스의 기억을 어디에 어떤 모양으로 둘까


4. 헷갈리는 개념

이 용어 비슷하지만 다른 것 차이
Q/K/V 어텐션 어텐션은 구조의 이름, Q/K/V는 그 구조를 이루는 세 벡터
Q/K/V 트랜스포머 더 위층이다. 트랜스포머 ⊃ 어텐션 ⊃ Q/K/V. 트랜스포머는 어텐션을 여러 층 쌓아 만든 모델 구조 전체를 가리킨다
어텐션 RAG 검색 어텐션은 모델 , RAG는 모델 . 아래 5번에서 자세히
Q/K/V DB의 Key-Value 이름이 여기서 왔다. DB는 정확히 일치하는 행만 가져오고, 어텐션은 모든 행을 비율대로 섞는다

이름의 뿌리가 데이터베이스라는 게 재미있다. WHERE user = '민수'를 보면 검색 조건 '민수'가 Q, 열 user가 K, 열 fact가 V에 해당한다. 어텐션은 말랑말랑한 데이터베이스 조회인 셈이다. DB는 맞거나 안 맞거나 둘 중 하나지만, 어텐션은 “85% 맞음”이 가능하다.


5. 많이들 오해하는 지점

ㄱ. “어텐션이 가장 관련 있는 단어 하나를 골라낸다”

고르지 않는다. 전부를 비율대로 섞는다.

도서관 비유로 돌아가면, 한 권만 빌려 오는 게 아니라 공룡백과 70% + 파충류책 20% + 나머지를 겹쳐 읽는 것이다. “그것”의 경우도 사과만 가져온 게 아니라 0.85×사과 + 0.10×떨어뜨 + 0.05×민수를 섞었다.

이 차이가 중요한 이유는, 그래서 애매한 문맥도 처리할 수 있기 때문이다. 하나만 골랐다면 애매할 때 틀릴 수밖에 없다.

ㄴ. “어텐션이랑 RAG 검색이 결국 같은 것 아닌가”

둘 다 “관련 있는 걸 찾아온다”라서 헷갈리는데, 층이 완전히 다르다.

  RAG 검색 어텐션
어디서 모델 (내 코드) 모델 (매 층마다)
대상 문서 수천 개 지금 문맥의 토큰들
결과 상위 3개만 골라온다 전부를 비율대로 섞는다
누가 짜나 내가 짠다 학습으로 저절로

어텐션은 모델 안의 검색, RAG는 모델 밖의 검색이라고 보면 된다.

ㄷ. “Q, K, V가 각각 다른 데이터다”

세 글자로 나뉘어 있으니 서로 다른 데서 온 것처럼 보인다. 그렇지 않다. 셋 다 같은 단어의 임베딩 하나에서 나온다. 곱하는 행렬(W_q, W_k, W_v)만 다를 뿐이다.

한 사람이 상황에 따라 “찾는 사람 · 이름표 · 내용물” 세 역할을 동시에 맡는다고 생각하면 된다. 문장 안의 모든 단어가 각자 이 셋을 전부 갖고 있고, 서로를 훑는다.


6. 관련 용어

어텐션 · 트랜스포머 · 임베딩 · 소프트맥스 · 토큰 · 벡터 · 행렬 · SQLite