728x90
딥러닝 모델 학습 중 libpng error: IDAT: CRC error 해당 에러가 발생 한 후 cv2.imread에서 이미지를 읽지 못해 AttributeError: 'NoneType' object has no attribute 'ndim' 해당 에러까지 발생하며 학습 중단 되었다.
에러 발생 원인
1. libpng error: IDAT: CRC error
- cv2.imread()가 PNG 파일을 디코딩 실패했을 때 발생하는 에러
- 파일이 깨졌거나, 디스크 일시 오류, 또는 I/O race로 인해 발생 가능
- But, PNG 파일이 손상되지 않았음은 cv2.imread() 또는 PIL.Image.verify()로 이미 확인함.
- 재시도하면 문제 없이 읽힘 → 파일 자체 문제가 아님
2. cv2.imread() → 아무것도 로드 되지 않아 None 반환
im = imread(f, flags=self.cv2_flag) # 결과가 None
3. ndim 접근 시도 → 'NoneType' object has no attribute 'ndim'
return im[..., None] if im.ndim == 2 else im # 이 시점에서 im == None → AttributeError 발생
- 위에서 None 반환된 것을 후속 코드가 처리 못함
4. 이 에러는 DataLoader worker 프로세스에서 발생
AttributeError: Caught AttributeError in DataLoader worker process 8.
- 멀티프로세스 중 한 worker에서 예외 발생하여 전체 학습 중단
원인 정리
- 학습 중 num_workers가 많아져서 HDD에 I/O 병목 발생.
- 동시에 많은 이미지 파일을 읽으려 하면서 HDD가 seek latency를 견디지 못함.
- 이로 인해 cv2.imread()가 일시적으로 파일을 제대로 읽지 못하고 None을 반환(특히 랜덤 I/O에 취약한 HDD에서).
- PNG는 디코딩 과정에서 더 많은 CPU와 I/O 연산이 필요.
- HDD 병목 + cv2.imread()의 내부 처리 실패가 맞물리면 PNG만 None 또는 libpng error로 실패할 수 있음.
→ num_workers 수가 많으면 CPU 사용률은 높아지지만, SATA HDD에서는 디스크 I/O가 병목이 되어 cv2.imread()에서 일시적으로 None을 반환하거나 libpng error가 발생할 수 있음.
⇒ num_worekrs 수를 보수적으로 가져 가던가 HDD에 있는 데이터를 비교적 안전한 SSD로 옮겨서 사용하는 방법이 가장 베스트임.
→ PNG는 무손실 압축, 디코딩 복잡도 높음 + zlib 압축 해제 필요 때문에 CRC(순환 중복 검사)를 모든 블록에 삽입
- PNG는 IHDR, IDAT, IEND 등 각 블록마다 CRC를 포함하고 있음.
- 따라서 조금이라도 내용이 바뀌거나 손상되면 즉시 오류 발생 (libpng error: IDAT: CRC error).
→ JPEG은 이런 검사 없음
- JPEG은 비손실 압축이 아니고, 구조가 간단함.
- 손상된 JPEG은 일부분만 깨지거나 무시되고 로드 될 수 있음.
⇒ 같은 손상이라도 PNG는 오류가 명확히 드러나고, JPEG은 넘어가거나 일부만 깨진 채 로딩 됨.
⇒ 때문에 png 파일을 미리 JPEG로 변환해두는 것이 안정성과 속도 측면에서 더 나음.
728x90