Diffusion de vLLM pour les modèles de langage textuels et multimodals sur les GPU Cloud

Ce guide vous explique comment déployer et mettre en service des modèles Llama 3.1 (texte uniquement) et Llama 3.2 (multimodaux) à l'aide de vLLM dans Vertex AI.

Dans ce document, vous allez apprendre à effectuer les opérations suivantes :

Le schéma suivant résume le workflow global :

Principales fonctionnalités de vLLM

Fonctionnalité Description
PagedAttention Mécanisme d'attention qui gère efficacement la mémoire pour prendre en charge la génération de texte à haut débit et plusieurs requêtes simultanées.
Traitement par lots continu Traite plusieurs requêtes dans un même lot pour maximiser l'utilisation et le débit du GPU.
Streaming de jetons Les jetons sont diffusés au fur et à mesure de leur génération, ce qui est idéal pour les applications à faible latence comme les chatbots.
Compatibilité des modèles Il est compatible avec un large éventail de modèles issus de frameworks tels que Hugging Face Transformers, ce qui simplifie l'intégration et l'expérimentation.
Multi-GPU et multi-hôte Distribue les charges de travail sur plusieurs GPU et hôtes pour augmenter le débit et l'évolutivité.
Déploiement efficace S'intègre aux API telles que l'API OpenAI Chat Completions pour un déploiement simple.
Intégration parfaite aux modèles Hugging Face Compatible avec les artefacts de modèle Hugging Face, ce qui vous permet de déployer des modèles Llama et d'autres modèles populaires tels que Gemma, Phi et Qwen dans un environnement optimisé.
Projet Open Source axé sur la communauté Projet Open Source qui encourage les contributions de la communauté pour améliorer en continu l'efficacité du service LLM.
Tableau 1. Récapitulatif des fonctionnalités de vLLM

Personnalisations vLLM Google Vertex AI

L'implémentation vLLM dans Vertex AI Model Garden est une version personnalisée de la bibliothèque Open Source, optimisée pour les performances, la fiabilité et l'intégration à Google Cloud.

  • Optimisation des performances :
    • Téléchargement parallèle depuis Cloud Storage : accélère le chargement et le déploiement des modèles en récupérant les données depuis Cloud Storage en parallèle.
  • Améliorations des fonctionnalités :
    • LoRA dynamique avec mise en cache améliorée et compatibilité avec Cloud Storage : étend les fonctionnalités LoRA dynamiques avec la mise en cache sur disque local, une gestion robuste des erreurs et la possibilité de charger les pondérations LoRA à partir de chemins Cloud Storage et d'URL signées.
    • Analyse des appels de fonction Llama 3.1/3.2 : inclut une analyse spécialisée pour les appels de fonction Llama 3.1 et 3.2 afin d'améliorer la robustesse.
    • Mise en cache des préfixes de mémoire hôte : ajoute la compatibilité avec la mise en cache des préfixes de mémoire hôte, qui n'est pas disponible dans la bibliothèque vLLM Open Source standard.
    • Décodage spéculatif : Vertex AI fournit des configurations optimisées pour cette fonctionnalité vLLM existante, basées sur des tests internes.
  • Intégration de l'écosystème Vertex AI :
    • Prise en charge des formats d'entrée/sortie de prédiction Vertex AI : assure la compatibilité avec les formats de prédiction Vertex AI pour simplifier le traitement et l'intégration des données.
    • Connaissance des variables d'environnement Vertex : utilise les variables d'environnement Vertex AI (par exemple, AIP_*) pour la configuration et la gestion des ressources.
    • Gestion des gestion des exceptions et robustesse améliorées : inclut une gestion complète des erreurs, une validation des entrées/sorties et des mécanismes d'arrêt du serveur pour améliorer la stabilité.
    • Serveur Nginx pour la capacité : intègre un serveur Nginx pour prendre en charge le déploiement de plusieurs répliques, ce qui améliore l'évolutivité et la haute disponibilité.

Avantages supplémentaires de vLLM

  • Performances de référence : vLLM offre un débit et une latence compétitifs par rapport à d'autres systèmes de diffusion tels que Hugging Face text-generation-inference et FasterTransformer de NVIDIA.
  • Facilité d'utilisation : la bibliothèque dispose d'une API simple qui vous permet d'intégrer et de déployer les modèles Llama 3.1 et 3.2 avec une configuration minimale.
  • Fonctionnalités avancées : vLLM est compatible avec le streaming des sorties et gère les requêtes de longueur variable, ce qui améliore l'interactivité et la réactivité des applications.

Pour obtenir une présentation du système vLLM, consultez l'article.

Modèles compatibles

vLLM est compatible avec un large éventail de modèles. Le tableau suivant présente une sélection de ces modèles. Pour obtenir la liste complète, consultez la page officielle des modèles compatibles de vLLM.

Catégorie Modèles
Meta IA Llama 3.3, Llama 3.2, Llama 3.1, Llama 3, Llama 2, Code Llama
Mistral AI Mistral 7B, Mixtral 8x7B, Mixtral 8x22B et leurs variantes (Instruct, Chat), Mistral-tiny, Mistral-small, Mistral-medium
DeepSeek AI DeepSeek-V3, DeepSeek-R1, DeepSeek-R1-Distill-Qwen-1.5B, DeepSeek-R1-Distill-Qwen-7B, DeepSeek-R1-Distill-Llama-8B, DeepSeek-R1-Distill-Qwen-14B, DeepSeek-R1-Distill-Qwen-32B, DeepSeek-R1-Distill-Llama-70B, Deepseek-vl2-tiny, Deepseek-vl2-small, Deepseek-vl2
MosaicML MPT (7B, 30B) et variantes (Instruct, Chat), MPT-7B-StoryWriter-65k
OpenAI GPT-2, GPT-3, GPT-4, GPT-NeoX
Together AI RedPajama, Pythia
Stability AI StableLM (3B, 7B), StableLM-Alpha-3B, StableLM-Base-Alpha-7B, StableLM-Instruct-Alpha-7B
TII (Technology Innovation Institute) Falcon 7B, Falcon 40B et leurs variantes (Instruct, Chat), Falcon-RW-1B, Falcon-RW-7B
BigScience BLOOM, BLOOMZ
Google FLAN-T5, UL2, Gemma (2B, 7B), PaLM 2,
Salesforce CodeT5, CodeT5+
LightOn Persimmon-8B-base, Persimmon-8B-chat
EleutherAI GPT-Neo, Pythia
AI21 Labs Jamba
Cerebras Cerebras-GPT
Intel Intel-NeuralChat-7B
Autres modèles importants StarCoder, OPT, Baichuan, Aquila, Qwen, InternLM, XGen, OpenLLaMA, Phi-2, Yi, OpenCodeInterpreter, Nous-Hermes, Gemma-it, Mistral-Instruct-v0.2-7B-Zeus,
Tableau 2. Modèles sélectionnés compatibles avec vLLM

Premiers pas dans Model Garden

Vous pouvez utiliser le conteneur de diffusion vLLM Cloud GPUs dans Model Garden via Playground, le déploiement en un clic ou les exemples de notebooks Colab Enterprise. Ce document explique comment utiliser un notebook pour déployer des modèles de la famille Llama.

Ouvrir le notebook Colab Enterprise

Les Playgrounds et les déploiements en un clic sont également disponibles, mais ne sont pas abordés dans ce document.

  1. Accédez à la page de la fiche de modèle Llama 3.1, puis cliquez sur Ouvrir le notebook.
  2. Sélectionnez le notebook Vertex Serving. Le notebook s'ouvre dans Colab Enterprise.
  3. Exécutez les cellules du notebook pour déployer un modèle à l'aide de vLLM et envoyez des requêtes de prédiction au point de terminaison.

Préparation

Avant de commencer, configurez votre projet et votre environnement Google Cloud pour déployer des modèles vLLM.

Activer la facturation

Assurez-vous que la facturation est activée pour votre projet Google Cloud . Pour en savoir plus, consultez Activer, désactiver ou modifier la facturation pour un projet.

Vérifier la disponibilité et les quotas de GPU

Pour exécuter des prédictions avec des GPU hautes performances, vérifiez vos quotas pour les GPU requis dans la région sélectionnée.

Type de machine Type d'accélérateur Régions recommandées
a2-ultragpu-1g 1 NVIDIA_A100_80GB us-central1, us-east4, europe-west4, asia-southeast1
a3-highgpu-8g 8 NVIDIA_H100_80GB us-central1, us-west1, europe-west4, asia-southeast1

Configurer votre projet

Le code suivant configure votre environnement Google Cloud . Le script effectue les actions suivantes :

  • Installation : met à niveau la bibliothèque google-cloud-aiplatform et clone un dépôt avec des fonctions utilitaires.
  • Configuration de l'environnement : définit les variables pour l'ID de votre projet Google Cloud , la région et un bucket Cloud Storage pour stocker les artefacts du modèle.
  • Activation des API : active les API Vertex AI et Compute Engine.
  • Configuration du bucket : crée un bucket Cloud Storage ou vérifie qu'un bucket existant se trouve dans la bonne région.
  • Initialisation de Vertex AI : initialise la bibliothèque cliente Vertex AI avec votre projet, votre emplacement et votre bucket de préproduction.
  • Configuration du compte de service : identifie le compte de service par défaut pour les jobs Vertex AI et lui accorde les autorisations nécessaires.
BUCKET_URI = "gs://"

REGION = ""

! pip3 install --upgrade --quiet 'google-cloud-aiplatform>=1.64.0'
! git clone https://github.com/GoogleCloudPlatform/vertex-ai-samples.git

import datetime
import importlib
import os
import uuid
from typing import Tuple

import requests
from google.cloud import aiplatform

common_util = importlib.import_module(
    "vertex-ai-samples.community-content.vertex_model_garden.model_oss.notebook_util.common_util"
)

models, endpoints = {}, {}

PROJECT_ID = os.environ["GOOGLE_CLOUD_PROJECT"]

if not REGION:
    REGION = os.environ["GOOGLE_CLOUD_REGION"]

print("Enabling Vertex AI API and Compute Engine API.")
! gcloud services enable aiplatform.googleapis.com compute.googleapis.com

now = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
BUCKET_NAME = "/".join(BUCKET_URI.split("/")[:3])

if BUCKET_URI is None or BUCKET_URI.strip() == "" or BUCKET_URI == "gs://":
    BUCKET_URI = f"gs://{PROJECT_ID}-tmp-{now}-{str(uuid.uuid4())[:4]}"
    BUCKET_NAME = "/".join(BUCKET_URI.split("/")[:3])
    ! gsutil mb -l {REGION} {BUCKET_URI}
else:
    assert BUCKET_URI.startswith("gs://"), "BUCKET_URI must start with `gs://`."
    shell_output = ! gsutil ls -Lb {BUCKET_NAME} | grep "Location constraint:" | sed "s/Location constraint://"
    bucket_region = shell_output[0].strip().lower()
    if bucket_region != REGION:
        raise ValueError(
            "Bucket region %s is different from notebook region %s"
            % (bucket_region, REGION)
        )
print(f"Using this Bucket: {BUCKET_URI}")

STAGING_BUCKET = os.path.join(BUCKET_URI, "temporal")
MODEL_BUCKET = os.path.join(BUCKET_URI, "llama3_1")

print("Initializing Vertex AI API.")
aiplatform.init(project=PROJECT_ID, location=REGION, staging_bucket=STAGING_BUCKET)

shell_output = ! gcloud projects describe $PROJECT_ID
project_number = shell_output[-1].split(":")[1].strip().replace("'", "")
SERVICE_ACCOUNT = "your service account email"
print("Using this default Service Account:", SERVICE_ACCOUNT)

! gsutil iam ch serviceAccount:{SERVICE_ACCOUNT}:roles/storage.admin $BUCKET_NAME

! gcloud config set project $PROJECT_ID
! gcloud projects add-iam-policy-binding --no-user-output-enabled {PROJECT_ID} --member=serviceAccount:{SERVICE_ACCOUNT} --role="roles/storage.admin"
! gcloud projects add-iam-policy-binding --no-user-output-enabled {PROJECT_ID} --member=serviceAccount:{SERVICE_ACCOUNT} --role="roles/aiplatform.user"

Utiliser Hugging Face avec Meta Llama 3.1 et 3.2

Pour accéder aux modèles Llama de Meta, vous devez accepter leurs conditions d'utilisation.

Contrat de licence Communauté Meta Llama 3 Figure 1. Contrat de licence Communauté Meta Llama 3

Présentation des collections Meta Llama 3.1 et 3.2

Les collections Llama 3.1 et 3.2 offrent des options flexibles pour diverses tâches, y compris le dialogue multilingue. Pour en savoir plus, consultez la page de présentation de Llama.

  • Llama 3.1 : cette collection inclut des modèles uniquement textuels allant de 8 à 405 milliards de paramètres. Ils sont pré-entraînés et ajustés aux instructions pour générer du texte de haute qualité.
  • Llama 3.2 : cette collection inclut des modèles textuels plus petits (1B, 3B) et des modèles multimodaux plus grands (11B, 90B) qui peuvent traiter à la fois du texte et des images.
  • Architecture du modèle : Llama 3.1 et 3.2 utilisent un framework Transformer autorégressif. Ils sont affinés avec SFT et RLHF pour aligner les modèles sur l'utilité et la sécurité.

Jetons d'accès utilisateur Hugging Face

Ce guide nécessite un jeton d'accès en lecture depuis le Hugging Face Hub.

Paramètres du jeton d'accès Hugging Face Figure 2. Paramètres du jeton d'accès Hugging Face
  1. Générez un jeton d'accès en lecture :

  2. Utilisez le jeton :

    • Utilisez le jeton généré pour vous authentifier et accéder aux dépôts publics ou privés selon les besoins de ce guide.
Gérer le jeton d'accès Hugging Face Figure 3. Gérer le jeton d'accès Hugging Face

Lorsque vous définissez votre jeton en tant que variable d'environnement lors du déploiement, il reste privé pour votre projet. Pour en savoir plus, consultez Hugging Face Access Tokens – Best Practices (Jetons d'accès Hugging Face – Bonnes pratiques).

Déployer un modèle Llama 3.1 uniquement textuel

Cette section vous explique comment déployer un modèle Llama 3.1 uniquement textuel avec vLLM.

Étape 1 : Choisir un modèle à déployer

Sélectionnez une variante du modèle Llama 3.1.

base_model_name = "Meta-Llama-3.1-8B"  # @param ["Meta-Llama-3.1-8B", "Meta-Llama-3.1-8B-Instruct", "Meta-Llama-3.1-70B", "Meta-Llama-3.1-70B-Instruct", "Meta-Llama-3.1-405B-FP8", "Meta-Llama-3.1-405B-Instruct-FP8"]
hf_model_id = "meta-Llama/" + base_model_name

Étape 2 : Configurez le matériel de déploiement et vérifiez le quota

Définissez le GPU et le type de machine appropriés en fonction de la taille du modèle.

if "8b" in base_model_name.lower():
    accelerator_type = "NVIDIA_L4"
    machine_type = "g2-standard-12"
    accelerator_count = 1
elif "70b" in base_model_name.lower():
    accelerator_type = "NVIDIA_L4"
    machine_type = "g2-standard-96"
    accelerator_count = 8
elif "405b" in base_model_name.lower():
    accelerator_type = "NVIDIA_H100_80GB"
    machine_type = "a3-highgpu-8g"
    accelerator_count = 8
else:
    raise ValueError(f"Recommended GPU setting not found for: {accelerator_type} and {base_model_name}.")

Vérifiez que vous disposez d'un quota de GPU suffisant dans votre région.

common_util.check_quota(
    project_id=PROJECT_ID,
    region=REGION,
    accelerator_type=accelerator_type,
    accelerator_count=accelerator_count,
    is_for_training=False,
)

Étape 3 : Définissez la fonction de déploiement

La fonction suivante importe un modèle dans Vertex AI et le déploie sur un point de terminaison à l'aide d'une image Docker vLLM prédéfinie.

def deploy_model_vllm(
    model_name: str,
    model_id: str,
    service_account: str,
    base_model_id: str = None,
    machine_type: str = "g2-standard-8",
    accelerator_type: str = "NVIDIA_L4",
    accelerator_count: int = 1,
    gpu_memory_utilization: float = 0.9,
    max_model_len: int = 4096,
    dtype: str = "auto",
    enable_trust_remote_code: bool = False,
    enforce_eager: bool = False,
    enable_lora: bool = False,
    max_loras: int = 1,
    max_cpu_loras: int = 8,
    use_dedicated_endpoint: bool = False,
    max_num_seqs: int = 256,
) -> Tuple[aiplatform.Model, aiplatform.Endpoint]:
    """Deploys trained models with vLLM into Vertex AI."""
    endpoint = aiplatform.Endpoint.create(
        display_name=f"{model_name}-endpoint",
        dedicated_endpoint_enabled=use_dedicated_endpoint,
    )

    if "8b" in base_model_name.lower():
        accelerator_type = "NVIDIA_L4"
        machine_type = "g2-standard-12"
        accelerator_count = 1
    elif "70b" in base_model_name.lower():
        accelerator_type = "NVIDIA_L4"
        machine_type = "g2-standard-96"
        accelerator_count = 8
    elif "405b" in base_model_name.lower():
        accelerator_type = "NVIDIA_H100_80GB"
        machine_type = "a3-highgpu-8g"
        accelerator_count = 8
    else:
        raise ValueError(f"Recommended GPU setting not found for: {accelerator_type} and {base_model_name}.")

    common_util.check_quota(
        project_id=PROJECT_ID,
        region=REGION,
        accelerator_type=accelerator_type,
        accelerator_count=accelerator_count,
        is_for_training=False,
    )

    vllm_args = [
        "python", "-m", "vllm.entrypoints.api_server",
        "--host=0.0.0.0",
        "--port=8080",
        f"--model={model_id}",
        f"--tensor-parallel-size={accelerator_count}",
        "--swap-space=16",
        f"--gpu-memory-utilization={gpu_memory_utilization}",
        f"--max-model-len={max_model_len}", f"--dtype={dtype}",
        f"--max-loras={max_loras}", f"--max-cpu-loras={max_cpu_loras}",
        f"--max-num-seqs={max_num_seqs}", "--disable-log-stats"
    ]

    if enable_trust_remote_code:
        vllm_args.append("--trust-remote-code")
    if enforce_eager:
        vllm_args.append("--enforce-eager")
    if enable_lora:
        vllm_args.append("--enable-lora")
    if model_type:
        vllm_args.append(f"--model-type={model_type}")

    env_vars = {
        "MODEL_ID": model_id,
        "DEPLOY_SOURCE": "notebook",
        "HF_TOKEN": HF_TOKEN
    }

    model = aiplatform.Model.upload(
        display_name=model_name,
        serving_container_image_uri=VLLM_DOCKER_URI,
        serving_container_args=vllm_args,
        serving_container_ports=[8080],
        serving_container_predict_route="/generate",
        serving_container_health_route="/ping",
        serving_container_environment_variables=env_vars,
        serving_container_shared_memory_size_mb=(16 * 1024),
        serving_container_deployment_timeout=7200,
    )
    print(f"Deploying {model_name} on {machine_type} with {accelerator_count} {accelerator_type} GPU(s).")

    model.deploy(
        endpoint=endpoint,
        machine_type=machine_type,
        accelerator_type=accelerator_type,
        accelerator_count=accelerator_count,
        deploy_request_timeout=1800,
        service_account=service_account,
    )
    print("endpoint_name:", endpoint.name)

    return model, endpoint

Étape 4 : Déployer le modèle

Appelez la fonction de déploiement avec le modèle et la configuration de votre choix. Selon la taille du modèle, cette étape peut prendre jusqu'à une heure. Pour suivre la progression, consultez la section sur la prédiction en ligne.

HF_TOKEN = ""

VLLM_DOCKER_URI = "us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20241001_0916_RC00"

model_name = common_util.get_job_name_with_datetime(prefix=f"{base_model_name}-serve-vllm")
gpu_memory_utilization = 0.9
max_model_len = 4096
max_loras = 1

models["vllm_gpu"], endpoints["vllm_gpu"] = deploy_model_vllm(
    model_name=common_util.get_job_name_with_datetime(prefix=f"{base_model_name}-serve"),
    model_id=hf_model_id,
    service_account=SERVICE_ACCOUNT,
    machine_type=machine_type,
    accelerator_type=accelerator_type,
    accelerator_count=accelerator_count,
    gpu_memory_utilization=gpu_memory_utilization,
    max_model_len=max_model_len,
    max_loras=max_loras,
    enforce_eager=True,
    enable_lora=True,
    use_dedicated_endpoint=use_dedicated_endpoint,
)
Point de terminaison de déploiement Llama 3.1 dans le tableau de bord Vertex Figure 4. Point de terminaison de déploiement Llama 3.1 dans le tableau de bord Vertex

Effectuer des prédictions avec un modèle Llama 3.1

Une fois le modèle Llama 3.1 déployé, vous pouvez envoyer des requêtes textuelles au point de terminaison pour générer des réponses.

Étape 1 : Définissez votre requête et vos paramètres

Configurez votre requête textuelle et vos paramètres d'échantillonnage pour guider la réponse du modèle.

  • prompt : texte d'entrée pour le modèle.
  • max_tokens : nombre maximal de jetons dans le résultat généré.
  • temperature : contrôle le caractère aléatoire des prédictions. Des valeurs plus élevées (1,0, par exemple) augmentent la diversité, tandis que des valeurs plus faibles (0,2, par exemple) rendent le résultat plus ciblé.
  • top_p : limite le pool d'échantillonnage à la probabilité cumulative la plus élevée.
  • top_k : limite l'échantillonnage aux k jetons les plus probables.
  • raw_response : si la valeur est True, renvoie la sortie brute du modèle. Si la valeur est False, met en forme le résultat.
  • lora_id (facultatif) : chemin d'accès aux fichiers de poids LoRA (URL d'un bucket Cloud Storage ou d'un dépôt Hugging Face). Pour ce faire, --enable-lora doit être défini lors du déploiement.
prompt = "What is a car?"
max_tokens = 50
temperature = 1.0
top_p = 1.0
top_k = 1
raw_response = False
lora_id = ""

Étape 2 : Envoyer la requête de prédiction

Envoyez la requête de prédiction au point de terminaison Vertex AI déployé.

response = endpoints["vllm_gpu"].predict(
    instances=instances, use_dedicated_endpoint=use_dedicated_endpoint
)

for prediction in response.predictions:
    print(prediction)

Exemple de résultat :

Human: What is a car?
Assistant: A car, or a motor car, is a road-connected human-transportation system
used to move people or goods from one place to another.
  • Modération : pour garantir la sécurité du contenu, vous pouvez modérer le texte généré à l'aide des fonctionnalités de modération de texte de Vertex AI.
  • Gérer les délais d'attente : si vous rencontrez des problèmes tels que ServiceUnavailable: 503, essayez de réduire le paramètre max_tokens.

Déployer un modèle multimodal Llama 3.2

Cette section vous explique comment déployer un modèle multimodal Llama 3.2 préentraîné sur un point de terminaison Vertex AI. Le déploiement peut prendre jusqu'à une heure. Les modèles Llama 3.2 sont compatibles avec les formats texte uniquement et image unique plus texte.

Étape 1 : Choisir un modèle à déployer

Spécifiez la variante du modèle Llama 3.2. Cet exemple utilise Llama-3.2-11B-Vision.

base_model_name = "Llama-3.2-11B-Vision"  # @param ["Llama-3.2-1B", "Llama-3.2-1B-Instruct", "Llama-3.2-3B", "Llama-3.2-3B-Instruct", "Llama-3.2-11B-Vision", "Llama-3.2-11B-Vision-Instruct", "Llama-3.2-90B-Vision", "Llama-3.2-90B-Vision-Instruct"]
hf_model_id = "meta-Llama/" + base_model_name

Étape 2 : Configurez le matériel et les ressources

Sélectionnez le matériel approprié à la taille de votre modèle.

  • Modèles 1B et 3B : GPU NVIDIA L4
  • Modèles 11B : GPU NVIDIA A100
  • Modèles 90B : GPU NVIDIA H100
if "3.2-1B" in base_model_name or "3.2-3B" in base_model_name:
    accelerator_type = "NVIDIA_L4"
    machine_type = "g2-standard-8"
    accelerator_count = 1
elif "3.2-11B" in base_model_name:
    accelerator_type = "NVIDIA_TESLA_A100"
    machine_type = "a2-highgpu-1g"
    accelerator_count = 1
elif "3.2-90B" in base_model_name:
    accelerator_type = "NVIDIA_H100_80GB"
    machine_type = "a3-highgpu-8g"
    accelerator_count = 8
else:
    raise ValueError(f"Recommended GPU setting not found for: {base_model_name}.")

Assurez-vous de disposer du quota de GPU requis.

common_util.check_quota(
    project_id=PROJECT_ID,
    region=REGION,
    accelerator_type=accelerator_type,
    accelerator_count=accelerator_count,
    is_for_training=False,
)

Étape 3 : Déployer le modèle à l'aide de vLLM

La fonction suivante gère le déploiement du modèle Llama 3.2 sur Vertex AI. Il configure l'environnement du modèle, l'utilisation de la mémoire et les paramètres vLLM pour une diffusion efficace.

def deploy_model_vllm(
    model_name: str,
    model_id: str,
    service_account: str,
    base_model_id: str = None,
    machine_type: str = "g2-standard-8",
    accelerator_type: str = "NVIDIA_L4",
    accelerator_count: int = 1,
    gpu_memory_utilization: float = 0.9,
    max_model_len: int = 4096,
    dtype: str = "auto",
    enable_trust_remote_code: bool = False,
    enforce_eager: bool = False,
    enable_lora: bool = False,
    max_loras: int = 1,
    max_cpu_loras: int = 8,
    use_dedicated_endpoint: bool = False,
    max_num_seqs: int = 12,
    model_type: str = None,
) -> Tuple[aiplatform.Model, aiplatform.Endpoint]:
    """Deploys trained models with vLLM into Vertex AI."""
    endpoint = aiplatform.Endpoint.create(
        display_name=f"{model_name}-endpoint",
        dedicated_endpoint_enabled=use_dedicated_endpoint,
    )

    if not base_model_id:
        base_model_id = model_id

    vllm_args = [
        "python",
        "-m",
        "vllm.entrypoints.api_server",
        "--host=0.0.0.0",
        "--port=8080",
        f"--model={model_id}",
        f"--tensor-parallel-size={accelerator_count}",
        "--swap-space=16",
        f"--gpu-memory-utilization={gpu_memory_utilization}",
        f"--max-model-len={max_model_len}",
        f"--dtype={dtype}",
        f"--max-loras={max_loras}",
        f"--max-cpu-loras={max_cpu_loras}",
        f"--max-num-seqs={max_num_seqs}",
        "--disable-log-stats",
    ]

    if enable_trust_remote_code:
        vllm_args.append("--trust-remote-code")
    if enforce_eager:
        vllm_args.append("--enforce-eager")
    if enable_lora:
        vllm_args.append("--enable-lora")
    if model_type:
        vllm_args.append(f"--model-type={model_type}")

    env_vars = {
        "MODEL_ID": base_model_id,
        "DEPLOY_SOURCE": "notebook",
    }

    # HF_TOKEN is not a compulsory field and may not be defined.
    try:
        if HF_TOKEN:
            env_vars["HF_TOKEN"] = HF_TOKEN
    except NameError:
        pass

    model = aiplatform.Model.upload(
        display_name=model_name,
        serving_container_image_uri=VLLM_DOCKER_URI,
        serving_container_args=vllm_args,
        serving_container_ports=[8080],
        serving_container_predict_route="/generate",
        serving_container_health_route="/ping",
        serving_container_environment_variables=env_vars,
        serving_container_shared_memory_size_mb=(16 * 1024),
        serving_container_deployment_timeout=7200,
    )
    print(f"Deploying {model_name} on {machine_type} with {accelerator_count} {accelerator_type} GPU(s).")

    model.deploy(
        endpoint=endpoint,
        machine_type=machine_type,
        accelerator_type=accelerator_type,
        accelerator_count=accelerator_count,
        deploy_request_timeout=1800,
        service_account=service_account,
    )
    print("endpoint_name:", endpoint.name)

    return model, endpoint

Étape 4 : Exécuter le déploiement

Exécutez la fonction de déploiement avec le modèle et les paramètres configurés. La fonction renverra les instances de modèle et de point de terminaison, que vous pourrez utiliser pour l'inférence.

model_name = common_util.get_job_name_with_datetime(prefix=f"{base_model_name}-serve-vllm")
models["vllm_gpu"], endpoints["vllm_gpu"] = deploy_model_vllm(
    model_name=model_name
    model_id=hf_model_id,
    base_model_id=hf_model_id,
    service_account=SERVICE_ACCOUNT,
    machine_type=machine_type,
    accelerator_type=accelerator_type,
    accelerator_count=accelerator_count,
    gpu_memory_utilization=gpu_memory_utilization,
    max_model_len=max_model_len,
    enforce_eager=True,
    use_dedicated_endpoint=use_dedicated_endpoint,
    max_num_seqs=max_num_seqs,
)
Point de terminaison de déploiement Llama 3.2 dans le tableau de bord Vertex Figure 5. Point de terminaison de déploiement Llama 3.2 dans le tableau de bord Vertex

Effectuer des prédictions avec un modèle multimodal

Vous pouvez utiliser deux formats d'API différents pour faire des prédictions avec votre modèle multimodal déployé.

Méthode d'inférence Description Cas d'utilisation
Route de prédiction par défaut Utilise le point de terminaison de prédiction Vertex AI standard (/generate). La charge utile de la requête est un objet JSON personnalisé qui contient la requête, les données d'image et les paramètres d'échantillonnage. Idéal pour l'inférence directe et simple, et pour l'intégration aux workflows Vertex AI existants qui utilisent le format de prédiction standard.
API OpenAI Chat Completion Émule le format de l'API Chat Completions d'OpenAI, ce qui vous permet d'utiliser la bibliothèque cliente OpenAI. La requête utilise une structure de messages familière (par exemple, role et content). Idéal pour les développeurs qui connaissent déjà l'API OpenAI, ce qui permet de migrer facilement les applications existantes. Il est idéal pour créer des applications multimodales conversationnelles ou basées sur le chat.

Effectuer des prédictions avec la route de prédiction par défaut

Cette section vous explique comment effectuer des prédictions avec le modèle Llama 3.2 Vision à l'aide de la route de prédiction par défaut.

Étape 1 : Définissez votre requête et vos paramètres

Fournissez une URL d'image et une requête textuelle que le modèle pourra traiter.

Exemple d'image d'entrée pour les requêtes Llama 3.2 Figure 6. Exemple d'image d'entrée pour solliciter Llama 3.2
image_url = "https://images.pexels.com/photos/1254140/pexels-photo-1254140.jpeg"

raw_prompt = "This is a picture of"

# Reference prompt formatting guidelines here: https://www.Llama.com/docs/model-cards-and-prompt-formats/Llama3_2/#-base-model-prompt
prompt = f"<|begin_of_text|><|image|>{raw_prompt}"

Étape 2 : Configurez les paramètres de prédiction

Ajustez les paramètres suivants pour contrôler la réponse du modèle.

max_tokens = 64
temperature = 0.5
top_p = 0.95

Étape 3 : Préparez la requête de prédiction

Configurez la requête de prédiction avec l'URL de l'image, l'invite et d'autres paramètres.

instances = [
    {
        "prompt": prompt,
        "multi_modal_data": {"image": image_url},
        "max_tokens": max_tokens,
        "temperature": temperature,
        "top_p": top_p,
    },
]

Étape 4 : Effectuer la prédiction

Envoyez la requête à votre point de terminaison Vertex AI et traitez la réponse.

response = endpoints["vllm_gpu"].predict(instances=instances)

for raw_prediction in response.predictions:
    prediction = raw_prediction.split("Output:")
    print(prediction[1])

Si vous rencontrez un problème de délai d'attente, essayez de réduire la valeur max_tokens.

Faire des prédictions avec l'API OpenAI Chat Completion

Cette section vous explique comment effectuer des prédictions sur les modèles Llama 3.2 Vision Instruct à l'aide du format de l'API OpenAI Chat Completions. Cette approche est idéale pour les applications conversationnelles.

Étape 1 : Déployer un modèle Llama 3.2 Vision Instruct

Cette méthode nécessite un modèle ajusté aux instructions. Pour déployer le modèle Llama-3.2-11B-Vision-Instruct, appelez la fonction deploy_model_vllm définie précédemment.

base_model_name = "Llama-3.2-11B-Vision-Instruct"
hf_model_id = f"meta-llama/{base_model_name}"
model_name = common_util.get_job_name_with_datetime(prefix=f"{base_model_name}-serve-vllm")
model, endpoint = deploy_model_vllm(
    model_name=model_name
    model_id=hf_model_id,
    base_model_id=hf_model_id,
    service_account=SERVICE_ACCOUNT,
    machine_type="a2-highgpu-1g",
    accelerator_type="NVIDIA_TESLA_A100",
    accelerator_count=1,
    gpu_memory_utilization=0.9,
    max_model_len=4096,
    enforce_eager=True,
    max_num_seqs=12,
)

Étape 2 : Configurez la ressource de point de terminaison

Configurez le nom de ressource du point de terminaison pour votre déploiement. Pour vous reconnecter à un point de terminaison créé précédemment, remplacez la variable endpoint.name par l'ID de votre point de terminaison existant.

ENDPOINT_RESOURCE_NAME = "projects/{}/locations/{}/endpoints/{}".format(
    PROJECT_ID, REGION, endpoint.name
)

Étape 3 : Installez le SDK OpenAI et les bibliothèques d'authentification

Pour envoyer des requêtes à l'aide du SDK OpenAI, installez les bibliothèques nécessaires.

!pip install -qU openai google-auth requests

Étape 4 : Définir les paramètres d'entrée pour la finalisation du chat

Configurez l'URL de votre image et votre requête textuelle. Ajustez max_tokens et temperature pour contrôler la longueur et le caractère aléatoire de la réponse.

user_image = "https://images.freeimages.com/images/large-previews/ab3/puppy-2-1404644.jpg"
user_message = "Describe this image?"
max_tokens = 50
temperature = 1.0

Étape 5 : Configurez l'authentification et l'URL de base

Récupérez vos identifiants et définissez l'URL de base pour les requêtes API.

import google.auth
import openai

creds, project = google.auth.default()
auth_req = google.auth.transport.requests.Request()
creds.refresh(auth_req)

BASE_URL = (
    f"https://{REGION}-aiplatform.googleapis.com/v1beta1/{ENDPOINT_RESOURCE_NAME}"
)
try:
    if use_dedicated_endpoint:
        BASE_URL = f"https://{DEDICATED_ENDPOINT_DNS}/v1beta1/{ENDPOINT_RESOURCE_NAME}"
except NameError:
    pass

Étape 6 : Envoyez la requête Chat Completion

À l'aide de l'API OpenAI Chat Completions, envoyez l'image et la requête textuelle à votre point de terminaison Vertex AI.

client = openai.OpenAI(base_url=BASE_URL, api_key=creds.token)

model_response = client.chat.completions.create(
    model="",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "image_url", "image_url": {"url": user_image}},
                {"type": "text", "text": user_message},
            ],
        }
    ],
    temperature=temperature,
    max_tokens=max_tokens,
)

print(model_response)

Nettoyage

Pour éviter les frais récurrents, supprimez les modèles et les points de terminaison déployés, ainsi que le bucket de stockage.

Étape 1 : Supprimez les points de terminaison et les modèles

Le code suivant annule le déploiement de chaque modèle et supprime les points de terminaison et les modèles associés.

# Undeploy model and delete endpoint
for endpoint in endpoints.values():
    endpoint.delete(force=True)

# Delete models
for model in models.values():
    model.delete()

Étape 2 : (Facultatif) Supprimez le bucket Cloud Storage

Si vous avez créé un bucket Cloud Storage pour ce guide et que vous n'en avez plus besoin, vous pouvez le supprimer.

delete_bucket = False
if delete_bucket:
    ! gsutil -m rm -r $BUCKET_NAME

Débogage

Cette section fournit des conseils pour résoudre les problèmes courants qui peuvent survenir lors du déploiement et de l'inférence de modèles vLLM.

Vérifier les journaux

Pour trouver la cause première d'un problème, consultez les journaux de votre point de terminaison :

  1. Accédez à la console Vertex AI Prediction.
  2. Sélectionnez votre point de terminaison.
  3. Cliquez sur l'onglet Journaux ou sur Afficher les journaux pour ouvrir Cloud Logging, filtré pour votre point de terminaison.
  4. Analysez les journaux pour identifier les messages d'erreur liés aux contraintes de ressources, à l'authentification ou à la configuration.

Problème courant 1 : CUDA Out of Memory (OOM) lors du déploiement

Les erreurs CUDA de mémoire insuffisante (OOM, Out Of Memory) se produisent lorsque l'utilisation de la mémoire par le modèle dépasse la capacité du GPU disponible. Cette erreur se produit souvent si le paramètre max_num_seqs, qui définit le nombre maximal de requêtes simultanées, est défini sur une valeur trop élevée pour le modèle et le GPU.

Par exemple, le déploiement d'un modèle multimodal tel que Llama-3.2-11B-Vision-Instruct avec max_num_seqs = 256 sur un GPU NVIDIA L4 peut entraîner une erreur OOM, car les modèles multimodaux consomment plus de mémoire par séquence que les modèles textuels.

Dans le cas du modèle de texte uniquement, nous avons utilisé les arguments de moteur suivants :

base_model_name = "Meta-Llama-3.1-8B"
hf_model_id = f"meta-llama/{base_model_name}"
accelerator_type = "NVIDIA_L4"
accelerator_count = 1
machine_type = "g2-standard-12"
accelerator_count: int = 1
gpu_memory_utilization = 0.9
max_model_len = 4096
dtype = "auto"
max_num_seqs = 256

Dans le cas du modèle multimodal, nous avons utilisé les arguments de moteur suivants :

base_model_name = "Llama-3.2-11B-Vision-Instruct"
hf_model_id = f"meta-llama/{base_model_name}"
accelerator_type = "NVIDIA_L4"
accelerator_count = 1
machine_type = "g2-standard-12"
accelerator_count: int = 1
gpu_memory_utilization = 0.9
max_model_len = 4096
dtype = "auto"
max_num_seqs = 12

Exemple de journal des erreurs :

[rank0]: torch.OutOfMemoryError: CUDA out of memory. Tried to allocate 3.91 GiB. GPU 0 has a total capacity of 39.38 GiB of which 3.76 GiB is free. Including non-PyTorch memory, this process has 0 bytes memory in use. Of the allocated memory 34.94 GiB is allocated by PyTorch, and 175.15 MiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True to avoid fragmentation.  See documentation for Memory Management  (https://pytorch.org/docs/stable/notes/cuda.html#environment-variables)
Journal des erreurs de mémoire insuffisante (OOM) du GPU Figure 7. Journal des erreurs GPU pour cause de mémoire insuffisante (OOM)

Solution : Pour résoudre cette erreur, réduisez la valeur max_num_seqs. Par exemple, pour le modèle Llama-3.2-11B-Vision-Instruct sur un GPU L4, une valeur de 12 est plus appropriée. Redéployez le modèle avec le paramètre ajusté.

Message d&#39;erreur indiquant que le déploiement de Llama 3.2 a échoué Figure 8. Échec du déploiement de Llama 3.2

Problème courant 2 : Jeton Hugging Face requis

Cette erreur se produit lorsque vous déployez un modèle restreint depuis Hugging Face sans fournir de jeton d'accès valide.

Exemple de journal d'erreurs : le journal contient un message tel que Cannot access gated repository for URL, qui indique qu'une authentification est requise.

Message d&#39;erreur indiquant qu&#39;un jeton HuggingFace est nécessaire pour accéder au modèle Figure 9. Erreur de jeton Hugging Face

Solution : Assurez-vous d'avoir généré un jeton d'accès Hugging Face avec au moins les autorisations Read (Lecture) et d'avoir accepté les conditions de licence du modèle. Fournissez ce jeton dans la variable d'environnement HF_TOKEN lors du déploiement.

Problème courant 3 : Modèle de chat requis

Cette erreur peut se produire avec les versions plus récentes de la bibliothèque transformers si le tokenizer du modèle ne comporte pas de modèle de chat par défaut.

Exemple de journal des erreurs : le journal affiche un ValueError qui indique qu'un modèle de chat est manquant et doit être fourni.

Message d&#39;erreur indiquant qu&#39;un modèle de chat est nécessaire pour accéder au modèle Figure 10. Erreur "Modèle de chat requis"

Résolution : pour résoudre cette erreur, fournissez un modèle de chat lors du déploiement à l'aide de l'argument --chat-template. Vous trouverez des exemples de modèles dans le dépôt d'exemples vLLM.

Problème courant 4 : Erreur de longueur maximale de séquence du modèle

Cette erreur se produit lorsque la longueur de séquence maximale du modèle (max_model_len) est supérieure au nombre de jetons pouvant être stockés dans le cache KV du GPU.

Exemple de journal des erreurs :

ValueError: The model's max seq len (4096) is larger than the maximum number of tokens that can be stored in KV cache (2256). Try increasing `gpu_memory_utilization` or decreasing `max_model_len` when initializing the engine.
Longueur de séquence maximale du modèle Figure 11. Erreur "Max Seq Length too Large" (Longueur de séquence max. trop élevée)

Résolution : Pour résoudre cette erreur, diminuez la valeur de max_model_len à une valeur inférieure à la taille du cache KV disponible (par exemple, 2048) ou augmentez le paramètre gpu_memory_utilization. Vous pouvez également utiliser un GPU plus grand ou plusieurs GPU avec le paramètre tensor-parallel-size approprié.

Notes de version du conteneur vLLM Model Garden

Versions principales

vLLM standard

Date de disponibilité Architecture Version de vLLM URI du conteneur
17 juil. 2025 ARM v0.9.2 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250717_0916_arm_RC01
10 juillet 2025 x86 v0.9.2 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250710_0916_RC01
20 juin 2025 x86 Après la version 0.9.1, commit us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250620_0916_RC01
11 juin 2025 x86 v0.9.1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250611_0916_RC01
2 juin 2025 x86 v0.9.0 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250601_0916_RC01
6 mai 2025 x86 v0.8.5.post1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250506_0916_RC01
29 avril 2025 x86 v0.8.4 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250429_0916_RC01, 20250430_0916_RC00_maas
17 avril 2025 x86 v0.8.4 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250417_0916_RC01
10 avril 2025 x86 Au-delà de la version 0.8.3, commit us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250410_0917_RC01
7 avril 2025 x86 v0.8.3 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250407_0917_RC01, 20250407_0917_RC0120250429_0916_RC00_maas
7 avril 2025 x86 v0.8.1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250404_0916_RC01
5 avril 2025 x86 Après la version 0.8.2, commit us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250405_1205_RC01
31 mars 2025 x86 v0.8.1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250401_0916_RC01
26 mars 2025 x86 v0.8.1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250327_0916_RC01
23 mars 2025 x86 v0.8.1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250324_0916_RC01
21 mars 2025 x86 v0.8.1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250321_0916_RC01
11 mars 2025 x86 Après la version 0.7.3, commit us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250312_0916_RC01
3 mars 2025 x86 v0.7.2 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250304_0916_RC01
14 janv. 2025 x86 v0.6.4.post1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20250114_0916_RC00_maas
2 déc. 2024 x86 v0.6.4.post1 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20241202_0916_RC00_maas
12 novembre 2024 x86 v0.6.2 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20241112_0916_RC00_maas
16 octobre 2024 x86 v0.6.2 us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:20241016_0916_RC00_maas

vLLM optimisé

Date de disponibilité Architecture URI du conteneur
21 janvier 2025 x86 us-docker.pkg.dev/vertex-ai-restricted/vertex-vision-model-garden-dockers/pytorch-vllm-optimized-serve:20250121_0835_RC00
29 octobre 2024 x86 us-docker.pkg.dev/vertex-ai-restricted/vertex-vision-model-garden-dockers/pytorch-vllm-optimized-serve:20241029_0835_RC00

Autres versions

Pour obtenir la liste complète des versions standards de conteneurs vLLM de VMG, consultez la page Artifact Registry.

Les versions de vLLM-TPU en état expérimental sont taguées avec <yyyymmdd_hhmm_tpu_experimental_RC00>.