Chapter 17: Multimodal Embeddings & Distributed Vector RAG
- Topic Focus • Ray Data for GenAI, Distributed Embedding Generation, Vector Search, and Multimodal RAG
- Interactive Challenges • 4 Hands-on Exercises
- Launch Playground in Wasm →
1. Architectural Overview & Control Plane Mechanics
Scaling Retrieval-Augmented Generation (RAG) to billions of documents requires distributed embedding extraction and parallel vector index partitioning. Using Ray Data, documents and multimodal media (images, audio, text) are processed in parallel across actor pools.
flowchart TD
Raw["Raw Multimodal Media<br/>(Text / Images / Audio)"] -->|"1. Streaming Dataset"| DS["Ray Data Pipeline"]
DS -->|"2. map_batches"| Pool["GPU Embedding Actor Pool<br/>(Vision / Text Encoders)"]
Pool -->|"3. Index Embeddings"| Shards["Sharded Vector Index<br/>(FAISS / HNSW Partitions)"]
Query["User Search Query"] -->|"4. Scatter-Gather Search"| Shards
Shards -->|"5. Heap Merge"| TopK["Global Top-K Context<br/>(To LLM Generator)"]
style Raw fill:#1e293b,stroke:#38bdf8,stroke-width:2px,color:#f8fafc
style DS fill:#0f172a,stroke:#818cf8,stroke-width:2px,color:#f8fafc
style Pool fill:#1e1e38,stroke:#f59e0b,stroke-width:2px,color:#f8fafc
style Shards fill:#0f172a,stroke:#34d399,stroke-width:2px,color:#f8fafc
style Query fill:#1e293b,stroke:#38bdf8,stroke-width:1px,color:#f8fafc
style TopK fill:#1e1e38,stroke:#c084fc,stroke-width:2px,color:#f8fafc
Diagram Walkthrough & Core Concepts: - Streaming Vector Embedding: Ray Data streams multimodal raw content directly through GPU worker actor pools, running vectorized embedding extractions with zero CPU stalls. - Distributed Vector Partitioning: Embeddings are partitioned and stored in memory across distributed FAISS or HNSW index shards. - Scatter-Gather Parallel Retrieval: Incoming user search queries are broadcast to all vector partitions in parallel, and local candidate results are aggregated through a heap merge reducer to produce the global top-K context.
2. Annotated Python Code Anatomy & API Reference
import ray
import numpy as np
# 1. Define stateful embedding model actor
class EmbeddingWorker:
def __init__(self):
# In real systems: from sentence_transformers import SentenceTransformer
self.dim = 384
def __call__(self, batch: dict) -> dict:
texts = batch["text"]
# Generate normalized dense embeddings
embeddings = np.random.randn(len(texts), self.dim).astype(np.float32)
embeddings /= np.linalg.norm(embeddings, axis=1, keepdims=True)
return {"text": texts, "embeddings": embeddings}
# 2. Stream dataset through embedding actor pool
ds = ray.data.from_items([{"text": f"Document chunk {i}"} for i in range(100)])
embedded_ds = ds.map_batches(
EmbeddingWorker,
compute=ray.data.ActorPoolStrategy(min_size=2, max_size=4),
batch_size=32
)
3. Production Best Practices & Hardening Guidelines
- Use
ActorPoolStrategyinmap_batches: Avoid reloading heavy embedding model weights per batch by maintaining persistent worker actors. - Normalize Vector Embeddings: Normalize embeddings (
L2norm = 1.0) so cosine similarity can be computed via high-speed dot products. - Partition Vector Indices by Shard: Shard large vector databases across nodes to parallelize top-K search queries.
- Tune Batch Sizes for Tensor Cores: Align embedding batch sizes to multiples of 8 or 16 (e.g. 32, 64, 128) to maximize GPU Tensor Core utilization.
- Stream Direct to Storage / Vector DBs: Write embedded chunks directly to cloud object stores or vector databases without staging on the driver.
4. Troubleshooting & Diagnostic Workflows
- Embedding Pipeline Memory Leaks:
- Symptom: Actor workers crash with OOM after processing thousands of batches.
- Fix: Call
torch.cuda.empty_cache()periodically inside the embedding actor's__call__method. - Slow Embedding Throughput:
- Symptom: Low GPU utilization during embedding generation.
- Fix: Increase
batch_sizeinmap_batchesand prefetch input data chunks. - Uneven Index Shards:
- Symptom: One vector search worker takes 10x longer than peers during query execution.
- Fix: Repartition datasets uniformly before embedding generation with
ds.repartition().
5. Hands-on Practice Exercises
| Exercise ID | Goal / Topic | Playground Link |
|---|---|---|
data_genai01 |
Streaming Multimodal Image & Audio ETL | Open Exercise data_genai01 → |
data_genai02 |
Accelerated Batch Embeddings with ActorPoolStrategy | Open Exercise data_genai02 → |
data_genai03 |
Dynamic Token Length Bucketing & Padding Optimization | Open Exercise data_genai03 → |
data_genai04 |
Streaming Parallel Ingestion into Vector Databases | Open Exercise data_genai04 → |