Swiftlet: cómo correr un 80B con 4.3 GB de RAM en tu Mac
Swiftlet: cómo correr un 80B con 4.3 GB de RAM en tu Mac
La primera vez que vi el benchmark, fui a verificar dos veces que no me estaba mintiendo la tabla. Un modelo de 80 mil millones de parámetros corriendo con 4.3 GB de RAM pico en una Mac M5, a 4.5 tokens por segundo. Y la versión de 35B, en un iPhone 17, con 2.6 GB de RAM. No es magia ni un benchmark trucado: es Swiftlet, un runtime open source escrito en Swift y Metal que explota una propiedad muy concreta de los modelos MoE modernos. Te lo desarmo en este post.
Si ya corriste Ollama localmente y te quedaste corto con la RAM, este es el siguiente paso lógico: dejar de pensar en "cuánta RAM tenés" y empezar a pensar en "qué disco tenés libre".
La idea intuitiva — y la que sigue siendo cierta para los modelos densos — es que necesitás aproximadamente 0.5 GB de RAM por cada mil millones de parámetros en cuantización 4-bit. Con esa regla, un 80B necesita alrededor de 40 GB. Imposible en una laptop de 16 GB, ni soñar en un iPhone.
Pero los Qwen3-Next y Qwen3.5/3.6 no son modelos densos. Son MoE híbridos (Mixture of Experts). En cada forward pass, por cada token, el router activa solo una pequeña fracción de los parámetros totales. Concretamente:
- Qwen3-Next-80B-A3B: 80B totales, pero solo ~3B activos por token. Cada capa enruta cada token a 10 de 512 expertos.
- Qwen3.6-35B-A3B: 35B totales, ~3B activos. Cada capa enruta a 8 de 256 expertos.
Ahí está la palanca. Si solo el 4% de los parámetros se toca en cada paso, ¿para qué cargarlos todos en RAM? La mayoría puede quedarse en disco y leerse bajo demanda.
El insight central: en un MoE, los expertos enrutados se pueden tratar como un recurso "barato" de almacenamiento. El cuello de botella no es la capacidad, es la latencia de leerlos del SSD en el momento justo.
Cómo lo hace Swiftlet por dentro
El runtime hace tres cosas bien, y cada una es un compromiso ingeniería muy concreto.
1. Mantener residentes solo las partes densas
Lo que sí tiene que estar en RAM siempre — atención, proyecciones DeltaNet, routers, expertos compartidos, embeddings — pesa mucho menos. En cuantización 4-bit, son aproximadamente:
- 1.3 GB para el 35B
- 2.5 GB para el 80B
Eso explica por qué el 80B entra en 4.3 GB de pico: la mayor parte del presupuesto de RAM lo consume la activación de unos pocos expertos a la vez, no el modelo entero.
2. Empaquetar los expertos en un formato que el SSD pueda servir
El detalle de diseño que más me gustó: en vez de mmap o de pelearse con la page cache del sistema operativo, Swiftlet reempaqueta los decenas de miles de expertos enrutados en blobs de stride fijo dentro de un contenedor .qpack. Leer un experto es exactamente un pread del SSD. Sin mmap, sin thrashing de page cache, sin sorpresas con la VM del sistema.
Es el mismo truco que usan los loaders de assets en juegos: layout pensado para que el medio de almacenamiento (SSD) lo sirva directo, sin que el sistema operativo se interponga.
3. Cachear lo que se usa, dejar ir lo que no
Un cache acotado con política LFU + recencia se encarga de mantener en RAM los expertos más usados. Lo interesante que midieron los autores: la tasa de hits del cache importa menos de lo que parece. En sus pruebas, hit rates entre 43% y 70% rinden aproximadamente igual, porque los SSDs de Apple absorben los misses sin que baje el throughput.
# Decodificar 5 tokens por segundo en una Mac M5 con un 80B
# no requiere intervención del usuario. Solo compilar y correr.
git clone https://github.com/leonickson1/Swiftlet.git && cd Swiftlet
swift build -c release
.build/release/swiftlet-repack \
--from-hf Leonickson/Qwen3-Next-80B-A3B-qpack \
--output ~/models/qwen3-next-80b.qpack
Probándolo en tu Mac hoy mismo
Los requisitos son los que te esperás: Apple Silicon, macOS 14+, y espacio libre en disco. El 80B ocupa 42 GB; el 35B, 18 GB. La RAM del sistema no es el factor limitante.
Chat interactivo
.build/release/swiftlet chat ~/models/qwen3.6-35b.qpack \
"¿Quién escribió 'Cien años de soledad'?" \
"¿En qué idioma escribía?"
El comando aplica el chat template del modelo, desactiva el bloque de razonamiento cuando corresponde y mantiene el estado de la conversación, así que las preguntas de seguimiento solo re-prompten el turno nuevo en vez de todo el historial.
Generación one-shot con estadísticas
.build/release/swiftlet generate ~/models/qwen3.6-35b.qpack \
--gpu --chat --prompt "Explicame expert streaming en un párrafo."
Servidor compatible con OpenAI
Si querés enchufarlo en algo que ya consume la API de OpenAI, hay un servidor que escucha en loopback:
.build/release/swiftlet-server --model ~/models/qwen3.6-35b.qpack --port 8080
Después apuntás tu cliente a http://localhost:8080/v1 y la API responde como si fuera la original. Muy útil para probar agentes o pipelines sin tocar código.
En un iPhone, sin servidor, sin internet
El caso de uso más extremo — y más interesante — es el de la app Priv AI en el App Store. Dentro de Settings → Experimental Models, descargás el 35B y chateás on-device. Nada sale del teléfono. La función acaba de entrar a revisión de Apple, así que puede tardar un par de días en aparecer; si la querés ya, el código de la app es open source en leonickson1/localLLM.
Pensá lo que esto significa en la práctica: un modelo de 35 mil millones de parámetros corriendo localmente en un teléfono, sin servidor, sin internet, sin telemetry. Para casos sensibles — datos médicos, legal, código propietario de un cliente — la promesa de "LLM que cabe en tu bolsillo" deja de ser marketing.
Expectativas honestas: como solo ~3B parámetros están activos por token, el modelo chatea y escribe como uno grande, pero recuerda hechos como uno chico. No le pidas que recite la tabla periódica completa esperando que funcione como un 70B denso.
Qué comparás y qué no
Swiftlet no compite con Ollama, con vLLM ni con llama.cpp en el mismo segmento. La pregunta que responde cada uno es distinta:
- Ollama es la forma rápida de bajar un modelo, cuantizarlo, y servirlo en CPU/GPU. Asume que el modelo entra en tu hardware.
- llama.cpp es el runtime de referencia en CPU/Metal, pero sigue pensando en términos de "cargar el modelo entero".
- vLLM es el servidor de producción para GPUs grandes, con continuous batching y speculation decoding.
- Swiftlet apunta al nicho donde no entra el modelo entero y la única memoria masiva que tenés es SSD. Es una pieza complementaria, no un reemplazo.
Si tenés una Mac con 32 GB de RAM y querés correr un 7B o un 13B denso, Ollama sigue siendo la respuesta correcta. Si querés un 80B en una Mac con 16 GB o un 35B en un iPhone, Swiftlet es lo único que conozco que lo hace sin trucos.
Lo que me llevo
Lo que más me gustó del proyecto no es el benchmark — es la decisión arquitectónica. Los modelos MoE híbridos ya están entre nosotros (Qwen3-Next, DeepSeek V3, los próximos Mixtral) y muchos developers los ven como "imposibles de correr localmente". Swiftlet demuestra que esa percepción es obsoleta: con un layout de archivo pensado para SSD, un cache chico, y el SSD moderno absorbiendo los misses, el límite práctico pasa de "cuánta RAM tenés" a "cuánto disco libre te queda".
Para mí cambia la conversación sobre IA local. Ya no es "comprate una Mac con 64 GB". Es "comprate una Mac con SSD grande, y un iPhone para el 35B". El resto es software.
seguir leyendo
Cómo usar Ollama para correr LLMs localmente: guía completa para developers
Aprende a instalar Ollama, descargar modelos open-source y correr LLMs como Llama 3 o Mistral directamente en tu máquina. Privacidad, cero costos de API y control total sobre tus datos.
OpenAI Astra: 10 problemas matemáticos resueltos por USD 2.000
El modelo interno Astra de OpenAI resolvió 10 problemas matemáticos estancados hace más de una década, con formalizaciones verificables en Lean 4 y menos de USD 2.000 en tokens. Te cuento qué hay detrás, las críticas que le hacen y qué cambia para los que trabajamos con código.
Claude Opus 5: qué cambia para los que lo usamos desde la API
Anthropic lanzó Claude Opus 5 con un knob de effort configurable y resultados SOTA en coding. Mirá los benchmarks, precios y un ejemplo real con el SDK.
comentarios
$ subscribe --newsletter
Recibe los nuevos posts en tu email
Un email cuando publico algo nuevo. Sin ruido, sin relleno.