2021. 3. 26. 23:18ㆍDeep Learning/framework
yolov5를 공부하다가 이런 부분을 발견
if half: #device != cpu이면
model.half() # to FP16
어떤 의미일까 궁금했다. 단순히 모델의 half만 이용한다기에는 gpu인데 굳이..?라는 생각에 찾아봤다.
1. FP16과 FP32의 차이
FP16(16 bit floating point), FP32(32 bit floating point)
일단은.. computer science(이하 cs)에서의 정밀도의 차이이다.
cs에서의 정밀도는 보통 bit / 이진수로 측정된다.
정밀도가 높을수록 계산 자원, 데이터 전송 및 메모리 저장이 더 많이 필요하다. 더 많은 비용이 들고 더 많은 전력을 소비한다는 것은 당연하다. 따라서 AI 분야에선 서로 다른 수준의 정밀도를 혼합/일치 시켜 목표를 달성할 수 있다.
※ 단일 정밀도(Single-Precision), 배 정밀도(Double-Precision) 및 반 정밀도(Half-Precision), 부동 소수점(Floating-Point) 형식
Floating-Point = FP
각 숫자가 차지하는 공간 : single-precision은 32bit, double-precision은 64bit, half-precision은 16bit를 차지한다.
Nvidea Tensor Core GPU는 다중 및 혼합 정밀도(mixed precision) 기술을 지원하기 때문에 작성된 코드라고 보인다.
2. Mixed Precision
헷갈릴만한 용어로 Multi Precision이 있는데, Multi Precision은 필요에 따라 Double-precision을 사용하고, 다른 부분에 대해 Half-Precision, Single-Precision을 사용하여 다영한 정밀도로 계산할 수 있는 프로세서를 사용하는 것이다.
Mixed Precision은 단일 작업 내에서 다른 정밀도 수준을 사용해 정확도를 유지하며 계산 효율성을 달성하는 방법이다.
2019 NVIDIA AI Conference 에서는 이를 이용해 딥러닝 학습 가속을 쉽게 하는 방법을 소개
: tensor core
이 과정은 fp16 행렬을 입력으로 받고 fp32 행렬로 출력을 반환하기 때문에 mixed precision이라고 불립니다.
tensor core는 single precision을 사용하므로 parameter size가 줄어 메모리 사용량이 줄어듭니다 = 두배의 데이터 처리 가능
즉, model performance를 높이기 위해 FP16을 사용한다면 FP32 의 8배 가냥의 연산처리량을 얻으면서, 두배의 메모리 처리량, 절반의 메모리 사용량 효과를 얻을 수 있습니다.
Mixed Precision이란 간단히 말해, FP16은 speed와 scale을 위해 사용하고 task-specific accuracy 유지를 위해 FP32를 섞어 쓰는 것 입니다.
모델 구성에 따라 Tensorcore를 사용하는 비중이 높아질수록 훈련 성능이 올라가며, acc면에서도 학습이 잘 된다고 합니다.(모델이나, Task따라 많이 달라지는 듯해 보이긴 합니다)
다음 사진은 Mixed Precision을 적용가능한 task들 목록입니다.
다음은 기존 모델에서 Mixed Precision을 적용한 결과를 나타내며, NVIDIA Github에 예제 코드가 있습닌다.
Mixed Precision을 적용해 Training하기 위해서는
model conversion | 모든 것을 FP16 values를 실행하기 위해 바꾼다 |
full precision이 필요한 loss function과 정규화/포인트별 작업을 위해 FP32에 cast를 삽입. | |
master weights | FP32 모델의 파라미터들을 유지하면서, 각 iteration을 업데이트 한다 |
forward pass와 backpropagation 둘 다를 위해서 FP16-casted copy를 사용한다. | |
Loss scaling | loss value를 scale하고, gradients를 un-scale(FP32유지)한다. |
각 iteration에서 overflow를 위해 gradients를 확인한다. 필요하다면 loss scale을 적용하고 update를 skip한다. |
그림으로 확인해보면, FP16으로 계산하되 합칠 때 FP32로 되돌아가야 한다.
- 특정 연산(GEMMs, Convolution 등등)은 TensorCore의 도움을 받되 뒷단의 Softmax나 loss 연산 부분은 acc 유지에 중요한 역할을 하므로 FP32 유지 필수.
- weight는 single precision을 유지하지만 back-propagation은 half-precision으로 수행
- single과 half를 섞어 쓰기 때문에 mixed precision training이라고 부름.
AMP(Automatic Mixed Precision)라는 것이 Mixed Precision적용을 더 편하게 수행할 수 있도록 도와준다고 한다.
(AMP는 tensorflow, pytorch에서 모드 두세줄로 사용할 수 있다고 한다. : NVIDIA github에 예제코드 존재)
- single precision -> half precision으로 바꾸는 부분이나/ 앞의 입력이 single인지 half인지 판단하는 부분을 자동화
-half로 떨어뜨리면 gradient vanishing이 발생할 수 있으므로 자동으로 loss scaling까지 수행 (loss scaling은 hyper parameter라서 test가 필요)
- tensorflow 나 pytorch 같은 framework들은 tensor 연산 대한 expressions가 잘 정의되어 Automatic casting이 편리 - TensorCore 적용 편함
- Master weight를 single precision으로 유지하는 것이 핵심으로, acc 유지에 매우 중요한 역할.
- 단순히 precision을 half로 다운하면 FP16 범위의 한계로 인해 loss scale 표현에 문제가 생기고, 이로 인해 weight나 gradient가 0으로 바뀔 수 있는 위험성이 있다.따라서 weight는 single precision으로 유지해야 함. 그래서 shift연산을 해서 값을 올려줌
- 즉 FP16의 최대값이 FP32대비 작기 때문에 shift연산 시 overflow를 조심해야 한다. (그러나 이마저도 자동으로 해 줌)
'Deep Learning > framework' 카테고리의 다른 글
[Pytorch] torch.no_grad (0) | 2021.05.22 |
---|---|
[PyTorch] tensor 부등호 연산 (?), list와 차이점 (0) | 2021.05.13 |
[Pytorch] gpu가 인식이 안 되는 오류 - Linux 에서 Nvidia driver설치 (0) | 2021.04.05 |
torch.backends.cudnn.benchmark = True (0) | 2021.03.30 |
yaml (+ xml, json) (0) | 2021.02.02 |