Diffuser un LLM avec GKE Inference Gateway


Ce tutoriel explique comment déployer un grand modèle de langage (LLM) sur Google Kubernetes Engine (GKE) avec la passerelle d'inférence GKE. Le tutoriel explique comment configurer un cluster, déployer un modèle, configurer la passerelle d'inférence GKE et gérer les requêtes LLM.

Ce tutoriel s'adresse aux ingénieurs en machine learning (ML), aux administrateurs et opérateurs de plate-forme, ainsi qu'aux spécialistes des données et de l'IA qui souhaitent déployer et gérer des applications LLM à l'aide de LLM sur GKE avec le GKE Inference Gateway.

Avant de lire cette page, familiarisez-vous avec les points suivants:

Arrière-plan

Cette section décrit les principales technologies utilisées dans ce tutoriel. Pour en savoir plus sur les concepts et la terminologie liés à l'inférence de modèle, et sur la façon dont les fonctionnalités d'IA générative de GKE peuvent améliorer et optimiser les performances de l'inférence de modèle, consultez À propos de l'inférence de modèle sur GKE.

vLLM

vLLM est un framework de diffusion LLM Open Source hautement optimisé qui augmente 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 qui améliore 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.

Passerelle d'inférence GKE

GKE Inference Gateway améliore les fonctionnalités de GKE pour la diffusion de LLM. Il optimise les charges de travail d'inférence avec des fonctionnalités telles que les suivantes:

  • Équilibrage de charge optimisé par inférence en fonction des métriques de charge.
  • Prise en charge de la diffusion multitâche dense des adaptateurs LoRA.
  • Routage tenant compte du modèle pour des opérations simplifiées

Pour en savoir plus, consultez la section À propos de GKE Inference Gateway.

Objectifs

  1. Obtenez un accès au modèle.
  2. Préparez votre environnement.
  3. Créez et configurez des ressources Google Cloud .
  4. Installez les CRD InferenceModel et InferencePool.
  5. Déployer le serveur de modèles
  6. Configurez l'observabilité de votre passerelle d'inférence.

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 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 chaque rôle supplémentaire.
    7. Cliquez sur Enregistrer.

Accéder au modèle

Pour déployer le modèle Llama3.1 sur GKE, signez le contrat de consentement de la licence et générez un jeton d'accès Hugging Face.

Vous devez signer le contrat de consentement pour utiliser le modèle Llama3.1. Procédez comme suit :

  1. Accédez à la page d'autorisation et vérifiez l'autorisation d'utiliser votre compte Hugging Face.
  2. 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.
  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 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=CLUSTER_NAME
    export HF_TOKEN=HF_TOKEN
    

    Remplacez les valeurs suivantes :

    • PROJECT_ID: 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 H100.
    • CLUSTER_NAME : nom du cluster
    • HF_TOKEN: jeton Hugging Face que vous avez généré précédemment.

Créer et configurer des ressources Google Cloud

Pour créer les ressources requises, suivez ces instructions.

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

Diffuser des LLM 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

Remplacez les valeurs suivantes :

  • PROJECT_ID: 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 H100.
  • 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 \
        --region=REGION \
        --workload-pool=PROJECT_ID.svc.id.goog \
        --release-channel=rapid \
        --num-nodes=1 \
        --enable-managed-prometheus \
        --monitoring=SYSTEM,DCGM
    

    Remplacez les valeurs suivantes :

    • PROJECT_ID: 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 H100.
    • CLUSTER_NAME : nom du cluster

    La création du cluster peut prendre plusieurs minutes.

  2. Pour créer un pool de nœuds avec la taille de disque appropriée pour exécuter le modèle Llama-3.1-8B-Instruct, exécutez la commande suivante:

    gcloud container node-pools create gpupool \
        --accelerator type=nvidia-h100-80gb,count=2,gpu-driver-version=latest \
        --project=PROJECT_ID \
        --location=REGION \
        --node-locations=REGION-a \
        --cluster=CLUSTER_NAME \
        --machine-type=a3-highgpu-2g \
        --num-nodes=1 \
        --disk-type="pd-standard"
    

    GKE crée un pool de nœuds unique contenant un GPU H100.

  1. Pour configurer l'autorisation d'extraction des métriques, créez le secret inference-gateway-sa-metrics-reader-secret:

    kubectl apply -f - <<EOF
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: inference-gateway-metrics-reader
    rules:
    - nonResourceURLs:
      - /metrics
      verbs:
      - get
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: inference-gateway-sa-metrics-reader
      namespace: default
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: inference-gateway-sa-metrics-reader-role-binding
      namespace: default
    subjects:
    - kind: ServiceAccount
      name: inference-gateway-sa-metrics-reader
      namespace: default
    roleRef:
      kind: ClusterRole
      name: inference-gateway-metrics-reader
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: inference-gateway-sa-metrics-reader-secret
      namespace: default
      annotations:
        kubernetes.io/service-account.name: inference-gateway-sa-metrics-reader
    type: kubernetes.io/service-account-token
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: inference-gateway-sa-metrics-reader-secret-read
    rules:
    - resources:
      - secrets
      apiGroups: [""]
      verbs: ["get", "list", "watch"]
      resourceNames: ["inference-gateway-sa-metrics-reader-secret"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: gmp-system:collector:inference-gateway-sa-metrics-reader-secret-read
      namespace: default
    roleRef:
      name: inference-gateway-sa-metrics-reader-secret-read
      kind: ClusterRole
      apiGroup: rbac.authorization.k8s.io
    subjects:
    - name: collector
      namespace: gmp-system
      kind: ServiceAccount
    EOF
    

Créer un secret Kubernetes pour les identifiants Hugging Face

Dans Cloud Shell, procédez comme suit :

  1. Pour communiquer avec votre cluster, configurez kubectl:

      gcloud container clusters get-credentials CLUSTER_NAME \
          --location=REGION
    

    Remplacez les valeurs suivantes :

    • REGION: région compatible avec le type d'accélérateur que vous souhaitez utiliser, par exemple us-central1 pour les GPU H100.
    • CLUSTER_NAME : nom du cluster
  2. Créez un secret Kubernetes contenant le jeton Hugging Face:

      kubectl create secret generic HF_SECRET \
          --from-literal=token=HF_TOKEN \
          --dry-run=client -o yaml | kubectl apply -f -
    

    Remplacez les éléments suivants :

    • HF_TOKEN: jeton Hugging Face que vous avez généré précédemment.
    • HF_SECRET: nom de votre secret Kubernetes. Exemple :hf-secret

Installer les CRD InferenceModel et InferencePool

Dans cette section, vous allez installer les définitions de ressources personnalisées (CRD) nécessaires pour GKE Inference Gateway.

Les CRD étendent l'API Kubernetes. Cela vous permet de définir de nouveaux types de ressources. Pour utiliser le GKE Inference Gateway, installez les CRD InferencePool et InferenceModel dans votre cluster GKE en exécutant la commande suivante:

kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/v0.3.0/manifests.yaml

Déployer le serveur de modèles

Cet exemple déploie un modèle Llama3.1 à l'aide d'un serveur de modèle vLLM. Le déploiement est associé à l'étiquette app:vllm-llama3-8b-instruct. Ce déploiement utilise également deux adaptateurs LoRA nommés food-review et cad-fabricator de Hugging Face. Vous pouvez mettre à jour ce déploiement avec votre propre serveur de modèle et votre propre conteneur de modèle, votre port de diffusion et le nom du déploiement. Vous pouvez éventuellement configurer des adaptateurs LoRA dans le déploiement ou déployer le modèle de base.

  1. Pour déployer sur un type d'accélérateur nvidia-h100-80gb, enregistrez le fichier manifeste suivant sous le nom vllm-llama3-8b-instruct.yaml. Ce fichier manifeste définit un déploiement Kubernetes avec votre modèle et votre serveur de modèles:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vllm-llama3-8b-instruct
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: vllm-llama3-8b-instruct
      template:
        metadata:
          labels:
            app: vllm-llama3-8b-instruct
        spec:
          containers:
            - name: vllm
              image: "vllm/vllm-openai:latest"
              imagePullPolicy: Always
              command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
              args:
              - "--model"
              - "meta-llama/Llama-3.1-8B-Instruct"
              - "--tensor-parallel-size"
              - "1"
              - "--port"
              - "8000"
              - "--enable-lora"
              - "--max-loras"
              - "2"
              - "--max-cpu-loras"
              - "12"
              env:
                # Enabling LoRA support temporarily disables automatic v1, we want to force it on
                # until 0.8.3 vLLM is released.
                - name: VLLM_USE_V1
                  value: "1"
                - name: PORT
                  value: "8000"
                - name: HUGGING_FACE_HUB_TOKEN
                  valueFrom:
                    secretKeyRef:
                      name: hf-token
                      key: token
                - name: VLLM_ALLOW_RUNTIME_LORA_UPDATING
                  value: "true"
              ports:
                - containerPort: 8000
                  name: http
                  protocol: TCP
              lifecycle:
                preStop:
                  # vLLM stops accepting connections when it receives SIGTERM, so we need to sleep
                  # to give upstream gateways a chance to take us out of rotation. The time we wait
                  # is dependent on the time it takes for all upstreams to completely remove us from
                  # rotation. Older or simpler load balancers might take upwards of 30s, but we expect
                  # our deployment to run behind a modern gateway like Envoy which is designed to
                  # probe for readiness aggressively.
                  sleep:
                    # Upstream gateway probers for health should be set on a low period, such as 5s,
                    # and the shorter we can tighten that bound the faster that we release
                    # accelerators during controlled shutdowns. However, we should expect variance,
                    # as load balancers may have internal delays, and we don't want to drop requests
                    # normally, so we're often aiming to set this value to a p99 propagation latency
                    # of readiness -> load balancer taking backend out of rotation, not the average.
                    #
                    # This value is generally stable and must often be experimentally determined on
                    # for a given load balancer and health check period. We set the value here to
                    # the highest value we observe on a supported load balancer, and we recommend
                    # tuning this value down and verifying no requests are dropped.
                    #
                    # If this value is updated, be sure to update terminationGracePeriodSeconds.
                    #
                    seconds: 30
                  #
                  # IMPORTANT: preStop.sleep is beta as of Kubernetes 1.30 - for older versions
                  # replace with this exec action.
                  #exec:
                  #  command:
                  #  - /usr/bin/sleep
                  #  - 30
              livenessProbe:
                httpGet:
                  path: /health
                  port: http
                  scheme: HTTP
                # vLLM's health check is simple, so we can more aggressively probe it.  Liveness
                # check endpoints should always be suitable for aggressive probing.
                periodSeconds: 1
                successThreshold: 1
                # vLLM has a very simple health implementation, which means that any failure is
                # likely significant. However, any liveness triggered restart requires the very
                # large core model to be reloaded, and so we should bias towards ensuring the
                # server is definitely unhealthy vs immediately restarting. Use 5 attempts as
                # evidence of a serious problem.
                failureThreshold: 5
                timeoutSeconds: 1
              readinessProbe:
                httpGet:
                  path: /health
                  port: http
                  scheme: HTTP
                # vLLM's health check is simple, so we can more aggressively probe it.  Readiness
                # check endpoints should always be suitable for aggressive probing, but may be
                # slightly more expensive than readiness probes.
                periodSeconds: 1
                successThreshold: 1
                # vLLM has a very simple health implementation, which means that any failure is
                # likely significant,
                failureThreshold: 1
                timeoutSeconds: 1
              # We set a startup probe so that we don't begin directing traffic or checking
              # liveness to this instance until the model is loaded.
              startupProbe:
                # Failure threshold is when we believe startup will not happen at all, and is set
                # to the maximum possible time we believe loading a model will take. In our
                # default configuration we are downloading a model from HuggingFace, which may
                # take a long time, then the model must load into the accelerator. We choose
                # 10 minutes as a reasonable maximum startup time before giving up and attempting
                # to restart the pod.
                #
                # IMPORTANT: If the core model takes more than 10 minutes to load, pods will crash
                # loop forever. Be sure to set this appropriately.
                failureThreshold: 3600
                # Set delay to start low so that if the base model changes to something smaller
                # or an optimization is deployed, we don't wait unnecessarily.
                initialDelaySeconds: 2
                # As a startup probe, this stops running and so we can more aggressively probe
                # even a moderately complex startup - this is a very important workload.
                periodSeconds: 1
                httpGet:
                  # vLLM does not start the OpenAI server (and hence make /health available)
                  # until models are loaded. This may not be true for all model servers.
                  path: /health
                  port: http
                  scheme: HTTP
    
              resources:
                limits:
                  nvidia.com/gpu: 1
                requests:
                  nvidia.com/gpu: 1
              volumeMounts:
                - mountPath: /data
                  name: data
                - mountPath: /dev/shm
                  name: shm
                - name: adapters
                  mountPath: "/adapters"
          initContainers:
            - name: lora-adapter-syncer
              tty: true
              stdin: true
              image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/lora-syncer:main
              restartPolicy: Always
              imagePullPolicy: Always
              env:
                - name: DYNAMIC_LORA_ROLLOUT_CONFIG
                  value: "/config/configmap.yaml"
              volumeMounts: # DO NOT USE subPath, dynamic configmap updates don't work on subPaths
              - name: config-volume
                mountPath:  /config
          restartPolicy: Always
    
          # vLLM allows VLLM_PORT to be specified as an environment variable, but a user might
          # create a 'vllm' service in their namespace. That auto-injects VLLM_PORT in docker
          # compatible form as `tcp://<IP>:<PORT>` instead of the numeric value vLLM accepts
          # causing CrashLoopBackoff. Set service environment injection off by default.
          enableServiceLinks: false
    
          # Generally, the termination grace period needs to last longer than the slowest request
          # we expect to serve plus any extra time spent waiting for load balancers to take the
          # model server out of rotation.
          #
          # An easy starting point is the p99 or max request latency measured for your workload,
          # although LLM request latencies vary significantly if clients send longer inputs or
          # trigger longer outputs. Since steady state p99 will be higher than the latency
          # to drain a server, you may wish to slightly this value either experimentally or
          # via the calculation below.
          #
          # For most models you can derive an upper bound for the maximum drain latency as
          # follows:
          #
          #   1. Identify the maximum context length the model was trained on, or the maximum
          #      allowed length of output tokens configured on vLLM (llama2-7b was trained to
          #      4k context length, while llama3-8b was trained to 128k).
          #   2. Output tokens are the more compute intensive to calculate and the accelerator
          #      will have a maximum concurrency (batch size) - the time per output token at
          #      maximum batch with no prompt tokens being processed is the slowest an output
          #      token can be generated (for this model it would be about 100ms TPOT at a max
          #      batch size around 50)
          #   3. Calculate the worst case request duration if a request starts immediately
          #      before the server stops accepting new connections - generally when it receives
          #      SIGTERM (for this model that is about 4096 / 10 ~ 40s)
          #   4. If there are any requests generating prompt tokens that will delay when those
          #      output tokens start, and prompt token generation is roughly 6x faster than
          #      compute-bound output token generation, so add 20% to the time from above (40s +
          #      16s ~ 55s)
          #
          # Thus we think it will take us at worst about 55s to complete the longest possible
          # request the model is likely to receive at maximum concurrency (highest latency)
          # once requests stop being sent.
          #
          # NOTE: This number will be lower than steady state p99 latency since we stop       receiving
          #       new requests which require continuous prompt token computation.
              # NOTE: The max timeout for backend connections from gateway to model servers should
          #       be configured based on steady state p99 latency, not drain p99 latency
          #
          #   5. Add the time the pod takes in its preStop hook to allow the load balancers have
          #      stopped sending us new requests (55s + 30s ~ 85s)
          #
          # Because the termination grace period controls when the Kubelet forcibly terminates a
          # stuck or hung process (a possibility due to a GPU crash), there is operational safety
          # in keeping the value roughly proportional to the time to finish serving. There is also
          # value in adding a bit of extra time to deal with unexpectedly long workloads.
          #
          #   6. Add a 50% safety buffer to this time since the operational impact should be low
          #      (85s * 1.5 ~ 130s)
          #
          # One additional source of drain latency is that some workloads may run close to
          # saturation and have queued requests on each server. Since traffic in excess of the
          # max sustainable QPS will result in timeouts as the queues grow, we assume that failure
          # to drain in time due to excess queues at the time of shutdown is an expected failure
          # mode of server overload. If your workload occasionally experiences high queue depths
          # due to periodic traffic, consider increasing the safety margin above to account for
          # time to drain queued requests.
          terminationGracePeriodSeconds: 130
          nodeSelector:
            cloud.google.com/gke-accelerator: "nvidia-h100-80gb"
          volumes:
            - name: data
              emptyDir: {}
            - name: shm
              emptyDir:
                medium: Memory
            - name: adapters
              emptyDir: {}
            - name: config-volume
              configMap:
                name: vllm-llama3-8b-adapters
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: vllm-llama3-8b-adapters
    data:
      configmap.yaml: |
          vLLMLoRAConfig:
            name: vllm-llama3.1-8b-instruct
            port: 8000
            defaultBaseModel: meta-llama/Llama-3.1-8B-Instruct
            ensureExist:
              models:
              - id: food-review
                source: Kawon/llama3.1-food-finetune_v14_r8
              - id: cad-fabricator
                source: redcathode/fabricator
    ---
    kind: HealthCheckPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: health-check-policy
      namespace: default
    spec:
      targetRef:
        group: "inference.networking.x-k8s.io"
        kind: InferencePool
        name: vllm-llama3-8b-instruct
      default:
        config:
          type: HTTP
          httpHealthCheck:
              requestPath: /health
              port: 8000
    
  2. Appliquez le fichier manifeste à votre cluster :

    kubectl apply -f vllm-llama3-8b-instruct.yaml
    

Créer une ressource InferencePool

La ressource personnalisée Kubernetes InferencePool définit un groupe de pods avec une configuration de calcul et de LLM de base commune.

La ressource personnalisée InferencePool inclut les principaux champs suivants:

  • selector: spécifie les pods appartenant à ce pool. Les libellés de ce sélecteur doivent correspondre exactement aux libellés appliqués à vos pods de serveur de modèle.
  • targetPort: définit les ports utilisés par le serveur de modèles dans les pods.

La ressource InferencePool permet à GKE Inference Gateway d'acheminer le trafic vers vos pods de serveur de modèle.

Pour créer un InferencePool à l'aide de Helm, procédez comme suit:

helm install vllm-llama3-8b-instruct \
  --set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
  --set provider.name=gke \
  --set healthCheckPolicy.create=false \
  --version v0.3.0 \
  oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool

Modifiez le champ suivant pour qu'il corresponde à votre déploiement:

  • inferencePool.modelServers.matchLabels.app: clé du libellé utilisé pour sélectionner vos pods de serveur de modèle.

Cette commande crée un objet InferencePool qui représente de manière logique le déploiement de votre serveur de modèle et qui fait référence aux services de point de terminaison du modèle dans les pods sélectionnés par Selector.

Créer une ressource InferenceModel avec une criticité de diffusion

La ressource personnalisée Kubernetes InferenceModel définit un modèle spécifique, y compris les modèles configurés pour LoRA, et sa criticité de diffusion.

La ressource personnalisée InferenceModel inclut les principaux champs suivants:

  • modelName: spécifie le nom du modèle de base ou de l'adaptateur LoRA.
  • Criticality: spécifie la criticité de diffusion du modèle.
  • poolRef: fait référence à l'InferencePool sur lequel le modèle est diffusé.

InferenceModel permet à la passerelle d'inférence GKE d'acheminer le trafic vers vos pods de serveur de modèle en fonction du nom et de la criticité du modèle.

Pour créer un InferenceModel, procédez comme suit:

  1. Enregistrez l'exemple de fichier manifeste suivant sous le nom inferencemodel.yaml :

    apiVersion: inference.networking.x-k8s.io/v1alpha2
    kind: InferenceModel
    metadata:
      name: inferencemodel-sample
    spec:
      modelName: MODEL_NAME
      criticality: CRITICALITY
      poolRef:
        name: INFERENCE_POOL_NAME
    

    Remplacez les éléments suivants :

    • MODEL_NAME: nom de votre modèle de base ou de votre adaptateur LoRa. Exemple :food-review
    • CRITICALITY: criticité de diffusion choisie. Sélectionnez Critical, Standard ou Sheddable. Par exemple, Standard.
    • INFERENCE_POOL_NAME: nom de l'InferencePool que vous avez créé à l'étape précédente. Exemple : vllm-llama3-8b-instruct.
  2. Appliquez l'exemple de fichier manifeste à votre cluster:

    kubectl apply -f inferencemodel.yaml
    

L'exemple suivant crée un objet InferenceModel qui configure le modèle LoRA food-review sur le InferencePool vllm-llama3-8b-instruct avec une criticité de service Standard. L'objet InferenceModel configure également le modèle de base pour qu'il soit diffusé avec un niveau de priorité Critical.

apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceModel
metadata:
  name: food-review
spec:
  modelName: food-review
  criticality: Standard
  poolRef:
    name: vllm-llama3-8b-instruct
  targetModels:
  - name: food-review
    weight: 100

---
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceModel
metadata:
  name: llama3-base-model
spec:
  modelName: meta-llama/Llama-3.1-8B-Instruct
  criticality: Critical
  poolRef:
    name: vllm-llama3-8b-instruct

Créer la passerelle

La ressource Gateway sert de point d'entrée au trafic externe vers votre cluster Kubernetes. Il définit les écouteurs qui acceptent les connexions entrantes.

GKE Inference Gateway est compatible avec la classe de passerelle gke-l7-rilb et gke-l7-regional-external-managed. Pour en savoir plus, consultez la documentation GKE sur les classes Gateway.

Pour créer une passerelle, procédez comme suit:

  1. Enregistrez l'exemple de fichier manifeste suivant sous le nom gateway.yaml :

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: GATEWAY_NAME
    spec:
      gatewayClassName: gke-l7-regional-external-managed
      listeners:
        - protocol: HTTP # Or HTTPS for production
          port: 80 # Or 443 for HTTPS
          name: http
    

    Remplacez GATEWAY_NAME par un nom unique pour votre ressource de passerelle. Exemple :inference-gateway

  2. Appliquez le fichier manifeste à votre cluster :

    kubectl apply -f gateway.yaml
    

Créer la ressource HTTPRoute

Dans cette section, vous allez créer une ressource HTTPRoute pour définir comment la passerelle achemine les requêtes HTTP entrantes vers votre InferencePool.

La ressource HTTPRoute définit la manière dont la passerelle GKE achemine les requêtes HTTP entrantes vers les services de backend, qui sont vos InferencePool. Il spécifie les règles de correspondance (par exemple, les en-têtes ou les chemins d'accès) et le backend auquel le trafic doit être transféré.

Pour créer un HTTPRoute, procédez comme suit:

  1. Enregistrez l'exemple de fichier manifeste suivant sous le nom httproute.yaml :

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: HTTPROUTE_NAME
    spec:
      parentRefs:
      - name: GATEWAY_NAME
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: PATH_PREFIX
        backendRefs:
        - name: INFERENCE_POOL_NAME
          group: inference.networking.x-k8s.io
          kind: InferencePool
    

    Remplacez les éléments suivants :

    • HTTPROUTE_NAME: nom unique de votre ressource HTTPRoute. Par exemple, my-route.
    • GATEWAY_NAME: nom de la ressource Gateway que vous avez créée. Par exemple, inference-gateway.
    • PATH_PREFIX: préfixe de chemin d'accès que vous utilisez pour faire correspondre les requêtes entrantes. Par exemple, / pour correspondre à tout.
    • INFERENCE_POOL_NAME: nom de la ressource InferencePool vers laquelle vous souhaitez acheminer le trafic. Par exemple, vllm-llama3-8b-instruct.
  2. Appliquez le fichier manifeste à votre cluster :

    kubectl apply -f httproute.yaml
    

Envoyer une requête d'inférence

Une fois que vous avez configuré GKE Inference Gateway, vous pouvez envoyer des requêtes d'inférence à votre modèle déployé.

Pour envoyer des requêtes d'inférence, procédez comme suit:

  • Récupérez le point de terminaison de la passerelle.
  • Créez une requête JSON correctement mise en forme.
  • Utilisez curl pour envoyer la requête au point de terminaison /v1/completions.

Vous pouvez ainsi générer du texte en fonction de votre requête d'entrée et des paramètres spécifiés.

  1. Pour obtenir le point de terminaison de la passerelle, exécutez la commande suivante:

    IP=$(kubectl get gateway/GATEWAY_NAME -o jsonpath='{.status.addresses[0].value}')
    PORT=PORT_NUMBER # Use 443 for HTTPS, or 80 for HTTP
    

    Remplacez les éléments suivants :

    • GATEWAY_NAME: nom de votre ressource de passerelle.
    • PORT_NUMBER: numéro de port que vous avez configuré dans la passerelle.
  2. Pour envoyer une requête au point de terminaison /v1/completions à l'aide de curl, exécutez la commande suivante:

    curl -i -X POST https://${IP}:${PORT}/v1/completions \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer $(gcloud auth print-access-token)' \
    -d '{
        "model": "MODEL_NAME",
        "prompt": "PROMPT_TEXT",
        "max_tokens": MAX_TOKENS,
        "temperature": "TEMPERATURE"
    }'
    

    Remplacez les éléments suivants :

    • MODEL_NAME: nom du modèle ou de l'adaptateur LoRA à utiliser.
    • PROMPT_TEXT: requête d'entrée du modèle.
    • MAX_TOKENS: nombre maximal de jetons à générer dans la réponse.
    • TEMPERATURE: contrôle le caractère aléatoire de la sortie. Utilisez la valeur 0 pour une sortie déterministe ou un nombre plus élevé pour une sortie plus créative.

Tenez compte des comportements suivants:

  • Corps de la requête: le corps de la requête peut inclure des paramètres supplémentaires tels que stop et top_p. Pour obtenir la liste complète des options, consultez la spécification de l'API OpenAI.
  • Traitement des erreurs: implémentez un traitement approprié des erreurs dans votre code client pour gérer les erreurs potentielles dans la réponse. Par exemple, vérifiez le code d'état HTTP dans la réponse curl. Un code d'état autre que 200 indique généralement une erreur.
  • Authentification et autorisation: pour les déploiements en production, sécurisez votre point de terminaison d'API à l'aide de mécanismes d'authentification et d'autorisation. Incluez les en-têtes appropriés (par exemple, Authorization) dans vos requêtes.

Configurer l'observabilité de votre passerelle d'inférence

La passerelle d'inférence GKE offre une observabilité sur l'état, les performances et le comportement de vos charges de travail d'inférence. Cela vous aide à identifier et à résoudre les problèmes, à optimiser l'utilisation des ressources et à garantir la fiabilité de vos applications. Vous pouvez afficher ces métriques d'observabilité dans Cloud Monitoring via l'explorateur de métriques.

Pour configurer l'observabilité pour GKE Inference Gateway, consultez la section Configurer l'observabilité.

Supprimer les ressources déployées

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

gcloud container clusters delete CLUSTER_NAME \
    --region=REGION

Remplacez les valeurs suivantes :

  • REGION: région compatible avec le type d'accélérateur que vous souhaitez utiliser, par exemple us-central1 pour les GPU H100.
  • CLUSTER_NAME : nom du cluster

Étapes suivantes