Generating Embeddings

1. Choosing Embedding Models

ModelDimStrength
OpenAI text-embedding-3-small1536Best cost/quality
OpenAI text-embedding-3-large3072Highest quality
Cohere embed-v31024Multilingual
Pinecone multilingual-e5-large1024Inference API, 100+ langs
SentenceTransformers MiniLM384Free, runs locally
Voyage voyage-31024Strong retrieval

2. Using Sentence Transformers

Example: Local Embeddings

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")
embeddings = model.encode(["hello world", "foo bar"]).tolist()

3. Normalizing Embeddings

Example: L2 Normalize

import numpy as np

arr = np.array(embeddings)
normed = arr / np.linalg.norm(arr, axis=1, keepdims=True)
normed_list = normed.tolist()
ReasonBenefit
Cosine ≡ dotproduct on unitFaster, equivalent
Stable scoringRemoves magnitude bias

4. Batch Processing Embeddings

Example: Batched OpenAI

from openai import OpenAI
client = OpenAI()

def embed_batch(texts, batch=100):
    out = []
    for i in range(0, len(texts), batch):
        chunk = texts[i:i+batch]
        r = client.embeddings.create(model="text-embedding-3-small", input=chunk)
        out += [d.embedding for d in r.data]
    return out

5. Caching Embeddings

Example: Hash-Keyed Cache

import hashlib, json, redis

r = redis.Redis()

def cached_embed(text, model="text-embedding-3-small"):
    key = f"emb:{model}:{hashlib.sha256(text.encode()).hexdigest()}"
    if (v := r.get(key)): return json.loads(v)
    e = embed_one(text)
    r.set(key, json.dumps(e), ex=86400 * 30)
    return e

6. Validating Embedding Quality

TestMethod
Sanity pairsSimilar texts should score > 0.7
MTEB benchmarkRun on representative set
Retrieval@KMeasure recall on labeled set

7. Reducing Embedding Dimensions

Example: Matryoshka Truncation

# OpenAI text-embedding-3 supports dimension truncation
r = client.embeddings.create(
    model="text-embedding-3-large",
    input="...",
    dimensions=512,  # truncate from 3072
)
MethodTradeoff
Matryoshka truncationNative support; small accuracy loss
PCANeed training data; larger loss
Quantization (int8)~4× storage savings

8. Implementing Custom Embeddings

Example: HuggingFace

from transformers import AutoTokenizer, AutoModel
import torch

tok = AutoTokenizer.from_pretrained("BAAI/bge-large-en-v1.5")
mdl = AutoModel.from_pretrained("BAAI/bge-large-en-v1.5").eval()

def embed(text):
    enc = tok(text, return_tensors="pt", truncation=True)
    with torch.no_grad():
        out = mdl(**enc)
    return out.last_hidden_state[:, 0].squeeze().tolist()

9. Handling Embedding Drift

ScenarioAction
Model version changeRe-embed all + reindex (cannot mix)
VersioningTag metadata embedding_model
A/B testUse separate namespaces per model

10. Optimizing Embedding Latency

TipEffect
Batch callsAmortize HTTP overhead
Co-locate with indexSame region/cloud
Cache by text hashSkip duplicate work
GPU for local models10–100× speedup

11. Managing Embedding Costs

LeverEffect
Smaller model3-small vs 3-large = ~6× cheaper
Truncate dimsStorage + query cost down
Cache repeated textAvoid re-embedding
Batch APIOpenAI batch API 50% off

12. Using Pinecone Inference API

Example: Built-in Embeddings

r = pc.inference.embed(
    model="multilingual-e5-large",
    inputs=["hello", "bonjour"],
    parameters={"input_type": "passage"},
)
vectors = [e["values"] for e in r.data]