Published on

Stable Diffusion VRAM OOM 7가지 원인·해결

Authors

Stable Diffusion을 돌리다 보면 가장 흔하게 마주치는 에러가 CUDA out of memory(VRAM OOM)입니다. 특히 해상도를 조금만 올리거나, ControlNet·LoRA를 얹거나, 배치 사이즈를 키우는 순간 바로 터집니다. OOM은 단순히 “VRAM이 부족하다”로 끝나지 않습니다. 같은 GPU에서도 설정, 파이프라인, 메모리 파편화, 백엔드 옵션에 따라 체감 사용량이 크게 달라집니다.

이 글에서는 OOM을 만드는 대표 원인 7가지를 분해하고, Automatic1111(WebUI)·ComfyUI·순수 PyTorch 스크립트에서 바로 적용 가능한 해결책을 체크리스트처럼 제공합니다.

참고: VRAM 이슈를 근본적으로 줄이는 방법 중 하나가 양자화/경량화입니다. PyTorch 관점에서 모델을 더 가볍게 다루는 접근은 PyTorch 2.x PTQ로 int8 양자화해 4배 경량화도 함께 보면 도움이 됩니다.

OOM의 본질: 어디서 VRAM이 폭증하는가

Stable Diffusion의 VRAM은 크게 4군데에서 증가합니다.

  1. U-Net 활성화(activation): 스텝마다 중간 텐서가 생기며 가장 크게 먹습니다.
  2. Attention(KV 캐시 포함): 해상도와 토큰 수에 민감합니다.
  3. VAE 디코드/인코드: 고해상도에서 추가로 크게 튑니다.
  4. 부가 네트워크(ControlNet, IP-Adapter, LoRA 다중 적용 등): 모델 파라미터와 중간 텐서가 늘어납니다.

따라서 해결도 “어느 단계의 메모리를 줄일지”로 접근해야 빠릅니다.

1) 해상도(픽셀 수) 과다: 512에서 768로 올리면 왜 터질까

원인

VRAM은 대체로 면적(가로×세로) 에 비례해 증가합니다. 512×512에서 768×768은 한 변만 1.5배지만 면적은 2.25배입니다. 여기에 attention 비용까지 얹히면 체감은 더 큽니다.

해결

  • 가장 확실한 처방은 해상도 낮추고 업스케일입니다.
  • SDXL은 기본 해상도 자체가 높아 OOM이 더 쉽게 납니다.

WebUI 권장 조합

  • 512 또는 640으로 생성 후 업스케일
  • Hires. fix를 쓸 때는 Upscale byDenoising strength를 낮춰 단계적 접근

ComfyUI 전략

  • Latent Upscale로 latent 단계에서 먼저 키우고, 마지막에 VAE decode

예시(개념 코드)

# 해상도에 따른 메모리 압박을 줄이려면
# 1) 낮은 해상도에서 샘플링
# 2) 업스케일 후 짧은 denoise로 디테일 보강
base_w, base_h = 512, 512
upscale_w, upscale_h = 768, 768

2) 배치 사이즈(batch size)·배치 카운트(batch count) 착각

원인

Stable Diffusion에서 batch size는 한 번에 동시에 처리하는 샘플 수라 VRAM을 직격으로 때립니다. 반면 batch count는 반복 실행에 가깝고 VRAM 영향이 상대적으로 적습니다(툴에 따라 다름).

해결

  • OOM이면 먼저 batch size=1로 고정하세요.
  • 여러 장이 필요하면 batch count를 늘리는 방식으로 우회합니다.

WebUI 체크

  • Batch size를 2 이상으로 올렸다면 즉시 1로
  • XY Plot 같은 스크립트가 내부적으로 배치를 키우는지 확인

3) 샘플링 스텝·CFG·스케줄러가 만드는 “숨은” 메모리

원인

스텝 수 자체는 주로 시간에 영향을 주지만, 특정 조합에서는 메모리 피크가 높아질 수 있습니다.

  • 고CFG에서 guidance 계산이 더 무거워지는 경우
  • 일부 백엔드/최적화 옵션에서 중간 버퍼가 커지는 경우

해결

  • OOM이 반복되면 steps를 줄이는 것보다, 아래를 우선 적용하세요.
    • xFormers 또는 SDPA(Scaled Dot-Product Attention) 사용
    • --medvram 또는 --lowvram 같은 메모리 최적화 모드

4) Attention 최적화 미적용(xFormers/SDPA/Flash Attention)

원인

Attention은 해상도에 민감하고, 최적화가 없으면 VRAM이 급증합니다. 특히 SDXL·ControlNet 조합에서 차이가 큽니다.

해결(WebUI)

  • xFormers 설치 후 실행 옵션 적용
  • 또는 PyTorch 2.x의 SDPA 경로를 타도록 설정

WebUI 실행 옵션 예시

# Windows/Linux 공통 개념 예시
# 실제 옵션은 배포판/버전에 따라 다를 수 있음
python launch.py --xformers

PyTorch에서 SDPA 활성화(개념)

import torch

# 일부 환경에서는 SDPA/메모리 효율 attention 경로가 자동 선택됩니다.
# 필요 시 torch 버전과 CUDA, 드라이버를 맞추는 것이 핵심입니다.
print(torch.__version__)
print(torch.cuda.is_available())

5) VAE가 병목: 디코드 단계에서만 OOM 나는 케이스

원인

샘플링은 끝났는데 마지막에 OOM이 나는 경우가 있습니다. 이는 VAE 디코드가 고해상도에서 큰 텐서를 만들기 때문입니다.

해결

  • VAE를 타일링(tiling) 디코드로 바꾸거나, 타일 기반 업스케일러 사용
  • WebUI에서는 Tiled VAE류 확장이나 관련 옵션을 고려
  • ComfyUI는 VAE decode 노드를 타일 버전으로 교체

개념 예시

# 타일 디코드는 이미지를 여러 조각으로 나눠 디코드해
# 피크 VRAM을 낮추는 방식입니다.
# (구현은 툴/노드/확장에 따라 다름)
use_tiled_vae = True

6) ControlNet·IP-Adapter·LoRA 다중 적용으로 모델/텐서가 누적

원인

ControlNet 2개, IP-Adapter 1개, LoRA 여러 개를 동시에 쓰면 “모델 파라미터 + 중간 텐서”가 눈덩이처럼 불어납니다. 특히 SDXL에서 ControlNet은 체감 VRAM 증가가 큽니다.

해결

  • ControlNet은 필요한 것만 최소 개수로
  • LoRA는 가급적 1~2개로 시작해서 점진적으로 추가
  • IP-Adapter는 해상도/strength를 줄여 영향 확인

문제 재현 패턴

  • 같은 프롬프트인데 ControlNet만 켜면 OOM
  • 여러 LoRA를 끼면 특정 스텝에서만 터짐(피크 증가)

점검 순서

  1. ControlNet 전부 끄고 정상 동작 확인
  2. ControlNet 1개만 켜기
  3. LoRA 1개만 추가
  4. IP-Adapter 마지막에 추가

7) 메모리 파편화·캐시·다른 프로세스 점유(“VRAM은 있는데 OOM”)

원인

nvidia-smi로 보면 여유가 있어 보이는데도 OOM이 날 때가 있습니다.

  • PyTorch CUDA allocator의 파편화(fragmentation)
  • 브라우저(특히 하드웨어 가속), 게임, 다른 모델 서버가 VRAM 선점
  • WebUI/ComfyUI에서 여러 번 로드하며 캐시가 쌓임

해결

  • 다른 GPU 점유 프로세스 종료
  • WebUI/ComfyUI 재시작(가장 즉효)
  • PyTorch allocator 설정으로 파편화 완화

VRAM 점유 확인

nvidia-smi

PyTorch 파편화 완화(환경 변수)

아래는 대표적으로 쓰이는 설정입니다. 런처 스크립트나 실행 전에 환경 변수로 넣습니다.

# 메모리 블록 분할 정책을 조정해 파편화를 줄이는 방법 중 하나
# 값은 환경에 따라 튜닝 포인트입니다.
export PYTORCH_CUDA_ALLOC_CONF=max_split_size_mb:128

코드에서 캐시 정리(응급처치)

import torch
import gc

gc.collect()
if torch.cuda.is_available():
    torch.cuda.empty_cache()

실전 체크리스트: OOM이 나면 이 순서로 줄여라

  1. batch size=1로 고정
  2. 해상도부터 내리기(특히 SDXL은 1024 고집 금지)
  3. ControlNet/IP-Adapter/LoRA를 모두 끄고 하나씩 추가
  4. xFormers 또는 SDPA 경로 적용
  5. VAE 타일 디코드(디코드 단계 OOM일 때)
  6. --medvram/--lowvram 같은 메모리 모드 사용
  7. 재시작 + nvidia-smi로 점유 프로세스 제거 + 파편화 설정

WebUI(Automatic1111)에서 자주 먹히는 옵션 조합

아래는 “품질 조금 손해 보더라도 일단 안 터지게” 만드는 조합입니다.

  • batch size=1
  • 해상도는 512~768 범위에서 시작
  • --xformers 또는 동등한 attention 최적화
  • 필요 시 --medvram
  • Hires fix는 업스케일 배율을 낮게(예: 1.5) 시작

ComfyUI에서의 접근: 그래프를 쪼개서 피크를 낮춘다

ComfyUI는 노드 그래프가 명확해서 “피크 VRAM이 어디서 터지는지” 찾기 좋습니다.

  • 샘플링 이전 단계에서 불필요한 고해상도 입력을 줄이기
  • VAE decode를 마지막으로 미루기
  • 타일 VAE/타일 업스케일 노드로 교체
  • ControlNet을 그래프에서 분리해 영향 비교

마무리: OOM은 설정 문제가 아니라 “피크” 문제다

Stable Diffusion의 OOM은 평균 VRAM 사용량이 아니라, 특정 순간의 피크 메모리 때문에 발생하는 경우가 많습니다. 따라서 해결도 “옵션 하나 바꾸기”보다, 원인을 7가지 범주로 나눠 피크를 만드는 요소를 제거하는 방식이 가장 빠릅니다.

추가로, 모델 자체를 더 가볍게 만드는 방향(양자화/경량화)을 병행하면 장기적으로 OOM 빈도가 크게 줄어듭니다. 관련해서는 PyTorch 2.x PTQ로 int8 양자화해 4배 경량화도 함께 참고하세요.