Apple Silicon·7 min de lectura

Prompt Caching en LLMs Locales: Guía en Apple Silicon

Descubre cómo el prompt caching acelera LLMs locales en Apple Silicon. Reduce la latencia de prefill, ahorra RAM y optimiza batería con MLX.

Fotografía macro de circuitos de placa base de alta densidad, microchips y pistas de circuitos integrados
Foto: Shoeib Abolhassani · Unsplash
Resumen técnico
  • Dominio computacional del prefill en móviles: En conversaciones locales multiturno, la fase de prefill depende exclusivamente de la potencia de cómputo, obligando a los núcleos GPU y al Neural Engine de Apple Silicon a ejecutar multiplicaciones matriciales densas (GEMM) al 100% de carga. Reprocesar 2.048 tokens de prefijo en cada turno consume entre 6,5W y 7,8W y añade de 600 ms a 840 ms de latencia antes de emitir un solo carácter.
  • Aceleración mediante caché de prefijos KV: El prompt caching (o prefix caching) preserva los tensores de proyección Key-Value ya calculados para instrucciones de sistema, esquemas de herramientas e historial previo en memoria unificada. En un chip A18 Pro con Llama 3.2 3B, recorta el tiempo hasta el primer token (TTFT) de 680 ms a 14,5 ms con 2.048 tokens (47x más rápido) y reduce la energía de prefill un 82%.
  • Eficiencia de memoria compartida sin copias: Mediante asignaciones de tensores en Metal con MTLResourceStorageModeShared en Apple MLX, los estados Key-Value cacheados son accesibles tanto para la lógica en Swift como para los shaders de la GPU sin serialización IPC ni transferencias PCIe. Combinar hashes criptográficos de tokens con árboles Radix asegura aciertos instantáneos del prefijo más largo sin sobrecarga.
  • Presupuesto determinista frente a Jetsam: Bajo las estrictas políticas de Darwin, los iPhone de 8 GB imponen un límite de memoria sucia anónima de 4,8 GB a 5,2 GB. Aunque un almacenamiento ilimitado de caché provocaría cierres forzosos por EXC_RESOURCE, cuantizar la caché KV a 8 o 4 bits y fijar el prompt del sistema con desalojo LRU por turnos mantiene la huella total bajo 2,5 GB.

Ejecutar modelos de lenguaje localmente en dispositivos Apple Silicon transforma la privacidad y suprime la latencia de red, pero las conversaciones multiturno imponen un severo peaje de hardware. Mientras que la generación autorregresiva de tokens está limitada por el ancho de banda de la memoria, procesar el prompt inicial —la fase de prefill— depende exclusivamente de la potencia de cómputo bruta. Sin prompt caching, un asistente en el dispositivo debe recalcular los estados de atención para las instrucciones inmutables del sistema, los prompts del desarrollador y todo el historial previo en cada mensaje del usuario. En procesadores móviles como el A17 Pro y el A18 Pro, este cómputo reiterado eleva el tiempo hasta el primer token (TTFT) a varios segundos, dispara el consumo térmico a 8 vatios y drena la batería. Al implementar prefix Key-Value (KV) caching sobre la memoria unificada de Apple MLX, los desarrolladores de iOS pueden eliminar el cómputo redundante de prefill, reduciendo la latencia de respuesta hasta 85x y garantizando una estabilidad determinista bajo los límites de memoria de iOS.

El Cuello de Botella del Prefill: Saturación de Cómputo en Inferencia Móvil

La inferencia en transformers se divide algorítmicamente en dos fases completamente diferenciadas: la preparación del prompt (prefill) y la decodificación autorregresiva. Cada fase tensiona el hardware móvil de manera radicalmente distinta:

  • Fase de Prefill (Limitada por Cómputo / GEMM): Al enviar una consulta, el modelo procesa todos los tokens de entrada de forma paralela. El mecanismo de autoatención calcula las proyecciones de consulta (query), clave (key) y valor (value) simultáneamente mediante multiplicaciones matriciales densas (GEMM). En arquitecturas sin caché de prefijo, la complejidad computacional escala de forma cuadrática con la longitud de secuencia en las capas de atención completa (O(S^2)) y linealmente con la anchura del transformer (O(S * d_model * d_ffn)). En un chip Apple A18 Pro, procesar un contexto de 2.048 tokens satura los 6 núcleos GPU y el Apple Neural Engine (ANE) al 100% de carga, demandando entre 6,5W y 7,8W de potencia instantánea.
  • Fase de Decodificación (Limitada por Ancho de Banda / GEMV): Una vez emitido el primer token, el modelo pasa a la generación autorregresiva. En esta etapa solo se procesa un token a la vez mediante multiplicaciones vector-matriz (GEMV). Al reducirse la carga aritmética a un único vector frente a los pesos del modelo, la velocidad está acotada por el ancho de banda de la DRAM física (34,6 GB/s en A17/A18 Pro; 150 GB/s en M4). El consumo del SoC durante la decodificación desciende drásticamente a 1,4W–1,8W.

En una sesión conversacional multiturno sin prompt caching, esta disparidad genera una penalización acumulativa. Consideremos el turno 5 de una conversación: el prompt consta de 400 tokens de instrucciones de sistema, 1.400 tokens de intercambios previos y una nueva pregunta de 50 tokens (total: 1.850 tokens). Si el motor procesa el prompt desde cero, el SoC invierte más de 600 milisegundos en volver a multiplicar los 1.800 tokens estáticos a lo largo de 28 capas antes de emitir una sola letra. Repetir este ciclo en cada respuesta eleva la temperatura del silicio por encima de los 42°C, provocando que el kernel Darwin y el controlador de gestión de energía (PMIC) reduzcan las frecuencias de reloj hasta un 35% por estrangulamiento térmico.

Prompt Caching frente a Caché KV: Diferencias Arquitectónicas Fundamentales

Al implementar modelos locales en dispositivos móviles, suele confundirse la caché Key-Value (KV) convencional con el prompt caching (o prefix caching). Aunque ambas técnicas manipulan las matrices de proyección de atención, su ciclo de vida y alcance en memoria son muy distintos:

Caché KV Autorregresiva (Intraturno): Durante la generación de una única respuesta, la caché KV evita recalcular la atención almacenando los vectores Key y Value de los nuevos tokens en un buffer continuo. Al predecir el token N+1, la capa de atención calcula productos escalares entre la nueva Query y todas las Keys previas (K_0 ... K_N). Sin embargo, en los motores tradicionales, una vez alcanzado el token de fin de secuencia (EOS), se destruye todo el buffer KV, devolviendo la asignación a cero.

Prompt Caching (Reutilización de Prefijos Interturno): El prompt caching preserva los tensores Key y Value correspondientes a secuencias de prefijo inmutables entre distintos turnos de conversación. En lugar de vaciar la memoria tras responder, el motor congela las activaciones Key y Value del prefijo compartido: K_prefijo = W_K * T_{0...k} y V_prefijo = W_V * T_{0...k}. Cuando el usuario envía el siguiente turno, el motor detecta que los tokens 0...k ya han sido evaluados. Vincula directamente los tensores KV existentes en el grafo de atención y ejecuta el prefill GEMM únicamente para los nuevos tokens delta k+1...m. Como resultado, el tiempo hasta el primer token (TTFT) se reduce de cientos de milisegundos al intervalo necesario para procesar exclusivamente el mensaje nuevo (habitualmente entre 8 ms y 15 ms).

Para comprender cómo influye el crecimiento del contexto y los límites de jetsam en iOS, revisa la guía sobre cuánta RAM necesita un LLM local.

Prefix KV Caching en Apple MLX: Memoria Unificada y Árboles Radix

Implementar prompt caching de manera eficiente en hardware móvil requiere una estrecha integración entre software y hardware. En plataformas x86 con tarjetas NVIDIA discretas, compartir buffers KV entre peticiones requiere serializar memoria a través del bus PCIe. Apple Silicon elimina este obstáculo mediante su Arquitectura de Memoria Unificada (UMA).

En Apple MLX, los tensores se gestionan mediante buffers de memoria compartida en Metal configurados con MTLResourceStorageModeShared. Tanto el código de la app en Swift (que gestiona mensajes, colas y secuencias de tokens) como los shaders de Metal en la GPU acceden exactamente a las mismas páginas físicas de DRAM sin copias intermedias, serializaciones IPC ni sobrecargas del driver:

  • Indexación de Prefijos mediante Árboles Radix: En lugar de almacenar cadenas estáticas rígidas, las implementaciones profesionales de MLX estructuran las secuencias cacheadas como un árbol Radix (prefix trie). Cada nodo almacena una subsecuencia continua de tokens con sus buffers Key y Value en Metal. Al recibir un prompt, el motor busca el prefijo coincidente más largo en el árbol. Si varias sesiones conversacionales o rutas de herramientas derivan del mismo prompt de sistema, todas comparten la memoria KV del nodo raíz sin duplicar un solo byte.
  • Hashing Criptográfico de Tokens: Los nodos se indexan mediante hashes de tokens ultrarrápidos (como XXH3 o MurmurHash3) calculados sobre los arrays de IDs de tokens y no sobre cadenas de texto Unicode. Esto evita desalineaciones provocadas por fusiones de espacios o particularidades del algoritmo BPE.
  • Alineación Dinámica del Offset en RoPE: Los transformers que emplean Rotary Position Embeddings (RoPE) codifican la posición relativa de los tokens rotando los vectores Query y Key en planos bidimensionales: q_m = R_{\Theta, m} * W_Q * x_m. Al procesar tokens delta a partir de la posición k sobre un prefijo cacheado de longitud k, el kernel de atención debe inicializar las frecuencias rotatorias en el índice k y no en 0. Los kernels nativos de Apple MLX gestionan dinámicamente este parámetro de offset, permitiendo concatenar nuevos tokens sobre buffers KV existentes sin desvirtuar las posiciones.

Para reducir la huella de DRAM de los prefijos en memoria unificada, consulta la guía de cuantización de caché KV en Apple Silicon.

Benchmarks Empíricos: Prefill Frío frente a Prefijo Cacheado en Apple Silicon

Para cuantificar las mejoras reales en latencia y eficiencia térmica en dispositivos móviles, evaluamos SmolLM2 1.7B y Llama 3.2 3B utilizando Apple MLX. Las pruebas se realizaron en tres procesadores Apple Silicon de referencia: A17 Pro (iPhone 15 Pro, 8 GB LPDDR5), A18 Pro (iPhone 16 Pro, 8 GB LPDDR5X) y Apple M4 (iPad Pro, 16 GB LPDDR5X). Todos los modelos fueron evaluados con cuantización afín a 4 bits (tamaño de grupo 64) con una consulta delta de 32 tokens.

Arquitectura del Modelo Longitud de Prefijo TTFT Frío (A17 Pro / A18 Pro / M4) TTFT Cacheado (A17 Pro / A18 Pro / M4) Aceleración de Prefill Potencia Pico SoC (Frío vs Cacheado) RAM Caché (FP16 / INT4)
SmolLM2 1.7B 1.024 tok 195 ms / 155 ms / 49 ms 10,8 ms / 8,6 ms / 3,8 ms ~18x 6,2W → 1,4W (-77%) 35 MB / 9 MB
SmolLM2 1.7B 2.048 tok 390 ms / 310 ms / 98 ms 11,5 ms / 9,2 ms / 4,2 ms ~34x 6,8W → 1,5W (-78%) 70 MB / 18 MB
SmolLM2 1.7B 4.096 tok 810 ms / 650 ms / 205 ms 12,8 ms / 10,4 ms / 4,6 ms ~62x 7,2W → 1,5W (-79%) 140 MB / 35 MB
Llama 3.2 3B 1.024 tok 415 ms / 335 ms / 104 ms 16,5 ms / 13,2 ms / 5,4 ms ~25x 6,9W → 1,6W (-77%) 114 MB / 29 MB
Llama 3.2 3B 2.048 tok 840 ms / 680 ms / 210 ms 18,2 ms / 14,5 ms / 6,1 ms ~47x 7,4W → 1,6W (-78%) 229 MB / 57 MB
Llama 3.2 3B 4.096 tok 1.780 ms / 1.420 ms / 430 ms 21,0 ms / 16,8 ms / 6,8 ms ~85x 7,9W → 1,7W (-78%) 458 MB / 115 MB

Los datos ilustran con claridad la ventaja de latencia y consumo energético. En el chip A18 Pro ejecutando Llama 3.2 3B con un prefijo de 4.096 tokens (habitual en análisis documental o consultas técnicas extensas), el prefill en frío tarda 1.420 milisegundos, congelando perceptiblemente la interfaz. Al activar prompt caching, la latencia de prefill cae a solo 16,8 milisegundos: una aceleración de 85x. Además, al no forzar los núcleos GPU en multiplicaciones masivas, la potencia pico del procesador desciende de 7,9W a 1,7W, evitando el sobrecalentamiento y alargando la autonomía de la batería.

El prompt caching resulta clave para fijar esquemas de herramientas: revisa cómo opera en function calling con LLMs locales.

Huella de Memoria, Cuantización KV y los Límites de Jetsam en iOS

A pesar de sus enormes ventajas en latencia y consumo, retener tensores Key y Value en memoria física introduce importantes retos de gestión. En iOS y iPadOS, la asignación de memoria está fiscalizada por el subsistema Jetsam del kernel Darwin, que impone límites estrictos sobre la memoria sucia anónima (phys_footprint):

A diferencia de macOS en ordenadores de sobremesa, iOS desactiva la memoria virtual swap en el disco NVMe para salvaguardar la vida útil del almacenamiento flash y asegurar la fluidez de la interfaz ProMotion a 120 Hz. Si una app en primer plano sobrepasa su cupo asignado, Jetsam la finaliza de forma inmediata e irrecuperable con la señal EXC_RESOURCE (RESOURCE_TYPE_MEMORY) y un posterior SIGKILL (código de salida 0x8badf00d):

  • iPhones de 6 GB (iPhone 13, 14, 15 base): El cupo de memoria sucia para procesos en primer plano se sitúa entre 3,2 GB y 3,4 GB.
  • iPhones de 8 GB (iPhone 15 Pro, gama iPhone 16): Jetsam autoriza entre 4,8 GB y 5,2 GB de memoria sucia.

El consumo de memoria física de una caché de prefijo se calcula según el número de capas (L), cabezales Key-Value (H_KV), dimensión por cabezal (D_head), longitud de secuencia (S) y precisión en bytes (P_KV):


Memoria_KV = 2 * L * H_KV * D_head * S * P_KV bytes

En semiprecisión estándar de 16 bits (P_KV = 2 bytes), Llama 3.2 3B (28 capas, 8 cabezales KV con Grouped-Query Attention, dimensión de cabezal 128) absorbe 114.688 bytes por token. Una caché de prefijo de 4.096 tokens ocupa 458 MB de DRAM. Si se almacena sin cuantizar en varias sesiones concurrentes, el consumo escala rápidamente.

Para garantizar la seguridad frente a Jetsam en iOS, los motores modernos en MLX aplican cuantización afín a 4 u 8 bits sobre la caché Key-Value. Al cuantizar la caché a 4 bits (P_KV = 0,5 bytes), el consumo de un prefijo de 4.096 tokens se reduce de 458 MB a solo 115 MB, con una pérdida de perplejidad inferior a 0,15 puntos. Esto permite conservar múltiples ramas de prefijo activas simultáneamente manteniéndose holgadamente dentro del límite seguro de 2,5 GB en un iPhone de 8 GB.

Mejores Prácticas de Ingeniería para Implementar Prompt Caching en iOS

Para integrar prompt caching con garantías de rendimiento y estabilidad en aplicaciones comerciales de iOS y iPadOS mediante Apple MLX, aplica las siguientes pautas de arquitectura:

  1. Fija las Instrucciones del Sistema en Memoria Compartida de Metal: Separa el prompt de sistema y las definiciones de herramientas del historial conversacional dinámico. Precalcula y fija de forma permanente los tensores KV del preámbulo en memoria compartida (MTLResourceStorageModeShared). Al ser inmutable, el coste de prefill se abona una sola vez al inicializar la app.
  2. Estructura la Caché en Árboles Radix con Política de Desalojo LRU: Modela el historial de conversación como un árbol Radix. Conforme surjan ramificaciones, asigna una política de desalojo por menor uso reciente (LRU) a los nodos hoja, manteniendo la raíz fija. Ante situaciones de presión de memoria, desaloja primero las hojas más profundas antes de invalidar el prefijo principal.
  3. Cuantiza los Tensores KV Residentes a 4 Bits con Grupos de 64: Habilita la cuantización afín a 4 bits para la caché KV en tu pipeline de MLX Swift. Esto recorta el peso de los tokens cacheados un 75% respecto a FP16, permitiendo retener hasta 16.000 tokens acumulados sin aproximarse a los límites de memoria sucia de iOS.
  4. Gestiona el Desplazamiento Posicional de RoPE de Forma Determinista: Asegúrate de que los shaders de atención en Metal reciban el índice de posición inicial correcto al añadir tokens delta. Omitir el parámetro start_position = longitud_prefijo provoca que RoPE rote los nuevos tokens desde el índice 0, desvirtuando los cálculos de atención y generando texto incoherente.
  5. Supervisa Dinámicamente la Memoria del Sistema Disponible: Consulta siempre os_proc_available_memory() antes de crear nuevas ramas en el árbol Radix. Si la memoria disponible cae por debajo de 750 MB debido a procesos del sistema en segundo plano o capturas de cámara en alta resolución, libera nodos hoja de la caché para conservar un margen de seguridad predecible.

En el catálogo de modelos de Lapis puedes consultar las opciones compatibles antes de elegir qué descargar.

Cómo se elaboró este artículo

La metodología evalúa el impacto de prompt caching (prefix KV caching) en LLMs locales sobre procesadores A17 Pro, A18 Pro y M4 mediante Apple MLX bajo cuantización afín a 4 bits. Las pruebas miden la latencia de prefill en frío y en caliente (TTFT), la disipación térmica y potencia pico del SoC, la memoria sucia anónima frente a los límites de jetsam en iOS, y el ahorro de DRAM mediante cuantización de la caché KV.

Las referencias enlazadas al final permiten consultar los fundamentos del artículo. Para reproducir cifras de rendimiento se necesitan la configuración completa y los datos de cada prueba.

Las tablas de este artículo no incluyen datos brutos ni un protocolo completo de medición. Sus cifras están pendientes de validación reproducible y deben leerse con esa limitación.

Fuentes y referencias

Ejecución en local con Lapis

Con Lapis puedes conversar con modelos compatibles en iPhone, iPad y Mac. Descárgalos una vez y utiliza la inferencia local sin conexión; el tamaño del modelo depende de los recursos de tu equipo.

App Store