Prácticas recomendadas: grupos de trabajadores de Cloud Run con GPUs

En esta página, se proporcionan prácticas recomendadas para optimizar el rendimiento cuando se usa un grupo de trabajadores de Cloud Run con cargas de trabajo de IA, como el entrenamiento de modelos de lenguaje grandes (LLM) con tus frameworks preferidos, el ajuste y la inferencia por lotes o sin conexión en LLM. Para crear un grupo de trabajadores de Cloud Run que pueda realizar tareas que requieren mucha capacidad de procesamiento o procesamiento por lotes en tiempo real, debes hacer lo siguiente:
  • 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 la ejecución simultánea máxima y eficiente para reducir la cantidad de GPUs necesarias para atender una solicitud objetivo por segundo y, al mismo tiempo, mantener bajos los costos.

Formas recomendadas de cargar modelos de AA grandes en Cloud Run

Google recomienda almacenar los modelos de AA dentro de imágenes de contenedor o optimizar su carga desde Cloud Storage.

Compensaciones entre el almacenamiento y la carga de modelos de AA

A continuación, se incluye una comparación de las opciones:

Ubicación del modelo Tiempo de implementación Experiencia de desarrollo Tiempo de inicio del contenedor Costo de almacenamiento
Imagen de contenedor Lenta Una imagen que contiene un modelo grande tardará más en importarse a Cloud Run. Los cambios en la imagen de contenedor requerirán una reimplementación, que puede ser lenta para imágenes grandes. Depende del tamaño del modelo. Para modelos muy grandes, usa Cloud Storage para obtener un rendimiento más predecible, pero más lento. Es posible que haya varias copias en Artifact Registry.
Cloud Storage, cargado con la activación de volumen de Cloud Storage FUSE Rápido. El modelo se descargó 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 de forma simultánea con el comando gcloud storage cp de Google Cloud CLI o la API de Cloud Storage, como se muestra en el ejemplo de código de descarga simultánea del administrador de transferencias Rápido. El modelo se descargó durante el inicio del contenedor. Es un poco más difícil de configurar, ya que deberás instalar Google Cloud CLI en la imagen o actualizar tu código para usar la API de Cloud Storage. Es rápida cuando usas optimizaciones de red. La CLI de Google Cloud descarga el archivo del modelo en paralelo, lo que la hace más rápida que el montaje de FUSE. Una copia en Cloud Storage
Internet Rápido. El modelo se descargó durante el inicio del contenedor. Por lo general, son más simples (muchos frameworks descargan modelos de repositorios centrales). Por lo general, es deficiente e impredecible:
  • Los frameworks pueden aplicar transformaciones del modelo durante la inicialización. (deberías hacerlo en el momento de la compilación).
  • Es posible que el host del modelo y las bibliotecas para descargarlo no sean eficientes.
  • Existe un riesgo de confiabilidad asociado con la descarga desde Internet. Es posible que tus grupos de trabajadores no se inicien si el destino de descarga no funciona, y el modelo subyacente descargado podría cambiar, lo que disminuye la calidad. Te recomendamos que lo alojes en tu propio bucket de Cloud Storage.
Depende del proveedor de alojamiento del modelo.

Almacena modelos en imágenes de contenedor

Al almacenar el modelo de AA en la imagen del contenedor, la carga del modelo se beneficiará de la infraestructura optimizada de transmisión de contenedores de Cloud Run. Sin embargo, compilar imágenes de contenedores que incluyan modelos de AA es un proceso que requiere muchos recursos, en especial cuando se trabaja con modelos grandes. En particular, el proceso de compilación puede verse limitado por la capacidad de procesamiento de la red. Cuando uses Cloud Build, te recomendamos que uses una máquina de compilación más potente con mayor rendimiento de procesamiento y redes. Para ello, compila una imagen con un archivo de configuración de compilación que tenga los siguientes 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). Podría haber un costo adicional de Artifact Registry, ya que podría haber una copia del modelo por imagen si la capa del modelo es única en cada imagen.

Almacena modelos en Cloud Storage

Para optimizar la carga de modelos de AA cuando se cargan modelos de AA desde Cloud Storage, ya sea con activaciones 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 de configuración de salida establecido en all-traffic, junto con el Acceso privado a Google.

Por un costo adicional, usar Anywhere Cache puede reducir la latencia de carga del modelo almacenando datos de manera eficiente en SSD para lecturas más rápidas.

Para reducir los tiempos de lectura del modelo, prueba las siguientes opciones de activación para habilitar las funciones de Cloud Storage FUSE:

  • cache-dir: Habilita la función de almacenamiento en caché de archivos con un activación de volumen en la memoria para usar como directorio subyacente para conservar archivos. Establece el valor de la opción de montaje cache-dir en el nombre del volumen en memoria con el formato cr-volume:{volume name}. Por ejemplo, si tienes un volumen en memoria llamado in-memory-1 que deseas usar como directorio de caché, especifica cr-volume:in-memory-1. Cuando se establece este valor, también puedes establecer otras marcas de file-cache disponibles para configurar la caché.
  • enable-buffered-read: Establece el campo enable-buffered-read en true para la recuperación previa asíncrona de partes de un objeto de Cloud Storage en un búfer en memoria. Esto permite que las lecturas posteriores se publiquen desde el búfer en lugar de requerir llamadas de red. Cuando configuras este campo, también puedes establecer el campo read-global-max-blocks para configurar la cantidad máxima de bloques disponibles para las lecturas almacenadas en búfer en todos los identificadores de archivos.

Cuando se usan cache-dir y enable-buffered-read, cache-dir tendrá prioridad. Ten en cuenta que habilitar cualquiera de estas funciones cambiará el registro de recursos del proceso de Cloud Storage FUSE para que se contabilice según los límites de memoria del contenedor. Considera aumentar el límite de memoria del contenedor siguiendo las instrucciones para configurar los límites de memoria.

Carga modelos de Internet

Para optimizar la carga de modelos de AA desde Internet, enruta todo el tráfico a través de la red de VPC con el valor de configuración de salida establecido en all-traffic y configura Cloud NAT para acceder a la Internet pública con un ancho de banda alto.

Consideraciones de diseño del sistema, tiempo de ejecución, implementación y compilación

En las siguientes secciones, se describen las consideraciones para el diseño del sistema, la compilación, la implementación y el tiempo de ejecución.

En el momento de la compilación

En la siguiente lista, se muestran las consideraciones que debes tener en cuenta cuando planifiques tu compilación:

  • Elige una buena imagen base. Debes comenzar con una imagen de los contenedores de aprendizaje profundo o del registro de contenedores de NVIDIA para el framework de IA que usas. Estas imágenes tienen instalados los paquetes relacionados con el rendimiento más recientes. No recomendamos crear una imagen personalizada.
  • Elige modelos cuantificados de 4 bits para maximizar la simultaneidad, a menos que puedas demostrar que afectan 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 entregar 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 objetivo en lugar de cuantificarse a la baja 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 objetivo y requieren menos transformaciones cuando se cargan en la GPU. Por motivos de seguridad, no uses puntos de control en formato pickle.
  • Crear y mantener activas cachés de LLM en el 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 instrucciones y proporciona instrucciones comunes o de ejemplo para ayudar a activar la caché para el uso en el mundo real. Guarda los resultados que genera para que se carguen en el tiempo de ejecución.
  • Guarda tu propio modelo de inferencia que generes durante el tiempo de compilación. Esto ahorra una cantidad significativa de tiempo en comparación con la carga de modelos almacenados de manera menos eficiente y la aplicación de transformaciones, como la cuantización, al inicio del contenedor.

Durante la implementación

En la siguiente lista, se muestran las consideraciones que debes tener en cuenta cuando planifiques tu implementación:

  • Los grupos de trabajadores con GPU no se pueden ajustar automáticamente. Se te cobrará por la GPU incluso si no está ejecutando ningún proceso.
  • La CPU y la memoria de los grupos de trabajadores tienen un precio diferente al de los servicios y los trabajos. Sin embargo, el SKU de GPU tiene el mismo precio que los servicios y los trabajos.

En el tiempo de ejecución.

  • Administra de forma activa 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 para hacerlo dependen del framework.
  • Usar las cachés de LLM que generaste en el tiempo de compilación Proporciona las mismas marcas que usaste durante el tiempo de compilación cuando generaste la caché de instrucciones y prefijos.
  • Carga el modelo guardado que acabas de escribir. Consulta Almacenamiento y carga de modelos: comparativa de las ventajas y desventajas para obtener una comparación sobre cómo cargar el modelo.
  • Considera usar una caché de clave-valor cuantificada si tu framework la admite. Esto puede reducir los requisitos de memoria por búsqueda y permite configurar más paralelismo. Sin embargo, también puede afectar la calidad.
  • Ajusta la cantidad de memoria de GPU que se reservará para los pesos del modelo, las activaciones y las cachés de clave-valor. Establécela lo más alto posible sin que se produzca un error de memoria insuficiente.
  • Comprueba si tu framework tiene alguna opción para mejorar el rendimiento de inicio del contenedor (por ejemplo, usar la paralelización de la carga del modelo).

A nivel del diseño del sistema

  • Agrega cachés semánticas cuando corresponda. En algunos casos, almacenar en caché consultas y respuestas completas puede ser una excelente manera de limitar el costo de las consultas comunes.
  • Controla la varianza en tus preámbulos. Las memorias caché de instrucciones solo son útiles cuando contienen las instrucciones en secuencia. Las cachés se almacenan de forma eficaz con prefijos. Las inserciones o ediciones en la secuencia significan que no están almacenadas en caché o que solo están presentes de forma parcial.