Local • Private • AI-powered

Your media library,
finally searchable.

Iris is a self-hosted AI tool that indexes, transcribes, describes, and semantically searches your images, videos, GIFs, and audio — all on your own machine.

Get started GitHub →

What Iris does

A single tool that replaces manual file browsing with AI-powered intelligence.

🔍

Semantic text search

Describe what you're looking for in natural language. CLIP embeddings find visual matches even without keyword overlap.

🖼️

Visual similarity search

Upload a reference image and find visually similar files across your entire library instantly.

🎧

Semantic audio search

Search audio files by describing the sound in text — "male voice speaking", "electronic music". CLAP embeddings bridge text and audio semantics.

📝

OCR

EasyOCR extracts text from images — memes, screenshots, documents — and makes it searchable.

🤖

AI captions

Florence-2-large describes scene content, objects, and context to enrich search signals.

🎤

Speech transcription

OpenAI Whisper transcribes audio and video files. Search spoken content the same way you search images.

🧠

Concept recognition

Teach Iris to recognize specific people, characters, or objects using a few reference images. It auto-tags your library.

🌐

Web enrichment

Reverse-image lookup via Google Lens, then an LLM distills character, source work, and tags from the results — applied after human review.

📍

Auto-metadata & album suggestions

Reads EXIF date, GPS, and source app from files at import and suggests collections to group them — handy for photo libraries.

📁

Collections & albums

Organize files into named albums. Assign during import or add later from search results.

🧹

Duplicate detection

Hash-exact, Chromaprint acoustic fingerprinting, and visual near-duplicate detection with centroid-based cluster filtering. Review and send duplicates to system trash safely.

🎬

Multi-frame video embeddings

Videos are indexed by averaging 6 CLIP embeddings across evenly-spaced frames. Trims, re-encodes, and resolution changes are detected reliably.

🚫

Deleted file registry

SHA-256 and perceptual hashes of trashed files are stored. Re-importing the same files is silently skipped — deleted content stays deleted.

⏳

Background indexing

Import thousands of files without blocking the UI. Search and browse while indexing runs in the background.

Supported formats

Drop in any of these and Iris handles the rest.

IMAGES
.png .jpg .jpeg .webp .gif .svg
VIDEO
.mp4 .webm .mkv .mov .avi .flv .ogg
AUDIO
.mp3 .ogg

Installation

One server holds your originals and runs the AI; the browser and the Android app connect to it. It ships as a Docker image, so the server needs Docker — not Python or CUDA.

Requirements

ComponentMinimumRecommended
OSLinux x86_64Linux x86_64
SoftwareDocker + Compose v2, git, curl—
RAM8 GB16 GB+
GPU—NVIDIA RTX 20+ (driver ≥ 580, NVIDIA Container Toolkit)
Disk (models)~10 GB+ a second disk for backups
1

Download and install the server

bash
git clone https://github.com/MiguelLopesDel/Iris.git
cd Iris
./scripts/server.sh install        # detects an NVIDIA GPU by itself
2

Create the administrator account

bash
Finish setup in the browser: http://127.0.0.1:8501/setup
Installation code: K7QM-4XPA

Open the /setup page, type the installation code the installer printed, and choose the administrator's username and password. Then create the other accounts in Sistema.

3

Reach it from your devices

bash
sudo tailscale serve --bg http://127.0.0.1:8501

Iris listens only on 127.0.0.1. Publish it with the private layer you prefer — Tailscale, ZeroTier, WireGuard or a reverse proxy with TLS — and use that address in the browser or the Android app.

Updates, backups and every option: server guide.

Concept recognition

Teach Iris to recognize any visual entity using a handful of reference images.

1

Open the Concepts tab and click "Create new concept"

Give it a name and category: Person, Character, Place, Object, Animal, or Other.

2

Upload 2–5 reference images

Clear, varied images of the subject give better results. Iris embeds them with CLIP.

3

Click "Find auto matches"

Iris scans the library and proposes candidates ranked by visual similarity to the centroid of your references.

4

Review and apply

Reject false positives, then click Apply. Confirmed matches are stored and excluded from future auto-match runs.

5

Search by name

Type the concept name in the search box. Iris uses the visual embedding of the concept — not text matching — to retrieve results.

Architecture

Fully local stack — no cloud APIs, no telemetry.

Indexing pipeline (core/indexer.py)
  → EasyOCR — text extraction from images
  → Florence-2-large — scene description & captions
  → OpenAI Whisper — speech transcription (audio/video)
  → CLIP ViT-L/14 — 768-dim visual & text embeddings (images + multi-frame video)
  → CLAP — 512-dim semantic audio embeddings (optional, GPU recommended)
  → Chromaprint — acoustic fingerprinting for exact audio deduplication (optional, fpcalc required)
  → SQLite — metadata, OCR text, embeddings, deleted registry (schema v4)
  → FAISS — IndexFlatIP for image embeddings + separate index for CLAP audio embeddings

Search engine (core/search_engine.py)
  → Hybrid ranking — visual CLIP + description embedding + lexical bonus
  → Audio semantic search — text query encoded with CLAP, searched against audio FAISS index
  → Concept search — concept name resolves to centroid embedding
  → Negative terms — "-word" filters results post-ranking

Duplicate detection (core/duplicates.py)
  → Exact hash — SHA-256 groups byte-identical files
  → Chromaprint — Hamming distance < 0.20 groups acoustically identical audio
  → FAISS cosine — visual near-duplicates above configurable threshold (default 0.985)
  → Centroid filter — removes outliers that joined clusters via transitive chains

UI (server.py + templates/ + static/ — FastAPI SPA)
  → Text & image search — gallery, grouped results, audio results section
  → REST API — FastAPI endpoints consumed by browser modules
  → Concept management — reference upload, auto-match, confirmed/rejected

Hybrid search weights

ParameterDefaultDescription
balance0.65Weight between visual CLIP score (1.0) and description/text score (0.0)
text_bonus1.0Multiplier applied when query terms match OCR/caption text lexically
lexical_weight0.0Weight of pure lexical (BM25-style) scoring

Override defaults by placing data/best_weights.json in the project root, or run python scripts/optimize.py to tune weights automatically.

CLI reference

Index a media folder
python -m core.indexer \
  --dir /path/to/media \
  --db data/library.db \
  --device cuda \
  --recursive \
  --batch-size 8
Index with CLAP audio embeddings (semantic audio search)
python -m core.indexer \
  --dir /path/to/media \
  --db data/library.db \
  --clap-model laion/larger_clap_music_and_speech
Skip AI models for fast initial index
python -m core.indexer \
  --dir /path/to/media \
  --db data/library.db \
  --caption-model none \
  --whisper-model none
Rebuild FAISS index only
python -m core.indexer --db data/library.db --rebuild-faiss-only
Find and review duplicates
python scripts/find_duplicates.py \
  --db data/library.db \
  --media-root media \
  --threshold 0.985

License

Iris is source-available under the Iris Non-Commercial Personal-Use License.
You may use it and create your own forks for personal, non-commercial use, as long as you credit the author.
Selling Iris or any fork is not permitted; the author retains ownership and may revoke the license at any time.