Files
Leonid PershinandCursor 07bb521b70 Add Assistent reference books and remove training dataset output.
Introduce books/ with civitai-krea2 and HF fictext builders, sha-diff seed to VM, and drop train.jsonl from the civitai scrape pipeline.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-23 22:56:07 +03:00

377 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLI и конфигурация
Имя команды: `gpu-rent`. Лаунчеры: `gpu-rent.bat` / `.\gpu-rent.ps1` / `./gpu-rent.sh` (создают `.venv` и вызывают `python -m gpu_rent`).
Без аргументов CLI показывает **help**. Поднять GPU с двойного клика: в `gpu-rent.vars``GPU_RENT_DEFAULT_ARGS=up --yes`.
---
## Типичные сценарии
### Первый раз
```text
gpu-rent doctor
gpu-rent up --yes
# … работа …
gpu-rent stop
```
Подготовка ключей: [setup.md](setup.md).
### Обычная сессия
```text
gpu-rent up --yes
# Ctrl+C / Ctrl+D → stop GPU (диски остаются)
gpu-rent tunnel --open
gpu-rent hold
gpu-rent stop
```
### Только облако (туннель позже)
```text
gpu-rent up --yes --no-tunnel
gpu-rent tunnel --open
```
### LLM рядом со SwarmUI
```text
gpu-rent setup # или
gpu-rent up --yes --ollama
```
Подробности: [llm.md](llm.md).
---
## Команды
| Команда | Поведение |
| --- | --- |
| `gpu-rent version` | Версия пакета (`0.2.0`) |
| `gpu-rent setup` | Wizard: манифесты (в т.ч. ollama-models), `LLM_RUNTIME` (нумерованное меню), пресет, опционально local-watchdog |
| `gpu-rent doctor` | Preflight **без** create. Exit ≠ 0 → сессию начинать нельзя |
| `gpu-rent flavors` | Скан `SCAN_POOLS` по сегментам a/b/c × `FLAVOR_PREFERENCE` × `FLAVOR_SIZE_PRESET`, список в текущем регионе |
| `gpu-rent dry-run` | План без mutating-вызовов |
| `gpu-rent up` | Без `--yes`: меню LLM (если runtime none) → пресет → **Selectel**: flavor # / data GB / preemptible → confirm → create → туннель. Цветной лог (ошибки/warn/ok) |
| `gpu-rent up --yes` | Без вопросов; flavor из `FLAVOR_PREFERENCE` / `DEFAULT_FLAVOR_ID` |
| `up --keep-on-fail` | Не гасить GPU при ошибке install (по умолчанию `UP_STOP_ON_FAIL=true``stop`) |
| `gpu-rent up -v` / `--verbose` | Полная таблица doctor на `up` (по умолчанию кратко) |
| `gpu-rent up --ollama` / `--llm ollama` | Ollama рядом со SwarmUI |
| `gpu-rent up --no-swarm` / `--llm-only` | Только Ollama (нужен `--ollama` / `LLM_RUNTIME=ollama`); без clone SwarmUI |
| `gpu-rent up --no-update` | Без `git pull` SwarmUI/extensions (только недостающие clone) |
| `gpu-rent up --update` | Форс `git pull` SwarmUI + extensions (перекрывает `UPDATE_GIT=false`) |
| `gpu-rent up --no-tunnel` | Только облако |
| `gpu-rent up --no-spot` | Не preemptible |
| `gpu-rent up --flavor ID --yes` | Явный flavor; без `--flavor` + `--yes` — первый доступный из `FLAVOR_PREFERENCE` |
| `gpu-rent tunnel` / `tunnel --open` | Повторный проброс; `--open` сразу браузер. **Ctrl+C / Ctrl+D** вызывают `stop` |
| `gpu-rent open` / `open --llm` | Браузер на SwarmUI / LLM-порт (туннель уже должен слушать) |
| `gpu-rent status` | State, Nova, диск, killer/hold, LLM, local-watchdog |
| `gpu-rent diag` | SwarmUI/Comfy diagnostics с VM (API + journal + paths) |
| `gpu-rent debug` | Локальный read-only Debug API (`:17821`) — для агента после `--no-tunnel` / без активного `up` |
| `gpu-rent hold` / `--minutes N` / `--until ISO` / `--clear` | Пауза idle-killer (нужны живая VM + SSH) |
| `gpu-rent stop` / `stop --no-pull` | Удалить compute (+ FIP), диски оставить; optional pull Output |
| `gpu-rent destroy --i-understand-data-loss` | `stop` + диски |
| `gpu-rent logs` / `logs -u UNIT` | journalctl на VM; `-u swarm\|ollama\|killer\|cloud-init` (алиас `ollama` → юнит `gpu-rent-ollama`) |
| `gpu-rent ssh` | Оболочка на VM |
| `gpu-rent seed-models` | Докачать новые строки Civitai-манифеста на живой диск |
| `gpu-rent seed-extensions` | Доклонировать/обновить git-репы; restart swarmui |
| `gpu-rent seed-personas` | Пуш `assistent-extensions/``Assistent/extensions/` (+ `_base`); также `seed-books` если есть `books/` |
| `gpu-rent seed-books` | Push изменённых `books/*/``Assistent/books/` (`--force` — все) |
| `gpu-rent push` / `push-models` | Локальные деревья → VM |
| `gpu-rent pull-output` | VM `Output/``./Output` |
| `gpu-rent capture` / `capture all` | Инвентарь VM → merge **ссылок** в `models.yaml` + `extensions.yaml` (веса не качать) |
| `gpu-rent capture models` / `--kind lora` | Только модели (фильтр по типу) |
| `gpu-rent capture wanted` | Очередь Assistent Cards → `models.yaml` |
| `gpu-rent capture extensions` | Только git Extensions / DLNodes |
| `gpu-rent capture --dry-run` | Отчёт без записи файлов |
| `gpu-rent resize-data --gb 400` | Data volume **только вверх** |
| `gpu-rent watchdog install` / `uninstall` / `status` / `tick` | Локальный safety-net (см. ниже) |
Второй `up` при живой VM: не создаёт второй GPU; autocomplete-check + push локальных папок; при `PULL_OUTPUT` — подтянуть Output. `--adopt` — подхватить тег без state.
Нет команды `generate`. Локальный SwarmUI целиком не зеркалируем — только папки приложения ([local-folders.md](local-folders.md)).
### Отдельный CLI: `civitai-dataset` (не Typer)
Лаунчеры `civitai-dataset.bat` / `.ps1` / `.sh``python -m gpu_rent.civitai_dataset`. По умолчанию `all`. Подробности и пути: [datasets/README.md](../datasets/README.md).
| Команда | Поведение |
| --- | --- |
| `discover` | Топ Krea2 checkpoints/LoRAs → `catalog/models.json` |
| `scrape` | Галереи (метаданные, **без** картинок); `--target`, `--per-version`, `--min-score` |
| `split` | `by_kind/` / `by_rating/` / `search.jsonl` + `books/civitai-krea2/` |
| `all` | discover + scrape + split |
Нужен `CIVITAI_API_TOKEN` (лучше `CIVITAI_API_HOST=civitai.red`). Книги: `books-dataset.bat` / `python -m gpu_rent.books download fictext --variant both` (pyarrow: `pip install 'gpu-rent[books]'`). На `up` / `seed-books` изменённые `books/*/``Assistent/books/`.
---
## `doctor`
Не создаёт сервер и не тратит GPU. Нужен до первого `up` и когда «вчера работало».
Проверки (все печатаются в отчёт):
1. Читается `.env`, обязательные `OS_*`
2. Keystone выдаёт токен
3. Квота GPU > 0 (иначе текст про поддержку Selectel)
4. В сегменте есть flavor из `FLAVOR_PREFERENCE` / `DEFAULT_FLAVOR_ID`
5. Volume type / место под data ~100 GB
6. SSH-ключ есть или будет создан в `.gpu-rent/`
7. Живой сервер с тегом `gpu-rent` (info) и boot snapshot `gpu-rent-boot-ok` (info)
8. Если есть `CIVITAI_API_TOKEN` — доступ к API-хосту; манифест парсится
9. `extensions.yaml` парсится, если есть; при `LLM_RUNTIME=ollama``ollama-models.yaml` + строка Assistent ext
10. Предупреждения по огромным локальным `Models/`
Exit 0 → можно `up`. Exit 1 → причина в таблице / кратком списке на `up`.
---
## `status` и `hold`
**status** — без туннеля. При SSH: ещё `df` диска и состояние killer; иначе только OpenStack + локальный state.
**hold** пишет на VM `/mnt/swarm_data/.gpu-rent-hold-until`. Killer не удаляет compute, пока `now < ts`. Без живой VM — ошибка (не «запомню на потом»). После unshelve hold на диске сохраняется.
---
## Debug API (localhost)
На `gpu-rent up` и `gpu-rent tunnel` CLI поднимает **read-only** HTTP sidecar на `127.0.0.1:17821` (`DEBUG_LOCAL_PORT`). Ссылка печатается сразу и на access card.
Агент: `GET /openapi.json``GET /snapshot` → точечные пути (`/progress`, `/events?since=`, `/checks`, `/logs`, `/diag`, `/gpu`, `/swarm`, `/ollama`, `/assistent`). Пока SSH нет — VM-эндпоинты отвечают `ssh_unavailable`; прогресс установщика всё равно виден в `/progress` и `/events`.
### Assistent (глубокая отладка)
| Путь | Зачем |
| --- | --- |
| `/assistent` | Сводка: extension + overlay + roles + memory + live API + hints + playbook |
| `/assistent/diagnose` | То же + journal по умолчанию + session store meta |
| `/assistent/extension` | DLL, Sqlite deps, Tab/Assets, git HEAD |
| `/assistent/overlay` | personas/packs на VM vs локальный `assistent-extensions/` |
| `/assistent/roles` | `ollama-roles.json``/api/tags` (`default_chat`) |
| `/assistent/memory` | `assistent.sqlite` + counts |
| `/assistent/api` | `AssistentListPersonas/Models/Memory/Chats` через туннель (или SSH) |
| `/assistent/api?chat_smoke=1` | + 1-token Ollama `/api/chat` (кратко грузит модель) |
| `/assistent/wanted` | **GET** — очередь wanted-моделей на data volume |
| `/assistent/logs` | journalctl swarmui: build/load/Sqlite |
| `/assistent?logs=1` | Сводка + journal |
| `/assistent/session` | **POST** — multi-turn debug chat (in-memory, TTL ~45m) |
| `/assistent/session/{id}/chat` | **POST** — ход + объект `trace` |
| `/assistent/session/{id}` | **GET** / **DELETE** — состояние / сброс |
| `/assistent/chat-eval` | One-shot: session + один chat + delete |
| `/assistent/analyze-reply` | **POST** `{message, reply}` — офлайн extract + `client.would_generate` (без VRAM) |
| `/assistent/client-event` | **POST** — beacon из вкладки Assistent (последний ход UI) |
| `/assistent/client-events` | **GET** `?since=` — кольцо beacon'ов |
Симптомы → куда смотреть: поле `playbook` в `/assistent`.
**Session / chat-eval** не входят в `/snapshot`. Могут грузить VRAM, писать sqlite chat, тратить биллинг GPU. `compactContext` / Exact merge в Assistent HTTP API **нет** — sidecar реконструирует best-effort (`trace.gaps`).
#### Agent playbook (curl)
```bash
BASE=http://127.0.0.1:17821
# Static+live health (no chat)
curl -sS "$BASE/assistent/diagnose" | jq '{ok,hints,playbook,session_store}'
# Multi-turn conversational diagnostics
SID=$(curl -sS -X POST "$BASE/assistent/session" \
-H 'Content-Type: application/json' \
-d '{"persona":"neutral","pack":"ordinary","context":{"krea_profile":"turbo","checkpoint":"krea-turbo"}}' \
| jq -r .debug_session_id)
curl -sS -X POST "$BASE/assistent/session/$SID/chat" \
-H 'Content-Type: application/json' \
-d '{"message":"какой checkpoint и какие steps/cfg должны быть"}' \
| jq '{ok,reply,trace:{timings_ms,patch,exact_merge,compact_context,system_layers,gaps}}'
curl -sS -X POST "$BASE/assistent/session/$SID/chat" \
-H 'Content-Type: application/json' \
-d '{"message":"сделай generate с этими params"}' \
| jq '{ok, trace:{patch,exact_merge}}'
curl -sS "$BASE/assistent/session/$SID" | jq .session
curl -sS -X DELETE "$BASE/assistent/session/$SID"
# One-shot convenience (session + one chat + delete)
curl -sS -X POST "$BASE/assistent/chat-eval" \
-H 'Content-Type: application/json' \
-d '{"message":"какие steps/cfg для turbo?","persona":"neutral","timeout":120}' \
| jq '{ok,reply,patch,client,trace}'
# Offline: paste a live UI reply (no GPU)
curl -sS -X POST "$BASE/assistent/analyze-reply" \
-H 'Content-Type: application/json' \
-d '{"persona":"neutral","message":"а ты знаешь какие то промпты с civitai","reply":"```json\n{\"prompt\":\"x\",\"generate\":true}\n```"}' \
| jq '{patch,client}'
```
Ответ chat: `ok`, `reply`, `trace` (`timings_ms`, `patch`, `exact_merge`, `compact_context`, `system_chars` / `system_layers`, `skills`, `hops`, `gaps`, `errors`/`warnings`/`hints`). Sqlite SaveChat fail — soft error, если текст ответа есть.
После `up --no-tunnel` процесс завершается и sidecar гаснет — держи отдельно:
```text
gpu-rent debug
```
Мутаций конфига/GPU нет (restart/hold/stop — как раньше через CLI). `chat_smoke` только пингует Ollama; session/chat-eval — полноценный AssistentChat (opt-in).
---
## Local watchdog (опционально)
Основной авто-stop — **idle-killer на VM** (ноут можно закрыть). Local watchdog — если хочешь гасить GPU при «убили окно / ребут» без `stop`.
1. `gpu-rent watchdog install` (раз на машине, из корня репо)
2. Пока крутится `up`/`tunnel`, пишется heartbeat `.gpu-rent/local-lease.json`
3. **Ctrl+C / Ctrl+D**`stop` (как `gpu-rent stop`)
4. Процесс умер / ребут → через `LOCAL_WATCHDOG_GRACE_MINUTES` (дефолт 10) → `stop`
5. `gpu-rent stop` чистит lease сам
Без `install` поведение прежнее. При `up --no-tunnel` lease не вооружается.
---
## Конфигурация
| Файл | Назначение |
| --- | --- |
| `.env` | Секреты и OpenStack (`OS_*`, токены). Не в git |
| `gpu-rent.vars` | Несекретные дефолты; читают лаунчеры и CLI. Пример: `gpu-rent.vars.example` |
| `models.yaml` / `extensions.yaml` / `ollama-models.yaml` | Манифесты (gitignore; из `*.example.yaml`) |
### Лаунчер (`gpu-rent.vars`)
```env
# Двойной клик / запуск без аргументов у .ps1/.bat/.sh:
GPU_RENT_DEFAULT_ARGS=up --yes
# Дописать ко всем вызовам:
# GPU_RENT_EXTRA_ARGS=--no-update
UPDATE_GIT=true
LLM_RUNTIME=none
# DATA_VOLUME_SIZE_GB=100
# DEFAULT_FLAVOR_ID=
# DEFAULT_SPOT=true
```
### Основные переменные (`.env` / vars)
```env
OS_AUTH_URL=https://cloud.api.selcloud.ru/identity/v3
OS_USER_DOMAIN_NAME=
OS_USERNAME=
OS_PASSWORD=
OS_PROJECT_ID=
OS_REGION_NAME=ru-7
GPU_RENT_AZ=ru-7a
SSH_PRIVATE_KEY_PATH=
SSH_USER=ubuntu
# Пусто = авто /32 твоего IP. Для spike/WARP иногда 0.0.0.0/0:
GPU_RENT_SSH_CIDR=
BOOT_VOLUME_ID=
DATA_VOLUME_ID=
DATA_VOLUME_SIZE_GB=100
BOOT_SNAPSHOT_NAME=gpu-rent-boot-ok
CIVITAI_API_TOKEN=
CIVITAI_API_HOST=civitai.red
# HF для download/capture (любой из двух):
# HF_TOKEN=
# HUGGING_FACE_HUB_TOKEN=
MODELS_MANIFEST=
LOCAL_MODELS_DIR=
LOCAL_WILDCARDS_DIR=
LOCAL_WORKFLOWS_DIR=
LOCAL_OUTPUT_DIR=
EXTENSIONS_MANIFEST=
GIT_TOKEN=
AUTOCOMPLETE_ENABLED=true
SWARMUI_LOCAL_PORT=17801
LLM_RUNTIME=none
OLLAMA_LOCAL_PORT=17811
DEBUG_LOCAL_PORT=17821
# ENABLE_SWARMUI=false / WORKLOAD=llm — только LLM (см. llm.md)
UPDATE_GIT=true
DEFAULT_FLAVOR_ID=
FLAVOR_PREFERENCE=4090-24,4090-48,a5000,a100-40
FLAVOR_FALLBACK=true
FLAVOR_SIZE_PRESET=cheap
SCAN_POOLS=ru-6,ru-7
DEFAULT_SPOT=true
KEEP_FLOATING_IP=false
IDLE_MINUTES=30
IDLE_GRACE_MINUTES=45
# LOCAL_WATCHDOG_GRACE_MINUTES=10
PULL_OUTPUT=false
NOTIFY_READY=true
# Баланс ₽ (X-Token панели, не OS_*). Нужен watchdog install:
# SELECTEL_API_TOKEN=
# BALANCE_NOTIFY_STEP_RUB=200
# BALANCE_NOTIFY_LOW_RUB=
```
Flavor uuid в git не хардкодить. `FLAVOR_FALLBACK=false` — только `DEFAULT_FLAVOR_ID` / `--flavor`.
Application credential для idle-killer CLI создаёт на `up` (узко: DELETE/GET **этого** server) и отзывает на `stop`. В `.env` ноутбука дублировать не нужно.
Пути локальных папок по умолчанию: `Models/`, `Wildcards/`, `CustomWorkflows/`, `Output/` в корне репо.
Полный шаблон: [`env.example`](../env.example).
---
## State
`<repo>/.gpu-rent/state.json` — ids, фаза, timestamps (окно preempt 24 ч). Без паролей. Lockfile рядом — два `up` не создадут два сервера.
---
## Ожидание готовности
Ориентир: **~20–40 мин** первый bootstrap, **~510 мин** unshelve.
Порядок готовности:
1. Nova `ACTIVE`
2. TCP 22 / SSH
3. First-install Comfy (InstallConfirmWS, если backend был empty) → backend **ready (`running`)** → toast (если `NOTIFY_READY`)
4. На VM: HTTP сервисов стека (SwarmUI `:7801` / Ollama `:11434`) — `verify_stack_on_vm`
5. На VM: **nvidia-smi / CUDA** (fail-fast) + **torch+cuda** в Comfy venv при SwarmUI (ждём) — `verify_gpu_env`
6. В логе: строка **`тайминг up:`** (SSH / bootstrap / Idle / verify / …)
7. Туннель + проверка **localhost** тех же сервисов → access-card (красная рамка, если killer failed) → **дайджест journal** поднятых юнитов (~20 строк, без cloud-init)
`gpu-rent logs --unit swarm|ollama|killer` — полный journalctl (и cloud-init при `--unit all` / по умолчанию).
`gpu-rent status` — killer/hold, последний стек/GPU-env, тайминг up.
Локальный порт UI: **17801** (на VM по-прежнему 7801 на loopback).
---
## Windows / notify
`NOTIFY_READY`: toast + системный звук, когда backend ready (`running`). Если toast недоступен — только звук и лог, без падения CLI.
### Баланс Selectel (шаг 200 ₽)
Нужны:
1. `SELECTEL_API_TOKEN` в `.env`**статический ключ панели** (`X-Token`), не OpenStack password ([баланс API](https://docs.selectel.ru/api/balance/)).
2. `gpu-rent watchdog install` — тот же локальный тикер, что и аварийный stop.
На `up` запоминается baseline баланса. Каждый tick watchdog: если с `up` ушло ещё ~200 ₽ (`BALANCE_NOTIFY_STEP_RUB`) — toast «Списано ~N ₽…». Пополнение сбрасывает baseline. Опционально `BALANCE_NOTIFY_LOW_RUB=300` — разовое «баланс низкий».