Rendimiento y GPU
Este documento explica cómo Mantis decide qué corre en cada GPU, qué frenos impiden que un servidor se sature, y cómo dimensionar el hardware de una sede. Todas las cifras están medidas en el servidor de Girardot (dos NVIDIA RTX A4000 de 16 GB, 35 cámaras H.265 a 1080p), no estimadas.
Resumen para quien tiene prisa
Sección titulada «Resumen para quien tiene prisa»| Pregunta | Respuesta corta |
|---|---|
| ¿Mantis usa todas las GPU? | Sí, y en tres niveles distintos a la vez |
| ¿Qué pasa si una se llena? | Deja de aceptar trabajo nuevo antes de saturarse |
| ¿Cuántas cámaras aguanta una tarjeta? | ~17 con reconocimiento facial continuo |
| ¿Y si solo hay una GPU? | Funciona igual, sin repartir |
El problema: tres consumidores distintos, no uno
Sección titulada «El problema: tres consumidores distintos, no uno»Es tentador pensar en “la carga de IA” como una sola cosa. No lo es. En un servidor de Mantis hay tres consumidores de GPU muy diferentes, y confundirlos lleva a repartos que parecen equilibrados sobre el papel y no lo son:
| Consumidor | Qué es | Cuántos hay | Cómo crece |
|---|---|---|---|
| Modelos de IA | Redes neuronales cargadas en memoria | Uno por worker (~8) | Fijo |
| Decodificadores | Un ffmpeg que convierte H.265 en imágenes |
Uno por cámara | Con las cámaras |
| Transcodificadores | Preparan el vídeo para el navegador | Dos por cámara | Con las cámaras |
El detalle que lo cambia todo: los decodificadores crecen con el número de cámaras, los modelos no. En una sede de 6 cámaras el peso está en los modelos; en una de 35, los decodificadores son mayoría abrumadora.
Un reparto que solo mire los modelos funcionará en la primera sede y fallará en la segunda.
Nivel 1 — Los modelos: un worker por tarjeta
Sección titulada «Nivel 1 — Los modelos: un worker por tarjeta»Cada worker de IA es un proceso independiente, así que basta con decirle a cada
uno qué tarjeta puede ver (CUDA_VISIBLE_DEVICES). Dentro del proceso, esa
tarjeta pasa a ser la número 0 y el código Python no necesita saber nada.
El reparto no es por turnos, sino por peso: los workers no consumen igual. El detector facial ocupa unos 4 GB de memoria de vídeo y el de cuerpo 1,5 GB; el resto, decenas de megabytes. Repartir por turnos puede juntar a los dos grandes en la misma tarjeta.
Se recorren de más pesado a menos y cada uno va a la tarjeta menos cargada. Es el algoritmo de bin packing más simple que existe y con media docena de workers da un reparto óptimo.
La tarjeta que pinta la pantalla no está vacía
Sección titulada «La tarjeta que pinta la pantalla no está vacía»Si el servidor tiene un monitor conectado —o una sesión de escritorio remoto abierta— esa tarjeta ya llega con el escritorio de Windows encima: el compositor, el explorador de archivos y lo que el operador tenga abierto.
Mantis lo mide antes de repartir y lo cuenta como carga previa. Sin eso, el reparto trata las dos tarjetas como si estuvieran vacías y carga de más la que ya tiene trabajo.
Nivel 2 — Los decodificadores: uno por cámara
Sección titulada «Nivel 2 — Los decodificadores: uno por cámara»Aquí está el volumen. Con 35 cámaras hay 35 decodificadores solo para el reconocimiento facial, y todos los abre el mismo proceso.
Si heredaran la tarjeta de su worker, los 35 caerían juntos. Por eso el reparto se hace cámara a cámara, no worker a worker.
Por turnos, no por sorteo
Sección titulada «Por turnos, no por sorteo»Se reparten en orden alfabético del nombre de la cámara, en turnos. Es determinista —la misma cámara cae siempre en la misma tarjeta, así que un reinicio no mueve el trabajo de sitio— y además exacto: con cualquier número de cámaras y tarjetas, la diferencia entre la más cargada y la menos cargada es como mucho de una cámara.
Se probó antes con una función de dispersión (hash), que es lo que se suele usar. No reparte bien con pocos elementos: 35 cámaras entre 4 tarjetas daban 15/7/7/6 — un 43 % en una sola. Y es justo en las sedes pequeñas, donde el hardware también es más modesto, donde peor cae.
Un solo juego de decodificadores
Sección titulada «Un solo juego de decodificadores»Dos workers distintos pueden querer la misma cámara. Si cada uno abre su propio decodificador, se decodifica dos veces la misma imagen: el doble de trabajo para el mismo resultado.
Solo el worker que muestrea con frecuencia abre decodificadores propios. Los demás piden el fotograma ya decodificado por HTTP, que cuesta más por petición pero se paga una vez por ciclo en vez de mantener un proceso vivo.
Nivel 3 — Un worker que no cabe en una tarjeta
Sección titulada «Nivel 3 — Un worker que no cabe en una tarjeta»El reconocimiento facial es el caso extremo. Con 35 cámaras revisadas dos veces por segundo son 70 inferencias por segundo, y cada una cuesta unos 30 milisegundos: el 211 % de una tarjeta.
Ningún reparto arregla eso, porque un proceso no puede usar dos GPU a la vez: satura la suya y acumula retraso mientras la otra descansa.
La solución es partir el worker: Mantis lanza una instancia por tarjeta, cada una con la mitad de las cámaras. Cada instancia queda cerca del 105 % de su tarjeta y no se pierde ninguna pasada.
El reparto va por resto, no por rangos
Sección titulada «El reparto va por resto, no por rangos»Podría parecer natural darle a una instancia “las cámaras de la 1 a la 17”. No funciona: los identificadores tienen huecos —cámaras dadas de baja— y partir el rango por la mitad deja una instancia con más trabajo.
Se reparte por el resto de la división del identificador. Con los identificadores reales de Girardot (25 a 52 y 60 a 65, con huecos) el reparto queda en 17 y 18.
Los frenos: que no se sature, pase lo que pase
Sección titulada «Los frenos: que no se sature, pase lo que pase»El reparto evita el problema conocido. Los frenos actúan venga la carga de donde venga: una cámara añadida de golpe, un worker que no libera memoria, o un caso que nadie previó.
Freno por memoria
Sección titulada «Freno por memoria»Antes de arrancar un decodificador se mira cuánta memoria queda en su tarjeta. Si pasa del 85 %, no se arranca: se reintenta en el siguiente ciclo.
El porcentaje solo no basta. El 15 % libre de una tarjeta de 48 GB son 7 GB de sobra; el de una de 4 GB son 600 MB, que un solo modelo se lleva por delante. Por eso se exige además un margen libre mínimo en megabytes. Frena el que primero se cumpla, así que el mismo criterio sirve en hardware grande y pequeño.
Freno por temperatura
Sección titulada «Freno por temperatura»Una tarjeta puede estar al 40 % de memoria y aun así rozando su límite térmico. Son dos formas distintas de llegar al mismo sitio, y se vigilan las dos.
Techo de potencia
Sección titulada «Techo de potencia»Al arrancar la analítica, Mantis limita el consumo de cada tarjeta. Los últimos vatios de una GPU aportan muy poco trabajo y casi todo el calor: la curva de rendimiento por vatio se aplana mucho antes del tope.
El valor se ajusta al rango que admita cada tarjeta, así que funciona igual en hardware distinto.
Ante la duda, se deja pasar
Sección titulada «Ante la duda, se deja pasar»Los tres frenos comparten una regla: si no se puede medir, no se bloquea.
Quedarse sin analítica por no poder consultar el estado de la tarjeta sería peor que el riesgo que se pretende evitar. En una cárcel, una cámara sin analizar es un hueco de seguridad; una tarjeta un poco más cargada, no.
Dimensionar una sede
Sección titulada «Dimensionar una sede»Cifras medidas, para estimar hardware. Todas por tarjeta:
| Concepto | Coste |
|---|---|
| Modelo de reconocimiento facial | ~4 GB de memoria |
| Modelo de detección de cuerpo | ~1,5 GB |
| Decodificador (una cámara 1080p H.265) | ~150 MB |
| Una inferencia facial | ~30 ms |
Regla práctica: una RTX A4000 sostiene unas 17 cámaras con reconocimiento facial continuo. Para 35 cámaras hacen falta dos tarjetas; para 70, cuatro.
Si el reconocimiento facial no es continuo —solo en accesos, o solo en horario laboral— la misma tarjeta rinde para muchas más.
Ajustes que cambian el coste
Sección titulada «Ajustes que cambian el coste»| Ajuste | Efecto |
|---|---|
| Frecuencia de revisión | Proporcional: revisar cada segundo en vez de cada medio segundo cuesta la mitad |
| Tamaño de detección | 640 en vez de 1024 cuesta un 43 % menos, a costa de detectar peor las caras lejanas |
| Número de cámaras con analítica | Proporcional |
Diagnóstico: cómo saber qué está pasando
Sección titulada «Diagnóstico: cómo saber qué está pasando»La Consola de Servidor muestra CPU, memoria, GPU (uso, memoria y temperatura) y latencia de la base de datos, junto a los registros y los controles de arranque y parada.
Al mirar el Administrador de tareas de Windows, la distinción importante:
- “3D” alto, “Video Decode” bajo → la satura la inferencia (los modelos). Se resuelve repartiendo workers o bajando la frecuencia de revisión.
- “Video Decode” alto → la saturan los decodificadores. Se resuelve repartiendo cámaras o reduciendo las que llevan analítica.
Son problemas distintos con soluciones distintas, y el porcentaje global no distingue entre ellos.
Qué hacer si una tarjeta se satura
Sección titulada «Qué hacer si una tarjeta se satura»- Mirar cuál de los dos indicadores está alto (3D o Video Decode).
- Si es 3D: bajar la frecuencia de revisión del detector es el ajuste más directo, y es reversible sin tocar código.
- Si es Video Decode: revisar cuántas cámaras llevan analítica activa.
- Comprobar el reparto en los registros del supervisor: dice qué worker fue a qué tarjeta y con cuánta carga previa.
Un servidor bien dimensionado debería quedar por debajo del 70 % en reposo, para tener margen ante picos.