Skip to content

Architecture

The Duskfall Portal Crew edited this page Jun 12, 2026 · 1 revision

Architecture

System design overview for contributors and advanced users.


High-Level Architecture

Browser (Next.js Frontend) ──HTTP/WS──→ FastAPI Backend ──→ Service Layer ──→ Kohya SS (Training)
                                              │
                                              ├── HuggingFace Hub
                                              ├── Civitai API
                                              └── ComfyUI (Generation)

Backend — api/

FastAPI route handlers that accept HTTP requests from the frontend and delegate to the service layer.

File Purpose
api/main.py FastAPI app entry point, CORS, WebSocket setup
api/routes/dataset.py Dataset upload, browse, delete
api/routes/training.py Training config validation and execution
api/routes/models.py Model downloads (HuggingFace / Civitai)
api/routes/utilities.py LoRA resize, merge, HuggingFace upload
api/routes/config.py Configuration management
api/routes/files.py File operations and tree browsing
api/routes/settings.py Application settings persistence
api/routes/civitai.py Civitai API proxy
api/routes/debug.py Debug and diagnostic endpoints

Key detail: api/main.py sets asyncio.WindowsProactorEventLoopPolicy() on Windows — do not remove. Server bind to 0.0.0.0 (required for cloud deployment). Routes never call Kohya scripts directly.


Service Layer — services/

Business logic layer. Route handlers call services; services call the training backend. This is the core of the application.

services/
├── core/                    # Foundation
│   ├── exceptions.py        # Exception hierarchy
│   ├── validation.py        # Path validation (security)
│   └── log_parser.py        # Kohya/WD14 log parsing
├── models/                  # Pydantic schemas
│   ├── training.py          # TrainingConfig (~140 fields)
│   ├── tagging.py           # Tagging config
│   ├── dataset.py           # Dataset models
│   ├── caption.py           # Caption models
│   ├── lora.py              # LoRA utility models
│   ├── job.py               # Job tracking models
│   └── common.py            # Shared base models
├── jobs/                    # Job management
│   ├── job.py               # Job dataclass
│   ├── job_store.py         # In-memory storage (dict-based)
│   └── job_manager.py       # Subprocess monitoring
├── trainers/                # Training backends
│   ├── base.py              # BaseTrainer ABC
│   ├── kohya.py             # KohyaTrainer implementation
│   └── kohya_toml.py        # TOML config generation
├── training_service.py      # Training orchestration
├── tagging_service.py       # WD14 tagging
├── captioning_service.py    # BLIP/GIT captioning
├── dataset_service.py       # Dataset file operations
├── caption_service.py       # Caption file editing
├── lora_service.py          # LoRA utilities
├── websocket.py             # WebSocket handlers
└── __init__.py              # Service exports

~3200 lines across 24 files. All services are fully built.

Design Principles

  1. Small files — each <200 lines
  2. Pydantic first — data validation from the start
  3. Async by default — non-blocking subprocess execution via asyncio.create_subprocess_exec
  4. Job tracking built-in — all long operations return a job_id
  5. Strategy patternBaseTrainer ABC allows swapping training backends
  6. Never hardcode paths — use sys.executable and os.path.join()

Job System

Every long-running operation (training, tagging, captioning) creates a job:

  • In-memory store (dict-based, no database required)
  • Log buffer: last 1000 lines
  • Status updates: 500ms intervals via WebSocket
  • Progress: parsed from Kohya/WD14 tqdm output

Trainer Pattern

BaseTrainer (ABC)
  └── KohyaTrainer (current)
  └── MultiGPUKohyaTrainer (future)
  └── ROCmTrainer (future)

All trainers share the same interface. TOML generation is handled by kohya_toml.py which produces:

  • dataset.toml — dataset config (paths, resolution, batch size)
  • config.toml — training hyperparameters

Frontend — frontend/

Next.js 16 with React 19, TypeScript, and Tailwind CSS v4.

Tech Stack

  • Framework: Next.js 16.2.4 (App Router)
  • UI Components: shadcn/ui (Radix primitives)
  • API Integration: Centralized lib/api.ts with typed modules
  • State Management: React hooks + TanStack Query
  • Real-time: Native WebSocket API
  • Styling: Tailwind CSS v4 with CSS custom properties

Key Routes

Route Purpose
/ Homepage
/dataset Dataset uploader
/dataset/[name]/tags Tag editor with image gallery
/dataset/[name]/auto-tag Auto-tagging interface
/files File manager with tree view
/models Model downloader
/training Training configuration
/calculator LoRA step calculator
/utilities Post-training utilities
/settings Application settings

Component Architecture

frontend/
├── app/              # Next.js App Router pages
├── components/
│   ├── ui/          # shadcn/ui components
│   ├── blocks/      # Page sections (navbar, footer, hero)
│   ├── training/    # Training-specific components
│   └── effects/     # Visual effects library
├── lib/
│   └── api.ts       # Centralized API client
└── hooks/           # Custom React hooks

API Client Rules

  • All backend communication through lib/api.ts — never fetch the backend directly from components
  • Typed modules: datasetAPI, trainingAPI, fileAPI, modelsAPI, utilitiesAPI, captioningAPI
  • WebSocket connections: trainingAPI.connectLogs(), datasetAPI.connectTaggingLogs(), etc.
  • Environment variable: NEXT_PUBLIC_API_URL (default: http://localhost:8000/api)

Frontend Rules

  • Mandatory: Use shadcn/ui components — never raw HTML form elements
  • TypeScript everywhere — no .js files in frontend/
  • Use @/ path alias, not relative paths
  • Accessibility is mandatory — semantic HTML, keyboard navigation, ARIA attributes
  • 'use client' for components with hooks or browser APIs
  • Server components preferred when no client-side features needed

Training Backend — trainer/derrian_backend/

Vendored Kohya SS distribution (committed directly, not a git submodule):

Directory Purpose
sd_scripts/ Kohya SS training scripts
lycoris/ LyCORIS library (DoRA, LoHa, LoKr)
custom_scheduler/ Custom optimizers (CAME, Compass, LPFAdamW)

Do not modify vendored backend files unless explicitly instructed. Upstream bug fixes are documented in docs/upstream-bug-fixes-2026-05-05.md (20 bugs fixed across sd-scripts and LyCORIS).


Startup Scripts

Script Platform Purpose
install.bat / install.sh Windows / Linux Install dependencies
installer.py Both Python dependency installer
start_services_local.bat / .sh Both Start locally
start_services_vastai.sh VastAI Supervisor-managed startup
provision_runpod.sh RunPod Direct port binding startup
vastai_setup.sh VastAI One-time provisioning
restart.bat / restart.sh Both Quick restart (no rebuild)
fetch-restart.sh Linux Pull + rebuild + restart
diagnose.bat / diagnose.sh Both Diagnostic collection
clean_slate.py Both Remove build artifacts

Configuration System

Two TOML files auto-generated from web UI form inputs:

  • trainer/runtime_store/dataset.toml — dataset config
  • trainer/runtime_store/config.toml — hyperparameters

The kohya_toml.py service handles generation. The TOML files are consumed by KohyaTrainer which launches Kohya SS as a subprocess.

Data Flow

User fills form → Pydantic validates → kohya_toml.py generates TOML →
KohyaTrainer launches subprocess → Job manager monitors →
Logs stream via WebSocket → Frontend displays progress

Three-Layer Architecture

When adding or modifying features, maintain consistency across all three layers:

  1. Frontend (lib/api.ts + lib/validation.ts) — TypeScript types and Zod schemas
  2. API Route (api/routes/) — FastAPI endpoint with route-level Pydantic model
  3. Service Layer (services/) — Business logic with service-level Pydantic model

Field names, types, and defaults must match across all layers.


See Also

Clone this wiki locally