딥러닝 모델을 학습시키다 보면 예기치 않은 오류에 직면하기 마련입니다. 그중 하나가 바로 **세그멘테이션 오류(Segmentation Fault, SIGSEGV: 11)**입니다. 이 오류는 주로 메모리 액세스 위반으로 발생하며, PyTorch와 diffusers
라이브러리를 사용한 이미지 생성 모델 학습에서 자주 나타날 수 있습니다. 이번 포스팅에서는 파노라마 이미지 생성 모델 학습 스크립트(train_panorama_model.py
)에서 발생한 세그멘테이션 오류를 해결한 사례를 바탕으로, 문제를 진단하고 해결하는 트러블슈팅 방법을 단계별로 소개합니다.
오류 상황: 무엇이 문제였나?
최근 파노라마 이미지 생성을 위한 커스텀 모델을 학습시키던 중, train_panorama_model.py
스크립트 실행 시 다음과 같은 오류가 발생했습니다:
ERROR - 모델 학습 중 오류 발생: Command [...] died with <Signals.SIGSEGV: 11>.
이 오류는 여러 차례 실행에도 반복되었으며, 배치 크기를 4에서 16으로 늘렸을 때도 해결되지 않았습니다. 로그를 분석한 결과, 데이터셋 준비 단계는 성공했으나 학습 단계에서 문제가 발생했음을 확인했습니다. 주요 원인으로는 메모리 부족, 라이브러리 호환성 문제, 데이터셋 오류, 또는 코드 내 메모리 관리 부실이 의심되었습니다.
세그멘테이션 오류의 주요 원인
세그멘테이션 오류는 다양한 요인으로 발생할 수 있습니다. 딥러닝 학습 환경에서는 다음이 주요 원인으로 꼽힙니다:
- GPU 메모리 부족: 모델 크기, 배치 크기, 또는 이미지 해상도가 GPU 메모리를 초과.
- 라이브러리 호환성 문제: PyTorch, CUDA, GPU 드라이버 간 버전 불일치.
- 데이터셋 문제: 손상된 이미지 파일이나 잘못된 메타데이터.
- 코드 내 버그: 부적절한 메모리 관리 또는 잘못된 텐서 연산.
- 시스템 자원 제한: CPU 스레드 수, 파일 디스크립터 제한 등.
트러블슈팅 단계
아래는 세그멘테이션 오류를 해결하기 위해 적용한 단계별 접근법입니다. 각 단계는 문제를 좁혀가며 해결책을 찾는 데 도움을 줍니다.
1. 환경 점검: 시스템 및 라이브러리 확인
먼저, 학습 환경을 점검합니다. 세그멘테이션 오류는 종종 라이브러리 또는 하드웨어 설정 문제로 발생합니다.
- PyTorch와 CUDA 버전 확인:
python -c "import torch; print(torch.__version__, torch.cuda.is_available(), torch.version.cuda)"
출력 예:2.0.1 True 11.7
- PyTorch 버전과 설치된 CUDA 버전이 GPU 드라이버와 호환되는지 확인하세요. PyTorch 공식 웹사이트에서 호환 표를 참고하세요.
- 호환되지 않는 경우, 올바른 버전을 설치합니다:
pip install torch==2.0.1 --extra-index-url https://download.pytorch.org/whl/cu117
- GPU 메모리 상태 확인:
학습 시작 전과 중에nvidia-smi
명령어로 GPU 메모리 사용량을 모니터링하세요:nvidia-smi
- 메모리가 거의 꽉 찼다면, 배치 크기를 줄이거나 혼합 정밀도 학습을 활성화해야 합니다.
- 시스템 자원 확인:
- CPU 스레드 수 제한: 환경 변수로 설정합니다.
export OMP_NUM_THREADS=1 export MKL_NUM_THREADS=1
- 파일 디스크립터 한계 확인 및 증가:
ulimit -n 65535
- CPU 스레드 수 제한: 환경 변수로 설정합니다.
2. 코드 최적화: 메모리 관리 개선
train_panorama_model.py
스크립트를 검토한 결과, 메모리 관리가 최적화되지 않은 부분이 있었습니다. 다음 수정 사항을 적용했습니다:
- 배치 크기 감소:
- 기본 배치 크기를 4에서 2로 줄여 GPU 메모리 부하를 완화했습니다.
- 코드 변경:
parser.add_argument("--batch_size", type=int, default=2, help="학습 배치 크기")
- 주기적 메모리 정리:
- 학습 루프에서 10 스텝마다 GPU 캐시를 정리하고 가비지 컬렉션을 실행했습니다.
if step % 10 == 0: torch.cuda.empty_cache() gc.collect()
- 학습 루프에서 10 스텝마다 GPU 캐시를 정리하고 가비지 컬렉션을 실행했습니다.
- 혼합 정밀도 학습 기본화:
fp16
혼합 정밀도를 기본으로 설정하여 메모리 사용량을 줄였습니다.parser.add_argument("--mixed_precision", type=str, default="fp16", choices=["no", "fp16", "bf16"])
3. 데이터셋 검증: 손상된 데이터 제거
데이터셋 문제는 세그멘테이션 오류를 유발할 수 있습니다. metadata.jsonl
파일과 이미지 파일을 검증했습니다.
- 메타데이터 검증:
- 이미지 파일 경로가 실제로 존재하는지 확인하는 로직을 추가했습니다:
if os.path.exists(image_path): image_paths.append(image_path) prompts.append(item["prompt"]) else: logger.warning(f"이미지 파일을 찾을 수 없습니다: {image_path}")
- 이미지 파일 경로가 실제로 존재하는지 확인하는 로직을 추가했습니다:
- 이미지 파일 검증:
- 손상된 이미지를 건너뛰기 위해 예외 처리를 추가했습니다:
try: image = Image.open(image_path).convert("RGB") image = self.transforms(image) except Exception as e: logger.error(f"데이터 로딩 중 오류: {e}, 파일: {self.image_paths[idx]}") return None
- 손상된 이미지를 건너뛰기 위해 예외 처리를 추가했습니다:
- 별도 검증 스크립트:
데이터셋을 학습 전에 검증하는 스크립트를 작성하여 손상된 파일을 사전에 제거했습니다:from PIL import Image import os import json metadata_file = "/home/work/.exdata98/training_dataset/metadata.jsonl" dataset_path = "/home/work/.exdata98/training_dataset" with open(metadata_file, 'r') as f: for line in f: item = json.loads(line) image_path = os.path.join(dataset_path, item["file_name"]) try: Image.open(image_path).convert("RGB") except Exception as e: print(f"손상된 이미지: {image_path}, 오류: {e}")
4. 로그 강화: 디버깅 정보 추가
오류의 원인을 좁히기 위해 상세한 로깅을 추가했습니다. 데이터 로딩, 모델 초기화, 학습 루프에서 발생하는 예외를 기록하도록 수정했습니다:
logger.error(f"데이터 로딩 중 오류: {e}, 파일: {self.image_paths[idx]}")
또한, TensorBoard 로그를 활용하여 손실 값과 학습 진행 상황을 모니터링했습니다:
accelerator.log(logs, step=global_step)
5. 대안 테스트: 점진적 디버깅
문제가 지속될 경우, 다음 대안을 시도했습니다:
- 배치 크기 1로 테스트:
python train_panorama_model.py --batch_size=1 ...
- 단일 해상도 학습:
해상도 증가 단계를 1로 설정하여 초기 해상도(256×256)만 학습:python train_panorama_model.py --resolution_steps=1 --target_resolution=256 ...
- CPU 학습 테스트:
GPU 관련 문제를 배제하기 위해 CPU에서 소규모 데이터로 학습:device = "cpu" unet = unet.to(device)
해결 결과
위 단계를 적용한 결과, 다음과 같은 수정으로 세그멘테이션 오류를 해결했습니다:
- 배치 크기를 2로 줄이고, 혼합 정밀도(
fp16
)를 활성화. - 데이터셋 검증을 통해 손상된 이미지를 제거.
- 주기적인 메모리 정리 추가.
- PyTorch와 CUDA 버전 호환성 확인 및 업데이트.
수정된 스크립트는 안정적으로 학습을 완료했으며, 최종 모델은 StableDiffusionPipeline
으로 성공적으로 로드되었습니다. 학습된 모델을 사용한 추론 예시는 다음과 같습니다:
from diffusers import StableDiffusionPipeline
model_path = "/home/work/.exdata98/panorama_model/final_model"
pipe = StableDiffusionPipeline.from_pretrained(model_path).to("cuda")
prompt = "equirectangular 360° VR, seamless stitching, tropical beach, turquoise water, golden sunset"
image = pipe(prompt, height=768, width=768).images[0]
image.save("panorama.png")
결론 및 팁
세그멘테이션 오류는 딥러닝 학습에서 흔히 마주치는 문제지만, 체계적인 트러블슈팅으로 해결할 수 있습니다. 다음은 앞으로 비슷한 문제를 예방하기 위한 팁입니다:
- 작게 시작하세요: 작은 배치 크기와 낮은 해상도로 테스트하여 문제를 조기에 발견.
- 로그를 적극 활용하세요: 상세한 로그는 오류 원인을 좁히는 데 필수적입니다.
- 환경을 최신으로 유지하세요: PyTorch, CUDA, 드라이버를 정기적으로 업데이트.
- 데이터 품질 관리: 학습 전에 데이터셋을 철저히 검증.
이 포스팅이 딥러닝 학습 중 세그멘테이션 오류로 고생하는 분들에게 도움이 되길 바랍니다!
답글 남기기