AI VIDEO BRIEFING

트랜스포머 행렬 연산 원리 정리: 셀프 어텐션과 디코더 마스킹, 인코더 디코더 구조까지

영어 문장을 스페인어로 옮기는 아주 작은 예제를 따라가며, 트랜스포머의 단어 임베딩과 위치 인코딩부터 셀프 어텐션, 디코더 마스킹, 인코더 디코더 어텐션까지 모든 계산을 행렬 표기로 한 단계씩 짚는다.

트랜스포머는 어떻게 행렬 곱셈만으로 문장을 번역할까 영상 대표 이미지

핵심 메시지

  • 단어 임베딩은 토큰을 표시한 입력 행렬과 가중치 행렬의 곱으로 한 번에 구해지고, 위치 정보는 사인·코사인 곡선에서 읽은 값을 더해 넣는다.
  • 쿼리·키·값은 각기 다른 가중치 행렬을 곱해 만들며, 모든 토큰의 값을 한 번의 행렬 곱으로 동시에 계산한다.
  • 어텐션은 Q와 K의 전치를 곱해 내적 유사도를 얻고, 키 차원의 제곱근으로 나눈 뒤 행마다 소프트맥스를 적용해 V에 가중치를 주는 절차다.
  • 디코더는 뒤에 올 토큰을 미리 보지 못하도록 무시할 자리에 음의 무한대를 더하는 마스크 행렬을 사용한다.
  • 인코더-디코더 어텐션은 계산 방식이 셀프 어텐션과 같고, Q는 디코더 값에서, K와 V는 인코더 출력에서 만든다는 점만 다르다.

쉽게 이해하기

이 영상은 트랜스포머의 개념을 이미 한 번 본 사람을 위해, 같은 내용을 이번에는 행렬 표기로 다시 훑는다. 강사가 든 이유는 실용적이다. 행렬 표기를 이해해야 트랜스포머를 직접 코드로 옮기기가 훨씬 쉬워지고, GPU가 행렬 연산에 최적화돼 있어 실제 구현도 이렇게 돌아간다는 것이다. 예제는 영어 'let's go'를 스페인어 'vamos'로 번역하는 인코더-디코더 구조이며, 토큰마다 값이 두 개뿐인 아주 작은 모델이라 모든 숫자를 눈으로 따라갈 수 있다.

출발점은 입력 문장을 숫자로 바꾸는 일이다. 문장 시작을 알리는 SOS 토큰을 포함해 각 토큰을 한 자리만 1인 행으로 표시한 뒤 가중치 행렬을 곱하면, 그 곱셈이 곧 해당 토큰의 임베딩을 꺼내오는 역할을 한다. 여기에 위치 인코딩을 더한다. 사인과 코사인 곡선에서 읽은 값을 자리마다 더하는데, 실제로는 미리 계산해 표에 저장해 두기 때문에 계산 시간이 들지 않는다.

다음은 셀프 어텐션이다. 인코딩된 값에 쿼리·키·값 각각의 가중치 행렬을 곱해 Q, K, V를 만든다. 여기서 강사는 파이토치가 가중치를 출력하는 방식 때문에 실제 코드에서는 전치가 필요하다는 점을 짚는다. 그다음 Q에 K의 전치를 곱하는데, 단순히 모양을 맞추기 위해서가 아니다. 이렇게 곱해야 모든 쿼리와 모든 키의 내적이 한꺼번에 나오기 때문이다. 내적은 스케일이 조정되지 않은 유사도이고, 이를 -1에서 1 사이로 맞춘 것이 코사인 유사도다.

유사도 행렬은 키 차원의 제곱근으로 나눈 뒤 행마다 소프트맥스를 거친다. 각 행의 합이 1이 되므로 결과는 '이 토큰이 다른 토큰들과 얼마나 관련되는지'의 비율로 읽을 수 있다. 예제에서 SOS 토큰은 자신과 1%, 'let's'와 99%, 'go'와 0% 관련된다는 식이다. 이 비율을 V에 곱하면 각 토큰의 어텐션 점수가 나오고, 여기에 위치 인코딩 직후의 값을 다시 더하는 잔차 연결을 거치면 인코더의 출력이 완성된다.

디코더에서 가장 중요한 장치는 마스킹이다. 학습할 때는 정답 출력을 이미 알고 있어 모든 토큰을 동시에 계산할 수 있고, 그래서 병렬 하드웨어를 제대로 쓸 수 있다. 앞 토큰의 출력을 다음 디코더의 입력으로 넣어주는 방식은 교사 강요라고 부르며 학습을 빠르게 한다. 하지만 실제 번역 시점에는 뒤에 무엇이 올지 알 수 없으므로, 앞 토큰이 뒤를 훔쳐보지 못하게 무시할 자리에 음의 무한대를 더한다. 소프트맥스를 거치면 그 자리는 0%가 된다. 이후 인코더-디코더 어텐션, 잔차 연결, 완전연결 층과 소프트맥스를 지나면 첫 디코더에서 'vamos'가, 두 번째 디코더에서 문장 끝을 알리는 EOS가 나온다.

주요 인사이트

  • 행렬 표기는 수식을 예쁘게 쓰기 위한 장치가 아니라 구현 그 자체다. 토큰마다 반복하던 계산이 한 번의 곱셈으로 묶이기 때문에 GPU 병렬 연산과 그대로 맞아떨어진다.
  • K를 전치해서 곱하는 이유를 '모양이 안 맞아서'로만 기억하면 절반만 아는 것이다. 그 곱셈의 결과가 모든 쿼리-키 쌍의 내적, 즉 유사도 표라는 점이 핵심이다.
  • 스케일링에 대해 강사는 솔직하다. 키 차원의 제곱근으로 나눠도 값의 범위가 체계적으로 좁혀지지는 않고(예제에서도 5.01에서 -66.2까지 벌어진다), 원 논문 저자들이 성능이 좋아졌다고 밝혔을 뿐이라고 설명한다.
  • 학습을 병렬로 돌리는 것과 추론이 순차적이라는 사실은 서로 충돌한다. 마스킹은 이 간극을 메우는 장치로, 병렬 계산의 이점을 유지하면서 추론 조건을 흉내 낸다.

자주 묻는 질문

왜 K를 전치해서 Q와 곱하나요?

모양을 맞추기 위한 이유도 있지만 더 중요한 것은 계산 결과입니다. Q에 K의 전치를 곱하면 각 쿼리와 각 키의 내적이 한꺼번에 계산돼, 모든 토큰 조합의 유사도 표가 만들어집니다. 내적은 스케일이 조정되지 않은 유사도이며, 이를 -1~1로 맞춘 것이 코사인 유사도입니다.

유사도를 키 차원의 제곱근으로 나누는 이유는 무엇인가요?

여기서 차원은 토큰 하나에 배정된 값의 개수를 뜻하며, 예제에서는 2이므로 루트 2로 나눕니다. 강사는 이 방식이 값의 범위를 체계적으로 줄여주지는 않는다고 지적하면서, 트랜스포머 원 논문 저자들이 이렇게 했을 때 성능이 좋아졌다고 밝혔기 때문이라고 설명합니다.

디코더의 마스킹은 정확히 무엇을 막나요?

학습 중에는 정답 출력을 알고 있어 모든 토큰의 계산을 동시에 할 수 있지만, 실제 번역에서는 뒤에 올 토큰을 알 수 없습니다. 그래서 앞 토큰이 뒤 토큰을 참고하지 못하도록 무시해야 할 자리에 음의 무한대를 더하고, 소프트맥스를 거치면 그 자리의 비중이 0%가 됩니다.

원문과 출처

이 글은 원본 영상의 자막을 바탕으로 한국어 독자를 위해 요약했습니다. 전체 맥락과 최신 정보는 원문에서 확인하세요.

YouTube 원본 영상 보기 ↗

관련 AI 소식

#트랜스포머#셀프어텐션#딥러닝#행렬연산#어텐션마스킹