Módulo 7: Comparación técnica de proveedores

Benchmark de costo

Latencia te dice si tu producto se siente bien. Costo te dice si tu producto es viable. Un endpoint con P50 de 1s pero que cuesta $10,000/mes es un problema distinto a uno con P50 de 4s pero $200/mes.

En esta cápsula vas a construir una calculadora que estima costo mensual real de cada proveedor para distintos perfiles de tráfico. No vas a usar "el precio nominal por 1M tokens" — vas a calcular lo que pagas tú considerando warm pool, storage, free tier, todo.

Al terminar vas a poder:

  • Calcular costo mensual aproximado para cualquier proveedor dado tu volumen y largo promedio de request
  • Comparar proveedores a 3 escalas de tráfico (low/medium/high) y encontrar el "cross-over point" donde cambia el ganador
  • Detectar costos ocultos que la mayoría omite (warm pool, egress, storage de modelos)
  • Hacer una hoja de cálculo defendible para mostrar a un cofounder o finance

Por qué importa

Tres escenarios reales donde esto cambia decisiones:

Escenario 1. Una startup MVP estima "vamos a usar OpenAI para empezar". Hacen el cálculo: $0.15 por 1M tokens input, parece barato. No consideran que su request promedio incluye 3000 tokens de contexto RAG. El costo real es 20× lo que estimaron.

Escenario 2. Un equipo decide self-hosting con Ollama "porque es gratis". No incluyen el costo de la VM con GPU prendida 24/7, que termina siendo $1,800/mes. Más caro que OpenAI a su volumen actual.

Escenario 3. Una agencia usa Modal y se ve barato. No notan que su min_containers=2 los cuesta $1,400/mes de warm pool aunque casi no haya tráfico nocturno.

Todos estos son evitables con 15 minutos de hoja de cálculo. Esta cápsula te enseña a hacerla bien.


Modelo mental: tipos de costo

TipoQuién lo cobraCaracterística
Por tokenOpenAI, Anthropic, OpenRouter, TogetherLineal con volumen. Escala bien hacia abajo.
Por segundo de GPUModal, Replicate, RunPodLineal con tiempo de inferencia. Sensible a optimizaciones.
Fijo (renta)Self-hosted (VM con GPU 24/7)Independiente del volumen. Gana con volumen alto.
FreeOllama local en tu hardwarePagas con tu hardware/electricidad, no facturado.

Cross-over points (puntos de cruce): la línea donde un tipo deja de ser más barato que otro. Identificarlos es el punto de esta cápsula.


La fórmula base

Para proveedores token-based:

costo_mensual = requests_mes × tokens_promedio_por_request × precio_por_token

Para proveedores GPU-based:

costo_mensual = (requests_mes × segundos_por_request × precio_por_segundo)
              + (horas_warm × 3600 × precio_por_segundo)
              + costo_storage_modelo

Para self-hosted (VM 24/7):

costo_mensual = horas_mes × precio_VM_por_hora
              + costo_setup_amortizado
              + costo_mantenimiento (tu tiempo $$$)

Calculadora: implementación

Crea calculadora_costos.py:

# calculadora_costos.py
from dataclasses import dataclass
from typing import Literal

# ============================================================
# Precios de referencia (verificar actuales en docs de cada proveedor)
# Estos son aproximados a inicios de 2026; revisa antes de usar.
# ============================================================
PRECIOS = {
    "openai_gpt-4o-mini": {
        "input_per_1m_tokens": 0.15,
        "output_per_1m_tokens": 0.60,
    },
    "openai_gpt-4o": {
        "input_per_1m_tokens": 2.50,
        "output_per_1m_tokens": 10.00,
    },
    "anthropic_claude-3.5-sonnet": {
        "input_per_1m_tokens": 3.00,
        "output_per_1m_tokens": 15.00,
    },
    "openrouter_mistral-7b-instruct": {
        "input_per_1m_tokens": 0.07,
        "output_per_1m_tokens": 0.07,
    },
    "openrouter_mixtral-8x7b-instruct": {
        "input_per_1m_tokens": 0.24,
        "output_per_1m_tokens": 0.24,
    },
    "modal_a10g": {
        "per_second": 0.000306,    # GPU only
    },
    "modal_t4": {
        "per_second": 0.000164,
    },
    "modal_a100_40gb": {
        "per_second": 0.001097,
    },
    "selfhosted_a10g_aws": {
        "per_hour": 1.006,         # g5.xlarge spot aprox
    },
    "selfhosted_a100_aws": {
        "per_hour": 4.10,          # p4d.24xlarge spot aprox
    },
}


# ============================================================
# Perfil de uso
# ============================================================
@dataclass
class PerfilUso:
    requests_mes: int
    tokens_input_promedio: int = 500
    tokens_output_promedio: int = 200
    segundos_gpu_promedio: float = 2.0   # para proveedores GPU
    warm_pool_horas_mes: float = 0      # 0 si min_containers=0; 720 si 24/7

    def costo_openai(self, modelo: str) -> float:
        p = PRECIOS[f"openai_{modelo}"]
        return (
            self.requests_mes * self.tokens_input_promedio * p["input_per_1m_tokens"] / 1_000_000
            + self.requests_mes * self.tokens_output_promedio * p["output_per_1m_tokens"] / 1_000_000
        )

    def costo_anthropic(self, modelo: str) -> float:
        p = PRECIOS[f"anthropic_{modelo}"]
        return (
            self.requests_mes * self.tokens_input_promedio * p["input_per_1m_tokens"] / 1_000_000
            + self.requests_mes * self.tokens_output_promedio * p["output_per_1m_tokens"] / 1_000_000
        )

    def costo_openrouter(self, modelo: str) -> float:
        p = PRECIOS[f"openrouter_{modelo}"]
        tokens_total = self.tokens_input_promedio + self.tokens_output_promedio
        return self.requests_mes * tokens_total * p["input_per_1m_tokens"] / 1_000_000

    def costo_modal(self, gpu: str = "a10g") -> float:
        precio_seg = PRECIOS[f"modal_{gpu}"]["per_second"]
        gpu_activa = self.requests_mes * self.segundos_gpu_promedio * precio_seg
        warm_pool = self.warm_pool_horas_mes * 3600 * precio_seg
        storage_modelo = 2.0  # ~14GB × $0.10/GB/mes ≈ $1.40, redondeado
        return gpu_activa + warm_pool + storage_modelo

    def costo_selfhosted(self, gpu: str = "a10g_aws") -> float:
        per_hour = PRECIOS[f"selfhosted_{gpu}"]["per_hour"]
        return 720 * per_hour  # 24×30 = 720 hrs/mes

    def costo_ollama_local(self) -> float:
        return 0.0  # tu hardware/electricidad, no facturado directamente


# ============================================================
# Reporte comparativo
# ============================================================
def reporte(perfil: PerfilUso, etiqueta: str):
    print(f"\n=== {etiqueta} ===")
    print(f"  Volumen: {perfil.requests_mes:,} requests/mes")
    print(f"  Tokens: {perfil.tokens_input_promedio} input + {perfil.tokens_output_promedio} output")
    print(f"  Warm pool: {perfil.warm_pool_horas_mes} hrs/mes\n")

    print(f"  {'Opción':<45} {'Costo/mes':>12}")
    print(f"  {'-' * 60}")

    candidatos = [
        ("OpenAI GPT-4o-mini", perfil.costo_openai("gpt-4o-mini")),
        ("OpenAI GPT-4o", perfil.costo_openai("gpt-4o")),
        ("Anthropic Claude 3.5 Sonnet", perfil.costo_anthropic("claude-3.5-sonnet")),
        ("OpenRouter Mistral 7B", perfil.costo_openrouter("mistral-7b-instruct")),
        ("OpenRouter Mixtral 8x7B", perfil.costo_openrouter("mixtral-8x7b-instruct")),
        ("Modal Mistral 7B (A10G)", perfil.costo_modal("a10g")),
        ("Modal Mistral 7B (T4)", perfil.costo_modal("t4")),
        ("Self-hosted Ollama (AWS A10G)", perfil.costo_selfhosted("a10g_aws")),
        ("Ollama local (tu hardware)", perfil.costo_ollama_local()),
    ]

    for nombre, costo in sorted(candidatos, key=lambda x: x[1]):
        marcador = " ←" if costo == min(c for _, c in candidatos) else ""
        print(f"  {nombre:<45} ${costo:>10.2f}{marcador}")


# ============================================================
# Tres perfiles representativos
# ============================================================
if __name__ == "__main__":
    LOW = PerfilUso(
        requests_mes=10_000,
        tokens_input_promedio=300,
        tokens_output_promedio=150,
        segundos_gpu_promedio=1.5,
        warm_pool_horas_mes=0,
    )

    MEDIUM = PerfilUso(
        requests_mes=200_000,
        tokens_input_promedio=500,
        tokens_output_promedio=200,
        segundos_gpu_promedio=2.0,
        warm_pool_horas_mes=200,  # warm pool en horario laboral
    )

    HIGH = PerfilUso(
        requests_mes=2_000_000,
        tokens_input_promedio=800,
        tokens_output_promedio=300,
        segundos_gpu_promedio=2.5,
        warm_pool_horas_mes=720,  # warm pool 24/7
    )

    reporte(LOW, "LOW: MVP / hobby (10k req/mes)")
    reporte(MEDIUM, "MEDIUM: Producto en growth (200k req/mes)")
    reporte(HIGH, "HIGH: Producto established (2M req/mes)")

Ejecutar:

python calculadora_costos.py

Lectura típica de resultados

Salidas aproximadas (con números 2026, ajusta a precios actuales):

=== LOW: MVP / hobby (10k req/mes) ===
  Ollama local (tu hardware)                     $      0.00 ←
  OpenAI GPT-4o-mini                             $      1.65
  OpenRouter Mistral 7B                          $      0.32
  Modal Mistral 7B (T4)                          $      4.46
  OpenAI GPT-4o                                  $     27.50
  ...
  Self-hosted Ollama (AWS A10G)                  $    724.32

=== MEDIUM: Producto en growth (200k req/mes) ===
  OpenRouter Mistral 7B                          $      9.80 ←
  Ollama local                                   $      0.00 (excluido — no escala así)
  OpenAI GPT-4o-mini                             $     39.00
  Modal Mistral 7B (T4) + warm pool              $    187.20
  ...
  OpenAI GPT-4o                                  $    900.00
  Self-hosted Ollama (AWS A10G)                  $    724.32

=== HIGH: Producto established (2M req/mes) ===
  Self-hosted Ollama (AWS A10G)                  $    724.32 ←
  Modal Mistral 7B (T4) full warm                $  1,200.00 (aprox)
  OpenRouter Mistral 7B                          $    154.00
  OpenAI GPT-4o-mini                             $    660.00
  OpenAI GPT-4o                                  $ 12,000.00

Patrones que emergen:

  • Low: local "gana" si te alcanza tu hardware. OpenRouter Mistral es escandalosamente barato si no necesitas calidad GPT-4.
  • Medium: OpenRouter sigue ganando para casos donde Mistral basta. OpenAI/Anthropic ganan si tu calidad lo requiere.
  • High: self-hosted empieza a hacer sentido. Pago de GPU 24/7 vs pago por uso cambia las cuentas.

Cross-over points: dónde cambia el ganador

Pregunta interesante: ¿a partir de qué volumen Self-hosted vence a OpenAI?

# Resolver: 720 × $1 = req × 700 × ($0.15 + $0.60) / 1M (gpt-4o-mini)
# $720 = req × 525 / 1M
# req = 1.37M requests/mes

Con 700 tokens totales/request, OpenAI GPT-4o-mini es más barato que Self-hosted A10G hasta ~1.4M req/mes. Pasado ese punto, self-hosted gana.

Pero — y esto es importante — Self-hosted asume 100% utilización (tráfico 24/7 saturando la GPU). Si tu tráfico es bursty (200K en horario laboral, 0 en madrugada), la GPU está idle el 50% del tiempo y necesitas multiplicar tu break-even por ~2×.

Lección: los cross-over points dependen de tu patrón de tráfico, no solo del volumen total.


Costos ocultos que casi nadie incluye

1. Warm pool. Modal con min_containers=1 A10G = ~$720/mes adicional. Easy de olvidar; doloroso al fin de mes.

2. Egress. Modal y cloud providers cobran transferencia hacia fuera. Para chat texto es negligible; para imágenes/audio puede dolerte.

3. Storage de modelos. Volumes de 50GB con varios modelos = ~$5/mes. Acumulable.

4. Mantenimiento humano (self-hosted). Si tu equipo dedica 5hrs/semana a mantener la GPU, parchar drivers, debuggear OOM — eso es tiempo del engineer. A $80/hr × 20hrs/mes = $1,600/mes "invisible".

5. Logging y observabilidad. Datadog, Sentry, etc. agregan ~$50-300/mes. Lo necesitas pero no aparece en la calc de proveedor LLM.

6. Tier creep en OpenAI. "Vamos a empezar con gpt-4o-mini" → "necesitamos mejor calidad, pasamos a gpt-4o" → factura 15× más alta. Plan para ese drift.


Trampas comunes

Trampa 1 — "OpenAI dice $0.15 por 1M tokens, qué barato." Es por input. Output cuesta 4×. Y tu request real suma input + output. Lee los precios completos.

Trampa 2 — "Ollama es gratis." Tu hardware no es gratis (laptop $2000, electricidad ~$15/mes corriendo full-time). Para uso personal, "gratis enough". Para producto comercial, considera amortización.

Trampa 3 — "Self-hosted siempre es más barato en escala." Solo si la GPU está saturada. Si tu tráfico nocturno es 5% del diurno, una GPU prendida 24/7 desperdicia 50%+ del tiempo. Modal/serverless puede seguir ganando.

Trampa 4 — "Comparo Mistral 7B vs GPT-4 por precio." No es comparación justa. Si Mistral 7B no resuelve tu task con calidad aceptable, su "precio bajo" es irrelevante. Compara modelos que cumplen el SLA de calidad, no cualquier modelo.

Trampa 5 — "Calculé con precios de hace un año." Precios cambian. OpenAI bajó gpt-4o-mini significativamente en 2025. Anthropic cambió pricing. Modal ajusta. Verifica precios actuales cuando vas a tomar decisión.


Ejercicio

Tu producto es un asistente de soporte técnico B2B:

  • 80K requests/mes esperados
  • Cada request incluye 1500 tokens de contexto RAG + 200 tokens de pregunta = ~1700 input
  • Respuesta promedio ~250 tokens
  • Tráfico concentrado de 9am-6pm hora laboral, casi nada de noche
  • Tu cliente enterprise mayor exige que los datos no salgan a USA (proveedores cloud-managed quedan con ⚠️)

Calcula:

  1. Costo aprox mensual con OpenAI GPT-4o-mini (¿es válido para tu cliente enterprise?)
  2. Costo aprox mensual con Modal Mistral 7B + warm pool en horario laboral
  3. Costo aprox mensual con Self-hosted Ollama en EU
  4. ¿Cuál recomiendas y por qué?
Ver solución
perfil_caso = PerfilUso(
    requests_mes=80_000,
    tokens_input_promedio=1700,
    tokens_output_promedio=250,
    segundos_gpu_promedio=2.5,
    warm_pool_horas_mes=200,  # ~9hrs × 22 días
)

# OpenAI gpt-4o-mini
# = 80000 × 1700 × 0.15 / 1M + 80000 × 250 × 0.60 / 1M
# = $20.40 + $12.00 = $32.40
# ⚠️ NO válido si cliente enterprise restringe data residency en USA

# Modal Mistral 7B A10G
# GPU activa: 80000 × 2.5 × $0.000306 = $61.20
# Warm pool: 200 × 3600 × $0.000306 = $220.32
# Storage: ~$2
# Total: ~$283.52
# (verifica certificación SOC2/data residency de Modal con tu cliente)

# Self-hosted Ollama EU
# A10G en AWS EU eq.: ~$1.05/hr × 720 = $756/mes
# + costo humano mantenimiento (variable)

# Recomendación:
# - Si Modal cumple data residency de tu cliente (verifica), Modal es ~3× más barato
# - Si no, Self-hosted EU es la única opción válida y aceptas el costo
# - OpenAI no es viable por la restricción contractual

Decisión defendible: documenta los números, verifica certificaciones con el cliente legal, y recomienda con razones contractuales y económicas explícitas.


Resumen

Aprendiste:

  • ✅ Tipos de costo (token, GPU-second, fijo, free) y cuándo cada uno gana
  • ✅ Calcular costo mensual incluyendo costos ocultos (warm pool, storage, egress, humano)
  • ✅ Identificar cross-over points donde cambia el ganador económico
  • ✅ Diseñar perfiles representativos (low/medium/high) que reflejan crecimiento típico
  • ✅ Defender una recomendación con números, no opiniones

Checkpoint: si puedes responder "¿cuánto cuesta esto al mes?" sin balbucear, con un número justificado por una fórmula, estás listo.


Siguiente cápsula

04 — Benchmark de calidad. La dimensión más difícil de las tres. Vamos a aterrizarla con: set de evaluación representativo, rubric clara, LLM-as-judge, y métricas defendibles.


Recursos

  1. OpenAI Pricing — fuente de verdad, cambia.
  2. Modal Pricing — GPU por segundo actual.
  3. OpenRouter Models — precios por modelo agregado.
  4. Anthropic Pricing — Claude variants.
  5. Artificial Analysis — Pricing Comparisons — tabla pública comparativa.
  6. AWS EC2 GPU Pricing — para cálculo self-hosted.