Affiner les modèles ouverts Gemma à l'aide de plusieurs GPU sur GKE


Ce tutoriel vous explique comment affiner un grand modèle de langage (LLM) Gemma, notre famille de modèles ouverts, à l'aide de processeurs graphiques (GPU) sur Google Kubernetes Engine (GKE) avec la bibliothèque Transformers de Hugging Face. L'affinage est un processus d'apprentissage supervisé qui améliore la capacité d'un modèle pré-entraîné à effectuer des tâches spécifiques en mettant à jour ses paramètres avec un nouvel ensemble de données. Dans ce tutoriel, vous allez télécharger les modèles de la famille Gemma pré-entraînés de paramètre 2B à partir de Hugging Face et les affiner sur un cluster GKE Autopilot ou Standard.

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 de l'affinage d'un LLM.

Bonne pratique :

Essayez notre solution Vertex AI 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.

Arrière-plan

En diffusant Gemma à l'aide de GPU sur GKE avec la bibliothèque Transformers, 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.

Dans ce guide, nous présentons Gemma pour la génération de texte. Vous pouvez également affiner ces modèles pour vous spécialiser dans l'exécution de tâches spécifiques.

L'ensemble de données que vous utilisez dans ce document est b-mc2/sql-create-context.

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.

Hugging Face Transformers

La bibliothèque Transformers de Hugging Face vous permet d'accéder à des modèles pré-entraînés de pointe. La bibliothèque Transformers vous permet de réduire la durée, les ressources et les coûts de calcul associés à l'entraînement complet du modèle.

Dans ce tutoriel, vous allez utiliser les API et les outils Hugging Face pour télécharger et affiner ces modèles pré-entraînés.

Objectifs

Ce guide est destiné aux utilisateurs nouveaux ou existants de GKE, aux ingénieurs en ML, aux ingénieurs MLOps (DevOps) ou aux administrateurs de plate-forme qui souhaitent utiliser les fonctionnalités d'orchestration de conteneurs Kubernetes pour affiner 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éparez votre environnement avec un cluster GKE en mode Autopilot.
  2. Créez un conteneur d'affinage.
  3. Utilisez des GPU pour affiner le modèle Gemma 2B et l'importer dans Hugging Face.

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

  • Verify 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

  • Verify 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 column 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 tous les rôles supplémentaires.
    7. Cliquez sur Enregistrer.
    8. 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 Write.
      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 surGoogle 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 consoleGoogle 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 CONTROL_PLANE_LOCATION=CONTROL_PLANE_LOCATION
        export CLUSTER_NAME=CLUSTER_NAME
        export HF_TOKEN=HF_TOKEN
        export HF_PROFILE=HF_PROFILE
        

        Remplacez les valeurs suivantes :

        • PROJECT_ID : ID de votre projet Google Cloud.
        • CONTROL_PLANE_LOCATION : région Compute Engine du plan de contrôle de votre cluster. Indiquez une région compatible avec le type d'accélérateur que vous souhaitez utiliser, par exemple us-central1 pour les GPU L4.
        • CLUSTER_NAME : nom du cluster
        • HF_TOKEN : jeton Hugging Face que vous avez généré précédemment.
        • HF_PROFILE : ID du profil Hugging Face que vous avez créé précédemment.
      3. Clonez l'exemple de dépôt de code depuis GitHub :

        git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
        cd kubernetes-engine-samples/ai-ml/llm-finetuning-gemma
        

      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. Pour choisir le mode de fonctionnement GKE le mieux adapté à vos charges de travail, consultez la section Choisir un mode de fonctionnement GKE.

      Bonne pratique:

      Utilisez Autopilot pour une expérience Kubernetes entièrement gérée.

      Autopilot

      Dans Cloud Shell, exécutez la commande suivante :

      gcloud container clusters create-auto CLUSTER_NAME \
          --project=PROJECT_ID \
          --location=CONTROL_PLANE_LOCATION \
          --release-channel=rapid \
          --cluster-version=1.29
      

      Remplacez les valeurs suivantes :

      • PROJECT_ID : ID de votre projet Google Cloud.
      • CONTROL_PLANE_LOCATION : région Compute Engine du plan de contrôle de votre cluster. Indiquez une région compatible avec le type d'accélérateur que vous souhaitez utiliser, par exemple us-central1 pour les GPU L4.
      • CLUSTER_NAME : nom du cluster

      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 \
            --location=CONTROL_PLANE_LOCATION \
            --workload-pool=PROJECT_ID.svc.id.goog \
            --release-channel=rapid \
            --num-nodes=1
        

        Remplacez les valeurs suivantes :

        • PROJECT_ID : ID de votre projet Google Cloud.
        • CONTROL_PLANE_LOCATION : région Compute Engine du plan de contrôle de votre cluster. Indiquez une région compatible avec le type d'accélérateur que vous souhaitez utiliser, par exemple us-central1 pour les GPU L4.
        • CLUSTER_NAME : nom du cluster

        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 :

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

        GKE crée un pool de nœuds unique contenant deux 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=CONTROL_PLANE_LOCATION
        

        Remplacez les valeurs suivantes :

        • CONTROL_PLANE_LOCATION : région Compute Engine du plan de contrôle de votre cluster.
        • CLUSTER_NAME : nom du cluster
      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 -
        

        Remplacez $HF_TOKEN par le jeton Hugging Face que vous avez généré précédemment, ou utilisez la variable d'environnement si vous l'avez définie.

      Créer un conteneur d'affinage à l'aide de Docker et Cloud Build

      Ce conteneur utilise le code PyTorch et Hugging Face Transformers pour affiner le modèle Gemma pré-entraîné existant.

      1. Créez un dépôt Docker Artifact Registry :

        gcloud artifacts repositories create gemma \
            --project=PROJECT_ID \
            --repository-format=docker \
            --location=us \
            --description="Gemma Repo"
        

        Remplacez PROJECT_ID par l'ID de votre projet Google Cloud.

      2. Créez et transférez l'image:

        gcloud builds submit .
        
      3. Exportez le IMAGE_URL pour une utilisation ultérieure dans ce tutoriel.

        export IMAGE_URL=us-docker.pkg.dev/PROJECT_ID/gemma/finetune-gemma-gpu:1.0.0
        

      Exécuter un job d'affinage sur GKE

      Dans cette section, vous allez déployer le job d'affinage Gemma. Dans Kubernetes, un contrôleur Job crée un ou plusieurs pods et s'assure qu'ils exécutent correctement une tâche spécifique.

      1. Ouvrez le fichier finetune.yaml.

        apiVersion: batch/v1
        kind: Job
        metadata:
          name: finetune-job
          namespace: default
        spec:
          backoffLimit: 2
          template:
            metadata:
              annotations:
                kubectl.kubernetes.io/default-container: finetuner
            spec:
              terminationGracePeriodSeconds: 600
              containers:
              - name: finetuner
                image: $IMAGE_URL
                resources:
                  limits:
                    nvidia.com/gpu: "8"
                env:
                - name: MODEL_NAME
                  value: "google/gemma-2b"
                - name: NEW_MODEL
                  value: "gemma-2b-sql-finetuned"
                - name: LORA_R
                  value: "8"
                - name: LORA_ALPHA
                  value: "16"
                - name: TRAIN_BATCH_SIZE
                  value: "1"
                - name: EVAL_BATCH_SIZE
                  value: "2"
                - name: GRADIENT_ACCUMULATION_STEPS
                  value: "2"
                - name: DATASET_LIMIT
                  value: "1000"
                - name: MAX_SEQ_LENGTH
                  value: "512"
                - name: LOGGING_STEPS
                  value: "5"
                - name: HF_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
              restartPolicy: OnFailure
      2. Appliquez le fichier manifeste pour créer le job d'affinage :

        envsubst < finetune.yaml | kubectl apply -f -
        

        Cette instruction remplace IMAGE_URL par la variable du fichier manifeste.

      3. Mettez à jour le job en exécutant la commande suivante :

        watch kubectl get pods
        
      4. Vérifiez les journaux du job en exécutant la commande suivante :

        kubectl logs job.batch/finetune-job -f
        

        La ressource du job télécharge les données du modèle, puis affine le modèle sur les huit GPU. Cette opération peut prendre jusqu'à 20 minutes.

      5. Une fois le job terminé, accédez à votre compte Hugging Face. Un nouveau modèle nommé HF_PROFILE/gemma-2b-sql-finetuned apparaît dans votre profil Hugging Face.

      Diffuser le modèle affiné sur GKE

      Dans cette section, vous allez déployer le conteneur vLLM pour diffuser le modèle Gemma. Ce tutoriel utilise un déploiement Kubernetes pour déployer le conteneur vLLM. Un déploiement est un objet de l'API Kubernetes qui vous permet d'exécuter plusieurs instances dupliquées de pods répartis entre les nœuds d'un cluster.

      1. Créez le fichier manifeste serve-gemma.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-2b
                ai.gke.io/inference-server: vllm
                examples.ai.gke.io/source: user-guide
            spec:
              containers:
              - name: inference-server
                image: docker.io/vllm/vllm-openai:v0.10.0
                resources:
                  requests:
                    cpu: "2"
                    memory: "7Gi"
                    ephemeral-storage: "10Gi"
                    nvidia.com/gpu: 1
                  limits:
                    cpu: "2"
                    memory: "7Gi"
                    ephemeral-storage: "10Gi"
                    nvidia.com/gpu: 1
                command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
                args:
                - --model=$(MODEL_ID)
                - --tensor-parallel-size=1
                env:
                - name: LD_LIBRARY_PATH
                  value: ${LD_LIBRARY_PATH}:/usr/local/nvidia/lib64
                - name: MODEL_ID
                  value: google/gemma-2b
                - 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
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: llm-service
        spec:
          selector:
            app: gemma-server
          type: ClusterIP
          ports:
            - protocol: TCP
              port: 8000
              targetPort: 8000
      2. Créez la variable d'environnement pour le nouveau MODEL_ID :

        export MODEL_ID=HF_PROFILE/gemma-2b-sql-finetuned
        

        Remplacez HF_PROFILE par l'ID de profil Hugging Face que vous avez créé précédemment.

      3. Remplacez MODEL_ID dans le fichier manifeste :

        sed -i "s|google/gemma-2b|$MODEL_ID|g" serve-gemma.yaml
        
      4. Appliquez le fichier manifeste :

        kubectl apply -f serve-gemma.yaml
        

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

      5. Attendez que le déploiement soit disponible :

        kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
        
      6. 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

      Une fois le modèle déployé, 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

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

      Voici un exemple de commande pour TGI :

      USER_PROMPT="Question: What is the total number of attendees with age over 30 at kubecon eu? Context: CREATE TABLE attendees (name VARCHAR, age INTEGER, kubecon VARCHAR)"
      
      curl -X POST http://localhost:8000/generate \
        -H "Content-Type: application/json" \
        -d @- <<EOF
      {
          "prompt": "${USER_PROMPT}",
          "temperature": 0.1,
          "top_p": 1.0,
          "max_tokens": 24
      }
      EOF
      

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

      {"generated_text":" Answer: SELECT COUNT(age) FROM attendees WHERE age > 30 AND kubecon = 'eu'\n"}
      

      Selon votre requête, vous devrez peut-être modifier la valeur max_token pour obtenir un meilleur résultat. Vous pouvez également utiliser le modèle adapté aux instructions pour une meilleure expérience de chat.

      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 \
          --location=CONTROL_PLANE_LOCATION
      

      Remplacez les valeurs suivantes :

      • CONTROL_PLANE_LOCATION : région Compute Engine du plan de contrôle de votre cluster. Indiquez une région compatible avec le type d'accélérateur que vous souhaitez utiliser, par exemple us-central1 pour les GPU L4.
      • CLUSTER_NAME : nom du cluster

      Étapes suivantes