Gemma 4 26B en ~2 GB de RAM: el runtime en Swift que streamea los experts desde el SSD

Gemma 4 26B en ~2 GB de RAM: el runtime en Swift que streamea los experts desde el SSD

En abril publicamos una guía para correr Gemma 4 en una Mac con Ollama, y el veredicto sobre la variante 26B MoE fue directo: con 24 GB de memoria unificada el modelo técnicamente entra, pero deja a macOS al borde del colapso, y lo que realmente quieres son 32 GB o más. Era correcto en ese momento, y era correcto por un supuesto que todos compartimos: los weights tienen que vivir en RAM.

Andrey Mikhaylov publicó un runtime que rompe ese supuesto. TurboFieldfare es un motor en Swift + Metal que corre el checkpoint instruction-tuned de Gemma 4 26B-A4B manteniendo alrededor de 2 GB residentes. No es una cuantización más chica ni una variante destilada: es el mismo checkpoint de 14.3 GB, streameado desde el SSD sobre la marcha. Mide 5.1–6.3 tok/s en una MacBook Air M2 de 8 GB y 31–35 tok/s en una M5 Pro.

Antes de que te entusiasmes: esto necesita macOS 26, Metal 4 y Swift 6.2+, más unos 15 GB de disco libre para la descarga y el repack. Si estás en macOS 15 o anterior, este artículo es un adelanto, no una lista de tareas. Los 8 GB se refieren a la RAM total del sistema, y la Air M2 de 8 GB es la configuración más baja que el autor validó.


Por qué funciona: el A4B del nombre

Gemma 4 26B-A4B es un modelo Mixture-of-Experts. Veintiséis mil millones de parámetros totales, pero solo unos cuatro mil millones están activos para cualquier token dado: un router elige un subconjunto chico de experts por capa y el resto queda quieto.

Todos los runtimes mainstream cargan los 26B igual, porque no sabes de antemano qué experts va a necesitar un token, y frenar la GPU para ir a buscarlos es peor que pagar el costo de RAM. TurboFieldfare hace la apuesta contraria: paga el I/O, ahorra la RAM.

Lo que queda residente:

  • El shared core — 1.35 GB de weights que todos los tokens tocan: embeddings, attention, los routers mismos.
  • El KV cache en FP16 — buffers circulares acotados para las 25 capas de sliding-window, almacenamiento lineal para las 5 capas de full-attention.

Esos son tus ~2 GB. Todo lo demás —los weights de los experts, la abrumadora mayoría del checkpoint— vive en el SSD y se busca solo cuando un token efectivamente rutea hacia él.

El loop por token: Metal calcula attention y las decisiones del router desde los weights residentes, la CPU convierte esas decisiones en un plan de fetch, llamadas pread en paralelo acotado traen los experts faltantes directo a buffers visibles para Metal, y Metal combina las salidas shared y routed. Un LFU cache de 16 slots por capa absorbe las repeticiones.

Por qué pread y no mmap

Esta fue la pregunta que apareció de inmediato en Hacker News, y es la correcta: llama.cpp lleva años haciendo memory-mapping de weights, y el page cache del sistema operativo supuestamente resuelve exactamente esto.

La respuesta del autor, en el thread: un expert frío cuesta unos 2.8 ms con pread explícito en paralelo acotado, contra unos 10 ms cuando dejas que lo maneje mmap del sistema. De punta a punta, en la misma máquina, eso fue la diferencia entre 4 tok/s y 0.50 tok/s. Son números self-reported por el autor, pero el mecanismo es plausible: los faults de mmap se serializan y el kernel no tiene idea de qué experts vas a necesitar, mientras que el router te avisa con una capa de anticipación y puedes emitir las lecturas en paralelo.

El otro dato que hace funcionar el diseño: el 40% de los experts se repite en el token siguiente, y el 57% dentro de dos tokens. Por eso un cache de apenas 16 slots por capa alcanza para que el SSD no se convierta en el cuello de botella en cada paso. El lenguaje es repetitivo, y el ruteo que lo sigue también.

Instalación

Todo lo que sigue viene del repo en el release 0.1.1, Apache-2.0. Los weights del modelo se descargan aparte desde Hugging Face bajo los términos de Google.

git clone https://github.com/drumih/turbo-fieldfare.git
cd turbo-fieldfare
swift build -c release

Después instala el modelo. El paso de repack es la parte inteligente del instalador: streamea y reescribe el checkpoint a su propio layout .gturbo sin llegar a dejar la descarga completa en disco, algo que importa si eres de los que corre una Air de 8 GB con 40 GB libres.

swift run -c release TurboFieldfareRepack \
  --output scratch/gemma4.gturbo \
  --overwrite

Si la descarga se muere a mitad de camino —y en un pull de 15 GB puede pasar— la retomas:

swift run -c release TurboFieldfareRepack \
  --output scratch/gemma4.gturbo \
  --overwrite \
  --resume

Para descartar un estado parcial roto y empezar limpio:

swift run -c release TurboFieldfareRepack \
  --discard-partial \
  --output scratch/gemma4.gturbo

Y para confirmar que el resultado quedó íntegro antes de confiar en cualquier benchmark que corras contra él:

swift run -c release TurboFieldfareRepack \
  --verify-install \
  --input-gturbo scratch/gemma4.gturbo

Tres formas de usarlo

Completion cruda desde la CLI — la forma más rápida de confirmar que está vivo:

swift run -c release TurboFieldfareCLI \
  --model scratch/gemma4.gturbo \
  --prompt "The capital of France is" \
  --max-new 64 \
  --temperature 0

Chat con instrucciones, pasando un archivo de messages con la forma role/content de siempre:

swift run -c release TurboFieldfareCLI \
  --model scratch/gemma4.gturbo \
  --messages-file messages.json

Un server local que habla la API de Chat Completions de OpenAI, con streaming y function tools, atado a loopback:

swift build -c release --product TurboFieldfareServer
.build/release/TurboFieldfareServer \
  --model scratch/gemma4.gturbo

Levanta en http://127.0.0.1:8080/v1, lo que significa que cualquier cosa que ya apuntes a un endpoint compatible con OpenAI —la extensión de tu editor, un script, un framework de agentes— lo toma como drop-in cambiando la base URL y poniendo una API key descartable.

También hay una app nativa de Mac, en SwiftUI/AppKit, con descarga del modelo, carga y los controles de sampling habituales:

.build/release/TurboFieldfareMac

Los números, y la advertencia que importa más

Máquina Throughput
MacBook Air M2, 8 GB 5.1–6.3 tok/s
M5 Pro 31–35 tok/s

Todas las cifras son del propio autor, medidas en su hardware.

Esa diferencia de seis veces no es principalmente el chip. Es el SSD. En el thread señalaron que los discos de la M5 leen a unos 6,323 MB/s mientras que los de la M4 andan cerca de 2,031 MB/s — más de 3x. Cuando tu arquitectura streamea weights de experts en cada token, el ancho de banda de storage es tu velocidad de inferencia. Dos Macs con la misma RAM y distinta generación de SSD no te van a dar el mismo resultado, y esa es la variable que conviene revisar antes de predecir qué va a hacer tu máquina.

A 5–6 tok/s en la Air no vas a disfrutar un coding agent. Y está bien: es aproximadamente velocidad de lectura, perfectamente usable para procesamiento de texto, extracción, output JSON y trabajos por lote que lanzas y revisas después. Alguien en el thread levantó la pregunta obvia sobre corridas sostenidas de noche en un chasis sin ventilador; nadie publicó números térmicos todavía, así que trata los trabajos largos desatendidos en una Air como no probados.

Otra cosa que conviene saber antes de comprometer el espacio en disco: es solo texto —nada de imágenes, audio ni video, y sin ejecución de tools del lado del runtime— y es un proceso de un solo modelo por diseño. Esto no es un framework de inferencia de propósito general, es un runtime construido para un modelo. Justamente por eso puede hacer lo que hace.

La parte que se gana la confianza

El repo documenta 103 resultados medidos entre kernels, caching, I/O, prefill y decode — incluyendo los experimentos que no funcionaron. Eso es raro, y es la razón por la que esto se lee como ingeniería y no como una demo. Puedes ver qué políticas de cache perdieron, en qué profundidad de I/O dejó de ayudar, dónde importó el chunking del prefill. Cuando alguien te muestra sus fracasos junto a sus aciertos, los aciertos ganan credibilidad, no la pierden.

Ocho commits, un release, un issue abierto. Es software temprano bajo cualquier criterio. Pero lo que demuestra no se va a des-demostrar: para modelos MoE, la cantidad de RAM que tienes es una decisión de diseño, no un techo duro. Todo el que hoy hace inferencia local tiene que explicar por qué sigue cargando el checkpoint completo.

Si quieres la versión basada en RAM de esta decisión —qué variante de Gemma 4 entra en tu Mac por la vía convencional— nuestra guía de abril sigue siendo el punto de partida: Gemma 4 en tu Mac con Ollama: Qué Variante Elegir Según tu RAM

¿Y tú? ¿Cuál es el modelo más grande que lograste correr en tu máquina, y qué tuviste que resignar para llegar ahí?