Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions course-multi-vector-search/module-0/installing-dependencies.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "9af5bc4b49d17ebc",
"metadata": {},
"source": [
"# Module 0: Installing Dependencies"
]
},
{
"cell_type": "markdown",
"id": "mli6s9xkllr",
"metadata": {},
"source": [
"We need `qdrant-client` for interacting with Qdrant and `fastembed` for generating vector embeddings locally."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "466eb04e8e447feb",
"metadata": {
"jupyter": {
"is_executing": true
}
},
"outputs": [],
"source": [
"!pip install -q \"qdrant-client>=1.16.2\" \"fastembed>=0.8.0\""
]
},
{
"cell_type": "markdown",
"id": "6u2wb574s8n",
"metadata": {},
"source": [
"Let's verify that both packages were installed correctly by importing them."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8e66867cd6ebf200",
"metadata": {},
"outputs": [],
"source": [
"from qdrant_client import QdrantClient\n",
"from fastembed import TextEmbedding\n",
"\n",
"print(\"All dependencies installed successfully!\")"
]
},
{
"cell_type": "markdown",
"id": "uvxeas5v8er",
"metadata": {},
"source": [
"Connect to your Qdrant instance. Replace the URL and API key with your own Qdrant Cloud credentials, or use a local instance."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1ea6882564a624f5",
"metadata": {},
"outputs": [],
"source": [
"# For Qdrant Cloud\n",
"client = QdrantClient(\n",
" url=\"https://your-cluster-url.cloud.qdrant.io\",\n",
" api_key=\"your-api-key\"\n",
")\n",
"\n",
"# For local Qdrant\n",
"# client = QdrantClient(url=\"http://localhost:6333\")\n",
"\n",
"print(f\"Connected to Qdrant: {client.get_collections()}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a9bdeae2-ae97-4110-92f4-531168f3b31c",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
214 changes: 214 additions & 0 deletions course-multi-vector-search/module-1/late-interaction-basics.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "3ebe879db87a4432",
"metadata": {},
"source": [
"# Module 1: Late Interaction Basics"
]
},
{
"cell_type": "markdown",
"id": "9b9p5pv2oh9",
"metadata": {},
"source": [
"Define a simple query and two documents to compare how different embedding approaches represent them."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "396986ed-a976-41a0-aad3-6de8f2406c5b",
"metadata": {},
"outputs": [],
"source": [
"documents = [\n",
" \"Qdrant is an AI-native vector database and a semantic search engine\",\n",
" \"Relational databases are not well-suited for search\",\n",
"]\n",
"query = \"What is Qdrant?\""
]
},
{
"cell_type": "markdown",
"id": "11591ce2-f88c-438d-9594-beb4d7cff0bb",
"metadata": {},
"source": [
"## Single-Vector Embeddings (No Interaction)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a54183c0-4a75-4981-a06c-3f1bc14b6b9b",
"metadata": {},
"outputs": [],
"source": [
"from fastembed import TextEmbedding\n",
"\n",
"# Load the BAAI/bge-small-en-v1.5 model\n",
"dense_model = TextEmbedding(\"BAAI/bge-small-en-v1.5\")\n",
"# Pass the documents through the model. The .passage_embed \n",
"# method returns a generator we can iterate over and is \n",
"# supposed to be used for the documents only.\n",
"dense_generator = dense_model.passage_embed(documents)\n",
"# Running next on the generator yields one vector at\n",
"# the time, representing a single document.\n",
"dense_vector = next(dense_generator)\n",
"dense_vector.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "21f340ad-8ba3-4572-84ee-6171cdf5aa38",
"metadata": {},
"outputs": [],
"source": [
"# Generate a dense vector for the query as well, using \n",
"# the .query_embed method this time.\n",
"dense_query_vector = next(dense_model.query_embed(query))\n",
"dense_query_vector.shape"
]
},
{
"cell_type": "markdown",
"id": "wxe4h2vwnue",
"metadata": {},
"source": [
"Compute dot product similarity between the query and each document. Higher scores indicate stronger semantic matches."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d7416f7b-c2d1-4642-b3b6-a5df3549a8b9",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"# Calculate the dot product between the query\n",
"# and the first document vector\n",
"np.dot(dense_query_vector, dense_vector)"
]
},
{
"cell_type": "markdown",
"id": "2zgkv6yd2r4",
"metadata": {},
"source": [
"Now compare the same query against the second document."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bada239c-dc12-47d5-8923-407452cb7731",
"metadata": {},
"outputs": [],
"source": [
"# Calculate the dot product between the same query\n",
"# and the second document vectors\n",
"np.dot(dense_query_vector, next(dense_generator))"
]
},
{
"cell_type": "markdown",
"id": "811caba5-69d2-45bc-9552-5aeac7adf37b",
"metadata": {},
"source": [
"## Cross-Encoders (Early Interaction)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e995ba5b-ebd4-49e1-b06f-69f0cdd9052f",
"metadata": {},
"outputs": [],
"source": [
"from fastembed.rerank.cross_encoder import TextCrossEncoder\n",
"\n",
"# Load the Xenova/ms-marco-MiniLM-L-6-v2 cross encoder model\n",
"cross_encoder = TextCrossEncoder(\"Xenova/ms-marco-MiniLM-L-6-v2\")\n",
"# Run .rerank method on the query and all the documents.\n",
"# It does not create any vector representations, but gives\n",
"# the score indicating the relevance of the document for\n",
"# the provided query.\n",
"score_generator = cross_encoder.rerank(query, documents)\n",
"list(score_generator)"
]
},
{
"cell_type": "markdown",
"id": "9c154200-a65c-4f47-bc97-e0d092d2623f",
"metadata": {},
"source": [
"## Late Interaction: The Core Paradigm\n",
"\n",
"### The ColBERT Approach"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "27c39129-3acb-4876-ba07-5cda22f00bcc",
"metadata": {},
"outputs": [],
"source": [
"from fastembed import LateInteractionTextEmbedding\n",
"\n",
"# Load the colbert-ir/colbertv2.0 model\n",
"colbert_model = LateInteractionTextEmbedding(\"colbert-ir/colbertv2.0\")\n",
"# Run .passage_embed on all the documents and create\n",
"# a generator of the multi-vector representations\n",
"colbert_generator = colbert_model.passage_embed(documents)\n",
"colbert_vector = next(colbert_generator)\n",
"colbert_vector.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6f88562d-deef-4ce5-a448-0c854742521c",
"metadata": {},
"outputs": [],
"source": [
"# Create multi-vector representation for the query\n",
"colbert_query_vector = next(colbert_model.query_embed(query))\n",
"colbert_query_vector.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a768b8df-75a0-4c66-a5d9-5c7be934af0a",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading