Caché de prompts en Ollama — dónde editas decide la factura

Caché de prompts en Ollama — dónde editas decide la factura

Seis sondas, una VM nueva: una repetición exacta reevaluó 1,539 tokens en 0.2 s frente a 75.6 s en frío — y una palabra movida a mitad del prompt facturó 49 s.

HUMANpor @msvram40m7 min de lectura

verify: seis sondas, una VM nueva, seed 42 · temp 0 · ollama 0.40.16 · recibos abajo, log promptcache-2026-11-12.log

segundos de prompt-eval · prompt de 1,539 tokens · qwen3:4b · 2 vCPU · pregunta en frío = la línea del 100% línea base en frío 75.6 s 75.6 sP1 frío 0.2 sP2 repetición 1.4 sP3 sufijo 49.2 sP4 edición al medio 79.9 sP5 reordenar 4.2 sP6 casi al final

Fig 1 — seis sondas, un prompt. Las barras atenuadas son el recibo: una edición a mitad del prompt devolvió el 65% de la factura en frío, y reordenar cobró más que la propia carga en frío.

¿Qué guarda realmente la caché de prompts de ollama?

No tu texto. Cuando ollama evalúa un prompt calcula un tensor KV por cada token — la huella de atención de ese token frente a todos los anteriores — y el runner conserva esos tensores en RAM mientras el modelo siga cargado. Un prompt nuevo se coteja con ese almacén token por token, desde el frente. Cada token que continúa exactamente el prefijo viejo es gratis. El primer token que difiere es la frontera: todo desde ahí hasta el final se relee a precio completo. Es la misma residencia KV que cubrió nuestra pieza KV-cache para el timing de descarga — la caché que sirve velocidad es la caché que retiene RAM (y por eso keep_alive decide cuánto sobrevive cada cual — la pieza de la ventana de contexto tiene la parte del dimensionado de esa factura).

prefijo acertado — tokens gratis. Bytes idénticos desde la posición 0 no cuestan nada en re-proceso. 0.2 s para 1,539 tokens, medido.
primera divergencia — la frontera. Un token cambiado invalida cada token después de él. No hay crédito parcial hacia atrás; la cola siempre refactura.
residencia — keep_alive. La caché vive lo que vive el modelo. Descarga el modelo y el descuento muere con él; fija keep_alive si tu bucle habla con pausas.

¿Por qué la repetición exacta costó 0.2 segundos?

La sonda: un prompt de 1,539 tokens — ocho secciones numeradas de hechos de logs de fixture, luego una pregunta — preguntado en frío sobre una VM nueva. El motor leyó los 1,539 tokens a 20.4 tok/s y facturó 75.6 s de evaluación de prompt. La pregunta idéntica, reenviada con el modelo aún residente: 0.2 s. Mismo endpoint, mismo cuerpo, nada conmutado — ollama hace esto sin flag, sin cache: true, sin conjuro de calentamiento. Llevas tiempo cobrando el descuento cada vez que re-preguntas; este post va de no devolverlo.

curl http://localhost:11434/api/generate -d '{
  "model": "qwen3:4b",
  "prompt": "<your 1,500-token prompt>",
  "keep_alive": "45m",
  "think": false,
  "options": {"seed": 42, "temperature": 0, "num_predict": 128}
}'

verify: P1 frío 75.6 s → P2 repetición 0.2 s, cuerpo de sonda idéntico byte a byte, modelo residente · promptcache-2026-11-12.log

Dónde editas decide qué pagas

Conservamos el cuerpo de 1,539 tokens y movimos exactamente una palabra, de tres formas. Cambia una palabra en la última frase: 4.2 s — la cabeza compartida sobrevivió, solo la cola se releyó. Añade una frase después de la pregunta: 1.4 s — acierto casi total, cinco tokens nuevos facturados al margen. Cambia una palabra en el hecho 41 de 96, a mitad de cuerpo: 49.2 s — el 65% de la factura en frío, pagado por reubicar un adjetivo. La caché tiene memoria de elefante y perdón de aduanero: lo recuerda todo, y un solo formulario erróneo anula todos los sellos de la libreta — para todo lo que va detrás del formulario erróneo.

sondaqué cambióprompt-evalpregunta completavs frío
P1 fríonada — VM nueva, primera pregunta75.6 s111.8 sreferencia
P2 repeticiónnada — cuerpo idéntico0.2 s26.6 s370× más rápido
P3 sufijo+1 frase después de la pregunta1.4 s27.2 s54× más rápido
P4 edición al medio1 palabra en el hecho 41/9649.2 s75.2 s65% del frío
P5 reordenarsecciones 1–2 ↔ 7–8 intercambiadas79.9 s135.5 speor que en frío
P6 casi al final1 palabra en la última frase4.2 s34.0 s18× más rápido

prompt de 1539 tokens · prompt-eval es la factura de relectura; la «pregunta completa» añade la generación de 128 tokens, que se mantuvo ~25–29 s todo el tiempo.

¿Por qué reordenar factura más que una carga en frío?

Porque la frontera está en el token ~1. Intercambia las dos primeras secciones por las dos últimas y el prefijo compartido queda vacío — el match muere de inmediato y cada token refactura. Pero P5 facturó 79.9 s, no 75.6 s: 5.7% por encima de la carga en frío por la que tiró el descuento. No vamos a fingir que atrapamos al culpable — la nota honesta es que la pasada de generación también corrió 2.1× más lenta en esa sonda (55.4 s contra 25.5–29.4 s de cada otra pregunta, mismo seed, mismo presupuesto). El estado caliente del servidor se suma a la factura de formas que un diagrama de caché no muestra; la pieza de determinismo ya se topó con este testigo con un token volcado a temp 0. Lo que sí podemos afirmar como recibo: un prompt reordenado no es un «mismo prompt, otro orden». Es una factura nueva de fábrica, más ruido.

La lista de correcciones

síntomaqué está pasandola corrección
cada petición se siente como una carga en fríoel modelo se descarga entre preguntas — la caché muere con élsube keep_alive; revisa load_duration en la respuesta
ediciones minúsculas del prompt, latencia enormela edición cae a mitad de prompt; la cola refactura desde la divergenciamueve la parte volátil a la cola del prompt
la «misma petición» factura distinto en cada runel orden o el boilerplate derivó entre peticionescongela la cabeza byte a byte; haz diff de los prompts, no de las vibras
recibo · seis sondas, una VM nueva (qwen3:4b · ollama 0.40.16 · 2 vCPU · prompt 1,539 tok)
P1 cold-full-ask      prompt_eval 75,646 ms   (1,539 tok · 20.4 tok/s)  wall 111.8 s
P2 exact-repeat       prompt_eval    203 ms                             wall  26.6 s
P3 suffix-only        prompt_eval  1,402 ms   (+5 tok)                  wall  27.2 s
P4 mid-edit-kill      prompt_eval 49,176 ms   (1 word, fact 41/96)      wall  75.2 s
P5 reorder-full-miss  prompt_eval 79,878 ms   (secs 1–2 ↔ 7–8)          wall 135.5 s
P6 edit-near-end      prompt_eval  4,189 ms   (1 word, last sentence)   wall  34.0 s

Un prompt. Seis facturas, de 0.2 a 79.9 segundos — un rango de 370× sin cambiar ningún ajuste ni conmutar ningún flag. La caché siempre estuvo encendida. La única variable fue dónde nos atrevimos a editar.

última prueba 2026-11-12

qwen3:4b · 2,497,293,931 B · sha256 359d7dd4…74e7 · ollama 0.40.16 · una VM Arch nueva, 2 vCPU — bench CPU, cero declaraciones VRAM