110 lines
4.5 KiB
Markdown
110 lines
4.5 KiB
Markdown
# Modelo de capacidad — 100.000 facturas/mes
|
||
|
||
No sustituye una corrida real de 100k PDFs. Usa supuestos conservadores + evidencia k6 del 2026-07-13.
|
||
|
||
## Objetivo
|
||
|
||
| Escenario | Facturas/hora necesarias |
|
||
|-----------|--------------------------|
|
||
| 100k/mes 24×7 | ≈ 139/h |
|
||
| 100k/mes jornada 8h×22d | ≈ 570/h |
|
||
|
||
## Estimaciones por etapa (host compartido 8 GiB)
|
||
|
||
| Etapa | facturas/h estimadas | vs 139/h | vs 570/h |
|
||
|-------|----------------------|----------|----------|
|
||
| Gateway (orquestación) | >>10 000 (health ~57 rps) | OK | OK |
|
||
| count-api OCR | **≈100–325** (ST-COUNT-01 2026-07-17: p50 35,8 s @3 conc.; 9/9 ok) | ÁMBAR/OK | NO |
|
||
| extraction LLM | **≈506** (ST-EXT-02 2026-07-17: p50 7,114 s, gpt-5.4-mini, 23 PDFs) | OK | ÁMBAR (1w); OK≈1012/h con 2w sin cuota |
|
||
| Agent Selenium (1 agent PC) | **≈422** (medido: 633 PDFs / 90 min) | OK vs 139/h | NO vs 570/h |
|
||
| cleaning CSV | 500–2000 | OK | ÁMBAR |
|
||
| Pipeline completo (este host) | **≈100–325** (= min etapas; cuello OCR; **no** medido E2E) | JUSTO/NO vs 139 | NO vs 570 |
|
||
|
||
## Bench cola ARQ (ST-EXT-01) — LLM mock
|
||
|
||
Mide enqueue + drenado de backlog **sin coste OpenAI**. Requiere mock + `ASYNC_QUEUE=true`.
|
||
|
||
```bash
|
||
# Terminal 1 — mock OpenAI-compatible
|
||
bash docs/plan_pruebas/scripts/llm_mock_server.sh
|
||
# Apuntar extraction/workers:
|
||
# EXTRACTOR_BASE_URL=http://host.docker.internal:8099/v1
|
||
# ASYNC_QUEUE=true
|
||
# WORKER_REPLICAS=1 # shared8g; lab → 2
|
||
|
||
# Terminal 2 — bench
|
||
bash docs/plan_pruebas/scripts/st_ext_01_arq_bench.sh
|
||
PROFILE=lab ARQ_BENCH_LIMIT=100 bash docs/plan_pruebas/scripts/st_ext_01_arq_bench.sh
|
||
|
||
# Windows
|
||
.\docs\plan_pruebas\scripts\llm_mock_server.ps1
|
||
.\docs\plan_pruebas\scripts\st_ext_01_arq_bench.ps1 -Profile shared8g -Limit 30
|
||
```
|
||
|
||
Salida: `informes/st_ext_01_arq_YYYYMMDD.csv` + `.summary.json`. Schema: `st_ext_01_schema.json`.
|
||
|
||
**Resultados 2026-07-17 (shared8g, Limit=30):** mode=async; 30/30 queued; drained en **22,5 s**; total **23,9 s**; throughput cola ≈ **4 528 docs/h** (mock ≈50 ms — no es SLO LLM). Producción: `ASYNC_QUEUE=true`.
|
||
|
||
## Bench OCR carga (ST-COUNT-01)
|
||
|
||
```bash
|
||
# Python (recomendado si no hay k6):
|
||
python docs/plan_pruebas/scripts/st_count_01_bench.py --profile shared8g
|
||
# Windows:
|
||
.\docs\plan_pruebas\scripts\st_count_01_bench.ps1 -Profile shared8g
|
||
|
||
# k6 (campo multipart corregido a "files"):
|
||
k6 run -e PROFILE=shared8g k6_count_batches.js
|
||
```
|
||
|
||
**Resultados 2026-07-17:** 9/9 ok; p50 **35,8 s** @3 concurrentes; throughput obs. ≈ **325 fact/h**; sin 5xx/OOM.
|
||
|
||
## Bench LLM (ST-EXT-02) — mismo schema/campos
|
||
|
||
Congela `fields` en `informes/st_ext_02_schema.json` y los reutiliza en toda la corrida
|
||
(y en re-runs) para que latencia/coste sean comparables. Modelo default: **gpt-5.4-mini**.
|
||
|
||
```bash
|
||
# Linux/macOS
|
||
bash docs/plan_pruebas/scripts/st_ext_02_llm_bench.sh
|
||
LLM_BENCH_LIMIT=10 bash docs/plan_pruebas/scripts/st_ext_02_llm_bench.sh
|
||
|
||
# Windows
|
||
.\docs\plan_pruebas\scripts\st_ext_02_llm_bench.ps1
|
||
.\docs\plan_pruebas\scripts\st_ext_02_llm_bench.ps1 -Limit 10 -Model gpt-5.4-mini
|
||
# Forzar redescubrimiento de schema:
|
||
.\docs\plan_pruebas\scripts\st_ext_02_llm_bench.ps1 -Rediscover
|
||
```
|
||
|
||
Salida:
|
||
- `docs/plan_pruebas/informes/llm_latency_YYYYMMDD.csv`
|
||
- `docs/plan_pruebas/informes/llm_latency_YYYYMMDD.summary.json`
|
||
- `docs/plan_pruebas/informes/st_ext_02_schema.json` (campos fijos)
|
||
|
||
Coste de referencia: USD **0,0257**/doc → **USD 2 570** por 100 000 que pasan conteo.
|
||
|
||
**Resultados 2026-07-17:** 23/23 ok; p50 **7,114** s; p95 **8,582** s; ≈**506** fact/h (1 worker).
|
||
Volcados en `informe/sections/13_llm_latency.tex` y fila LLM de `08_capacidad_100k.tex`.
|
||
|
||
## Escenario dedicado (condicional)
|
||
|
||
Con host ≥16–32 GiB solo IPS, OCR pool, 2+ workers extraction, cuota LLM, N agents Selenium: pipeline completo puede acercarse a 139–570/h según dimensionamiento (y p50 LLM medido).
|
||
|
||
## Coste LLM — 100 000 facturas que pasan el filtro de conteo
|
||
|
||
Supuesto: el conteo filtra el lote y **100 000 PDFs** llegan a extracción.
|
||
|
||
| Concepto | Valor |
|
||
|----------|-------|
|
||
| Modelo de extracción | **gpt-5.4 mini** |
|
||
| Coste por documento | **USD 0,0257** |
|
||
| Volumen (pasan filtro conteo) | 100 000 |
|
||
| **Coste estimado extracción/mes** | **USD 2 570** |
|
||
|
||
Fórmula: `100_000 × 0.0257 = 2_570`.
|
||
|
||
Notas:
|
||
- No incluye agent Selenium, orquestación `bot-descarga`, OCR de conteo, infra ni reintentos.
|
||
- Si el filtro de conteo deja pasar menos de 100k, el coste baja linealmente (`n_válidos × 0.0257`).
|
||
- ST-EXT-02 2026-07-17 usó el unitario 0.0257 como estimación; contrastar con tokens reales si se instrumenta usage.
|