Processing math: 100%
본문 바로가기
Python

[PyTorch] dtype 단축메서드로 바꾸기

by ds31x 2025. 3. 14.

아래의 URL에서 간단히 다룬 단축 method들을 이용한 방식 (to나 type이 아닌)을 설명하는 문서임.

2024.03.15 - [Python] - [DL] Tensor: dtype 변경(casting) 및 shape 변경.

 

[DL] Tensor: dtype 변경(casting) 및 shape 변경.

Tensor를 추상화하고 있는 class로는numpy.array: numpy의 ndarraytorch.tensortensorflow.constant: (or tensorflow.Variable)이 있음. 이들은 Python의 sequence types과 달리 일반적으로 다음과 같은 특징을 지님.데이터들이

ds31x.tistory.com


사용예제: 정수형

import torch

b = torch.rand((2,3))
# 단축 메소드 사용
b_int64 = b.long()     # torch.int64 (64비트 정수)
b_int32 = b.int()      # torch.int32 (32비트 정수)
b_int16 = b.short()    # torch.int16 (16비트 정수)
b_int8 = b.byte()      # torch.uint8 (부호 없는 8비트)
b_int8_signed = b.char()  # torch.int8 (부호 있는 8비트)

print(f"long():  {b_int64.dtype}")
print(f"int():   {b_int32.dtype}")
print(f"short(): {b_int16.dtype}")
print(f"byte():  {b_int8.dtype}")
print(f"char():  {b_int8_signed.dtype}")

# long():  torch.int64
# int():   torch.int32
# short(): torch.int16
# byte():  torch.uint8
# char():  torch.int8

각 정수형 데이터 타입이 유리한 경우

  1. torch.int64 (long)
    • 큰 정수 값(2632631)을 다룰 때
    • Tensor Indexing이나 Masking 작업에 사용할 때
    • GPU 메모리가 충분하고 정밀도가 중요한 경우
    • 큰 배열의 합계나 내적 계산 시 오버플로우 방지가 필요할 때
  2. torch.int32 (int)
    • 일반적인 정수 연산에 충분한 범위(2312311)를 제공
    • CPU 연산에서 최적화된 경우가 많음
    • 메모리와 정밀도 사이의 균형이 필요할 때
    • 대부분의 딥러닝 모델에서 충분한 범위를 제공
  3. torch.int16 (short)
    • 메모리 사용량을 줄여야 할 때(32,76832,767 범위)
    • 작은 범위의 값을 다룰 때 메모리 효율성 중요
    • 네트워크 가중치 양자화가 필요한 경우
    • 모바일 또는 임베디드 장치용 모델 최적화 시
  4. torch.uint8 (byte)
    • 이미지 데이터 처리(0-255 값)에 매우 효율적
    • 마스크나 불리언 연산 결과 저장 시
    • 최대한의 메모리 절약이 필요할 때
    • 양자화된 모델에서 가중치 표현 시
  5. torch.int8 (char)
    • 부호 있는 작은 범위의 값(-128 ~ 127)
    • 메모리를 최소화하면서 음수도 표현해야 할 때
    • 양자화된 신경망에서 부호 있는 작은 가중치 표현
    • 저사양 장치에서의 추론에 중요

사용예제: 부동소수점 데이터 타입

# 부동소수점 단축 메소드
b_float16 = b.half()      # torch.float16 (16비트 반정밀도)
b_float32 = b.float()     # torch.float32 (32비트 단정밀도)
b_float64 = b.double()    # torch.float64 (64비트 배정밀도)
b_bfloat16 = b.bfloat16() # torch.bfloat16 (16비트 브레인 부동소수점)

print(f"half(): {b_float16.dtype}")
print(f"float(): {b_float32.dtype}")
print(f"double(): {b_float64.dtype}")
print(f"bfloat16(): {b_bfloat16.dtype}")

각 부동소수점 데이터 타입이 유리한 경우

  1. torch.float16 (half)
    • 메모리 사용량을 크게 줄여야 할 때
    • 최신 GPU에서 빠른 연산이 필요할 때(특히 NVIDIA의 Tensor Cores 활용)
    • 대규모 모델 학습에서 메모리 효율성이 중요할 때
    • 정밀도보다 속도가, 학습보다 추론이 중요할 때
    • 단점: 정밀도가 낮아 수치 불안정성 발생 가능
  2. torch.float32 (float)
    • 딥러닝에서 가장 널리 사용되는 표준 타입
    • 대부분의 학습 작업에서 좋은 정밀도와 성능 균형 제공
    • 대부분의 GPU에서 최적화되어 있음
    • 일반적인 딥러닝 모델 학습에 권장됨
  3. torch.float64 (double)
    • 높은 수치 정밀도가 필요한 과학적 계산
    • 매우 작거나 큰 값을 다룰 때 정밀도 손실 방지 필요
    • 수치적으로 불안정한 연산이나 긴 계산 체인에서
    • 그라디언트 스케일이 크게 다른 경우
    • 단점: 메모리 사용량 2배, 일부 연산에서 속도 감소
  4. torch.bfloat16 (bfloat16)
    • Google의 TPU와 일부 최신 CPU/GPU에 최적화
    • float32와 동일한 지수 비트(8비트)를 가져 범위는 유지하면서 메모리 절약
    • 학습 중 그라디언트의 수치 안정성이 중요할 때
    • TPU에서 학습하거나 최신 Intel CPU/NVIDIA GPU에서 작업할 때
    • float16보다 수치적으로 안정적이지만 정밀도는 더 낮을 수 있음

부동소수점 선택 시 고려사항

  1. 메모리와 속도:
    • 메모리: float16 ≈ bfloat16 < float32 < float64
    • 속도(하드웨어에 따라 다름): float16 > bfloat16 ≥ float32 > float64
  2. 정밀도와 범위:
    • 정밀도: float64 > float32 > bfloat16 > float16
    • 수치 범위: float64 > float32 = bfloat16 > float16
  3. 일반적인 권장사항:
    • 학습: float32 또는 mixed precision(float16+float32)
    • 메모리 제약이 심한 학습: bfloat16 또는 float16(그래디언트 스케일링 필요)
    • 추론: float16 또는 더 낮은 정밀도의 양자화
    • 과학적 계산: float64


참고: Mixed Precision이란?

훈련 속도와 메모리 효율성을 높이기 위해 mixed precision 학습을 사용하기도 함.

이 방식은 forward/backward 계산은 float16으로, 파라미터 저장 및 업데이트는 float32로 수행.

 

Mixed precision의 주요 이점은 다음과 같음:

  • 메모리 사용량 감소 (최대 2배)
  • 특정 하드웨어(Tensor Cores)에서 연산 속도 향상
  • 대규모 모델 학습 가능

하지만,

  • PyTorch는 기본적으로 mixed precision을 사용하지 않으며
  • 기본 설정에서 단일 데이터 타입(보통 float32)으로 연산을 수행함.
  • Mixed precision 학습을 사용하기 위해서는 명시적으로 이를 설정해야 함.
모든 모델이나 하드웨어에서 mixed precision이 항상 이점을 가져오는 것은 아니며,
일부 연산에서는 수치 안정성 문제가 발생할 수 있음.