Optimización de puntos de conexión del Modelo de servicio para producción

Obtenga información sobre cómo optimizar los puntos de conexión de servicio de modelos para cargas de trabajo de producción que requieren un alto rendimiento, una latencia baja y un rendimiento confiable.

Las estrategias de optimización se dividen en tres categorías:

Cuándo optimizar el punto de conexión

Considere la posibilidad de optimizar el punto de conexión de servicio de modelos cuando encuentre cualquiera de los escenarios siguientes:

  • Gran volumen de consultas: la aplicación envía más de 50 000 consultas por segundo (QPS) a un único punto de conexión.
  • Requisitos de latencia: la aplicación requiere tiempos de respuesta de sub-100 ms
  • Escalado de cuellos de botella: los puntos de conexión experimentan acumulación o devuelven errores HTTP 429 durante los picos de tráfico
  • Optimización de costos: quiere reducir los costos de servicio al tiempo que mantiene los objetivos de rendimiento.
  • Preparación para la producción: estás preparándote para pasar de las cargas de trabajo de desarrollo a producción.

Optimizaciones de infraestructura

Las optimizaciones de infraestructura mejoran el enrutamiento de red, el comportamiento de escalado y la capacidad de proceso.

Optimización de rutas

La optimización de rutas proporciona la mejora de infraestructura más importante para cargas de trabajo de alto rendimiento. Al habilitar la optimización de rutas en un punto de conexión, Databricks Model Serving mejora la ruta de acceso de red para las solicitudes de inferencia, lo que da lugar a una comunicación más rápida y directa entre los clientes y los modelos.

Ventajas de rendimiento:

Característica Límite de puntos de conexión estándar Límite de puntos de conexión optimizados para rutas
Consultas por segundo (QPS) por área de trabajo 200 Más de 50 000 (póngase en contacto con Databricks para obtener límites más altos)
Concurrencia de clientes por espacio de trabajo 192-1024 (varía según la región) Sin límite explícito (limitado por la simultaneidad aprovisionada)
Simultaneidad aprovisionada de punto de conexión por entidad atendida 1024 1024 (póngase en contacto con Databricks para obtener límites más altos)

Cuándo usar la optimización de rutas:

  • Cargas de trabajo que requieren más de 200 QPS
  • Aplicaciones con requisitos estrictos de latencia (sobrecarga de sub-50 ms)
  • Implementaciones de producción que sirven a varios usuarios simultáneos

Importante

La optimización de rutas solo está disponible para los puntos de conexión de Modelo de servicio personalizados. Las API de Foundation Model y los modelos externos no admiten la optimización de rutas. Los tokens de OAuth son necesarios para la autenticación; No se admiten tokens de acceso personal.

Consulte Optimización de rutas en puntos de conexión de servicio para obtener instrucciones de configuración y Consultar puntos de conexión de servicio optimizados para rutas para consultar los detalles.

Simultaneidad aprovisionada

La simultaneidad aprovisionada controla cuántas solicitudes simultáneas puede procesar el punto de conexión. Configure la simultaneidad aprovisionada en función de los requisitos de QPS y latencia esperados.

Directrices de configuración:

  • Simultaneidad mínima: ajuste lo suficientemente alto como para controlar el tráfico base sin poner en cola
  • Simultaneidad máxima: fija un nivel lo suficientemente alto para acomodar los picos de tráfico a la vez que controla los costes.
  • Escalado automático: habilite el escalado automático para ajustar dinámicamente la capacidad en función de la demanda

Calcule la simultaneidad necesaria:

Required Concurrency = Target QPS × Average Latency (seconds)

Por ejemplo, si tu objetivo es 100 QPS con una latencia media de 200 ms.

Required Concurrency = 100 × 0.2 = 20

Use pruebas de carga para medir la latencia real y determinar la configuración de simultaneidad óptima.

Tipos de instancia

Elija los tipos de instancia en función de los requisitos de proceso del modelo:

Tipo de instancia Más adecuado para Ventajas y desventajas
CPU (pequeña, mediana, grande) Modelos ligeros, lógica de inferencia simple Menor costo, más lento para los modelos intensivos en cómputo.
GPU (pequeña, mediana, grande) Modelos grandes, cálculos complejos, procesamiento de imágenes y vídeos Mayor costo, rendimiento óptimo para el aprendizaje profundo

Sugerencia

Comience con instancias de CPU para desarrollo y pruebas. Cambie a instancias de GPU solo si observa una latencia de inferencia alta o el modelo requiere un proceso especializado (como operaciones de aprendizaje profundo).

Optimizaciones de modelos

Las optimizaciones de modelos mejoran la velocidad de inferencia y la eficiencia de los recursos.

Tamaño y complejidad del modelo

Tamaño y complejidad del modelo: los modelos más pequeños y menos complejos suelen dar lugar a tiempos de inferencia más rápidos y QPS más altos. Considere las técnicas como la cuantificación del modelo o la eliminación si el modelo es grande.

Batching

Si la aplicación puede enviar varias solicitudes en una sola llamada, habilite el procesamiento por lotes en el lado cliente. Esto puede reducir significativamente la sobrecarga por predicción.

Preprocesamiento y optimización posterior al procesamiento

Descargue el procesamiento previo y posprocesamiento complejos de los puntos finales de servicio para reducir la carga en la infraestructura de inferencia.

Optimizaciones del lado cliente

Las optimizaciones del lado cliente mejoran cómo interactúan las aplicaciones con los puntos de conexión de servicio.

Agrupación de conexiones

La agrupación de conexiones reutiliza las conexiones existentes en lugar de crear nuevas conexiones para cada solicitud, lo que reduce significativamente la sobrecarga.

  • Uso del SDK de Databricks, que implementa automáticamente los procedimientos recomendados de agrupación de conexiones
  • Si usa clientes personalizados, implemente la agrupación de conexiones usted mismo.

Estrategias de control y reintento de errores

Implemente un control sólido de errores para controlar correctamente los errores temporales, especialmente durante los eventos de escalado automático o las interrupciones de red.

Optimización del tamaño de carga

Minimice los tamaños de carga de solicitud y respuesta para reducir el tiempo de transferencia de red y mejorar el rendimiento.

Medición y mejora del rendimiento

Supervisión de rendimiento

Supervise el rendimiento del punto de conexión mediante las herramientas proporcionadas por Model Serving:

Métrica Qué mide Objetivo Acción si se supera
Latencia (P50, P90, P99) Tiempo de respuesta de las solicitudes Dependiente de la aplicación (normalmente <de 100 a 500 ms) Verificar la cola, optimizar el modelo o el cliente
Rendimiento (QPS) Solicitudes completadas por segundo Dependiente de la carga de trabajo Habilitación de la optimización de rutas, aumento de la simultaneidad aprovisionada
Frecuencia de errores Porcentaje de solicitudes con error <1 % Revise los registros de servicio y compruebe si hay problemas de capacidad.
Profundidad de la cola Solicitudes en espera de procesamiento 0 (sin cola) Aumento de la simultaneidad aprovisionada o habilitación del escalado automático
Uso de CPU/memoria Uso de recursos <80% Aumentar el tipo de instancia o incrementar la simultaneidad

Consulte Supervisión de la calidad del modelo y el estado del punto de conexión para obtener instrucciones detalladas de supervisión y Seguimiento y exportación de métricas de mantenimiento de puntos de conexión a Prometheus y Datadog para exportar métricas a herramientas de observabilidad.

Pruebas de carga

Las pruebas de carga miden el rendimiento del punto de conexión en condiciones de tráfico realistas y le ayudan a:

  • Determinación de la configuración de simultaneidad aprovisionada óptima
  • Identificar cuellos de botella de rendimiento
  • Validación de los requisitos de latencia y rendimiento
  • Descripción de la relación entre la simultaneidad de cliente y la simultaneidad del servidor

Consulte Load Testing para atender puntos de conexión.

Solución de problemas de rendimiento habituales

Puesta en cola

Model Serving admite el escalado automático para ajustar la capacidad en función de los patrones de tráfico. Sin embargo, los aumentos repentinos del tráfico pueden provocar colas porque el escalado automático requiere tiempo para detectar una mayor carga y aprovisionar capacidad adicional. Durante este período, las solicitudes entrantes pueden superar temporalmente la capacidad disponible, lo que provoca que las solicitudes se ponen en cola.

La puesta en cola se produce cuando la tasa de solicitudes o la simultaneidad supera la capacidad de procesamiento actual del punto de conexión. Esto suele ocurrir durante picos de tráfico agudos, ráfagas de carga de trabajo o cuando el punto de conexión no tiene simultaneidad aprovisionada suficiente. Los puntos de conexión del Modelo de servicio permite que la puesta en cola temporal controle las ráfagas, pero más allá de un umbral definido, el punto de conexión devuelve errores HTTP 429 (demasiadas solicitudes) para proteger la estabilidad del sistema.

La puesta en cola aumenta la latencia porque las solicitudes en cola esperan antes de procesarse. Para minimizar la puesta en cola:

  • Establezca la simultaneidad aprovisionada mínima lo suficientemente alta como para manejar el tráfico base más las ráfagas típicas.
  • Activar la optimización de rutas para límites de capacidad más alta
  • Implementación de la lógica de reintento con retroceso exponencial en las aplicaciones cliente

Cuellos de botella de API externos

Los modelos suelen llamar a API externas para el enriquecimiento de datos, la recuperación de características u otras tareas durante la inferencia. Estas dependencias externas pueden convertirse en cuellos de botella de rendimiento:

  • Latencia: mida el tiempo de respuesta de cada llamada API externa. La latencia alta en estas llamadas aumenta directamente la latencia general de servicio y reduce el rendimiento.
  • Límites de rendimiento: las API externas pueden imponer límites de velocidad o restricciones de capacidad. Superar estos límites puede causar restricciones, errores y degradación del rendimiento.
  • Tasas de error: los errores frecuentes de las API externas pueden desencadenar reintentos y aumentar la carga en el punto de conexión de servicio.
  • Caché: implemente caché para los datos a los que se accede con frecuencia desde APIs externas para reducir el número de llamadas y mejorar los tiempos de respuesta.

Supervise estos factores para identificar cuellos de botella e implementar optimizaciones dirigidas para cargas de trabajo de alto rendimiento.

Llamadas bloqueantes en código de modelo en endpoints de CPU

En endpoints de servicio en CPU para modelos personalizados que usan gevent workers, una llamada que se bloquea en código compilado puede bloquear todas las solicitudes en ese worker, incluso cuando la llamada se ejecuta en un hilo en segundo plano. Para evitar esto, ejecuta dichas llamadas en un conjunto separado de hilos del sistema operativo.

Un worker de gevent puede atender varias solicitudes al mismo tiempo. Los hilos de Python que inicia tu código de modelo, incluidos threading.Thread y concurrent.futures.ThreadPoolExecutor, se ejecutan como tareas cooperativas de gevent en el hilo del trabajador. Solo cambian en llamadas que gevent hace cooperativas, como la E/S de socket , time.sleepy los bloqueos, por lo que la E/S de red puramente Python, por ejemplo con requests, funciona como se espera. Una llamada que espera dentro de código compilado, como una extensión de C, C++ o Rust, algunos controladores de bases de datos o algunos SDK, no cede el control, por lo que mantiene ocupado todo el trabajador hasta que regresa. Un síntoma común son picos de latencia o tiempos de espera en muchas solicitudes al mismo tiempo que coinciden con un servicio dependiente posterior lento.

Para comprobar si el punto de conexión usa trabajadores de gevent, registre gevent.monkey.is_module_patched("threading") cuando se carga el modelo. En endpoints que no usan gevent, una llamada bloqueada solo retrasa la solicitud que la ha hecho.

El siguiente ayudante ejecuta una llamada en un grupo dedicado de hilos del sistema operativo cuando gevent está activo y, en caso contrario, la llama directamente:

_pool = None


def run_blocking(fn, *args, **kwargs):
    """Run fn on an OS thread when gevent is active. Otherwise, call fn directly."""
    try:
        from gevent import monkey
        from gevent.threadpool import ThreadPool
    except ImportError:
        return fn(*args, **kwargs)
    if not monkey.is_module_patched("threading"):
        return fn(*args, **kwargs)
    global _pool
    if _pool is None:
        _pool = ThreadPool(8)
    return _pool.apply(fn, args, kwargs)

Por ejemplo, en un hilo en segundo plano que escribe registros con un cliente SDK que espera en código compilado, llama run_blocking(client.write, record) en lugar de client.write(record). Tenga en cuenta lo siguiente:

  • fn se ejecuta en un hilo diferente al del llamante, y varias llamadas pueden ejecutarse al mismo tiempo. Úsalo solo con objetos seguros para hilos, crea objetos vinculados a hilos como conexiones de base de datos dentro de fn, y pasa valores específicos de la petición como argumentos. contextvars y los valores de hilos locales que el que llama establece no son visibles dentro de fn. Llama a run_blocking desde el código Python que ejecuta tu modelo, no desde un callback que una biblioteca compilada ejecuta en su propio hilo.
  • Establece un tiempo de espera en la propia llamada bloqueante. Un hilo de pool no se puede cancelar, así que una llamada que nunca devuelva mantiene su hilo. Cuando todos los hilos del pool están ocupados, las nuevas llamadas esperan un hilo libre.
  • La externalización solo ayuda si la llamada compilada libera el bloqueo global del intérprete (GIL) de Python mientras espera.
  • Si fn genera una excepción, run_blocking la vuelve a lanzar en el código llamador.

Recursos adicionales