본문 바로가기
  • AI 개발자가 될래요
Deep Learning

[pytorch/분산처리/디버깅노트] 배치사이즈 주의점 / 배치사이즈가 1일 때 분산처리 주의사항 / 에러 원인 및 해결방법

by 꿀개 2025. 2. 18.

[pytorch/분산처리] 배치사이즈 주의점 / 배치사이즈가 1일 때 분산처리 주의사항 / 에러 원인 및 해결 방법

 
인고의 디버깅 끝에 알아낸 문제와 해결 과정 및 방법.
 

1. 문제

현재 어떤 오픈소스 모델 학습 중에 있는데, 건드린게 없는데도 학습 시 에러가 발생했다.

audio = audio.view(-1, 5, audio.shape[-1]) # [B, T, 128]
RuntimeError: shape '[-1, 5, 128]' is invalid for input of size 256

 
해석하자면 audio 변수를 [b, 5, 128] 형태로 바꿀 수 없다는 것이다.
audio 변수는 코드상으로는 [b*5, 128] 형태이기 때문에, [b, 5, 128]으로 당연히 바꿀 수 있는 것이었다.
 
그러나 특정 구간에서 에러가 발생.. 학습이 중지되었다.
 

2. 에러 발생 구간

에러 발생 구간은 validation 부분이었다.
train 구간 까지는 정상적으로 동작되다가, validation 할 때 형태 변경 코드를 만나면 위의 에러 메세지를 출력했다.
 

3. 문제 해결 과정

3.1. 데이터 자체 문제 여부 확인

활용 중인 코드는 동영상을 5개의 프레임으로 쪼개서 dataloader에 넣는데,
어떤 데이터에 5개보다 적은 개수의 프레임이 저장되어 해당 에러가 나는지 확인해봤다.
 
train, valid 데이터로더를 선언하고 데이터를 읽어와서 프레임 개수가 5개인지 확인해봤다.

imgs, audio, mask = batch_data 

if audio.shape[1] != 5:
    print(f"🚨 [ERROR] Audio frames mismatch! Expected 5, but got {audio.shape[1]}. (Iteration {n_iter})")

 
 
실행 결과 에러가 발생하지 않았다. 데이터 자체는 문제가 없다는 뜻이다.
 

3.2. validation set 데이터로더 부분 체크

train부분과 valid 부분의 모델 입출력은 동일했기때문에 train에서는 되고, valid에서는 안되는 이유를 찾아야 했다.
두 부분의 유일한 차이점은 데이터로더가 참조하는 데이터셋과 배치사이즈 뿐이었다.
하지만 3.1.에서 데이터 자체에는 문제가 없다는 것을 확인했으니 다른 부분이 원인이었다.
원저자는 train과 valid의 배치사이즈 기본값을 아래처럼 각각 4, 1로 설정해놓았다.

parser.add_argument("--train_batch_size", default=4, type=int)
parser.add_argument("--val_batch_size", default=1, type=int)

 
형태를 변경하는 코드 위에 5로 나누어 떨어지지 않는다면 shape을 출력하는 코드를 추가하여 문제 상황을 파악했다.

if audio.shape[0] % 5 != 0:
    print(f"🚨 Error: {audio.shape[0]} is not divisible by 5!")
audio = audio.view(-1, 5, audio.shape[-1]) # [B, T, 128]

 
결과는 train 부분에서는 에러 없이 지나가고, valid 부분에서 다음과 같은 에러메세지를 출력했다.

🚨 Error: 2 is not divisible by 5!
🚨 Error: 2 is not divisible by 5!
🚨 Error: 1 is not divisible by 5!

 
3.1.번에서 모든 audio 형태의 첫 번째 원소는 5의 배수인 것을 확인했기 때문에 왜 2, 2, 1으로 나오는지 의문이었지만, 금방 답을 알 수 있었다.
 

4. 문제 원인

필자는 gpu 4개로 분산학습을 실행했는데, 배치사이즈가 4인 train set 에서는 각각의 gpu에 배치 1개씩 넣어 계산하여 문제가 없었지만, 배치사이즈가 1인 valid set을 4개의 gpu에 각각 넣으려니 문제가 발생한것이었다.
멀티 GPU (DataParallel 또는 DistributedDataParallel) 를 사용하면 배치 크기가 예상과 다르게 나뉘면서 view(-1, 5, audio_feature.shape[-1])에서 문제가 발생한 것이었다.
 
2+2+1 =5 라서 해당 부분이 원인이라는 것을 알아차렸다..
 

5. 해결 방법

validation 배치사이즈를 4로 변경했다.. 문제가 발생하지 않는다..
 

결론: 다중 GPU를 이용하여 분산학습 시 배치사이즈를 1로 설정하면 형태 변경 등에서 예기치 못한 문제가 발생할 수 있다.