Kimi K3 en una CPU con 8 GB: el disco NVMe es ahora el cuello de botella

Estación de trabajo con unidades NVMe en actividad y una sola CPU, sin GPU

El proyecto de código abierto kimi-k3-in-c, publicado por el desarrollador Fareed Khan, ejecuta el modelo completo Kimi K3, de 2,78 billones de parámetros, en una sola CPU con un pico de memoria medido de 8,24 GB, sin GPU y con un binario de 176 KB escrito en C99. Para quien administra sistemas, lo interesante no es tanto la cifra de memoria como lo que implica: cuando el modelo no cabe en RAM, el rendimiento pasa a depender casi por completo del almacenamiento. Con 8 GB se generan tokens a unos 26,5 segundos cada uno; con 128 GB o más, a 5,6.

Las claves de Kimi K3 en CPU para sistemas en 30 segundos

  • Qué es: un motor en C99, con OpenMP como única dependencia, que ejecuta Kimi K3 completo solo con CPU.
  • Requisitos: CPU con AVX2 y FMA o NEON, 8 GB de RAM como mínimo y unos 1,7 TB de disco.
  • Rendimiento: de 26,5 s por token con 8 GB a 5,6 s con 128 GB, siempre con la misma salida.
  • La clave: el disco limita más que la CPU; el motor lee con O_DIRECT y saca entre 5,4 y 6 GB/s de un NVMe.

Kimi K3, el modelo abierto de Moonshot AI, es una mezcla de expertos (MoE) de 93 capas con 896 expertos por capa, de los que solo se activan 16 por token. El motor aprovecha esa estructura: los 1,447 TB de expertos, que se distribuyen en el formato de 4 bits MXFP4, nunca se mantienen en memoria y se leen del disco según los pide el enrutador; el tronco denso, unos 113 GB, se reempaqueta en un archivo de 109 GB que se lee capa a capa. Como ya contamos en Noticias.ai, el autor asegura que la salida es idéntica byte a byte con cualquier cantidad de RAM.

Requisitos y puesta en marcha

La plataforma de referencia es Linux x86-64; también compila y pasa todas las pruebas en macOS con Apple Silicon y en Windows mediante MSYS2 con MinGW-w64, y funciona sin cambios en WSL. Hace falta una CPU con AVX2 y FMA en x86-64 o NEON en ARM (AVX-512 no es necesario), GCC 9 o Clang 10 en adelante, y Python 3.9 solo para las herramientas de descarga y empaquetado. El requisito que manda es el almacenamiento: 1,56 TB para el modelo y 109 GB para el tronco empaquetado, mejor en un NVMe local.

git clone https://github.com/FareedKhan-dev/kimi-k3-in-c.git
cd kimi-k3-in-c
./scripts/k3-doctor.sh          # comprueba toolchain, RAM, disco y sugiere perfil
make -j && make test            # compila y valida sin descargar el modelo
export HF_TOKEN=hf_...
./scripts/download-model.sh ~/k3model     # 1,56 TB, reanudable
./scripts/pack-trunk.sh ~/k3model ~/k3trunk   # unos 4 minutos, una vez
./bin/k3 ~/k3model --trunk ~/k3trunk --preset laptop --tok ~/k3model --prompt "Hola" --gen 16 --incrementalLenguaje del código: PHP (php)

make test merece la pena antes de comprometerse con una descarga de 1,56 TB: compara el motor de forma exacta con una referencia en PyTorch sobre un modelo de prueba de 13 capas con la misma estructura, y no necesita red. El script de descarga verifica el tamaño exacto de cada uno de los 96 archivos, porque una descarga parcial no falla con un error, sino que produce tokens equivocados. Un detalle a vigilar: si se omite --trunk, el tronco se carga entero en memoria, unos 113,5 GB, ignore el perfil que ignore.

Perfiles de memoria y cómo se midieron

El motor reparte la memoria entre dos presupuestos: el tronco fijado en RAM (con un anillo de lectura para las capas que se van trayendo del disco) y una caché LRU para los expertos. Los perfiles van de laptop (8,2 GB de pico) a desktop (31,9 GB), workstation (95,5 GB), server (unos 128 GB, con 90 de las 93 capas del tronco fijadas) y max (unos 224 GB). Hay un perfil ultra de unos 3 GB que el autor presenta como prueba de vida, no para uso real. El motor se niega a arrancar si el plan supera el 95 % de la memoria disponible, así que server necesita unos 135 GB libres.

Todas las cifras proceden de una sola máquina: dos AMD EPYC 7763 con 124 núcleos sin SMT, 228 GB de RAM y 3,2 TB de NVMe. Para simular cada nivel de memoria, el autor limitó el proceso con un grupo de control de systemd y sin swap, algo fácil de reproducir:

systemd-run --scope --user -q -p MemoryMax=8G -p MemorySwapMax=0 ./bin/k3 ~/k3model --trunk ~/k3trunk --trunk-gb 2.5 --cache-gb 0.5 --ids 1008,10484,318,15383,387 --gen 8 --incrementalLenguaje del código: JavaScript (javascript)

Eso significa que los 26,5 segundos por token del perfil más modesto se midieron con 124 núcleos y un NVMe rápido, no en un portátil de 8 GB real. En un equipo doméstico, con menos núcleos y un SSD más lento, el tiempo será mayor. El autor también cuenta que tuvo que desactivar unattended-upgrades y los temporizadores de apt antes de medir, porque el actualizador consumía un 63 % de un núcleo y alteraba los tiempos más que muchas optimizaciones.

Por qué el almacenamiento lo decide todo

Con poca memoria, el modelo se lee del disco en cada paso. Según los informes de ejecución, entre el 41 % y el 61 % del tiempo total se va en E/S, y el tronco se lee a entre 5.373 y 6.064 MB/s sostenidos. Un hallazgo contraintuitivo marcó el diseño: en esa máquina, leer con O_DIRECT, saltándose la caché de páginas del kernel, era más rápido (3,2 GB/s en frío) que leer a través de ella (2,3 GB/s), así que el motor abre el tronco con O_DIRECT y alinea cada lectura al tamaño de bloque. El repositorio incluye tools/devbw.py para medir el disco tal y como lo usa el motor, con lecturas aleatorias grandes a profundidad de cola 1 y 16, algo que dd no refleja. El propio autor avisa de que un volumen de red puede ser varias veces más lento que un NVMe local.

Otra conclusión útil para dimensionar: con un presupuesto fijo de 128 GB, dar la memoria al tronco antes que a la caché de expertos fue 1,69 veces más rápido, y el perfil max, con 96 GB más, no mejoró a server fuera del ruido de medida. Para scripts y automatización, el binario devuelve códigos de salida distintos: 2 para errores de uso o una configuración que no puede leer con seguridad, y 4 cuando la ejecución termina pero algún experto no se pudo cargar y los resultados no son fiables. La opción --threads usa por defecto los núcleos físicos, porque con SMT el motor rinde peor.

Preguntas frecuentes

¿Qué hardware necesita kimi-k3-in-c?

Una CPU con AVX2 y FMA o NEON, al menos 8 GB de RAM y unos 1,7 TB de almacenamiento, idealmente NVMe local. No usa GPU.

¿Por qué usa O_DIRECT?

Porque en la máquina de pruebas leer saltándose la caché de páginas fue más rápido que leer a través de ella: 3,2 GB/s frente a 2,3 GB/s.

¿Qué perfil de memoria conviene?

El script k3-doctor.sh lo sugiere según la memoria disponible. Con 128 GB o más, server es el más rápido; max no mejora sus resultados.

Fuente: GitHub, repositorio FareedKhan-dev/kimi-k3-in-c

Suscríbete al boletín SysAdmin

Este es tu recurso para las últimas noticias y consejos sobre administración de sistemas, Linux, Windows, cloud computing, seguridad de la nube, etc. Lo enviamos 2 días a la semana. Recuerda revisar tu email para confirmar la suscripción.

Scroll al inicio
×