Module 5: Distance Metrics Deep Dive

FAISS Introduction

What FAISS is

FAISS (Facebook AI Similarity Search): an open-source library from Facebook for efficient large-scale vector search.

Features:

  • ✅ Optimized for GPU/CPU
  • ✅ Multiple algorithms (IVF, HNSW, PQ)
  • ✅ Built by: Meta AI
  • ✅ Used by: Pinecone, Milvus, etc.

Installation

pip install faiss-cpu  # CPU only
# Or
pip install faiss-gpu  # GPU support

Basic example

import faiss
import numpy as np

# Prepare data
d = 1536  # Dimensions
n = 10000  # Number of vectors
embeddings = np.random.randn(n, d).astype('float32')

# Index (flat = brute force)
index = faiss.IndexFlatL2(d)
index.add(embeddings)

# Search
query = np.random.randn(1, d).astype('float32')
k = 5

distances, indices = index.search(query, k)

print(f"Top-5 nearest: {indices[0]}")
print(f"Distances: {distances[0]}")

Index types

1. IndexFlatL2 (exact, Euclidean)

index = faiss.IndexFlatL2(d)
# - Exact search
# - Slow for >1M vectors
# - Use as a baseline

2. IndexFlatIP (exact, dot product)

index = faiss.IndexFlatIP(d)
# - Inner Product (dot product)
# - Equivalent to cosine if normalized

3. IndexIVFFlat (approximate)

nlist = 100  # Clusters
quantizer = faiss.IndexFlatL2(d)
index = faiss.IndexIVFFlat(quantizer, d, nlist)

# Train
index.train(embeddings)
index.add(embeddings)

# Search (faster)
index.nprobe = 10  # Search across 10 clusters
distances, indices = index.search(query, k)

4. IndexHNSWFlat (approximate, HNSW)

M = 32  # Connections per layer
index = faiss.IndexHNSWFlat(d, M)
index.add(embeddings)

# Search (fastest, best accuracy)
distances, indices = index.search(query, k)

Production pattern

import faiss
import numpy as np

class FAISSVectorStore:
    """Production FAISS wrapper"""
    
    def __init__(self, dim=1536):
        self.dim = dim
        self.index = faiss.IndexHNSWFlat(dim, 32)
        self.ids = []
    
    def add(self, embeddings, ids):
        """Add vectors"""
        embeddings = np.array(embeddings).astype('float32')
        self.index.add(embeddings)
        self.ids.extend(ids)
    
    def search(self, query, k=5):
        """Search top-K"""
        query = np.array([query]).astype('float32')
        distances, indices = self.index.search(query, k)
        
        results = []
        for i, idx in enumerate(indices[0]):
            results.append({
                'id': self.ids[idx],
                'distance': float(distances[0][i])
            })
        
        return results

# Usage
store = FAISSVectorStore(dim=1536)
store.add(embeddings, ids=['doc1', 'doc2', ...])
results = store.search(query_embedding, k=5)

Summary

  • FAISS: Gold standard for vector search
  • HNSW: Best algorithm (99% accuracy, 100x speed)
  • Production: Use FAISS or vector databases built on FAISS
  • Next: the Vector Databases guide covers full vector databases

Module 5 - Capsule 07