Diffuser des modèles ouverts Gemma à l'aide de GPU sur GKE avec vLLM


Ce tutoriel explique comment diffuser un grand modèle de langage (LLM) Gemma à l'aide de processeurs graphiques (GPU) sur Google Kubernetes Engine (GKE) en utilisant le framework de diffusion vLLM.

Dans ce tutoriel, vous allez télécharger un modèle avec réglage des instructions Gemma 2 (paramètres 2B, 9B et 27B) de Hugging Face. Vous allez ensuite déployer le modèle sur un cluster GKE Autopilot ou Standard à l'aide d'un conteneur qui exécute vLLM.

Ce guide est un bon point de départ si vous avez besoin du contrôle précis, de l'évolutivité, de la résilience, de la portabilité et de la rentabilité des services Kubernetes gérés lors du déploiement et de la diffusion de vos charges de travail d'IA/de ML. Si vous avez besoin d'une plate-forme d'IA gérée unifiée pour créer et diffuser rapidement des modèles de ML à moindre coût, nous vous recommandons d'essayer notre solution de déploiement Vertex AI.

Expérience

En diffusant Gemma à l'aide de GPU sur GKE avec vLLM, vous pouvez mettre en œuvre une solution de diffusion d'inférences robuste et prête pour la production avec tous les avantages de Kubernetes géré, y compris une évolutivité efficace et une meilleure disponibilité. Cette section décrit les principales technologies utilisées dans ce guide.

Gemma

Gemma est un ensemble de modèles d'intelligence artificielle (IA) générative, légers et disponibles publiquement, publiés sous licence ouverte. Ces modèles d'IA sont disponibles pour s'exécuter dans vos applications, votre matériel, vos appareils mobiles ou vos services hébergés. Vous pouvez utiliser les modèles Gemma pour la génération de texte, mais vous pouvez également les ajuster pour des tâches spécialisées.

Pour en savoir plus, consultez la documentation Gemma.

GPU

Les GPU vous permettent d'accélérer des charges de travail spécifiques exécutées sur vos nœuds, telles que le machine learning et le traitement de données. GKE fournit toute une gamme d'options de types de machines pour la configuration des nœuds, y compris les types de machines avec des GPU NVIDIA H100, L4 et A100.

Avant d'utiliser des GPU dans GKE, nous vous recommandons de suivre le parcours de formation suivant :

  1. Découvrez la disponibilité actuelle des versions des GPU.
  2. Apprenez-en plus sur les GPU dans GKE.

vLLM

vLLM est un framework de diffusion LLM Open Source hautement optimisé qui peut augmenter le débit de diffusion sur les GPU, avec des fonctionnalités telles que:

  • Implémentation optimisée du transformateur avec PagedAttention
  • Traitement par lots continu pour améliorer le débit global de diffusion
  • Parallélisme des Tensors et diffusion distribuée sur plusieurs GPU

Pour en savoir plus, consultez la documentation de vLLM.

Objectifs

Ce guide est destiné aux clients d'IA générative qui utilisent PyTorch, aux utilisateurs nouveaux ou existants de GKE, aux ingénieurs en ML, aux ingénieurs MLOps (DevOps) ou aux administrateurs de plate-forme qui s'intéressent à l'utilisation des fonctionnalités d'orchestration de conteneurs Kubernetes pour diffuser des LLM sur du matériel GPU H100, A100 et L4.

À la fin de ce guide, vous devriez être capable d'effectuer les étapes suivantes:

  1. Préparer votre environnement avec un cluster GKE en mode Autopilot ou Standard.
  2. Déployer un conteneur vLLM sur votre cluster.
  3. Utilisez vLLM pour diffuser le modèle Gemma 2 via curl et une interface de chat Web.

Avant de commencer

  • Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  • Make sure that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Enable the API

  • In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  • Make sure that billing is enabled for your Google Cloud project.

  • Enable the required API.

    Enable the API

  • Make sure that you have the following role or roles on the project: roles/container.admin, roles/iam.serviceAccountAdmin

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role colunn to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

      Accéder à IAM
    2. Sélectionnez le projet.
    3. Cliquez sur Accorder l'accès.
    4. Dans le champ Nouveaux comptes principaux, saisissez votre identifiant utilisateur. Il s'agit généralement de l'adresse e-mail d'un compte Google.

    5. Dans la liste Sélectionner un rôle, sélectionnez un rôle.
    6. Pour attribuer des rôles supplémentaires, cliquez sur Ajouter un autre rôle et ajoutez chaque rôle supplémentaire.
    7. Cliquez sur Enregistrer.

Accéder au modèle

Pour accéder aux modèles Gemma en vue du déploiement sur GKE, vous devez d'abord signer le contrat d'autorisation de licence, puis générer un jeton d'accès Hugging Face.

Vous devez signer le contrat de consentement pour utiliser Gemma. Procédez comme suit :

  1. Accédez à la page de consentement du modèle sur Kaggle.com.
  2. Vérifiez l'autorisation à l'aide de votre compte Hugging Face.
  3. Acceptez les conditions du modèle.

Générer un jeton d'accès

Pour accéder au modèle via Hugging Face, vous avez besoin d'un jeton Hugging Face.

Pour générer un nouveau jeton si vous n'en possédez pas, procédez comme suit:

  1. Cliquez sur Your Profile > Settings > Access Tokens (Votre profil > Paramètres > Jetons d'accès).
  2. Sélectionnez New Token (Nouveau jeton).
  3. Spécifiez le nom de votre choix et un rôle d'au moins "Read" (lecture).
  4. Sélectionnez Générer un jeton.
  5. Copiez le jeton dans votre presse-papiers.

Préparer votre environnement

Dans ce tutoriel, vous utilisez Cloud Shell pour gérer les ressources hébergées sur Google Cloud. Cloud Shell est préinstallé avec les logiciels dont vous avez besoin pour ce tutoriel, y compris kubectl et gcloud CLI.

Pour configurer votre environnement avec Cloud Shell, procédez comme suit :

  1. Dans la console Google Cloud, lancez une session Cloud Shell en cliquant sur Icône d'activation Cloud Shell Activer Cloud Shell dans la console Google Cloud. Une session s'ouvre dans le volet inférieur de la console Google Cloud.

  2. Définissez les variables d'environnement par défaut :

    gcloud config set project PROJECT_ID
    export PROJECT_ID=$(gcloud config get project)
    export REGION=REGION
    export CLUSTER_NAME=vllm
    export HF_TOKEN=HF_TOKEN
    

    Remplacez les valeurs suivantes :

    • PROJECT_ID : L'ID de votre projet Google Cloud.
    • REGION: région compatible avec le type d'accélérateur que vous souhaitez utiliser, par exemple us-central1 pour les GPU L4.
    • HF_TOKEN: jeton Hugging Face que vous avez généré précédemment.

Créer et configurer des ressources Google Cloud

Suivez les instructions ci-dessous pour créer les ressources requises.

Créer un cluster GKE et un pool de nœuds

Vous pouvez diffuser les modèles Gemma sur des GPU dans un cluster GKE Autopilot ou GKE Standard. Nous vous recommandons d'utiliser un cluster GKE Autopilot pour une expérience Kubernetes entièrement gérée. Pour choisir le mode de fonctionnement GKE le mieux adapté à vos charges de travail, consultez la section Choisir un mode de fonctionnement GKE.

Autopilot

Dans Cloud Shell, exécutez la commande suivante :

gcloud container clusters create-auto ${CLUSTER_NAME} \
  --project=${PROJECT_ID} \
  --region=${REGION} \
  --release-channel=rapid

GKE crée un cluster Autopilot avec des nœuds de processeur et de GPU, à la demande des charges de travail déployées.

Standard

  1. Dans Cloud Shell, exécutez la commande suivante pour créer un cluster GKE Standard :

    gcloud container clusters create ${CLUSTER_NAME} \
      --project=${PROJECT_ID} \
      --region=${REGION} \
      --workload-pool=${PROJECT_ID}.svc.id.goog \
      --release-channel=rapid \
      --num-nodes=1
    

    La création du cluster peut prendre plusieurs minutes.

  2. Exécutez la commande suivante pour créer un pool de nœuds pour votre cluster :

    Gemma 2 2B

    gcloud container node-pools create gpupool \
      --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \
      --project=${PROJECT_ID} \
      --location=${REGION} \
      --node-locations=${REGION}-a \
      --cluster=${CLUSTER_NAME} \
      --machine-type=g2-standard-8 \
      --num-nodes=1
    

    GKE crée un pool de nœuds unique contenant un GPU L4 pour chaque nœud.

    Gemma 2 9B

    gcloud container node-pools create gpupool \
      --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \
      --project=${PROJECT_ID} \
      --location=${REGION} \
      --node-locations=${REGION}-a \
      --cluster=${CLUSTER_NAME} \
      --machine-type=g2-standard-24 \
      --num-nodes=1
    

    GKE crée un pool de nœuds unique contenant deux GPU L4 pour chaque nœud.

    Gemma 2 27B

    gcloud container node-pools create gpupool \
      --accelerator type=nvidia-l4,count=4,gpu-driver-version=latest \
      --project=${PROJECT_ID} \
      --location=${REGION} \
      --node-locations=${REGION}-a \
      --cluster=${CLUSTER_NAME} \
      --machine-type=g2-standard-48 \
      --num-nodes=1
    

    GKE crée un pool de nœuds unique contenant quatre GPU L4 pour chaque nœud.

Créer un secret Kubernetes pour les identifiants Hugging Face

Dans Cloud Shell, procédez comme suit :

  1. Configurez kubectl de manière à communiquer avec votre cluster :

    gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${REGION}
    
  2. Créez un secret Kubernetes contenant le jeton Hugging Face:

    kubectl create secret generic hf-secret \
    --from-literal=hf_api_token=$HF_TOKEN \
    --dry-run=client -o yaml | kubectl apply -f -
    

Déployer vLLM

Dans cette section, vous allez déployer le conteneur vLLM pour diffuser le modèle Gemma que vous souhaitez utiliser.

Gemma 2 2B-it

Suivez ces instructions pour déployer le modèle adapté aux instructions Gemma 2 2B.

  1. Créez le fichier manifeste vllm-2-2b-it.yaml suivant :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-gemma-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: gemma-server
      template:
        metadata:
          labels:
            app: gemma-server
            ai.gke.io/model: gemma-2-2b-it
            ai.gke.io/inference-server: vllm
            examples.ai.gke.io/source: user-guide
        spec:
          containers:
          - name: inference-server
            image:  vllm/vllm-openai:v0.5.5
            resources:
              requests:
                cpu: "2"
                memory: "10Gi"
                ephemeral-storage: "10Gi"
                nvidia.com/gpu: "1"
              limits:
                cpu: "2"
                memory: "10Gi"
                ephemeral-storage: "10Gi"
                nvidia.com/gpu: "1"
            command: ["python3", "-m", "vllm.entrypoints.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --tensor-parallel-size=1
            env:
            - name: MODEL_ID
              value: google/gemma-2-2b-it
            - name: VLLM_ATTENTION_BACKEND
              value: FLASHINFER
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
                medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-l4
            cloud.google.com/gke-gpu-driver-version: latest
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llm-service
    spec:
      selector:
        app: gemma-server
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
  2. Appliquez le fichier manifeste :

    kubectl apply -f vllm-2-2b-it.yaml
    

Gemma 2 9B-it

Suivez ces instructions pour déployer le modèle adapté aux instructions Gemma 2 9B.

  1. Créez le fichier manifeste vllm-2-9b-it.yaml suivant :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-gemma-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: gemma-server
      template:
        metadata:
          labels:
            app: gemma-server
            ai.gke.io/model: gemma-2-9b-it
            ai.gke.io/inference-server: vllm
            examples.ai.gke.io/source: user-guide
        spec:
          containers:
          - name: inference-server
            image:  vllm/vllm-openai:v0.5.5
            resources:
              requests:
                cpu: "4"
                memory: "30Gi"
                ephemeral-storage: "30Gi"
                nvidia.com/gpu: "2"
              limits:
                cpu: "4"
                memory: "30Gi"
                ephemeral-storage: "30Gi"
                nvidia.com/gpu: "2"
            command: ["python3", "-m", "vllm.entrypoints.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --tensor-parallel-size=2
            env:
            - name: MODEL_ID
              value: google/gemma-2-9b-it
            - name: VLLM_ATTENTION_BACKEND
              value: FLASHINFER
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
                medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-l4
            cloud.google.com/gke-gpu-driver-version: latest
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llm-service
    spec:
      selector:
        app: gemma-server
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
  2. Appliquez le fichier manifeste :

    kubectl apply -f vllm-2-9b-it.yaml
    

Gemma 2 27B-it

Suivez ces instructions pour déployer le modèle adapté aux instructions Gemma 2 27B.

  1. Créez le fichier manifeste vllm-2-27b-it.yaml suivant :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-gemma-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: gemma-server
      template:
        metadata:
          labels:
            app: gemma-server
            ai.gke.io/model: gemma-2-27b-it
            ai.gke.io/inference-server: vllm
            examples.ai.gke.io/source: user-guide
        spec:
          containers:
          - name: inference-server
            image:  vllm/vllm-openai:v0.5.5
            resources:
              requests:
                cpu: "10"
                memory: "80Gi"
                ephemeral-storage: "80Gi"
                nvidia.com/gpu: "4"
              limits:
                cpu: "10"
                memory: "80Gi"
                ephemeral-storage: "80Gi"
                nvidia.com/gpu: "4"
            command: ["python3", "-m", "vllm.entrypoints.api_server"]
            args:
            - --model=$(MODEL_ID)
            - --tensor-parallel-size=4
            env:
            - name: MODEL_ID
              value: google/gemma-2-27b-it
            - name: VLLM_ATTENTION_BACKEND
              value: FLASHINFER
            - name: HUGGING_FACE_HUB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: hf-secret
                  key: hf_api_token
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          volumes:
          - name: dshm
            emptyDir:
                medium: Memory
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-l4
            cloud.google.com/gke-gpu-driver-version: latest
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: llm-service
    spec:
      selector:
        app: gemma-server
      type: ClusterIP
      ports:
        - protocol: TCP
          port: 8000
          targetPort: 8000
  2. Appliquez le fichier manifeste :

    kubectl apply -f vllm-2-27b-it.yaml
    

Un pod du cluster télécharge les pondérations du modèle à partir de Hugging Face et lance le moteur de diffusion.

Attendez que le déploiement soit disponible :

kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment

Affichez les journaux du déploiement en cours d'exécution :

kubectl logs -f -l app=gemma-server

La ressource Déploiement télécharge les données du modèle. Ce processus peut prendre quelques minutes. Le résultat ressemble à ce qui suit :

INFO 01-26 19:02:54 model_runner.py:689] Graph capturing finished in 4 secs.
INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

Assurez-vous que le modèle est entièrement téléchargé avant de passer à la section suivante.

Diffuser le modèle

Dans cette section, vous allez interagir avec le modèle.

Configurer le transfert de port

Exécutez la commande suivante pour configurer le transfert de port sur le modèle :

kubectl port-forward service/llm-service 8000:8000

Le résultat ressemble à ce qui suit :

Forwarding from 127.0.0.1:8000 -> 8000

Interagir avec le modèle à l'aide de curl

Cette section explique comment effectuer un test de fumée de base pour vérifier les modèles pré-entraînés ou adaptés aux instructions déployés. Par souci de simplicité, cette section décrit l'approche de test uniquement avec le modèle adapté aux instructions Gemma 2 (2-2B-it).

Dans une nouvelle session de terminal, utilisez curl pour discuter avec votre modèle :

USER_PROMPT="I'm new to coding. If you could only recommend one programming language to start with, what would it be and why?"

curl -X POST http://localhost:8000/generate \
  -H "Content-Type: application/json" \
  -d @- <<EOF
{
    "prompt": "<start_of_turn>user\n${USER_PROMPT}<end_of_turn>\n",
    "temperature": 0.90,
    "top_p": 1.0,
    "max_tokens": 128
}
EOF

Le résultat suivant affiche un exemple de réponse du modèle :

{"predictions":["Prompt:\n<start_of_turn>user\nI'm new to coding. If you could only recommend one programming language to start with, what would it be and why?<end_of_turn>\nOutput:\n**Python** is an excellent choice for beginners due to the following reasons:\n\n* **Clear and simple syntax:** Python boasts a simple and straightforward syntax that makes it easy to learn the fundamentals of programming.\n* **Extensive libraries and modules:** Python comes with a vast collection of libraries and modules that address various programming tasks, including data manipulation, machine learning, and web development.\n* **Large and supportive community:** Python has a vibrant and active community that offers resources, tutorials, and support to help you along your journey.\n* **Cross-platform compatibility:** Python can be run on various platforms, including Windows, macOS, and"]}

(Facultatif) Interagir avec le modèle via une interface de chat Gradio

Dans cette section, vous allez créer une application de chat Web qui vous permet d'interagir avec votre modèle adapté aux instructions. Par souci de simplicité, cette section ne décrit que l'approche de test utilisant le modèle 2B-it.

Gradio est une bibliothèque Python dotée d'un wrapper ChatInterface qui crée des interfaces utilisateur pour les chatbots.

Déployer l'interface de chat

  1. Dans Cloud Shell, enregistrez le fichier manifeste suivant sous le nom gradio.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: gradio
      labels:
        app: gradio
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: gradio
      template:
        metadata:
          labels:
            app: gradio
        spec:
          containers:
          - name: gradio
            image: us-docker.pkg.dev/google-samples/containers/gke/gradio-app:v1.0.3
            resources:
              requests:
                cpu: "250m"
                memory: "512Mi"
              limits:
                cpu: "500m"
                memory: "512Mi"
            env:
            - name: CONTEXT_PATH
              value: "/generate"
            - name: HOST
              value: "http://llm-service:8000"
            - name: LLM_ENGINE
              value: "vllm"
            - name: MODEL_ID
              value: "gemma"
            - name: USER_PROMPT
              value: "<start_of_turn>user\nprompt<end_of_turn>\n"
            - name: SYSTEM_PROMPT
              value: "<start_of_turn>model\nprompt<end_of_turn>\n"
            ports:
            - containerPort: 7860
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: gradio
    spec:
      selector:
        app: gradio
      ports:
        - protocol: TCP
          port: 8080
          targetPort: 7860
      type: ClusterIP
  2. Appliquez le fichier manifeste :

    kubectl apply -f gradio.yaml
    
  3. Attendez que le déploiement soit disponible :

    kubectl wait --for=condition=Available --timeout=300s deployment/gradio
    

Utiliser l'interface de chat

  1. Dans Cloud Shell, exécutez la commande suivante :

    kubectl port-forward service/gradio 8080:8080
    

    Cela crée un transfert de port de Cloud Shell vers le service Gradio.

  2. Cliquez sur le bouton Icône Aperçu sur le Web Aperçu sur le Web qui se trouve en haut à droite de la barre des tâches Cloud Shell. Cliquez sur Preview on Port 8080 (Aperçu sur le port 8080). Un nouvel onglet s'ouvre dans le navigateur.

  3. Interagissez avec Gemma via l'interface de chat Gradio. Ajoutez une requête et cliquez sur Envoyer.

Résoudre les problèmes

Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.

Supprimer les ressources déployées

Pour éviter que les ressources que vous avez créées dans ce guide soient facturées sur votre compte Google Cloud, exécutez la commande suivante :

gcloud container clusters delete ${CLUSTER_NAME} \
  --region=${REGION}

Étapes suivantes