- En un ESP32-S3 se ejecuta un modelo de lenguaje de 28.9 millones de parámetros sin conectarse a un servidor, mostrando texto en una pantalla pequeña a unas 9 tokens por segundo
- Usa una estructura de Per-Layer Embeddings que deja 25 millones de parámetros en la memoria flash lenta y solo lee por token unas 6 filas necesarias, 450 bytes
- El modelo ocupa 14.9 MB en 4 bits; en los 512 KB de SRAM se coloca el núcleo de cómputo usado en cada token, en los 8 MB de PSRAM el cabezal de salida y la memoria de trabajo, y en los 16 MB de flash la tabla grande de embeddings
- Entrenado con TinyStories, genera historias cortas y simples de forma generalmente consistente, pero no es adecuado para responder preguntas, seguir instrucciones, escribir código ni aportar conocimiento factual
- Tiene cerca de 100 veces más parámetros que un modelo previo de 260 mil parámetros ejecutado en un chip similar; la clave no está en la calidad de generación, sino en la arquitectura de memoria para meter un modelo grande en un chip pequeño
Hardware y rendimiento de ejecución
- Todo el procesamiento se hace en un solo ESP32-S3 de unos 8 dólares, sin enviar datos a un servidor
- Usa 512 KB de SRAM, 8 MB de PSRAM y 16 MB de flash
- La velocidad total es de unos 9.5 tok/s, y la velocidad de cómputo puro es de unos 9.7 tok/s
- El tamaño del modelo en 4 bits es de 14.9 MB
- De los 28.9 millones de parámetros totales, 25 millones se guardan en una tabla de consulta en flash
Cómo meter el modelo en una memoria pequeña
- Normalmente todo el modelo debe poder accederse desde memoria rápida, pero la SRAM del ESP32-S3 es de apenas 512 KB, así que solo caben modelos muy pequeños
- Aprovecha que la mayoría de los parámetros están en una tabla de embeddings y no en el cómputo directo, por lo que la tabla se deja en flash
- Por token solo se leen unas 6 filas necesarias, alrededor de 450 bytes
- Solo la parte pequeña encargada del cómputo real se mantiene en memoria rápida
- La mayor parte del modelo no se carga durante la ejecución; solo se seleccionan las partes necesarias desde la flash
- El papel de cada memoria se divide así
- SRAM: núcleo de cómputo usado en todos los tokens
- PSRAM: cabezal de salida y memoria de trabajo
- Flash: tabla de 25 millones de parámetros
Aplicación de Per-Layer Embeddings
- Aplica Per-Layer Embeddings, usado por Google en Gemma 3n y Gemma 4, a una arquitectura de memoria de microcontrolador en lugar de un teléfono o una GPU
- Según lo verificado por el autor del proyecto, no hay precedentes de aplicar este método en un chip tan pequeño
Qué puede hacer el modelo y sus límites
- Entrenado con las historias sintéticas cortas de TinyStories, genera historias simples y en general mantiene la consistencia
- No puede responder preguntas, seguir instrucciones, escribir código ni proporcionar conocimiento factual
- Esta limitación proviene del pequeño núcleo encargado del razonamiento, y la técnica de distribución de memoria no mejora por sí misma la capacidad de razonamiento
Código y material experimental
- En
firmware/esp32_llm/README.mdestán el firmware, el cableado y el procedimiento de flasheo - En
src/yexperiments/se incluye código de entrenamiento, experimentos de ablación y cuantización - En
RESULTS.mdse resumen el método completo, los experimentos de ablación y las mediciones en chip
Proyecto base y registro
- TinyStories es un conjunto de datos de historias sintéticas cortas creado para que incluso modelos pequeños aprendan a escribir con consistencia
- Per-Layer Embeddings de Google Gemma sirve como base para meter modelos grandes en chips pequeños
- llama2.c de Andrej Karpathy influyó en el enfoque de entrenar modelos de lenguaje pequeños y ejecutarlos en C puro
- El repositorio también conserva el error de cálculo que al inicio infló la cantidad de parámetros, junto con el proceso de corrección
- En el historial de commits y en
RESULTS.mdse puede ver dónde cambiaron las cifras y por qué
- En el historial de commits y en
1 comentarios
Opiniones de Hacker News
Hoy en día es sorprendente lo que se puede hacer con un microcontrolador de 5 dólares. Entre las placas Milk-V, la Duo tiene hasta 256MB de memoria y una TPU de 1TOPS@INT8, e incluso corre Linux, así que compré 5
GCC y Clang soportan completamente xTHeadVector, y usando funciones intrínsecas de C es compatible con RVV 1.0 solo con opciones de línea de comandos. Buena parte del código que maneja elementos de 8 bits, como
memcpy(),memset(),memcmp(),strlen(),strcpy()ystrcmp(), es binariamente compatibleCuando compré la Duo de 64MB costaba 3 dólares, y después los modelos de 64MB, 256MB y 512MB costaban 5, 7 y 10 dólares respectivamente, pero este año el precio subió bastante: https://arace.tech/products/milk-v-duo, https://arace.tech/products/milkv-duo-s
Sigue habiendo usos donde un PIC de 4KB es lo mejor, pero en la mayoría de los casos no hay que actuar como si no existieran alternativas mejores
Los modelos de voz a texto y de texto a voz también se están acercando a este tamaño, así que me pregunto qué tan cerca estamos de tener dispositivos pequeños capaces de hablar con nosotros. Tal vez llegue un mundo donde un cepillo de dientes te dé consejos de higiene bucal o hasta te muestre anuncios de pasta dental
Pero no quisiera vivir en un mundo donde también haya que buscar un bloqueador de anuncios para la IA del cepillo de dientes
Usaron de forma muy ingeniosa una técnica de embeddings por capa. También existen modelos TTS prácticos de unos 20 a 30 millones de parámetros, así que un ESP32 sin conexión de red podría leer texto casi en tiempo real
La PSRAM, la flash y las tarjetas SD no tienen mucho ancho de banda individualmente, pero si se usan varias al mismo tiempo se puede alcanzar un rendimiento considerable. El hardware dedicado a gran escala seguramente gane en rendimiento por vatio, pero por su bajo costo inicial y escalabilidad gradual este tipo de configuración también resulta atractiva
Más que un microcontrolador, me pregunto cuál sería una opción realista para que un LLM local en Raspberry Pi 4 no tarde 30 segundos por respuesta
Está genial correr un LLM en un dispositivo diminuto, pero me impresiona todavía más la forma de entrenamiento que produjo estos pesos
Si se aprovechara la flash con un buen patrón de acceso, me pregunto si no se podría escalar esto para correr modelos mucho más grandes en CPU
El ESP32-S3 es bastante potente; actualmente lo uso para trabajo de desarrollo en Raspberry Pi 4. Uno de sus dos puertos USB soporta OTG, así que permite implementar funciones que de otro modo costarían más de 100 dólares
Ahora mismo funciona con tinyusb y pico-pio-usb, y también estoy probando un port a Rust esperando mejor rendimiento
Me pregunto qué tan buena será la precisión de este modelo cuantizado
El rendimiento que muestra a este tamaño es impresionante, y entusiasma pensar hasta dónde se podrá llegar en las computadoras de placa única un poco más potentes que aparecieron en el hilo