한 줄 정의

F32는 숫자 하나를 32비트로 담는 부동소수점 정밀도 표기야. PyTorch 문서의 torch.float32·torch.float, CUDA의 단정밀도 float, 모델 카드에서 보이는 FP32가 같은 축에 놓여. 값 하나가 32비트라 4바이트를 쓰고, FP16이나 BF16의 16비트 값보다 저장·전송 단위가 2배 커.

그래서 F32는 “가볍게 돌리는 포맷”이라기보다 기준선에 가까워. 가중치, 활성값, logits, 일부 누산 경로에서 수치 흔들림을 줄이고 싶을 때 남기는 정밀도야. 대신 같은 텐서를 16비트로 옮길 때보다 메모리와 대역폭을 더 쓴다.

어떻게 작동하나

부동소수점은 부호, 지수, 유효숫자 쪽으로 값을 나눠 담아. 지수는 값이 얼마나 커지거나 작아질 수 있는지를 맡고, 유효숫자는 값 사이 간격이 얼마나 촘촘한지를 맡아. CUDA 문서에서 32비트 float는 최대값이 약 3.39e38, 최소 양의 정규값이 약 1.18e-38, epsilon이 2^-23으로 나온다. 이 숫자들은 F32가 16비트 포맷보다 넓은 기준선으로 쓰이는 이유를 보여 줘.

하지만 넓은 정밀도는 비용을 같이 가져와. 같은 LLM이라도 F32 가중치BF16 가중치보다 파일과 VRAM을 더 많이 차지해. 그래서 실무 런타임은 모델 전체를 F32로만 밀기보다, 큰 행렬곱은 BF16·FP16으로 돌리고 수치가 예민한 연산은 F32로 남기는 혼합 정밀도를 자주 써.

PyTorch AMP 문서도 이 감각을 그대로 보여 줘. linear나 convolution 같은 연산은 낮은 정밀도에서 빨라질 수 있지만, reduction처럼 동적 범위가 필요한 연산은 float32가 필요할 수 있다고 설명해. 그러니까 F32는 “느리지만 정확한 모드” 하나가 아니라, 연산별 dtype 선택표에서 기준이 되는 칸이야.

왜 중요한가

F32를 알아야 모델 카드의 파일 크기와 실행 비용을 덜 헷갈려. Hugging Face 모델 카드에서 Tensor type에 F32가 보이면 먼저 “이 모델을 어떤 정밀도 기준으로 읽어야 하지?”를 물어야 해. 특히 BF16과 F32가 같이 표시되면 전체 가중치가 전부 F32라는 뜻으로 바로 읽으면 안 돼.

Qwen 예시가 이 지점을 잘 보여 줘. Qwen/Qwen3.5-9B 원본 카드는 모델 이름은 9B지만 Hugging Face UI에서 Model size를 10B params로 표시하고, Tensor type에는 BF16 · F32를 같이 보여 줘. mlx-community/Qwen3.5-9B-MLX-bf16 변환본도 본문에서는 bfloat16 MLX 버전이라고 설명하지만, 파일 정보 영역에는 9B params, BF16 · F32, MLX, 18.8GB가 같이 나온다.

이런 표기를 보면 F32를 모델 이름처럼 읽지 말고, 파일 안의 tensor dtype과 실행 dtype을 확인하는 신호로 읽는 편이 맞아. config.json, safetensors index, 변환 스크립트, 런타임 로딩 옵션까지 봐야 실제로 어디가 F32이고 어디가 BF16인지 갈라진다.

BF16·FP16·FP8과 비교

BF16은 16비트지만 지수 폭을 넓게 남기는 포맷이야. PyTorch 표는 BF16을 S-E-M 1-8-7로 설명해. 값 범위는 F32와 비슷하게 가져가면서 저장 단위를 절반으로 줄일 수 있어서, 요즘 추론 기준선으로 많이 올라와.

FP16은 S-E-M 1-5-10이라 BF16보다 값 범위는 좁고 유효숫자 쪽은 조금 더 촘촘해. 특정 GPU 커널에서는 FP16이 빠를 수 있지만, overflow나 underflow가 더 빨리 보일 수 있어. FP8은 더 공격적인 8비트 선택지라 저장·전송 이득은 크지만 스케일링, 지원 GPU, 정확도 회귀 검사가 더 빡빡해져.

양자화와도 경계를 나눠야 해. F32, BF16, FP16, FP8은 부동소수점 dtype 축이고, INT8·INT4·Q4_K_M 같은 양자화는 값을 낮은 비트 격자와 scale로 다시 매핑하는 배포 기법이야. 같은 모델 카드나 파일명 안에 둘이 같이 등장해도 같은 칸에 넣으면 안 돼.

실무에서 읽는 법

F32 표기를 봤을 때 바로 할 일은 네 가지야.

  • 모델 카드의 Tensor type이 F32만인지, BF16·F32처럼 여러 개가 같이 나오는지 본다.
  • 파일 목록에서 safetensors shard, index, config가 어떤 dtype을 가리키는지 확인한다.
  • 런타임 로딩 옵션에서 torch_dtype, autocast, KV cache dtype, quantization 설정을 확인한다.
  • 같은 프롬프트 묶음으로 최대 VRAM, p95 지연시간, tokens/sec, 품질 지표를 비교한다.

F32가 필요한 구간은 보통 작게 잡는 게 좋아. logits, loss, 일부 reduction, normalization, 평가 기준선처럼 작은 수치 차이가 결과를 흔드는 곳은 F32를 남길 만해. 반대로 대형 행렬곱과 어텐션 경로가 메모리 대역폭 병목이라면 BF16·FP16 기준선도 같이 재야 해.

정리하면 F32는 모델이 더 똑똑하다는 배지가 아니야. 더 넓고 촘촘한 숫자 표현을 쓰는 기준선이고, 그만큼 파일·VRAM·대역폭 비용을 더 먹는 선택지야.