- Usa modelos que se carguen rápido y requieran una transformación mínima en estructuras listas para la GPU, y optimiza la forma en que se cargan.
- Usa configuraciones que permitan una ejecución simultánea máxima y eficiente para reducir el número de GPUs necesarias para atender una solicitud por segundo y, al mismo tiempo, mantener los costes bajos.
Formas recomendadas de cargar modelos de aprendizaje automático grandes en Cloud Run
Google recomienda almacenar los modelos de aprendizaje automático en imágenes de contenedor o optimizar su carga desde Cloud Storage.
Ventajas e inconvenientes de almacenar y cargar modelos de aprendizaje automático
A continuación se muestra una comparación de las opciones:
Ubicación del modelo | Tiempo de implementación | Experiencia de desarrollo | Tiempo de inicio del contenedor | Coste de almacenamiento |
Imagen del contenedor | Lento. Una imagen que contenga un modelo grande tardará más en importarse a Cloud Run. | Para aplicar los cambios en la imagen del contenedor, será necesario volver a implementar la aplicación, lo que puede ser un proceso lento en el caso de imágenes grandes. | Depende del tamaño del modelo. En el caso de los modelos muy grandes, usa Cloud Storage para obtener un rendimiento más predecible, pero más lento. | Potencialmente, varias copias en Artifact Registry. |
Cloud Storage, cargado mediante el montaje de volúmenes de Cloud Storage FUSE | Rápido. Modelo descargado durante el inicio del contenedor. | No es difícil de configurar y no requiere cambios en la imagen de Docker. | Es rápida cuando usas optimizaciones de red. No paraleliza la descarga. | Una copia en Cloud Storage. |
Cloud Storage, descargado simultáneamente mediante el comando gcloud storage cp de la CLI de Google Cloud o la API de Cloud Storage, tal como se muestra en el ejemplo de código de descarga simultánea del gestor de transferencias.
|
Rápido. Modelo descargado durante el inicio del contenedor. | Es un poco más difícil de configurar, ya que tendrás que instalar la CLI de Google Cloud en la imagen o actualizar el código para usar la API de Cloud Storage. | Es rápida cuando usas optimizaciones de red. Google Cloud CLI descarga el archivo del modelo en paralelo, por lo que es más rápido que el montaje de FUSE. | Una copia en Cloud Storage. |
Internet | Rápido. Modelo descargado durante el inicio del contenedor. | Suele ser más sencillo (muchos frameworks descargan modelos de repositorios centrales). | Normalmente, la calidad es mala e impredecible:
|
Depende del proveedor de alojamiento del modelo. |
Almacenar modelos en imágenes de contenedor
Al almacenar el modelo de aprendizaje automático en la imagen de contenedor, la carga del modelo se beneficiará de la infraestructura de streaming de contenedores optimizada de Cloud Run. Sin embargo, crear imágenes de contenedor que incluyan modelos de aprendizaje automático es un proceso que requiere muchos recursos, sobre todo cuando se trabaja con modelos grandes. En concreto, el proceso de compilación puede verse limitado por el rendimiento de la red. Cuando uses Cloud Build, te recomendamos que utilices una máquina de compilación más potente con un mayor rendimiento de computación y de red. Para ello, crea una imagen con un archivo de configuración de compilación que siga estos pasos:
steps: - name: 'gcr.io/cloud-builders/docker' args: ['build', '-t', 'IMAGE', '.'] - name: 'gcr.io/cloud-builders/docker' args: ['push', 'IMAGE'] images: - IMAGE options: machineType: 'E2_HIGHCPU_32' diskSizeGb: '500'
Puedes crear una copia del modelo por imagen si la capa que contiene el modelo es distinta entre las imágenes (hash diferente). Puede haber costes adicionales de Artifact Registry, ya que puede haber una copia del modelo por imagen si la capa del modelo es única en cada imagen.
Almacenar modelos en Cloud Storage
Para optimizar la carga de modelos de aprendizaje automático al cargar modelos de aprendizaje automático desde Cloud Storage, ya sea mediante montajes de volúmenes de Cloud Storage o directamente con la API o la línea de comandos de Cloud Storage, debes usar VPC directa con el valor del ajuste de salida definido como all-traffic
, junto con Acceso privado de Google.
Cargar modelos de Internet
Para optimizar la carga de modelos de AA desde Internet, dirige todo el tráfico a través de la red de VPC con el valor all-traffic
en el ajuste de salida y configura Cloud NAT para acceder a Internet pública con un ancho de banda alto.
Consideraciones sobre la compilación, la implementación, el tiempo de ejecución y el diseño del sistema
En las siguientes secciones se describen las consideraciones sobre la compilación, la implementación, el tiempo de ejecución y el diseño del sistema.
En tiempo de compilación
En la siguiente lista se muestran los aspectos que debes tener en cuenta al planificar tu compilación:
- Elige una buena imagen base. Debes empezar con una imagen de Deep Learning Containers o del registro de contenedores de NVIDIA para el framework de aprendizaje automático que estés usando. Estas imágenes tienen instalados los paquetes más recientes relacionados con el rendimiento. No recomendamos crear una imagen personalizada.
- Elige modelos cuantizados de 4 bits para maximizar la simultaneidad, a menos que puedas demostrar que afectan a la calidad de los resultados. La cuantización produce modelos más pequeños y rápidos, lo que reduce la cantidad de memoria de GPU necesaria para servir el modelo y puede aumentar el paralelismo en el tiempo de ejecución. Lo ideal es que los modelos se entrenen con la profundidad de bits de destino en lugar de cuantificarse hasta alcanzarla.
- Elige un formato de modelo con tiempos de carga rápidos para minimizar el tiempo de inicio del contenedor, como GGUF. Estos formatos reflejan con mayor precisión el tipo de cuantización de destino y requieren menos transformaciones cuando se cargan en la GPU. Por motivos de seguridad, no utilices puntos de control en formato pickle.
- Crea y calienta cachés de LLM en tiempo de compilación. Inicia el LLM en la máquina de compilación mientras se compila la imagen de Docker. Habilita el almacenamiento en caché de las peticiones y proporciona peticiones comunes o de ejemplo para ayudar a calentar la caché para su uso en el mundo real. Guarda las salidas que genera para cargarlas en el tiempo de ejecución.
- Guarda tu propio modelo de inferencia, que se genera durante el tiempo de compilación. Esto ahorra mucho tiempo en comparación con la carga de modelos almacenados de forma menos eficiente y la aplicación de transformaciones, como la cuantización, al iniciar el contenedor.
En el momento del despliegue
En la siguiente lista se muestran los aspectos que debe tener en cuenta al planificar su implementación:
- Configura la simultaneidad de los servicios con precisión en Cloud Run.
- Ajusta las sondas de inicio en función de tu configuración.
Las sondas de inicio determinan si el contenedor se ha iniciado y está listo para aceptar tráfico. Ten en cuenta estos puntos clave al configurar las sondas de inicio:
- Tiempo de inicio adecuado: deja suficiente tiempo para que tu contenedor, incluidos los modelos, se inicialice y se cargue por completo.
- Verificación de la disponibilidad del modelo: configura tu sonda para que solo se complete cuando tu aplicación esté lista para servir solicitudes. La mayoría de los motores de servicio lo hacen automáticamente cuando el modelo se carga en la memoria de la GPU, lo que evita las solicitudes prematuras.
Ten en cuenta que Ollama puede abrir un puerto TCP antes de que se cargue un modelo. Para solucionar este problema, puedes hacer lo siguiente:
- Precargar modelos: consulta la documentación de Ollama para obtener instrucciones sobre cómo precargar tu modelo durante el inicio.
En tiempo de ejecución
- Gestiona activamente la longitud del contexto admitida. Cuanto más pequeña sea la ventana de contexto que admitas, más consultas podrás ejecutar en paralelo. Los detalles sobre cómo hacerlo dependen del framework.
- Usa las cachés de LLM que has generado en tiempo de compilación. Proporciona las mismas marcas que usaste durante el tiempo de compilación al generar la caché de prefijos y peticiones.
- Carga el modelo guardado que acabas de escribir. Consulta la sección Ventajas y desventajas de almacenar y cargar modelos para ver una comparación de cómo cargar el modelo.
- Si tu framework lo admite, considera la posibilidad de usar una caché de pares clave-valor cuantificados. Esto puede reducir los requisitos de memoria por consulta y permite configurar un mayor paralelismo. Sin embargo, también puede afectar a la calidad.
- Ajusta la cantidad de memoria de la GPU que se va a reservar para los pesos, las activaciones y las cachés de clave-valor del modelo. Configúrala con el valor más alto posible sin que se produzca un error de falta de memoria.
- Comprueba si tu framework tiene alguna opción para mejorar el rendimiento de inicio del contenedor (por ejemplo, mediante la paralelización de la carga de modelos).
- Configura la simultaneidad correctamente en el código de tu servicio. Asegúrate de que el código de tu servicio esté configurado para funcionar con los ajustes de simultaneidad de tu servicio de Cloud Run.
A nivel de diseño del sistema
- Añade cachés semánticas cuando corresponda. En algunos casos, almacenar en caché consultas y respuestas completas puede ser una forma excelente de limitar el coste de las consultas habituales.
- Controla la varianza de tus preámbulos. Las cachés de peticiones solo son útiles cuando contienen las peticiones en secuencia. Las cachés se almacenan en caché de prefijos de forma eficaz. Las inserciones o las ediciones en la secuencia significan que no están en la caché o que solo están presentes parcialmente.
Autoescalado y GPUs
Si usas el autoescalado predeterminado de Cloud Run, Cloud Run escalará automáticamente el número de instancias de cada revisión en función de factores como la utilización de la CPU y la simultaneidad de las solicitudes. Sin embargo, Cloud Run no escala automáticamente el número de instancias en función del uso de la GPU.
En el caso de una revisión con una GPU, si la revisión no tiene un uso significativo de la CPU, Cloud Run se escala horizontalmente para la simultaneidad de las solicitudes. Para conseguir un escalado óptimo de la simultaneidad de las solicitudes, debe definir un número máximo óptimo de solicitudes simultáneas por instancia, tal como se describe en la siguiente sección.
Número máximo de solicitudes simultáneas por instancia
El ajuste Número máximo de solicitudes simultáneas por instancia controla el número máximo de solicitudes que Cloud Run envía a una sola instancia a la vez. Debes ajustar la simultaneidad para que coincida con la simultaneidad máxima que puede gestionar el código de cada instancia con un buen rendimiento.
Concurrencia máxima y cargas de trabajo de IA
Cuando se ejecuta una carga de trabajo de inferencia de IA en una GPU de cada instancia, la simultaneidad máxima que el código puede gestionar con un buen rendimiento depende de detalles específicos del framework y de la implementación. Esto influye en la forma de definir el ajuste óptimo de solicitudes simultáneas máximas:
- Número de instancias de modelo cargadas en la GPU
- Número de consultas paralelas por modelo
- Uso de los procesos por lotes
- Parámetros de configuración de lote específicos
- Cantidad de trabajo que no es de la GPU
Si el número máximo de solicitudes simultáneas es demasiado alto, es posible que las solicitudes tengan que esperar en la instancia para acceder a la GPU, lo que provoca un aumento de la latencia. Si el número máximo de solicitudes simultáneas es demasiado bajo, es posible que la GPU no se utilice lo suficiente, lo que provocará que Cloud Run escale a más instancias de las necesarias.
Una regla general para configurar el número máximo de solicitudes simultáneas de cargas de trabajo de IA es la siguiente:
(Number of model instances * parallel queries per model) + (number of model instances * ideal batch size)
Por ejemplo, supongamos que una instancia carga instancias del modelo 3
en la GPU y que cada instancia del modelo puede gestionar 4
consultas paralelas. El tamaño de lote ideal también es 4
, ya que es el número de consultas paralelas que puede gestionar cada instancia del modelo. Según esta regla general, el número máximo de solicitudes simultáneas sería 24
: (3
* 4
) + (3
* 4
).
Ten en cuenta que esta fórmula es solo una regla general. El ajuste máximo de solicitudes simultáneas ideal depende de los detalles específicos de tu implementación. Para conseguir el rendimiento óptimo real, te recomendamos que pruebes la carga de tu servicio con diferentes ajustes de solicitudes simultáneas máximas para evaluar qué opción ofrece el mejor rendimiento.
Compensaciones entre el rendimiento, la latencia y el coste
Consulta las compensaciones entre el rendimiento, la latencia y los costes para ver cómo influyen las solicitudes simultáneas máximas en el rendimiento, la latencia y el coste. Ten en cuenta que todos los servicios de Cloud Run que usen GPUs deben tener configurada la facturación basada en instancias.