SDXL로 텍스처 생성 프로젝트를 진행하면서
23.04.01
SDXL로 텍스처 생성 프로젝트를 진행하면서
2023년 하반기, Stable Diffusion XL(SDXL)이 공개되었을 때 솔직히 충격을 받았습니다. 이전 버전들은 "AI가 그린 거 티가 난다"는 느낌이 있었는데, SDXL은 품질이 한 단계 올라갔습니다. 회사에서 텍스처 생성 프로젝트를 진행하면서 SDXL을 본격적으로 활용해봤고, 그 경험을 공유합니다.
SDXL의 달라진 점
SDXL은 기존 SD 1.5나 SD 2.1과 비교해서 몇 가지 중요한 개선이 있었습니다.
from diffusers import StableDiffusionXLPipeline
import torch
# SDXL 로드
pipe = StableDiffusionXLPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
variant="fp16",
use_safetensors=True
)
pipe = pipe.to("cuda")
# 기본 해상도가 1024x1024
image = pipe(
prompt="a medieval castle, detailed architecture, golden hour lighting",
height=1024,
width=1024,
num_inference_steps=40,
guidance_scale=7.5
).images[0]주요 개선점:
- 해상도: 기본 1024x1024 (기존 512x512)
- 디테일: 훨씬 선명하고 세밀한 표현
- 손/얼굴: 여전히 완벽하지는 않지만 많이 개선됨
- 프롬프트 이해: 복잡한 프롬프트도 더 잘 따름
텍스처 생성 프로젝트
회사에서 3D 에셋의 텍스처를 빠르게 프로토타이핑하는 프로젝트를 진행했습니다. 기존에는 아티스트가 수작업으로 그리던 것을, AI로 초안을 만들고 수정하는 방식으로 파이프라인을 개선하려 했습니다.
워크플로우 설계
[기존 파이프라인]
1. 아티스트가 레퍼런스 수집 (2-3일)
2. 컨셉 스케치 (1-2일)
3. 텍스처 제작 (3-5일)
4. 피드백 및 수정 (1-2일)
총: 7-12일
[AI 보조 파이프라인]
1. SDXL로 컨셉 이미지 다량 생성 (몇 시간)
2. 아티스트가 선별 및 방향 결정 (반나절)
3. ControlNet으로 구조 잡고 텍스처 생성 (1일)
4. 아티스트가 후처리 및 완성 (2-3일)
총: 3-5일시간을 약 50% 단축할 수 있었습니다.
ControlNet과의 결합
핵심은 ControlNet과 함께 사용하는 것이었습니다. 아티스트가 기본 스케치를 그리면, 그 구조를 유지하면서 텍스처를 입히는 방식입니다.
from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel
from PIL import Image
import torch
# ControlNet 로드 (Canny edge용)
controlnet = ControlNetModel.from_pretrained(
"diffusers/controlnet-canny-sdxl-1.0",
torch_dtype=torch.float16
)
pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
controlnet=controlnet,
torch_dtype=torch.float16
)
pipe = pipe.to("cuda")
# 스케치 이미지 로드 및 edge 추출
def get_canny_edge(image_path):
import cv2
import numpy as np
image = cv2.imread(image_path)
image = cv2.Canny(image, 100, 200)
image = Image.fromarray(image)
return image
sketch = get_canny_edge("artist_sketch.png")
# 스케치 구조를 유지하면서 텍스처 생성
result = pipe(
prompt="stone castle wall texture, medieval, weathered, moss",
image=sketch,
controlnet_conditioning_scale=0.8, # 스케치 영향력 조절
num_inference_steps=30
).images[0]여러 종류의 ControlNet을 상황에 따라 사용했습니다:
CONTROLNET_CONFIGS = {
"structure": {
# 구조/형태를 잡을 때
"model": "diffusers/controlnet-depth-sdxl-1.0",
"scale": 0.7
},
"outline": {
# 윤곽선 기반 생성
"model": "diffusers/controlnet-canny-sdxl-1.0",
"scale": 0.8
},
"normal": {
# 노멀맵 기반 (3D 텍스처에 유용)
"model": "controlnet-normal-sdxl",
"scale": 0.6
}
}커스텀 LoRA 학습
프로젝트 아트 스타일에 맞는 결과물을 얻기 위해 커스텀 LoRA를 학습시켰습니다.
# LoRA 학습 설정 (kohya_ss 스크립트 기반)
training_config = {
"pretrained_model_name_or_path": "stabilityai/stable-diffusion-xl-base-1.0",
"train_data_dir": "./training_images", # 30-50장의 레퍼런스 이미지
"output_dir": "./lora_output",
# LoRA 파라미터
"network_dim": 32, # rank
"network_alpha": 16,
# 학습 파라미터
"learning_rate": 1e-4,
"max_train_epochs": 10,
"save_every_n_epochs": 2,
# 메모리 최적화
"mixed_precision": "fp16",
"gradient_checkpointing": True,
}학습 과정에서 배운 점들:
- 데이터 품질이 중요: 30장의 좋은 이미지가 100장의 평범한 이미지보다 낫습니다.
- 캡션이 중요: 각 이미지에 대한 설명을 잘 달아야 합니다.
- 과적합 주의: 에포크를 너무 많이 돌리면 과적합됩니다.
# 학습된 LoRA 적용
from diffusers import StableDiffusionXLPipeline
pipe = StableDiffusionXLPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16
)
# LoRA 로드
pipe.load_lora_weights("./lora_output", weight_name="project_style.safetensors")
# LoRA 가중치 조절 (0.0 ~ 1.0)
pipe.fuse_lora(lora_scale=0.8)실제 작업 결과
잘 된 것들
# 컨셉 아트 초안 - 매우 효과적
good_use_cases = [
"배경 컨셉 아트",
"환경 텍스처 (돌, 나무, 금속 등)",
"프롭 디자인 초안",
"무드보드 / 레퍼런스 이미지"
]
# 예시 프롬프트
prompts = {
"stone_wall": "seamless stone wall texture, medieval castle, weathered, mossy, 4k, detailed",
"wood_floor": "wooden floor planks, aged oak, scratched, warm lighting, seamless texture",
"metal_plate": "rusted metal plate, industrial, scratches and dents, seamless, pbr"
}아직 어려운 것들
# 한계가 있는 경우들
challenging_cases = [
"정확한 글씨/로고 - 여전히 이상하게 나옴",
"일관된 캐릭터 - 같은 캐릭터 여러 포즈 어려움",
"정확한 구도/레이아웃 - 대략적으로만 가능",
"완성품 수준 퀄리티 - 항상 후처리 필요"
]아티스트와의 협업
"AI가 아티스트를 대체하는 거 아니야?"라는 우려가 처음에 있었습니다. 하지만 실제로 써보니 오히려 아티스트의 역할이 더 중요해졌습니다.
AI가 잘하는 것:
- 대량의 옵션 빠르게 생성
- 레퍼런스 이미지 만들기
- 초안/프로토타입
아티스트가 잘하는 것:
- "이건 된다/안 된다" 판단
- 방향 설정과 큐레이션
- 세밀한 수정과 완성
- 프로젝트 스타일 일관성 유지결국 AI는 도구이고, 그 도구를 어떻게 활용하느냐는 사람의 역할입니다.
비용 분석
# 로컬 GPU vs 클라우드 API 비용 비교
local_gpu_cost = {
"hardware": "RTX 4090 (약 250만원)",
"전기세": "월 약 3-5만원",
"생성량": "하루 수천 장 가능",
"장기_비용": "6개월 이상 사용 시 유리"
}
cloud_api_cost = {
"per_image": "약 $0.01-0.02",
"daily_1000": "약 $10-20",
"monthly": "약 $300-600 (활발히 사용 시)",
"장점": "초기 투자 없음, 관리 불필요"
}우리 프로젝트에서는 생성량이 많아서 로컬 GPU가 유리했습니다. A100 한 대로 팀 전체가 사용했습니다.
저작권 고려사항
상업 프로젝트에서 가장 신경 쓴 부분입니다.
# 저작권 리스크 최소화 전략
safety_guidelines = {
"avoid": [
"특정 아티스트 이름 사용",
"특정 작품 언급",
"유명 IP 관련 프롬프트"
],
"prefer": [
"일반적인 스타일 설명 (예: 'watercolor style')",
"자체 데이터로 학습한 LoRA 사용",
"결과물 후처리로 변형"
]
}우리 프로젝트에서는 자체 레퍼런스 이미지로 LoRA를 학습시켜서 리스크를 줄였습니다.
2023년을 돌아보며
SDXL은 "이미지 생성 AI가 드디어 실무에서 쓸만해졌다"를 보여준 모델이었습니다. 완벽하지는 않지만, 워크플로우에 잘 통합하면 생산성을 크게 높일 수 있었습니다.
2024년에는 더 발전하리라 예상합니다. 특히 기대하는 것들:
- 일관된 캐릭터 생성 (IP-Adapter 등의 발전)
- 비디오 생성 (Stable Video Diffusion의 발전)
- 더 빠른 생성 속도 (SDXL Turbo, Lightning 등)
2024년 업데이트: 예상대로 많은 발전이 있었습니다.
POST_SDXL_DEVELOPMENTS = {
"SD3 (2024.02)": {
"architecture": "DiT (Diffusion Transformer) 기반",
"highlight": "텍스트 렌더링 크게 개선",
"note": "SDXL과 다른 아키텍처로 전환"
},
"FLUX (2024.08)": {
"creator": "Black Forest Labs",
"highlight": "현재 오픈소스 이미지 생성 최고 품질",
"variants": ["FLUX.1 [dev]", "FLUX.1 [schnell]"]
},
"video_generation": {
"Sora": "OpenAI (비공개)",
"Runway Gen-3": "상업 서비스",
"CogVideo": "오픈소스 대안"
}
}관련 글
참고 자료
- Stability AI - SDXL
- ControlNet
- kohya-ss LoRA Training
- ComfyUI - 노드 기반 워크플로우 도구
Comments