M3-ID (Multi-Modal Movie Identification) is a Python-based microservice project designed to build an information retrieval system capable of identifying movies from diverse, multi-modal user queries. Users can search for a movie using a line of dialogue (text), a memorable scene (image), or a piece of music (audio).
The system uses a state-of-the-art hybrid retrieval strategy, combining dense vector (semantic) search with sparse vector (keyword) search in a Qdrant vector database.
The primary goal of this project is to design, implement, and evaluate a robust, multi-modal information retrieval system. This project aims to demonstrate mastery of modern IR concepts, including:
Identifying a specific movie from a vague memory is a common user problem. Traditional search engines struggle with multi-modal queries (e.g., "What's that movie that looks like this [image] and has this sound in it [audio]?").
M3-ID bridges this gap. It's an end-to-end system that allows users to submit text, image, or audio "clues." These clues are converted into vector embeddings by a dedicated machine-learning service. A retrieval service then queries a vector database using a novel hybrid search, which combines the "vibe" (semantic meaning) of the clues with specific keywords (like transcribed dialogue or names) to provide highly accurate and robust results.
The system is designed as a containerized set of Python microservices, promoting scalability and separation of concerns.
+------------------------------------------------+
| USER (e.g., Postman) |
+------------------------------------------------+
|
| (1) REST API Request (JSON + Files)
v
+-----------------------------------------------------------------------------------+
| (Docker Network) |
| |
| +-------------------------+ (2) gRPC Request +---------------------+
| | API & Retrieval | ---------------------------> | Feature Extractor |
| | Service (FastAPI) | (Raw Data) | Service (gRPC) |
| | | <--------------------------- | (Holds all ML Models)|
| | - Public /search API | (3) gRPC Response +---------------------+
| | - gRPC Client | (Query Vectors) |
| | - Qdrant Client | | (Offline Ingestion)
| | - Orchestrates flow | |
| +-------------------------+ |
| | ^ v
| | | (5) Results +--------------------------------+
| | | | scripts/ingest.py |
| | (4) Hybrid Search Query | (Offline Script) |
| | | +--------------------------------+
| v |
| +-------------------------+
| | Vector Database |
| | (Qdrant) |
| | |
| | - Stores Dense Vectors |
| | - Stores Sparse Vectors |
| +-------------------------+
| |
+-----------------------------------------------------------------------------------+
POST /search request to the API Service (FastAPI), containing any combination of text, image files, or audio files.scripts/ingest.py) is run once.This project's core novelty is its hybrid retrieval.
We employ Late Fusion. Each modality (text, image, audio) is first processed by its own "expert" model to create an embedding. These embeddings are then combined (e.g., via simple concatenation) after extraction.
grpcio, grpcio-tools)qdrant-client)transformers (e.g., openai/clip-vit-base-patch32)transformers (e.g., MIT/ast-finetuned-audioset)openai-whisper (for transcribing dialogue)sentence-transformers (e.g., all-MiniLM-L6-v2)scikit-learn (for TfidfVectorizer) or a sparse model (e.g., SPLADE).FR1: Multi-modal Query Input
POST /search)..wav, .mp3)..png, .jpg).FR2: Feature Extraction
FR3: Data Ingestion
FR4: Retrieval
FeatureExtractor gRPC service must be stateless and horizontally scalable.docker-compose.yml for one-command setup.docker-compose.yml file that builds and launches the entire M3-ID system (API, Feature Extractor, Qdrant).evaluate.py script to run the test queries against the API and calculate mAP/R@K.REPORT.pdf (in IEEE format) detailing the system design, architecture, methodology, experiments, and results (including performance charts).PRESENTATION.pdf summarizing the project and its findings.Sprint Goal: Establish the foundational architecture. By the end of this week, the Qdrant database and the gRPC FeatureExtractor service will be operational and a debug dataset will be ingested.
As the System Admin, I want to provision the Qdrant database service.
qdrant/qdrant image to docker-compose.yml.docker-compose up and verify the container is running and the web UI is accessible.qdrant-client to create the "msr-vtt" collection.dense_fused (HNSW index) and sparse_text (inverted index). As the Developer, I want to implement the gRPC FeatureExtractor service.
feature_extractor/server.py file.grpcio-tools).docker-compose.yml. As the ML Engineer, I want to load all pre-trained models into the FeatureExtractor service.
transformers, sentence-transformers, openai-whisper, etc. to requirements.txt. As the Developer, I want to define the .proto contract for multi-modal feature extraction.
features.proto file.QueryRequest (with fields like text_query, image_bytes, audio_bytes).QueryResponse (with fields for the resulting dense and sparse vectors)..proto file and integrate it into the server.As the Data Engineer, I want to create an ingestion script that processes a 100-video debug subset and populates Qdrant.
scripts/ingest.py script.FeatureExtractor service.qdrant-client to upload the vectors and metadata to the database.Sprint Goal: Implement the user-facing API and orchestrate the full retrieval pipeline. By the end of this week, a user can send a multi-modal query to the API and receive a ranked list of results.
As the Developer, I want to create the FastAPI API service with a /search endpoint.
api/main.py FastAPI application.docker-compose.yml so it runs alongside the other services./docs page is accessible. As a User, I want the /search endpoint to accept text, image, and audio queries.
POST /search endpoint.Form data for text_query (FR1-text).UploadFile for image_query (FR1-image).UploadFile for audio_query (FR1-audio).As the System, I want the FastAPI service to orchestrate the query-to-vector pipeline.
/search endpoint, add the logic to:
a. Read raw data from the request.
b. Send the data to the FeatureExtractor service via gRPC.
c. Receive the dense and sparse query vectors back.As the System, I want to execute a hybrid (sparse + dense) search against Qdrant.
qdrant-client logic inside the FastAPI app.α=0.5 to start).As a User, I want to receive a ranked JSON list of movie results.
/search endpoint must return a 200 OK with a JSON list of ranked results.Sprint Goal: Scale the system to the full dataset, quantitatively evaluate its performance against baselines, and document all findings.
As the Data Engineer, I want to run the ingestion script on the full MSR-VTT dataset.
scripts/ingest.py script and monitor it until it successfully processes all 10,000 videos. As the Developer, I want to build an evaluate.py script to measure mAP and R@K.
scripts/evaluate.py script.POST /search API.mAP and R@K.As the Researcher, I want to run the evaluation harness for all baselines.
evaluate.py script in "sparse-only" mode and save the metrics.evaluate.py script in "dense-only" mode and save the metrics.evaluate.py script in the default "hybrid" mode and save the metrics. As the Researcher, I want to tune the hybrid search α (alpha) weight to find the optimal mAP.
α (alpha) weight in the API's search logic.evaluate.py script in a loop with different α values (e.g., 0.25, 0.5, 0.75).α value that produces the highest mAP.As the Author, I want to write the final technical report and presentation.
REPORT.pdf (e.g., in IEEE format), detailing the project architecture, methodology, and results.PRESENTATION.pdf summarizing the project.4 commits
Python
80.5%
JavaScript
7.6%
CSS
5.6%
Makefile
1.9%
Dockerfile
1.6%
Shell
1.4%
Batchfile
1.2%
M3-ID (Multi-Modal Movie Identification) is a Python-based microservice project designed to build an information retrieval system capable of identifying movies from diverse, multi-modal user queries. Users can search for a movie using a line of dialogue (text), a memorable scene (image), or a piece of music (audio).
The system uses a state-of-the-art hybrid retrieval strategy, combining dense vector (semantic) search with sparse vector (keyword) search in a Qdrant vector database.
The primary goal of this project is to design, implement, and evaluate a robust, multi-modal information retrieval system. This project aims to demonstrate mastery of modern IR concepts, including:
Identifying a specific movie from a vague memory is a common user problem. Traditional search engines struggle with multi-modal queries (e.g., "What's that movie that looks like this [image] and has this sound in it [audio]?").
M3-ID bridges this gap. It's an end-to-end system that allows users to submit text, image, or audio "clues." These clues are converted into vector embeddings by a dedicated machine-learning service. A retrieval service then queries a vector database using a novel hybrid search, which combines the "vibe" (semantic meaning) of the clues with specific keywords (like transcribed dialogue or names) to provide highly accurate and robust results.
The system is designed as a containerized set of Python microservices, promoting scalability and separation of concerns.
+------------------------------------------------+
| USER (e.g., Postman) |
+------------------------------------------------+
|
| (1) REST API Request (JSON + Files)
v
+-----------------------------------------------------------------------------------+
| (Docker Network) |
| |
| +-------------------------+ (2) gRPC Request +---------------------+
| | API & Retrieval | ---------------------------> | Feature Extractor |
| | Service (FastAPI) | (Raw Data) | Service (gRPC) |
| | | <--------------------------- | (Holds all ML Models)|
| | - Public /search API | (3) gRPC Response +---------------------+
| | - gRPC Client | (Query Vectors) |
| | - Qdrant Client | | (Offline Ingestion)
| | - Orchestrates flow | |
| +-------------------------+ |
| | ^ v
| | | (5) Results +--------------------------------+
| | | | scripts/ingest.py |
| | (4) Hybrid Search Query | (Offline Script) |
| | | +--------------------------------+
| v |
| +-------------------------+
| | Vector Database |
| | (Qdrant) |
| | |
| | - Stores Dense Vectors |
| | - Stores Sparse Vectors |
| +-------------------------+
| |
+-----------------------------------------------------------------------------------+
POST /search request to the API Service (FastAPI), containing any combination of text, image files, or audio files.scripts/ingest.py) is run once.This project's core novelty is its hybrid retrieval.
We employ Late Fusion. Each modality (text, image, audio) is first processed by its own "expert" model to create an embedding. These embeddings are then combined (e.g., via simple concatenation) after extraction.
grpcio, grpcio-tools)qdrant-client)transformers (e.g., openai/clip-vit-base-patch32)transformers (e.g., MIT/ast-finetuned-audioset)openai-whisper (for transcribing dialogue)sentence-transformers (e.g., all-MiniLM-L6-v2)scikit-learn (for TfidfVectorizer) or a sparse model (e.g., SPLADE).FR1: Multi-modal Query Input
POST /search)..wav, .mp3)..png, .jpg).FR2: Feature Extraction
FR3: Data Ingestion
FR4: Retrieval
FeatureExtractor gRPC service must be stateless and horizontally scalable.docker-compose.yml for one-command setup.docker-compose.yml file that builds and launches the entire M3-ID system (API, Feature Extractor, Qdrant).evaluate.py script to run the test queries against the API and calculate mAP/R@K.REPORT.pdf (in IEEE format) detailing the system design, architecture, methodology, experiments, and results (including performance charts).PRESENTATION.pdf summarizing the project and its findings.Sprint Goal: Establish the foundational architecture. By the end of this week, the Qdrant database and the gRPC FeatureExtractor service will be operational and a debug dataset will be ingested.
As the System Admin, I want to provision the Qdrant database service.
qdrant/qdrant image to docker-compose.yml.docker-compose up and verify the container is running and the web UI is accessible.qdrant-client to create the "msr-vtt" collection.dense_fused (HNSW index) and sparse_text (inverted index). As the Developer, I want to implement the gRPC FeatureExtractor service.
feature_extractor/server.py file.grpcio-tools).docker-compose.yml. As the ML Engineer, I want to load all pre-trained models into the FeatureExtractor service.
transformers, sentence-transformers, openai-whisper, etc. to requirements.txt. As the Developer, I want to define the .proto contract for multi-modal feature extraction.
features.proto file.QueryRequest (with fields like text_query, image_bytes, audio_bytes).QueryResponse (with fields for the resulting dense and sparse vectors)..proto file and integrate it into the server.As the Data Engineer, I want to create an ingestion script that processes a 100-video debug subset and populates Qdrant.
scripts/ingest.py script.FeatureExtractor service.qdrant-client to upload the vectors and metadata to the database.Sprint Goal: Implement the user-facing API and orchestrate the full retrieval pipeline. By the end of this week, a user can send a multi-modal query to the API and receive a ranked list of results.
As the Developer, I want to create the FastAPI API service with a /search endpoint.
api/main.py FastAPI application.docker-compose.yml so it runs alongside the other services./docs page is accessible. As a User, I want the /search endpoint to accept text, image, and audio queries.
POST /search endpoint.Form data for text_query (FR1-text).UploadFile for image_query (FR1-image).UploadFile for audio_query (FR1-audio).As the System, I want the FastAPI service to orchestrate the query-to-vector pipeline.
/search endpoint, add the logic to:
a. Read raw data from the request.
b. Send the data to the FeatureExtractor service via gRPC.
c. Receive the dense and sparse query vectors back.As the System, I want to execute a hybrid (sparse + dense) search against Qdrant.
qdrant-client logic inside the FastAPI app.α=0.5 to start).As a User, I want to receive a ranked JSON list of movie results.
/search endpoint must return a 200 OK with a JSON list of ranked results.Sprint Goal: Scale the system to the full dataset, quantitatively evaluate its performance against baselines, and document all findings.
As the Data Engineer, I want to run the ingestion script on the full MSR-VTT dataset.
scripts/ingest.py script and monitor it until it successfully processes all 10,000 videos. As the Developer, I want to build an evaluate.py script to measure mAP and R@K.
scripts/evaluate.py script.POST /search API.mAP and R@K.As the Researcher, I want to run the evaluation harness for all baselines.
evaluate.py script in "sparse-only" mode and save the metrics.evaluate.py script in "dense-only" mode and save the metrics.evaluate.py script in the default "hybrid" mode and save the metrics. As the Researcher, I want to tune the hybrid search α (alpha) weight to find the optimal mAP.
α (alpha) weight in the API's search logic.evaluate.py script in a loop with different α values (e.g., 0.25, 0.5, 0.75).α value that produces the highest mAP.As the Author, I want to write the final technical report and presentation.
REPORT.pdf (e.g., in IEEE format), detailing the project architecture, methodology, and results.PRESENTATION.pdf summarizing the project.4 commits
Python
80.5%
JavaScript
7.6%
CSS
5.6%
Makefile
1.9%
Dockerfile
1.6%
Shell
1.4%
Batchfile
1.2%