Python for AI, Embedded/Deep Learning: PyTorch & AI Modeling

PyTorch 데이터 로딩 파이프라인 구축: Dataset부터 DataLoader까지

임베디드 친구 2026. 5. 1. 21:33
반응형

핵심 요약 3줄

  1. 데이터 병목 해결: GPU 연산 효율을 극대화하기 위해 CPU 기반의 선행 데이터 로딩 파이프라인 구축이 필수적입니다.
  2. 표준 라이브러리 활용: torchvision과 torchtext를 사용하여 이미지와 텍스트 데이터를 체계적으로 관리합니다.
  3. 커스텀 유연성: Dataset 상속을 통해 고유한 데이터 규격에 맞춘 맞춤형 로더를 설계할 수 있습니다.

Generated by Gemini AI.

1. 딥러닝 성능의 숨은 조연: 데이터 로딩 아키텍처

엔지니어의 관점에서 딥러닝 모델 학습은 일종의 '파이프라인 공정'과 같습니다. 아무리 성능 좋은 GPU(NPU)를 사용하더라도, 데이터를 공급하는 CPU 단에서 병목이 발생하면 전체 시스템의 실시간성(Latency)은 떨어질 수밖에 없습니다. PyTorch는 이를 해결하기 위해 두 가지 핵심 추상화 클래스를 제공합니다.

  • torch.utils.data.Dataset: 데이터셋의 전체 크기를 정의하고 개별 데이터를 호출하는 역할을 담당합니다.
  • torch.utils.data.DataLoader: 데이터를 배치(Batch) 단위로 묶고, 섞기(Shuffle) 및 멀티 프로세싱(num_workers)을 통해 병렬 처리를 수행하는 엔진입니다.

2. 이미지 데이터 로딩 (torchvision)

이미지 처리는 전처리 과정(Resize, Normalize)이 연산 자원을 많이 소모하므로, 효율적인 구성이 중요합니다.

2.1 표준 데이터셋 활용 예시

CIFAR-10과 같은 데이터셋은 torchvision.datasets를 통해 즉시 로드할 수 있습니다.

Python
 
import torch
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 임베디드 환경을 고려한 최적화 변환 정의
transform = transforms.Compose([
    transforms.Resize((32, 32)),   # 입력 해상도 통일
    transforms.ToTensor(),         # 텐서 변환
    transforms.Normalize((0.5,), (0.5,))  # 데이터 분포 정규화
])

# 데이터셋 로딩
train_dataset = datasets.CIFAR10(root="./data", train=True, transform=transform, download=True)

# DataLoader 생성 (병렬 처리 num_workers 설정 권장)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=4)

2.2 ImageFolder 및 커스텀 Dataset

폴더 구조가 클래스별로 구분되어 있다면 ImageFolder를, 특수한 데이터 규격이 필요하다면 Dataset 클래스를 상속받아 구현합니다.


3. 텍스트 데이터 로딩 (torchtext)

텍스트는 이미지와 달리 비정형 시퀀스 데이터이므로 토큰화(Tokenization) 과정이 핵심입니다.

3.1 torchtext를 활용한 IMDB 로딩

Python
 
from torchtext.datasets import IMDB
from torchtext.data.utils import get_tokenizer

# 데이터 다운로드 및 토크나이저 설정
train_iter = IMDB(split='train')
tokenizer = get_tokenizer("basic_english")

# 배치 처리를 위한 샘플 확인
for label, line in train_iter:
    tokens = tokenizer(line)
    print(f"Label: {label}, Tokens: {tokens[:5]}...") # 첫 5개 토큰 출력
    break

3.2 커스텀 텍스트 데이터셋 정의

파일 시스템에서 직접 텍스트를 읽어오는 경우, 다음과 같이 상속을 통해 구현합니다.

Python
 
class CustomTextDataset(Dataset):
    def __init__(self, file_path, tokenizer):
        with open(file_path, "r", encoding="utf-8") as f:
            self.data = f.readlines()
        self.tokenizer = tokenizer

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx):
        return self.tokenizer(self.data[idx].strip())

실전 개발 팁 (Pro Tips) - 추가된 내용

  1. Lazy Loading으로 RAM 점유율 관리: 임베디드 장치처럼 메모리가 적은 환경에서는 __init__ 단계에서 모든 데이터를 메모리에 올리지 마세요. 파일 경로 리스트만 생성한 뒤, __getitem__이 호출되는 시점에 파일을 하나씩 읽는 Lazy Loading 방식을 사용해야 OOM(Out of Memory) 에러를 방지할 수 있습니다.
  2. num_workers 튜닝과 병목 모니터링: num_workers 값을 무작정 높인다고 속도가 빨라지지는 않습니다. 과도한 프로세스 생성은 오히려 컨텍스트 스위칭 오버헤드를 발생시킵니다. 일반적으로 CPU 코어 수 / 2에서 시작하여 GPU 사용률(nvidia-smi)이 90% 이상 유지되는 최적점을 찾는 것이 좋습니다.
  3. 입력 데이터 타입 최적화 (Memory Format): 최신 GPU 가속을 극대화하려면 이미지 데이터에 Channels Last 포맷(memory_format=torch.channels_last) 적용을 고려해 보세요. 특정 아키텍처(Tensor Core 등)에서 연산 처리량을 20~30% 가량 더 끌어올릴 수 있는 고급 엔지니어링 기법입니다.

4. 결론: 효율적인 로딩이 모델의 속도를 결정한다

임베디드 시스템이나 실시간 On-Device AI 환경에서 데이터 로딩 속도는 곧 사용자 경험과 직결됩니다. Dataset과 DataLoader를 적절히 활용하여 시스템의 자원을 효율적으로 배분하는 것이 실력 있는 소프트웨어 개발자의 핵심 역량입니다.

반응형