글

9월, 2026의 게시물 표시

Multi-Head Attention이란? 여러 Head가 서로 다른 관계를 찾는 원리

이미지
지난 글에서는 하나의 Self-Attention Head가 입력 X에서 Q·K·V를 만들고, 점수 행렬과 Softmax를 거쳐 문맥 벡터를 만드는 전 과정을 계산했습니다. 그런데 실제 Transformer는 이 계산을 한 번만 수행하지 않습니다. 여러 Attention Head를 병렬로 실행한 뒤 결과를 합칩니다. Multi-Head Attention의 핵심은 같은 계산을 똑같이 반복하는 것이 아닙니다. 각 Head가 서로 다른 학습 가중치로 입력을 투영하기 때문에 같은 문장에서도 다른 관계를 볼 수 있습니다. 이번 글에서는 Head마다 무엇이 달라지는지, 결과를 어떻게 합치는지, 차원과 계산량은 어떻게 연결되는지 살펴보겠습니다. 왜 Attention Head를 여러 개 사용할까? 문장 안에는 한 종류의 관계만 있는 것이 아닙니다. “철수가 사과를 먹었다. 그것은 달았다”에는 주어와 동사의 관계, 목적어와 동사의 관계, 대명사와 지시 대상의 관계, 가까운 단어 사이의 관계가 함께 존재합니다. 하나의 Head도 여러 관계를 표현할 수 있지만, 하나의 가중치 분포로 모든 관점을 섞으면 중요한 패턴이 평균화될 수 있습니다. 여러 Head는 입력을 서로 다른 표현 공간으로 투영하고 각 공간에서 독립적인 Attention을 계산합니다. Transformer 원 논문 도 Multi-Head Attention이 서로 다른 위치와 표현 부분공간의 정보를 함께 참고할 수 있게 한다고 설명합니다. Head마다 무엇이 다를까? 각 Head는 자기만의 WQ, WK, WV를 가집니다. Head i의 계산은 다음처럼 표현할 수 있습니다. Qᵢ = XWQᵢ Kᵢ = XWKᵢ Vᵢ = XWVᵢ headᵢ = Softmax(QᵢKᵢᵀ / √dₖ)Vᵢ 입력 X는 같지만 가중치 행렬이 다르므로 Qᵢ·Kᵢ·Vᵢ도 달라집니다. 따라서 Attention Score와 최종 Head 출력도 달라집니다. Head 1이 높은 점수를 주는 토큰 쌍과 Head 2가 강조하는 ...

Self-Attention 계산 과정: 입력부터 문맥 벡터까지 직접 계산하기

이미지
지난 글에서는 같은 입력 X에 서로 다른 가중치 행렬 WQ·WK·WV를 곱해 Query, Key, Value를 만드는 원리를 살펴봤습니다. 그전 글에서는 Q와 K의 내적을 Softmax 가중치로 바꾸는 과정도 계산했습니다. 이제 흩어져 있던 두 과정을 하나로 연결할 차례입니다. Self-Attention은 문장 안의 각 토큰이 같은 문장의 모든 토큰을 살펴보고, 자신에게 필요한 정보를 가중합해 새로운 표현을 만드는 연산입니다. 이번 글에서는 토큰 두 개와 2차원 벡터를 이용해 입력부터 Q·K·V, 점수 행렬, Softmax, 최종 출력까지 전 과정을 직접 계산하겠습니다. Self-Attention에서 Self는 무엇을 뜻할까? Attention은 Query가 Key를 비교해 필요한 Value를 가져오는 구조입니다. Self-Attention에서는 Q·K·V가 모두 같은 입력 시퀀스에서 만들어집니다. 문장 속 토큰들이 자기 자신을 포함한 같은 문장의 토큰을 참고한다는 뜻에서 Self라는 이름이 붙습니다. 예를 들어 “사과가 달다”에서 ‘달다’의 표현은 자기 자신뿐 아니라 ‘사과가’라는 앞 토큰을 참고해 과일의 맛이라는 문맥을 얻을 수 있습니다. 여기서는 계산을 간단히 하기 위해 두 토큰을 A와 B라고 부르겠습니다. 준비: 입력 X와 가중치 행렬 두 토큰의 입력 표현을 다음과 같이 정합니다. 각 행은 토큰 하나이고 각 열은 벡터의 한 성분입니다. X = [[1, 2], [2, 1]] 앞 글과 같은 세 가중치 행렬을 사용하겠습니다. WQ = [[1, 0], [0, 1]] WK = [[1, 1], [0, 1]] WV = [[1, 0], [1, 1]] 이 값들은 원리를 보여주기 위한 예제입니다. 실제 모델에서는 가중치가 학습으로 결정되고 벡터 차원도 훨씬 큽니다. 1단계: Q·K·V 행렬 만들기 X의 각 행에 같은 가중치 행렬을 곱합니다. Q = XWQ = [[1, 2], [2, 1]] K...

Q·K·V는 어디서 만들어질까? 가중치 행렬로 만드는 원리

이미지
지난 글에서는 Query와 Key의 내적으로 Attention Score를 만들고, √dₖ로 나눈 뒤 Softmax를 적용해 Value를 섞는 과정을 계산했습니다. 그런데 당시에는 Q·K·V 벡터가 이미 준비되어 있다고 가정했습니다. 이 세 벡터는 처음부터 따로 존재하는 것일까요? Self-Attention에서는 같은 입력 표현 X에 서로 다른 가중치 행렬을 곱해 Query, Key, Value를 만듭니다. 하나의 토큰을 ‘무엇을 찾는가’, ‘어떤 정보와 연결되는가’, ‘실제로 전달할 내용은 무엇인가’라는 세 관점으로 바꾸는 과정입니다. 이번 글에서는 이 선형 투영을 작은 행렬로 직접 계산해 보겠습니다. Q·K·V의 출발점은 같은 입력 X다 문장이 토큰으로 나뉘면 각 토큰은 임베딩 벡터로 변환됩니다. 여기에 위치 정보가 더해지고, 더 깊은 Transformer 층이라면 이전 층의 출력이 다음 층의 입력이 됩니다. 이렇게 Attention 층으로 들어오는 토큰별 표현을 X라고 하겠습니다. 토큰이 n개이고 각 표현의 크기가 d model 이라면 X의 모양은 보통 n×d model 입니다. 한 행은 토큰 하나, 한 열은 표현의 한 차원에 해당합니다. Self-Attention에서는 이 동일한 X로부터 다음 세 행렬을 계산합니다. Q = XWQ K = XWK V = XWV WQ, WK, WV는 사람이 미리 의미를 정해 넣은 표가 아니라 학습되는 가중치 행렬입니다. 학습 중 최종 예측의 오차가 역전파되면 세 행렬의 값도 조금씩 바뀝니다. 그 결과 모델은 주어진 과제에 도움이 되는 질문 관점, 비교 기준, 전달 내용을 스스로 형성합니다. 왜 같은 벡터를 그대로 세 번 쓰지 않을까? 입력 벡터를 Q·K·V에 그대로 사용해도 수학적 계산은 가능합니다. 그러나 세 역할에 서로 다른 투영을 사용하면 모델이 비교할 특징과 전달할 특징을 분리할 수 있습니다. Query 는 현재 위치가 주변에서 찾으려는 특징을 강조합니다. Key 는 각...

Attention Score란? Q·K 내적부터 Softmax까지 직접 계산하기

이미지
지난 글에서는 임베딩이 토큰을 학습 가능한 벡터로 바꾸고, Transformer 층을 지나면서 문맥에 맞는 표현으로 발전한다는 점을 알아봤습니다. 그렇다면 모델은 주변 토큰 중 무엇을 얼마나 참고해야 하는지 어떻게 결정할까요? 그 출발점이 바로 Attention Score입니다. Attention Score는 현재 처리 중인 토큰의 질문과 다른 토큰이 가진 단서를 비교한 점수입니다. Transformer에서는 이 비교를 Query와 Key의 내적으로 계산합니다. 이어서 점수를 적절한 크기로 조정하고 Softmax를 적용해 합계 1의 가중치로 바꿉니다. 이번 글에서는 작은 2차원 벡터를 사용해 이 과정을 직접 계산해 보겠습니다. Attention은 무엇을 해결할까? 문장 “철수는 사과를 먹었다. 그것은 달콤했다”를 생각해 보겠습니다. “그것”의 의미를 이해하려면 앞부분의 “사과”를 중요하게 참고해야 합니다. 모든 단어를 똑같이 섞으면 주체인 철수, 행동인 먹었다, 대상인 사과의 역할이 흐려집니다. Attention은 각 토큰이 다른 토큰과 얼마나 관련 있는지 점수로 계산한 뒤, 관련성이 큰 정보에는 높은 가중치를 주는 방식입니다. Transformer 원 논문 은 Attention을 Query와 Key-Value 쌍을 출력 벡터로 매핑하는 함수로 설명합니다. 가중치는 Query와 각 Key의 적합도를 이용해 구하고, 출력은 Value들의 가중합으로 만듭니다. Query, Key, Value를 역할로 이해하기 Q·K·V는 서로 완전히 다른 원본 데이터가 아닙니다. Self-Attention에서는 같은 입력 표현에 서로 다른 학습 행렬을 곱해 세 가지 관점의 벡터를 만듭니다. 이번 글에서는 생성 과정 자체보다 계산 역할에 집중합니다. Query(Q) : 현재 토큰이 다른 토큰에서 찾으려는 정보입니다. 검색창에 입력한 질문에 비유할 수 있습니다. Key(K) : 각 토큰이 어떤 정보와 연결될 수 있는지 나타내는 비교용 특징입니다...

임베딩 심화: AI는 어떻게 단어의 의미를 벡터 공간에 학습할까?

이미지
지난 글에서는 Softmax가 여러 점수를 합계 1의 비율로 바꾸는 원리를 살펴봤습니다. 그런데 언어 모델이 Softmax로 다음 단어의 비율을 계산하려면, 그보다 먼저 단어와 문맥을 숫자로 표현해야 합니다. 이때 핵심 역할을 하는 것이 임베딩(Embedding)입니다. 임베딩을 단순히 “단어를 숫자 벡터로 바꾸는 기술”이라고만 기억하면 중요한 부분을 놓치기 쉽습니다. 어떤 숫자가 들어가는지, 비슷한 의미가 왜 가까워지는지, 같은 단어가 문장에 따라 왜 다르게 표현되는지를 이해해야 이후의 Attention 계산도 자연스럽게 연결됩니다. 이번 글에서는 임베딩을 하나의 학습된 의미 공간 으로 바라보겠습니다. 임베딩은 단어에 붙인 번호가 아니다 문장을 모델에 넣기 전에는 먼저 토큰이라는 작은 단위로 나눕니다. 각 토큰에는 토큰 ID가 부여됩니다. 예를 들어 “고양이”가 125번이고 “강아지”가 387번일 수 있습니다. 하지만 125와 387이라는 숫자 자체에는 의미가 없습니다. 번호 차이가 262라고 해서 두 단어의 의미가 그만큼 멀다는 뜻도 아닙니다. 임베딩 층은 이 ID를 입력받아 해당 토큰에 대응하는 벡터를 꺼냅니다. 토큰이 1만 개이고 임베딩 차원이 4라면, 모델 안에는 대략 10,000행 × 4열의 임베딩 행렬이 있다고 생각할 수 있습니다. 각 행은 토큰 하나에 대응하고, 행 안의 네 숫자가 그 토큰의 현재 좌표입니다. 토큰 ID 125 → [0.21, -0.13, 0.42, 0.08] 토큰 ID 387 → [0.18, -0.09, 0.39, 0.11] 두 벡터가 비슷해 보이지만, 사람이 각 숫자를 보고 “첫 번째 값은 동물성, 두 번째 값은 귀여움”이라고 해석할 수 있는 것은 아닙니다. 실제 임베딩의 각 차원은 여러 특성이 섞인 채 학습되는 경우가 많습니다. 중요한 것은 개별 숫자의 이름보다 벡터 사이의 상대적 위치와 방향입니다. TensorFlow의 단어 임베딩 안내 도 임베딩을 정수 인덱스를 밀집 벡터로 바꾸는 조회표로 설...

Softmax란? AI가 여러 점수를 합계 1의 비율로 바꾸는 원리

이미지
지난 글에서는 코사인 유사도가 두 벡터의 방향을 비교해 관계 점수를 만드는 원리를 살펴봤습니다. AI에는 이렇게 여러 후보를 나타내는 점수가 자주 등장합니다. 그런데 점수 2, 1, 0만 보고 각 후보가 전체에서 어느 정도 비중을 차지하는지 바로 이해하기는 어렵습니다. Softmax 는 여러 실수 점수를 0과 1 사이의 값으로 바꾸고, 전체 합을 1로 만드는 함수입니다. 분류 모델의 클래스 점수, 언어 모델의 다음 토큰 점수, Transformer의 Attention 점수를 비교 가능한 비율로 바꿀 때 사용됩니다. 이번 글에서는 지수함수가 왜 필요한지, 직접 계산하면 어떤 값이 나오는지, 확률처럼 보이는 결과를 어떻게 해석해야 하는지 알아보겠습니다. Softmax란? Softmax는 점수 벡터 z의 각 원소를 지수화한 뒤, 모든 지수값의 합으로 나눕니다. softmax(zᵢ) = e zᵢ / Σⱼe zⱼ e는 약 2.718인 자연상수이고, zᵢ는 i번째 입력 점수입니다. 지수값은 항상 양수이므로 결과도 0보다 작아지지 않습니다. 각 지수값을 동일한 합으로 나누기 때문에 모든 출력의 합은 정확히 1이 됩니다. PyTorch 공식 문서도 Softmax가 지정한 차원의 값을 0과 1 사이로 재조정하고 합을 1로 만든다고 설명합니다. PyTorch Softmax 공식 문서 입력 점수 로짓이란? Softmax에 들어가기 전의 원시 점수를 흔히 로짓(Logit) 이라고 부릅니다. 로짓은 양수일 수도, 0일 수도, 음수일 수도 있으며 합이 1일 필요도 없습니다. 예를 들어 이미지 분류 모델이 고양이, 강아지, 토끼에 대해 [2, 1, 0]을 출력했다면 이는 아직 확률이 아니라 클래스별 상대 점수입니다. 로짓 사이의 차이는 중요하지만 절대적인 기준점은 중요하지 않습니다. [2, 1, 0]에 같은 숫자 10을 더한 [12, 11, 10]은 Softmax를 통과하면 같은 결과를 냅니다. 모든 점수에 같은 값을 더해도 ...

코사인 유사도란? AI가 벡터의 방향으로 의미를 비교하는 원리

이미지
지난 글에서는 AI가 두 벡터의 비슷함을 판단할 때 유클리드 거리, 내적, 코사인 유사도처럼 서로 다른 기준을 사용할 수 있다는 점을 알아봤습니다. 이번에는 그중 임베딩 검색에서 자주 만나는 코사인 유사도(Cosine Similarity) 를 직접 계산해 보겠습니다. 코사인 유사도는 벡터의 길이보다 두 벡터가 향하는 방향에 집중합니다. 문장이 길거나 숫자의 전체 규모가 달라도 특징의 비율과 방향이 비슷한지를 비교할 수 있다는 점이 핵심입니다. 다만 높은 점수가 언제나 사람이 느끼는 의미의 동일성을 보장하는 것은 아니므로 계산과 해석을 함께 이해해야 합니다. 코사인 유사도란? 두 벡터 a와 b를 같은 원점에서 그렸을 때 그 사이의 각도를 θ라고 하겠습니다. 코사인 유사도는 이 각도의 코사인값입니다. 공식은 다음과 같습니다. cos(a,b) = (a · b) / (||a|| ||b||) 분자 a · b는 두 벡터의 내적이고, 분모는 각 벡터의 크기를 곱한 값입니다. 내적에는 방향과 크기가 함께 반영되지만, 벡터 크기로 나누면 길이의 영향이 사라지고 각도 관계가 남습니다. scikit-learn 공식 문서도 코사인 유사도를 두 벡터의 정규화된 내적으로 정의합니다. scikit-learn cosine_similarity 문서 두 벡터의 차원은 같아야 합니다. 각 성분이 같은 종류의 특징을 나타내야 같은 위치끼리 곱하는 내적도 의미가 있습니다. 다른 임베딩 모델에서 만든 벡터나 차원의 의미가 다른 벡터를 공식에 넣는 것은 피해야 합니다. 왜 이름에 코사인이 들어갈까? 삼각함수의 코사인은 각도에 따라 −1에서 1 사이의 값을 가집니다. 두 벡터가 완전히 같은 방향이면 각도는 0도이고 cos 0° = 1입니다. 서로 직각이면 cos 90° = 0, 정반대 방향이면 cos 180° = −1입니다. 1에 가까움: 두 벡터가 비슷한 방향을 향합니다. 0에 가까움: 두 벡터가 거의 직교...

유사도란? AI가 두 데이터의 비슷함을 숫자로 판단하는 방법

이미지
지난 글에서는 두 벡터의 같은 위치끼리 곱해 더하는 내적 을 알아봤습니다. 내적은 두 벡터의 관계를 하나의 숫자로 만드는 방법이지만, AI가 ‘비슷하다’를 판단하는 방법이 내적 하나뿐인 것은 아닙니다. 두 문장이 비슷한지, 사용자가 좋아할 상품이 무엇인지, 수많은 문서 중 질문과 가까운 자료가 무엇인지 찾으려면 먼저 비슷함의 기준을 정해야 합니다. 이번 글에서는 유사도(Similarity)가 무엇인지, 거리·내적·코사인이 무엇을 다르게 보는지, 실제 검색에서는 이 점수를 어떻게 사용하는지 살펴보겠습니다. 유사도란? 유사도는 두 대상을 비교해 얼마나 비슷한지를 숫자로 나타내는 기준입니다. 보통 값이 클수록 비슷하도록 정의하지만, 모든 방법이 그런 것은 아닙니다. 유클리드 거리는 값이 작을수록 가깝고, 코사인 유사도나 내적은 일반적으로 값이 클수록 가깝다고 해석합니다. 중요한 점은 유사도가 대상 자체에 붙어 있는 절대적인 성질이 아니라는 것입니다. 무엇을 특징으로 표현했는지, 특징의 단위를 어떻게 맞췄는지, 어떤 측정 공식을 선택했는지에 따라 결과가 달라집니다. 같은 두 영화도 장르를 중심으로 보면 비슷하고, 개봉 연도나 상영 시간을 중심으로 보면 다르게 평가될 수 있습니다. Google의 머신러닝 용어집은 유사도 측정을 데이터 예시 두 개가 얼마나 닮았는지 결정하는 기준으로 설명합니다. 군집화에서는 이 기준을 이용해 가까운 데이터끼리 묶고, 추천이나 검색에서는 질의와 가까운 후보의 순위를 정합니다. Google 머신러닝 유사도 용어 설명 AI가 비교하기 전에 필요한 것 컴퓨터는 문장이나 이미지의 의미를 그대로 자로 잴 수 없습니다. 먼저 각 대상을 같은 형식의 숫자 벡터로 표현해야 합니다. 사람이 특징을 직접 정할 수도 있고, 신경망이 학습한 임베딩을 사용할 수도 있습니다. 예를 들어 과일을 [단맛, 신맛, 단단함]이라는 세 특징으로 표현했다면 사과와 배는 3차원 벡터가 됩니다. 이때 첫 번째 성분은 두...