Embora as várias opções de apresentação de modelos do Vertex AI sejam suficientes para muitos exemplos de utilização, pode ter de usar as suas próprias imagens de contentores para apresentar modelos no Vertex AI. Este documento descreve como usar uma imagem de contentor personalizada de vLLM para publicar modelos no Vertex AI em CPUs, GPUs ou TPUs. Para mais informações sobre os modelos suportados pelo vLLM, consulte a documentação do vLLM.
O servidor da API vLLM implementa o protocolo da API OpenAI, mas não suporta os requisitos de pedido e resposta da Vertex AI. Por conseguinte, tem de usar um pedido de inferência bruta do Vertex AI para obter inferências de modelos implementados no Vertex AI através de um ponto final de previsão. Para mais informações sobre o método Raw Prediction no Vertex AI Python SDK, consulte a documentação do Python SDK.
Pode obter modelos do Hugging Face e do Cloud Storage. Esta abordagem oferece flexibilidade, o que lhe permite tirar partido do hub de modelos orientado pela comunidade (Hugging Face) e das capacidades de transferência de dados e segurança otimizadas do Cloud Storage para a gestão de modelos internos ou versões ajustadas.
O vLLM transfere os modelos do Hugging Face se for fornecido um token de acesso do Hugging Face. Caso contrário, o vLLM assume que o modelo está disponível no disco local. A imagem do contentor personalizado permite que o Vertex AI transfira o modelo de Google Cloud além do Hugging Face.
Antes de começar
No seu Google Cloud projeto, ative as APIs Vertex AI e Artifact Registry.
gcloud services enable aiplatform.googleapis.com \ artifactregistry.googleapis.comConfigure a CLI do Google Cloud com o ID do projeto e inicialize o SDK do Vertex AI.
PROJECT_ID = "PROJECT_ID" LOCATION = "LOCATION" import vertexai vertexai.init(project=PROJECT_ID, location=LOCATION)gcloud config set project {PROJECT_ID}Crie um repositório Docker no Artifact Registry.
gcloud artifacts repositories create DOCKER_REPOSITORY \ --repository-format=docker \ --location=LOCATION \ --description="Vertex AI Docker repository"Opcional: se transferir modelos do Hugging Face, obtenha um token do Hugging Face.
- Crie uma conta do Hugging Face se não tiver uma.
- Para modelos restritos, como o Llama 3.2, peça e receba acesso no HuggingFace antes de continuar.
- Gere um token de acesso: aceda a O seu perfil > Definições > Tokens de acesso.
- Selecione Novo token.
- Especifique um nome e uma função de, pelo menos, Leitura.
- Selecione Gerar um token.
- Guarde este token para os passos de implementação.
Prepare os ficheiros de compilação do contentor
O comando Dockerfile cria a imagem de contentor personalizada do vLLM para GPUs, TPUs e CPUs. Este contentor personalizado transfere modelos do Hugging Face ou do
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"]
Crie a imagem do contentor personalizada com o Cloud Build. O ficheiro de configuração
cloudbuild.yaml seguinte mostra como criar a imagem para várias
plataformas usando o mesmo 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
Os ficheiros estão disponíveis no repositório do googlecloudplatform/vertex-ai-samples GitHub. Clone o repositório para os usar:
git clone https://github.com/GoogleCloudPlatform/vertex-ai-samples.git
Crie e envie a imagem de contentor
Crie a imagem do contentor personalizado com o Cloud Build enviando o ficheiro
cloudbuild.yaml. Use substituições para especificar o tipo de dispositivo de destino, que pode ser GPU, TPU ou CPU, e a imagem base correspondente.
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
Após a compilação terminar, configure o Docker para autenticar com o Artifact Registry:
gcloud auth configure-docker LOCATION-docker.pkg.dev --quiet
Carregue o modelo para o Registo de modelos e implemente-o
Carregue o seu modelo para o Registo de modelos Vertex AI, crie um ponto final e implemente o modelo através destes passos. Este exemplo usa o Llama 3.2 3B, mas pode adaptá-lo para outros modelos.
Defina as variáveis do modelo e da implementação. Defina a variável
DOCKER_URIpara a imagem que criou no passo anterior (por exemplo, para a GPU):DOCKER_URI = f"LOCATION-docker.pkg.dev/PROJECT_ID/DOCKER_REPOSITORY/vllm-gpu"Defina variáveis para o token do Hugging Face e as propriedades do modelo. Por exemplo, para a implementação de GPUs:
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 = 1Carregue o modelo para o Registo de modelos. A função
upload_modelvaria ligeiramente consoante o tipo de dispositivo devido a diferentes argumentos vLLM e variáveis de 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)Crie um ponto final.
endpoint = aiplatform.Endpoint.create(display_name=f"model_name-endpoint")Implemente o modelo no ponto final. A implementação do modelo pode demorar entre 20 e 30 minutos.
# 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, )Para as TPUs, omita os parâmetros
accelerator_typeeaccelerator_counte useautoscaling_target_request_count_per_minute=60. Para CPUs, omita os parâmetrosaccelerator_typeeaccelerator_counte useautoscaling_target_cpu_utilization=60.
Carregue modelos a partir do Cloud Storage
O contentor personalizado transfere o modelo a partir de uma localização do Cloud Storage em vez de o transferir a partir do Hugging Face. Quando usa o Cloud Storage:
- Defina o parâmetro
model_idna funçãoupload_modelpara um URI do Cloud Storage, por exemplo,gs://<var>my-bucket</var>/<var>my-models</var>/<var>llama_3_2_3B</var>. - Omita a variável
HF_TOKENdeenv_varsquando chamarupload_model. - Quando chamar
model.deploy, especifique umservice_accountque tenha autorizações para ler a partir do contentor do Cloud Storage.
Crie uma conta de serviço da IAM para acesso ao Cloud Storage
Se o seu modelo estiver no Cloud Storage, crie uma conta de serviço que os pontos finais da Vertex AI Prediction possam usar para aceder aos artefactos do modelo.
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 implementar, transmita o email da conta de serviço para o método deploy:
service_account=<var>SERVICE_ACCOUNT_EMAIL</var>.
Receba previsões através do ponto final
Depois de implementar o modelo com êxito no ponto final, valide a resposta do modelo com 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)
Exemplo de saída:
{
"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
}
O que se segue?
- Escolha uma opção de publicação de modelos abertos
- Use modelos abertos através do modelo como serviço (MaaS)
- Implemente modelos abertos do Model Garden
- Implemente modelos abertos com contentores pré-criados