Cuando uses Dataflow para la inferencia de AA, te recomendamos que uses la transformación RunInference. Usar esta transformación tiene varios beneficios, incluidos los siguientes:
- Administración inteligente de la memoria del modelo optimizada para un trabajador de Dataflow cuando se realiza la inferencia local.
- Procesamiento por lotes dinámico que usa las características de la canalización y las restricciones definidas por el usuario para optimizar el rendimiento.
- Funciones de backend de Dataflow compatibles con el AA que pueden proporcionar un mejor rendimiento y latencia
- Mecanismos inteligentes de espera exponencial y ajuste de escala automático cuando se alcanzan las cuotas de inferencia remota.
- Métricas listas para la producción y funciones operativas.
Cuando uses RunInference, ten en cuenta lo siguiente:
Administración de la memoria
Cuando cargas un modelo de AA mediano o grande, es posible que tu máquina se quede sin memoria. Dataflow proporciona herramientas para evitar errores de memoria insuficiente (OOM) cuando se cargan modelos de AA. Usa la siguiente tabla para determinar el enfoque adecuado para tu situación.
| Situación | Solución |
|---|---|
| Los modelos son lo suficientemente pequeños como para caber en la memoria. |
Usa la transformación RunInference sin ninguna configuración adicional. La transformación RunInference comparte los modelos entre los subprocesos. Si puedes ajustar un modelo por núcleo de CPU en tu máquina, tu canalización puede usar la configuración predeterminada.
|
| Varios modelos entrenados de forma diferente realizan la misma tarea. | Usa claves por modelo. Para obtener más información, consulta Ejecuta la inferencia de AA con varios modelos entrenados de forma diferente. |
| Se carga un modelo en la memoria, y todos los procesos comparten este modelo. |
Usa el parámetro Si compilas un controlador de modelos personalizado, en lugar de usar el parámetro |
| Debes configurar la cantidad exacta de modelos cargados en tu máquina. |
Para controlar exactamente cuántos modelos se cargan, usa el parámetro
Si compilas un controlador de modelos personalizado, anula el parámetro |
Para obtener más información sobre la administración de memoria con Dataflow, consulta Soluciona problemas de errores de memoria insuficiente de Dataflow.
Agrupación en lotes
Hay muchas formas de realizar el procesamiento por lotes en Beam, pero, cuando se realiza la inferencia, te recomendamos que permitas que la transformación RunInference controle el procesamiento por lotes. Si tu modelo funciona mejor con un tamaño de lote específico, considera restringir los parámetros de tamaño de lote objetivo de RunInference. La mayoría de los controladores de modelos exponen los tamaños de lote máximos y mínimos como parámetros. Por ejemplo, para controlar el tamaño del lote que se ingresa en una canalización de HuggingFace, podrías definir el siguiente controlador de modelos:
mh = HuggingFacePipelineModelHandler('text-classification', min_batch_size=4, max_batch_size=16)
La transformación RunInference siempre respeta el tamaño máximo del lote. El tamaño mínimo del lote es un objetivo, pero no se garantiza que se cumpla en todos los casos. Por ejemplo, consulta Procesamiento por lotes basado en paquetes en la siguiente sección.
Agrupación en lotes basada en paquetes
Dataflow pasa los datos a las transformaciones en paquetes. Estos paquetes pueden variar en tamaño según las heurísticas definidas por Dataflow. Por lo general, los paquetes en las canalizaciones por lotes son bastante grandes (O(cientos) de elementos), mientras que, en las canalizaciones de transmisión, pueden ser bastante pequeños (incluso de tamaño 1).
De forma predeterminada, RunInference genera lotes a partir de cada paquete y no genera lotes entre paquetes. Esto significa que, si tienes un tamaño de lote mínimo de 8, pero solo quedan 3 elementos en tu paquete, RunInference usa un tamaño de lote de 3. La mayoría de los controladores de modelos exponen un parámetro max_batch_duration_secs que te permite anular este comportamiento. Si se establece max_batch_duration_secs, RunInference se agrupa en lotes en todos los paquetes. Si la transformación no puede alcanzar el tamaño de lote objetivo con un solo paquete, espera como máximo max_batch_duration_secs antes de generar un lote. Por ejemplo, para habilitar el procesamiento por lotes entre paquetes cuando se usa una canalización de HuggingFace, puedes definir el siguiente controlador de modelos:
mh = HuggingFacePipelineModelHandler('text-classification', min_batch_size=4, max_batch_size=16, max_batch_duration_secs=3)
Esta función es útil si experimentas tamaños de lote muy bajos en tu canalización. De lo contrario, el costo de sincronización para procesar por lotes en varios paquetes no suele valer la pena, ya que puede provocar una mezcla costosa.
Manejo de fallas
El control de errores es una parte importante de cualquier canalización de producción. Dataflow procesa los elementos en paquetes arbitrarios y vuelve a probar el paquete completo si se produce un error de cualquier elemento de ese paquete. Si no aplicas manejo de errores adicional, Dataflow reintenta los paquetes que incluyen un elemento defectuoso cuatro veces cuando se ejecuta en modo por lotes. Si un paquete individual falla cuatro veces, la canalización fallará por completo. Cuando se ejecuta en modo de transmisión, Dataflow reintenta un paquete que incluye un elemento defectuoso de forma indefinida, lo que puede hacer que la canalización se estanque de forma permanente.
RunInference proporciona un mecanismo de manejo de errores integrado con su funciónwith_exception_handling.
Cuando aplicas esta función, se enrutan todas las fallas a un PCollection de falla independiente junto con sus mensajes de error. Esto te permite volver a procesarlos. Si asocias operaciones de procesamiento previo o posterior con el controlador del modelo, RunInference también las enruta a la recopilación de errores. Por ejemplo, para recopilar todas las fallas de un controlador de modelos con operaciones de procesamiento previo y posterior, usa la siguiente lógica:
main, other = pcoll | RunInference(model_handler.with_preprocess_fn(f1).with_postprocess_fn(f2)).with_exception_handling()
# handles failed preprocess operations, indexed in the order in which they were applied
other.failed_preprocessing[0] | beam.Map(logging.info)
# handles failed inferences
other.failed_inferences | beam.Map(logging.info)
# handles failed postprocess operations, indexed in the order in which they were applied
other.failed_postprocessing[0] | beam.Map(logging.info)
Tiempos de espera
Cuando usas la función with_exception_handling de RunInference, también puedes establecer un tiempo de espera para cada operación, que se cuenta por lote. Esto te permite evitar que una sola inferencia atascada haga que toda la canalización deje de responder. Si se produce un tiempo de espera, el registro con tiempo de espera se enruta al PCollection de falla, se limpia y se vuelve a crear todo el estado del modelo, y continúa la ejecución normal.
# Timeout execution after 60 seconds
main, other = pcoll | RunInference(model_handler).with_exception_handling(timeout=60)
A partir de Beam 2.68.0, también puedes especificar un tiempo de espera con la opción de canalización --element_processing_timeout_minutes. En este caso, un tiempo de espera hace que se reintente un elemento de trabajo fallido hasta que se complete correctamente, en lugar de enrutar la inferencia fallida a una cola de mensajes no entregados.
Trabaja con aceleradores
Cuando usas aceleradores, muchos controladores de modelos tienen configuraciones específicas del acelerador que puedes habilitar. Por ejemplo, cuando usas una GPU y canalizaciones de Hugging Face, te recomendamos que establezcas el parámetro device en GPU:
mh = HuggingFacePipelineModelHandler('text-classification', device='GPU')
También te recomendamos que comiences con una sola instancia de VM y ejecutes tu canalización de forma local allí. Para ello, sigue los pasos que se describen en la guía de solución de problemas de GPU. Esto puede reducir significativamente el tiempo necesario para poner en funcionamiento una canalización. Este enfoque también puede ayudarte a comprender mejor el rendimiento de tu trabajo.
Para obtener más información sobre el uso de aceleradores en Dataflow, consulta la documentación de Dataflow sobre GPUs y TPUs.
Administración de dependencias
Las canalizaciones de AA suelen incluir dependencias grandes e importantes, como PyTorch o TensorFlow. Para administrar estas dependencias, te recomendamos que uses contenedores personalizados cuando implementes tu trabajo en producción. Esto garantiza que tu trabajo se ejecute en un entorno estable durante varias ejecuciones y simplifica la depuración.
Para obtener más información sobre la administración de dependencias, consulta la página de administración de dependencias de Python de Beam.
¿Qué sigue?
- Explora los notebooks de Dataflow ML para ver ejemplos prácticos.
- Obtén información detallada sobre el uso del AA con Apache Beam en la documentación de canalizaciones de IA/AA.
- Obtén más información sobre la API de
RunInference. - Obtén más información sobre las métricas que puedes usar para supervisar tu transformación
RunInference. - Regresa a la página Acerca de Dataflow ML para obtener una descripción general de las capacidades de AA de Dataflow.