Bien que les différentes options de diffusion de modèles Vertex AI soient suffisantes pour de nombreux cas d'utilisation, vous devrez peut-être utiliser vos propres images de conteneur pour diffuser des modèles sur Vertex AI. Ce document explique comment utiliser une image de conteneur vLLM personnalisée pour diffuser des modèles sur Vertex AI sur des CPU, des GPU ou des TPU. Pour en savoir plus sur les modèles compatibles avec vLLM, consultez la documentation vLLM.
Le serveur d'API vLLM implémente le protocole de l'API OpenAI, mais il n'est pas compatible avec les exigences de Vertex AI concernant les requêtes et les réponses. Par conséquent, vous devez utiliser une demande d'inférence brute Vertex AI pour obtenir des inférences à partir de modèles déployés sur Vertex AI à l'aide d'un point de terminaison de prédiction. Pour en savoir plus sur la méthode de prédiction brute dans le SDK Vertex AI pour Python, consultez la documentation du SDK Python.
Vous pouvez obtenir des modèles à partir de Hugging Face et de Cloud Storage. Cette approche offre de la flexibilité, ce qui vous permet de profiter du hub de modèles axé sur la communauté (Hugging Face) et des fonctionnalités optimisées de transfert de données et de sécurité de Cloud Storage pour la gestion des modèles internes ou les versions affinées.
vLLM télécharge les modèles depuis Hugging Face si un jeton d'accès Hugging Face est fourni. Sinon, vLLM suppose que le modèle est disponible sur le disque local. L'image de conteneur personnalisée permet à Vertex AI de télécharger le modèle à partir deGoogle Cloud en plus de Hugging Face.
Avant de commencer
Dans votre projet Google Cloud , activez les API Vertex AI et Artifact Registry.
gcloud services enable aiplatform.googleapis.com \ artifactregistry.googleapis.comConfigurez la Google Cloud CLI avec votre ID de projet et initialisez le SDK Vertex AI.
PROJECT_ID = "PROJECT_ID" LOCATION = "LOCATION" import vertexai vertexai.init(project=PROJECT_ID, location=LOCATION)gcloud config set project {PROJECT_ID}créer un dépôt Docker dans Artifact Registry ;
gcloud artifacts repositories create DOCKER_REPOSITORY \ --repository-format=docker \ --location=LOCATION \ --description="Vertex AI Docker repository"Facultatif : Si vous téléchargez des modèles depuis Hugging Face, obtenez un jeton Hugging Face.
- Créez un compte Hugging Face si vous n'en avez pas.
- Pour les modèles avec accès restreint comme Llama 3.2, demandez et obtenez l'accès sur Hugging Face avant de continuer.
- Générez un jeton d'accès : accédez à Votre profil > Paramètres > Jetons d'accès.
- Sélectionnez New Token (Nouveau jeton).
- Spécifiez un nom et un rôle d'au moins Lecture.
- Sélectionnez Générer un jeton.
- Enregistrez ce jeton pour les étapes de déploiement.
Préparer les fichiers de compilation du conteneur
Le Dockerfile suivant crée l'image de conteneur personnalisée vLLM pour les GPU, les TPU et les CPU. Ce conteneur personnalisé télécharge des modèles depuis Hugging Face ou Cloud Storage.
ARG BASE_IMAGE
FROM ${BASE_IMAGE}
ENV DEBIAN_FRONTEND=noninteractive
# Install gcloud SDK
RUN apt-get update && \
apt-get install -y apt-utils git apt-transport-https gnupg ca-certificates curl \
&& echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list \
&& curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg \
&& apt-get update -y && apt-get install google-cloud-cli -y \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /workspace/vllm
# Copy entrypoint.sh to the container
COPY ./entrypoint.sh /workspace/vllm/vertexai/entrypoint.sh
RUN chmod +x /workspace/vllm/vertexai/entrypoint.sh
ENTRYPOINT ["/workspace/vllm/vertexai/entrypoint.sh"]
Créez l'image de conteneur personnalisée à l'aide de Cloud Build. Le fichier de configuration cloudbuild.yaml suivant montre comment créer l'image pour plusieurs plates-formes à l'aide du même fichier Dockerfile.
steps:
- name: 'gcr.io/cloud-builders/docker'
automapSubstitutions: true
script: |
#!/usr/bin/env bash
set -euo pipefail
device_type_param=${_DEVICE_TYPE}
device_type=${device_type_param,,}
base_image=${_BASE_IMAGE}
image_name="vllm-${_DEVICE_TYPE}"
if [[ $device_type == "cpu" ]]; then
echo "Quietly building open source vLLM CPU container image"
git clone https://github.com/vllm-project/vllm.git
cd vllm && DOCKER_BUILDKIT=1 docker build -t $base_image -f docker/Dockerfile.cpu . -q
cd ..
fi
echo "Quietly building container image for: $device_type"
docker build -t $LOCATION-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/$image_name --build-arg BASE_IMAGE=$base_image . -q
docker push $LOCATION-docker.pkg.dev/$PROJECT_ID/${_REPOSITORY}/$image_name
substitutions:
_DEVICE_TYPE: gpu
_BASE_IMAGE: vllm/vllm-openai
_REPOSITORY: my-docker-repo
Les fichiers sont disponibles dans le dépôt GitHub googlecloudplatform/vertex-ai-samples. Clonez le dépôt pour les utiliser :
git clone https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
Créer et transférer l'image de conteneur
Créez l'image de conteneur personnalisée à l'aide de Cloud Build en envoyant le fichier cloudbuild.yaml. Utilisez des substitutions pour spécifier le type d'appareil cible (GPU, TPU ou CPU) et l'image de base correspondante.
GPU
DEVICE_TYPE="gpu"
BASE_IMAGE="vllm/vllm-openai"
cd vertex-ai-samples/notebooks/official/prediction/vertexai_serving_vllm/cloud-build && \
gcloud builds submit \
--config=cloudbuild.yaml \
--region=LOCATION \
--timeout="2h" \
--machine-type=e2-highcpu-32 \
--substitutions=_REPOSITORY=DOCKER_REPOSITORY,_DEVICE_TYPE=$DEVICE_TYPE,_BASE_IMAGE=$BASE_IMAGE
TPU
DEVICE_TYPE="tpu"
BASE_IMAGE="vllm/vllm-tpu:nightly"
cd vertex-ai-samples/notebooks/official/prediction/vertexai_serving_vllm/cloud-build && \
gcloud builds submit \
--config=cloudbuild.yaml \
--region=LOCATION \
--timeout="2h" \
--machine-type=e2-highcpu-32 \
--substitutions=_REPOSITORY=DOCKER_REPOSITORY,_DEVICE_TYPE=$DEVICE_TYPE,_BASE_IMAGE=$BASE_IMAGE
Processeur
DEVICE_TYPE="cpu"
BASE_IMAGE="vllm-cpu-base"
cd vertex-ai-samples/notebooks/official/prediction/vertexai_serving_vllm/cloud-build && \
gcloud builds submit \
--config=cloudbuild.yaml \
--region=LOCATION \
--timeout="2h" \
--machine-type=e2-highcpu-32 \
--substitutions=_REPOSITORY=DOCKER_REPOSITORY,_DEVICE_TYPE=$DEVICE_TYPE,_BASE_IMAGE=$BASE_IMAGE
Une fois la compilation terminée, configurez Docker pour qu'il s'authentifie auprès d'Artifact Registry :
gcloud auth configure-docker LOCATION-docker.pkg.dev --quiet
Importer un modèle dans Model Registry et le déployer
Importez votre modèle dans Vertex AI Model Registry, créez un point de terminaison et déployez le modèle en suivant ces étapes. Cet exemple utilise Llama 3.2 3B, mais vous pouvez l'adapter à d'autres modèles.
Définissez les variables de modèle et de déploiement. Définissez la variable
DOCKER_URIsur l'image que vous avez créée à l'étape précédente (par exemple, pour le GPU) :DOCKER_URI = f"LOCATION-docker.pkg.dev/PROJECT_ID/DOCKER_REPOSITORY/vllm-gpu"Définissez les variables pour le jeton Hugging Face et les propriétés du modèle. Par exemple, pour le déploiement de GPU :
hf_token = "your-hugging-face-auth-token" model_name = "gpu-llama3_2_3B-serve-vllm" model_id = "meta-llama/Llama-3.2-3B" machine_type = "g2-standard-8" accelerator_type = "NVIDIA_L4" accelerator_count = 1Importez le modèle dans Model Registry. La fonction
upload_modelvarie légèrement en fonction du type d'appareil en raison des différents arguments vLLM et variables d'environnement.from google.cloud import aiplatform def upload_model_gpu(model_name, model_id, hf_token, accelerator_count, docker_uri): vllm_args = [ "python3", "-m", "vllm.entrypoints.openai.api_server", "--host=0.0.0.0", "--port=8080", f"--model={model_id}", "--max-model-len=2048", "--gpu-memory-utilization=0.9", "--enable-prefix-caching", f"--tensor-parallel-size={accelerator_count}", ] env_vars = { "HF_TOKEN": hf_token, "LD_LIBRARY_PATH": "$LD_LIBRARY_PATH:/usr/local/nvidia/lib64", } model = aiplatform.Model.upload( display_name=model_name, serving_container_image_uri=docker_uri, serving_container_args=vllm_args, serving_container_ports=[8080], serving_container_predict_route="/v1/completions", serving_container_health_route="/health", serving_container_environment_variables=env_vars, serving_container_shared_memory_size_mb=(16 * 1024), # 16 GB serving_container_deployment_timeout=1800, ) return model def upload_model_tpu(model_name, model_id, hf_token, tpu_count, docker_uri): vllm_args = [ "python3", "-m", "vllm.entrypoints.openai.api_server", "--host=0.0.0.0", "--port=8080", f"--model={model_id}", "--max-model-len=2048", "--enable-prefix-caching", f"--tensor-parallel-size={tpu_count}", ] env_vars = {"HF_TOKEN": hf_token} model = aiplatform.Model.upload( display_name=model_name, serving_container_image_uri=docker_uri, serving_container_args=vllm_args, serving_container_ports=[8080], serving_container_predict_route="/v1/completions", serving_container_health_route="/health", serving_container_environment_variables=env_vars, serving_container_shared_memory_size_mb=(16 * 1024), # 16 GB serving_container_deployment_timeout=1800, ) return model def upload_model_cpu(model_name, model_id, hf_token, docker_uri): vllm_args = [ "python3", "-m", "vllm.entrypoints.openai.api_server", "--host=0.0.0.0", "--port=8080", f"--model={model_id}", "--max-model-len=2048", ] env_vars = {"HF_TOKEN": hf_token} model = aiplatform.Model.upload( display_name=model_name, serving_container_image_uri=docker_uri, serving_container_args=vllm_args, serving_container_ports=[8080], serving_container_predict_route="/v1/completions", serving_container_health_route="/health", serving_container_environment_variables=env_vars, serving_container_shared_memory_size_mb=(16 * 1024), # 16 GB serving_container_deployment_timeout=1800, ) return model # Example for GPU: vertexai_model = upload_model_gpu(model_name, model_id, hf_token, accelerator_count, DOCKER_URI)Créez un point de terminaison.
endpoint = aiplatform.Endpoint.create(display_name=f"model_name-endpoint")Déployez le modèle sur le point de terminaison. Le déploiement du modèle peut prendre entre 20 et 30 minutes.
# Example for GPU: vertexai_model.deploy( endpoint=endpoint, deployed_model_display_name=model_name, machine_type=machine_type, accelerator_type=accelerator_type, accelerator_count=accelerator_count, traffic_percentage=100, deploy_request_timeout=1800, min_replica_count=1, max_replica_count=4, autoscaling_target_accelerator_duty_cycle=60, )Pour les TPU, omettez les paramètres
accelerator_typeetaccelerator_count, et utilisezautoscaling_target_request_count_per_minute=60. Pour les processeurs, omettez les paramètresaccelerator_typeetaccelerator_count, et utilisezautoscaling_target_cpu_utilization=60.
Charger des modèles depuis Cloud Storage
Le conteneur personnalisé télécharge le modèle à partir d'un emplacement Cloud Storage au lieu de le télécharger à partir de Hugging Face. Lorsque vous utilisez Cloud Storage :
- Définissez le paramètre
model_iddans la fonctionupload_modelsur un URI Cloud Storage, par exemplegs://<var>my-bucket</var>/<var>my-models</var>/<var>llama_3_2_3B</var>. - Omettez la variable
HF_TOKENdeenv_varslorsque vous appelezupload_model. - Lorsque vous appelez
model.deploy, spécifiez unservice_accountqui dispose des autorisations nécessaires pour lire les données du bucket Cloud Storage.
Créer un compte de service IAM pour accéder à Cloud Storage
Si votre modèle se trouve dans Cloud Storage, créez un compte de service que les points de terminaison Vertex Prediction peuvent utiliser pour accéder aux artefacts du modèle.
SERVICE_ACCOUNT_NAME = "vertexai-endpoint-sa"
SERVICE_ACCOUNT_EMAIL = f"SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com"
gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
--display-name="Vertex AI Endpoint Service Account"
# Grant storage read permission
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/storage.objectViewer"
Lors du déploiement, transmettez l'adresse e-mail du compte de service à la méthode deploy :
service_account=<var>SERVICE_ACCOUNT_EMAIL</var>.
Obtenir des prédictions à l'aide d'un point de terminaison
Une fois le modèle déployé sur le point de terminaison, vérifiez la réponse du modèle à l'aide de raw_predict.
import json
PROMPT = "Distance of moon from earth is "
request_body = json.dumps(
{
"prompt": PROMPT,
"temperature": 0.0,
},
)
raw_response = endpoint.raw_predict(
body=request_body, headers={"Content-Type": "application/json"}
)
assert raw_response.status_code == 200
result = json.loads(raw_response.text)
for choice in result["choices"]:
print(choice)
Exemple de résultat :
{
"index": 0,
"text": "384,400 km. The moon is 1/4 of the earth's",
"logprobs": null,
"finish_reason": "length",
"stop_reason": null,
"prompt_logprobs": null
}
Étapes suivantes
- Choisir une option de diffusion de modèle ouvert
- Utiliser des modèles ouverts avec le modèle en tant que service (MaaS)
- Déployer des modèles Open Source à partir de Model Garden
- Déployer des modèles ouverts avec des conteneurs prédéfinis