Módulo 1: Introducción a IA Multimodal
5. Landscape de Modelos
Descripción
El ecosistema multimodal tiene varios proveedores principales: OpenAI (GPT-4 Vision, Whisper, DALL-E, TTS), Anthropic (Claude 3), Google (Gemini). Cada uno tiene fortalezas, limitaciones y costos distintos. En esta cápsula aprenderás a compararlos con criterios concretos y elegir el adecuado para cada caso de uso. No existe "el mejor modelo" — existe "el mejor para tu caso".
Por qué importa: Elegir mal el modelo puede significar 10x más costo, peor calidad, o funcionalidades faltantes. Conocer el landscape te permite tomar decisiones informadas, diseñar fallbacks efectivos, y optimizar tu presupuesto en producción.
Conexión con el módulo: Las cápsulas 02-04 te mostraron capacidades de visión, audio y combinaciones. Aquí comparas los proveedores para saber cuándo usar cada uno. Esta información es fundamental para el Clasificador multimodal (cápsula 08), que debe recomendar el modelo óptimo.
Los 3 Grandes Proveedores
OpenAI
Ecosistema completo: GPT-4o (vision), Whisper (STT), DALL-E 3 (imagen), TTS (voz).
from openai import OpenAI
client = OpenAI() # Una sola librería para todo
Fortalezas:
- ✅ Ecosistema integrado (una API key para todo)
- ✅ GPT-4o excelente en vision y razonamiento
- ✅ Whisper líder en transcripción
- ✅ Documentación extensa, comunidad grande
- ✅
gpt-4o-miniofrece buen balance calidad/precio
Debilidades:
- ⚠️ Costos pueden acumularse rápidamente
- ⚠️ Rate limits estrictos en tiers gratuitos/bajos
- ⚠️ No ofrece speaker diarization en Whisper API
Anthropic
Especializado en razonamiento: Claude 3 (Sonnet, Opus, Haiku) con visión.
from anthropic import Anthropic
client = Anthropic() # Solo chat/vision
Fortalezas:
- ✅ Razonamiento profundo (especialmente Opus)
- ✅ Excelente en documentos complejos y análisis extenso
- ✅ Context window de 200K tokens
- ✅ Buenas instrucciones de seguimiento (instruction following)
- ✅ Menos "alucinaciones" en tareas de extracción
Debilidades:
- ⚠️ No tiene Whisper/TTS/DALL-E (solo vision + texto)
- ⚠️ Límite de imagen: 5MB (base64)
- ⚠️ Más caro que GPT-4o para vision
Google (Gemini)
Contexto masivo: Gemini 1.5 Pro (1M tokens), Flash (rápido y barato).
import google.generativeai as genai
genai.configure(api_key="...")
Fortalezas:
- ✅ Context window de 1M tokens (el más grande)
- ✅ Gemini Flash: muy rápido y muy barato
- ✅ Nativo multimodal (texto, imagen, audio, video en un solo modelo)
- ✅ Tier gratuito generoso
- ✅ Procesa video nativamente
Debilidades:
- ⚠️ Calidad de razonamiento un paso detrás de GPT-4o y Claude 3 Opus
- ⚠️ API menos madura que OpenAI
- ⚠️ Menor comunidad y ejemplos
Tablas Comparativas
Vision
| Criterio | GPT-4o (OpenAI) | GPT-4o-mini | Claude 3.5 Sonnet | Claude 3 Opus | Gemini 1.5 Pro | Gemini 1.5 Flash |
|---|---|---|---|---|---|---|
| OCR | Excelente | Bueno | Excelente | Excelente | Muy bueno | Bueno |
| Razonamiento | Muy alto | Alto | Muy alto | Máximo | Alto | Medio |
| Imágenes/req | Hasta 10 | Hasta 10 | Múltiples | Múltiples | Múltiples | Múltiples |
| Max tamaño | 20MB | 20MB | 5MB (b64) | 5MB (b64) | 20MB | 20MB |
| Context | 128K | 128K | 200K | 200K | 1M | 1M |
| Input cost | $2.50/1M | $0.15/1M | $3/1M | $15/1M | $1.25/1M | $0.075/1M |
| Output cost | $10/1M | $0.60/1M | $15/1M | $75/1M | $5/1M | $0.30/1M |
| Latencia | Media | Baja | Media | Alta | Media | Muy baja |
Audio (Speech-to-Text)
| Criterio | Whisper (OpenAI) | Google STT | AssemblyAI |
|---|---|---|---|
| Idiomas | 50+ | 100+ | 100+ |
| Costo | $0.006/min | Variable (~$0.006-0.024) | ~$0.015/min |
| Max archivo | 25 MB | Streaming sin límite | 5 hrs |
| Tiempo real | No | Sí | Sí |
| Speaker ID | No nativo | Sí | Sí |
| Precisión | Excelente | Excelente | Excelente |
| Modelo local | Sí (open-source) | No | No |
| API simplicity | Muy simple | Compleja | Media |
Text-to-Speech
| Criterio | OpenAI TTS | ElevenLabs | Google Cloud TTS |
|---|---|---|---|
| Voces | 6 predefinidas | 100+ + clonación | 200+ WaveNet |
| Naturalidad | Alta | Muy alta | Alta |
| Clonación | No | Sí | No |
| Costo | $15/1M chars | Desde $5/mo | Variable |
| Latencia | Baja | Media | Baja |
| Idiomas | Multiidioma auto | Multiidioma | 40+ |
Generación de Imágenes
| Criterio | DALL-E 3 (OpenAI) | Stable Diffusion (Replicate) | Midjourney |
|---|---|---|---|
| API | Sí (simple) | Sí (via Replicate/APIs) | No (solo web/Discord) |
| Calidad | Muy alta | Alta (configurable) | Muy alta |
| Costo | $0.04-0.08/img | ~$0.002-0.01/img | Suscripción |
| Control | Prompt | Prompt + params + ControlNet | Prompt |
| Velocidad | ~10-20s | ~5-15s | Variable |
| Edición | Variaciones | Inpainting/outpainting | Variaciones |
Árbol de Decisión: ¿Qué Modelo Usar?
Para Vision
¿Qué necesitas?
├── OCR de documentos simples
│ └── gpt-4o-mini (barato, bueno)
│
├── Análisis profundo de documentos complejos
│ └── Claude 3.5 Sonnet o GPT-4o (mejor razonamiento)
│
├── Volumen alto, costo bajo
│ └── Gemini 1.5 Flash (muy barato, rápido)
│
├── Context window enorme (docs largos)
│ └── Gemini 1.5 Pro (1M tokens)
│
├── Máxima calidad de razonamiento
│ └── Claude 3 Opus (caro pero superior)
│
└── Ecosistema integrado (vision + audio + imagen)
└── OpenAI (GPT-4o + Whisper + DALL-E + TTS)
Para Audio
¿Qué necesitas?
├── Transcripción simple de archivos
│ └── Whisper (simple, barato, excelente)
│
├── Transcripción en tiempo real (streaming)
│ └── Google STT o AssemblyAI
│
├── Speaker diarization (quién dijo qué)
│ └── AssemblyAI
│
├── TTS estándar (buena calidad)
│ └── OpenAI TTS
│
└── TTS premium o clonación de voz
└── ElevenLabs
Estrategias de Fallback
Fallback por disponibilidad
Si el proveedor principal falla (rate limit, timeout, error), usar alternativa.
from openai import OpenAI
from anthropic import Anthropic
import base64
import logging
logger = logging.getLogger(__name__)
openai_client = OpenAI()
anthropic_client = Anthropic()
def analyze_image_with_fallback(image_path: str, prompt: str) -> dict:
"""Intenta OpenAI → Anthropic → Error."""
with open(image_path, "rb") as f:
image_data = base64.b64encode(f.read()).decode()
# Intento 1: OpenAI
try:
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url", "image_url": {
"url": f"data:image/jpeg;base64,{image_data}"
}}
]
}],
max_tokens=500
)
return {
"provider": "openai",
"model": "gpt-4o",
"result": response.choices[0].message.content
}
except Exception as e:
logger.warning(f"OpenAI falló: {e}")
# Intento 2: Anthropic
try:
response = anthropic_client.messages.create(
model="claude-3-5-sonnet-latest",
max_tokens=500,
messages=[{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": image_data
}
},
{"type": "text", "text": prompt}
]
}]
)
return {
"provider": "anthropic",
"model": "claude-3-5-sonnet",
"result": response.content[0].text
}
except Exception as e:
logger.warning(f"Anthropic falló: {e}")
raise RuntimeError("Todos los proveedores de vision fallaron")
Tabla de prioridad de fallback
| Caso de uso | Primary | Fallback 1 | Fallback 2 |
|---|---|---|---|
| Vision general | gpt-4o-mini | Gemini Flash | gpt-4o |
| OCR de documentos | gpt-4o | Claude 3.5 Sonnet | Gemini Pro |
| Transcripción | Whisper | Google STT | AssemblyAI |
| TTS estándar | OpenAI TTS | Google TTS | ElevenLabs |
| Generación de imagen | DALL-E 3 | Stable Diffusion | — |
Fallback por costo
Usar modelo barato por defecto, escalar a premium si la calidad no es suficiente.
def smart_cost_analysis(image_path: str, prompt: str) -> dict:
"""Empieza con mini, escala a pro si necesario."""
# Paso 1: Intento con modelo económico
result = call_vision("gpt-4o-mini", image_path, prompt)
# Paso 2: Verificar si la respuesta es confiable
if needs_escalation(result):
result = call_vision("gpt-4o", image_path, prompt)
return {"tier": "premium", "result": result}
return {"tier": "economic", "result": result}
def needs_escalation(result: str) -> bool:
"""Detecta si el resultado necesita un modelo mejor."""
uncertainty_phrases = [
"no estoy seguro", "no puedo determinar",
"la imagen no es clara", "no es posible"
]
return any(phrase in result.lower() for phrase in uncertainty_phrases)
Troubleshooting
Problema 1: Rate limit exceeded
Causa: Demasiadas requests al mismo proveedor.
Solución:
import time
def call_with_rate_limit(func, *args, max_retries=3, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
if "rate_limit" in str(e).lower():
wait = 2 ** attempt
time.sleep(wait)
else:
raise
raise RuntimeError(f"Rate limit después de {max_retries} intentos")
Problema 2: Diferencias de formato entre proveedores
Causa: OpenAI, Anthropic y Google tienen formatos de API distintos.
Solución: Crear wrappers con interfaz unificada (como se muestra en el código de fallback arriba).
Problema 3: API de Anthropic diferente a OpenAI
Causa: Las APIs tienen interfaces distintas para enviar imágenes.
Solución: Nota las diferencias clave:
# OpenAI: imagen como "image_url" con data URI
{"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,..."}}
# Anthropic: imagen como "image" con source object
{"type": "image", "source": {"type": "base64", "media_type": "image/jpeg", "data": "..."}}
# Google: usa PIL.Image directamente
model.generate_content([prompt, PIL.Image.open(path)])
Problema 4: Costos inesperados
Causa: No monitorear uso.
Solución: Implementar tracking de costos por request:
COSTS = {
"gpt-4o": {"input": 2.50, "output": 10.0}, # por 1M tokens
"gpt-4o-mini": {"input": 0.15, "output": 0.60},
"whisper-1": {"per_minute": 0.006},
"tts-1": {"per_million_chars": 15.0},
"dall-e-3": {"per_image": 0.04},
}
def estimate_cost(model: str, input_tokens: int = 0,
output_tokens: int = 0) -> float:
if model in COSTS:
cost_info = COSTS[model]
return (
(input_tokens / 1_000_000) * cost_info.get("input", 0)
+ (output_tokens / 1_000_000) * cost_info.get("output", 0)
)
return 0.0
Ejercicios
Ejercicio 1: Tabla de decisión personalizada (Fácil)
Para un proyecto de análisis de facturas en español (10,000 facturas/mes), ¿qué proveedor elegirías y por qué? Considera costo, calidad OCR, y volumen.
Ver solución
Análisis:
- Volumen: 10,000 facturas/mes = alto volumen
- Requisito: OCR de facturas (texto + estructura)
- Idioma: Español
Recomendación por tiers:
- Gemini 1.5 Flash: $0.075/1M tokens input → más barato por volumen. OCR bueno.
- GPT-4o-mini: $0.15/1M tokens → buen balance. OCR bueno. Fallback si Flash no basta.
- GPT-4o: Solo para facturas complejas donde mini falla.
Estrategia: Flash por defecto (90% del volumen), GPT-4o-mini para fallback (9%), GPT-4o para casos difíciles (1%).
Costo estimado: ~$75-150/mes (vs ~$2,500/mes si usaras GPT-4o para todo).
Ejercicio 2: Wrapper multi-proveedor (Medio)
Crea una función vision_analyze que acepte un parámetro provider ("openai", "anthropic", "google") y llame a la API correspondiente con la misma interfaz.
Ver solución
def vision_analyze(
image_path: str,
prompt: str,
provider: str = "openai"
) -> str:
with open(image_path, "rb") as f:
image_data = base64.b64encode(f.read()).decode()
if provider == "openai":
response = openai_client.chat.completions.create(
model="gpt-4o-mini",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url", "image_url": {
"url": f"data:image/jpeg;base64,{image_data}"
}}
]
}],
max_tokens=500
)
return response.choices[0].message.content
elif provider == "anthropic":
response = anthropic_client.messages.create(
model="claude-3-5-sonnet-latest",
max_tokens=500,
messages=[{
"role": "user",
"content": [
{"type": "image", "source": {
"type": "base64",
"media_type": "image/jpeg",
"data": image_data
}},
{"type": "text", "text": prompt}
]
}]
)
return response.content[0].text
elif provider == "google":
import google.generativeai as genai
from PIL import Image
model = genai.GenerativeModel("gemini-1.5-flash")
img = Image.open(image_path)
response = model.generate_content([prompt, img])
return response.text
else:
raise ValueError(f"Proveedor no soportado: {provider}")
Explicación: El wrapper unifica la interfaz de los 3 proveedores. Facilita cambiar de proveedor sin modificar el código que lo llama.
Ejercicio 3: Benchmark de proveedores (Medio)
Crea una función que envíe la misma imagen y prompt a los 3 proveedores y compare resultados (respuesta, latencia).
Ver solución
import time
def benchmark_providers(image_path: str, prompt: str) -> list[dict]:
providers = ["openai", "anthropic", "google"]
results = []
for provider in providers:
try:
start = time.time()
result = vision_analyze(image_path, prompt, provider)
latency = round(time.time() - start, 2)
results.append({
"provider": provider,
"status": "ok",
"latency_s": latency,
"response_length": len(result),
"response_preview": result[:200]
})
except Exception as e:
results.append({
"provider": provider,
"status": "error",
"error": str(e)
})
return results
# Uso
results = benchmark_providers("test_image.jpg", "Describe esta imagen.")
for r in results:
print(f"{r['provider']}: {r.get('latency_s', 'N/A')}s - {r['status']}")
Explicación: Benchmarking te permite decidir con datos reales qué proveedor usar para tu caso de uso específico.
Ejercicio 4: Calculator de costos (Difícil)
Crea una función que, dado un plan de uso mensual (N imágenes con vision, M minutos de audio, K imágenes generadas), calcule el costo por proveedor.
Ver solución
def estimate_monthly_cost(
vision_images: int = 0,
audio_minutes: int = 0,
generated_images: int = 0,
tts_characters: int = 0
) -> dict:
avg_tokens_per_image = 800 # tokens promedio por imagen
avg_output_tokens = 300
costs = {}
# OpenAI
vision_cost = (
(vision_images * avg_tokens_per_image / 1_000_000) * 2.50
+ (vision_images * avg_output_tokens / 1_000_000) * 10.0
)
audio_cost = audio_minutes * 0.006
image_cost = generated_images * 0.04
tts_cost = (tts_characters / 1_000_000) * 15
costs["openai"] = round(
vision_cost + audio_cost + image_cost + tts_cost, 2
)
# GPT-4o-mini (vision más barata)
vision_mini = (
(vision_images * avg_tokens_per_image / 1_000_000) * 0.15
+ (vision_images * avg_output_tokens / 1_000_000) * 0.60
)
costs["openai_mini"] = round(
vision_mini + audio_cost + image_cost + tts_cost, 2
)
# Gemini Flash
vision_flash = (
(vision_images * avg_tokens_per_image / 1_000_000) * 0.075
+ (vision_images * avg_output_tokens / 1_000_000) * 0.30
)
costs["gemini_flash"] = round(vision_flash, 2)
return costs
# Uso
monthly = estimate_monthly_cost(
vision_images=10000,
audio_minutes=500,
generated_images=100,
tts_characters=500000
)
print(monthly)
# Output: {"openai": 27.5, "openai_mini": 4.31, "gemini_flash": 0.69}
Explicación: La diferencia de costo entre proveedores y modelos puede ser 10-40x. Esta función te ayuda a tomar decisiones informadas antes de comprometerte con un proveedor.
Resumen
En esta cápsula aprendiste:
- 3 proveedores principales: OpenAI (ecosistema completo), Anthropic (razonamiento profundo), Google (contexto masivo y costo bajo)
- Cada proveedor tiene trade-offs claros en costo, calidad, latencia y funcionalidades
- El árbol de decisión te guía: qué necesitas → qué modelo usar
- Fallback por disponibilidad (proveedor falla → alternativa) y por costo (barato primero → premium si necesario)
- Gemini Flash es el más barato para vision por volumen
- Claude 3 Opus tiene el mejor razonamiento pero es el más caro
- GPT-4o-mini ofrece el mejor balance calidad/precio para la mayoría de casos
- Para volumen alto, la diferencia de costo entre modelos puede ser 10-40x
- Un wrapper multi-proveedor con interfaz unificada facilita cambiar de modelo sin reescribir código
Próxima cápsula: Formatos y APIs — los detalles técnicos de Base64, URLs, tamaños y costos por endpoint.
Recursos Adicionales
- OpenAI Pricing — Precios actualizados de todos los modelos OpenAI
- Anthropic Pricing — Precios de Claude 3
- Google AI Pricing — Precios de Gemini (incluye tier gratuito)
- Replicate Models — Catálogo de modelos incluyendo Stable Diffusion
- ElevenLabs Pricing — Precios de TTS premium
- AssemblyAI Pricing — Precios de transcripción con features avanzadas