⤵️ Quick shortcut: Select the module you’re currently studying ⤵️
Courses Module 1 Module 2 Module 3 Module 4 Module 5 Module 6
⏲️ Duration: 30 minutes hands-on + 20 minutes self-paced practice.
Topics:
Introduction to FAISS and its capabilities.
Searching in vector space using similarity metrics (e.g., cosine similarity).
Efficient querying and updating of vector databases.
Here are some Udemy courses that cover FAISS, vector similarity search, and efficient querying in vector databases:
Below you will find some suggested materials on these topics, which we believe may help you complete the final activity in the lesson. Please note that using these resources is entirely optional, and you are welcome to explore any other sources or courses at your own discretion.
Here are some recommended courses to explore:
Master RAG: Ultimate Retrieval-Augmented Generation Course
Overview: This course provides hands-on experience in building Retrieval-Augmented Generation (RAG) systems, including implementing a basic RAG Q&A system using LLMs, LangChain, and the FAISS vector database.
Master Vector Databases
Overview: This course delves into vector databases, teaching how to harness the power of OpenAI embeddings and integrate state-of-the-art language models into applications, enhancing text-based data analysis.
Master Vector Databases
Overview: This course delves into vector databases, teaching how to harness the power of OpenAI embeddings and integrate state-of-the-art language models into applications, enhancing text-based data analysis.
Below you will find some suggested materials on these topics, which we believe may help you complete the final activity in the lesson. Please note that using these resources is entirely optional, and you are welcome to explore any other sources or courses at your own discretion.
Introduction (2 Minutes)
Opening Statement:
Welcome to Lesson 3 of Module 3! In this session, we’ll explore how to build and query a vector database using FAISS, an industry-standard tool for efficient similarity searches.
By the end of this lesson, you’ll understand how to store embeddings, perform similarity searches, and retrieve meaningful results.
Agenda:
What is FAISS, and why use it?
Key concepts: similarity metrics and vector databases.
Hands-on: Build a vector database and perform queries.
Part 1: What Is FAISS and Why Use It? (4 Minutes)
Definition:
FAISS (Facebook AI Similarity Search) is an open-source library designed for efficient similarity search and clustering of dense vectors.
Why Use FAISS?
Efficiency: Handles millions of embeddings with low latency.
Scalability: Optimized for large-scale datasets.
Flexibility: Supports different similarity metrics and indexing methods.
Use Cases:
Recommendation Systems: Retrieve items similar to a user’s preference.
Question Answering: Fetch contextually relevant documents for user queries.
Clustering: Group similar data points for analysis.
FAISS Workflow Overview:
Index Construction: Store embeddings in a vector database.
Querying: Find the closest vectors to a given input using similarity metrics.
Updates: Add or remove embeddings dynamically.
Part 2: Key Concepts (4 Minutes)
1. Similarity Metrics:
Metrics used to compare vectors in embedding space:
Cosine Similarity: Measures the angle between two vectors.
Euclidean Distance: Measures the straight-line distance between points.
Example:
High cosine similarity or low Euclidean distance indicates closer embeddings.
2. Index Types in FAISS:
Flat Index:
Stores all vectors and performs exhaustive search.
Best for small datasets.
Approximate Indexes (e.g., IVF, HNSW):
Partition data for faster searches.
Suitable for large-scale datasets.
3. Vector Normalization:
Ensures embeddings are on the same scale.
Example:
Normalize vectors for cosine similarity searches.
Code Example: Vector Normalization
python
Copy code
from sklearn.preprocessing import normalize
# Normalize embeddings
normalized_embeddings = normalize(embeddings, norm='l2')
Part 3: Hands-On: Building and Querying a Vector Database (10 Minutes)
Step 1: Install FAISS
bash
Copy code
pip install faiss-cpu
Step 2: Create a Vector Database
Code Example: Building a Flat Index
python
Copy code
import faiss
import numpy as np
# Load embeddings
embeddings = np.load("embeddings.npy")
# Create a flat index
dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
# Add embeddings to the index
index.add(embeddings)
print(f"Number of vectors in the index: {index.ntotal}")
Step 3: Perform Similarity Searches
Code Example: Querying the Index
python
Copy code
# Example query vector (normalized)
query_vector = embeddings[0].reshape(1, -1)
# Search for the top 5 most similar vectors
k = 5
distances, indices = index.search(query_vector, k)
print("Distances:", distances)
print("Indices:", indices)
Explanation:
distances: Measures how close each result is to the query.
indices: Returns the row numbers of the closest embeddings.
Step 4: Advanced: Use Approximate Index
python
Copy code
# Create an IVF index for larger datasets
nlist = 100 # Number of partitions
quantizer = faiss.IndexFlatL2(dimension)
index_ivf = faiss.IndexIVFFlat(quantizer, dimension, nlist)
# Train the index
index_ivf.train(embeddings)
index_ivf.add(embeddings)
# Perform a search
distances, indices = index_ivf.search(query_vector, k)
print("Distances:", distances)
print("Indices:", indices)
Step 5: Save and Load Index
Save the index for reuse:
python
Copy code
faiss.write_index(index, "vector_index.faiss")
Load the saved index:
python
Copy code
loaded_index = faiss.read_index("vector_index.faiss")
Conclusion and Key Takeaways (4 Minutes)
Recap:
FAISS is a powerful tool for storing and querying embeddings efficiently.
Flat indexes work well for small datasets, while approximate indexes scale for larger ones.
Similarity metrics like cosine similarity or Euclidean distance are key to retrieving meaningful results.
Next Steps:
Use the vector database to power applications like recommendation systems or retrieval-augmented generation.
Experiment with different index types and similarity metrics to optimize performance for your dataset.
NOTE: If you decide to use OpenAI, a payment account is required.
In this activity, you will:
Install and configure FAISS.
Build a vector database using the generated embeddings.
Perform similarity searches on the vector database to find the most relevant vectors.
FAISS is an open-source library for efficient similarity search and clustering of dense vectors.
Installation:
Install the FAISS CPU version (suitable for most systems):
bash
Copy code
pip install faiss-cpu
If you are using a GPU and have the necessary drivers installed, you can install the GPU version:
bash
Copy code
pip install faiss-gpu
Verify the installation:
python
Copy code
import faiss
print("FAISS version:", faiss.__version__)
Ensure you have your embeddings saved in a file (embeddings.csv).
Code Example:
python
Copy code
import numpy as np
# Load the saved embeddings
embeddings = np.load("embeddings.csv")
# Display shape of embeddings
print("Embeddings Shape:", embeddings.shape)
FAISS provides different index types. For this example, we will use a Flat Index for exact nearest neighbor searches.
Code Example:
python
Copy code
import faiss
# Get the dimensionality of the embeddings
dimension = embeddings.shape[1]
# Create a FlatL2 index
index = faiss.IndexFlatL2(dimension)
# Add embeddings to the index
index.add(embeddings)
# Verify the number of vectors in the index
print("Number of vectors in the index:", index.ntotal)
Explanation:
FlatL2 Index: Uses exact nearest neighbor search with Euclidean distance.
Search the vector database for the most similar vectors to a given query.
Code Example:
python
Copy code
# Select a query vector (e.g., the first embedding)
query_vector = embeddings[0].reshape(1, -1)
# Perform a similarity search for the top 5 nearest neighbors
k = 5
distances, indices = index.search(query_vector, k)
# Display the results
print("Distances:", distances)
print("Indices:", indices)
Explanation:
distances: The Euclidean distances to the nearest neighbors.
indices: The indices of the nearest neighbors in the original dataset.
For large datasets, you can use an IVF Index to partition the data for faster searches.
Code Example:
python
Copy code
# Create an IVF index
nlist = 100 # Number of partitions
quantizer = faiss.IndexFlatL2(dimension)
ivf_index = faiss.IndexIVFFlat(quantizer, dimension, nlist)
# Train the index with the embeddings
ivf_index.train(embeddings)
ivf_index.add(embeddings)
# Perform a similarity search
distances, indices = ivf_index.search(query_vector, k)
# Display the results
print("Distances:", distances)
print("Indices:", indices)
Advantages of IVF Index:
Faster searches for large datasets.
Trades off some accuracy for speed.
To avoid rebuilding the index every time, save it to a file.
Code Example:
python
Copy code
# Save the index
faiss.write_index(index, "vector_index.faiss")
# Reload the index
loaded_index = faiss.read_index("vector_index.faiss")
# Verify the number of vectors in the reloaded index
print("Vectors in reloaded index:", loaded_index.ntotal)
Use the indices returned by the search to retrieve original data points.
Example for retrieving metadata:
python
Copy code
import pandas as pd
# Load the metadata
metadata = pd.read_csv("embeddings.csv")
# Display the closest neighbors
print("Closest Neighbors:")
for i in indices[0]:
print(metadata.iloc[i])
Configured FAISS:
Installed and ready for use.
Vector Database:
Embeddings are stored in a FAISS index, ready for efficient similarity searches.
Search Results:
Identified the most similar vectors to the query vector with distances and indices.
Write a Python script that:
Loads the cleaned dataset.
Generates embeddings using an API.
Saves the embeddings in a format suitable for vector database integration.
This activity will guide you through writing a Python script to:
Load the saved embeddings from a file.
Build a FAISS index for storing the embeddings.
Perform similarity queries to find the closest embeddings for a given input.
Ensure you have the embeddings.csv file saved from previous activities.
Code Example:
python
Copy code
import numpy as np
# Load the embeddings from the saved file
embeddings = np.loadtxt("embeddings.csv", delimiter=",")
# Display the shape of the embeddings to confirm successful loading
print("Loaded Embeddings Shape:", embeddings.shape)
Expected Output:
The shape of the embeddings, e.g., (number_of_vectors, embedding_dimension).
We will use the FlatL2 Index for exact nearest neighbor searches. For larger datasets, approximate indexes can be used (e.g., IVF).
Code Example:
python
Copy code
import faiss
# Determine the dimensionality of the embeddings
dimension = embeddings.shape[1]
# Create a FAISS FlatL2 index
index = faiss.IndexFlatL2(dimension)
# Add the embeddings to the index
index.add(embeddings)
# Verify the number of vectors in the index
print("Number of vectors in the FAISS index:", index.ntotal)
Explanation:
IndexFlatL2 is a basic index type in FAISS that performs exhaustive search using Euclidean distance.
To perform a similarity search, you need a query vector. Here, we’ll use one of the embeddings as a sample query.
Code Example:
python
Copy code
# Select a query vector (e.g., the first embedding)
query_vector = embeddings[0].reshape(1, -1)
# Number of closest neighbors to retrieve
k = 5
# Perform a similarity search
distances, indices = index.search(query_vector, k)
# Display the results
print("Distances to nearest neighbors:", distances)
print("Indices of nearest neighbors:", indices)
Explanation:
distances: The Euclidean distances between the query vector and its nearest neighbors.
indices: The indices of the closest embeddings in the dataset.
If you have metadata associated with your embeddings (e.g., employee names or roles), you can use the indices to retrieve this information.
Code Example:
python
Copy code
import pandas as pd
# Load the metadata file
metadata = pd.read_csv("metadata.csv")
# Display the closest neighbors using indices
print("Closest Neighbors:")
for idx in indices[0]:
print(metadata.iloc[idx])
Save the FAISS index for reuse without rebuilding it.
Code Example:
python
Copy code
# Save the FAISS index to a file
faiss.write_index(index, "faiss_index.bin")
# Reload the index from the file
loaded_index = faiss.read_index("faiss_index.bin")
# Verify the number of vectors in the reloaded index
print("Number of vectors in the reloaded FAISS index:", loaded_index.ntotal)
Here’s the complete Python script combining all the steps:
python
Copy code
import numpy as np
import faiss
import pandas as pd
# Step 1: Load embeddings
embeddings = np.load("embeddings.csv")
print("Loaded Embeddings Shape:", embeddings.shape)
# Step 2: Build a FAISS index
dimension = embeddings.shape[1]
index = faiss.IndexFlatL2(dimension)
index.add(embeddings)
print("Number of vectors in the FAISS index:", index.ntotal)
# Step 3: Perform similarity queries
query_vector = embeddings[0].reshape(1, -1) # Example query
k = 5 # Number of neighbors
distances, indices = index.search(query_vector, k)
print("Distances to nearest neighbors:", distances)
print("Indices of nearest neighbors:", indices)
# Step 4: Retrieve metadata
metadata = pd.read_csv("metadata.csv")
print("Closest Neighbors:")
for idx in indices[0]:
print(metadata.iloc[idx])
# Step 5: Save and reload the FAISS index
faiss.write_index(index, "faiss_index.bin")
loaded_index = faiss.read_index("faiss_index.bin")
print("Number of vectors in the reloaded FAISS index:", loaded_index.ntotal)
FAISS Index:
A fully built FAISS index containing your embeddings.
Ability to save and reload the index for future use.
Query Results:
List of nearest neighbors for a given query vector, along with their distances.
Metadata retrieved for the nearest neighbors.