부호, 지수, 가수
IEEE 754 부동소수점 형식
모든 부동소수점 숫자는 세 개의 필드를 저장합니다:
- 부호 비트 (1 비트): 양수 또는 음수
- 지수 (E 비트): 크기 척도, 2의 정수 거듭제곱
- 가수 (M 비트): 소수 정밀도, 1.0과 ~2.0 사이의 숫자
총 비트 수 = 1 + E + M. 값은 대략 (-1)^sign (1 + mantissa) 2^(exponent - bias)와 같다.
훈련에 중요한 두 가지 속성:
동적 범위 = 2^(2^E) (대략). 지수 비트가 많을수록 오버플로 없이 더 작고 더 큰 숫자를 표현할 수 있다.
정밀도 = 2^M 개의 서로 다른 값이 2의 거듭제곱당 존재합니다. 맨티사 비트가 많을수록 연속된 2의 거듭제곱 사이의 표현이 더 세밀해집니다.
세 가지 형식
| 형식 | 전체 비트 | 부호 | 지수 | 맨티사 | 동적 범위 | 정밀도 |
|---|---|---|---|---|---|---|
| FP32 | 32 | 1 | 8 | 23 | ~10^-38 ~ ~10^38 | ~7자리 |
| FP16 | 16 | 1 | 5 | 10 | ~10^-5 ~10^5 | ~3 digits |
| FP8 E4M3 | 8 | 1 | 4 | 3 | ~2^-9 ~448 | ~2 digits |
FP8 E4M3는 "지수 비트 4개, 가수 비트 3개"를 의미합니다. 대안인 FP8 E5M2는 범위를 위해 정밀도를 교환합니다. ANDREA 실험에서는 트랜스포머 활성화가 좁은 크기 범위에 머무르기 때문에 추가 정밀도가 추가 범위보다 유리한 E4M3를 사용합니다.
매개변수당 바이트 수
왜 낮은 정밀도가 더 빠르게 실행되는가
메모리 대역폭이 훈련 속도를 지배한다
현대 GPU는 계산보다 메모리를 기다리는 데 더 많은 시간을 보낸다. RTX 4090은 1008 GB/s 메모리 대역폭과 165 TFLOPS FP16 계산 성능을 가진다. 전형적인 레이어는 VRAM에서 가중치를 읽고, 활성화를 곱한 후 결과를 다시 쓴다. 대역폭이, 계산이 아닌 처리량을 결정한다.
정밀도를 반으로 줄이면 매개변수당 바이트가 반으로 줄어들어, 동일한 가중치를 읽는 데 메모리 대역폭의 절반만 사용한다. 처리량이 대략 두 배 증가한다.
텐서 코어: 하드웨어 가속 행렬 곱셈
RTX 4090은 FP16 또는 FP8에서 직접 행렬 곱셈을 계산하는 전용 텐서 코어 유닛을 탑재하고 있습니다. 단일 텐서 코어 연산은 작은 블록(예: 16x16)을 한 사이클에 곱셈하며, 스칼라 FP32 곱셈보다 훨씬 빠릅니다.
ANDREA-120M의 실증 데이터:
| 정밀도 | Steps/min | 비고 |
|---|---|---|
| FP32 | ~3 | 기준; 텐서 코어 가속 없음 |
| FP16 | ~6 | cuBLAS 텐서 코어; 2배 속도 향상 |
| FP8 E4M3 | ~6 | 텐서 코어; FP16과 비슷함 |
FP8은 이 작업에서 FP16의 처리량을 이기지 못했습니다. 왜냐하면 계산 처리량이 더 이상 병목이 아니었기 때문입니다; 메모리 대역폭과 실행 오버헤드가 병목이 되었습니다. ANDREA-120M v3는 처리량을 잃지 않으면서도 여유로운 안전 마진을 위해 FP16 cuBLAS에서 6단계/분으로 출시됩니다.
FP8에서의 NaN 위험
FP8 E4M3은 ~2^-9에서 ~448까지의 숫자를 표현합니다. 이 범위를 벗어난 활성화나 그래디언트는 NaN(숫자가 아님)으로 오버플로우되거나 0으로 언더플로우됩니다. 단 하나의 NaN이 모든 후속 계산을 오염시킵니다: NaN이 포함된 행렬 곱은 모든 NaN을 반환합니다; 모든 NaN 그래디언트는 AdamW 상태를 손상시킵니다; NaN m & v를 가진 AdamW은 NaN 업데이트를 출력합니다; 가중치가 NaN이 됩니다; 전체 훈련 실행이 죽습니다.
ANDREA의 FP8 실험은 가끔 NaN 절벽을 발생시켜 loss scaling, scheduled precision switching, 또는 fallback 경로가 필요했습니다. FP16의 동적 범위(~10^-5 ~ ~10^5)는 NaN 이벤트가 복잡한 scaling 트릭 없이도 드물게 유지될 만큼 충분히 넓습니다.
새로운 실행을 위한 정밀도 선택
단일 4090에 120M 맞추기
인트로 레슨의 6-8배 배수
grow_a_language_model_intro에서 회상하듯이, 훈련 메모리는 대략 원시 가중치 수의 6-8배로, 다음을 고려합니다:
- 가중치 (1x)
- Adam 1차 모멘트 m (1x)
- Adam 2차 모멘트 v (1x)
- 그래디언트 버퍼 (1x)
- 활성화 & 임시 데이터 (~2-4x, 배치 및 컨텍스트에 따라 다름)
ANDREA-120M at FP16 with batch_size=8, context=1024:
| 구성 요소 | FP16 크기 |
|---|---|
| 가중치 | 240 MB |
| m (첫 번째 모멘트) | 240 MB |
| v (두 번째 모멘트) | 240 MB |
| 그래디언트 | 240 MB |
| 활성화값 | ~2-4 GB (배치, ctx) |
| 총합 | ~3.5 GB |
RTX 4090은 24 GB VRAM을 가집니다. ANDREA-120M은 FP16에서 ~14%를 사용합니다. 더 큰 배치 크기나 더 긴 컨텍스트 윈도우를 위한 충분한 여유 공간이 있습니다. ANDREA-12M은 총 1.4 GB만 사용했습니다.
혼합 정밀도가 존재하는 곳
ANDREA는 모든 것을 하나의 정밀도로 유지하지 않습니다. 혼합 정밀도 훈련은 다음을 저장합니다:
- 마스터 가중치: FP32 (훈련 안정성 보존)
- 전방 및 후방 계산: FP16 (텐서 코어 사용)
- AdamW 옵티마이저 상태: FP32 (m & v는 장기 꼬리 업데이트를 위해 정밀도 필요)
- 기울기 버퍼: FP16 (계산 측)
최종 메모리 예산은 둘 다를 혼합합니다. ANDREA의 실제 메모리 사용량은 순수 FP16(720 MB optimizer state)과 순수 FP32(1.44 GB optimizer state) 사이에 위치하며, m과 v가 FP32로 유지되기 때문에 FP32에 더 가깝습니다.
ANDREA-480M을 위한 예산 크기 조정
실전에서의 정밀도
인접 활동
정밀도와 연결된 세 가지 형제 활동:
- Activity 1: Intro / VRAM budget. 정밀도는 메모리 예산 산술의 모든 항을 곱한다. 6-8x 배수 규칙은 단위가 없으며; bytes-per-param이 단위를 준다.
- 활동 10: AdamW. 옵티마이저 상태 (m & v)는 일반적으로 순전파/역전파 계산이 FP16으로 실행되더라도 FP32로 유지됩니다. 이유: 옵티마이저의 장기 누적기 정밀도가 런타임 속도보다 더 중요합니다.
- 활동 12: 그래디언트 클리핑. 클리핑은 옵티마이저 상태 업데이트 전에 그래디언트 크기를 제한합니다. FP16 순전파/역전파 & FP32 옵티마이저에서 클리핑은 정밀도가 변경되는 경계와 오버플로우 위험이 집중되는 지점에서 발생합니다.
정밀도는 무료 조절 노브입니다: 변경하면 모델 훈련이 빨라지고 메모리 사용량이 줄어듭니다. 비용은 수치적 주의입니다: NaN 처리, 손실 스케일링, 혼합 정밀도 규율. ANDREA-120M v3이 그 보상을 보여줍니다: FP16이 모든 것을 절반으로 줄여 소비자 하드웨어에서 120M 매개변수를 23일 만에 훈련했습니다.