Sebbene le varie opzioni di servizio dei modelli di Vertex AI siano sufficienti per molti casi d'uso, potresti dover utilizzare le tue immagini container per pubblicare i modelli su Vertex AI. Questo documento descrive come utilizzare un'immagine container personalizzata vLLM per pubblicare modelli su Vertex AI su CPU, GPU o TPU. Per saperne di più sui modelli supportati da vLLM, consulta la documentazione di vLLM.
Il server API vLLM implementa il protocollo API OpenAI, ma non supporta i requisiti di richiesta e risposta di Vertex AI. Pertanto, devi utilizzare una richiesta di inferenza non elaborata di Vertex AI per ottenere inferenze dai modelli di cui è stato eseguito il deployment su Vertex AI utilizzando un endpoint Prediction. Per saperne di più sul metodo Raw Prediction nell'SDK Vertex AI Python, consulta la documentazione dell'SDK Python.
Puoi utilizzare modelli di Hugging Face e Cloud Storage. Questo approccio offre flessibilità, consentendoti di sfruttare l'hub di modelli basato sulla community (Hugging Face) e le funzionalità di trasferimento e sicurezza dei dati ottimizzate di Cloud Storage per la gestione interna dei modelli o le versioni ottimizzate.
vLLM scarica i modelli da Hugging Face se viene fornito un token di accesso a Hugging Face. In caso contrario, vLLM presuppone che il modello sia disponibile sul disco locale. L'immagine container personalizzata consente a Vertex AI di scaricare il modello da Google Cloud oltre a Hugging Face.
Prima di iniziare
Nel tuo progetto Google Cloud , abilita le API Vertex AI e Artifact Registry.
gcloud services enable aiplatform.googleapis.com \ artifactregistry.googleapis.comConfigura Google Cloud CLI con l'ID progetto e inizializza l'SDK Vertex AI.
PROJECT_ID = "PROJECT_ID" LOCATION = "LOCATION" import vertexai vertexai.init(project=PROJECT_ID, location=LOCATION)gcloud config set project {PROJECT_ID}Creare un repository Docker in Artifact Registry.
gcloud artifacts repositories create DOCKER_REPOSITORY \ --repository-format=docker \ --location=LOCATION \ --description="Vertex AI Docker repository"(Facoltativo) Se scarichi modelli da Hugging Face, ottieni un token Hugging Face.
- Crea un account Hugging Face se non ne hai uno.
- Per i modelli con accesso limitato come Llama 3.2, richiedi e ricevi l'accesso su Hugging Face prima di procedere.
- Genera un token di accesso: vai a Il tuo profilo > Impostazioni > Token di accesso.
- Seleziona Nuovo token.
- Specifica un nome e un ruolo di almeno Lettura.
- Seleziona Genera un token.
- Salva questo token per i passaggi di deployment.
Prepara i file di compilazione del container
Il seguente Dockerfile crea l'immagine container personalizzata vLLM per GPU, TPU e CPU. Questo container personalizzato scarica i modelli da Hugging Face o
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"]
Crea l'immagine container personalizzata utilizzando Cloud Build. Il seguente file di configurazione
cloudbuild.yaml mostra come creare l'immagine per più piattaforme utilizzando lo stesso 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
I file sono disponibili nel repository GitHub
googlecloudplatform/vertex-ai-samples. Clona il repository per utilizzarli:
git clone https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
Crea ed esegui il push dell'immagine container
Crea l'immagine container personalizzata utilizzando Cloud Build inviando il
file cloudbuild.yaml. Utilizza le sostituzioni per specificare il tipo di dispositivo di destinazione,
che può essere GPU, TPU o CPU, e l'immagine di base corrispondente.
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
CPU
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
Al termine della build, configura Docker per l'autenticazione con Artifact Registry:
gcloud auth configure-docker LOCATION-docker.pkg.dev --quiet
Carica il modello in Model Registry ed esegui il deployment
Carica il modello in Vertex AI Model Registry, crea un endpoint ed esegui il deployment del modello completando questi passaggi. Questo esempio utilizza Llama 3.2 3B, ma puoi adattarlo ad altri modelli.
Definisci le variabili del modello e del deployment. Imposta la variabile
DOCKER_URIsull'immagine che hai creato nel passaggio precedente (ad esempio, per la GPU):DOCKER_URI = f"LOCATION-docker.pkg.dev/PROJECT_ID/DOCKER_REPOSITORY/vllm-gpu"Definisci le variabili per il token Hugging Face e le proprietà del modello. Ad esempio, per il deployment della 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 = 1Carica il modello in Model Registry. La funzione
upload_modelvaria leggermente a seconda del tipo di dispositivo a causa di diversi argomenti vLLM e variabili di ambiente.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)Crea un endpoint.
endpoint = aiplatform.Endpoint.create(display_name=f"model_name-endpoint")Esegui il deployment del modello sull'endpoint. Il deployment del modello potrebbe richiedere 20-30 minuti.
# 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, )Per le TPU, ometti i parametri
accelerator_typeeaccelerator_counte utilizzaautoscaling_target_request_count_per_minute=60. Per le CPU, ometti i parametriaccelerator_typeeaccelerator_counte utilizzaautoscaling_target_cpu_utilization=60.
Carica modelli da Cloud Storage
Il container personalizzato scarica il modello da una posizione Cloud Storage anziché da Hugging Face. Quando utilizzi Cloud Storage:
- Imposta il parametro
model_idnella funzioneupload_modelsu un URI Cloud Storage, ad esempiogs://<var>my-bucket</var>/<var>my-models</var>/<var>llama_3_2_3B</var>. - Ometti la variabile
HF_TOKENdaenv_varsquando chiamiupload_model. - Quando chiami
model.deploy, specifica unservice_accountche disponga delle autorizzazioni di lettura dal bucket Cloud Storage.
Crea un service account IAM per l'accesso a Cloud Storage
Se il modello si trova in Cloud Storage, crea un account di servizio che gli endpoint Vertex Prediction possono utilizzare per accedere agli artefatti del modello.
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"
Quando esegui il deployment, passa l'email del account di servizio al metodo deploy:
service_account=<var>SERVICE_ACCOUNT_EMAIL</var>.
Ottenere previsioni utilizzando l'endpoint
Dopo aver eseguito il deployment del modello nell'endpoint, verifica la risposta del modello utilizzando 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)
Output di esempio:
{
"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
}
Passaggi successivi
- Scegliere un'opzione di pubblicazione del modello aperto
- Utilizzare modelli aperti utilizzando Model as a Service (MaaS)
- Eseguire il deployment di modelli aperti da Model Garden
- Esegui il deployment di modelli aperti con container predefiniti