Módulo 3: Modelos de Embeddings Comparison
OpenAI Embeddings Models: Deep Dive Comparison
Descripción de la cápsula
OpenAI ofrece 2 modelos principales de embeddings en 2026: text-embedding-3-small y text-embedding-3-large. Aunque ambos funcionan bien, tienen diferencias críticas en performance, costo, dimensiones, y casos de uso óptimos.
En esta cápsula aprenderás las diferencias técnicas entre ambos modelos, cómo comparan en benchmarks (MTEB), cuándo usar cada uno según tu caso de uso, y cómo configurar dimensiones para optimizar storage/costo. También verás código para comparar ambos modelos empíricamente.
Al final, podrás elegir el modelo OpenAI correcto para tu proyecto.
Modelos disponibles (2026)
OpenAI Embeddings Models:
| Modelo | Dims default | Dims config | MTEB Score | Costo/1M tokens | Lanzamiento |
|---|---|---|---|---|---|
text-embedding-3-small | 1536 | 512-1536 | ~62 | $0.020 | 2024 |
text-embedding-3-large | 3072 | 256-3072 | ~64 | $0.130 | 2024 |
text-embedding-ada-002 (legacy) | 1536 | 1536 | ~61 | $0.100 | 2022 |
Recomendación: Usa 3-small o 3-large (ada-002 es legacy).
text-embedding-3-small
Características:
Modelo: text-embedding-3-small
Dimensiones: 1536 (default), configurable 512-1536
MTEB Score: ~62
Costo: $0.020 / 1M tokens
Max tokens: 8,191
Performance (MTEB):
Benchmark | Score | Rank
------------------|-------|------
Retrieval | 0.55 | Bueno
Classification | 0.68 | Muy bueno
Clustering | 0.47 | Bueno
Semantic Similarity| 0.82 | Excelente
Reranking | 0.60 | Bueno
MTEB Average: 0.62
Interpretación: Bueno para semantic search general, excelente para similarity tasks.
Cuándo usar 3-small:
✅ 1. Prototipado rápido
# Costo bajo = iteración rápida
# $0.02/1M tokens vs $0.13/1M tokens (6.5x más barato)
✅ 2. Presupuesto limitado
# Startup con $100/mes:
# 3-small: 5M tokens
# 3-large: 769K tokens
✅ 3. Semantic search no crítico
# FAQ search, documentation search
# No requiere máxima precisión
✅ 4. High volume (millones de queries)
# 10M queries/mes:
# 3-small: $200
# 3-large: $1,300
Código de uso:
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# Generar embedding con 3-small
response = client.embeddings.create(
model="text-embedding-3-small",
input="Python es un lenguaje de programación"
)
embedding = response.data[0].embedding
print(f"Modelo: text-embedding-3-small")
print(f"Dimensiones: {len(embedding)}")
print(f"Primeras 5 dims: {embedding[:5]}")
Output:
Modelo: text-embedding-3-small
Dimensiones: 1536
Primeras 5 dims: [0.0234, -0.0123, 0.0456, -0.0189, 0.0267]
text-embedding-3-large
Características:
Modelo: text-embedding-3-large
Dimensiones: 3072 (default), configurable 256-3072
MTEB Score: ~64
Costo: $0.130 / 1M tokens
Max tokens: 8,191
Performance (MTEB):
Benchmark | Score | Rank
------------------|-------|------
Retrieval | 0.60 | Excelente
Classification | 0.70 | Excelente
Clustering | 0.52 | Muy bueno
Semantic Similarity| 0.84 | Excelente
Reranking | 0.64 | Muy bueno
MTEB Average: 0.64
Mejora vs 3-small: +2 puntos MTEB (~3% mejor).
Cuándo usar 3-large:
✅ 1. RAG production-ready
# Contexto correcto es crítico
# +3% precision = queries mejores
✅ 2. Domain crítico (legal, medical)
# Errores son costosos
# Vale la pena pagar 6.5x más
✅ 3. Low-to-medium volume
# <1M queries/mes:
# Costo total manejable ($130/mes)
✅ 4. Benchmarking de otros modelos
# Usar 3-large como "gold standard"
# Comparar open-source vs este
Código de uso:
# Generar embedding con 3-large
response = client.embeddings.create(
model="text-embedding-3-large",
input="Python es un lenguaje de programación"
)
embedding = response.data[0].embedding
print(f"Modelo: text-embedding-3-large")
print(f"Dimensiones: {len(embedding)}")
Output:
Modelo: text-embedding-3-large
Dimensiones: 3072
Comparación directa: 3-small vs 3-large
Experimento empírico:
import numpy as np
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def cosine_similarity(vec_a, vec_b):
"""Cosine similarity"""
return np.dot(vec_a, vec_b) / (np.linalg.norm(vec_a) * np.linalg.norm(vec_b))
def compare_models(query, docs):
"""Comparar 3-small vs 3-large en retrieval"""
results = {}
for model in ["text-embedding-3-small", "text-embedding-3-large"]:
# Embed query
query_emb = client.embeddings.create(
model=model,
input=query
).data[0].embedding
# Embed docs
doc_embs = []
for doc in docs:
emb = client.embeddings.create(
model=model,
input=doc
).data[0].embedding
doc_embs.append(emb)
# Calculate similarities
sims = [cosine_similarity(query_emb, doc_emb) for doc_emb in doc_embs]
# Rank docs
ranked = sorted(zip(docs, sims), key=lambda x: x[1], reverse=True)
results[model] = ranked
return results
# Test
query = "¿Cómo instalar Python?"
docs = [
"Para instalar Python, descarga el instalador desde python.org",
"JavaScript es un lenguaje de programación web",
"Python requiere pip para instalar paquetes"
]
results = compare_models(query, docs)
print("Query:", query)
print("\n=== text-embedding-3-small ===")
for doc, sim in results["text-embedding-3-small"]:
print(f"{sim:.4f} | {doc[:50]}...")
print("\n=== text-embedding-3-large ===")
for doc, sim in results["text-embedding-3-large"]:
print(f"{sim:.4f} | {doc[:50]}...")
Output esperado:
Query: ¿Cómo instalar Python?
=== text-embedding-3-small ===
0.8234 | Para instalar Python, descarga el instalador d...
0.7123 | Python requiere pip para instalar paquetes...
0.5432 | JavaScript es un lenguaje de programación web...
=== text-embedding-3-large ===
0.8567 | Para instalar Python, descarga el instalador d... ← Mejor score
0.7421 | Python requiere pip para instalar paquetes...
0.5123 | JavaScript es un lenguaje de programación web...
Observación: 3-large diferencia mejor (mayor score para doc correcto, menor para irrelevante).
Dimensiones configurables
Por qué reducir dimensiones:
# Storage:
# 1M docs × 3072 dims × 4 bytes = 12 GB (3-large)
# 1M docs × 1536 dims × 4 bytes = 6 GB (3-small)
# 1M docs × 512 dims × 4 bytes = 2 GB (3-small reducido)
# Speedup:
# 512 dims → 3x más rápido en búsqueda vs 1536 dims
Código con dimensiones reducidas:
# text-embedding-3-small con 512 dims
response = client.embeddings.create(
model="text-embedding-3-small",
input="Python es popular",
dimensions=512 # Reducir de 1536 → 512
)
embedding = response.data[0].embedding
print(f"Dimensiones: {len(embedding)}") # 512
Trade-off: Precision vs Storage
# Benchmark interno de OpenAI (retrieval@10):
Modelo: text-embedding-3-small
- 1536 dims (default): 100% precision (baseline)
- 1024 dims: 98% precision
- 512 dims: 95% precision
- 256 dims: 90% precision
Recomendación: 512-1024 dims = sweet spot
Cost analysis detallado
Escenario 1: RAG system (100K queries/mes)
# Assumptions:
# - Query: 50 tokens promedio
# - Docs retrieved: 5 docs × 200 tokens = 1000 tokens
# - Total per query: 1050 tokens
tokens_per_month = 100_000 * 1050 # 105M tokens
# 3-small:
cost_small = (tokens_per_month / 1_000_000) * 0.020
print(f"3-small: ${cost_small:.2f}/mes") # $2.10/mes
# 3-large:
cost_large = (tokens_per_month / 1_000_000) * 0.130
print(f"3-large: ${cost_large:.2f}/mes") # $13.65/mes
# Diferencia: $11.55/mes (~6.5x)
Decisión: Si presupuesto <$50/mes → 3-small, si >$50/mes y RAG crítico → 3-large.
Escenario 2: E-commerce search (1M queries/mes)
# Assumptions:
# - Query: 30 tokens promedio
# - Productos: 100K (embed 1 vez)
# - Queries: 1M/mes
# Embedding inicial de productos (1 vez):
initial_tokens = 100_000 * 50 # 5M tokens
initial_cost_small = (initial_tokens / 1_000_000) * 0.020 # $0.10
initial_cost_large = (initial_tokens / 1_000_000) * 0.130 # $0.65
# Queries mensuales:
query_tokens = 1_000_000 * 30 # 30M tokens
query_cost_small = (query_tokens / 1_000_000) * 0.020 # $0.60/mes
query_cost_large = (query_tokens / 1_000_000) * 0.130 # $3.90/mes
# Total mensual (después de setup):
print(f"3-small: ${query_cost_small:.2f}/mes") # $0.60/mes
print(f"3-large: ${query_cost_large:.2f}/mes") # $3.90/mes
Decisión: Para e-commerce, 3-small probablemente suficiente (ahorro significativo).
Decision matrix
Cuándo elegir cada modelo:
Criterio | 3-small | 3-large
------------------------|---------|--------
Presupuesto <$100/mes | ✅ | ❌
RAG production-critical | ❌ | ✅
Prototipo/MVP | ✅ | ❌
Domain crítico (legal) | ❌ | ✅
High volume (>1M/mes) | ✅ | ❌
Máxima precisión | ❌ | ✅
Benchmarking en código
Comparación automática:
import time
def benchmark_model(model_name, texts):
"""Benchmark latencia y costo"""
start = time.time()
response = client.embeddings.create(
model=model_name,
input=texts
)
latency = time.time() - start
# Estimar costo (assumiendo 50 tokens/text)
tokens = len(texts) * 50
cost_per_1m = 0.020 if "small" in model_name else 0.130
cost = (tokens / 1_000_000) * cost_per_1m
return {
'model': model_name,
'latency_ms': latency * 1000,
'cost_usd': cost,
'texts_processed': len(texts)
}
# Test
texts = ["Python es popular"] * 100
result_small = benchmark_model("text-embedding-3-small", texts)
result_large = benchmark_model("text-embedding-3-large", texts)
print("=== Benchmark Results ===")
print(f"3-small: {result_small['latency_ms']:.0f}ms, ${result_small['cost_usd']:.6f}")
print(f"3-large: {result_large['latency_ms']:.0f}ms, ${result_large['cost_usd']:.6f}")
Output típico:
=== Benchmark Results ===
3-small: 324ms, $0.000100
3-large: 412ms, $0.000650
Observación: 3-large es ~25% más lento (más dims).
Resumen
Qué aprendiste:
- ✅ 2 modelos principales:
3-small(barato, bueno) y3-large(caro, excelente) - ✅ MTEB scores: 62 vs 64 (~3% mejora)
- ✅ Costos: $0.02 vs $0.13 (6.5x diferencia)
- ✅ Dimensiones: Configurables (reducir storage)
- ✅ Casos de uso: Prototipo vs producción
Conceptos clave:
3-small→ Prototipo, high volume, presupuesto limitado3-large→ RAG crítico, domain importante, low volume- Dimensiones reducidas → Ahorro de storage (~3x)
Recursos adicionales
- OpenAI Embeddings Guide - Oficial
- MTEB Leaderboard - Rankings
- OpenAI Pricing - Costos actualizados
- Embeddings Comparison - Docs
En la siguiente cápsula
Cápsula 03: Open-Source Embeddings Overview
Aprenderás:
- Sentence-BERT (SBERT)
- BGE Models (BAAI)
- Instructor Embeddings
- E5 Models
- Cómo usar HuggingFace Sentence-Transformers
De OpenAI API a open-source self-hosted.
Módulo 3 - Embeddings Deep Dive Guide OpenAI embeddings: eligiendo entre small y large