Как агентство перешло с Midjourney на свою LoRA и сократило расходы на графику в 4 раза
Как софтверное агентство обучило Stable Diffusion LoRA на брендовых иллюстрациях клиента, задеплоило API и сократило расходы на графику в 4× по сравнению с Midjourney.
Дисклеймер. Кейс выполнен агентством Nomadic Soft — разработчиком CloudCompute.ru. Конечный клиент агентства анонимизирован по условиям NDA. Все цифры — из реального проекта.
Контекст
Исполнитель: Nomadic Soft — софтверное агентство, специализирующееся на продуктовой разработке для SMB.
Клиент агентства: SaaS-продукт в сегменте B2B-маркетинга.
Задача клиента: 200+ иллюстраций в месяц в едином визуальном стиле для блога, email-рассылок и маркетинговых материалов.
Что использовали до этого: Midjourney Team Plan, ~$100/мес. Проблемы:
- Стиль нестабилен — каждое изображение требовало ручной проверки и нередко реджекта
- Ручная селекция занимала ~5 часов в неделю
- Нет API — невозможно интегрировать в CMS для автоматической генерации
- Проприетарная лицензия — ограничения на коммерческое использование неоднозначны
Требования
Клиент сформулировал четыре критерия:
- Консистентный стиль. Конкретные бренд-цвета, манера линий, характерная палитра — каждое изображение должно выглядеть частью одного набора.
- Коммерческая лицензия. Базовая модель с MIT/Apache лицензией — без юридических рисков при коммерческом использовании.
- API. REST-эндпоинт для интеграции в CMS клиента — автоматическая генерация обложек по заголовку статьи.
- Стоимость < $100/мес. Включая compute, storage и обслуживание — не дороже текущего Midjourney.
Решение: стек
После оценки требований агентство выбрало следующий стек:
| Компонент | Выбор | Почему |
|---|---|---|
| Базовая модель | SDXL | MIT-лицензия, зрелая экосистема, отличное качество при 1024×1024 |
| Тренировка | Kohya's GUI + LoRA rank 32 | Визуальный интерфейс, стабильные результаты, быстрый цикл итераций |
| Inference | ComfyUI API + FastAPI wrapper | Гибкие воркфлоу, поддержка LoRA hotswap, batch-обработка |
| Хостинг | CloudCompute.ru, RTX 4090 | 24 ГБ VRAM достаточно для SDXL + LoRA, оптимальная цена/производительность |
Процесс: по дням
День 1 — Подготовка датасета
- 80 референсных изображений от клиента: иллюстрации из текущих материалов, отобранные как эталон стиля
- Ручной caption через BLIP-2 + дочистка — каждое изображение получило текстовое описание с trigger-словом
[brandstyle] - Подготовка regularization images — 200 изображений из общего датасета SDXL в похожих тематиках, но без целевого стиля (предотвращает concept bleeding)
- Финальная структура:
dataset/
instance/
img_001.png
img_001.txt # "Иллюстрация [brandstyle], минималистичный офис, голубые тона, мягкие тени"
img_002.png
img_002.txt
...
regularization/
reg_001.png
reg_001.txt # "Иллюстрация, офисное пространство, нейтральные тона"
...
- Время: 6 часов работы дизайнера
День 2 — Тренировка
Запустили шаблон Kohya на CloudCompute.ru с RTX 4090.
Ключевые параметры:
[model]
pretrained_model = "stabilityai/stable-diffusion-xl-base-1.0"
vae = "madebyollin/sdxl-vae-fp16-fix"
[network]
network_module = "networks.lora"
network_dim = 32 # rank
network_alpha = 16 # alpha = rank/2
[training]
resolution = "1024,1024"
train_batch_size = 1
max_train_epochs = 10
learning_rate = 1e-4
lr_scheduler = "cosine"
optimizer_type = "AdamW8bit"
mixed_precision = "bf16"
[save]
save_every_n_epochs = 2
save_model_as = "safetensors"
[dataset]
train_data_dir = "/workspace/dataset/instance"
reg_data_dir = "/workspace/dataset/regularization"
- Одна итерация: ~3 часа GPU × ₽/час = ₽
- 4 итерации (эксперименты с learning rate и rank): ~12 часов GPU
- Общая стоимость тренировки: ₽
День 3 — Inference API
Задеплоили ComfyUI на CloudCompute.ru с загруженной LoRA:
- ComfyUI с workflow для batch-генерации: текстовый промпт → SDXL + LoRA → upscale → сохранение
- FastAPI wrapper — REST API поверх ComfyUI:
POST /generate— генерация изображения по промптуGET /status/{job_id}— статус задачиGET /result/{job_id}— скачивание результата
- Очередь через Redis — буферизация запросов, batch-обработка по 4 изображения
- Деплой на interruptible RTX 4090 — скидка ~50% по сравнению с on-demand
- Scale-to-zero — инстанс останавливается при отсутствии запросов, запускается автоматически при новых задачах
Результат в цифрах
| Метрика | До (Midjourney) | После (LoRA + CloudCompute) |
|---|---|---|
| Стоимость в месяц | $100 | ~$25 (compute) |
| Время ручной селекции | 5 ч/неделю | < 1 ч/неделю |
| Стилистическая консистентность | Нестабильная | Высокая (trigger word) |
| API-доступ | Нет | REST API |
| Лицензия | Проприетарная Midjourney | MIT (SDXL) |
| Скорость генерации | ~30 сек/изображение | ~8 сек/изображение (RTX 4090) |
Разовая инвестиция на обучение: ₽ (~12 часов GPU + 6 часов работы дизайнера + 4 часа работы ML-инженера).
Окупаемость: ~1.5 месяца. После этого — чистая экономия $75/мес по сравнению с Midjourney, плюс API и полный контроль над стилем.
Технические подробности
Inference API: ключевые эндпоинты
from fastapi import FastAPI, BackgroundTasks
from comfy_api import ComfyUIClient
app = FastAPI()
comfy = ComfyUIClient("http://localhost:8188")
@app.post("/generate")
async def generate(prompt: str, background_tasks: BackgroundTasks):
job_id = await comfy.queue_prompt(
workflow="brand_style_v1",
inputs={
"prompt": f"[brandstyle] {prompt}",
"negative_prompt": "blurry, low quality, watermark",
"steps": 30,
"cfg_scale": 7.0,
"width": 1024,
"height": 1024,
}
)
return {"job_id": job_id, "status": "queued"}
@app.get("/result/{job_id}")
async def result(job_id: str):
return await comfy.get_result(job_id)
Мониторинг
- nvidia-smi в фоне для отслеживания GPU utilization
- Метрики через Prometheus: GPU utilization, queue depth, generation latency
- Алерты при GPU utilization < 10% более 30 минут (сигнал к scale-down)
Обработка cold-start на interruptible
Interruptible-инстансы могут быть остановлены провайдером. Решение:
- Веса LoRA хранятся в persistent storage (~150 МБ)
- При запуске инстанса: автоматическая загрузка весов + прогрев одним тестовым запросом
- Время cold-start: ~90 секунд (загрузка SDXL + LoRA + один прогон)
Что не сработало с первого раза
Не все итерации были удачными. Вот что пришлось исправлять:
Overfitting на epoch 15+. Первый запуск шёл 20 epochs — модель запомнила тренировочные данные и перестала генерализовать. Откат на 10 epochs решил проблему. Визуально: изображения начинали повторять точные композиции из датасета.
Слишком низкий learning rate. LR 1e-5 дал блеклые, «размытые» цвета — модель недоучилась. LR 1e-4 дал яркую, консистентную палитру. Для SDXL LoRA оптимальный диапазон — 5e-5 ... 2e-4.
Rank 64 не дал прироста. Попробовали увеличить rank с 32 до 64 — качество не выросло, а размер весов удвоился (150 МБ → 300 МБ) и inference замедлился. Rank 32 — оптимум для задач стилизации.
Concept bleeding из-за regularization images. Первая итерация использовала regularization-изображения слишком похожие на целевой стиль. Модель не могла отличить «что учить» от «что игнорировать». Решение: regularization-изображения должны быть из той же тематики, но визуально непохожие на целевой стиль.
Когда этот подход не подходит
Не для каждого проекта LoRA — правильный ответ:
- Менее 50 референсных изображений. Результат нестабильный — модели не хватает данных для обобщения стиля. Минимум — 50, оптимум — 80–150.
- Более 500 разных стилей. Если у каждого клиента свой стиль, нужно обучать отдельную LoRA для каждого — или рассматривать full fine-tune.
- Фотореалистичные лица. Генерация лиц реальных людей несёт IP-риски и требует отдельного согласия. LoRA на иллюстрациях — безопасный сценарий.
- Гарантированный SLA. Interruptible-инстансы не подходят для mission-critical API. Используйте on-demand — но стоимость вырастет в ~2×.
Что использовано
Полный стек ссылок на материалы CloudCompute.ru:
- SDXL — генерация изображений
- LoRA — низкоранговые адаптеры
- ComfyUI — node-based интерфейс
- Шаблон Kohya's GUI
- RTX 4090 — цены и характеристики
Повторить у себя
Этот кейс воспроизводим. Вот что нужно:
- 80+ изображений в целевом стиле
- RTX 4090 на CloudCompute.ru (12 часов на эксперименты)
- Шаблон Kohya — запускается в один клик
Есть вопросы по вашему проекту? Напишите нам — поможем оценить стоимость и подобрать конфигурацию.