Published on

Stable Diffusion 4K 업스케일, VRAM OOM 피하는 법

Authors

서로 다른 업스케일 경로(리샘플 기반 vs 확산 기반)에서 VRAM이 어디서 터지는지 이해하면, 8GB GPU에서도 4K 워크플로우를 안정적으로 구성할 수 있습니다. 이 글은 AUTOMATIC1111 WebUI 기준으로 설명하지만, 원리는 ComfyUI나 InvokeAI에도 그대로 적용됩니다.

4K 업스케일에서 OOM이 나는 진짜 이유

4K(3840x2160)는 픽셀 수가 8,294,400입니다. 확산 모델의 UNet은 단순히 픽셀 수만큼만 메모리를 쓰지 않습니다.

  • 활성화(activation) 메모리: UNet의 각 블록에서 중간 feature map이 누적됩니다.
  • 어텐션(Attention) 메모리: 해상도가 커질수록 토큰 수가 늘고, 특정 구현은 메모리가 급격히 증가합니다.
  • VAE 디코드/인코드: 최종 이미지로 변환하는 구간도 큰 텐서를 다룹니다.
  • 배치/히든 스테이트: 배치가 1이어도, 단계 수와 샘플러 설정에 따라 피크가 달라집니다.

즉, 4K를 “한 번에” txt2img 또는 img2img로 돌리는 건 대부분의 소비자 GPU에서 불안정합니다. 해결책은 크게 두 가지입니다.

  1. 확산을 4K 전체에 한 번에 적용하지 않는다 (타일링)
  2. 확산 자체를 최소화하고 업스케일러에 맡긴다 (ESRGAN/4x-UltraSharp 등)

권장 전략 1: 2단계(저해상도 생성 + 타일 업스케일)

가장 안정적인 패턴은 아래입니다.

  1. txt2img짧은 변 기준 768 또는 1024 정도로 생성
  2. img2img타일 업스케일(또는 타일 디퓨전) 로 4K까지 확장

이 방식이 좋은 이유는, UNet이 한 번에 보는 해상도를 타일 크기로 제한해서 피크 VRAM을 고정할 수 있기 때문입니다.

1단계: 베이스 이미지 생성(권장 프리셋)

  • 해상도: 1024x576(16:9) 또는 960x540
  • Steps: 20 전후
  • Sampler: DPM++ 2M Karras 계열
  • CFG: 5~7
  • Hires.fix: 끄는 편(일단은)

Hires.fix는 편하지만, 설정이 과하면 중간에 해상도가 커지는 순간 VRAM이 급등해 OOM이 나기 쉽습니다. 4K 목적이면 2단계로 분리하는 게 안전합니다.

권장 전략 2: 타일 기반 업스케일(확산 적용)로 4K 만들기

A1111에서 4K를 안정적으로 만들려면, 보통 아래 조합 중 하나를 씁니다.

  • Tiled Diffusion + Tiled VAE
  • Ultimate SD Upscale(내부적으로 타일링)

둘 다 핵심은 동일합니다. 타일 크기오버랩을 적절히 잡아 경계(seam)를 숨기고, 타일 단위로 UNet을 돌려 VRAM을 통제합니다.

타일 크기와 오버랩 가이드

  • 타일 크기: 512 또는 768
  • 오버랩: 64~128
  • 디노이즈(denoise): 0.2~0.45

경험적으로

  • VRAM이 작으면 타일 512
  • 품질을 올리고 싶으면 타일 768(대신 VRAM 증가)

오버랩은 seam 방지에 중요합니다. 오버랩을 0으로 두면 경계가 티 나기 쉽습니다.

Ultimate SD Upscale 추천 프리셋(8GB~12GB 기준)

  • Target size: 3840x2160
  • Upscaler: 4x-UltraSharp 또는 R-ESRGAN 4x+
  • Tile width/height: 512
  • Tile overlap: 96
  • Denoising strength: 0.3
  • Steps: 12~20
  • CFG: 5.5 전후

이 조합은 “업스케일러로 크게 키운 뒤, 디퓨전으로 디테일을 정돈”하는 방식이라 4K에서도 비교적 안정적입니다.

VRAM OOM을 실제로 줄이는 체크리스트

여기부터는 “같은 워크플로우인데도 어떤 환경에서는 터지고 어떤 환경에서는 안 터지는” 차이를 만드는 항목들입니다.

1) VAE를 타일로 돌리기

VAE 디코드가 생각보다 VRAM 피크를 만들 때가 많습니다. Tiled VAE를 켜면 4K에서 안정성이 크게 올라갑니다.

  • 효과: VRAM 피크 감소
  • 비용: 약간의 속도 저하

2) Cross-Attention 최적화(SDP, xFormers)

환경에 따라 가장 체감이 큽니다.

  • PyTorch SDP(Scaled Dot-Product Attention) 사용
  • xFormers 활성화

둘 중 하나만으로도 메모리 사용량이 줄어드는 경우가 많습니다.

3) FP16(half)와 채널 마지막 메모리 포맷

  • --precision full 같은 설정은 피하기
  • 가능하면 fp16 유지

특히 업스케일 단계에서 fp32로 올라가면 OOM이 쉽게 납니다.

4) 불필요한 기능 끄기

  • ControlNet을 여러 개 동시에 사용
  • ADetailer 같은 후처리 확산
  • 고해상도에서 여러 LoRA 중첩

이런 것들이 “조금씩” VRAM을 갉아먹다가 타일 경계나 VAE 단계에서 터집니다. 4K 업스케일 시점에는 필요한 것만 남기세요.

5) 배치와 시드 반복을 분리

4K 업스케일은 배치 처리에 취약합니다.

  • batch size1
  • 여러 장이 필요하면 스크립트로 반복 실행

이건 서버 운영에서 과부하를 피하기 위해 재시도·큐잉을 두는 것과 사고방식이 유사합니다. 관련 패턴은 Claude API 529 Overloaded 재시도·큐잉 패턴 정리도 참고할 만합니다.

“확산 없이” 4K 업스케일: 가장 안전하지만 한계도 있음

VRAM이 정말 빡빡하거나, 빠르게 4K 납품이 필요하면 확산을 최소화하고 업스케일러만 쓰는 선택지가 있습니다.

  • Extras 탭에서 업스케일러만 적용
  • 4x-UltraSharp 2회(2x + 2x) 같은 체인

장점

  • OOM 확률이 매우 낮음
  • 속도가 빠름

단점

  • 디테일 “창조”가 아니라 샤프닝/보간이어서, 원본이 흐리면 결과도 한계가 있음

따라서 상업용 일러스트나 인물 디테일이 중요한 경우엔, 최소한 denoise 0.25~0.35 정도의 타일 디퓨전을 한 번 섞는 편이 결과가 더 좋습니다.

실전 예시: CLI로 타일 업스케일 파이프라인 구성

WebUI를 쓰더라도, 반복 작업은 CLI나 스크립트로 고정해두면 실수가 줄고 OOM 재현도 쉬워집니다. 아래는 “업스케일러로 2배” 후 “타일 img2img”를 수행한다는 가정의 의사 코드입니다.

# 1) 사전 업스케일(리샘플)
python upscale.py \
  --input "input.png" \
  --output "up2x.png" \
  --upscaler "4x-UltraSharp" \
  --scale 2

# 2) 타일 img2img(확산)로 디테일 정리
python tiled_img2img.py \
  --input "up2x.png" \
  --output "out_4k.png" \
  --target_width 3840 \
  --target_height 2160 \
  --tile_size 512 \
  --tile_overlap 96 \
  --steps 16 \
  --cfg 5.5 \
  --denoise 0.3 \
  --sampler "dpmpp_2m_karras" \
  --precision "fp16" \
  --vae "tiled"

핵심은 tile_size, tile_overlap, denoise 3개가 결과 품질과 안정성의 대부분을 결정한다는 점입니다.

OOM이 났을 때 “원인”을 빠르게 좁히는 방법

OOM은 같은 메시지처럼 보여도, 실제로는 피크 지점이 다릅니다. 아래 순서로 끊어보면 원인 파악이 빨라집니다.

  1. VAE 단계에서 터지나?

    • 증상: 샘플링은 끝났는데 저장 직전에 죽음
    • 대응: Tiled VAE, VAE 변경, 저장 포맷/후처리 축소
  2. UNet 샘플링 중간에 터지나?

    • 대응: 타일 크기 감소(768에서 512), steps 감소, ControlNet/LoRA 축소
  3. 특정 업스케일러에서만 터지나?

    • 대응: 업스케일러 교체, 2회 체인 대신 1회, 또는 업스케일을 CPU로 분리

원인 분해는 디버깅의 기본인데, 네트워크/플랫폼 이슈를 빠르게 좁히는 접근과 유사합니다. 예를 들어 EKS CoreDNS DNS timeout·SERVFAIL 10분 진단처럼 “어디서 병목이 생기는지”를 단계별로 분리하면 해결이 빨라집니다.

추천 조합 요약(환경별)

8GB GPU(가장 흔한 구간)

  • 베이스 생성: 768p~1024p
  • 4K 업스케일: Ultimate SD Upscale
  • 타일: 512, 오버랩 96
  • denoise: 0.25~0.35
  • 부가 기능: ControlNet은 1개 이하 권장

12GB~16GB GPU

  • 타일: 768도 가능(상황에 따라)
  • denoise를 0.35~0.45까지 올려 디테일 강화 가능

24GB 이상

  • 여전히 타일링이 유리한 경우가 많음
  • “한 번에 4K img2img”도 가능할 수 있지만, 속도와 안정성 관점에서 타일이 더 예측 가능

흔한 실수 5가지

  1. 4K를 txt2img로 바로 뽑으려 함
  2. 타일 오버랩을 너무 낮게 잡아 seam이 생김
  3. denoise를 과하게 올려 원본 구도가 무너짐
  4. 업스케일 단계에서 ControlNet/LoRA를 과도하게 중첩
  5. 배치 처리로 여러 장을 한 번에 돌리다가 OOM

결론: “4K를 한 번에”가 아니라 “4K를 나눠서”

Stable Diffusion에서 4K 업스케일을 VRAM OOM 없이 성공시키는 핵심은 단순합니다.

  • 확산 모델이 한 번에 보는 면적을 tile_size로 제한하고
  • 경계는 overlap으로 숨기며
  • 디테일은 denoise를 낮게 유지한 채 여러 단계로 쌓는다

이 3가지만 지키면, 스펙이 낮은 GPU에서도 4K 결과물을 안정적으로 얻을 수 있습니다. 다음에 OOM이 나면 “해상도 자체”가 아니라, 어느 단계의 피크가 터졌는지부터 분해해서 접근해 보세요.