DataLoader가 맡는 일
DataLoader는 Dataset을 감싸서 여러 기능을 더해 줘. N개 예시를 [N, ...] 형태의 텐서로 묶는 배치 처리, 샘플 순서를 바꾸는 셔플, 여러 워커 프로세스를 활용한 병렬 로딩, CPU→GPU 전송을 빠르게 하는 pin 메모리가 대표적이야. 학습 루프 맨 위에서 한 줄로 설정하면, 나머지 코드는 배치를 반복해서 처리하기만 하면 돼.
가장 중요한 인자는 두 가지야. batch_size는 VRAM과 처리량에 맞춰 조정하고, num_workers는 CPU와 입출력 대역폭에 맞춰 조정해. 기본값인 num_workers=0은 단일 프로세스로 동작해. 작은 데이터셋에는 괜찮지만, 그 밖의 경우에는 디버깅 악몽이 될 수 있어.
num_workers는 사용 가능한 물리 CPU 코어 수에 맞춰 잡아. 16 core 장비라면 num_workers=8이 합리적인 시작점이야. htop을 열어 두고 테스트해 봐. 워커와 GPU가 모두 바쁘게 움직이고, 어느 한쪽도 다른 쪽을 기다리며 놀지 않아야 해.자주 빠지는 함정
학습에서 shuffle=True를 빼먹는 경우 — 데이터가 클래스별로 정렬되어 있으면 모델이 첫 번째 클래스에 과적합한 뒤 회복하지 못해. 학습 로더에서는 항상 셔플해야 해.
검증 로더를 셔플하는 경우 — 시간만 낭비하고 배치별 지표의 재현성도 깨뜨려. 검증에서는 shuffle=False로 설정해.
CUDA에서 num_workers>0을 쓰면서 pin_memory=True를 빠뜨리는 경우 — CPU→GPU 대역폭를 낭비하게 돼. 둘은 항상 함께 설정해.
__getitem__에서 공유 상태를 변경하는 경우 — 워커는 subprocess이므로 전역 상태도 워커마다 따로 존재해. 기록 카운터와 RNG 상태 등이 예상과 미묘하게 다르게 동작할 수 있어.
맞춤형 collate
기본 collate_fn은 형태가 같은 텐서를 쌓아 줘. 길이가 제각각인 시퀀스인 텍스트, 오디오, 세트를 다룰 때는 pad나 pack을 수행하는 맞춤형 collate가 필요해. Hugging Face의 DataCollatorWithPadding은 흔히 만나는 경우를 처리해 줘.
shuffle=True, num_workers>0, 그리고 CUDA를 쓴다면 pin_memory=True야. 검증에도 세 가지를 설정해. shuffle=False, num_workers>0, pin_memory=True야.