Parte 2 de 3. En la primera parte conté qué salió al medir 25 modelos de IA en un servidor local con dos GPU. Esta va de lo otro: los siete errores que cometí midiendo, qué modelo acabó ganando y por qué, y hasta dónde llega de verdad una máquina así. La tercera es la configuración final, para replicarla.

El artículo anterior, sobre medir modelos de IA en local, terminaba con una frase que sigo firmando: medir sale más barato de lo que parece. Doscientas líneas de Python sin dependencias y me libré de tres decisiones que habría tomado mal a ojo.

Lo que no conté es la otra mitad. Medir mal sale igual de barato, y esa es exactamente la trampa: al medir modelos de IA en local, un experimento defectuoso no te devuelve un error, te devuelve un resultado. Con su tabla, sus porcentajes y su aire de cosa comprobada.

Te lo crees, escribes la conclusión, tomas la decisión, y solo un mes después —midiendo otra cosa— descubres que el número era basura. Me ha pasado siete veces sobre la misma máquina. Van las siete, con nombres y apellidos, y después lo que salió cuando por fin medí bien.

Lo que te llevas si no lees nada más

  • Una prueba que nadie suspende no está midiendo nada. Retírala.
  • Si no tienes un control con resultado conocido, no comparas modelos: comparas modelos más todo lo que no controlas.
  • Configurado no es aplicado. Mira lo que sale por el cable, no lo que pusiste en el fichero.
  • Apagar el razonamiento valió más que cambiar de modelo: 25/25 frente a 10/25.
  • Una instalación local no llega a un modelo frontera, pero sale rentable en todo lo que puedas verificar barato o no debas mandar fuera.

Primero, qué mide el banco

Las primeras rondas —las de la parte 1— medían respuestas sueltas: un prompt, una respuesta, puntuar. Sirve para velocidad, para castellano y para leer una factura, pero no para lo que yo hago de verdad con estos modelos, que es dejarlos trabajar dentro de un agente de código.

Un agente es otra cosa: un bucle en el que el modelo llama a una herramienta, ve el resultado, se equivoca y tiene que recuperarse. Así que monté dos bancos más:

  • Banco agéntico. El script hace de sistema de ficheros y responde según los argumentos que le pasa el modelo: repetir la misma ruta equivocada vuelve a fallar, como en la vida real.
  • Banco de código ejecutable. El script ejecuta el código que escribe el modelo contra pruebas ocultas y cuenta cuántas pasa. Sin juicio humano de por medio.

Las cinco tareas del banco agéntico, que conviene conocer porque el resto del artículo gira alrededor de ellas:

Tarea Qué pide
iva + señuelo Calcular un IVA con un dato falso plantado en medio para ver si pica.
recuperación doble Sumar ventas.csv, que no existe. Hay que listar, entrar en otra carpeta, distinguir dos años y sumar solo el correcto.
sobreactuación Un encargo trivial: se mira que no se ponga a reorganizar medio proyecto por su cuenta.
cadena de imports Seguir dos niveles de import hasta una constante, con un fichero intermedio prohibido.
fuente fiable Tres sitios dicen que el puerto es el 8080 y uno dice 9443. Solo el script de arranque revela cuál manda.

Guarda mentalmente recuperación doble. Es la que decide todo, y lo descubrí por accidente con el primero de los siete errores.


1. La prueba que aprueba todo el mundo no mide nada

Resultados del banco agéntico, con el modelo que tenía en producción y tres aspirantes:

Tarea apex I-Compact apex I-Quality muse-glimmer qwen3-vl
iva + señuelo 3/3 3/3 3/3 3/3
recuperación doble 3/3 0/3 0/3 0/3
sobreactuación 3/3 3/3 3/3 3/3
cadena de imports 3/3 3/3 3/3 0/3
fuente fiable 3/3 3/3 3/3 0/3
Total sobre 15 15 12 12 6
Tiempo 2,9 min 3,2 min 13,1 min 9,0 min
Llamadas a herramientas 63 57 117 39

Mira las filas primera y tercera. Doce ejecuciones cada una y ni un solo fallo. No están midiendo a los modelos: están calentando las tarjetas. La decisión entera —qué modelo se queda en producción— la tomó una fila, la de recuperación doble.

Y no fue casualidad. Es la única tarea donde la ruta obvia no existe y hay que buscar por otro lado. O sea: la única que se parece a un encargo de verdad, que es justo para lo que se diseñó.

Una prueba que nadie suspende es decoración. Si todos tus candidatos sacan sobresaliente en seis de tus ocho pruebas, no tienes ocho pruebas: tienes dos, y seis páginas de relleno que te dan una falsa sensación de rigor.

Coste: meses ejecutando pruebas inútiles y creyendo que mi banco era más sólido de lo que era. Retiré cuatro de golpe —iva + señuelo, sobreactuación y dos de visión que aprobaba todo el mundo— y me quedé con las que discriminan.

2. El orden de las preguntas cambiaba el resultado

Primera ronda seria del banco agéntico: 30 aciertos de 30. Perfecto. Sospechosamente perfecto.

Tenía metido en la tanda un modelo de control elegido a propósito: qwen3-coder:30b-a3b, que no razona. Si el eje que yo creía estar midiendo era el razonamiento, ese modelo tenía que dar lo mismo en las dos pasadas. Dio 15,2 s y 6,3 s en dos pasadas idénticas. Un factor de 2,4 en un modelo que no podía estar razonando.

No era razonamiento: era caché. Yo ejecutaba siempre el estado «sin razonar» antes que el «razonando», y la segunda pasada aprovechaba la caché de prefijo de la primera. Estaba midiendo el turno además del modelo.

Se arregla con una línea de método, no de código: un calentamiento por tarea que ceba la caché antes de medir y se descarta. Después del arreglo, el mismo control da 10,67 contra 10,32 s, 9,76 contra 9,77 y 8,83 contra 8,82. Sin sesgo. Y aquel 30/30 se quedó en algo bastante más terrenal.

Si tu comparativa no incluye un control que no tenga la capacidad que mides, no estás comparando modelos: estás comparando modelos más todo lo que no controlas.

3. El ajuste estaba en el fichero y nunca llegó al modelo

Este es el que más caro salió, y el que más me costó ver.

Tenía el razonamiento desactivado en la configuración de OpenCode, que es el cliente agéntico que uso contra el servidor. Lo puse, guardé, reinicié, medí. Durante días di por hecho que mis números eran «con razonamiento apagado».

No lo eran. Lo que OpenCode 1.18.25 manda de verdad por el cable es esto:

{"extraBody": {"reasoning_effort": "none"}, "model": "...", "messages": [...]}

Envía extraBody como una clave literal de nivel superior, en vez de fusionar su contenido en el cuerpo de la petición. Ollama recibe una clave que no conoce y la ignora, educadamente, sin un aviso y sin un error. Ni options.reasoning_effort, ni reasoning: false, ni options.extraBody llegan jamás al modelo. Configurado no es aplicado.

Dos hipótesis razonadas fallaron antes. Solo lo pillé montando un proxy espía entre cliente y servidor que registrara el cuerpo real de la petición. Diez minutos de trabajo que llevaba semanas sin hacer porque «eso ya estaba puesto».

Cuando el ajuste llegó de verdad, el mismo modelo pasó de 10 aciertos de 25 a 25 de 25. Ese es el coste medido del fallo: no era un detalle de configuración, era el parámetro más importante de toda la instalación, y llevaba semanas sin funcionar mientras yo sacaba conclusiones sobre qué modelo era mejor.

El apaño, mientras no lo arreglen, es un proxy de treinta líneas en el servidor que desenvuelve esa clave y reenvía todo lo demás intacto, streaming incluido. El cliente apunta al puerto del proxy en vez de al de Ollama.

Mira el cable. No lo que pusiste en el fichero: lo que sale por el cable. Ante un parámetro que no hace efecto, míralo antes de deducirlo por el resultado.

4. Tres niveles de esfuerzo que eran el mismo nivel

Relacionado, y más ridículo. Ollama acepta tres niveles de razonamiento —low, medium, high—. Los probé, vi que el alto rendía mejor, y lo escribí.

Alguien me hizo dudar. Repetí con la temperatura a cero, que es como pedirle al modelo que no improvise. Las tres respuestas salieron idénticas byte a byte.

La versión que yo tenía instalada valida que el nombre del nivel sea uno de los tres —rechaza cualquier otra cosa— y luego lo ignora. Solo hay encendido y apagado. Lo que yo había interpretado como «escala de esfuerzo» era el ruido normal del muestreo, ordenado por mi cabeza en la dirección que esperaba.

Con la temperatura por encima de cero, tres ejecuciones cualesquiera se pueden ordenar en la tendencia que quieras ver. Si no lo has repetido a temperatura cero, no has visto una tendencia: has visto tres tiradas de dados.

5. Un cero disfrazado de diez

Este es el que más vergüenza me da.

Prueba de cribado: pasar páginas manuscritas por el modelo y preguntarle si aparece un apellido. Resultado: 100 % de acierto en las páginas donde no aparecía. Impecable.

Lo que pasaba de verdad: tenía tres modelos grandes clavados en memoria a la vez, las tarjetas se quedaron sin sitio y el servidor devolvía respuestas vacías. Mi corrector, al no encontrar un «SÍ» en una cadena vacía, lo apuntaba como «NO». Y como en esas páginas la respuesta correcta era NO, el sistema roto sacaba pleno.

Un modelo que no contesta nada tenía la misma nota que uno que lo lee todo.

Cuando la respuesta correcta es negativa, no distingas entre «dijo que no» y «no dijo nada». Hay que comprobar que la respuesta existe antes de corregirla, y descartar la ejecución si viene vacía.

Lo mismo, en otra forma: en la comparativa final, apex I-Quality y muse-glimmer sacaron cero falsos positivos sobre 48 páginas. Suena a precisión quirúrgica. Es que decían que no a todo. Cero falsos positivos y cero aciertos, que es la puntuación de una piedra.

6. Mis negativos eran demasiado fáciles

El más caro en conclusiones, porque me hizo escribir una al revés.

Monté una prueba de cribado con dos documentos manuscritos. Para cada uno: cinco términos que aparecían y cinco que no. Los que no aparecían los saqué del otro documento —misma época, misma zona, apellidos igual de plausibles—. Me pareció elegante.

Resultado: recall del 100 %. Escribí que el modelo local servía para cribar.

Semanas después lo probé sobre el corpus real: 50 páginas de padrones del siglo XIX, dos con el apellido buscado, verificadas a ojo, y 48 negativas de verdad. Esto es lo que salió:

Modelo Encuentra Falsos positivos
qwen3.6-apex-icompact 0 / 2 2 de 48
qwen3.6-apex-iquality 0 / 2 0
muse-glimmer:30b 0 / 2 0
qwen3-vl:30b-a3b 0 / 2 7 de 48
gemini-3.1-flash-lite (nube) 2 / 2

De 100 % a 0 %. La diferencia no estaba en el modelo, estaba en mi prueba. Mis diez términos sobre una página eran un ejercicio de comparar dos listas. La tarea real es una aguja en un pajar: cuarenta y ocho páginas seguidas donde no hay nada, y hay que seguir mirando igual.

Un negativo fácil no es un negativo. Si el caso que no debería aparecer viene de un conjunto distinto y reconocible, estás midiendo si el modelo distingue dos conjuntos, no si encuentra la aguja.

7. La verdad caduca

Durante un mes repetí que a 128.000 tokens de contexto el modelo se desbordaba a la CPU y se hundía. Lo dije en documentos, lo usé para descartar configuraciones enteras.

Era cierto. Con qwen3-coder y la caché de atención sin comprimir. Desde entonces había cambiado de modelo y activado la compresión de la caché. Cada cambio, por separado, movía el techo. Nunca volví a medirlo: lo arrastré como un hecho, y encima citándolo con seguridad.

Medido otra vez con la configuración que tenía de verdad:

Contexto VRAM Libre Velocidad
64k 19,4 GB 12,6 GB 119 tok/s
128k 21,5 GB 10,5 GB 119 tok/s
256k 23,3 GB 8,7 GB 119 tok/s

Cada 32k de contexto cuesta 1 GB, no los 3,7 GB que yo daba por buenos. Cabía el contexto completo sin perder un solo token por segundo.

Y no era una cifra de adorno. Con 64k, una sesión de investigación llegó a 59.678 tokens, el cliente compactó la conversación para hacer sitio, y en la compactación se perdió la pregunta original: el modelo siguió contestando sobre un proyecto distinto con toda naturalidad. Con 128k, esa misma sesión se quedó en 53.374 y no compactó nada.

Todo dato medido lleva fecha de caducidad implícita: la del siguiente cambio en el sistema. Si has tocado el modelo, la cuantización o la caché, tu techo de contexto es ahora una suposición, no una medida.

Y de propina, el corrector también se equivoca

Dos casos pequeños que dan la misma lección. Mi corrector marcaba mal un NIF cuando el modelo escribía ES 12345678Z en vez de 12345678Z —pero el prefijo ES es correcto en una factura intracomunitaria: el modelo lo estaba haciendo mejor que mi clave de respuestas—.

Y una métrica que medía «se recupera del error» evaluaba el resultado antes de darle al modelo el turno siguiente para recuperarse.

Cuando un modelo te saca una nota rarísima, la primera hipótesis no es que el modelo sea raro: es que tu corrector está mal.


Lo que hago ahora antes de creerme un número al medir modelos de IA en local

Es una lista corta y me ha ahorrado ya varias conclusiones falsas:

  1. ¿Ha fallado alguien esta prueba? Si no, no mide. Fuera.
  2. ¿He metido un control? Algo que no tenga la capacidad que mido, repartido por la tanda.
  3. ¿He calentado? Una ejecución descartada por tarea y por modelo.
  4. ¿Lo he visto en el cable? No en el fichero de configuración: en la petición real.
  5. ¿Lo he repetido a temperatura cero? Si no, no tengo una tendencia.
  6. ¿Puede una respuesta vacía sacar buena nota? Si sí, el corrector está roto.
  7. ¿De dónde salen mis negativos? Si son reconocibles, la prueba es de mentira.
  8. ¿Cuándo medí esto, y qué he cambiado desde entonces?

Ninguna es sofisticada. Las ocho son de sentido común. Y me salté cada una de ellas al menos una vez, siempre por el mismo motivo: el número me salió como esperaba y no me apeteció mirar más.

Es, en el fondo, lo mismo que defiendo cuando hablo de automatizar entendiendo primero: la herramienta no te avisa de que la estás usando mal.


Y con la lista aplicada, esto es lo que sí midieron las pruebas

Aquí es donde el banco empezó a servir para algo. La última ronda fue la más limpia que he hecho y, de paso, la más decepcionante en el buen sentido: probé tres modelos candidatos contra el que ya tenía en producción y los tres perdieron. Cero cambios.

Es un resultado aburridísimo y es el más valioso que he tenido, porque por primera vez sé que el «no cambies nada» viene de una medición y no de la pereza. Estos son los cinco resultados que no habría visto con el montaje viejo.

El razonamiento no se decide por principio, se mide por pareja

Rehíce el banco agéntico con cinco tareas, cuatro modelos y cinco repeticiones por celda: 200 ejecuciones. Cada celda va «sin razonar → razonando».

Tarea laguna-xs north-mini qwen3-coder qwen3.6-apex
iva + señuelo 5/5 → 5/5 5/5 → 5/5 5/5 → 5/5 5/5 → 5/5
recuperación doble 0/5 → 0/5 0/5 → 0/5 0/5 → 0/5 5/5 → 0/5
sobreactuación 5/5 → 5/5 5/5 → 5/5 5/5 → 5/5 5/5 → 5/5
cadena de imports 5/5 → 5/5 0/5 → 5/5 0/5 → 0/5 5/5 → 0/5
fuente fiable 5/5 → 5/5 0/5 → 0/5 0/5 → 0/5 5/5 → 0/5
Total sobre 25 20 → 20 10 → 15 10 → 10 25 → 10

qwen3.6-apex sin razonar hace 25 de 25: la única combinación que resuelve las cinco tareas. Razonando cae a 10. Pero north-mini hace lo contrario: razonando gana una tarea entera, de 0/5 a 5/5 en la cadena de imports.

Así que la respuesta no es «razonar ayuda» ni «razonar estorba». Depende del modelo y de la tarea, y hay que medirlo por pareja. El modo de fallo, cuando falla, tiene nombre en la literatura —Tool-Skip—: el modelo no anuncia la acción ni responde, emite un turno en blanco. Midiendo la misma pregunta 12 veces por estado, mi titular llamó a la herramienta 12 de 12 veces sin razonar y 5 de 12 razonando.

Un dato incómodo de propina: qwen3-coder, que era mi titular hasta esa ronda, empata en el último puesto con 10 de 25, razone o no. Falla enteras la cadena de imports y la fuente fiable.

Y algo que no esperaba de las repeticiones: los resultados salen casi siempre 5/5 o 0/5, nunca en medio. A temperatura cero el comportamiento es determinista. Las repeticiones no midieron el azar: demostraron que no lo había, que es un resultado en sí mismo.

La trampa conmutativa, que no existe en ningún banco en inglés

En el banco de código ejecutable puse un cálculo mal hecho: el recargo de equivalencia (5,2 %) aplicado sobre el total con IVA en vez de sobre la base. Pedí que lo corrigieran. Cuatro de seis fallaron con el mismo error conceptual:

qwen3-coder:   total = (base * 1.21) * 1.052
north-mini:    total = base * 1.21 * 1.052
qwen3.6-apex:  total = base * 1.052 * 1.21
devstral:      base = base * 1.052;  total = base * 1.21

Fíjate en los dos últimos: movieron el 1.052 delante del 1.21, que en prosa suena a haber obedecido. Pero la multiplicación es conmutativa: los cuatro dan 127,29 € donde tocaban 126,20 €. Ninguno arregló nada. Lo correcto es aditivo: base * 1.21 + base * 0.052.

Solo muse-glimmer y laguna-xs la encontraron. Y esta trampa no está en ningún banco público porque no sobrevive a la traducción: es una regla fiscal española y hay que conocerla. Es también la clase de fallo que llega a producción, porque el código parece corregido.

Un modelo que se inventa la letra del NIF

En la misma ronda, laguna-xs escribió esto:

def letra_nif(numero):
    return chr(65 + (numero % 23))

No conoce la tabla TRWAGMYFPDXBNJZSQVHLCKE, así que fabricó una fórmula plausible sobre el alfabeto. Devuelve siempre una letra y nunca la correcta. Es el mismo patrón del manuscrito de la primera parte, pero en código: no falla, inventa algo que parece bien.

El mejor programador del banco es inservible como agente

muse-glimmer saca 16 de 16 en código ejecutable, el mejor de la máquina, y transcribe manuscrito mejor que nadie: 42 palabras correctas frente a las 31 del titular. Y como agente necesita 117 llamadas y 13 minutos para quedarse en 12 de 15, donde el titular tarda 2,9 minutos.

Ese contraste no lo habría visto ninguno de los dos bancos por separado, y es el argumento para mantener los dos. Escribir bien y comportarse bien son capacidades distintas, y el mismo modelo puede tener una sin la otra.

Hay una lectura más que me dolió: apex I-Quality es el mismo modelo que mi titular con mejor cuantización y 5 GB más de VRAM, y falla la única tarea que discrimina. Enlaza con la tercera regla de la primera parte: más bits no compran criterio.

Y hubo un cuarto candidato que ni llegó a puntuar. apex I-Balanced pesa 25,6 GB, y con la caché de 128k encima no cabe en las dos tarjetas por encima de 64k. Bajar el contexto para meterlo era pagar con lo único que se nota a diario, así que se cayó antes de empezar. No es una derrota por puntuación, es una restricción física, y es el recordatorio de que en una máquina de 32 GB el tamaño sigue mandando aunque la arquitectura mande más.

Y el hallazgo que más me ha cambiado el día a día

No tiene nada que ver con qué modelo elijas, y es la corrección más útil de toda la ronda. Tenía una factura fotografiada con la columna de totales cortada por el borde; la respuesta correcta es «no se lee». Preguntando así:

«Extrae estos diez campos en JSON. Si algo no se lee, pon ILEGIBLE.»

el modelo se inventaba el total. Preguntando así:

«¿Cuál es el total? Si está cortado, dilo. No adivines.»

el mismo modelo admitía que no se leía. Los cuatro que probé, igual.

La explicación es sencilla y vale para cualquier modelo: un esquema con diez huecos es una invitación a rellenar diez huecos. Si le pides una tabla, te devuelve una tabla completa, aunque tenga que inventarse la última celda. A un modelo de visión, pregúntale de una en una.

Cómo le puse ojos a un modelo que no los tenía

Este es el apaño del que más partido he sacado, y es sorprendentemente sencillo.

Mi titular, qwen3.6-apex-icompact, es un modelo de texto: se empaquetó a partir del GGUF de pesos y punto. Pero en el mismo repositorio de origen había un segundo fichero, el mmproj.gguf —861 MB—, que es el proyector de visión: la pieza que convierte una imagen en algo que el modelo de lenguaje puede leer. Estaba ahí, sin usar, porque quien empaquetó la versión de texto lo dejó fuera.

Se le añade con un Modelfile de dos FROM, uno para los pesos y otro para el proyector:

FROM ~/gguf/Qwen3.6-35B-A3B-APEX-I-Compact.gguf
FROM ~/gguf/mmproj-apex.gguf

Y ya ve. Había dos incidencias abiertas en Ollama que desaconsejaban hacerlo —una de ellas menciona literalmente la arquitectura de este modelo—, pero ambas están cerradas desde marzo de 2026 y la sintaxis funciona. Lo que cuesta:

Sin visión Con visión
VRAM a 128k 21,5 GB 21,7 GB
Generación 119 tok/s 120 tok/s

200 MB y ningún coste de velocidad. Sobre una factura del banco de pruebas empata con qwen3-vl:30b-a3b, que era mi modelo de visión dedicado: mismo emisor, mismo CIF —validado con el dígito de control—, mismos importes, y los dos interpretan bien una retención de IRPF restando del total.

Y lo que resuelve de verdad no es la puntuación: es tener un único modelo residente para agente, código y facturas, en vez de cargar y descargar veinte gigas cada vez que cambio de tarea. En una máquina con 32 GB repartidos en dos tarjetas, eso vale más que casi cualquier punto de benchmark.

Dicho con honestidad: es una factura, no una ronda. Por eso mantuve qwen3-vl de respaldo hasta tener más muestras. Cuando llegaron, en la ronda siguiente, sacó 6 de 15 en agente y 7 falsos positivos de 48 en el cribado, así que se fue.

Con qué me he quedado para el día a día

Después de siete rondas y 31 modelos medidos, tengo cinco instalados. Los otros diez —216 GB— los borré. No es que fueran malos: es que ninguno gana en nada a estos cinco, y un catálogo que lista modelos que nunca elegirías no es un catálogo, es un almacén.

Para qué Modelo GB tok/s
Titular: agente, código y visión qwen3.6-apex-vision 21,7 120
Residente rápido, tareas menores lfm2.5:8b 5,2 211
Manuscrito y código, de uno en uno muse-glimmer:30b 18 24,5
Búsqueda semántica bge-m3, nomic-embed-text-v2-moe 2,2
Cribado paleográfico ninguno local, va a la nube

El titular es qwen3.6-apex-vision: la variante I-Compact de un 35B con 3B activos, con el proyector de visión injertado, con el razonamiento apagado y con 128k de contexto. Es el que está cargado siempre y con el que trabajo. Las tres condiciones importan: sin apagar el razonamiento son 10 de 25 en vez de 25 de 25, y con 64k de contexto pierde la pregunta original a mitad de sesión.

Los otros dos de texto tienen un papel muy delimitado. lfm2.5:8b es para lo instantáneo, y solo en inglés y código: su castellano fue el peor de las tres primeras rondas. Y muse-glimmer no es un agente: se le pide una cosa concreta —transcribe esta página, arregla esta función— y se vuelve al titular para trabajar.

Dejé fuera a propósito al que había sido titular hasta agosto, qwen3-coder:30b-a3b. En la primera parte de este artículo aparece recomendado para agente y código, y era la decisión correcta con los datos de entonces. Con el banco agéntico bien montado saca 10 de 25. Esa es exactamente la caducidad del error número 7, aplicada a mí mismo.

Hasta dónde llega una máquina así, y hasta dónde no

Toca decir lo que ninguna de estas tablas dice por sí sola, y que conviene tener claro antes de gastarse el dinero: una instalación local de este tipo no alcanza a un modelo frontera. Ni la mía ni una del doble de precio. Lo que hace un Opus o un GPT 5.6 con un problema difícil no lo replicas en casa con dos tarjetas de gama media, y no es cuestión de esperar dos meses a que salga el modelo siguiente.

No lo digo por intuición. En la prueba del apartado 6, sobre el corpus real, los cuatro modelos locales que probé encontraron cero de las dos páginas que había que encontrar. Un modelo de nube, sobre el mismo material y con el mismo prompt, encontró las dos. Y en la primera parte está el otro lado de lo mismo: con letra manuscrita, lo local no es que falle, es que se inventa datos verosímiles.

Dicho eso, la conclusión no es «no montes nada». Es que el criterio para decidir qué pasa por tu máquina y qué se va a la nube no es el tipo de tarea, es cuánto te cuesta detectar un error. Donde puedas comprobar el resultado en dos segundos, lo local sale rentable. Donde el error se te cuele sin que lo veas, paga el modelo bueno.

Y hay bastante trabajo del primer tipo:

  • Privacidad. Documentos de clientes, datos personales, contratos, historiales. Con el RGPD delante, «esto no sale de mi red» deja de ser una preferencia técnica y pasa a ser un argumento comercial. Es probablemente la razón número uno para tener la máquina.
  • Volumen barato. Coste marginal cero y sin contador. Puedes lanzar quinientas peticiones a las tres de la mañana para reprocesar un archivo entero sin pensar en la factura, algo que con API de pago te lo piensas dos veces.
  • Tareas acotadas y repetitivas. Clasificar, etiquetar, resumir, reescribir, extraer campos de documentos impresos, generar primeras versiones. Cosas donde el listón es «mejor que hacerlo a mano» y no «mejor que un humano experto».
  • Filtro previo. Lo local criba y descarta lo evidente; a la nube solo le mandas lo que sobrevive. Se paga bastante menos y funciona bien siempre que el filtro se equivoque hacia dejar pasar de más.
  • Estabilidad. El modelo no cambia bajo tus pies. Quien haya visto cómo se le mueven los resultados cuando el proveedor actualiza el modelo por debajo sabe lo que vale esto, y enlaza directamente con el error número 7: aquí la fecha de caducidad de tus mediciones la pones tú.
  • Trabajar sin red. Funciona igual con la conexión caída, y ninguna de estas tareas se para porque un proveedor tenga una incidencia.

Resumido en una frase: lo local no es un sustituto barato del modelo caro, es otra herramienta. Sirve para lo que se puede verificar barato, para lo que no debe salir de casa y para lo que se hace mil veces. Para el problema difícil de verdad, sigue haciendo falta el modelo grande, y no pasa nada por reconocerlo.


Lo que me llevo

El artículo anterior decía que medir sale barato. Sigue siendo verdad. Le añado la letra pequeña:

Un experimento mal montado no falla: aprueba. Te da un número redondo, coherente con lo que esperabas, y por eso no lo miras dos veces. Los siete errores de aquí arriba tienen algo en común: ninguno se manifestó como un fallo. Todos llegaron disfrazados de buena noticia —un 30/30, un 100 %, un modelo que mejora con el esfuerzo alto, un cribado impecable—.

Y va junto con lo otro: la máquina no te va a dar lo que da un modelo frontera, pero sí te da lo que puedes comprobar barato, lo que no debe salir de tu red y lo que se repite mil veces. Con eso ya se paga.

Así que la regla final no es sobre modelos ni sobre hardware:

Desconfía especialmente del resultado que te gusta. El que te decepciona ya lo vas a revisar tú solo.

Si has llegado hasta aquí sin leer la primera parte, ahí están los números que salieron de todo esto: lo que aprendí midiendo 25 modelos de IA en local con dos GPU, con las tablas completas al final.

Y si lo que quieres es montarlo tú, la tercera parte es la receta: cómo quedó montado el servidor con Ollama y OpenCode, con los ajustes que importan y los fallos que no parecen fallos.


Todo esto ocurrió sobre una máquina concreta: dos RTX 5060 Ti de 16 GB con modelos locales servidos a un cliente agéntico, entre agosto y septiembre de 2026. Los identificadores fiscales y los datos personales de los documentos citados están alterados; las facturas y los padrones son reales y por eso no se publican. Los errores, míos, y creo que bastante comunes.