vLLM에서 dtype=float16(FP16) 또는 dtype=bfloat16(BF16)이 많이 사용되는 이유는 메모리 사용량과 추론 속도의 균형이 매우 좋기 때문이다.
모델의 가중치는 일반적으로 float32로 저장되는 경우가 많다.
| 타입 | 비트 수 | 상대적 메모리 사용량 |
|---|---|---|
| float32 | 32bit | 100% |
| float16 | 16bit | 50% |
| bfloat16 | 16bit | 50% |
예를 들어 8B 파라미터 모델을 사용할 경우:
즉, 동일한 GPU에서:
현대 NVIDIA GPU는 FP16 연산을 매우 빠르게 수행하도록 설계되어 있다.
대표적인 GPU:
이러한 GPU는 Tensor Core를 사용하여 FP16 연산을 가속한다.
결과적으로:
등의 이점을 얻을 수 있다.
LLM은 이미 학습이 완료된 상태에서 주로 추론(Inference)에 사용된다.
따라서:
FP32 → FP16
으로 변경하더라도 대부분의 경우 출력 품질 차이가 거의 발생하지 않는다.
예를 들어:
등의 모델은 FP16 환경에서도 매우 유사한 성능을 보여준다.
최신 LLM에서는 FP16보다 BF16을 선호하는 경우가 많다.
| 구성 요소 | 비트 |
|---|---|
| Sign | 1 |
| Exponent | 5 |
| Mantissa | 10 |
| 구성 요소 | 비트 |
|---|---|
| Sign | 1 |
| Exponent | 8 |
| Mantissa | 7 |
BF16은 지수(Exponent)에 더 많은 비트를 할당한다.
결과적으로:
이라는 장점이 있다.
딥러닝에서는 다음과 같은 값들이 자주 등장한다.
0.000000001
1000000000
FP16은 이러한 극단적인 값을 충분히 표현하지 못해 Overflow 또는 Underflow가 발생할 수 있다.
반면 BF16은 FP32 수준의 표현 범위를 유지하므로:
등의 문제를 줄일 수 있다.
그래서 최근 LLM들은 대부분 BF16 기반으로 학습된다.
--dtype float32
주로 디버깅이나 연구 목적으로 사용한다.
--dtype float16
구형 GPU와의 호환성이 좋다.
--dtype bfloat16
현재 가장 많이 사용되는 dtype이다.
--dtype auto
모델 설정에 따라 자동으로 dtype을 선택한다.
예시:
특별한 이유가 없다면 가장 권장되는 옵션이다.
많은 사람들이 dtype과 양자화를 혼동한다.
하지만 둘은 서로 다른 개념이다.
연산 시 사용하는 데이터 타입
예:
모델 가중치를 더 작은 비트로 저장하는 기법
예:
| 방식 | 비트 수 |
|---|---|
| FP32 | 32 |
| FP16 | 16 |
| BF16 | 16 |
| INT8 | 8 |
| INT4 | 4 |
예시:
vllm serve model \
--quantization awq
이 경우 FP16 대비 메모리 사용량을 크게 줄일 수 있다.
| 환경 | 추천 dtype |
|---|---|
| RTX 3090 | FP16 또는 BF16 |
| RTX 4090 | BF16 |
| A100 | BF16 |
| H100 | BF16 |
| 모델 설정 그대로 사용 | auto |
| 디버깅 | FP32 |
| GPU 메모리 부족 | AWQ/GPTQ + FP16 |
vLLM에서 FP16과 BF16이 널리 사용되는 이유는 메모리 사용량을 절반으로 줄이면서도 높은 추론 성능을 유지할 수 있기 때문이다.
특히 최근 LLM은 대부분 BF16으로 학습되므로 최신 GPU를 사용한다면 다음 옵션이 가장 일반적인 선택이다.
--dtype bfloat16
또는
--dtype auto
메모리가 부족한 경우에는 dtype을 낮추는 것보다 AWQ, GPTQ와 같은 양자화 기법을 함께 사용하는 것이 더 큰 효과를 얻을 수 있다.