Un sensor conectado a una placa pequeña, y una computadora portátil que muestra la señal en bruto convertida en un espectrograma y un único resultado
Contenido

Del sensor a la inferencia embebida: el pipeline completo

Qué pasa entre el sensor y la inferencia embebida: muestreo, buffers, features, modelos int8 y posprocesamiento, con presupuesto de tiempo, memoria y energía.

El modelo sacó 96 % en el notebook. En el microcontrolador se le escapan eventos, se dispara con el ruido y se acaba la batería en dos semanas. La red es la misma; lo que cambió es todo lo que la rodea. La inferencia embebida sobre un sensor es un pipeline que empieza en la etapa analógica y termina en una decisión, y el modelo es solo una etapa. Aquí recorremos cada etapa entre la entrada del sensor y la salida de una red neuronal pequeña (muestreo, buffers, extracción de features, el modelo cuantizado, posprocesamiento) y vemos cómo repartir el presupuesto de tiempo, memoria y energía entre ellas, con la investigación que dio forma a las herramientas actuales.

Puntos clave

  • Trata la inferencia como un pipeline con fecha límite: las features y la inferencia tienen que terminar antes de que llegue la siguiente ventana, o se pierden muestras.
  • Las features tienen que calcularse en el dispositivo exactamente igual que en el entrenamiento. Otra ventana, otra escala u otro filtro es otra entrada para el modelo.
  • Según los autores de TensorFlow Lite Micro, los procesadores embebidos tienen entre 100 y 1,000 veces menos cómputo, memoria y energía que los móviles, así que el modelo y el runtime deben caber en kilobytes.
  • La cuantización int8 reduce cuatro veces el almacenamiento de los pesos frente a float32 y permite kernels solo con enteros; los kernels optimizados para Cortex-M reportaron 4.6× más rendimiento y 4.9× más eficiencia energética.
  • La exactitud sola no es un resultado. MLPerf Tiny reporta exactitud, latencia y energía juntas, y tú también deberías.

El problema: un buen modelo en un mal pipeline

Casi todos los demos de IA en el borde que fallan, fallan fuera de la red. Las muestras llegan con jitter porque el ADC se dispara desde un ciclo ocupado. La ventana en el dispositivo es de 1,000 muestras y en el entrenamiento era de 1,024. Los datos de entrenamiento se normalizaron con estadísticas que el firmware no tiene. El modelo entrega una probabilidad cada 100 ms y la aplicación trata cualquier cuadro arriba de 0.5 como un evento. El microcontrolador nunca duerme porque la inferencia corre sin parar.

Nada de eso aparece en la exactitud del notebook. Aparece como detecciones perdidas, falsas alarmas y duración de batería, que es justo lo que nota el cliente.

Qué pasa en cada etapa

Etapa 1: Muestrear con un reloj, no en un ciclo

Todo lo que sigue supone muestras equiespaciadas. En un microcontrolador eso significa disparar el ADC (o leer la FIFO de un sensor digital) con un temporizador de hardware y mover los datos con DMA, para que el resto del trabajo del CPU no mueva los instantes de muestreo. El filtro antialiasing y la frecuencia de muestreo siguen las mismas reglas que cualquier sistema de adquisición; un modelo no puede recuperar información que el aliasing destruyó.

Es fácil subestimar el flujo de datos. Un ejemplo ilustrativo: un acelerómetro de tres ejes en la bomba de una planta en Monterrey, a 3,200 muestras por segundo con muestras de 16 bits, produce 19,200 bytes por segundo.

Etapa 2: Juntar muestras en ventanas

Los modelos consumen ventanas, no muestras. El firmware junta una ventana (digamos 1 s), se la pasa a la extracción de features y sigue juntando la siguiente. Con un doble buffer (ping-pong), el DMA llena una mitad mientras el CPU procesa la otra. En el ejemplo del acelerómetro, una ventana de 1 s son 19,200 bytes y el doble buffer son 38,400 bytes de RAM antes de cualquier memoria de features o del modelo.

El salto entre ventanas fija la fecha límite. Con 50 % de traslape llega una ventana nueva cada 0.5 s, así que extraer features e inferir tiene que terminar en bastante menos de 500 ms, e idealmente en mucho menos para que el procesador pueda dormir.

Etapa 3: Extracción de features, la etapa que debe coincidir con el entrenamiento

Las muestras crudas casi nunca son la entrada del modelo. Los modelos de audio suelen tomar features espectrales como MFCC o energías log-mel; los de vibración, magnitudes de FFT o energías por banda; los sensores lentos pueden usar estadísticas simples de la ventana. El estudio Hello Edge de Zhang y sus colegas sobre detección de palabras clave en microcontroladores es una buena referencia: compararon arquitecturas publicadas dentro de los límites de memoria y cómputo de un microcontrolador y encontraron que una CNN separable en profundidad alcanzó 95.4 % de exactitud en su tarea, unos 10 puntos más que una red totalmente conectada con un número parecido de parámetros. Sus resultados dependen de las features espectrales que se calculan antes de la red, y los tuyos también.

La regla práctica es estricta. La longitud de ventana, el traslape, la función de ventana, el tamaño de la FFT, los coeficientes de los filtros, el escalamiento y las constantes de normalización tienen que ser idénticos en el entrenamiento y en el dispositivo. La forma más segura de lograrlo es generar ambos a partir del mismo código o de la misma especificación, y probar las features del dispositivo contra las del pipeline de entrenamiento con la misma grabación.

Etapa 4: El modelo cuantizado

Dos cosas hacen que una red neuronal quepa en un microcontrolador: arquitecturas pequeñas y aritmética entera. El artículo de Jacob y sus colegas en CVPR 2018 sobre inferencia solo con enteros describió el esquema de cuantización que hoy usan casi todos los runtimes embebidos: pesos y activaciones guardados como enteros de 8 bits con una escala y un punto cero, acumulación en enteros de 32 bits y un procedimiento de entrenamiento que mantiene la exactitud cerca de la de punto flotante. El almacenamiento baja cuatro veces: un modelo ilustrativo con 50,000 parámetros necesita unos 200 KB en float32 y unos 50 KB en int8.

El runtime también importa. El artículo de TensorFlow Lite Micro de David y sus colegas describe las restricciones para las que se diseñó: procesadores embebidos con al menos 100 a 1,000 veces menos cómputo, memoria y energía que los dispositivos móviles, modelo y runtime que deben caber en unos cuantos kilobytes, sin asignación dinámica de memoria ni memoria virtual, y un panorama fragmentado de conjuntos de instrucciones con y sin unidad de punto flotante. Su respuesta es un intérprete con una arena de memoria planeada de forma estática. Debajo, kernels optimizados hacen la aritmética; Lai, Suda y Chandra reportaron que sus kernels CMSIS-NN para Arm Cortex-M mejoraron el rendimiento de las redes neuronales 4.6× y la eficiencia energética 4.9×.

Etapa 5: Posprocesar hasta una decisión

Un modelo entrega puntajes, cuadro por cuadro. La aplicación necesita eventos. En medio están el suavizado (promediar puntajes de varios cuadros), los umbrales con histéresis (para que un puntaje que ronda el umbral no haga parpadear la salida), las duraciones mínimas y los periodos refractarios. Estas decisiones cambian la tasa de falsas alarmas y de detecciones perdidas tanto como el modelo, y es barato ajustarlas con datos grabados.

Etapa 6: Presupuestos de tiempo, memoria y energía

Tiempo: features más inferencia más posprocesamiento tienen que caber en el intervalo entre ventanas, con margen para interrupciones y comunicación.

Memoria: la flash guarda el código, los pesos del modelo y las tablas constantes; la RAM guarda los buffers de muestras, los buffers de features y la arena de tensores del runtime. Los buffers de muestras por sí solos pueden ser más grandes que la arena.

Energía: la corriente promedio la fija el ciclo de trabajo. Un cálculo ilustrativo: si el procesador consume 10 mA activo y 5 µA dormido, y está activo 40 ms de cada segundo, el promedio es de unos 0.40 mA y una batería de 1,000 mAh dura unos 100 días. Activo 200 ms por segundo, la misma batería dura unos 21 días. Acortar la inferencia, o correrla solo cuando un disparador barato lo indica, muchas veces importa más que cualquier mejora del modelo.

Medir como en un benchmark

El benchmark MLPerf Tiny de Banbury y sus colegas, desarrollado por más de 50 organizaciones, evalúa sistemas de ML diminutos en cuatro tareas (detección de palabras clave, visual wake words, clasificación de imágenes y detección de anomalías) y reporta juntas la exactitud, la latencia y la energía de la inferencia. La lección para cualquier producto es la misma: un resultado es una terna, y un cambio que mejora un número mientras esconde otro no es una mejora.

Etapas del pipeline de inferencia embebida, comparadas

Etapa Qué hace Falla típica Presupuesto que consume Cómo revisarla
Muestreo ADC con temporizador o FIFO del sensor vía DMA Jitter, aliasing Canal DMA, carga de interrupciones Ponle marca de tiempo a las muestras y revisa el espaciado
Buffers Junta ventanas (doble buffer) Desbordamiento cuando el proceso se atrasa RAM (muchas veces el bloque más grande) Contador de desbordamientos en el firmware
Extracción de features FFT, MFCC, energía por banda, estadísticas No coincide con las features de entrenamiento Tiempo de CPU, RAM, tablas constantes Compara features del dispositivo y del entrenamiento con la misma grabación
Modelo cuantizado Inferencia int8 con runtime y kernels Pérdida de exactitud por cuantizar; arena insuficiente Flash (pesos), RAM (arena), tiempo de CPU Corre el modelo cuantizado con datos grabados antes de flashear
Posprocesamiento Suavizado, umbrales, histéresis Falsas alarmas, salidas que parpadean Pequeño Reproduce grabaciones y cuenta falsas alarmas y omisiones
Manejo de energía Dormir entre ventanas, disparadores para despertar El procesador nunca duerme Corriente promedio Mide la corriente durante un ciclo completo

Qué hacer

Escribe primero la fecha límite

A partir de la frecuencia de muestreo, la ventana y el traslape, calcula el intervalo entre ventanas. Ese es el tiempo disponible para features, inferencia y posprocesamiento.

Congela la especificación de las features

Anota cada parámetro de la extracción de features y genera las features de entrenamiento y las del firmware a partir de la misma definición. Pruébalas una contra otra con datos grabados.

Cuantiza pronto y prueba con datos grabados

Convierte el modelo a int8 en cuanto la arquitectura esté estable y evalúa el modelo cuantizado con el mismo conjunto de prueba que el de punto flotante. No esperes a la tarjeta para descubrir la pérdida de exactitud.

Presupuesta la RAM con todo y buffers

Suma los buffers de muestras, los de features y la arena de tensores. Si no caben, reduce la ventana o el traslape antes de achicar el modelo.

Ajusta el posprocesamiento con grabaciones reales

Pasa horas de datos reales del sensor por el pipeline completo y ajusta el suavizado y los umbrales para la tasa de falsas alarmas que tolera la aplicación.

Qué no hacer

No reportes la exactitud del notebook como la del dispositivo. Y no midas el consumo con la inferencia corriendo sin parar si el producto va a trabajar por ciclos; mide el ciclo real.

Cómo ponerlo en práctica

Si tienes una hora

Calcula tu intervalo entre ventanas, tu presupuesto de RAM (buffers más arena) y tu ciclo de trabajo con el tiempo de inferencia actual. Uno de los tres seguramente es la restricción real.

Si tienes un sprint

Graba un conjunto de datos representativo en el hardware de destino, pásalo por el código de features del dispositivo y por el de entrenamiento, y compara las features. Luego corre el modelo cuantizado sobre las features del dispositivo y compara la exactitud con la del notebook.

Si quieres que dure toda la vida del producto

Guarda juntos, versionados como una sola entrega, la especificación de features, el modelo cuantizado, los parámetros de posprocesamiento y la exactitud, latencia y energía medidas. Vuelve a medir las tres cuando cambie cualquier pieza, incluido el sensor.

La pregunta que debes hacerte: “Si mañana cambiara una etapa del pipeline, ¿sabría si la exactitud, la latencia y la batería siguen cumpliendo?”

Preguntas frecuentes

¿Qué es la inferencia embebida?

Es correr un modelo de aprendizaje automático ya entrenado directamente en un microcontrolador o un procesador embebido pequeño, junto al sensor, en lugar de mandar los datos a un servidor. El dispositivo adquiere los datos, calcula las features, corre el modelo y actúa sobre el resultado de forma local.

¿Por qué mi modelo funciona en Python pero no en el microcontrolador?

Las razones más comunes son features calculadas distinto en el dispositivo que en el entrenamiento, pérdida de exactitud por cuantización que no se probó, problemas de muestreo como jitter o aliasing, y un posprocesamiento que toma cada cuadro como un evento. Probar cada etapa con los mismos datos grabados encuentra la diferencia.

¿Cuánta memoria necesita un modelo de TinyML?

Depende del modelo, pero runtimes como TensorFlow Lite Micro están pensados para modelos y runtimes que caben en kilobytes. Los pesos int8 ocupan un byte por parámetro, así que 50,000 parámetros necesitan unos 50 KB de flash, más una arena de RAM para las activaciones y, muchas veces más importante, los buffers de muestras y de features.

¿Qué es la cuantización int8 y para qué se usa?

La cuantización int8 guarda pesos y activaciones como enteros de 8 bits con una escala y un punto cero, así que la inferencia usa aritmética entera. Reduce cuatro veces el almacenamiento de los pesos frente a flotantes de 32 bits y corre eficientemente en microcontroladores sin unidad de punto flotante, normalmente con una pérdida de exactitud pequeña.

¿Cómo se hace benchmark de un sistema de IA embebida?

Mide juntas la exactitud, la latencia y la energía por inferencia en el hardware de destino, como hace MLPerf Tiny. Reporta las condiciones (frecuencia de reloj, memoria, runtime, versión del modelo) para que los resultados se puedan comparar.

Lecturas relacionadas: del sensor a datos útiles: la cadena de señal, cómo medir un demo de IA embebida y cuantización int8 para microcontroladores.

Fuentes

  1. Banbury, C., Reddi, V. J., Torelli, P., Holleman, J., et al. (2021). “MLPerf Tiny Benchmark.” Proceedings of the Neural Information Processing Systems Track on Datasets and Benchmarks. arXiv:2106.07597. https://arxiv.org/abs/2106.07597
  2. David, R., Duke, J., Jain, A., Reddi, V. J., et al. (2021). “TensorFlow Lite Micro: Embedded Machine Learning on TinyML Systems.” Proceedings of Machine Learning and Systems (MLSys). arXiv:2010.08678. https://arxiv.org/abs/2010.08678
  3. Jacob, B., Kligys, S., Chen, B., et al. (2018). “Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference.” 2018 IEEE/CVF Conference on Computer Vision and Pattern Recognition, 2704–2713. https://doi.org/10.1109/CVPR.2018.00286
  4. Lai, L., Suda, N., y Chandra, V. (2018). “CMSIS-NN: Efficient Neural Network Kernels for Arm Cortex-M CPUs.” arXiv:1801.06601. https://arxiv.org/abs/1801.06601
  5. Zhang, Y., Suda, N., Lai, L., y Chandra, V. (2017). “Hello Edge: Keyword Spotting on Microcontrollers.” arXiv:1711.07128. https://arxiv.org/abs/1711.07128
Escrito porAlphaCrew Studio

Creamos contenido técnico y animación, desarrollamos apps y plataformas a la medida y configuramos flujos de trabajo con IA para equipos de ingeniería y tecnología.