Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/StarTrail-org/PixelRAG/llms.txt

Use this file to discover all available pages before exploring further.

PixelRAG converts source documents into a searchable vector index through four sequential stages — render, chunk, embed, and build-index — each of which can be run independently or orchestrated end-to-end by the pixelrag index command. Once the index is built, a separate pixelrag serve process loads it and handles search queries via a FastAPI HTTP server.

Pipeline at a glance

source → render (pixelshot) → chunk → embed → build-index → serve
Every stage writes its output to disk so that any stage can be restarted, parallelized, or run on a different machine without re-processing earlier work.

Stage 1 — Render (pixelshot / render_url)

The render stage converts source documents into tiled JPEG screenshots. It is exposed as the standalone pixelshot CLI command (available after pip install pixelrag) and as the render_url / render_urls Python API. How it works:
  • A headless Chromium CDP backend captures each URL as a full-page screenshot. The CDP backend auto-selects a turbo capture path when a capable Chrome binary is present.
  • PDF files are rendered via PyMuPDF (bundled) or pdf2image (poppler), selected automatically based on what is installed.
  • The output for each source is a directory named {output_dir}/{stem}.png.tiles/ containing:
    • tile_NNNN.jpg — JPEG tiles, each up to 8192px tall
    • tiles.json — a manifest recording the tile filenames, total page height, and viewport width
Default parameters:
ParameterDefaultDescription
tile_height8192 pxMaximum height of each output tile
viewport_width875 pxBrowser viewport width for URL rendering
quality85JPEG quality (1–100)
backendcdpRendering backend (cdp or playwright)
# Render a web page
pixelshot https://en.wikipedia.org/wiki/Python -o ./tiles

# Render a PDF (requires poppler: pip install 'pixelrag[pdf]')
pixelshot paper.pdf -o ./tiles --dpi 200

# Mix URLs and local files freely
pixelshot https://github.com/StarTrail-org/PixelRAG paper.pdf -o ./tiles
from pixelrag_render import render_url

tiles = render_url("https://en.wikipedia.org/wiki/Python", "./tiles")
On Linux (x64), a bundled turbo headless_shell binary is installed automatically. On Windows and macOS, pixelshot uses your system Chrome/Chromium (auto-detected from standard install locations). Set CHROME_PATH=/path/to/chrome if it is not found automatically.

Stage 2 — Chunk (pixelrag chunk)

The chunk stage splits each 8192px tile into smaller strips that the embedding model can process efficiently. How it works:
  • Each tile is cut into 1024px-tall horizontal strips (chunks). For tiles narrower than the viewport width, this produces a single column of strips. For wider sources (e.g. landscape PDFs), the grid is also split along the width at viewport_width intervals.
  • Each chunk is written as a chunk_XXXX_YY.png file alongside its tile, where XXXX is the tile index and YY is the chunk index within that tile.
  • A chunks.json manifest is written to each article directory, recording each chunk’s tile_index, chunk_index, x_offset, y_offset, width, and height.
  • MIN_CHUNK_HEIGHT = 28 px — strips shorter than one Qwen3-VL patch are merged into the previous chunk rather than being written as their own file. This avoids producing chunks that would cause processor errors downstream.
Why chunking matters: Embedding full 8192px tiles requires the model to process roughly 8× the visual tokens compared to 1024px chunks. Pre-chunking on disk reduces embedding throughput requirements by approximately 8×.
# Chunk a single shard directory
pixelrag chunk --shard-dir ./tiles

# Chunk all shards in parallel
pixelrag chunk --tiles-dir ./tiles --workers 96

Stage 3 — Embed (pixelrag embed)

The embed stage runs each chunk image through Qwen/Qwen3-VL-Embedding-2B to produce a float16 embedding vector for every chunk. How it works:
  • The model encodes each chunk image using last-token pooling followed by L2 normalization.
  • Multi-GPU support is available via --gpu-ids. Workers pull from a shared task queue so faster GPUs process more work automatically.
  • The output is a set of .npz shards, each containing:
ArraydtypeShapeDescription
embeddingsfloat16[N, D]Embedding vectors
article_idsint64[N]Source article identifier
tile_indicesint32[N]Which 8192px tile (0-based)
chunk_indicesint32[N]Which 1024px strip within the tile
y_offsetsint32[N]Y position of chunk top edge in page (px)
tile_heightsint32[N]Actual chunk height (last chunk may be <1024px)
page_heightsint32[N]Full page height in pixels
viewport_widthsint32[N]Page render width in pixels (capped at 875)
image_hashesS32[N]MD5 of source PNG (for deduplication and patching)
tile_pathsS512[N]Absolute path to the chunk PNG file
shard_idint32scalarShard number
# Single GPU
pixelrag embed --shard-dir ./tiles --output-dir ./embeddings --gpu-ids 0

# Multi-GPU (workers pull from shared queue dynamically)
pixelrag embed --shard-dir ./tiles --output-dir ./embeddings --gpu-ids 0,1,2,3

Stage 4 — Build Index (pixelrag build-index)

The build-index stage merges all shard .npz files into a single searchable vector index. How it works:
  • Merges all shard files into unified embedding and metadata arrays.
  • Deduplicates by (article_id, tile_index, chunk_index) tuple — duplicate vectors produced by incremental or parallel runs are dropped.
  • Builds the configured index backend:
    • FAISS IndexIVFFlat (default) — fast build, good recall. Configurable nlist and nprobe parameters.
    • Qdrant — supports quantization, disk-backed vectors, and payload filtering. Requires a running Qdrant server.
Output files (FAISS):
FileDescription
index.faissFAISS IndexIVFFlat binary
metadata.npzArticle IDs, tile/chunk indices, Y offsets, tile heights
summary.jsonIndex parameters (backend, nlist, nprobe, total vectors)
articles.jsonURL and title per article ID
# FAISS index (default)
pixelrag build-index --embeddings-dir ./embeddings --output-dir ./index

# Qdrant index
pixelrag build-index --embeddings-dir ./embeddings --output-dir ./index \
    --backend qdrant --qdrant-url http://localhost:6333 --collection pixelrag

Orchestrator (pixelrag index)

The pixelrag index build command runs all four stages automatically from a single pixelrag.yaml configuration file. It supports local files, web URLs, PDFs, and kiwix ZIM archives as source types.
source:
  type: local        # or: web, pdf, kiwix
  path: ./my_docs

embed:
  model: Qwen/Qwen3-VL-Embedding-2B
  device: auto       # cuda on Linux, mps on macOS, cpu as fallback

output: ./my_index
pixelrag index build
The orchestrator handles incremental builds (skipping already-rendered tiles), writes a tiles.json manifest for each document, and automatically adjusts FAISS nlist based on the total vector count.
Use pixelrag index build --force to clear the output directory and rebuild from scratch, or omit it to resume from where a previous run left off.

Serve (pixelrag serve)

The serve stage starts a FastAPI HTTP server that loads the built index and the Qwen3-VL model at startup, then handles incoming search requests. Endpoints:
EndpointMethodDescription
/searchPOSTBatch text/image/embedding search against the index
/statusGETIndex statistics (vector count, dimension, nprobe, model)
/healthGETLiveness check ({"status": "ok"})
/tile/{article_id}/{tile_index}/{chunk_index}GETServe a chunk image by coordinate
pixelrag serve --index-dir ./my_index --port 30001

curl -X POST http://localhost:30001/search \
  -H "Content-Type: application/json" \
  -d '{"queries": [{"text": "benchmark results table"}], "n_docs": 5}'
Set PIXELRAG_INDEX_MMAP=1 to memory-map the FAISS index file, which is essential for multi-100 GB indexes that exceed available RAM.

Installing only the stages you need

# CLI + render only (pixelshot on PATH)
pip install pixelrag

# Chunk + embed + build-index
pip install 'pixelrag[embed]'

# Full orchestrator (all stages)
pip install 'pixelrag[index]'

# Serve (FastAPI search API)
pip install 'pixelrag[serve]'

# Qdrant backend (add to embed or serve)
pip install 'pixelrag[serve,qdrant]'

Build docs developers (and LLMs) love