Vision-LLM powered quality triage for AI-generated images — scores and auto-sorts text-to-image outputs against a structured rubric.
IQA is a self-hosted web app that uses a vision-enabled LLM (e.g. Qwen VL via LM Studio) to grade text-to-image generations on anatomy, composition, lighting, realism, prompt adherence, and technical quality. It runs a fast triage pass over a directory of images, does a targeted deep-dive on borderline cases, and auto-sorts passes and rejects into separate folders. Designed to plug into the HomeHub portal ecosystem (shared PostgreSQL, portal network, registered app tile), but runs standalone too.
- Docker and Docker Compose
- A running LM Studio instance serving a vision model (default:
qwen/qwen3-vl-8b) on an OpenAI-compatible endpoint - PostgreSQL — either the HomeHub
portal-infrastack, or your own instance (updateDATABASE_URLto match) - For local dev without Docker: Python 3.11+, uv, Node.js 20+, and pnpm (enable via
corepack enable)
# Clone the repository
git clone https://github.com/cochbild/image-quality.git
cd image-quality
# Configure environment
cp .env.example .env
# Edit .env — set POSTGRES_PASSWORD, LM_STUDIO_URL, image directories, and
# generate an IQA_API_KEY (required):
# python -c "import secrets; print(secrets.token_urlsafe(32))"
# Build and run
docker compose build
docker compose up -dThe frontend serves on http://localhost:5180 and the backend API on http://localhost:8100 by default. The backend rejects every request that is missing the matching X-API-Key header — nginx injects it for browser traffic, so the key never touches client-side JavaScript.
# Backend — IQA_API_KEY and DATABASE_URL must be in backend/.env or the
# shell environment; the server fails fast if either is missing.
cd backend
uv sync
uv run uvicorn app.main:app --port 8100 --reload
# Frontend (separate terminal) — export the same IQA_API_KEY so the
# Vite dev proxy can inject it on outbound /api calls.
cd frontend
export IQA_API_KEY=... # same value as the backend
pnpm install
pnpm dev- Hybrid triage — fast overall scoring pass, with conditional deep-dive only on borderline categories
- Six-category rubric — anatomy, composition, lighting, realism, prompt adherence, technical quality (per-category thresholds configurable)
- Auto-sorting — passes, rejects, and originals routed to separate directories by outcome
- Scan history — browse past scans and drill into per-image category scores with model reasoning
- LM Studio integration — OpenAI-compatible vision endpoint; model selection filtered to VLMs only
- HomeHub tile — self-registers with the HomeHub portal when
HOMEHUB_API_URLis set - React + MUI frontend — dashboard, scan runner with live progress, settings, image detail view
- Backend: FastAPI, SQLAlchemy 2.0, Pydantic v2, httpx, Pillow
- Frontend: React 18, TypeScript, Vite, MUI v7, Axios
- Database: PostgreSQL 15 (tables prefixed
iqa_) - Infra: Docker Compose, nginx (frontend serving)
backend/ FastAPI app — API routes, assessment engine, LM Studio client, rubric
frontend/ React + Vite UI — dashboard, scan view, settings, history, image detail
docs/ Design notes and implementation plan
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Please see SECURITY.md for the vulnerability reporting policy.
MIT — see LICENSE for details.
Dale Cochran — @cochbild