
좋은 아침입니다.
KV Cache는 이전 토큰들의 Key와 Value를 저장해두고 재사용하여 LLM의 추론 속도를 높이는 방법이었습니다.
하지만 LLM을 실제로 실행할 때는 속도만큼 중요한 문제가 하나 더 있습니다.
바로 메모리 사용량입니다.
LLM은 파라미터 수가 매우 많기 때문에 모델을 GPU 메모리에 올리는 것부터 큰 부담이 됩니다.
이번 글에서는 모델을 더 가볍게 실행하기 위한 방법인 Quantization(양자화) 에 대해 알아보겠습니다.
LLM은 수십억 개에서 수천억 개의 파라미터를 가지고 있습니다.
모델의 파라미터는 보통 소수점 값을 가집니다.
예를 들어 다음과 같은 값들이 있다고 가정해보겠습니다.
0.13452
-1.28491
3.58213
0.00092
이러한 값들은 일반적으로 FP32, FP16, BF16 같은 부동소수점 형식으로 저장됩니다.
문제는 모델이 커질수록 이 값을 저장하는 데 필요한 메모리도 함께 커진다는 점입니다.
예를 들어 7B 모델은 약 70억 개의 파라미터를 가집니다.
파라미터 하나를 16-bit로 저장한다고 해도 상당한 GPU 메모리가 필요합니다.
그래서 모델을 더 작은 비트로 표현하여 메모리 사용량을 줄이는 방법이 필요해졌습니다.
이 방법이 Quantization입니다.
Quantization은 모델의 가중치나 연산에 사용되는 값을 더 낮은 정밀도로 표현하는 방법입니다.
기존에는 모델의 파라미터를 FP16이나 FP32처럼 비교적 높은 정밀도로 저장했다면,
Quantization에서는 이를 INT8, INT4처럼 더 낮은 비트로 표현합니다.
FP32
-> 32-bit로 값 표현
FP16 / BF16
-> 16-bit로 값 표현
INT8
-> 8-bit로 값 표현
INT4
-> 4-bit로 값 표현
비트 수가 줄어들면 하나의 값을 저장하는 데 필요한 메모리도 줄어듭니다.
예를 들어 FP16으로 저장하던 값을 INT8로 바꾸면 이론적으로 메모리 사용량을 절반 정도 줄일 수 있습니다.
INT4를 사용하면 더 많이 줄일 수 있습니다.
처음에는 이런 의문이 들 수 있습니다.
"소수점 값을 대충 표현하면 성능이 크게 떨어지지 않을까?"
물론 정밀도를 낮추면 정보 손실이 발생합니다.
하지만 LLM의 모든 파라미터가 아주 높은 정밀도를 반드시 필요로 하는 것은 아닙니다.
모델의 가중치 값들을 보면 일정한 범위 안에 분포하고 있고
이를 적절한 스케일로 변환하면 낮은 비트로도 어느 정도 표현할 수 있습니다.
예를 들어 다음과 같은 값을
-1.0 ~ 1.0 사이의 실수
몇 개의 구간으로 나누어 표현하는 방식입니다.
-1.0
-0.5
0
0.5
1.0
물론 원래 값과 완전히 같지는 않습니다.
하지만 메모리 사용량을 크게 줄이면서도 모델 성능을 어느 정도 유지할 수 있다면, 실제 서비스에서는 매우 큰 장점이 됩니다.
Quantization은 여러 방식으로 나눌 수 있습니다.
LLM에서 자주 접하는 방식은 다음과 같습니다.
Quantization
│
├── Weight Quantization
│
├── Activation Quantization
│
└── Weight-Only Quantization
각각의 목적은 조금씩 다릅니다.
Weight Quantization은 모델의 가중치 값을 낮은 비트로 표현하는 방법입니다.
LLM에서 가장 많이 이야기되는 양자화 방식입니다.
모델의 가중치는 파라미터 그 자체이기 때문에, 이를 줄이면 모델을 저장하고 불러오는 데 필요한 메모리를 크게 줄일 수 있습니다.
FP16 Weight -> INT8 / INT4 Weight
예를 들어 16-bit로 저장하던 가중치를 4-bit로 바꾸면, 같은 모델을 훨씬 적은 메모리로 올릴 수 있습니다.
개인 환경에서 LLM을 실행할 때 4-bit 양자화 모델을 많이 사용하는 이유도 여기에 있습니다.
Activation은 모델이 입력을 처리하는 중간 계산값입니다.
입력 토큰이 모델의 여러 Layer를 지나면서 중간 결과들이 계속 만들어집니다.
Activation Quantization은 이러한 중간 계산값도 낮은 비트로 표현하는 방법입니다.
가중치뿐만 아니라 중간 계산값까지 줄일 수 있기 때문에 메모리와 연산 비용을 더 줄일 수 있습니다.
다만 Activation은 입력에 따라 계속 달라지기 때문에 Weight Quantization보다 다루기 까다로운 편입니다.
LLM에서는 Weight-Only Quantization이라는 표현도 자주 등장합니다.
이 방식은 이름 그대로 모델의 가중치만 양자화하고,
Activation은 기존 정밀도를 유지하는 방식입니다.
Weight
-> INT4 / INT8
Activation
-> FP16 / BF16
가중치 메모리는 줄이면서도 계산 안정성을 어느 정도 유지할 수 있기 때문에 LLM Inference에서 자주 사용됩니다.
특히 모델을 GPU 메모리에 올리는 것이 가장 큰 문제일 때 효과적입니다.
Quantization의 가장 큰 장점은 모델을 더 가볍게 만들 수 있다는 점입니다.
정리하면 다음과 같습니다.
예를 들어 FP16으로는 실행하기 어려운 모델도
4-bit로 양자화하면 개인 GPU 환경에서 실행할 수 있는 경우가 있습니다.
그래서 로컬 LLM이나 오픈소스 LLM을 사용할 때 Quantization은 거의 필수적으로 등장합니다.
Quantization은 메모리 사용량을 줄이는 데 효과적이지만, 단점도 있습니다.
가장 큰 문제는 성능 저하입니다.
낮은 비트로 값을 표현하면 원래 값과 차이가 생기고,
이 차이가 모델의 출력 품질에 영향을 줄 수 있습니다.
특히 너무 낮은 비트로 양자화하면 다음과 같은 문제가 발생할 수 있습니다.
그래서 Quantization은 무조건 낮은 비트를 사용하는 것이 정답은 아닙니다.
메모리 사용량과 성능 사이의 균형을 맞추는 것이 중요합니다.
LLM을 사용하다 보면 8-bit, 4-bit 양자화 모델을 자주 보게 됩니다.
일반적으로 8-bit는 성능 저하가 비교적 적고 안정적인 편입니다.
반면 4-bit는 메모리를 더 많이 줄일 수 있지만, 성능 저하 가능성도 더 커집니다.
8-bit Quantization
-> 안정적이지만 메모리 절감 효과는 4-bit보다 작음
4-bit Quantization
-> 메모리 절감 효과가 크지만 성능 저하 가능성이 있음
그래서 실제 환경에서는 목적에 따라 선택합니다.
정확도가 중요하고 메모리가 어느 정도 충분하다면 8-bit를 사용할 수 있습니다.
반대로 제한된 GPU 메모리에서 큰 모델을 실행해야 한다면 4-bit를 선택할 수 있습니다.
이전 LLM Training 시리즈에서 QLoRA를 다룬 적이 있습니다.
QLoRA는 Quantization과 LoRA를 함께 사용하는 방법입니다.
Base Model을 4-bit로 양자화하여 메모리 사용량을 줄이고,
그 위에서 LoRA Adapter를 학습합니다.
1. Base Model 준비
2. Base Model을 4-bit로 Quantization
3. Quantization된 모델 위에서 LoRA Adapter 학습
여기서 Quantization은 모델을 가볍게 만들기 위한 기술이고,
LoRA는 일부 파라미터만 학습하기 위한 PEFT 기법입니다.
Inference 시리즈에서 다루는 Quantization은 주로 학습이 끝난 모델을 더 가볍게 실행하는 방법에 초점을 둡니다.
Quantization은 다음과 같은 상황에서 유용합니다.
특히 오픈소스 LLM을 직접 실행해보면 Quantization의 필요성을 바로 느끼게 됩니다.
모델 성능도 중요하지만, 실제로 모델을 메모리에 올릴 수 있어야 사용이 가능하기 때문입니다.
Quantization은 LLM을 더 낮은 비트로 표현하여 메모리 사용량을 줄이는 방법입니다.
모델 자체를 완전히 새로 학습하는 것이 아니라,
기존 모델을 더 가볍게 저장하고 실행하기 위한 최적화에 가깝습니다.
KV Cache가 추론 과정의 중복 계산을 줄여 속도를 개선했다면,
Quantization은 모델의 표현 방식을 줄여 메모리 사용량을 개선합니다.
두 기술 모두 LLM을 실제 환경에서 효율적으로 사용하기 위해 중요한 역할을 합니다.
최근에는 1.58 양자화(1.58-bit Quantization)과 같은 초저비트 양자화 방식도 연구되고 있습니다.
아마 이 분야에 대해서 관심이 있으신 분들은 한 번 쯤은 들어보셨을 것 입니다.
이 방식은 모델의 가중치를 단순히 INT4나 INT8로 표현하는 것이 아니라, 가중치를 세 가지 값(-1, 0, 1) 만을 사용하여 표현합니다.
세 가지 값을 표현하는 데 필요한 정보량은 이론적으로 bit 이기 때문에 1.58-bit Quantization이라는 이름이 붙었습니다.
대표적인 예가 Microsoft의 BitNe입니다.
하지만 BitNet은 일반적인 INT8이나 INT4 양자화와는 접근 방식이 조금 다릅니다.
앞에서 살펴본 Quantization은 대부분 학습이 완료된 모델을 더 작은 비트로 변환하여 사용하는(Post-Training Quantization) 방식입니다.
반면 BitNet은 기존 모델을 1.58-bit로 변환하는 것이 아니라, 처음부터 이러한 저비트 가중치를 고려하여 학습하도록 설계된 모델입니다.
따라서 BitNet은 일반적인 추론(Inference) 최적화를 위한 Quantization이라기보다, 저비트 표현을 전제로 한 새로운 모델 학습 방식에 가깝습니다.
현재도 관련 연구가 활발히 진행되고 있으며, 앞으로 더 적은 메모리와 연산량으로 LLM을 실행하기 위한 중요한 방향 중 하나로 주목받고 있습니다.
이번 글에서는 Quantization에 대해 알아보았습니다.
핵심 내용을 정리하면 다음과 같습니다.
다음 글에서는 LLM Inference 속도를 더 높이기 위한 방법인 Speculative Decoding에 대해 알아보겠습니다.
Speculative Decoding은 작은 모델이 먼저 여러 토큰 후보를 생성하고, 큰 모델이 이를 검증하는 방식으로 추론 속도를 개선하는 방법입니다.
부족한 글 읽어주셔서 감사합니다.
틀린 내용이나 피드백은 댓글로 남겨주시면 감사하겠습니다.
감사합니다.