이러한 AWQ 방식은 특히 대형 언어 모델의 효율적인 배포와 실행에 매우 중요한 기술로, 제한된 리소스에서도 모델의 성능을 최대한 보존할 수 있게 해줍니다.
입력 텍스트: "고양이"
Step 1) 토큰화
"고양이" → ['고', '양', '이']
Step 2) 임베딩
각 토큰은 벡터로 변환됩니다. 간단히 4차원 벡터로 예시를 들어보겠습니다.
'고' → [1.0, 0.2, -0.3, 0.8]
'양' → [0.5, 1.1, 0.7, -0.4]
'이' → [-0.2, 0.9, 0.4, 0.6]
Step 3) 원본 가중치 행렬 (W)
이 임베딩 벡터들은 가중치 행렬과 곱해집니다. 예를 들어:
W = [
[2.7, -1.4, 0.9, -0.3],
[1.5, 0.8, -1.2, 2.1],
[-0.6, 1.7, 0.4, -0.9],
[1.1, -0.5, 2.3, 0.7]
]
Step 4) 활성화 값 (A) 계산
'고' 벡터와 가중치 행렬을 곱하면:
[1.0, 0.2, -0.3, 0.8] × W = [1.2, 0.8, 0.3, 1.5]
이것이 바로 활성화 값 A입니다.
Step 1) 영향도(I) 계산
수식: I = |A × W|
예시로 첫 번째 원소:
|1.2 × 2.7| = 3.24
모든 원소에 대해 계산:
I = [3.24, 1.12, 0.27, 0.45]
Step 2) 스케일 팩터(s) 결정
영향도가 높은 가중치는 더 정밀한 양자화가 필요합니다.
예를 들어 s = 0.5로 정했다면:
원본 가중치 2.7의 양자화:
1) 2.7/0.5 = 5.4
2) round(5.4) = 5
3) 5 × 0.5 = 2.5
이것이 양자화된 가중치가 됩니다.
영향도에 따라 다른 비트 수를 할당합니다:
영향도: 3.24 → 5비트
영향도: 1.12 → 4비트
영향도: 0.27 → 2비트
영향도: 0.45 → 3비트
실제 결과를 시각화하면:
정밀도
5비트 - *
4비트 - *
3비트 - *
2비트 - *
+-------------------->
W1 W2 W3 W4
이렇게 함으로써:
AWQ도 이와 비슷합니다. 중요한 정보는 정밀하게, 덜 중요한 정보는 덜 정밀하게 저장합니다.
한글 "나"를 컴퓨터가 이해하는 과정:
Step 1) 먼저 "나"를 숫자로 변환
"나" → [1.5, -0.8, 2.3, 0.4]
Step 2) 이 숫자들이 신경망을 통과할 때 사용되는 가중치
원본 가중치(W):
W1 = 2.7 (매우 중요한 가중치)
W2 = -1.4 (중요한 가중치)
W3 = 0.9 (덜 중요한 가중치)
W4 = -0.3 (가장 덜 중요한 가중치)
Step 3) 활성화 계산
"나"의 벡터와 가중치를 곱합니다:
1.5 × 2.7 = 4.05 (큰 영향)
-0.8 × -1.4 = 1.12 (중간 영향)
2.3 × 0.9 = 2.07 (작은 영향)
0.4 × -0.3 = -0.12 (아주 작은 영향)
Step 4) AWQ 적용
큰 영향을 주는 가중치는 더 정밀하게 저장:
W1(2.7)의 경우:
W4(-0.3)의 경우:
실제 변환 과정을 보여드리면:
원본: 2.7
5비트 사용: 10110
실제 저장값: 2.75
오차: 0.05
원본: -0.3
2비트 사용: 11
실제 저장값: -0.25
오차: 0.05
이렇게 하면:
이것이 AWQ의 핵심입니다. 마치 중요한 물건은 좋은 상자에, 덜 중요한 물건은 간단한 상자에 넣는 것처럼, 가중치의 중요도에 따라 다른 정밀도로 저장하는 것입니다.