first commit

This commit is contained in:
Leonid Pershin
2026-08-21 02:42:48 +03:00
commit 167d07a733
46 changed files with 3334 additions and 0 deletions
+174
View File
@@ -0,0 +1,174 @@
# Модели
Два источника на data volume, они **складываются**, не заменяют друг друга:
1. **Civitai-seed** (ниже) — один раз на пустой диск, если есть API-токен и манифест.
2. **Папка `Models/` в корне gpu-rent** — на каждом `up` выгрузить на VM только то, что изменилось. `Wildcards/` и `CustomWorkflows/` — то же правило, см. [local-folders.md](local-folders.md).
Локальный SwarmUI на `7801` по-прежнему не зеркалируем. Только дерево `./Models` приложения.
## Локальная папка → сервер
Каталог: `<корень приложения>/Models/` (или `LOCAL_MODELS_DIR`). Раскладка как у SwarmUI: `Stable-Diffusion/`, `Lora/`, `VAE/`, … Описание: [`Models/README.md`](../Models/README.md). Веса в git не коммитятся.
Правило одно:
| Локально | На `up` |
| --- | --- |
| Папки нет, или только `.gitkeep` / README | **Ничего не выгружаем**, тихий лог |
| Появился файл весов (`.safetensors` / `.ckpt` / …) | Залить его **вместе с соседней метадатой** |
| Веса уже на VM с тем же SHA256 | Пропуск (нет «обновления») |
| Веса изменились | Залить веса заново и актуальную метадату |
Метадата — файлы рядом с тем же stem: `.json`, `.civitai.json`, `.swarm.json`, превью (`.preview.png` / `.png` / `.webp`), если лежат в той же папке. Веса без sidecar тоже можно залить (предупреждение в лог: «метадаты нет»). Метадату без весов **не** шлём отдельно.
С диска в облаке **ничего не удаляем**. Civitai-seed и то, чего нет в `./Models`, остаётся.
Технически: SHA256 локального файла vs тот же относительный путь под `/mnt/swarm_data/Models/`. SFTP/paramiko, resume `.partial`. Preflight свободного места. Если залили и SwarmUI уже жив — refresh списка моделей.
Повторный `up` при живой VM тоже смотрит папку (положил новую LoRA дома → следующий `up` её увезёт). Явно: `gpu-rent push-models` или `gpu-rent push` (все локальные деревья).
Пока идёт аплоад, idle-killer на паузе.
---
# Civitai: первый seed
Срабатывает **один раз**: пустой data-диск + первый инстанс. Повторный `up` к уже засеянному диску строки манифеста с совпавшим SHA256 пропускает.
## Две ветки
| Условие | Что происходит |
| --- | --- |
| В `.env` есть `CIVITAI_API_TOKEN` **и** в манифесте есть хотя бы одна запись | Скачать перечисленные модели с Civitai **на VM** (не через ноут). Рядом положить метаданные. **Не** качать дефолтный чекпоинт установщика SwarmUI |
| Токена нет, или манифест пуст/отсутствует | Обычный первый запуск SwarmUI: пусть ставит свою стандартную модель. В лог — почему Civitai-seed пропущен |
Токен без манифеста = предупреждение и ветка SwarmUI default, не «пустой диск без моделей».
ComfyUI в `dlbackend` качается всегда. Речь только о **модели весов** установщика SwarmUI, не о backend.
## Когда в жизненном цикле
Пока idle-killer ещё **не вооружён**:
1. Создать/примонтировать data volume, маркер FS.
2. Clone расширений из `extensions.yaml` ([extensions.md](extensions.md)).
3. Autocomplete word-list ([autocomplete.md](autocomplete.md)): скачать, если нет; иначе проверить GitHub sha.
4. Если ветка Civitai: залить на VM манифест (scp, не cloud-init — токен не должен светиться в Nova user_data).
5. Скачать файлы в `/mnt/swarm_data/Models/…`, проверить SHA256, записать sidecar.
6. Маркер `/mnt/swarm_data/.gpu-rent-models-seeded`.
7. **Push** из корневой `Models/` приложения (новые/изменённые, см. выше).
8. Первый старт SwarmUI (папки чекпоинтов уже не пустые → установщик не предлагает свой SD; Extensions и Autocompletions уже на месте).
9. Ждать backend Idle, затем вооружить idle-killer.
Качание нескольких GB легко длиннее льготы 45 минут. Поэтому killer не живёт, пока не закончился seed.
Позже тот же код: `gpu-rent seed-models` — докачать новые строки манифеста на уже живой диск (идемпотентно).
## Манифест
Пример в репозитории: [`models.example.yaml`](../models.example.yaml). Рабочая копия: `~/.gpu-rent/models.yaml` (или путь `MODELS_MANIFEST`).
Идентификатор — **Civitai model version id**, не имя файла и не «последняя версия модели» (она плывёт).
```yaml
# ~/.gpu-rent/models.yaml
checkpoint:
- version_id: 2514310
lora:
- version_id: 123456
vae:
- version_id: 789012
embedding:
- version_id: 111
controlnet:
- version_id: 222
upscaler:
- version_id: 333
```
Допустимо вместо `version_id` поле `url` страницы модели/версии — CLI вынимает id. Хосты `civitai.com`, `civitai.red`, `civitai.green` равнозначны (зелёный редиректит на `.com`). Несколько файлов у версии: берём `files[]` с `"primary": true`, иначе SafeTensor / fp16.
Типы манифеста → каталоги SwarmUI (`ModelRoot` = `Models`):
| Ключ yaml | Civitai `model.type` (ориентир) | Каталог на диске |
| --- | --- | --- |
| `checkpoint` | Checkpoint | `Models/Stable-Diffusion` |
| `lora` | LORA, LoCon, DoRA | `Models/Lora` |
| `vae` | VAE | `Models/VAE` |
| `embedding` | TextualInversion | `Models/Embeddings` |
| `controlnet` | Controlnet | `Models/controlnet` |
| `upscaler` | Upscaler | `Models/upscale_models` |
| `clip` | — | `Models/clip` |
Тип в yaml задаёт **куда класть**, даже если Civitai назвал иначе. Если API-тип совсем другой — предупреждение, кладём по yaml.
В git не коммитить рабочий манифест с личными чекпоинтами. В примере — вымышленные id.
## Civitai API (.com / .red)
С апреля 2026 у Civitai два входа в **одну** базу ([анонс](https://civitai.com/articles/28369/two-front-doors-civitaicom-civitaired-and-whats-next)):
| Домен | Что видно |
| --- | --- |
| `civitai.com` | SFW / PG (бывший green). NSFW-карточки с этого хоста часто **не находятся** (404) или без `files[]` |
| `civitai.red` | Полный каталог, включая NSFW |
| `civitai.green` | 301 на `.com` |
REST не раздвоился: те же `/api/v1/...` на обоих хостах, один аккаунт, один API-токен. Официальная дока по-прежнему пишет base `https://civitai.com/api/v1/`, но там же: ответы с «зелёного» домена и из части регионов **молча режутся до SFW**. Нам нужны **любые** `version_id` из манифеста → **дефолтный API-хост `civitai.red`**.
Клиент:
1. Доверять только `civitai.com`, `civitai.red` и их поддоменам. Токен на чужой хост (CDN после редиректа) **не** отправлять.
2. URL из yaml нормализовать: вытащить `modelVersionId` / `/models/{id}?modelVersionId=` с любого из трёх доменов.
3. Метаданные: `GET https://{CIVITAI_API_HOST}/api/v1/model-versions/{id}` с `Authorization: Bearer`.
4. Если 404, пустой `files[]` или нет `downloadUrl`**один** повтор на второй хост (`.red``.com`). Не крутить бесконечно.
5. Качать: `GET https://{хост_успешного_GET}/api/download/models/{id}` с Bearer, следовать редиректам на presigned S3. Имя — `Content-Disposition`. `downloadUrl` в JSON часто указывает на `.com` — для NSFW его переписать на хост, который отдал файлы.
6. Поле `nsfwLevel` / `model.nsfw` в sidecar сохранить как есть, фильтром не пользоваться.
Без токена скачивание часто 401 даже на публичные веса. `requireAuth: true` в mini-endpoint — токен обязателен.
После ответа version:
1. Primary file, `hashes.SHA256`, `sizeKB`.
2. Preflight места: сумма `sizeKB` × 1.2 < свободно на data volume.
3. Качать на VM. Прогресс в логах.
4. Сверить SHA256. Несовпадение — удалить файл, fail строки.
Рядом с весами:
| Файл | Содержимое |
| --- | --- |
| `{name}.safetensors` | веса |
| `{name}.civitai.json` | сырой JSON version (+ при желании `GET /models/{modelId}` для автора/тегов) |
| `{name}.swarm.json` | маппинг под SwarmUI: `name`, `title`, `description`, `trigger_phrase` из `trainedWords`, `author`, `license`, `tags` |
Превью-картинки в base64 не обязательны в v1 (раздувают json). SwarmUI подтянет превью сам, если умеет по civitai id.
Не класть API-токен в sidecar и не в Output.
## Пропуск дефолта SwarmUI
Когда seed успешен (есть хотя бы один checkpoint **или** пользователь явно согласен на «только LoRA»):
- первый старт SwarmUI — **после** появления файлов в `Models/`;
- на spike проверить: установщик не качает Z-Image / SDXL Base, если `Stable-Diffusion` не пуст;
- если всё же качает — выключить автозагрузку настройкой/LaunchArg (имя ключа зафиксировать на spike, не выдумывать сейчас).
Если в манифесте нет ни одного `checkpoint` — предупреждение «без базовой модели генерация может не стартовать», не жёсткий fail.
## Сбой
- 401 → «токен неверный или скачивание требует логина».
- 404 на обоих хостах → версии нет / снята / не published.
- Early access / 403 → строка fail, остальные можно продолжить; маркер seeded не ставить.
- Обрыв сети — resume по `.partial` + повтор SHA256.
## Конфиг
```env
CIVITAI_API_TOKEN=
CIVITAI_API_HOST=civitai.red # полный каталог; civitai.com = только SFW
MODELS_MANIFEST= # пусто = ~/.gpu-rent/models.yaml
LOCAL_MODELS_DIR= # пусто = <корень приложения>/Models
```