결국 “의미를 숫자(벡터와 행렬)로 바꾸고 이것을 계산(벡터 곱셈)하여 관련성(의미의 유사성)을 파악하고 어텐션 점수를 가지고 문맥을 이해하는 것”이 현대 AI의 핵심입니다!
임베딩 벡터:
트랜스포머 아키텍처:
행렬 연산의 역할:
중학생도 이해할 수 있게 차근차근 설명해드릴게요.
컴퓨터는 오직 숫자만 계산할 수 있어요.
“사과”라는 글자 → 컴퓨터가 못 알아들음
“사과” = [3, 8, 1, 9] → 컴퓨터가 계산 가능(이해 가능)
좌표평면을 생각해보세요!
단맛
↑
과일 ● | ● 사탕
|
────┼─────→ 단맛
|
● 자동차
비슷한 위치 = 비슷한 의미!
실제로는 2차원이 아니라 수백~수천 차원입니다.
“사과” = [0.2, -0.1, 0.8, 0.3, -0.5, 0.9, …]
예시: 간단한 문장 완성 게임
“사과는 ___이다”
문장: “빨간 사과가 맛있다”
어텐션이 묻는 질문: “맛있다”를 이해하려면 어떤 단어에 집중해야 할까?
"맛있다" 벡터와 다른 단어들 비교:
- "맛있다" × "빨간" = 0.3 (약간 관련)
- "맛있다" × "사과" = 0.9 (매우 관련!)
- "맛있다" × "가" = 0.1 (관련 없음)
→ "사과"에 90% 집중해서 "맛있다" 이해!
컴퓨터가 “의미”를 숫자로 계산할 수 있게 되었어요!
벡터는 의미를 숫자로 저장하고, 행렬은 의미를 변환하는 도구역할을 합니다!
행벡터 (Row Vector):
[1, 2, 3] ← 가로로 나열
열벡터 (Column Vector):
[1]
[2] ← 세로로 나열
[3]
행벡터 × 열벡터 = 스칼라 (하나의 숫자)
[1, 2, 3] × [4] = (1×4) + (2×5) + (3×6)
[5]
[6]
= 4 + 10 + 18 = 32
어텐션 계산:
Query (행벡터): [0.8, 0.2, 0.6]
Key (열벡터): [0.7]
[0.1] → 내적 = 0.8×0.7 + 0.2×0.1 + 0.6×0.4 = 0.82
[0.4]
가중치 행렬과 입력:
입력 (행벡터): [1, 2]
가중치 행렬: [0.5, 0.3] → 결과: [1×0.5+2×0.1, 1×0.3+2×0.8]
[0.1, 0.8] = [0.7, 1.9]
행벡터 × 열벡터 = 숫자 1개 (관련성 점수)
“문장에서 어떤 단어에 집중할지 결정하는 메커니즘”
문장: “그 남자가 강을 건넜다”
기존 방식의 문제:
어텐션의 해결:
Query(쿼리): 현재 처리 중인 단어
Key(키): 문장의 모든 단어들
Value(값): 각 단어의 의미 정보
어텐션 점수 = Query × Key^T (행렬 곱셈)
멀티 헤드 어텐션:
이게 트랜스포머가 문맥을 잘 이해하는 핵심 이유입니다.
두 벡터가 비슷한 방향을 가리키면 곱셈 결과가 크고, 다른 방향이면 작아져요.
좌표평면에서:
↑ y축
|
"사과"● (3, 4)
/|
/ |
/ |
─--─┼────→ x축
|
"빨강"● (4, 2)
벡터 내적 계산: 사과 · 빨강 = (3×4) + (4×2) = 12 + 8 = 20 (큰 값!)
반대 방향인 경우:
↑
|
"사과"● (3, 4)
|
─-─┼────→
|
|
● "돌" (-2, -3)
사과 · 돌 = (3×-2) + (4×-3) = -6 + (-12) = -18 (음수!)
“맛있는 사과”를 이해할 때:
“맛있는” = [0.8, 0.2, 0.9, 0.1, …] “사과” = [0.7, 0.3, 0.8, 0.2, …]
cf : 벡터 행렬의 0번째: 과일성, 1번째: 색깔, 2번째: 크기, …를 의미
곱셈: (0.8×0.7) + (0.2×0.3) + (0.9×0.8) + (0.1×0.2) + … = 0.56 + 0.06 + 0.72 + 0.02 + … = 1.36 (높은 관련성!)
“맛있는 자동차”라면:
“맛있는” = [0.8, 0.2, 0.9, 0.1, …] “자동차” = [0.1, 0.9, 0.2, 0.8, …]
곱셈: (0.8×0.1) + (0.2×0.9) + (0.9×0.2) + (0.1×0.8) + … = 0.08 + 0.18 + 0.18 + 0.08 + … = 0.52 (낮은 관련성)
비슷한 벡터 = 같은 방향 = 큰 내적값 = 높은 관련성
다른 벡터 = 다른 방향 = 작은 내적값 = 낮은 관련성
이렇게 단순한 곱셈과 덧셈으로 “의미의 유사성”을 계산할 수 있는 거예요!
원본 단어 벡터를 “변환”하기 위해서입니다.
원본 “사과” 벡터:
[1, 2] = [과일성, 색깔정보]
이 벡터를 다른 관점으로 변환하고 싶어요:
"사과"를 질문자 입장에서 보면?
W_query = [0.5, 0.3] ← 학습된 가중치
[0.1, 0.8]
[1, 2] × W_query = [0.7, 1.9]
= [질문_특성1, 질문_특성2]
** 단계별 계산 **
주어진 값:
입력 벡터: [1, 2]
가중치 행렬: [0.5, 0.3]
[0.1, 0.8]
행렬 곱셈 규칙
[1, 2] × [0.5, 0.3] = [?, ?]
[0.1, 0.8]
첫 번째 원소 계산:
[1, 2] × [0.5] = (1 × 0.5) + (2 × 0.1) = 0.5 + 0.2 = 0.7
[0.1]
두 번째 원소 계산:
[1, 2] × [0.3] = (1 × 0.3) + (2 × 0.8) = 0.3 + 1.6 = 1.9
[0.8]
최종 결과:
[1, 2] × [0.5, 0.3] = [0.7, 1.9]
[0.1, 0.8]
"사과"를 답변자 입장에서 보면?
W_key = [0.8, 0.2]
[0.4, 0.9]
[1, 2] × W_key = [1.6, 2.0]
= [답변_특성1, 답변_특성2]
마치 번역기처럼!
같은 “사과”지만 다른 역할(질문과 답변)을 위해 다르게 변환하는 거예요!
이렇게 변환된 Query와 Key를 곱해야 “질문”과 “답변”의 관련성을 정확히 계산할 수 있습니다.
원본 벡터를 그대로 쓰면 → 단순 유사성만 측정
변환한 벡터를 쓰면 → 역할별 관련성 측정 = 질문과 답변의 관련성 측정 가능