Mixed Precision Training, FP32 vs TF32 vs BF32 vs fp16 #68
luckyvickyricky
started this conversation in
General
Replies: 1 comment
-
프로젝트 전반에 적용하기에는 무리가 있는 내용이라 discussion으로만 기록합니다.(필요 하드웨어 RTX 30XX, A100이상의 Ampere 아키텍쳐) |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
FP32, TF32, BF32, fp16에 대한 간단한 정리
*fp16을 쓰더라도 실제로는 불안정성으로 인해 중요한 연산은 여전히 fp32를 유지하여 메모리를 실제로는 1.5배까지 사용할 수 있다.
FP32와 TF32는 정밀도 높은 계산의 처리량 최적화 측면에서 비교 되며, FP16과 BF16은 메모리 절감 및 연산 효율성 측면에서 비교 될 수 있다.
Mixed Precision Training
Mixed Precision Training은 일부 변수에 대해 낮은 정밀도의 수치 형식을 사용함으로써 모델 학습의 계산 효율을 최적화하는 기법이다. 전통적으로 대부분의 모델은 변수들을 표현하고 처리하기 위해 32비트 부동 소수점 정밀도(fp32 또는 float32)를 사용한다. 하지만 모든 변수에서 높은 정밀도가 필요한 것은 아니다. 일부 변수의 정밀도를 16비트 부동 소수점(fp16 또는 float16)과 같은 낮은 수치 형식으로 줄임으로써 계산 속도를 높일 수 있다. 이 접근법에서는 일부 계산은 반 정밀도(half precision)로, 일부는 여전히 전체 정밀도(full precision)로 수행되기 때문에 Mixed Precision Training이라고 불린다.
Mixed Precision Training은 보통 fp16(float16) 데이터 유형을 사용하여 이루어진다. 하지만 일부 GPU 아키텍처(예: Ampere 아키텍처)에서는 bf16 및 tf32(CUDA 내부 데이터 유형)와 같은 데이터 유형도 제공한다. 이러한 유형의 차이점은 NVIDIA Blog를 통해 확인할 수 있으며 아래 사용법을 제공한다.
fp16
Mixed Precision Training의 주요 장점은 활성화값을 반 정밀도(fp16)로 저장함으로써 얻을 수 있다. 기울기 역시 반 정밀도로 계산되지만, 최적화 단계에서는 다시 전체 정밀도로 변환되므로 여기서 메모리 절감 효과는 없다. fp16을 사용하는 이유는 메모리 효율이 아닌 계산 속도에 있다.
그 이유는 현대의 GPU(특히 NVIDIA의 Ampere 아키텍처 등)는 fp16 연산을 처리하는 Tensor Cores와 같은 특수 하드웨어를 가지고 있기 때문이다. 이러한 하드웨어는 낮은 정밀도인 fp16 형식을 사용함으로써 계산 속도를 크게 높일 수 있다. 이로 인해 학습 시간도 줄어들게 된다.
즉, fp16은 메모리를 아끼기 위한 것이 아니라, 연산 속도 향상을 위해 사용되는 것이다. 모델을 더 빠르게 훈련시키기 위해서는 GPU의 연산 능력을 최대한 활용하는 것이 중요한데, fp16을 사용하면 이러한 목적을 달성할 수 있다.
다만 fp16을 사용할 때 모든 계산을 반 정밀도로 처리하는 것이 아니라 중요한 연산은 여전히 fp32를 유지하여 모델의 정확도를 유지하면서도 속도를 높이는 것이다. 이 혼합된 접근 방식이 바로 Mixed Precision Training이며, 이 때문에 fp16을 사용해도 메모리에서 이점은 없더라도 계산 효율 면에서 중요한 이점이 있다.
Mixed Precision Training은 더 빠른 계산을 가능하게 하지만, 특히 작은 배치 크기의 경우 더 많은 GPU 메모리가 사용될 수 있다. 이는 모델이 GPU에 16비트와 32비트 정밀도로 모두 존재하기 때문으로, 결과적으로 GPU 상에서 원래 모델의 약 1.5배 크기를 차지하게 된다.
Mixed Precision Training을 활성화하려면 fp16 플래그를 True로 설정하면 된다.
BF16
Ampere 또는 그 이상의 하드웨어(RTX 3090, A100이상) 를 사용할 수 있다면, BF16을 사용하여 Mixed Precision Training과 평가를 수행할 수 있다. BF16은 FP16보다 정밀도는 낮지만, 훨씬 더 큰 동적 범위를 가지고 있다. FP16에서 표현할 수 있는 가장 큰 수는 65504이며, 이를 초과하는 수는 오버플로우가 발생한다. 반면 BF16은 최대 3.39e+38의 값을 가질 수 있으며, 이는 FP32와 거의 동일하다. 그 이유는 둘 다 수치 범위를 나타내는 데 8비트를 사용하기 때문이다.
Trainer에서 BF16을 활성화하려면 다음과 같이 설정하면 된다.
BF16은 더 큰 동적 범위를 가지고 있기 때문에, 오버플로우 문제를 줄이면서도 Mixed Precision Training의 이점을 취할 수 있다. Ampere와 같은 최신 하드웨어에서는 BF16을 사용하여 모델 학습을 최적화하는 것이 좋은 선택일 수 있다.
TF32
Ampere 하드웨어(RTX 3090, A100이상)는 TF32를 지원한다. TF32는 FP32와 동일한 수치 범위(8비트)를 가지지만, 정밀도는 23비트 대신 10비트(FP16과 동일)만 사용하며 전체적으로 19비트만 사용한다.
TF32가 "마법 같다"고 불리는 이유는 FP32를 사용한 일반적인 학습 및 추론 코드에서 TF32 지원을 활성화하면 최대 3배의 처리량 향상을 얻을 수 있기 때문이다. 이를 위해 다음과 같은 코드를 추가하면 된다.
위 설정을 추가하면, 사용 중인 GPU가 Ampere 시리즈인 경우 CUDA가 가능한 한 FP32 대신 TF32를 자동으로 사용하게 된다. NVIDIA의 연구에 따르면 대부분의 머신러닝 학습 작업에서 TF32 학습을 사용할 때 FP32와 동일한 퍼플렉서티(perplexity)와 수렴(convergence)을 보인다고 한다. 이미 FP16 또는 BF16 혼합 정밀도를 사용 중이라면 TF32가 처리량을 향상하는 데 도움이 될 수 있다.
Trainer에서 TF32 모드를 활성화하려면 다음과 같이 설정할 수 있다.
TF32는 tensor.to(dtype=torch.tf32)로 직접 접근할 수 없다. 이는 CUDA의 내부 데이터 유형이기 때문이다. TF32 데이터 유형을 사용하려면 torch>=1.7이 필요하다.
TF32와 다른 정밀도의 차이에 대한 추가 정보는 RTX-3090 및 A100에 대한 벤치마크를 참조할 수 있다.
Beta Was this translation helpful? Give feedback.
All reactions