Hasta aquí aprendimos a construir modelos, entrenarlos, evaluarlos, reutilizar pesos preentrenados y hasta interpretar algunas de sus decisiones. Pero en un proyecto real aparece otra pregunta decisiva: ¿puede este modelo correr de forma útil en el entorno donde debe usarse?
Un modelo puede tener muy buena accuracy y, sin embargo, ser impracticable si consume demasiada memoria, si tarda demasiado en responder o si requiere hardware que no estará disponible en producción. Aquí entra el tema de la optimización de modelos.
En este tema veremos por qué optimizar es tan importante en visión por computadora, qué tipos de optimización existen y qué estrategias suelen usarse para mejorar velocidad, tamaño y eficiencia sin degradar demasiado el rendimiento.
Optimizar un modelo no significa necesariamente hacerlo “matemáticamente mejor” en sentido abstracto. En la práctica, suele significar hacerlo más adecuado para un contexto real de uso.
Eso puede implicar:
En investigación muchas veces se destaca sobre todo la métrica de desempeño. Pero en entornos reales también importan mucho:
Por eso un modelo ligeramente menos preciso puede ser, en la práctica, una mejor solución si logra operar de forma fluida y sostenible.
Dos conceptos muy importantes en optimización son:
Dependiendo de la aplicación, uno puede importar más que el otro. En tiempo real, la latencia suele ser crítica. En procesamiento por lotes, el throughput puede ser más importante.
En aplicaciones de video, un indicador especialmente útil es FPS (frames per second). Este valor resume cuántos cuadros por segundo puede procesar el sistema.
Un detector que procesa 2 FPS puede ser suficiente para ciertos análisis offline, pero no para una cámara que debe reaccionar casi en tiempo real.
Otro aspecto importante es el tamaño del modelo en disco y en memoria. Modelos muy grandes pueden ser problemáticos para:
No solo importa cuánto pesa el archivo del modelo, sino también cuánta memoria requiere durante la inferencia. En visión por computadora esto puede crecer bastante debido a:
Por eso, a veces reducir resolución de entrada o tamaño del batch tiene un gran impacto operativo.
Un error común es pensar que la optimización depende únicamente de cambiar pesos o aplicar técnicas sofisticadas. En realidad, muchas mejoras prácticas vienen de decisiones de sistema, por ejemplo:
La optimización empieza incluso antes del entrenamiento. Si sabemos que el modelo deberá correr en hardware modesto, quizá convenga usar MobileNet o una variante pequeña de YOLO en lugar de una red mucho más pesada.
Una buena elección arquitectónica inicial puede ahorrar muchísimo trabajo posterior.
En visión por computadora, el tamaño de la imagen de entrada influye mucho en el costo computacional. Reducir la resolución puede acelerar la inferencia y bajar consumo de memoria.
Claro que esto también puede afectar la calidad de la predicción, especialmente si los objetos son pequeños o si el detalle fino es importante.
Cuando trabajamos offline o en servidores, procesar varias imágenes juntas puede mejorar throughput. En cambio, para aplicaciones interactivas o en vivo, un batch demasiado grande puede empeorar la latencia percibida.
Por eso el tamaño del batch también es una decisión de optimización dependiente del contexto.
Una técnica muy conocida de optimización es la cuantización. La idea general es representar pesos y, a veces, activaciones con menor precisión numérica que la habitual en punto flotante.
Por ejemplo, pasar de 32 bits a 8 bits puede reducir tamaño y acelerar ciertas operaciones en hardware compatible.
Muchos modelos no necesitan la máxima precisión numérica posible para funcionar razonablemente bien. Eso permite usar representaciones más compactas sin destruir completamente su capacidad predictiva.
El beneficio potencial es grande, aunque siempre hay que medir cuánto rendimiento se pierde.
De forma muy general, suelen distinguirse enfoques como:
La primera se aplica después de entrenar. La segunda intenta preparar al modelo durante el entrenamiento para tolerar mejor la representación reducida.
Otra técnica importante es el pruning, que consiste en eliminar o anular conexiones, pesos o incluso canales poco relevantes.
La intuición es que muchos modelos terminan con cierta redundancia interna. Si identificamos partes que contribuyen poco, podemos reducir complejidad sin perder demasiado desempeño.
El pruning puede conducir a modelos más dispersos (sparse), pero eso no siempre implica automáticamente una aceleración real en cualquier hardware. La ganancia práctica depende mucho de cómo esté implementada la ejecución.
Por eso conviene distinguir entre una mejora teórica del número de parámetros y una mejora efectiva de latencia en producción.
Una estrategia muy interesante es la knowledge distillation. En este enfoque, un modelo grande y potente actúa como “teacher” y ayuda a entrenar un modelo más pequeño “student”.
La idea es transferir parte del conocimiento del modelo grande para que el pequeño rinda mejor de lo que lograría entrenando solo de forma convencional.
Además de cambiar el modelo, muchas veces conviene optimizar el formato en que se ejecuta. Herramientas como TorchScript, ONNX o motores especializados permiten mejorar portabilidad y, en algunos casos, rendimiento.
No entraremos aquí en todo el detalle técnico, pero sí es importante entender que la optimización también pasa por cómo empaquetamos y ejecutamos el modelo.
model.eval() y torch.no_grad()Incluso sin técnicas avanzadas, hay prácticas básicas que mejoran la inferencia:
model.eval()
with torch.no_grad():
salida = model(x)
Esto reduce consumo de memoria y evita trabajo innecesario durante inferencia.
No se puede optimizar bien lo que no se mide. Por eso conviene perfilar el sistema y registrar:
La optimización seria se basa en datos concretos, no en intuiciones vagas.
Un experimento básico de timing puede hacerse así:
import time
import torch
model.eval()
x = torch.randn(1, 3, 224, 224)
inicio = time.time()
with torch.no_grad():
salida = model(x)
fin = time.time()
print("Tiempo de inferencia:", fin - inicio)
Este tipo de medición es muy simple, pero ya ayuda a comparar alternativas y detectar cuellos de botella evidentes.
El dispositivo de ejecución influye enormemente en el rendimiento. Un modelo que funciona muy bien en GPU puede ser demasiado lento en CPU, y viceversa en algunos casos pequeños o livianos.
Además, no todo entorno productivo dispone de GPU. Por eso conviene optimizar pensando en el hardware real de despliegue, no solo en el de desarrollo.
Cuando el modelo debe correr en dispositivos embebidos o móviles, la optimización suele volverse todavía más importante. Allí pesan especialmente:
En esos contextos, una solución menos precisa pero mucho más liviana puede ser claramente preferible.
Algunos errores frecuentes son:
La optimización de modelos de visión por computadora es el puente entre un sistema que funciona en laboratorio y un sistema que realmente puede usarse en producción. No alcanza con que el modelo sea correcto o preciso: tiene que ser ejecutable con los recursos disponibles y responder en tiempos compatibles con la aplicación.
Comprender estos compromisos es fundamental para pasar de la teoría del Deep Learning a soluciones de ingeniería útiles. En muchos proyectos, la diferencia entre una demo y un sistema operativo real está justamente en esta etapa.
En el próximo tema estudiaremos el deployment de modelos de visión artificial, donde veremos cómo llevar estos modelos optimizados a entornos concretos de uso.