Módulo 5: Distance Metrics Deep Dive

FAISS Introduction

Qué es FAISS

FAISS (Facebook AI Similarity Search): Biblioteca open-source de Facebook para búsqueda vectorial eficiente a gran escala.

Características:

  • ✅ Optimizado para GPU/CPU
  • ✅ Múltiples algoritmos (IVF, HNSW, PQ)
  • ✅ Producido por: Meta AI
  • ✅ Usado por: Pinecone, Milvus, etc.

Instalación

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

Ejemplo básico

import faiss
import numpy as np

# Preparar datos
d = 1536  # Dimensiones
n = 10000  # Cantidad de vectores
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 para >1M vectors
# - Use como baseline

2. IndexFlatIP (exact, dot product)

index = faiss.IndexFlatIP(d)
# - Inner Product (dot product)
# - Equivalente a cosine si 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 en 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

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

Resumen

  • FAISS: Gold standard para vector search
  • HNSW: Best algorithm (99% accuracy, 100x speed)
  • Production: Use FAISS or vector databases built on FAISS
  • Next: Módulo 6 cubre vector databases completos

Módulo 5 - Cápsula 07