1. 정밀도란 무엇인가
컴퓨터에서 정밀도(Precision)란 하나의 숫자를 표현하는 데 사용하는 비트(bit) 수를 의미한다. 비트 수가 많을수록 더 넓은 범위의 숫자를, 더 세밀하게 표현할 수 있다. 반대로 비트 수가 적으면 표현 가능한 범위가 좁아지고, 숫자 사이의 간격이 벌어진다.
딥러닝에서 "정밀도"라 하면 보통 모델의 가중치(weight)와 활성화(activation) 값을 몇 비트로 저장·연산하느냐를 가리킨다. 이 선택이 모델의 메모리 사용량, 연산 속도, 그리고 수치적 정확성을 좌우한다.
2. 숫자를 표현하는 두 가지 방식
컴퓨터가 숫자를 다루는 방식은 크게 정수형과 부동소수점형으로 나뉜다.
2.1 정수형 (Integer, INT)
소수점 없이 정수만 표현한다. 구조가 단순하고 연산이 빠르다.
INT8 예시 (8비트, 부호 있음):
┌──────────────────────────┐
│ 부호(1bit) │ 값(7bit) │
│ 0 │ 1100100 │ → +100
└──────────────────────────┘
표현 범위: -128 ~ +127 (총 256단계)
정수형은 소수점 이하를 표현할 수 없지만, 연산이 매우 빠르고 하드웨어 효율이 높다. 양자화에서 INT8, INT4 등이 바로 이 정수형이다.
2.2 부동소수점형 (Floating Point, FP)
실수를 표현하기 위한 방식이다. "부동소수점"이라는 이름은 소수점의 위치가 고정되지 않고 떠다닌다(浮動)는 뜻에서 왔다.
부동소수점은 숫자를 과학적 표기법(scientific notation)과 같은 원리로 저장한다.
일상적 과학적 표기법:
0.000123 → 1.23 × 10⁻⁴
98500 → 9.85 × 10⁴
컴퓨터의 부동소수점도 같은 구조:
값 = (-1)^부호 × 1.가수 × 2^지수
모든 부동소수점 수는 세 부분으로 구성된다.
┌────────┬──────────┬─────────────────────┐
│ 부호 │ 지수 │ 가수(소수부) │
│ Sign │ Exponent │ Mantissa(Fraction) │
│ 1bit │ E bits │ M bits │
└────────┴──────────┴─────────────────────┘
- 부호(Sign): 양수/음수를 결정한다. 0이면 양수, 1이면 음수이며, 항상 1비트를 차지한다.
- 지수(Exponent): 숫자의 크기 범위(얼마나 큰/작은 수를 표현할 수 있는지)를 결정한다. 비트가 많을수록 아주 큰 수와 아주 작은 수를 모두 표현할 수 있다.
- 가수(Mantissa/Fraction): 숫자의 정밀도(유효 자릿수)를 결정한다. 비트가 많을수록 숫자 사이의 간격이 촘촘해져 세밀한 값을 구분할 수 있다.
핵심 직관: 지수 비트 = "줌 범위" (얼마나 넓게 볼 수 있나), 가수 비트 = "해상도" (얼마나 선명하게 볼 수 있나)
3. 주요 정밀도 포맷 상세
3.1 FP32 (단정밀도, Single Precision)
┌──────┬───────────┬──────────────────────────────┐
│ 부호 │ 지수(8bit)│ 가수(23bit) │
│ 1bit │ 8bit │ 23bit │
└──────┴───────────┴──────────────────────────────┘
총 32비트 = 4바이트
- IEEE 754 표준의 기본 실수형이다. C/Python에서 float의 기본값이기도 하다.
- 유효 자릿수 약 7자리, 표현 범위 약 ±3.4 × 10³⁸이다.
- 딥러닝 학습의 전통적 기본 정밀도였으나, LLM 시대에는 메모리 부담이 커서 거의 사용하지 않는다.
- 파라미터 1개 = 4바이트 → 7B 모델 = 약 28GB이다.
3.2 FP16 (반정밀도, Half Precision)
┌──────┬───────────┬─────────────────┐
│ 부호 │ 지수(5bit)│ 가수(10bit) │
│ 1bit │ 5bit │ 10bit │
└──────┴───────────┴─────────────────┘
총 16비트 = 2바이트
- FP32의 절반 크기다. GPU(NVIDIA Tensor Core)에서 하드웨어 가속을 받는다.
- 유효 자릿수 약 3.3자리, 표현 범위 약 ±6.5 × 10⁴이다.
- 문제점: 지수가 5비트뿐이라 표현 범위가 좁다. 학습 중 gradient가 범위를 벗어나면 오버플로(inf)나 언더플로(0)가 발생할 수 있다.
- 파라미터 1개 = 2바이트 → 7B 모델 = 약 14GB이다.
3.3 BF16 (Brain Floating Point 16)
┌──────┬───────────┬────────────┐
│ 부호 │ 지수(8bit)│ 가수(7bit) │
│ 1bit │ 8bit │ 7bit │
└──────┴───────────┴────────────┘
총 16비트 = 2바이트
- Google Brain에서 제안한 포맷이다. FP32와 지수 비트가 동일(8bit)하여 표현 범위가 같다.
- 대신 가수가 7비트로 줄어 정밀도(유효 자릿수)는 낮다.
- 딥러닝 학습에 최적화된 포맷이다. 범위가 넓어 오버플로/언더플로 문제가 적고, 크기는 FP16과 동일하다.
- LLM 학습 시 가장 많이 사용되는 포맷이다. vLLM에서 --dtype bfloat16 옵션으로 지정한다.
- NVIDIA A100 이상, AMD MI 시리즈 등 최신 GPU에서 하드웨어 지원을 받는다.
3.4 FP8 (8비트 부동소수점)
FP8에는 두 가지 변형이 있다.
E4M3 (정밀도 우선):
┌──────┬───────────┬─────────┐
│ 부호 │ 지수(4bit)│ 가수(3bit)│
└──────┴───────────┴─────────┘
E5M2 (범위 우선):
┌──────┬───────────┬─────────┐
│ 부호 │ 지수(5bit)│ 가수(2bit)│
└──────┴───────────┴─────────┘
총 8비트 = 1바이트
- NVIDIA H100/H200에서 하드웨어 지원을 받는 차세대 학습·추론 포맷이다.
- E4M3: 가수가 3비트로 정밀도가 높아 가중치(weight) 저장에 적합하다.
- E5M2: 범위가 넓어 gradient 저장에 적합하다.
- vLLM에서 KV Cache를 FP8로 양자화하면 동시 처리량을 늘릴 수 있다.
3.5 INT8 / INT4 (정수 양자화)
INT8:
┌──────────────────────────┐
│ 부호(1bit) │ 값(7bit) │ → -128 ~ +127 (256단계)
└──────────────────────────┘
INT4:
┌─────────────────┐
│ 부호(1bit) │ 값(3bit) │ → -8 ~ +7 (16단계)
└─────────────────┘
- 부동소수점이 아닌 정수형이다. 소수점 표현이 불가능하다.
- 가중치를 정수로 매핑하고, 별도의 스케일 팩터(scale factor)와 제로 포인트(zero point)를 저장하여 원래 값을 근사적으로 복원한다.
- AWQ, GPTQ 등의 양자화 기법이 만드는 결과가 바로 INT4/INT8 가중치다.
4. 포맷별 비교 한눈에 보기
| 포맷 | 비트 수 | 지수 | 가수 | 파라미터당 크기 | 7B 모델 메모리 | 주 용도 |
| FP32 | 32 | 8 | 23 | 4 바이트 | ~28 GB | 전통적 학습 (현재는 거의 미사용) |
| FP16 | 16 | 5 | 10 | 2 바이트 | ~14 GB | 추론, Mixed Precision 학습 |
| BF16 | 16 | 8 | 7 | 2 바이트 | ~14 GB | LLM 학습·추론 표준 |
| FP8 (E4M3) | 8 | 4 | 3 | 1 바이트 | ~7 GB | 차세대 학습·추론 |
| INT8 | 8 | - | - | 1 바이트 | ~7 GB | 양자화 추론 |
| INT4 | 4 | - | - | 0.5 바이트 | ~3.5 GB | 양자화 추론 (AWQ/GPTQ) |
5. 지수(Exponent)가 LLM 답변 품질에 미치는 영향
지수 비트는 "얼마나 크거나 작은 수를 표현할 수 있느냐"를 결정한다. LLM에서 이것이 문제가 되는 대표적인 상황이 Attention Score 계산이다.
5.1 Attention에서 일어나는 일
Transformer의 Attention은 softmax(QK^T / √d) 를 계산한다. 이때 QK^T 내적값이 아주 크거나 작아질 수 있다. 시퀀스가 길어지면 특정 토큰에 대한 attention 값이 극단적으로 커지는 경우가 발생한다.
토큰 5000개짜리 문서를 읽는 상황:
softmax 입력값: [..., 0.001, 0.0003, 88.7, 0.0001, ...]
↑ 특정 토큰에 대한 강한 주목
FP16 (지수 5bit, 범위 ±65,504):
→ 88.7 자체는 표현 가능하다.
→ 하지만 softmax는 내부적으로 exp(88.7)을 계산한다.
→ exp(88.7) ≈ 3.4 × 10³⁸ ← FP16 범위 초과 → inf (오버플로!)
→ softmax 결과가 NaN이 되어 출력이 완전히 깨진다.
BF16 (지수 8bit, 범위 ±3.4 × 10³⁸):
→ FP32와 동일한 범위이므로 오버플로 없이 정상 처리된다.
5.2 실제로 어떤 문제가 생기는가
지수 범위 부족으로 인한 오버플로가 발생하면, 모델 출력이 구조적으로 붕괴한다. 이는 단순히 "약간 부정확한 답변"이 아니라, 답변 자체가 생성 불가능한 상태가 되는 것이다.
정상 출력 (BF16):
"서울의 인구는 약 950만 명입니다."
오버플로 발생 시 (FP16, 긴 문맥):
"서울의 인구는 는는는는는는는는는는..." ← 무한 반복
또는
"서울의 ████████████" ← 깨진 토큰 출력
또는
아예 응답 생성 실패 (NaN 전파)
이것이 FP16 대신 BF16이 LLM 학습과 추론의 표준이 된 핵심적인 이유다. 지수 8비트가 주는 넓은 범위 덕분에 긴 시퀀스, 대규모 배치에서도 안정적으로 동작한다.
6. 가수(Mantissa)가 LLM 답변 품질에 미치는 영향
가수 비트는 "숫자 사이를 얼마나 촘촘하게 구분할 수 있느냐"를 결정한다. 이것이 부족하면 비슷하지만 다른 의미를 가진 토큰들을 구분하지 못하는 문제가 생긴다.
6.1 다음 토큰 선택에서 일어나는 일
LLM이 다음 토큰을 고를 때, 어휘(vocabulary) 전체에 대한 확률을 계산한다. 예를 들어 Qwen3-8B의 어휘 크기가 약 150,000개라면, 150,000개 토큰 각각에 확률을 매기는 것이다.
"서울의 인구는 약 ___" 다음 토큰 확률:
정밀도가 충분할 때 (FP16, 가수 10bit):
"950" → 0.23401
"천" → 0.23398
"900" → 0.18220
"1" → 0.12005
...
→ "950"과 "천"의 확률 차이 = 0.00003
→ 구분 가능하다. "950"이 정확하게 선택된다.
정밀도가 부족할 때 (INT4, 16단계):
"950" → 0.234
"천" → 0.234 ← 같은 값으로 합쳐진다!
"900" → 0.182
"1" → 0.120
→ 둘 다 동일 확률이 되어 선택이 사실상 무작위가 된다.
→ 운에 따라 "천만"이 나올 수도, "950만"이 나올 수도 있다.
6.2 오차가 누적되는 경우
이 현상이 한두 토큰에서만 일어나면 체감이 거의 없다. 하지만 수학 문제 풀이나 코드 생성처럼 매 토큰의 선택이 정확해야 하는 태스크에서는 오차가 누적된다.
질문: "372 × 48은?"
FP16 (구분 가능):
3→7→2→ ×→ 4→8→ =→ 1→7→,→8→5→6 ✓ 정답 (17,856)
INT4 (구분 흐릿):
3→7→2→ ×→ 4→8→ =→ 1→7→,→8→4→6 ✗ 오답 (17,846)
↑ "5"와 "4"의 확률이 거의 같았는데
정밀도 부족으로 잘못 선택된 것이다.
이처럼 정밀한 추론이 연쇄적으로 이어지는 태스크에서는 가수 부족의 영향이 누적되어 최종 답변의 정확도를 떨어뜨린다.
6.3 영향이 적은 경우
반면 일상 대화나 요약처럼 여러 토큰이 비슷하게 적절한 태스크에서는 정밀도가 낮아도 체감 차이가 거의 없다. "오늘 날씨가 좋네요"든 "오늘 날씨가 화창하네요"든 둘 다 자연스러운 응답이기 때문이다.
태스크별 가수 정밀도 민감도:
민감도 높음 (정밀도 부족 시 품질 저하 뚜렷):
- 수학 연산, 논리 추론
- 코드 생성 (변수명·괄호·들여쓰기 한 글자 차이가 에러)
- 구조화된 데이터 추출 (JSON, 표)
- 장문의 단계별 추론 (Chain-of-Thought)
민감도 낮음 (정밀도 낮아도 체감 차이 작음):
- 일상 대화, 인사
- 텍스트 요약
- 감성 분류, 주제 분류
- 창작 글쓰기 (소설, 시 등)
7. 지수 vs 가수 — 영향의 차이 정리
지수 부족과 가수 부족은 LLM에서 질적으로 다른 문제를 일으킨다.
| 구분지수(Exponent) | 부족가수(Mantissa) | 부족 |
| 발생 지점 | 주로 Attention Score 계산 | 주로 최종 토큰 확률 분포 |
| 증상 | 출력 붕괴 (NaN, 무한 반복, 깨진 텍스트) | 미묘한 품질 저하 (오답, 부정확한 선택) |
| 심각도 | 치명적 — 답변 자체가 불가능하다 | 점진적 — 정밀 태스크에서 누적된다 |
| 비유 | 카메라 렌즈가 깨져서 사진 자체가 안 찍히는 것 | 해상도가 낮아서 세부 디테일이 뭉개지는 것 |
| 대표적 해결 | BF16 사용 (지수 8bit 확보) | 양자화 기법 고도화 (AWQ, GPTQ) |
양자화 기법들(AWQ, GPTQ)은 단순히 비트를 줄이는 것이 아니라, 이 "가수 부족으로 인한 품질 저하"를 최소화하는 데 핵심 노력을 기울이는 것이다.
8. 양자화와 정밀도의 관계
양자화란 결국 높은 정밀도 → 낮은 정밀도로의 변환이다. 이 과정에서 일어나는 일을 직관적으로 이해해 보자.
8.1 양자화 = 반올림의 확장
FP16 가중치 값이 0.0312, 0.0315, 0.0318인 세 값이 있다고 하자.
FP16 (연속적이고 촘촘한 눈금):
──┼──┼──┼──┼──┼──┼──┼──→
0.031 0.032 0.033 ...
세 값 모두 구분 가능하다.
INT4 (16단계밖에 없는 성긴 눈금):
──┼─────────┼─────────┼──→
0.03 0.04 0.05
세 값 모두 0.03으로 합쳐진다. (= 정보 손실)
이것이 양자화 시 정확도가 떨어지는 근본적인 이유다. 세밀한 차이를 표현할 수 있는 눈금이 줄어들기 때문이다.
8.2 스케일 팩터와 제로 포인트
정수형(INT)은 소수를 직접 표현할 수 없으므로, 부동소수점 값을 정수로 매핑하는 스케일(scale)과 제로 포인트(zero point)가 필요하다.
양자화: q = round((x - zero_point) / scale)
복원: x̂ = q × scale + zero_point
예를 들어, 가중치 범위가 [-0.5, +0.5]이고 INT8(-128~127)로 매핑한다면 다음과 같다.
scale = (0.5 - (-0.5)) / (127 - (-128)) = 1.0 / 255 ≈ 0.00392
zero_point = 0
원래 값 0.25 → q = round(0.25 / 0.00392) = round(63.8) = 64
복원 값 64 × 0.00392 = 0.25088 (오차: 0.00088)
AWQ/GPTQ 같은 기법들은 이 "반올림 오차"를 최소화하는 방법에서 차이가 나는 것이다.
9. 알아두면 좋은 추가 개념
9.1 Mixed Precision (혼합 정밀도)
하나의 모델 안에서 레이어나 연산 종류에 따라 서로 다른 정밀도를 섞어 쓰는 기법이다.
- 학습 시: 가중치는 FP32로 유지(master copy)하고, 순전파/역전파는 FP16/BF16으로 수행한다. 속도와 정확도를 모두 확보할 수 있다.
- 추론 시: 대부분 INT4로 양자화하되, 민감한 레이어(첫 번째/마지막 레이어, attention 등)는 FP16으로 유지한다.
- NVIDIA의 Automatic Mixed Precision(AMP)이 대표적인 구현이다.
9.2 오버플로와 언더플로
- 오버플로(Overflow): 표현 가능한 최댓값을 초과하여 inf(무한대)가 되는 현상이다. FP16에서 65,504를 넘으면 발생한다.
- 언더플로(Underflow): 표현 가능한 최소 양수보다 작아져 0이 되는 현상이다. 아주 작은 gradient가 사라지는 문제를 일으킨다.
- BF16이 LLM 학습에서 선호되는 이유가 바로 이것이다. 지수 비트가 FP32와 같아서 범위가 넓고, 오버플로/언더플로에 강하다.
9.3 Loss Scaling
FP16 학습 시 언더플로 문제를 완화하는 기법이다. Loss 값을 큰 수(예: 1024)로 곱해서 gradient를 키운 뒤, 가중치 업데이트 시 다시 나눈다. PyTorch의 GradScaler가 이 역할을 수행한다. BF16에서는 범위가 충분하여 Loss Scaling이 보통 불필요하다.
9.4 텐서 코어와 정밀도
NVIDIA GPU의 Tensor Core는 특정 정밀도에서만 하드웨어 가속이 동작한다.
| GPU 세대 | 지원하는 Tensor Core 정밀도 |
| V100 (Volta) | FP16 |
| A100 (Ampere) | FP16, BF16, TF32, INT8 |
| H100 (Hopper) | FP16, BF16, TF32, FP8, INT8 |
| B200 (Blackwell) | FP16, BF16, FP8, FP4, INT8 |
양자화 포맷을 선택할 때 사용 중인 GPU가 해당 포맷을 하드웨어 수준에서 지원하는지 확인하는 것이 중요하다. 소프트웨어 에뮬레이션으로도 동작은 하지만 속도 이점이 크게 줄어든다.
9.5 TF32 (TensorFloat-32)
┌──────┬───────────┬────────────┐
│ 부호 │ 지수(8bit)│ 가수(10bit) │
│ 1bit │ 8bit │ 10bit │
└──────┴───────────┴────────────┘
총 19비트 (내부 처리용, 저장은 FP32)
- NVIDIA A100에서 도입된 포맷이다. FP32의 범위(지수 8bit)와 FP16의 정밀도(가수 10bit)를 결합한 것이다.
- FP32 연산을 자동으로 TF32로 가속한다. 사용자가 코드를 바꿀 필요 없이 PyTorch에서 기본 활성화된다.
- 저장 포맷이 아니라 연산 포맷이므로, 메모리 사용량에는 영향이 없다.
10. 정리: 정밀도 선택 가이드
목적이 무엇인가?
│
├── LLM 학습 (Pre-training / Full Fine-tuning)
│ └── BF16 (지원 GPU) 또는 FP16 + Loss Scaling
│
├── LLM 추론 (정확도 최우선)
│ └── BF16 또는 FP16
│
├── LLM 추론 (속도·비용 최적화)
│ ├── GPU 메모리 여유 있음 → FP8 (H100 이상)
│ └── GPU 메모리 부족 → INT4 양자화 (AWQ/GPTQ)
│
└── 로컬/엣지 배포
└── INT4 양자화 (GGUF 포맷)
참고 자료
'📁 AI > 개념 정리' 카테고리의 다른 글
| [AI] 어텐션 메커니즘(Attention Mechanism) 쉽게 이해하기 (0) | 2026.03.26 |
|---|---|
| [AI] Zero-shot 학습(Zero-shot Learning, ZSL) (1) | 2025.03.25 |
| [AI/AWS]비정형 데이터 수집/저장(S3, Glue) (0) | 2025.02.04 |