대형 모델의 훈련과 추론은 종종 정확성 개념을 포함하며, 여러 유형이 있고, 동일한 정확도 수준에서 서로 다른 형식으로 나뉩니다. 또한 실제 사용 시나리오에서는 다정밀도와 혼합정밀도 개념도 존재합니다.
공통 정밀도
부동소수점 정확도: 배정밀도(FP64), 단정밀도(FP32, TF32), 반정밀도(FP16, BF16), 8비트 정확도(FP8), 4비트 정확도(FP4, NF4) 정량 정확도: INT8, INT4 (또는 INT3/INT5/INT6)
부동소수점 수는 부호, 지수, 가수비트의 세 부분으로 구성됩니다. 지수 비트가 클수록 표현할 수 있는 숫자의 범위가 넓어집니다. 가수숫자가 클수록 숫자의 정확도가 높아집니다.
표는 다음과 같이 요약합니다
| 판 | 심볼 비트 | 지수 비트 | 소수점 | 총 숫자 | | FP64 | 1 | 11 | 52 | 64 | | FP32 | 1 | 8 | 23 | 32 | | TF32 | 1 | 8 | 10 | 19 | | BF16 | 1 | 8 | 7 | 16 | | FP16 | 1 | 5 | 10 | 16 | | FP8 E4M3 | 1 | 4 | 3 | 8 | | FP8 E5M2 | 1 | 5 | 2 | 8 | | FP4 | 1 | 2 | 1 | 4 |
FP32: 32비트 부동소수점 번호, 데이터당 4바이트 TF32: 19비트 부동소수점 숫자, 각 데이터는 2바이트입니다 FP16: 16비트 부동소수점 숫자, 데이터당 2바이트 BF16: 16비트 부동소수점 숫자, 각 데이터는 2바이트입니다 Int8: 8비트 정수, 각 데이터는 1바이트를 차지합니다 Int4: 4비트 정수, 각 데이터는 0.5바이트입니다
왜 이렇게 정밀했나요
비용과 정확성 때문입니다. 우리는 모두 높은 정확도가 확실히 더 정확하다는 것을 알지만, 동시에 컴퓨팅과 저장 비용이 더 많이 듭니다. 정밀도가 낮으면 계산 정확도가 떨어지지만 계산 효율성과 성능을 향상시킬 수 있습니다. 따라서 다양한 정밀도를 통해 상황에 따라 가장 적합한 것을 선택할 수 있습니다. 이중 정밀도는 단일 정밀도 식보다 더 정확하지만, 저장 공간이 두 배이고 계산에 더 많은 시간이 걸립니다.
왜 대형 모델은 정량화되어야 할까요?
1. 메모리 사용량 감소 대형 모델은 보통 가중치와 활성화 값을 나타내기 위해 32비트 부동소수점(FP32) 또는 16비트 부동소수점 수(FP16)를 사용합니다. 양자화를 통해 이러한 고정밀도 값들을 낮은 정밀도 표현(예: 8비트 정수, INT8)으로 변환할 수 있어 모델의 저장 공간을 크게 줄일 수 있습니다. 이는 모바일 기기, 임베디드 시스템 등 자원이 제한된 기기에서의 배포에 중요합니다.
2. 추론 속도 가속화 양자화된 모델은 하드웨어에서 더 효율적으로 실행될 수 있습니다. 많은 현대 하드웨어(예: GPU, TPU, NPU 등)는 저정밀도 컴퓨팅을 위한 특화된 최적화 지원을 제공하여 더 빠른 양자화 연산을 가능하게 합니다. 또한, 저정밀도 계산은 비트 연산이 적어 계산 복잡도를 줄이고 추론 속도를 높입니다.
3. 전력 소비 감소 양자화된 모델은 컴퓨팅 자원의 필요성을 줄일 뿐만 아니라 전력 소비도 줄여줍니다. 이는 스마트폰, IoT 기기 등 배터리 구동 기기에서 특히 중요합니다. 낮은 전력 소비가 배터리 수명을 의미합니다.
4. 쉽게 배포할 수 있는 엣지 디바이스 많은 대형 모델이 처음에는 클라우드에서 학습 및 배포되었으나, 엣지 컴퓨팅의 발전으로 인해 점점 더 많은 응용 시나리오에서 엣지 장치에 모델을 배포해야 했습니다. 엣지 디바이스의 컴퓨팅 파워와 저장 자원이 제한적이기 때문에, 양자화는 이러한 모델들이 엣지 디바이스에서 더 효율적으로 실행되도록 도와줍니다.
5. 대역폭 요구량 감소 분산 추론이나 모델 업데이트 과정에서 양자화는 모델 전송에 필요한 대역폭을 줄일 수 있습니다. 이는 원격 지역의 IoT 기기처럼 네트워크 대역폭이 제한된 환경에서 유용합니다.
6. 모델 성능 유지 양자화는 정밀도 손실을 초래하지만, 적절한 양자화 방법(혼합정밀도 양자화, 훈련 후 양자화, 정량적 지각 훈련 등)을 통해 모델의 원래 성능을 대부분 유지할 수 있습니다. 따라서 실용적으로 정량화는 성능과 효율성 사이에서 좋은 균형을 이룰 수 있습니다.
메모리 참조
| 형 | 모든 10억 개의 매개변수는 메모리를 차지해야 합니다 | | float32 | 4G | | FP16/BF16 | 2G | | int8 | 1G | | int4 | 0.5G |
FP64 (이중 정밀도)
64비트 부동소수점은 일반적으로 IEEE 754에서 정의한 배정밀도 이진소수점 형식이며, 다음과 같습니다:
1자리 기호 11자리 인덱스 소수점 52자리
범위: ~2.23e-308 ... ~1.80e308, 15-17 십진법 정밀도 기준.
사용법:
이 형식은 고정밀도가 요구되는 과학적 계산에 사용됩니다. 딥러닝 계산에는 일반적으로 사용되지 않습니다. 소프트웨어 지원: 대부분의 C/C++ 시스템에서 이중 타입을 나타냅니다. TensorFlow(예: tf.float64)나 PyTorch(예: torch.float64 또는 torch.double)에서 지원됨. 하드웨어 지원: 일반적으로 x86 CPU에서 지원됩니다. 대부분의 GPU, 특히 RTX 시리즈를 포함한 게이밍 GPU는 FP64 성능에 심각하게 제한되어 있습니다(보통 FP32 성능의 1/32 수준이 아니라 1/2 수준). 최근 제한 없는 FP64 지원 GPU로는 테슬라 P40/P4와 쿼드로 GP100의 GP100/100/102/104, 테슬라 V100/쿼드로 GV100/타이탄 V의 GV100, 그리고 최근 발표된 A100의 GA100(흥미롭게도 새로운 Ampere 아키텍처는 3세대가 있음)이 있으며, 이는 FP64 지원 텐서 코어와 비교됩니다 IEEE 준수 FP64 처리가 이제 포함되어 V100의 FP64 성능을 2.5배 달성합니다.
FP32 (완전 정확도)
이 형식은 오랫동안 딥러닝의 주력 모델이었습니다. 또 다른 IEEE 754 형식인 단정밀도 부동소수점은 다음과 같습니다:
1자리 기호 8자리 인덱스 소수점 23자리 이상적으로는 훈련과 추론 모두 FP32에서 이루어져야 하지만, FP32는 FP16/BF16보다 두 배 느려서 실제로는 혼합정밀도 방법이 자주 사용되며, FP32 가중치를 정확한 '마스터 가중치'로 사용하고, FP16/BF16 가중치는 훈련 속도를 향상시키기 위한 순방향 및 후방 전파 계산에 사용되며, 마지막으로 FP32 주권 가중치는 경사 업데이트 단계에서 FP16/BF16 기울기로 업데이트됩니다.
훈련 중에는 항상 FP32가 주권 중량입니다. 실제로는 반정밀도 가중치가 추론 시 FP32와 유사한 정확도를 제공하는 경우가 많은데, 이는 모델 기울기가 업데이트될 때만 정확한 FP32 가중치가 필요하기 때문입니다. 즉, 추론할 때 반정밀도 가중치를 사용할 수 있어 GPU 메모리의 절반만으로도 같은 결과를 얻을 수 있습니다.
범위: ~1.18e-38 ... ~3.40e38, 정확도는 6-9 소수점.
사용법:
오랫동안 신경망 컴퓨팅의 표준 유형입니다. 신경망 내 가중치, 활성화 및 기타 값들은 오랫동안 기본적으로 FP32로 정해져 왔습니다. 특히 반복 계산의 많은 과학적 계산에서는 정확도가 부족해 오차 누적을 초래합니다. 소프트웨어 지원: 대부분의 C/C++ 시스템에서 float 타입을 나타냅니다. TensorFlow(예: tf.float32)/PyTorch(예: torch.float32 또는 torch.float)에서 지원됩니다. 하드웨어 지원: 일반적으로 x86 CPU에서 지원됩니다. 보통 NVIDIA/AMD GPU에서 지원됩니다.
FP16 (반 정확도)
마찬가지로, IEEE 754 표준 형식인 반정밀도 부동소수점 형식은 다음과 같습니다:
1자리 기호 5자리 인덱스 소수점 10자리 FP16 번호는 FP32보다 훨씬 낮은 수치 범위를 가지고 있습니다. 따라서 FP16은 매우 큰 수에 사용될 때는 오버플로우, 매우 작은 수를 나타낼 때는 언더플로우 위험에 노출되어 있습니다. 예를 들어, 10k × 10k를 계산하면 최종 결과는 100M이어야 하는데, FP16이 표현할 수 있는 최대 수는 64k이기 때문에 FP16은 이를 표현할 수 없습니다. 그래서 신경망 계산에서는 NaN(숫자가 아님)이 나오게 되는데, 계산이 계층화되고 배치 순서로 이루어지기 때문에, NaN이 나타나면 이전의 모든 계산이 사라지기 때문입니다. 일반적으로 손실 스케일링으로 이를 완화할 수 있지만, 이 방법이 항상 효과적이지는 않습니다.
범위: ~5.96e−8 (6.10e−5) ... 65504, 정확도는 4개의 유효 소수점입니다.
사용법:
딥러닝은 신경망에서 낮은 정밀도 계산이 중요하지 않은 것 같아 FP32 대신 FP16을 사용하는 경향이 있습니다. 추가된 정밀도는 아무 효과가 없고, 동시에 느려져서 메모리가 더 많이 필요하고 통신 속도도 느려집니다. 훈련에 사용할 수 있으며, 보통 혼합 정밀도 훈련(TensorFlow/PyTorch)을 사용합니다. 추론 속도를 높이기 위한 훈련 후 양자화에 사용할 수 있습니다(TensorFlow Lite). 학습 후 양자화에 사용되는 다른 형식으로는 INT8(8비트 정수), INT4(4비트), 심지어 INT1(이진 값)이 있습니다. 소프트웨어 지원: 현재 C/C++ 표준에는 포함되어 있지 않지만(하지만 짧은 플로트 제안이 있습니다). 일부 C/C++ 시스템은 __fp16 타입을 지원합니다. 그렇지 않으면 특수 라이브러리와 함께 사용할 수 있습니다. TensorFlow(예: tf.float16) / PyTorch(예: torch.float16 또는 torch.half)에서 지원됨. 하드웨어 지원: x86 CPU는 고유 타입으로서 지원되지 않습니다. 구형 게이밍 GPU의 지원은 좋지 않습니다(FP64 성능은 32/1, 자세한 내용은 GPU 게시글을 참고하세요). 현재 NVIDIA RTX 시리즈와 같은 최신 GPU에서 잘 지원되고 있습니다.
BFLOAT16 (반정밀도)
구글이 원래 개발한 또 다른 16비트 형식은 "브레인 플로팅 소수점 포맷"(줄여서 "bfloat16")이라고 불립니다. 이 이름은 구글 브레인에서 유래했습니다.
원래 IEEE FP16은 딥러닝 응용을 염두에 두고 설계되었고, 동적 범위가 너무 좁았습니다. BFLOAT16 이 문제를 해결해 FP32와 동일한 다이내믹 레인지를 제공합니다.
따라서 BFLOAT16는 다음과 같습니다:
1자리 기호 8자리 인덱스 소수점 7자리
bfloat16 형식은 IEEE 754 FP32로 축약되어 IEEE 754 FP32와의 빠른 변환이 가능합니다. bfloat16 형식으로 변환할 때는 지수 비트가 보존되지만, 가수수장은 절단으로 줄일 수 있습니다.
범위: ~1.18e-38 ... ~3.40e38, 소수점 3자리 포함. 사용법:
이제 FP16을 대체하는 것으로 보입니다. 손실 스케일링과 같은 특수 처리가 필요한 FP16과 달리, BF16은 딥 신경망을 훈련하고 실행할 때 FP32를 거의 직접적으로 대체합니다. 소프트웨어 지원: C/C++ 표준에는 없습니다. 특수 라이브러리와 함께 사용할 수 있습니다. TensorFlow(예: tf.bfloat16)/PyTorch(예: torch.bfloat16)에서 지원됩니다.
TF32
TensorFloat-32 또는 TF32는 NVIDIA A100 GPU의 새로운 수학 모드입니다.
반정밀도(FP16) 수학과 동일한 10비트 가수법을 사용하여 TF32는 AI 워크로드의 정밀도 요구를 충족할 충분한 여유를 갖추고 있음을 입증했습니다. 그리고 TF32는 FP32와 동일한 8비트 인덱스를 사용하므로 동일한 수치 범위를 지원할 수 있습니다.
기술적으로는 19비트 포맷입니다. "BFLOAT19" 같은 확장 정밀도 BFLOAT16이나 FP32처럼 정밀도가 낮아진 것으로 생각하세요.
그래서 TF32에는 다음과 같은 기능이 있습니다:
1자리 기호 8자리 인덱스 소수점 10자리 TF32의 장점은 FP32와 동일한 형식을 가지고 있다는 점입니다. TF32로 내적을 계산할 때, 입력 피연산수의 가수(가수)는 23비트에서 10비트로 반올림됩니다. 반올림 피연산자는 정확히 곱하여 일반 FP32에서 누적됩니다.
TF32 텐서 코어는 FP32 입력으로 동작하며, 코드 변경 없이 FP32에서 결과를 생성합니다. 비매트릭스 연산은 계속 FP32를 사용합니다. 이는 딥러닝 프레임워크와 HPC에서 FP32 입출력 데이터를 쉽게 가속화할 수 있는 방법을 제공합니다.
범위: ~1.18e-38 ... ~3.40e38, 정확도는 소수점 4자리입니다. 사용법:
TF32의 장점 중 하나는 컴파일러 지원이 가장 깊은 수준, 즉 CUDA 컴파일러 내부에서만 필요하다는 점입니다. 나머지 코드는 FP32를 덜 정밀하게 인식하지만, 동적 범위는 같습니다. TF32를 사용하는 것은 주로 라이브러리가 제대로 작동하는지 확인하기 위해 호출하는 것입니다. TF32의 존재 덕분에 텐서 코어의 속도를 크게 손들이지 않고 빠르게 플러그인을 사용할 수 있습니다. FP16이나 BFLOAT16 같은 포맷은 비트 배열이 달라서 더 많은 조정이 필요합니다. 하지만 이러한 포맷을 사용하면 메모리 대역폭이 줄어들어 실행 속도가 빨라집니다. 비교를 위해 A100의 최고 성능은 다음과 같습니다:
텐서 코어 없이 FP32: 19.5 TFLOPS TF32 텐서 코어: 156 TFLOPS (따라서 FP32 대신 TF32를 사용하면 속도를 올리기 쉽습니다). FP16/BF16 텐서 코어: 312 TFLOPS(따라서 FP16/BF16으로 합리적으로 전환하면 더 많은 속도 향상을 가져올 수 있지만, 비용이 더 큽니다). 소프트웨어 지원: C/C++ 표준에는 없습니다. CUDA 11 지원. 하드웨어 지원: GPU: NVIDIA A100이 최초로 지원되는 모델입니다
FP8
H100 GPU에서 도입된 이 기술은 더 큰 행렬 곱셈과 컨볼루션을 가능하게 하지만, 정밀도는 낮습니다.
H8에서 지원하는 FP100 데이터 타입은 실제로 신경망 훈련의 서로 다른 부분에 사용할 수 있는 두 가지 다른 데이터 타입입니다:
E4M3 - 1개의 기호 비트, 4개의 지수 비트, 3개의 소수점으로 구성됩니다. 최대 +/-448과 nan까지 저장할 수 있습니다. E5M2 - 부호 비트 1개, 지수 비트 5개, 소수점 2자리로 구성됩니다. 최대 +/-57344, +/-inf, nan 값을 저장할 수 있습니다. 다이내믹 레인지가 증가하면 저장된 값의 정확도가 떨어집니다.
부동소수점 데이터 타입의 구조. 표시된 모든 값(FP16, BF16, FP8 E4M3, FP8 E5M2)은 0.3952 값의 가장 근접한 표현입니다.
두 유형 모두 신경망 훈련 시 사용할 수 있습니다. 일반적으로 순방향 활성화와 가중치는 더 높은 정밀도가 필요하므로, 순방향 전달 시 E4M3 데이터 타입을 사용하는 것이 가장 좋습니다. 하지만 역전파에서는 네트워크를 통과하는 그라디언트가 정밀도 손실에 덜 취약하지만 더 높은 동적 범위가 필요합니다. 따라서 E5M2 데이터 포맷으로 저장하는 것이 가장 좋습니다. H100 TensorCore는 이러한 유형의 어떤 조합도 입력으로 지원하여, 각 텐서를 원하는 정밀도로 저장할 수 있습니다.
참조:
하이퍼링크 로그인이 보입니다.
하이퍼링크 로그인이 보입니다. |