Текстова інверсія для стабільної дифузії
Textual Inversion навчає новий токен в текстовому просторі CLIP, який кодує конкретний суб'єкт або стиль. Найлегший метод персоналізації SD: файл embedding важить 50-100 KB, навчається за 30-60 хвилин, застосовується як просте слово.
Принцип роботи
Textual Inversion не змінює ваги моделі - він знаходить новий вектор у CLIP embedding space, який найкраще описує навчальні зображення. Токен <my-style> додається до словника і використовується як звичайне слово.
from diffusers import StableDiffusionPipeline
import torch
# Обучение через diffusers скрипт
# accelerate launch textual_inversion.py \
# --pretrained_model_name_or_path="runwayml/stable-diffusion-v1-5" \
# --train_data_dir="./ti_images" \
# --learnable_property="style" \ # style или object
# --placeholder_token="<mystyle>" \
# --initializer_token="painting" \
# --resolution=512 \
# --train_batch_size=1 \
# --max_train_steps=3000 \
# --learning_rate=5.0e-04 \
# --output_dir="./ti_output"
# Применение обученного embedding
pipe = StableDiffusionPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
torch_dtype=torch.float16
).to("cuda")
# Загружаем embedding
pipe.load_textual_inversion("./ti_output/learned_embeds.bin")
# Используем токен в промпте
image = pipe(
"a portrait in <mystyle> style, dramatic lighting",
num_inference_steps=50,
guidance_scale=7.5
).images[0]
Python навчання
from diffusers import StableDiffusionPipeline
from transformers import CLIPTextModel, CLIPTokenizer
import torch
from torch.optim import AdamW
from torch.utils.data import Dataset, DataLoader
from PIL import Image
import os
class TextualInversionDataset(Dataset):
def __init__(self, images_dir: str, tokenizer, placeholder_token: str, size: int = 512):
self.images = [os.path.join(images_dir, f) for f in os.listdir(images_dir)
if f.endswith((".jpg", ".png", ".webp"))]
self.tokenizer = tokenizer
self.placeholder_token = placeholder_token
self.size = size
def __len__(self):
return len(self.images)
def __getitem__(self, idx):
img = Image.open(self.images[idx]).convert("RGB").resize((self.size, self.size))
# Простые промпты с placeholder токеном
prompts = [
f"a photo of {self.placeholder_token}",
f"{self.placeholder_token} in the scene",
f"an image featuring {self.placeholder_token}"
]
import random
prompt = random.choice(prompts)
return {"image": img, "prompt": prompt}
Порівняння методів персоналізації
| Метод | Розмір файлу Час навчання Якість Сумісність |
|---|---|
| Textual Inversion | 50–100 КБ |
| LoRA | 10-150 MB |
| DreamBooth (full) | 4-7 GB |
| DreamBooth + LoRA | 50-150 MB |
Textual Inversion виграє за розміром та портативністю: embedding можна поділитися одним файлом в 100 KB. Для точної передачі облич або складних стилів - LoRA або DreamBooth LoRA краще. Терміни навчання одного embedding – 30-60 хвилин, інтеграція у pipeline – 1 год.







