Paged attention: Transformer Self-Attention과 KV Cache의 기초

HanJu Han·2026년 4월 28일

Transformer Self-Attention과 KV Cache의 기초

Paged Attention을 이해하기 위해서는 먼저 Transformer의 Self-Attention 메커니즘KV Cache가 왜 필요한지를 정확히 알아야 합니다. 이것이 Paged Attention이 등장하게 된 가장 근본적인 이유이기 때문입니다.


1. Self-Attention이란 무엇인가?

정의

Self-Attention은 문장 내의 모든 단어(토큰)가 서로에게 얼마나 관련이 있는지를 계산하는 메커니즘입니다. 즉, 한 단어를 이해할 때 문장의 다른 단어들을 "얼마나 참고할지"를 가중치로 계산합니다.

왜 사용하는가?

RNN은 문장을 순차적으로 읽기 때문에 "멀리 떨어진 단어 간의 관계"를 잘 포착하지 못하고, 병렬 연산이 어렵습니다. Self-Attention은 모든 단어 쌍의 관계를 동시에(병렬로) 계산하여 이 문제를 해결합니다.


2. 수식과 계산 과정

Self-Attention의 핵심 수식은 다음과 같습니다:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

각 기호의 의미

  • QQ (Query): "내가 지금 누구를 찾고 있나?" (현재 토큰의 질문)
  • KK (Key): "나는 어떤 정보를 가지고 있나?" (모든 토큰의 식별자)
  • VV (Value): "나의 실제 내용은 무엇인가?" (모든 토큰의 실제 정보)
  • dkd_k: Key 벡터의 차원 (값이 클수록 softmax의 gradient가 작아지는 것을 방지하기 위해 dk\sqrt{d_k}로 나눔)

3. 예시 데이터로 하나하나 풀어보기

예시 문장

"나는 학교에 간다"

토큰화(간단히 단어별로): ["나는", "학교에", "간다"]

임베딩 차원을 4차원으로 가정하고, 각 토큰의 임베딩 벡터를 다음과 같이 정의합니다:

토큰임베딩 벡터 (4차원)
나는[1,0,1,0][1, 0, 1, 0]
학교에[0,1,1,0][0, 1, 1, 0]
간다[1,1,0,1][1, 1, 0, 1]

Step 1: Q, K, V 행렬 생성

가중치 행렬 WQ,WK,WVW_Q, W_K, W_V를 간단히 다음과 같이 가정합니다 (실제로는 학습됨):

WQ=[10011001],WK=[01100110],WV=[11100101]W_Q = \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 1 & 0 \\ 0 & 1 \end{bmatrix}, \quad W_K = \begin{bmatrix} 0 & 1 \\ 1 & 0 \\ 0 & 1 \\ 1 & 0 \end{bmatrix}, \quad W_V = \begin{bmatrix} 1 & 1 \\ 1 & 0 \\ 0 & 1 \\ 0 & 1 \end{bmatrix}

각 토큰별 Q, K, V 계산:

1) "나는" [1,0,1,0][1, 0, 1, 0]

  • Q1=[1,0,1,0]×WQ=[1×1+0×0+1×1+0×0,  1×0+0×1+1×0+0×1]=[2,0]Q_1 = [1, 0, 1, 0] \times W_Q = [1\times1+0\times0+1\times1+0\times0, \; 1\times0+0\times1+1\times0+0\times1] = [2, 0]
  • K1=[1,0,1,0]×WK=[1×0+0×1+1×0+0×1,  1×1+0×0+1×1+0×0]=[0,2]K_1 = [1, 0, 1, 0] \times W_K = [1\times0+0\times1+1\times0+0\times1, \; 1\times1+0\times0+1\times1+0\times0] = [0, 2]
  • V1=[1,0,1,0]×WV=[1×1+0×1+1×0+0×0,  1×1+0×0+1×1+0×1]=[1,2]V_1 = [1, 0, 1, 0] \times W_V = [1\times1+0\times1+1\times0+0\times0, \; 1\times1+0\times0+1\times1+0\times1] = [1, 2]

2) "학교에" [0,1,1,0][0, 1, 1, 0]

  • Q2=[0,1,1,0]×WQ=[0×1+1×0+1×1+0×0,  0×0+1×1+1×0+0×1]=[1,1]Q_2 = [0, 1, 1, 0] \times W_Q = [0\times1+1\times0+1\times1+0\times0, \; 0\times0+1\times1+1\times0+0\times1] = [1, 1]
  • K2=[0,1,1,0]×WK=[0×0+1×1+1×0+0×1,  0×1+1×0+1×1+0×0]=[1,1]K_2 = [0, 1, 1, 0] \times W_K = [0\times0+1\times1+1\times0+0\times1, \; 0\times1+1\times0+1\times1+0\times0] = [1, 1]
  • V2=[0,1,1,0]×WV=[0×1+1×1+1×0+0×0,  0×1+1×0+1×1+0×1]=[1,1]V_2 = [0, 1, 1, 0] \times W_V = [0\times1+1\times1+1\times0+0\times0, \; 0\times1+1\times0+1\times1+0\times1] = [1, 1]

3) "간다" [1,1,0,1][1, 1, 0, 1]

  • Q3=[1,1,0,1]×WQ=[1×1+1×0+0×1+1×0,  1×0+1×1+0×0+1×1]=[1,2]Q_3 = [1, 1, 0, 1] \times W_Q = [1\times1+1\times0+0\times1+1\times0, \; 1\times0+1\times1+0\times0+1\times1] = [1, 2]
  • K3=[1,1,0,1]×WK=[1×0+1×1+0×0+1×1,  1×1+1×0+0×1+1×0]=[2,1]K_3 = [1, 1, 0, 1] \times W_K = [1\times0+1\times1+0\times0+1\times1, \; 1\times1+1\times0+0\times1+1\times0] = [2, 1]
  • V3=[1,1,0,1]×WV=[1×1+1×1+0×0+1×0,  1×1+1×0+0×1+1×1]=[2,2]V_3 = [1, 1, 0, 1] \times W_V = [1\times1+1\times1+0\times0+1\times0, \; 1\times1+1\times0+0\times1+1\times1] = [2, 2]

정리된 Q, K, V 행렬

Q=[201112],K=[021121],V=[121122]Q = \begin{bmatrix} 2 & 0 \\ 1 & 1 \\ 1 & 2 \end{bmatrix}, \quad K = \begin{bmatrix} 0 & 2 \\ 1 & 1 \\ 2 & 1 \end{bmatrix}, \quad V = \begin{bmatrix} 1 & 2 \\ 1 & 1 \\ 2 & 2 \end{bmatrix}


4. Attention Score 계산 과정

Step 2: QKTQK^T 계산 (유사도 점수)

KT=[012211]K^T = \begin{bmatrix} 0 & 1 & 2 \\ 2 & 1 & 1 \end{bmatrix}

QKT=[2×0+0×22×1+0×12×2+0×11×0+1×21×1+1×11×2+1×11×0+2×21×1+2×11×2+2×1]=[024223434]QK^T = \begin{bmatrix} 2\times0+0\times2 & 2\times1+0\times1 & 2\times2+0\times1 \\ 1\times0+1\times2 & 1\times1+1\times1 & 1\times2+1\times1 \\ 1\times0+2\times2 & 1\times1+2\times1 & 1\times2+2\times1 \end{bmatrix} = \begin{bmatrix} 0 & 2 & 4 \\ 2 & 2 & 3 \\ 4 & 3 & 4 \end{bmatrix}

Step 3: dk\sqrt{d_k}로 나누기 (dk=2d_k = 2이므로 21.414\sqrt{2} \approx 1.414)

QKT2[01.4142.8281.4141.4142.1212.8282.1212.828]\frac{QK^T}{\sqrt{2}} \approx \begin{bmatrix} 0 & 1.414 & 2.828 \\ 1.414 & 1.414 & 2.121 \\ 2.828 & 2.121 & 2.828 \end{bmatrix}

Step 4: Softmax 적용 (행 단위)

첫 번째 행 [0,1.414,2.828][0, 1.414, 2.828]:

  • e0=1e^0 = 1, e1.4144.11e^{1.414} \approx 4.11, e2.82816.92e^{2.828} \approx 16.92
  • 합계: 1+4.11+16.92=22.031 + 4.11 + 16.92 = 22.03
  • Softmax: [1/22.03,4.11/22.03,16.92/22.03][0.045,0.187,0.768][1/22.03, 4.11/22.03, 16.92/22.03] \approx [0.045, 0.187, 0.768]

두 번째 행 [1.414,1.414,2.121][1.414, 1.414, 2.121]:

  • e1.4144.11e^{1.414} \approx 4.11, e1.4144.11e^{1.414} \approx 4.11, e2.1218.34e^{2.121} \approx 8.34
  • 합계: 4.11+4.11+8.34=16.564.11 + 4.11 + 8.34 = 16.56
  • Softmax: [4.11/16.56,4.11/16.56,8.34/16.56][0.248,0.248,0.504][4.11/16.56, 4.11/16.56, 8.34/16.56] \approx [0.248, 0.248, 0.504]

세 번째 행 [2.828,2.121,2.828][2.828, 2.121, 2.828]:

  • e2.82816.92e^{2.828} \approx 16.92, e2.1218.34e^{2.121} \approx 8.34, e2.82816.92e^{2.828} \approx 16.92
  • 합계: 16.92+8.34+16.92=42.1816.92 + 8.34 + 16.92 = 42.18
  • Softmax: [16.92/42.18,8.34/42.18,16.92/42.18][0.401,0.198,0.401][16.92/42.18, 8.34/42.18, 16.92/42.18] \approx [0.401, 0.198, 0.401]
softmax(QKT2)[0.0450.1870.7680.2480.2480.5040.4010.1980.401]\text{softmax}\left(\frac{QK^T}{\sqrt{2}}\right) \approx \begin{bmatrix} 0.045 & 0.187 & 0.768 \\ 0.248 & 0.248 & 0.504 \\ 0.401 & 0.198 & 0.401 \end{bmatrix}

Step 5: Attention Output 계산 (×V\times V)

Output=softmax()×V=[0.0450.1870.7680.2480.2480.5040.4010.1980.401]×[121122]\text{Output} = \text{softmax}(\cdots) \times V = \begin{bmatrix} 0.045 & 0.187 & 0.768 \\ 0.248 & 0.248 & 0.504 \\ 0.401 & 0.198 & 0.401 \end{bmatrix} \times \begin{bmatrix} 1 & 2 \\ 1 & 1 \\ 2 & 2 \end{bmatrix}

첫 번째 행 결과 (나는):

  • 첫 번째 값: 0.045×1+0.187×1+0.768×2=0.045+0.187+1.536=1.7680.045\times1 + 0.187\times1 + 0.768\times2 = 0.045 + 0.187 + 1.536 = 1.768
  • 두 번째 값: 0.045×2+0.187×1+0.768×2=0.09+0.187+1.536=1.8130.045\times2 + 0.187\times1 + 0.768\times2 = 0.09 + 0.187 + 1.536 = 1.813

두 번째 행 결과 (학교에):

  • 첫 번째 값: 0.248×1+0.248×1+0.504×2=0.248+0.248+1.008=1.5040.248\times1 + 0.248\times1 + 0.504\times2 = 0.248 + 0.248 + 1.008 = 1.504
  • 두 번째 값: 0.248×2+0.248×1+0.504×2=0.496+0.248+1.008=1.7520.248\times2 + 0.248\times1 + 0.504\times2 = 0.496 + 0.248 + 1.008 = 1.752

세 번째 행 결과 (간다):

  • 첫 번째 값: 0.401×1+0.198×1+0.401×2=0.401+0.198+0.802=1.4010.401\times1 + 0.198\times1 + 0.401\times2 = 0.401 + 0.198 + 0.802 = 1.401
  • 두 번째 값: 0.401×2+0.198×1+0.401×2=0.802+0.198+0.802=1.8020.401\times2 + 0.198\times1 + 0.401\times2 = 0.802 + 0.198 + 0.802 = 1.802

Output[1.7681.8131.5041.7521.4011.802]\text{Output} \approx \begin{bmatrix} 1.768 & 1.813 \\ 1.504 & 1.752 \\ 1.401 & 1.802 \end{bmatrix}


5. 시각화: Self-Attention 흐름도


6. Attention Score 해석

위 히트맵을 보면 다음과 같은 의미를 알 수 있습니다:

  • "나는"은 자기 자신(0.045)보다 "간다"(0.768)에 더 높은 가중치를 줍니다. → '나는'이라는 주어가 '간다'라는 동사와 가장 밀접하게 연결됨
  • "학교에""간다"(0.504)에 가장 높은 가중치를 줍니다. → '학교에'라는 부사어가 '간다'라는 동사와 연결됨
  • "간다""나는"(0.401)"간다"(0.401)에 비슷한 가중치를 줍니다. → 동사가 주어와 자신을 동시에 참조

이처럼 Self-Attention은 문장 내에서 의미적으로 연결된 단어들끼리 높은 가중치를 부여하는 것을 확인할 수 있습니다.


7. 왜 KV Cache가 필요한가? (Paged Attention의 전 단계)

지금까지 살펴본 Self-Attention은 모든 토큰이 한 번에 입력되는 경우입니다. 이를 Prefill(또는 Prompt Processing) 단계라고 합니다.

하지만 LLM(대형언어모델)은 실제로 문장을 생성할 때 한 토큰씩 순차적으로 생성합니다. 예를 들어:

입력: "나는 학교에"
출력: "간다" → "." → ...

이미 입력된 "나는", "학교에"의 Key와 Value를 매번 다시 계산하면 엄청난 중복 연산이 발생합니다. 따라서 한 번 계산한 Key와 Value를 메모리에 저장해두고 재사용하는 것이 바로 KV Cache입니다.


정리

개념정의왜 사용하는가
Self-Attention문장 내 모든 토큰 쌍의 관련도를 가중치로 계산병렬 처리 + 장거리 의존성 포착
Q (Query)현재 토큰이 "무엇을 찾는가"다른 토큰과의 관련도 측정 기준
K (Key)각 토큰의 "식별자"Query와의 유사도 계산 대상
V (Value)각 토큰의 "실제 정보"최종 출력의 가중합 재료
Softmax유사도를 확률(합=1)로 변환해석 가능한 가중치 생성
KV Cache이전 토큰의 K, V를 메모리에 저장중복 연산 제거, 생성 속도 향상
profile
시리즈를 기반으로 작성하였습니다.

0개의 댓글