# Qwen-Image-Layered로 포스터 자동 레이어 분해 (3/10): Qwen-Image-Layered 모델 깊이 이해 ## 논문 리뷰: 왜 레이어 분해가 가능한가? Qwen-Image-Layered는 2024년 12월에 발표된 최신 모델이다. 논문 제목은 **"Inherent Editability via Layer Decomposition"** (고유한 편집 가능성을 위한 레이어 분해). 핵심 아이디어: "완성된 이미지를 보고, 이것이 어떤 레이어들로 구성되었을지 역추론한다." ### 기존 방식의 한계 **전통적인 이미지 분할(Segmentation)**: ``` 입력 이미지 → [AI] → 객체별 마스크 예: 사람, 배경, 자동차 등으로 구분 ``` 문제점: - 의미론적 객체만 분리 (텍스트, 효과 등은 무시) - 레이어 순서 정보 없음 (어떤 게 앞/뒤인지) - Alpha channel 없음 (투명도 정보 부재) **Qwen-Image-Layered의 접근**: ``` 입력 이미지 → [AI] → RGBA 레이어 스택 각 레이어는: - RGB: 색상 정보 - Alpha: 투명도 (0~255) - 순서: 배경 → 전경 ``` ### 학습 방식 모델은 다음과 같이 학습되었다: 1. **합성 데이터 생성** ```python # 가상의 학습 과정 레이어1 (배경) + 레이어2 (객체) + 레이어3 (텍스트) ↓ 합성 완성된 이미지 ↓ 모델 학습 완성 이미지 → 원래 레이어들 복원 ``` 2. **Diffusion 기반 생성** Qwen-Image-Layered는 Diffusion 모델을 활용: ``` 노이즈 → [점진적 제거] → 깨끗한 레이어 ``` 각 레이어를 순차적으로 생성하면서, 이전 레이어와의 관계를 고려. ## 모델 아키텍처 ### Qwen2.5-VL 백본 Qwen-Image-Layered는 Qwen2.5-VL을 기반으로 한다. **Qwen2.5-VL이란?** - Alibaba Cloud의 Vision-Language 모델 - 이미지 이해 + 텍스트 생성 통합 - 7B ~ 72B 파라미터 (Layered는 7B 사용) **역할**: ``` 입력 이미지 → Qwen2.5-VL → 이미지 특징 추출 ↓ "이 이미지는 배경, 인물, 텍스트로 구성될 것 같다" (잠재 표현) ``` ### Diffusion 레이어 생성기 Qwen2.5-VL의 이해를 바탕으로, Diffusion 모델이 실제 레이어 생성: ```python # 간단화된 의사 코드 for layer_idx in range(num_layers): # 1. 현재까지 생성된 레이어 컨텍스트 context = stack_layers(previous_layers) # 2. Diffusion으로 다음 레이어 생성 noise = torch.randn(resolution, resolution, 4) # RGBA for step in range(50): # 50 inference steps noise = denoise_step(noise, context, step) # 3. 최종 레이어 layer = noise # 이제 노이즈가 아니라 깨끗한 레이어 previous_layers.append(layer) ``` ### Alpha Channel 예측 가장 중요한 부분: **투명도 예측** ```python # 각 픽셀의 Alpha 값 (0~255) alpha = model.predict_alpha(pixel_rgb, layer_context) # 0: 완전 투명 # 128: 반투명 # 255: 불투명 ``` 예시: ``` Layer 0 (배경): Alpha 전부 255 (불투명) Layer 1 (인물): 인물 부분만 255, 나머지 0 (투명) Layer 2 (텍스트): 글자 부분만 255 ``` ## 입력 및 출력 형식 ### 입력 ```python from PIL import Image # 1. 이미지 로드 image = Image.open("poster.jpg").convert("RGB") # 2. 크기 조정 (권장: 640 또는 1024) image = image.resize((1024, 1024)) # 3. 텐서 변환 import torch image_tensor = torch.from_numpy(np.array(image)).float() / 255.0 ``` **파라미터**: - `num_layers`: 2 ~ 10 (실험 결과 5가 최적) - `resolution`: 640 or 1024 (높을수록 품질 좋지만 느림) - `num_inference_steps`: 50 (Diffusion 단계, 많을수록 품질 향상) - `guidance_scale`: 7.5 (CFG, 높을수록 명확한 레이어) ### 출력 ```python # List[PIL.Image] layers = model.decompose(image, num_layers=5) # 각 레이어는 RGBA 형식 for i, layer in enumerate(layers): print(f"Layer {i}:") print(f" Mode: {layer.mode}") # RGBA print(f" Size: {layer.size}") # (1024, 1024) print(f" Format: {layer.format}") # PNG # 저장 layer.save(f"layer_{i}.png") ``` **레이어 순서**: - `layer_0`: 가장 뒤 (배경) - `layer_1`, `layer_2`, ... - `layer_n`: 가장 앞 (전경) ## 실제 추론 과정 시뮬레이션 포스터 예시: "AI 세미나 안내 포스터" ### 입력 이미지 분석 ``` [완성된 포스터] - 파란색 그라디언트 배경 - "AI Seminar" 큰 제목 - 날짜/장소 작은 글씨 - 로봇 일러스트 - 하단 주최사 로고 ``` ### 모델의 사고 과정 (Qwen2.5-VL) ``` 1. 이미지 특징 추출 → "텍스트 중심 디자인, 5개 레이어 적합" 2. 레이어 구조 예측 Layer 0: 배경 (그라디언트) Layer 1: 로봇 일러스트 Layer 2: 메인 타이틀 Layer 3: 부제목/날짜 Layer 4: 로고 ``` ### Diffusion 레이어 생성 ```python # Layer 0 (배경) noise_0 = random_noise(1024, 1024, 4) for step in range(50): # "배경만 생성하세요" 조건 noise_0 = denoise(noise_0, context="background gradient") layer_0 = noise_0 # RGB: 파란색 그라디언트 # Alpha: 전부 255 (완전 불투명) # Layer 1 (로봇) noise_1 = random_noise(1024, 1024, 4) for step in range(50): # "이전 레이어(배경) 위에 로봇만" noise_1 = denoise(noise_1, context=[layer_0, "robot illustration"]) layer_1 = noise_1 # RGB: 로봇 형태 # Alpha: 로봇 부분만 255, 나머지 0 # ... 반복 ... ``` ### 최종 출력 ``` layer_0.png: 1024x1024 RGBA, 450KB layer_1.png: 1024x1024 RGBA, 280KB (투명 영역 많음) layer_2.png: 1024x1024 RGBA, 120KB (텍스트만) layer_3.png: 1024x1024 RGBA, 80KB layer_4.png: 1024x1024 RGBA, 60KB ``` ## 성능 특성 ### GPU 메모리 요구사항 ``` Resolution Layers VRAM (FP16) VRAM (FP32) 640x640 3 4.2 GB 8.4 GB 640x640 5 5.8 GB 11.6 GB 1024x1024 3 8.5 GB 17.0 GB 1024x1024 5 12.1 GB 24.2 GB ``` **권장**: - 최소: GTX 1080 (8GB) - 640px, 3 레이어 - 권장: RTX 3090 (24GB) - 1024px, 5 레이어 - 최적: A100 (40GB) - 1024px, 10 레이어 ### 추론 속도 RTX 3090 기준: ``` Resolution Layers FP16 (초) FP32 (초) 640x640 3 15 32 640x640 5 28 58 1024x1024 3 35 72 1024x1024 5 62 128 ``` **최적화 팁**: ```python # 1. FP16 사용 (속도 2배, 메모리 절반) model = model.half() # torch.float16 # 2. Inference steps 감소 (품질 약간 하락) layers = model.decompose(image, num_inference_steps=30) # 50 → 30 # 3. Batch 처리 (여러 이미지 동시) layers_batch = model.decompose_batch([img1, img2, img3]) ``` ## 모델의 강점과 약점 ### 강점 1. **투명도 정보 포함** - Photoshop 레이어처럼 바로 사용 가능 - 재편집 용이 2. **가변 레이어 수** - 단순 이미지 → 3 레이어 - 복잡 이미지 → 10 레이어 3. **재귀 분해** ```python # 특정 레이어를 다시 분해 layer_1 = layers[1] sub_layers = model.decompose(layer_1, num_layers=3) # layer_1을 3개로 더 세분화 ``` 4. **범용성** - 포스터, 웹 디자인, 일러스트 모두 가능 ### 약점 1. **완벽하지 않은 경계선** ``` 문제: 객체 경계에 아티팩트 발생 해결: Alpha matting 후처리 (v8에서 다룸) ``` 2. **의미 없는 레이어 생성** ``` 문제: 5 레이어 요청 시, 빈 레이어 포함될 수 있음 해결: 레이어 유효성 검증 ``` 3. **텍스트 왜곡** ``` 문제: 텍스트가 정확히 복원되지 않음 해결: OCR + 원본 텍스트 오버레이 ``` 4. **색상 변화** ``` 문제: 원본과 레이어 합성 시 색상 미묘하게 다름 해결: 색상 보정 알고리즘 ``` ## 다른 모델과 비교 ### vs LayerDiffusion **LayerDiffusion** (2024년 초): - Stable Diffusion 기반 - 레이어별 생성 가능 - 하지만 "이미지 → 레이어 분해"는 불가 **Qwen-Image-Layered**: - 역방향 작업 가능 (이미지 → 레이어) - Qwen2.5-VL의 이미지 이해 능력 활용 ### vs Deep Image Matting **Deep Image Matting**: - 전경/배경 2개 레이어만 - Alpha matte 품질 우수 - 하지만 다층 분해 불가 **Qwen-Image-Layered**: - N개 레이어 (2~10) - 복잡한 구조 분해 ### vs Photoshop "Subject Select" **Photoshop AI**: - 객체별 선택 - 수작업 필요 - 레이어 자동 생성 없음 **Qwen-Image-Layered**: - 완전 자동 - 레이어 순서까지 예측 ## 실전 팁 ### 최적 레이어 수 선택 ```python # 이미지 복잡도 → 레이어 수 매핑 complexity = analyze_complexity(image) if complexity == "simple": num_layers = 3 # 배경, 주요 객체, 텍스트 elif complexity == "medium": num_layers = 5 # 배경, 2-3 객체, 텍스트, 효과 else: # complex num_layers = 7 # 다층 구조 def analyze_complexity(image): """간단한 복잡도 분석""" from scipy import ndimage # Edge detection edges = ndimage.sobel(np.array(image.convert('L'))) edge_density = np.mean(edges > 30) if edge_density < 0.1: return "simple" elif edge_density < 0.3: return "medium" else: return "complex" ``` ### Guidance Scale 조정 ```python # CFG (Classifier-Free Guidance) 스케일 # 낮음 (5.0): 부드럽지만 경계 불분명 # 중간 (7.5): 균형 (기본값) # 높음 (10.0): 명확하지만 아티팩트 증가 layers = model.decompose( image, guidance_scale=7.5 # 실험적으로 조정 ) ``` ## 다음 단계 v4에서는 **로컬 환경 세팅**을 다룬다: - Python 환경 구축 - Qwen-Image-Layered 모델 다운로드 - GPU 드라이버 설정 - 첫 추론 실행 및 검증 모델의 원리를 이해했으니, 이제 실제로 실행해볼 차례다. --- **이전 글**: [기술 스택 선정과 아키텍처 설계 (2/10)](./qwen-image-layered-v2.md) **다음 글**: [로컬 환경 세팅과 첫 추론 (4/10)](./qwen-image-layered-v4.md)