RU
EN
Исходный размер 853x1280

Праду носит Дьявол

// концепция

Моя собака — померанец по кличке Прада — занимает большое место не только в моем сердце, но и в моей галерее. Поэтому создать проект с ее участием показалось мне отличной идеей.
Она живет, возможно, не самую яркую жизнь: в городе Минске, в небольшой уютной квартире спального района, имея хозяйку (то есть меня) и трех кожаных в придачу. Однако, что мешает нам посмотреть на радикально другую жизнь моей собаки, поместив ее в контекст индустрии моды?

Прада необычна в своем невежестве. Это моя первая собака и сразу такой подарок — самое доброе и жизнерадостное существо на планете; Примеры исходных изображений

Идея проекта: научить нейросеть «знать» мою собаку Праду (шпиц) и «поселить» ее в визуальный мир фильма «Дьявол носит Prada». Это глянцевые офисы, подиумы, нью-йоркские улицы и редакторские фотосессии. Совпадение клички и названия бренда стало отправной точкой: собака получает роль
главной редакторши модного журнала, но остается узнаваемой. Технически проект построен на дообучении модели Stable Diffusion XL методом DreamBooth LoRA. Это позволяет «привить» базовой модели новый объект (конкретную собаку) по небольшому набору фотографий и затем свободно
помещать его в разные сцены с помощью текстовых описаний.

Прада очень любвеобильная и требует много внимания; Пример исходных изображений

Исходные изображения для обучения


В датасет вошло 19 фотографий Прады. Все они были приведены к квадрату 1:1
(1024×1024 px). Съёмка велась дома/ на улице, на телефон. Я старалась сделать набор разнообразным: разные, ракурсы, позы, моменты и эмоции.

Еще примеры исходных изображений

// разработка проекта

Первым этапом в разработке стала установка необходимых элементов:

ЯЧЕЙКА 1. Установка GPU! nvidia-smiЯЧЕЙКА 2. Установка библиотек! pip install bitsandbytes transformers accelerate peft datasets -qЯЧЕЙКА 3. Установка diffusers из git! pip install git+https://github.com/huggingface/diffusers.git -q

Исходный размер 1024x512

Итоговые изображения (1) Портретная съемка для обложки журнала; a magazine cover photo of sks spitz dog, glamorous studio portrait, soft beauty lighting, luxury fashion photography, sharp focus, 85 mm lens

Серия изображений строится на визуальном коде фильма: роскошные интерьеры, редакционный свет, «глянцевая» композиция и фэшн-фотография.
Описания:
сцены в промптах отсылали к ключевым локациям: офис редактора журнала, подиум, нью-йоркская улица, Париж.

Исходный размер 1024x512

Дополнительные изображения портретной сьемки модели Прада

Второй этап разработки кода — работа с архивом:ЯЧЕЙКА 5. Поиск и распаковка zip с фотоimport glob
import os
import shutil
import zipfile# 1) Ищем zip-архив
found = glob.glob («/content/.zip») + glob.glob («/content/**/.zip», recursive=True)
found = [p for p in dict.fromkeys (found) if «sample_data» not in p]
print («Найденные zip-архивы:», found)if not found:
raise FileNotFoundError («Zip не найден, загрузите его в папку /content»)ZIP_PATH = found[0]
print («Используем архив:», ZIP_PATH)# 2) Распаковываем
extract_dir = «/content/_unzipped»
shutil.rmtree (extract_dir, ignore_errors=True)with zipfile.ZipFile (ZIP_PATH) as z:
z.extractall (extract_dir)# 3) Ищем картинки во всех вложенных папках
exts = (».jpg», «.jpeg», «.png», «.webp», «.bmp»)
all_files = []for root, dirs, fs in os.walk (extract_dir):
if «__MACOSX» in root:
continue
for f in fs:
if f.lower ().endswith (exts) and not f.startswith (».»):
all_files.append (os.path.join (root, f))all_files.sort ()
print («Найдено изображений в архиве:», len (all_files))if not all_files:
print («Структура распакованного архива:»)
! find /content/_unzipped | head -50

Исходный размер 1024x512

Итоговое изображение (2) Прада катается по Нью-Йорку a photo of sks spitz dog wearing oversized black sunglasses, sitting in the back seat of a black luxury car, city lights through the window, moody editorial photo

Исходный размер 1024x1024

Итоговые изображения (3) Прада в своем офисе a photo of sks spitz dog sitting in a luxury fashion office, editorial magazine photo, high-end fashion, cinematic lighting, highly detailed

Третий этап — работа с исходными изображениями:ЯЧЕЙКА 6. Приведение фото к квадрату 1024 на 1024 import os
import shutil
from PIL import Image, ImageOpslocal_dir = «/content/prada_processed»
SIZE = 1024shutil.rmtree (local_dir, ignore_errors=True)
os.makedirs (local_dir, exist_ok=True)for i, p in enumerate (all_files):
img = Image.open (p).convert («RGB»)
img = ImageOps.exif_transpose (img)
img = ImageOps.fit (img, (SIZE, SIZE), Image.LANCZOS, centering=(0.5, 0.5))
img.save (f"{local_dir}/prada_{i: 03d}.jpg», quality=95)print («Готово:», len (os.listdir (local_dir)), «изображений в», local_dir)ЯЧЕЙКА 7. Функция для сетки картинокfrom PIL import Imagedef imageGrid (imgs, rows, cols, resize=256):
if resize is not None:
imgs = [img.resize ((resize, resize)) for img in imgs]w, h = imgs[0].size
grid = Image.new («RGB», size=(cols * w, rows * h))for i, img in enumerate (imgs):
grid.paste (img, box=(i % cols * w, i // cols * h))
return gridЯЧЕЙКА 8. Предпросмотр фотоimport glob
from PIL import Imageimgs = [Image.open (p) for p in sorted (glob.glob (f"{local_dir}/*.jpg»))]
num_imgs_to_preview = min (5, len (imgs))grid = imageGrid (imgs[: num_imgs_to_preview], 1, num_imgs_to_preview)
grid

Исходный размер 1024x512

Итоговое изображение (4) Прада на фотосессии на крыше здания, Нью-Йорк a photo of sks spitz dog on a rooftop terrace at sunset, city skyline in the background, wearing a silk scarf, golden hour, fashion editorial

Нейросеть усвоила окрас, форму морды, пушистость шерсти, цвет глаз и характерную мимику моей собаки. Особенно хорошо Прада узнаётся в кадрах на улице и в сидячем положении. В целом нейросеть хорошо выявила характерные эмоции и позы, и смогла четко выполнить промт.

Исходный размер 1024x512

Итоговое изображение (5) Прада на фотосессии в Париже a photo of sks spitz dog standing on a Paris street in front of the Eiffel Tower, wearing a designer scarf, golden hour, fashion editorial photo, highly detailed

Исходный размер 1024x512

Итоговое изображение (6) Фотосессия на улицах Нью-Йорка a movie poster style image of sks spitz dog in sunglasses walking forward, city street, dramatic backlight, cinematic composition, no text

Четвертый этап — BLIP:ЯЧЕЙКА 9. Загрузка BLIP для подписейimport requests
from transformers import AutoProcessor, BlipForConditionalGeneration
import torchdevice = «cuda» if torch.cuda.is_available () else «cpu»blip_processor = AutoProcessor.from_pretrained («Salesforce/blip-image-captioning-base»)
blip_model = BlipForConditionalGeneration.from_pretrained (
«Salesforce/blip-image-captioning-base», torch_dtype=torch.float16
).to (device)def caption_images (input_image):
inputs = blip_processor (images=input_image, return_tensors="pt»).to (device, torch.float16)
pixel_values = inputs.pixel_values
generated_ids = blip_model.generate (pixel_values=pixel_values, max_length=50)
generated_caption = blip_processor.batch_decode (generated_ids, skip_special_tokens=True)[0]
return generated_captionЯЧЕЙКА 10. Список фото для подписей:import glob
from PIL import Imageimgs_and_paths = [(path, Image.open (path)) for path in sorted (glob.glob (f"{local_dir}/*.jpg»))]
print (len (imgs_and_paths), «изображений для подписей»)ЯЧЕЙКА 11: Генерация подписей:import jsoncaption_prefix = «a photo of sks spitz dog, „with open (f"{local_dir}/metadata.jsonl», «w») as outfile:
for path, im in imgs_and_paths:
caption = caption_prefix + caption_images (im).split («\n»)[0]
entry = {"file_name»: os.path.basename (path), «prompt»: caption}
json.dump (entry, outfile)
outfile.write («\n»)ЯЧЕЙКА 12: Проверка подписей:! head -n 19 /content/prada_processed/metadata.jsonlЯЧЕЙКА 13: Освобождение памяти от BLIP:import gc
import torchdel blip_processor, blip_model
gc.collect ()
torch.cuda.empty_cache ()

Исходный размер 0x0

Исходное изображение (7) Фотосессия для рекламы нового пальто a photo of sks spitz dog wearing a tiny red trench coat on a rainy Paris street, wet cobblestones, reflections, cinematic, moody

Исходный размер 1024x512

Исходное изображение (8) Главный офис a photo of sks spitz dog as a fashion magazine editor-in-chief, sitting behind a glossy white desk in a luxury New York office, wearing a tiny black blazer, dramatic editorial lighting, highly detailed

Исходная идея была в том, чтобы получить не просто «собаку в красивом месте», а узнаваемую внешность Прады, из собранного мною архива, в эстетике фильма. Мне кажется у меня не получилось полностью передать ощущение фильма «Дьявол носит Парада», но удалось поместить мою собаку в контекст иной жизни, которая отличается от ее реальной.

Исходный размер 1024x512

Итоговое изображение (9) Прада блистает на подиуме a photo of sks spitz dog walking confidently down a fashion runway, flashing cameras, front row audience, high-end fashion show, cinematic lighting, highly detailed

Пятый этап — конфигурация, установка и обучение: ЯЧЕЙКА 14. Конфигурация accelerateimport locale
locale.getpreferredencoding = lambda: «UTF-8»! accelerate config defaultЯЧЕЙКА 15. Установка datasets! pip install datasets -qЯЧЕЙКА 16. Обучение! rm -rf /content/prada_dog_LoRA! accelerate launch /content/train_dreambooth_lora_sdxl.py <br> --pretrained_model_name_or_path="stabilityai/stable-diffusion-xl-base-1.0» <br> --pretrained_vae_model_name_or_path="madebyollin/sdxl-vae-fp16-fix» <br> --dataset_name="/content/prada_processed» <br> --caption_column="prompt» <br> --instance_prompt="a photo of sks spitz dog» <br> --output_dir="/content/prada_dog_LoRA» <br> --resolution=768 <br> --center_crop <br> --train_batch_size=1 <br> --gradient_accumulation_steps=4 <br> --gradient_checkpointing <br> --use_8bit_adam <br> --mixed_precision="fp16» <br> --learning_rate=1e-4 <br> --lr_scheduler="constant» <br> --lr_warmup_steps=0 <br> --snr_gamma=5.0 <br> --rank=8 <br> --max_train_steps=500 <br> --checkpointing_steps=500 <br> --seed=0

Исходный размер 1024x512

Итоговое изображение (10) Отсылка к фильму «Дьявол носит Прада», момент с голубым свитером «a photo of sks spitz dog wearing a tiny cerulean blue sweater, sitting in a bright fashion office, editorial photo, shallow depth of field

Шестой этап — проверка результатов обучения:ЯЧЕЙКА 17. Проверка результатов обученияimport os! ls -lh /content/prada_dog_LoRAf = «/content/prada_dog_LoRA/pytorch_lora_weights.safetensors»
print («Размер LoRA, МБ:», round (os.path.getsize (f) / 1024 / 1024, 1))
assert os.path.getsize (f) > 1_000_000, «Файл слишком маленький, обучение не отработало»ЯЧЕЙКА 18. Сохранение на Google Drivefrom google.colab import drive
drive.mount ('/content/drive')! cp -r /content/prada_dog_LoRA /content/drive/MyDrive/prada_dog_LoRA
print («Сохранено в Google Drive: MyDrive/prada_dog_LoRA»)ЯЧЕЙКА 19. Загрузка модели и LoRa для генерацииimport gc
import torch
from diffusers import DiffusionPipeline, AutoencoderKLgc.collect ()
torch.cuda.empty_cache ()vae = AutoencoderKL.from_pretrained («madebyollin/sdxl-vae-fp16-fix», torch_dtype=torch.float16)pipe = DiffusionPipeline.from_pretrained (
«stabilityai/stable-diffusion-xl-base-1.0»,
vae=vae,
torch_dtype=torch.float16,
variant="fp16»,
use_safetensors=True,
)# LoRA грузим из ПАПКИ с результатом обучения (не из checkpoint-500)
pipe.load_lora_weights («/content/prada_dog_LoRA»)# offload вместо pipe.to («cuda»), вместе их использовать нельзя
pipe.enable_model_cpu_offload ()
pipe.vae.enable_tiling ()print («Готово к генерации»)

Исходный размер 1024x512

Итоговое изображение (11) Закулисье, гримерка a photo of sks spitz dog backstage at a fashion week show, racks of clothes and makeup mirrors with lights, candid photo, warm tone

Звершающий этап — Генерация картинок:ЯЧЕЙКА 20. Генерация import gc
import torch
from diffusers import DiffusionPipeline, AutoencoderKLgc.collect ()
torch.cuda.empty_cache ()vae = AutoencoderKL.from_pretrained («madebyollin/sdxl-vae-fp16-fix», torch_dtype=torch.float16)pipe = DiffusionPipeline.from_pretrained (
«stabilityai/stable-diffusion-xl-base-1.0»,
vae=vae,
torch_dtype=torch.float16,
variant="fp16»,
use_safetensors=True,
)# LoRA грузим из ПАПКИ с результатом обучения (не из checkpoint-500)
pipe.load_lora_weights («/content/prada_dog_LoRA»)# offload вместо pipe.to («cuda»), вместе их использовать нельзя
pipe.enable_model_cpu_offload ()
pipe.vae.enable_tiling ()print («Готово к генерации»)ЯЧЕЙКА 21. Генерация по списку описаний
mport torch
# токен «sks spitz dog» использовался при обучении, он же должен быть в промпте
prompt = «a photo of sks spitz dog sitting in a luxury fashion office, editorial magazine photo, high-end fashion, cinematic lighting, highly detailed»
negative_prompt = «blurry, low quality, deformed, extra limbs»images = []
for seed in [1, 2, 3, 4]:
g = torch.Generator («cuda»).manual_seed (seed)
img = pipe (
prompt=prompt,
negative_prompt=negative_prompt,
num_inference_steps=30,
guidance_scale=7.5,
generator=g,
).images[0]
img.save (f"/content/result_{seed}.png»)
images.append (img)imageGrid (images, 2, 2, resize=512)

Мы используем файлы cookies для улучшения работы сайта НИУ ВШЭ и большего удобства его использования. Более подробную...
Показать больше