← Back to projects

MovieFinder

Semantic movie search: describe what you remember in natural language and find the exact title via embeddings, no exact text matching needed.

Catalogue
9,883 movies
Model
all-MiniLM-L6-v2
Inference
ONNX Runtime
Deployment
Docker · Render
  • FastAPI
  • ONNX Runtime
  • Python

Machine Learning · NLP · Embeddings · Dense Retrieval

Real API responses, recorded on 2026-10-16.

Try it yourself →

How it works

Three pieces: offline scripts that build the embeddings, a Docker API that only encodes the query and compares, and this Astro website, which calls the API and shows the results.

Swipe to see the full map →

Browser antoniocaballero.dev API · FastAPI Docker container on Render Offline preparation one-off in memory at startup same model Query text + filters GET /search Tokenizer ONNX Runtime all-MiniLM-L6-v2 Mean pooling + L2 norm Filters genre · years Cosine similarity Top-k JSON Results image.tmdb.org posters Catalogue 9,883 movies Title + overview per movie all-MiniLM-L6-v2 mean pooling + L2 embeddings.npy vectors
  1. 01

    The catalogue

    It all starts with a catalogue of 9,883 movies with title, release date, genres, overview and poster. For each one, the title + overview text is used.

  2. 02

    From text to vector

    That text goes through the all-MiniLM-L6-v2 model. With mean pooling and L2 normalisation, each movie becomes a vector that captures its meaning.

  3. 03

    Computed only once

    The vectors are stored in embeddings.npy. The API loads them into memory at startup, so they are never recomputed in production.

  4. 04

    A search comes in

    From the browser, the description and filters go to GET /search, a FastAPI service running in a Docker container on Render.

  5. 05

    The query becomes a vector too

    The description is tokenised and encoded with ONNX Runtime, using the same model, pooling and normalisation as the catalogue, so queries and movies live in the same space.

  6. 06

    Filters

    Before comparing, movies outside the selected genre or year range are dropped.

  7. 07

    The closest matches

    Cosine similarity is computed against the remaining movies and the top-k come back as JSON. The browser renders them and loads the posters from TMDB. In the first search above, Spider-Man (2002) wins with 0.752.

Limitations

  • It works best with descriptions in English.
  • The server is on Render’s free plan: after a period of inactivity, the first search can take around 30 seconds to respond.