Qwen 모델 구축, 삽질의 연속

Junyoung·2026년 3월 30일

AI(GPU)

목록 보기
4/4

3편에서 AWS 환경 세팅을 마쳤다.

이제 Qwen-Image-Edit-2511 모델을 실제로 올려보자.

생각보다 순탄하지 않았다.


모델 다운로드

작업 폴더를 만들고 모델을 내려받는다.

모델 크기가 약 40GB라 시간이 좀 걸린다.

mkdir -p ~/qwen-project
cd ~/qwen-project
from huggingface_hub import snapshot_download

snapshot_download(
    repo_id="Qwen/Qwen-Image-Edit-2511",
    local_dir="./model",
    local_dir_use_symlinks=False,
    resume_download=True
)

resume_download=True 덕분에 중간에 끊겨도 이어받을 수 있다 !


1차 시도 — device_map="cuda"

모델을 GPU에 전부 올리는 방식으로 시작했다.

pipeline = QwenImageEditPlusPipeline.from_pretrained(
    "Qwen/Qwen-Image-Edit-2511",
    torch_dtype=torch.float16,
    device_map="cuda",
    low_cpu_mem_usage=True
)

바로 에러가 떴다.

torch.OutOfMemoryError: CUDA out of memory.
Tried to allocate 72.00 MiB.
GPU 0 has a total capacity of 21.99 GiB of which 69.38 MiB is free.
Of the allocated memory 21.48 GiB is allocated by PyTorch

VRAM 상태를 보면 이렇다.

Total VRAM : 21.99 GiB
사용 중    : 21.91 GiB (99.6%)
 ├─ PyTorch : 21.48 GiB
 └─ 기타    : 0.43 GiB
남은 공간  : 0.069 GiB (69MB)

72MB가 필요한데 69MB밖에 없었다.

모델이 VRAM을 꽉 채워버린 것이다.


2차 시도 — device_map="balanced"

GPU 메모리가 부족하면 자동으로 CPU로 offload하는 방식으로 바꿨다.

pipeline = QwenImageEditPlusPipeline.from_pretrained(
    "Qwen/Qwen-Image-Edit-2511",
    torch_dtype=torch.float16,
    device_map="balanced",
    low_cpu_mem_usage=True
)

실행은 됐다.

근데 문제가 생겼다.

40%|████████| 12/30 [4:09:33<6:09:14, 1230.82s/it]

30 스텝 중 12번째(40%)에 4시간 9분이 걸렸다.

스텝당 약 20분, 총 예상 시간이 10시간이 넘었다.

GPU와 CPU를 계속 왔다갔다하면서 속도가 처참하게 느려진 것이다.

결국 KeyboardInterrupt 로 중단했다.


3차 시도 — FP 조절

VRAM 사용량을 줄이려면 데이터 타입을 낮추면 된다.

# 기존
torch_dtype=torch.float16

# 변경 시도
torch_dtype=torch.float8

바로 막혔다.

PyTorch에는 torch.float8 이 없다 !

AttributeError: module 'torch' has no attribute 'float8'

float16보다 더 낮은 타입을 쓰려면 다른 방법이 필요했다.


해결 — 서버 교체 + sequential offload + bfloat16 조합

원래 쓰던 서버는 VRAM 8GB였다.

모델 자체가 너무 커서 8GB로는 아예 올라가지도 않았다.

서버를 교체했지만 모델 전체를 다 올릴 수 있는 사양으로 바꾼 건 아니었다.

그래서 두 가지를 함께 적용했다.

sequential CPU offload — 레이어 단위로 필요할 때만 GPU에 올리고 나머지는 CPU에 둔다.

model 방식보다 느리지만 메모리를 훨씬 적게 쓴다.

pipeline.enable_sequential_cpu_offload()

bfloat16으로 타입 변경 — float16 대비 수치 안정성이 높고 메모리 사용량은 동일하다.

torch_dtype=torch.bfloat16

이 두 가지 조합으로 정상적으로 동작했다 !


결과

서버를 바꾼 뒤 정상적으로 동작했다.

GPU 상태도 안정적이었다.

GPU 사용률 : 89%
온도       : 73°C
전력       : 58W / 72W
메모리 사용 : 890 MiB / 23034 MiB (약 3.9%)
여유 메모리 : 약 21.6 GB

강아지 사진 테스트

원본 사진에 다양한 각도와 스타일 변환을 적용해봤다.

  • 원본 강아지 사진

  • right side view high-angle shot close-up

  • back side view high-angle shot close-up

  • left side view high-angle shot close-up

  • 지브리 스타일 변환 결과

지브리 스타일 변환에 사용한 프롬프트다.

Transform the actual photo provided into an anime-style landscape scene.
Keep the core composition and elements from the original photo,
but render everything in vibrant anime aesthetics with exaggerated colors,
dynamic lighting, soft gradients, and cel-shaded outlines typical of
Studio Ghibli-inspired landscapes.

사람 사진 테스트

  • 원본 사람 사진

  • right side view high-angle shot close-up 결과


LoRA + Gradio 서버

LoRA까지 붙이고 외부에서 접근할 수 있는 Gradio 서버를 구축했다.

단일 편집과 배치 편집(다중 각도 한 번에 생성) 두 가지 탭으로 구성했다.

import gradio as gr
import torch
from PIL import Image
from diffusers import QwenImageEditPlusPipeline
import gc
import os

os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'expandable_segments:True'

pipeline = QwenImageEditPlusPipeline.from_pretrained(
    "./model",
    torch_dtype=torch.bfloat16
)
pipeline.enable_sequential_cpu_offload()

pipeline.load_lora_weights(
    "fal/Qwen-Image-Edit-2511-Multiple-Angles-LoRA",
    adapter_name="multi_angle"
)
pipeline.set_adapters(["multi_angle"], adapter_weights=[0.9])

서버는 0.0.0.0:7860 으로 띄운다.

demo.launch(
    server_name="0.0.0.0",
    server_port=7860,
    share=False,
    debug=True
)
  • 결과화면

Qwen 모델 핵심 파라미터

일반적인 Diffusion 모델과 파라미터가 다르다.

공식 문서 기준으로 아래 값을 써야 제대로 동작한다.

output = pipeline(
    image=[img],           # 리스트로 전달
    prompt=prompt,
    negative_prompt=" ",   # 빈 문자열이 아닌 공백 하나
    true_cfg_scale=4.0,    # Qwen 필수 파라미터
    guidance_scale=1.0,    # Qwen 기본값
    num_inference_steps=20,
)

negative_prompt=" " 에서 "" 이 아니라 " " (공백 하나)를 써야 한다.

처음엔 이걸 몰라서 한참 헤맸다 !


메모리 최적화 정리

T4에서 삽질하면서 배운 최적화 포인트 4가지다.

항목변경 전변경 후효과
CPU Offloadmodelsequential메모리 절약
환경 변수없음expandable_segments단편화 방지
이미지 크기원본 그대로512px메모리 1/4 감소
Steps4020속도 2배 향상

1024x1024 → 512x512로 줄이는 것만으로 메모리 사용량이 1/4로 줄어든다 !


처음엔 단순히 모델을 올리는 거라 쉽게 생각했는데, VRAM 용량과 속도 사이에서 꽤 고생했다.

이번에 배운 건 하나다.

VRAM이 모델 크기를 전부 수용할 수 있으면 제일 좋다.

하지만 그렇지 않더라도 방법이 있다.

  • sequential CPU offload — 레이어 단위로 쪼개서 필요한 부분만 GPU에 올린다
  • bfloat16 / float16 — 데이터 타입을 낮춰서 메모리 사용량을 줄인다
  • 이미지 크기 축소 — 입력 해상도를 낮추면 메모리가 확 줄어든다

서버 사양이 부족하다고 바로 포기할 필요가 없다는 걸 직접 경험했다.

물론 속도 트레이드오프는 있다. 하지만 테스트 목적이라면 충분히 쓸 만하다 !

profile
라곰

0개의 댓글