본문 바로가기
NLP/논문리뷰

[논문 Review] 19. Mixed Precision Training

by ㅣlㅣl 2024. 7. 25.
FP16 casting을 통해 메모리 사용량과 학습 시간을 단축시키자!

 

 

https://arxiv.org/abs/1710.03740

 

Mixed Precision Training

Deep neural networks have enabled progress in a wide variety of applications. Growing the size of the neural network typically results in improved accuracy. As model sizes grow, the memory and compute requirements for training these models also increases.

arxiv.org

 


Abstract

일반적으로 신경망의 크기를 늘리면 정확도가 향상되지만, 메모리와 컴퓨팅 요구 사항이 증가한다.

본 논문에서는 정확도가 손실되거나, 하이퍼파라미터를 수정해야 할 일 없이 half-precision floating point number를 사용해 신경망을 훈련하며, 이 때 Weights, activations, gradients가 IEEE half- precision format으로 저장된다.

해당 방식을 사용하면 메모리 요구량이 거의 절반으로 줄어들고, 연산 속도가 빨라진다.

 

half- precision은 single-precision보다 좁은 범위를 가지고 있기에, 중요한 정보 손실을 방지하기 위해 아래 기법을 사용한다.

  • 각 optimizer step 이후 gradients를 누적하는 weights의 single-precision(FP32) copy를 유지
    -> 해당 복사본은 forward & backpropagation weight update에 사용됨
  • 작은 크기의 gradient value를 보존하기 위한 loss scaling
    -> gradient = 0이 되는 것을 최소화함
  • single-precision accumulated outputs을 메모리에 저장하기 전에 half-precision으로 변환 (tensor core 연산)

 

 

1. Introduction

훈련 데이터셋 크기 증가, 모델 파라미터 숫자의 증가로 더 많은 컴퓨팅 및 메모리 리소스가 필요해졌다.

이 때 정밀도가 낮은 표현 및 산술을 사용하면, 같은 수의 값을 저장하는 데 더 적은 비트를 사용함으로써 메모리 부담을 줄일 수 있으며 프로세서의 연산시간도 줄일 수 있다.

 

따라서 single-precision(FP32) 를 IEEE half-precision(FP16) 형태로 바꿔 모델 정확도는 유지하면서 정밀도를 낮춘 학습을 진행하고자 한다.

FP16은 당연하게도 FP32보다 저장 가능 범위가 좁기 때문에, 앞의 Abstract에서 언급했던 3가지 기법을 사용해 성능 손실을 최소화 한다.

해당 방법론은 이미지 분류, 언어 모델링, 기계 번역 등 다양한 분야에 적용이 가능하며, 모델이나 학습 하이퍼파라미터를 변경할 필요가 없다.

 

Single Precision (FP32) & Half Precision (FP16)

더보기
출처 : https://hoya012.github.io/blog/Mixed-Precision-Training/

 보편적으로 FP32를 single precision, FP16을 Half precision으로 지칭한다.

 

2. Related work

정밀도를 낮춘 CNN을 훈련하는 방법에 대한 선행 연구들이 있었다.

  • binary weights + 다른 텐서 및 산술 연산은 모두 single precision
  • binary weights, activations + gradient single precision
  • weights, activations를 2, 4, 6 bits로 quantization
  • gradient를 포함한 모든 tensor binarize

그러나 이러한 모든 접근 방식은 무시할 수 없을 정도의 정확도 손실을 유발한다.

 

  • weights, activations, gradients 를 다양한 비트 수로 quantization
    • 정확도 향상
    • 여전히 약간의 정확도 손실 & 네트워크마다 적절한 비트 수 탐색 필요
    • 대규모 모델에서는 비실용적
  • 이전 weight & activation quantization을 그대로 사용하되, CNN에서 레이어 폭을 2배, 3배로 늘림
    • 정확도 향상
    • gradient는 여전히 single-precision으로 계산 및 저장됨
  • 16비트 fixed point representation을 사용해 정확도 손실 없이 CNN 훈련이 가능하다는 것을 입증

 

 

RNN 훈련에 대한 선행 연구도 존재한다.

  • GRU와 LSTM를 quantize하여 weights, activations의 비트 수를 줄임
    • 약간의 정확도 손실
    • 이 결과가 대규모 네트워크에도 적용되는지는 명확하지 않음
  • 언어 모델링, 음성 인식을 위해 훈련된 다양한 RNN 모델의 weights에 대해 binary, ternary, exponential quantization을 진행

위와 같은 접근 방식들은 gradient를 single-precision으로 남겨두므로, back propagation에 들어가는 계산 비용은 줄어들지 않는다.

 

우리의 연구는 선행 연구들과 다음 3가지 차이점이 존재한다.

  • 모든 tensor, forward & back propagation 연산은 FP16을 사용
  • 하이퍼파라미터 (e.g. layer width) 를 따로 조정하지 않음
  • 정확도 손실이 거의 발생하지 않음

 

 

3. Implementation

3.1 FP32 master copy of weights

mixed precision training에서는 weights, activations, gradient 모두 FP16으로 저장된다.

이후의 weight update는 다음 과정을 통해서 진행된다.

  • Master-Weights를 FP32 -> FP16 변환 (fp16 copy)
  • forward & backward propagation은 모두 FP16 연산 수행
  • weight update 과정에서 다시 FP32로 변환

이 과정을 통해 정확도 하락을 막고, FP32 훈련에 필요한 스토리지와 대역폭을 절반으로 줄였다.

[그림 1] Mixed precision training 방법

 

그렇다면 왜 전체 과정을 FP16으로 진행하지 않고, weight update를 F32로 진행해서 이런 귀찮은 과정을 해야 하는 것일까?

업데이트 (learning rate * weight gradient) 가 너무 작아지는 경우 FP16으로 표현할 수 없기 때문이다.
FP16에서 2^-24보다 작은 값들은 모두 0이 되므로 모델 정확도에 악영향을 미칠 수 있다.
따라서 update를 할 때에는 single-precision copy를 사용해 문제를 해결하는 것이다.

[그림 2b] FP32 가중치를 사용한 중국어 음성 인식 훈련의 weight gradient에 대한 히스토그램

해당 도식은 중국어 음성 인식 훈련(FP32)의 weight gradient에 대한 히스토그램인데, 빨간색 선 왼쪽의 gradient 부분은 FP16에서 모두 0으로 표현되므로 weight gradient 손실이 발생한다.

 

 

 

3.2 Loss Scaling

해결해야 하는 또 다른 문제가 존재하는데, 실제 gradient 값은 매우 작은 값에 몰려있어 FP16의 표현 가능 범위를 벗어난다는 것이다.

아래 그림은 Multibox SSD detector network를 FP32 훈련할 때 모든 레이어의 activation gradient values 이다.

[그림 3] activation gradient values histogram

이를 FP16으로 표현할 경우, 대부분의 값은 표현 가능 범위보다 작아 0이 되어버린다.

이 때 작은 gradient 값을 scaling up 하면, 표현 가능한 범위를 더 많이 차지하게 하고 값을 보존할 수 있을 것이다.

즉 gradient에 scaling factor를 곱해서, 값들을 오른쪽으로 shift 시켜준다면 FP16 표현 가능 범위 안에 들도록 할 수 있을 것이다.

 

출처 : https://hoya012.github.io/blog/Mixed-Precision-Training/

 

 

SSD 네트워크는 gradient 값이 scaling 되지 않았을 때 발산하지만, scaling factor = 8로 지정해 gradient 값들에 8을 곱해주면 FP32에서의 훈련 성과와 비슷한 정확도를 낼 수 있었다.

이는 3만큼만 shift해도 학습이 잘 이뤄진다는 뜻으로, 2^-27 이하의 작은 gradient 들은 모델 학습에 큰 영향을 미치지 못하나, [2^-27, 2^-24) 사이의 value들 (=shift되어 표현 가능 범위로 들어온 애들)은 보존되어야 할 중요한 값이라는 것을 의미한다.

 

gradient 값을 FP16 표현 가능한 범위로 이동하는 효율적인 방법은 back-propagation을 시작하기 전에 forward pass에서 계산된 loss의 스케일을 조정하는 것이다.

이렇게 하면 chain rule에 따라 모든 gradient의 scale이 같은 양으로 조정되며, back-propagation 동안 추가 작업이 필요하지 않고 gradient 값이 0이 되는 경우를 방지할 수 있다.

 

단, FP32 훈련과 동일한 결과를 얻기 위해서는 업데이트 전 반드시 weight gradient의 unscaling이 수반되어야 한다. back-propagation 직후 바로 unscaling을 하는 것이 가장 간단한데, 이렇게 하면 gradient cliping을 비롯한 기타 gradient 관련 연산을 수행하기 전 복원을 완료할 수 있어 gradient clipping threshold, weight decay 등의 하이퍼파라미터를 조정할 필요가 없어진다.

 

loss scaling factor를 선정하는 방법은 여러 가지 있으나, 가장 간단한 방법은 constant scaling factor를 선택하는 것으로, 본 논문에서는 8 ~ 32K 범위의 scaling factor를 사용해 다양한 네트워크를 훈련했다.

상수 크기를 결정하는 방법은 실험적으로 결정하거나, gradient statistics가 사용 가능한 경우에는 maximum absolute gradient value의 곱이 65,504 이하 (FP16 표현 최대값) 가 되도록 직접 결정한다.

back propagation 중에 overflow를 일으키지 않는 한 큰 scaling factor를 사용하는 데에는 단점이 없다. overflow가 발생하는 경우에는 weight에 비가역적인 손상을 일으킬 수 있기에, overflow가 감지될 경우 업데이트를 건너뛰고 다음 iteration으로 넘어가는 것이 해결 방법으로 쓰일 수 있다.

 

Loss scaling이 적용된 weights update 과정은 다음과 같다.

https://www.slideshare.net/lablup/jmi-techtalk-how-to-use-gpu-for-developing-ai

  1. FP32 weight에 대한 FP16 copy를 생성
  2. FP16 weight을 이용해 forward pass 진행
  3. forward pass로 계산된 FP16 pred 값을 FP32로 casting
  4. FP32 pred를 이용해 FP32 loss를 계산하고, scaling factor S를 곱함
  5. scaled FP32 loss를 FP16으로 casting
  6. scaled FP32 loss를 이용해 backward propagation을 진행
  7. FP16 gradient를 FP32로 캐스팅하고 이를 scaling factor S로 다시 나눔 (unscaling)
    이 때, chain rule에 의해 모든 gradient는 같은 크기로 scaling된 상태임
  8. FP32 gradient를 이용해 FP32 weight update

 

즉 FP32 weight를 저장하고, FP16 copy weight을 만들어 forward/backward pass를 진행한 다음, 여기서 얻은 gradient로 FP32 weight을 업데이트하는 것이다.

 

 

3.3 Arithmetic Precision

신경망 학습에 쓰이는 산술은 크게 vector dot-products, reductions, point-wise operations의 3가지 범주로 나뉜다. 

 

Vector dot-products

모델 정확도를 유지하기 위해, 일부 네트워크에서는 FP16 vector dot-product를 FP32 format으로 누적한 후, 메모리에 쓰기 전에 FP16으로 변환해야 한다는 것을 발견했다. FP32로 누적하지 않으면 일부 FP16 모델은 베이스라인 모델의 정확도까지 도달하지 못했다.

이전 GPU는 FP16 곱셈 / 덧셈 연산만 지원했으나, NVIDIA Volta GPU는 FP16 입력 행렬을 곱하고 결과를 FP16, FP32 출력으로 누적하는 Tensor Cores를 도입했다.

 

What is Tensor Cores?

더보기
출처 : https://www.nvidia.com/ko-kr/data-center/tensor-cores/

Tensor cores란 NVIDIA에서 개발한 행렬 곱셈 프로세스를 가속하는 처리 장치 입니다. CUDA Cores가 1 Core Clock에 하나의 fp32 부동소수점 연산을 수행하는 것에 비해 Tensor Cores는 같은 Term 동안 4 x 4 크기의 fp16 행렬 두 개를 곱하고 그 결과를 4 x 4 fp32 행렬에 더하는 Matrix multiply-accumulate 연산(A와 B를 곱하고 C를 더하는 과정을 하나의 연산으로 수행)을 수행합니다.

출처:  https://comsys-pim.tistory.com/5

 

 

 

Reductions

reduction (vector elements의 합) 은 FP32에서 수행해야 한다.

Reduction은 주로 batch-normalization에서 통계를 누적하거나, softmax에서 발생한다.

구현을 할 때, 메모리에는 여전히 FP16  텐서를 읽고 쓰지만 산술 연산은 FP32로 진행하도록 했다.

이 레이어들은 메모리 대역폭에만 영향을 받고 산술 속도에 민감하지 않기 때문에, 학습 과정은 느려지지 않았다.

 

Point-wise operations

이 또한 마찬가지로 메모리 대역폭에만 영향을 받고 산술 속도에 영향을 미치지 않기 대문에, FP16과 FP32 연산을 모두 사용할 수 있다.

 

 

4. Results

  • Baseline (FP32)
    • activation, weight, gradient 모두 FP32로 저장되며 산술 연산 또한 FP32로 이뤄짐
    • NVIDIA의 Maxwell 혹은 Pascal GPU에서 시행
  • Mixed Precision (MP)
    • FP16은 저장 및 산술 연산에 사용됨
    • weight, activation, gradient는 FP16으로 저장되며, weight의 FP32 master copy는 업데이트에 사용됨
    • 일부 사례에서는 loss scaling이 사용됨
    • FP16 산술 연산을 시행할 때, convolutions, fully-connected layers,matrix multiplies in recurrent layers를 위해 FP32로 누적된 tensor core 연산이 사용됨
    • Tensor Cores가 가능한 Volta V100에서 수행
    • mixed precision speech recognition experiments에서는 FP16 스토리지만 사용하는 Maxwell에서 수행

 

NVIDIA Maxwell, Pascal, Volta GPU?

더보기

 

각 아키텍처별 특징이 잘 정리되어 있는 글도 참고

 

 

4.1 CNNs For ILSVRC Classification

What is ILSVRC Classification?

더보기

ImageNet Large Scale Visual Recognition Challenge

대규모 객체 탐지 및 이미지 분류 알고리즘을 평가

출처 : https://developer.nvidia.com/blog/nvidia-ibm-cloud-support-imagenet-large-scale-visual-recognition-challenge/

 

이곳에서 사용된 ILSVRC12의 구체적인 태스크 / 데이터셋은 여기서 볼 수 있다.

 

Mixed precision을 Alexnet, VGG-D, GoogLeNet, Inception v2, Inception v3, pre-activation Resnet-50 모델에 적용해 동일한 하이퍼파라미터를 사용하여 훈련을 진행한 결과, FP32 훈련의 top-1 정확도와 일치할 수 있었다.

네트워크는 Volta TensorOps를 사용하도록 수정된 Caffe 프레임워크를 사용해 훈련되었으며, Resnet50만 PyTorch를 사용해 훈련되었다.

[표 1] ILSVRC12 classification top-1 결과표
  • 일부 사례의 FP32 정확도는 single-crop testing, simpler data augmentation으로 인해 공개된 결과와 차이가 있다
    • Alexnet, VGG-D, GoogLeNet, Inception v2, Inception v3 : random horizontal flipping, random cropping (256*256)
    • Resnet50 : PyTorch vision repo에서 full augmentation 사용
  • loss scaling은 사용하지 않음

 

Caffe Framework?

더보기

Caffe는 컴퓨터 비전을 중심으로 한 딥러닝 프레임워크입니다. UC 버클리의 BVLC(Berkeley Vision and Learning Center)에 의해 개발되었습니다. 이 라이브러리는 이미지 분류, 세그멘테이션, 모델 학습 등 다양한 컴퓨터 비전 작업에 사용됩니다. Caffe의 주요 특징은 빠른 속도, 모듈화된 구조, 그리고 대규모 데이터 처리 능력입니다. [각주:2]



 

4.2 Detection CNNs

Object detection은 regression task로, bounding box의 좌표 값을 예측함과 동시에 각 bounding box에 속한 객체 유형 확률을 예측하는 classification task도 포함되어 있다.

출처 : https://jungnamgyu.tistory.com/35

VGG-16을 backbone으로 해 두 가지 접근 방식인 Faster-RCNN, Multibox-SSD 학습을 수행한 결과는 다음과 같다.

[표 2] Detection CNN 결과표
  •  MultiboxSSD 에서는 loss-scaling을 적용하지 않았을 때 FP16 훈련에 실패 (발산)
    • scaling factor=8을 사용했을 경우, 중간에 gradient 값이 손실되지 않고 baseline과 비슷한 정확도를 보이는 것을 알 수 있음

 

 

4.3 Speech Recognition

영어와 중국어 데이터셋 모두 DeepSpeech 2[각주:3] 모델을 사용하여 mixed precision training을 진행한다.

  • 영어
    • 모델 구성 : 2D convolution layer, 3 GRU cells, 1 row convolution layer, CTC cost layer[각주:4]
    • 파라미터 수 : 115M
    • 데이터 : 6000시간 분량의 영어 음성으로 구성
  • 중국어
    • 모델 구성 : 영어와 유사
    • 파라미터 수 : 215M
    • 데이터 : 2600시간 분량의 중국어 음성으로 구성
  • Optimizer : SGD
  • epochs : 20
  • 모든 하이퍼파라미터는 baseline, mp에서 동일하게 사용됨

 

What is CER? 

더보기

인식된 문자열(한 글자)과 정답 문자열(한 글자) 사이의 문자 오류 비율을 나타내는 지표

e.g. "cat" 을 "hat"으로 인식했을 경우, CER = 0.333 (1/3)

당연히 낮을수록 좋은 지표이다.

 

CNN과 마찬가지로, RNN 기반 네트워크에서도 Mixed Precision Training이 효과적으로 동작하는 것을 알 수 있었다.

또한 MP의 결과가 baseline보다 5~10% 정도 우수한 것을 볼 수 있는데, 이는 half-precision format이 훈련 중에 정규화의 역할을 할 수도 있음을 시사한다.

 

 

4.4 Machine Translation

언어 번역을 위해 Google이 제공하는 TensorFlow tutorial (English -> Franch Translation) 를 사용했다.

  • 데이터셋 : WMT15 dataset
    • 영어 : 100K vocabs / 프랑스어 : 40K vocabs
WMT15 데이터셋
  • 모델 : encoder - decoder 구조 (layer = 3, 5)
    • 하나의 layer는 1024개의 LSTM 셀로 구성
  • Optimizer :  SGD
[그림 4] Machine Translation 결과표 (3 layers)
  • loss scaling이 포함된 경우에는 FP32 성능과 거의 일치
  • loss scaling이 없는 경우 성능이 떨어짐
  • 5 layer로 구성된 모델도 비슷한 그래프를 보임

 

 

4.5 Language Modeling

  • 모델 : bigLSTM[각주:5] (영어 언어 모델)
    • 8192개의 LSTM 셀로 구성된 2개의 레이어
  • 데이터셋 : 1B word dataset
  • Optimizer : Adagrad
  • epochs : 50
  • vocab size : 793K
  • 8K의 negative sample이 포함된 sampled softmax layer 사용
  • batch size = 1024 (over 4 GPUs)

 

[그림 5] bigLSTM ppl 결과
  • loss scaling이 없을 경우 성능 저하
  • scaling factor = 128로 설정할 경우 정확도가 FP32와 일치

 

 

4.6 DCGAN Results

GAN은 훈련 중에 regression + discrimination 태스크가 결합되어 있으며, 이미지 태스크에서는 generator network 가 픽셀 색상(3 channels, 8-bit values) 을 회귀 예측한다.

  • 모델 : DCGAN을 사용해 128*128 픽셀의 얼굴 이미지를 생성하도록 훈련
    • Generator : 7 fractionally-strided convolutions, 6개의 leaky ReLU activations, 1개의 tanh
    • Discriminator : 6 convolutions, 2 fully-connected layers
  • 데이터셋 : CelebFaces dataset
  • Optimizer : Adam

GAN은 결과 품질에 대해 널리 통용되는 정량 지표가 없으므로 정성적으로 평가

 

좀 혐짤이라 접었음..

더보기
[그림 6] DCGAN 결과표

 

 

 

5. Conclusions and future work

Mixed precision으로 학습에 사용되는 메모리 사용량과 산술 연산 소요 시간을 줄일 수 있으며, 하이퍼파라미터 등의 튜닝이 별도로 필요하지 않아 다양한 태스크에 적용이 가능하다.

 


참고 문헌

https://bo-10000.tistory.com/32

https://hoya012.github.io/blog/Mixed-Precision-Training/