Ingeniería de modelos
Arquitectura de micromodelos para reconocimiento facial en terminales
Cómo comprimir una red neuronal hasta 2 MB sin perder precisión útil
El terminal que usamos como referencia no es nada del otro mundo: un SoC de gama baja con 512 MB de RAM, un NPU que ronda 1 TOPS en int8 y una cámara global shutter de 2 MP. Está montado en el marco de una puerta de acceso, con luz que cambia según la hora y gente que no se detiene a posar. Sobre ese hardware hay que correr un reconocimiento facial que verifique en menos de 300 ms y no consuma más de lo que aguanta una batería de respaldo.
La primera versión del modelo pesaba 6.2 MB en fp32 y no cabía con holgura en la memoria reservada al runtime. La última que desplegamos ocupa 1.8 MB y verifica mejor en movimiento. Lo que sigue es el recorrido entre esos dos puntos, con las decisiones que tomamos y las que descartamos.
Qué se puede podar sin romper la verificación
La poda estructurada por canales fue el primer paso. No tocamos las dos primeras etapas del backbone: son las que sostienen la respuesta a cambios de iluminación y a rostros parcialmente ocluidos por gorras o barbijos. A partir de la tercera etapa sí eliminamos entre el 30 % y el 40 % de los canales con menor norma L2 promedio sobre un set de calibración de 8 000 imágenes capturadas en el propio sitio.
El criterio que usamos no es la magnitud del peso, sino la contribución a la varianza de la activación en la capa siguiente. Con ese criterio, la tasa de verificación (TAR a FAR de 1e-4) cayó 0.4 puntos tras la poda. Con el criterio clásico de magnitud de pesos, la caída era de 1.7 puntos. La diferencia se nota sobre todo en rostros con iluminación lateral fuerte.
Cuantización int8: dónde duele de verdad
La cuantización post-entrenamiento con calibración por percentiles (99.99) fue suficiente para casi toda la red. La excepción fueron las capas de atención del módulo de alineación: ahí la pérdida de precisión se traducía en landmarks que oscilaban dos o tres píxeles entre fotogramas consecutivos, y eso rompía el seguimiento.
La solución fue mantener esas capas en fp16. El coste en tamaño es de unos 180 KB, pero la estabilidad del alineamiento mejora de forma clara. En pruebas con luz variable (de 40 a 4 000 lux, con transiciones bruscas al abrir una puerta al exterior), la caída de TAR con int8 puro era de 2.1 puntos frente al modelo fp32. Con el híbrido int8/fp16 bajó a 0.6 puntos.
Destilado: dos estrategias y por qué elegimos la segunda
Probamos dos rutas. La primera fue destilar desde un ResNet-100 entrenado con un dataset interno de 2.4 millones de rostros. La segunda, destilar desde un modelo intermedio de 12 MB que ya había pasado por poda y cuantización en una iteración anterior.
La ruta directa desde el modelo grande daba mejor precisión en imágenes estáticas, pero el micromodelo resultante era más sensible al motion blur. La segunda ruta, en cambio, arrastraba la regularización implícita del modelo intermedio y generalizaba mejor cuando el rostro se movía. En el banco de pruebas con sujetos caminando a paso normal hacia la cámara, el modelo de 1.8 MB destilado por la segunda ruta superó en 1.3 puntos de TAR al de 6 MB destilado por la primera. Ese fue el argumento decisivo.
Latencia y consumo medidos en el propio terminal
Con el modelo final, la inferencia completa (detección, alineación, embedding y comparación contra una galería de 500 plantillas) tarda 187 ms de media y 241 ms en el percentil 95. El NPU se queda en torno al 62 % de ocupación y el consumo medido en la línea de 3.3 V es de 410 mW durante la inferencia, con picos de 520 mW en la fase de detección.
Eso deja margen para correr el pipeline completo con la cámara a 15 fps sin que el SoC entre en throttling térmico. En un ciclo de 8 horas de operación continua, el terminal no superó los 58 °C en la superficie del disipador, con temperatura ambiente de 31 °C.
Lo que no funcionó
Intentamos bajar de 1.5 MB con poda no estructurada al 70 % y cuantización a int4 en las capas convolucionales profundas. El modelo cabía, pero la tasa de falsos rechazos en personas con barba cerrada o anteojos con reflejo se disparaba. También probamos destilar sin datos del sitio y con datos sintéticos: el resultado era bueno en validación y malo en producción. La lección, otra vez, es que el set de calibración tiene que venir del mismo lugar donde va a trabajar el modelo.
Si te interesa cómo se protegen las plantillas que genera este tipo de modelo una vez que salen del pipeline de inferencia, lo tratamos en detalle en Plantillas biométricas irreversibles. Y si el problema es qué pasa cuando el terminal pierde conexión con el servidor central, el escenario está desarrollado en Inferencia sin nube.