Ejecutando un LLM de 2.78T Parámetros en una CPU con 8GB de RAM: Dentro del Motor C de Kimi K3
Descubre cómo un binario C99 de 176KB ejecuta un modelo Kimi K3 de 2.78 billones de parámetros en una sola CPU con solo 8.24GB de RAM, usando streaming, MXFP4 y una gestión inteligente de memoria.
Imagina ejecutar un modelo de lenguaje de 2.78 billones de parámetros en tu portátil. No una versión cuantizada, destilada o comprometida de alguna manera—el Kimi K3 completo, original, con 1.56TB de pesos, produciendo una salida byte-idéntica a la que obtendrías de un clúster de GPUs en un centro de datos. Eso es exactamente lo que logra el proyecto kimi-k3-in-c, y es una clase magistral en ingeniería de sistemas.
Esto no es una demo de juguete. Es un motor de inferencia completamente funcional escrito en C99 portátil, sin BLAS, sin framework de aprendizaje profundo y sin soporte para GPU. Todo el motor se compila en un binario de 176KB. ¿El secreto? Una combinación de explotación de la arquitectura del modelo, streaming agresivo de memoria y una comprensión profunda de dónde vive cada byte.
El Problema: Un Modelo Que No Cabe
Kimi K3 tiene 2.78 billones de parámetros, que en precisión bfloat16 requerirían 5.56TB de memoria. El checkpoint liberado es de 1.56TB, aún muy por encima de cualquier máquina de consumo. Pero Kimi K3 es un modelo de Mezcla de Expertos (MoE): por cada token, solo 16 de 896 expertos por capa están activos. Eso son alrededor de 104 mil millones de parámetros activos—solo el 3.7% del total.
La idea clave: el otro 96.3% de los parámetros no necesitan estar en RAM. Solo necesitan ser accesibles. Al transmitir los expertos inactivos desde el disco bajo demanda, el requisito de memoria se reduce drásticamente.
Las Cuatro Reducciones
El proyecto logra una reducción de memoria de 675x desde la línea base teórica de bfloat16 mediante cuatro pasos clave:
Cuantización MXFP4: Los expertos enrutados ya están almacenados en formato MXFP4—un formato de coma flotante de 4 bits con microescala. Cada peso es un nibble de 4 bits, con un exponente compartido de 8 bits por cada 32 pesos. Esto reduce el almacenamiento de expertos de 5.45TB a 1.447TB.
Dispersión: Solo 16 de 896 expertos se activan por token, por lo que los 1.447TB de expertos nunca necesitan estar completamente residentes. Se transmiten desde el disco según sea necesario.
Atención KDA: 69 de 93 capas usan Atención Delta de Kimi, un mecanismo de atención recurrente con un estado de tamaño fijo que no crece con la longitud del contexto. Esto elimina la explosión de caché KV en la mayoría de las capas.
Compresión MLA: Las 24 capas restantes usan Atención Latente Multi-cabeza, que almacena en caché un único latente de 576 dimensiones por posición en lugar de pares clave/valor por cabeza. Esto reduce el tamaño de la caché KV en 53x.
Después de estas reducciones, el conjunto siempre residente es de solo 113.49GB (el tronco denso, los embeddings y la cabeza de salida). Pero eso sigue siendo demasiado para un portátil. La reducción final: transmitir el propio tronco.
Transmitiendo el Tronco: Un Dial, No un Piso
El tronco (93 capas densas) es de 108.81GB. Cada capa se usa en cada token, por lo que no hay dispersión que explotar. La solución es fijar tantas capas en RAM como permita tu presupuesto, y transmitir el resto desde el disco a través de un único búfer anular.
El motor recorre las capas 0-92 en orden en cada token. Esto es un escaneo cíclico, que es el peor caso para el almacenamiento en caché LRU. Así que en lugar de una caché, usa un prefijo fijo: las primeras N capas están permanentemente residentes, y el resto cicla a través de una ranura anular. Esto da una tasa de aciertos determinista de N/93.
Por ejemplo, con un --preset laptop (presupuesto de tronco de 3GB), solo 10 capas están fijadas, y el resto se transmite desde el disco. El resultado: pico de RSS de 8.24GB, pero 26.5 segundos por token. Con --preset server (presupuesto de tronco de 110GB), 90 capas están fijadas, y la velocidad salta a 5.6 segundos por token.
La Caché de Expertos: Una Lección de Medición
El motor también incluye una caché LRU para los expertos enrutados. Pero aquí está la parte sorprendente: la caché es casi inútil en tamaños pequeños. Las mediciones del proyecto muestran que aumentar la caché de 28 ranuras a 1,344 ranuras (un aumento de 48x) cambia los bytes leídos por token en exactamente cero.
¿Por qué? Porque Kimi K3 usa una técnica llamada Equilibrio de Cuantiles, que aplana el uso de expertos en todo el grupo. Sin un subconjunto caliente de expertos, una caché LRU no retiene nada útil. La caché solo comienza a ayudar cuando es lo suficientemente grande como para contener una fracción significativa del conjunto de trabajo (alrededor de 36GB de arena).
Esto lleva a una optimización contraintuitiva: dale memoria al tronco primero, no a la caché de expertos. Con un presupuesto fijo de 128GB, asignar 110GB al tronco y 13GB a la caché es 1.69x más rápido que la división inversa, aunque esta última tenga una tasa de aciertos de caché más alta.
Reproducibilidad Bit-Exacta
Uno de los aspectos más impresionantes es el compromiso con la reproducibilidad bit-exacta. El motor asegura que las rutas de código escalar, OpenMP y AVX2 produzcan resultados idénticos. Esto se logra mediante:
- Usar
-ffp-contract=offpara prevenir la contracción FMA, que cambiaría el redondeo. - Acumular en doble precisión con un orden de suma fijo.
- Ampliar bf16 a fp32 mediante un simple desplazamiento (sin pérdida).
Esto significa que la salida es byte-idéntica ya sea que se ejecute en un portátil de 8GB o en una estación de trabajo de 224GB. La única diferencia es la velocidad.
Validación: Probando Que Funciona
El proyecto incluye un riguroso conjunto de validación:
- Pruebas sin pesos: Un modelo oráculo de 13 capas con el mismo grafo tensorial que el modelo completo, verificado contra una referencia de PyTorch. Todas las compuertas pasan exactamente.
- Conformidad del checkpoint completo: Las 93 capas verificadas contra PyTorch, con un error en el peor caso de 0.00x la tolerancia permitida.
- Paridad de logits: Los logits del motor C coinciden con la referencia de PyTorch elemento a elemento, con una diferencia máxima de 7.87e-6.
- Escalera de memoria: 12 presupuestos de memoria diferentes desde 8GB hasta 224GB, todos produciendo IDs de token idénticos.
El Resultado Final
Este proyecto es un testimonio de lo que es posible con una ingeniería de sistemas cuidadosa. Demuestra que un modelo de billón de parámetros no requiere un centro de datos—solo una comprensión inteligente de dónde viven los bytes y cómo moverlos eficientemente.
Ya sea que te interesen las arquitecturas MoE, la inferencia eficiente en memoria, o simplemente quieras ver algo de código C impresionante, kimi-k3-in-c vale la pena una inmersión profunda. El README por sí solo es un tesoro de detalles técnicos, y el código es limpio y bien documentado.
Si te sientes inspirado para probarlo tú mismo, necesitarás alrededor de 1.7TB de espacio libre en disco y mucha paciencia para la descarga. Pero la recompensa es ejecutar uno de los modelos abiertos más grandes en hardware que probablemente ya posees.