본문 바로가기

파이썬/GFPGAN 얼굴 복원 사용기

GFPGAN 학습 중 UnicodeDecodeError: 'cp949'

Windows에서 GFPGAN 학습 중 UnicodeDecodeError: 'cp949' 오류 해결기

TL;DR
윈도우 기본 로캘(cp949) 때문에 UTF-8로 저장된 YAML을 basicsr가 열다가 깨진 오류입니다.
한 줄 해결:

  • CMD: python -X utf8 gfpgan\train.py -opt ...
  • PowerShell: $env:PYTHONUTF8=1; python gfpgan/train.py -opt ...
    또는 options.py에서 open(..., encoding='utf-8')로 패치.

증상

GFPGAN 학습 실행 시 아래와 같은 에러가 터짐:

(.venv) C:\Project\Python\GFPGAN>python gfpgan/train.py -opt options/train_GFPGANv3_512_ALL_stage1.yml
Traceback (most recent call last):
  File "C:\Project\Python\GFPGAN\gfpgan\train.py", line 10, in <module>
    train_pipeline(root_path)
  File "...\site-packages\basicsr\train.py", line 93, in train_pipeline
    opt, args = parse_options(root_path, is_train=True)
  File "...\site-packages\basicsr\utils\options.py", line 95, in parse_options
    opt = yaml.load(f, Loader=ordered_yaml()[0])
  ...
UnicodeDecodeError: 'cp949' codec can't decode byte 0xec in position 437: illegal multibyte sequence
  • cp949(윈도우 한국어 기본 인코딩)이 UTF-8 한글 바이트(예: 0xEC …)를 해석하지 못해 발생.
  • YAML 내부에 한글 주석/값이 있거나, 파일 자체가 UTF-8로 저장되어 있으면 흔히 재현됨.

원인

  • Python은 기본적으로 운영체제 로캘 인코딩을 따라 파일을 엽니다.
  • Windows 한국어 로캘은 cp949가 기본 → UTF-8로 저장된 YAML을 인코딩 미지정으로 open()하면 디코딩 실패.

해결 방법 1 — 실행 옵션으로 UTF-8 강제(가장 간단)

CMD

REM 1) 일회성 강제
python -X utf8 gfpgan\train.py -opt options\train_GFPGANv3_512_ALL_stage1.yml

REM 2) 환경변수로 강제(터미널 세션 동안)
set PYTHONUTF8=1
python gfpgan\train.py -opt options\train_GFPGANv3_512_ALL_stage1.yml

PowerShell

# 1) 일회성 강제
python -X utf8 gfpgan/train.py -opt options/train_GFPGANv3_512_ALL_stage1.yml

# 2) 환경변수로 강제(세션 동안)
$env:PYTHONUTF8=1
python gfpgan/train.py -opt options/train_GFPGANv3_512_ALL_stage1.yml

-X utf8 또는 PYTHONUTF8=1 둘 중 하나만 써도 충분합니다.
chcp 65001(콘솔 코드페이지 변경)은 표준 입출력만 바뀌고 open() 기본 인코딩은 그대로라서 근본 해결이 아닙니다.

영구 적용(선택)

REM 사용자 환경변수에 영구 등록(새 터미널부터 적용)
setx PYTHONUTF8 1

해결 방법 2 — 라이브러리 소스에 인코딩 지정(대안)

패키지 업데이트 시 덮어쓰기 될 수 있으니, 방법 1이 더 깔끔합니다.

<venv>\Lib\site-packages\basicsr\utils\options.py 의 YAML 로드 부분을 다음처럼 수정:

# before
with open(args.opt, 'r') as f:
    opt = yaml.load(f, Loader=ordered_yaml()[0])

# after
with open(args.opt, 'r', encoding='utf-8') as f:
    opt = yaml.load(f, Loader=ordered_yaml()[0])

해결 방법 3 — YAML 파일 자체 점검

  • 에디터(예: VS Code)에서 UTF-8(BOM 없어도 OK)로 저장되어 있는지 확인.
  • 한글 주석을 일시 제거해도 에러가 사라지면, 인코딩/저장 문제가 맞습니다.

왜 chcp 65001만으로는 안 되나?

  • chcp 65001은 콘솔의 입출력 코드페이지만 바꿉니다.
  • Python의 open() 기본 인코딩은 OS 로캘을 따르며, 콘솔 코드페이지와 별개입니다.
  • 따라서 -X utf8 또는 PYTHONUTF8=1처럼 파이썬 레벨에서 UTF-8 모드를 켜야 파일 디코딩 문제가 근본적으로 해결됩니다.

확인 체크리스트

  • 현재 파이썬 기본 인코딩 확인:
    • UTF-8이면 안전. cp949이면 위 해결책을 적용.
  • python -c "import locale; print(locale.getpreferredencoding(False))"
  • YAML 저장 형식:
    • VS Code 우하단 인코딩 표시가 UTF-8인지 확인 → 아니면 다른 인코딩으로 저장.

마무리

  • 추천 루틴: 개발/학습 스크립트 실행 시 항상 -X utf8을 붙이거나, 사용자 환경변수에 PYTHONUTF8=1을 등록.
  • 팀/CI 환경이라면 프로젝트 README에 “Windows는 -X utf8 권장”을 명시해두면 재발을 줄일 수 있습니다.