본문 바로가기

기술

어텐션 알고리즘 이해하기

밑바닥부터 만들면서 배우는 LLM 책의 3장 어텐션 메커니즘 구현하기를 읽으면서 떠오른 질문과 답을 정리해보았습니다.

Build a LLM from Scratch

1. RNN의 한계와 내적(Dot Product)의 기하학적 의미

  • 질문
    • 인코더-디코더 RNN은 직전 은닉 상태만 참조 가능하다는데 왜 이런 제약이 있는가?
    • 내적(Dot Product)은 기하학적/수학적으로 어떤 의미이며, 어떤 성질이 있는가?
    • 내적으로 유사도를 측정하면 벡터의 길이(Magnitude)가 결과에 영향을 미치지 않는가?
  • 답변 요약
    • RNN의 구조적 병목: RNN은 고정된 크기의 벡터에 모든 정보를 압축해야 하는 '마르코프 성질'에 의존함. 즉, 이전 정보를 오직 '하나의 직전 상태' 메모리 셀에 넣어 전달해야 하므로 문장이 길어지면 앞부분 정보를 잊어버리는 물리적 한계가 존재함.
      • 마르코프 성질: 과거의 세부적인 이력은 현재 상태에 이미 모두 반영되어 있다고 가정하는 성질.
    • 내적의 의미: 두 벡터 A, B에 대해  \( A \cdot B = |A||B|\cos\theta \) 임.
      • 수학적으로는 '한 벡터를 다른 벡터로 투영한 길이'를 의미.
      • 성질: 방향이 같으면 최대(양수), 수직이면 0, 반대면 최소(음수).
    • 길이의 영향: 영향을 미치는 게 맞음. 내적은 각도뿐만 아니라 벡터의 길이에도 비례함. 따라서 단순히 내적만 쓰면 값이 너무 커질 수 있어, 최신 모델들은 이를 보완하기 위해 '스케일링'이나 '정규화' 과정을 거침.

그림을 통해 얼추 RNN의 구조는 이해할 수 있었지만 왜 직전 은닉 상태만 의존하는지 궁금했습니다. AI의 답변이 썩 만족스럽진 않지만 애초에 그 제약을 타파한 것이 트랜스포머 알고리즘이라고 생각하면 납득은 갔습니다. 트랜스포머 알고리즘도 NN의 한 부류로 이해하고 있는데 RNN과 어떻게 갈라지는지 궁금하네요.

 

오랜만에 기하와 벡터 내용이 나오니 기억이 나지 않아 다시 복습했습니다. 요즘 고등학생은 미적분, 기하와 벡터, 확률과 통계 중 하나를 선택한다는데 AI 공부할 때 3가지가 모두 필요하고 여기에 선형대수학까지 들어가니, 우리가 어릴 때 배우는 수학이 생각보다 써먹을 곳이 많다고 느낍니다.

2. 유사도 측정 방법과 Softmax를 사용하는 이유

  • 질문
    • 최신 모델들은 유사도 측정 시 어떤 방법들을 사용하는가?
    • Softmax 함수가 훈련 과정에서 유용한 gradient(기울기) 속성을 가진다는 게 무슨 의미인가?
  • 답변 요약
    • 유사도 측정 기법들
      • 점곱 (Dot Product): 단순 곱셈 합. 연산이 가장 빠르지만 벡터 길이에 매우 민감함.
      • 스케일드 점곱 (Scaled Dot Product): 트랜스포머의 표준. 입력 차원 수의 제곱근으로 나눠 값의 폭주를 막음.
      • 코사인 유사도 (Cosine Similarity): 벡터의 길이를 1로 정규화하여 '방향(각도)'만 측정. RAG 문서 검색의 표준.
      • 유클리드 거리 (Euclidean Distance, L2): 두 점 사이의 직선 거리. 거리가 가까울수록 유사하다고 판단. KNN-LM 등에서 활용.
      • 맨해튼 거리 (Manhattan Distance, L1): 격자 형태의 경로 거리. 이상치(Outlier)에 유클리드 거리보다 강건함.
      • 피어슨 상관계수 (Pearson Correlation): 두 벡터의 선형적 상관관계를 측정. 데이터의 스케일 변화에 무관하게 유사성을 찾을 때 유용.
      • 자카드 유사도 (Jaccard Similarity): 집합 간의 겹치는 정도를 측정. 주로 키워드 중복도나 토큰 단위 유사성 검사에 사용.
    • Softmax와 Gradient: Softmax는 결과값을 확률 분포(0~1 사이, 총합 1)로 만들 뿐만 아니라, 모든 구간에서 미분 가능함. 특히 Hardmax와 달리 작은 값들에게도 미세한 확률을 배분하므로, 역전파(Backpropagation) 시 가중치가 낮은 토큰도 적절히 고려하여 가중치를 부드럽게 업데이트할 수 있게 해줌.

아직 역전파 알고리즘에 대해 구체적으로 공부하지 않아서 어느 지점에서 미분하는지 이해를 못해 왜 미분 가능하다는지 이해하기 어렵네요. '미분 가능'은 어떤 함수에 대한 판단일텐데 책을 읽으면서 함수는 아직 등장하지 않고 행렬 연산만 지속하고 있어서 어디를 미분한다는 것인지 감이 잡히지 않습니다. 더 읽어보고 다시 돌아와 공부해보겠습니다.

3. 어텐션 계산의 논리와 스케일링의 이유

  • 질문
    • 문맥 벡터 계산 시 왜 자기 자신과의 유사도도 포함하는가?
    • 스케일드 점곱 어텐션에서 입력 차원의 제곱근으로 나누는 구체적인 이유는?
  • 답변 요약
    • 자기 자신도 맥락: 단어의 의미는 주변 단어에 의해 결정되지만, 그 단어 본연의 정보(Anchor)가 가장 중요함. '사과'라는 단어의 문맥 벡터를 만들 때 '사과' 자체의 정보를 빼버리면 문맥만 남고 알맹이가 사라짐.
    • 분산 제어: 벡터의 차원이 커질수록 내적 값의 변동성(분산)이 매우 커짐. 값이 너무 커지면 Softmax의 기울기가 0에 가까워지는 '포화 상태'에 빠져 학습이 멈춤. 이를 방지하기 위해 표준 편차를 1로 맞춰주는 수학적 장치가 바로 \( \sqrt{d_{in}} \)로 나누는 것임.

스케일드 점곱에 대해서는 책에서도 참고 설명이 많았습니다. 일단 정규화를 하기 전 가중치 값의 격차(분산)이 너무 커지면 Softmax를 적용했을 때 가장 큰 가중치가 1에 가까워지고 나머지 모든 가중치가 0에 가까워진다는 것은 이해했습니다. 분산을 줄일 때 왜 \( \sqrt{d_{in}} \)인지가 사실 궁금했는데요. '표준 편차'라는 단어가 나오니 확률과 통계에 관련된 지식이라는 것은 어렴풋이 알 수 있었습니다. 학부 시절 미적분, 선형대수학 개론은 듣고 확률과 통계만 안들었는데 조금 후회되네요.

4. Dropout과 정규화

  • 질문
    • 가중치 행렬을 nn.Parameter로 만드는 것과 nn.Linear로 만드는 것의 차이는?
    • 코잘 어텐션(Causal Attention)에서 Dropout 이후 왜 다시 정규화하지 않는가?
  • 답변 요약
    • 추상화의 차이: nn.Parameter는 모델 학습에 필요한 가중치를 직접 정의하는 저수준(Low-level) API이며, nn.Linear는 내부적으로 nn.Parameter를 가지고 있으면서 편향(Bias)과 행렬 곱셈 연산까지 캡슐화해 둔 고수준(High-level) API임. 실무에서는 코드 가독성과 편의성을 위해 nn.Linear를 주로 사용함.
    • Dropout과 기댓값: PyTorch의 Dropout은 훈련 시 살아남은 노드의 값을 \( 1/(1-p) \) 만큼 키워줌. 그래서 합이 1이 아니게 되어도 평균적인 기대값은 유지됨. 훈련 단계가 아닌 추론 단계에서는 Dropout을 사용하지 않아 원래의 정규화가이 그대로 유지되어 아무 문제가 없음.

Dropout 파트는 읽자마자 정규화가 깨진다는 것을 알 수 있었는데요. 일단 AI의 설명은 장기적으로 기댓값은 그대로 1이기 때문에 괜찮다는데 그게 괜찮다면 굳이 정규화를 진행하지 않아도 되지 않나 싶었습니다. 추론할 때는 Dropout을 사용하지 않는다는 말도 처음엔 이해하기 어려웠습니다. AI 가라사대 훈련이 끝나면 가중치 행렬이 고정되고 이 시점에는 Dropout이 없으므로 모든 행의 합이 1로 그대로 유지되어 확률 왜곡이 없다고 합니다.

5. 멀티헤드 어텐션의 효율성과 출력 투영(Output Projection)

  • 질문
    • 여러 개의 어텐션을 병렬로 하는 것과 큰 행렬 하나로 하는 것의 계산 복잡도는 같지 않나?
    • 마지막에 출력 투영(Output Projection) 층을 한 번 더 두는 진짜 이유는?
  • 답변 요약
    • 행렬 연산의 효율성: 수학적 복잡도(FLOPs)는 같음. 하지만 GPU는 작은 연산 여러 개보다 큰 행렬 곱셈 하나를 훨씬 빠르게 처리함(병렬 가속). 그래서 현대 모델들은 헤드를 물리적으로 나누지 않고 큰 행렬로 한 번에 계산한 뒤 쪼개는 방식을 씀.
    • 정보의 통합: 멀티헤드를 통해 각자 다른 관점(문법, 의미, 거리 등)으로 본 정보들을 마지막에 다시 '하나의 일관된 문맥'으로 섞어주는 과정이 필요함. 이 투영 층이 없으면 헤드 간의 정보가 단절된 채 남게 됨. 성능 면에서도 이 '비선형 믹서'가 있는 것이 일반적으로 훨씬 유리함.

책에서는 코잘 어텐션을 단순히 이어붙이는 형태의 멀티헤드 어텐션과 처음부터 확장시킨 가중치 파라미터를 이용한 방법을 나누어 멀티헤드 어텐션을 구현했습니다. 손으로 계산해봤을 때 두 연산의 계산복잡도는 동일한 것으로 보여서 AI에게 물어봤습니다.

 

멀티헤드 어텐션 과정의 가장 마지막에 '출력 투영'이라고 부르는 행렬 곱 연산이 존재하는데요. 입력 차원과 출력 차원도 동일해서 굳이 필요한가 의문이 들었고, 책에서도 성능에 영향을 미치지 않는다는 말도 써있었습니다. (부록을 참고하라는데 부록도 해당 층이 없을 때 성능이 더 좋다는 논문) 여러모로 설명이 애매한데 아무래도 기계학습 분야가 하이퍼 파라미터의 영향을 정확하게 파악한다기보다 이렇게 해보니 좋더라 정도의 연관관계만 알 수 있어서 그런 것 같습니다.

마치며

3장 초반에 간단한 어텐션 알고리즘부터 설명을 시작할 때는 머릿속이 어지러웠습니다. 그런데 반복해서 3장을 읽고, 어텐션 알고리즘을 차근차근 개선하다보니 어느새 염두에 자리를 잡은 느낌입니다. 아직 수학적으로 부족한 점이 많아 의문도 있지만 조금씩 빈 공간을 채워갈 수 있겠다는 자신감이 생깁니다.

 

아직 역전파 과정에 대한 이해가 부족해서 책 중간에 나오는 설명들을 건너뀌는 경우가 종종 있습니다. 이 부분도 공부해서 잘 정리해보겠습니다.