Small program to view and edit datasets for lora training
Find a file
Reki 66a630a15b Add tag validation/normalization via tags.db (danbooru/e621)
Use the bundled tags.db SQLite dump (tag/alias/category/source tables) to
check captions against the chosen source and replace aliases with canonical
names.

Dataset config (dataset_config.json):
- new tag_source field: "auto" (default — derived from model_target: danbooru
  for Illustrious/NoobAI/Pony/Animagine/SDXL/SD1.5, none for Flux/Custom) or
  explicit "danbooru" / "e621" / "none".
- new tags_db_path field (empty = look next to the app).
- Both editable in the settings dialog (source dropdown + file picker).

tag_db.TagDb:
- Thread-safe read-only SQLite connection (query_only + lock).
- validate(): per-tag status — valid / alias (with canonical name) / missing /
  invalid (e621 category 6 = deprecated). Caches the category map at startup.
- canonicalize(): applies aliases, preserves order.
- find_tags_db(): explicit path → tags.db next to the app.

UI:
- detail view: "🔍 Проверить теги" opens TagCheckDialog with a per-tag report
  table, canonical names, categories, counts, and checkboxes (apply aliases,
  remove missing, remove deprecated, dedupe) with a live preview before save.
- gallery: "🔍 Нормализовать теги" runs the same normalization across the
  selection or the whole dataset with a progress dialog and dedupe.
- Tags are written back in the source file's existing format (txt/toml/jsonl)
  and the dataset cache is refreshed.

tags.db is gitignored (large binary).

Co-Authored-By: GLM-5.2 <noreply@z.ai>
2026-07-26 02:10:19 +03:00
app Add tag validation/normalization via tags.db (danbooru/e621) 2026-07-26 02:10:19 +03:00
.gitignore Add tag validation/normalization via tags.db (danbooru/e621) 2026-07-26 02:10:19 +03:00
main.py Add SD Dataset Viewer application 2026-07-24 00:38:20 +03:00
README.md Add tag validation/normalization via tags.db (danbooru/e621) 2026-07-26 02:10:19 +03:00
requirements.txt Add interactive crop/resize to square target 2026-07-25 17:33:19 +03:00

SD Dataset Viewer

Просмотрщик датасетов для обучения LoRA (Stable Diffusion и подобные). Позволяет одновременно видеть изображение и его подпись (caption), перемещаться по всему датасету с вложенными папками и сетевыми расположениями, а также редактировать теги с автодополнением и массовыми операциями.

Возможности

  • Два вида:
    • Галерея — дерево файловой системы слева (со списком дисков и миниатюрами изображений) и сетка миниатюр справа с фильтром по имени файла или тегам.
    • Просмотр — крупное изображение + редактор подписи + навигация вперёд/назад. Двойной клик по миниатюре открывает просмотр.
  • Режим сравнения эпох (Файл → Сравнение эпох…) — отдельный режим для сравнения версий одного сэмпла из разных эпох обучения LoRA. См. ниже.
  • Навигация по файловой системе:
    • корень дерева — список дисков (кнопка «Компьютер»);
    • кнопка «↑ Вверх» для подъема на уровень;
    • двойной клик по папке в дереве — раскрыть и просканировать как датасет;
    • кнопка «Обзор…» или ввод пути в строку + Enter — открыть датасет.
    • В дереве сортировка: директории сверху, затем файлы по алфавиту (без учёта регистра).
  • Форматы подписей (автоопределение по расширению рядом с изображением):
    • .txt — текст подписи целиком (теги через запятую).
    • .toml — поля caption и tags.
    • .json / .jsonl — объект с полями caption и tags.
  • Сетевые папки и UNC-пути (\\server\share\...) поддерживаются напрямую.
  • Вложенные папки сканируются рекурсивно.
  • Автодополнение тегов из частотного словаря текущего датасета — подсказки сортируются по популярности тега в датасете.
  • Массовые операции по выбранному диапазону или всему датасету:
    • добавить тег;
    • удалить тег;
    • заменить тег (с возможностью удаления, если новый пустой).
  • Фильтр кропов в галерее — выпадающий список «Все файлы / Только кропы / Без кропов» для показа или сокрытия обрезков ({name}_cropN). Комбинируется с текстовым фильтром по имени/тегам.
  • VLM-теггинг (🤖 VLM теги в просмотре) — пересоздание подписей через локальную VLM (LM Studio / llama.cpp, OpenAI-совместимый API). После кропа можно запустить теггинг для новых обрезок; результат показывается для проверки и правки перед сохранением. См. ниже.
  • Валидация и нормализация тегов по tags.db (danbooru/e621): проверка тегов на существование в выбранном источнике, замена алиасов каноническими именами, удаление ненайденных/deprecated. По одному файлу — 🔍 Проверить теги в просмотре; по всему датасету — 🔍 Нормализовать теги в галерее. См. ниже.

Настройки датасета и VLM-теггинг

Настройки хранятся в корне датасета в dataset_config.json (кнопка ⚙ Настройки в галерее или меню Файл → Настройки датасета…):

  • Целевая SD-модель (Illustrious-XL, NoobAI-XL, Pony, Animagine, SDXL, SD 1.5, Flux.1, Custom) — влияет на стиль тегов в промпте.
  • Инструкции — свободный текст пожеланий («danbooru tags, без рейтингов, английский» и т.п.).
  • VLM endpoint и модель — для LM Studio по умолчанию http://localhost:1234/v1. Кнопка «Проверить» стучится в /v1/models и подставляет первую доступную модель.
  • Temperature, Max tokens, флаг «передавать старые теги» модели для фильтрации/дополнения.

VLM-теггинг

  • В просмотре: 🤖 VLM теги — запрос для текущего изображения. После ответа модели открывается диалог со старыми и новыми тегами — можно отредактировать (есть кнопка «← Вернуть старые») и сохранить.
  • После кропа приложение предлагает запустить теггинг для всех новых обрезок по очереди.
  • В запросе участвуют: целевая модель, инструкции, опционально старые теги и само изображение (base64). Поддерживаются любые OpenAI-совместимые сервера с vision (LM Studio, llama.cpp server с --mmproj, Ollama с OpenAI-эндпоинтом и т.п.). Сетевых вызовов наружу не делается.

Валидация и нормализация тегов (tags.db)

Файл tags.db (SQLite, ~25 МБ) содержит дамп тегов и алиасов danbooru и e621: таблицы tag, alias, category, source. Положите его рядом с приложением или укажите путь в «Настройках датасета». Источник тегов выбирается там же: auto (по целевой модели — danbooru для Illustrious/NoobAI/Pony/Animagine/ SDXL/SD1.5, none для Flux/Custom), либо явно danbooru / e621 / none.

  • 🔍 Проверить теги (в просмотре) — для текущего изображения открывается отчёт: каждый тег помечается как ✓ валиден / → алиас / ✗ не найден / ⚠ deprecated (e621, категория invalid). Показан канонический вариант, категория и count. Опции (чекбоксы): применить алиасы, удалить ненайденные, удалить deprecated, убрать дубликаты. Превью результата — перед сохранением.
  • 🔍 Нормализовать теги (в галерее) — то же по выбранному диапазону или всему датасету, с прогресс-баром.

Все lookups идут через индексы SQLite (idx_tag_name, idx_alias_tag), 1000 файлов обрабатываются за пару секунд. Алиасы раскрываются в канонические имена (1girls1girl, high_reshighres и т.п.), что повышает стабильность обучения под конкретный тег-сортс.

  • Сохранение с подтверждением при переходе, горячая клавиша Ctrl+S.
  • Кроп/ресайз (✂ Кроп… в режиме просмотра) — интерактивная рамка поверх изображения: drag — двигать, колесо — размер. Цель — прямоугольник с двумя сторонами (по умолчанию 1536×1536), есть пресеты популярных размеров SDXL и кнопка для swap W/H. Aspect рамки всегда равен аспекту цели, поэтому при ресайзе нет искажений. Можно сделать несколько обрезок — каждая сохраняется как {name}_crop{N}.{ext} в ту же папку с переносом подписи из исходника (в тот же формат txt/toml/json/jsonl). После кропа галерея автоматически пересканируется.

Кроп/ресайз изображений

В режиме просмотра нажмите ✂ Кроп… (несохранённая подпись сначала сохраняется — она перенесётся в обрезки).

  • Поверх исходного изображения — прямоугольная рамка. Drag внутри рамки — двигает её, колесо мыши — масштаб (aspect сохраняется).
  • Цель задаётся двумя сторонами W × H вручную (spinbox'ы 648192) или пресетом из списка (1536×1536, 1024×1024, 1152×896, 896×1152, 1216×832, 832×1216, 1344×768, 768×1344, 1536×640, 640×1536, 512×512). Кнопка меняет W и H местами (портрет ↔ ландшафт).
  • Aspect рамки всегда = W : H, поэтому при ресайзе до цели нет искажений.
  • Справа — превью целевого прямоугольника.
  • «Сохранить обрезку» — создаёт файл {name}_crop{N}.{ext} в той же папке (номер N подбирается свободным) и копирует подпись исходника в тот же формат ({name}_crop{N}.txt / .toml / .jsonl). Можно сохранить ещё одну обрезку — счётчик покажет, сколько сохранено.
  • «Готово» закрывает диалог; галерея автоматически пересканируется.

Кроп и ресайз через Pillow (LANCZOS), расширение сохраняется как у исходника.

Режим сравнения эпох

Отдельный режим для выбора лучшей эпохи обучения LoRA. Откройте папку, в которой каждая подпапка — отдельная эпоха:

compare_root/
  mt_lora-000001/     ← Epoch 1
    scene_001.png
    scene_002.png
  mt_lora-000002/     ← Epoch 2
    scene_001.png     ← тот же промпт/сид, другая LoRA
    scene_002.png
  ...
  baseline/           ← папка без trailing-номера показывается как есть

Как пользоваться:

  • Сэмплы сопоставляются по одинаковому имени файла между эпохами.
  • Слева — список сэмплов (помечаются ★ при наличии голоса) и статистика по эпохам с прогресс-баром голосов.
  • В центре — сетка версий всех эпох для текущего сэмпла. Отметьте галочками лучшие версии (можно несколько за один сэмпл).
  • Двойной клик по версии — полноразмерный просмотр с зумом (Ctrl + колесо мыши), навигация между эпохами стрелками ← / →.
  • Навигация по сэмплам — кнопки или стрелки ← / →.
  • Голоса сохраняются в votes.json в корне сравнения (атомарно) и переживают перезапуск; файл можно коммитить в репозиторий или делиться.

Номер эпохи извлекается из trailing-цифр имени папки (mt_lora-000007 → 7); папки без номера сортируются после нумерованных.

Горячие клавиши (в режиме просмотра)

Клавиша Действие
/ / PageUp предыдущее изображение / сэмпл
/ / PageDown следующее изображение / сэмпл
Ctrl+S сохранить подпись
Ctrl+Enter сохранить и перейти к следующему
Esc вернуться в галерею
Ctrl + колесо мыши зум изображения

Стрелки листают только когда фокус не в поле редактирования подписи.

Установка

pip install -r requirements.txt

Требуется Python 3.10+. Для TOML на Python 3.10 пакет tomli ставится автоматически как зависимость PySide6; на Python 3.11+ используется встроенный tomllib.

Запуск

python main.py

Затем: Файл → Открыть папку… (или кнопка на панели галереи) и выбрать корень датасета.

Форматы файлов подписей

Для изображения image.png ищется первый существующий файл:

image.txt   → содержимое = подпись (теги через запятую)
image.toml  → caption = "...", tags = [...]
image.json  → {"caption": "...", "tags": [...]}
image.jsonl → одна строка: {"caption": "...", "tags": [...]}

При редактировании подпись сохраняется в тот же формат, в котором файл уже существовал. Если файла подписи не было, создаётся .txt.

Структура проекта

main.py                  — точка входа (+ настройка плагинов Qt)
app/
  caption_io.py          — чтение/запись txt/toml/jsonl
  dataset.py             — скан папок, кэш тегов, массовые операции
  dataset_config.py      — настройки датасета (dataset_config.json)
  thumbnail_loader.py    — ленивая загрузка миниатюр в фоновом потоке
  tag_completer.py       — поле редактора с автодополнением
  gallery_view.py        — дерево папок + сетка миниатюр
  image_label.py         — QLabel с зумом (общий для detail и сравнения)
  detail_view.py         — просмотр: изображение + редактор + навигация
  batch_ops_dialog.py    — диалог массовых операций
  crop_dialog.py         — диалог кропа/ресайза
  vlm_client.py          — клиент к локальной VLM (OpenAI-совместимый API)
  dataset_settings_dialog.py — диалог настроек датасета
  vlm_result_dialog.py   — проверка/правка тегов после VLM
  tag_db.py              — lookups/валидация/нормализация тегов по tags.db
  tag_check_dialog.py    — отчёт по тегам + опции нормализации (одиночный)
  tag_normalize_dialog.py — опции нормализации (массовая)
  compare_model.py       — модель режима сравнения эпох + votes.json
  compare_view.py        — UI режима сравнения + полноразмерный просмотр
  main_window.py         — главное окно, стек видов, меню
  thumb_filesystem_model.py — модель дерева с асинхронными миниатюрами