Déployer la passerelle d'inférence GKE


Cette page explique comment déployer GKE Inference Gateway.

Cette page s'adresse aux spécialistes de la mise en réseau chargés de gérer l'infrastructure GKE et aux administrateurs de plate-forme qui gèrent les charges de travail d'IA.

Avant de lire cette page, assurez-vous de connaître les éléments suivants:

La passerelle d'inférence GKE améliore la passerelle Google Kubernetes Engine (GKE) pour optimiser la diffusion des applications d'IA générative. GKE Inference Gateway vous permet d'optimiser le traitement des charges de travail d'IA générative sur GKE. Il permet de gérer et d'évoluer efficacement les charges de travail d'IA, d'atteindre des objectifs de performances spécifiques aux charges de travail, comme la latence, et d'améliorer l'utilisation des ressources, l'observabilité et la sécurité de l'IA.

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez gcloud CLI. Si vous avez déjà installé gcloud CLI, assurez-vous de disposer de la dernière version en exécutant la commande gcloud components update.
  • Activez l'API Compute Engine, l'API Network Services et l'API Model Armor si nécessaire.

    Accédez à Activer l'accès aux API et suivez les instructions.

Conditions requises pour le contrôleur GKE Gateway

  • Version de GKE 1.32.3
  • Google Cloud CLI version 407.0.0 ou ultérieure.
  • L'API Gateway n'est compatible qu'avec les clusters de VPC natif.
  • Vous devez activer un sous-réseau proxy réservé.
  • Le module complémentaire HttpLoadBalancing doit être activé sur votre cluster.
  • Si vous utilisez Istio, vous devez mettre à niveau Istio vers l'une des versions suivantes :
    • 1.15.2 ou ultérieure
    • 1.14.5 ou ultérieure
    • 1.13.9 ou version ultérieure
  • Si vous utilisez un VPC partagé, vous devez attribuer le rôle Compute Network User au compte de service GKE du projet de service dans le projet hôte.

Restrictions et limitations

Les restrictions et limites suivantes s'appliquent:

  • Les passerelles multiclusters ne sont pas compatibles.
  • GKE Inference Gateway n'est compatible qu'avec les ressources GatewayClass gke-l7-regional-external-managed et gke-l7-rilb.
  • Les équilibreurs de charge d'application internes interrégionaux ne sont pas compatibles.

Configurer la passerelle d'inférence GKE

Pour configurer la passerelle d'inférence GKE, consultez cet exemple. Une équipe exécute des modèles vLLM et Llama3, et teste activement deux adaptateurs LoRA affinés distincts: "food-review" et "cad-fabricator".

Le workflow général pour configurer GKE Inference Gateway est le suivant:

  1. Préparez votre environnement: configurez l'infrastructure et les composants nécessaires.
  2. Créer un pool d'inférence: définissez un pool de serveurs de modèles à l'aide de la ressource personnalisée InferencePool.
  3. Spécifiez les objectifs de diffusion du modèle: spécifiez les objectifs du modèle à l'aide de la ressource personnalisée InferenceModel.
  4. Créez la passerelle: exposez le service d'inférence à l'aide de l'API Gateway.
  5. Créez HTTPRoute: définissez le routage du trafic HTTP vers le service d'inférence.
  6. Envoyer des requêtes d'inférence: envoyez des requêtes au modèle déployé.

Préparer votre environnement

  1. Installez Helm.

  2. Créez un cluster GKE :

  3. Pour installer les définitions de ressources personnalisées (CRD, Custom Resource Definitions) InferencePool et InferenceModel dans votre cluster GKE, exécutez la commande suivante:

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

    Remplacez VERSION par la version des CRD que vous souhaitez installer (par exemple, v0.3.0).

  4. Si vous utilisez une version de GKE antérieure à la version 1.32.2-gke.1182001 et que vous souhaitez utiliser Model Armor avec le GKE Inference Gateway, vous devez installer les CRD d'extension de trafic et de routage:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcptrafficextensions.yaml
    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcproutingextensions.yaml
    
  5. 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 serveur de modèle et le déployer

Cette section explique comment déployer un serveur de modèles et un modèle. L'exemple utilise un serveur de modèles vLLM avec un modèle Llama3. Le déploiement est marqué comme 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 adapter cet exemple avec votre propre conteneur de serveur de modèle et votre propre modèle, port de service et nom de déploiement. Vous pouvez également configurer des adaptateurs LoRA dans le déploiement ou déployer le modèle de base. Les étapes suivantes décrivent comment créer les ressources Kubernetes nécessaires.

  1. Créez un secret Kubernetes pour stocker votre jeton Hugging Face. Ce jeton est utilisé pour accéder aux adaptateurs LoRA:

    kubectl create secret generic hf-token --from-literal=token=HF_TOKEN
    

    Remplacez HF_TOKEN par votre jeton Hugging Face.

  2. 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: 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 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
    
  3. Appliquez l'exemple de fichier manifeste à votre cluster:

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

Après avoir appliqué le fichier manifeste, tenez compte des champs et paramètres clés suivants:

  • replicas: spécifie le nombre de pods pour le déploiement.
  • image: spécifie l'image Docker pour le serveur de modèle.
  • command: spécifie la commande à exécuter au démarrage du conteneur.
  • args: spécifie les arguments à transmettre à la commande.
  • env: spécifie les variables d'environnement du conteneur.
  • ports: spécifie les ports exposés par le conteneur.
  • resources: spécifie les demandes et les limites de ressources pour le conteneur, telles que le GPU.
  • volumeMounts: spécifie comment les volumes sont installés dans le conteneur.
  • initContainers: spécifie les conteneurs qui s'exécutent avant le conteneur d'application.
  • restartPolicy: spécifie la règle de redémarrage des pods.
  • terminationGracePeriodSeconds: spécifie le délai de grâce pour la résiliation du pod.
  • volumes: spécifie les volumes utilisés par les pods.

Vous pouvez modifier ces champs pour les adapter à vos besoins spécifiques.

Créer un pool d'inférence

La ressource personnalisée Kubernetes InferencePool définit un groupe de pods avec un grand modèle de langage (LLM) de base commun et une configuration de calcul. Le champ selector spécifie les pods qui appartiennent à ce pool. Les libellés de ce sélecteur doivent correspondre exactement aux libellés appliqués à vos pods de serveur de modèle. Le champ targetPort définit les ports que le serveur de modèle utilise dans les pods. Le champ extensionRef fait référence à un service d'extension qui fournit des fonctionnalités supplémentaires pour le pool d'inférence. InferencePool permet à la passerelle d'inférence GKE de router le trafic vers vos pods de serveur de modèle.

Avant de créer le InferencePool, assurez-vous que les pods sélectionnés par le InferencePool sont déjà en cours d'exécution.

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 \
  --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.

L'installation Helm installe automatiquement la règle de délai avant expiration, le sélecteur de point de terminaison et les pods nécessaires à l'observabilité.

Cela crée un objet InferencePool: vllm-llama3-8b-instruct qui fait référence aux services de point de terminaison du modèle dans les pods. Il crée également un déploiement du sélecteur de point de terminaison nommé app:vllm-llama3-8b-instruct-epp pour ce InferencePool créé.

Spécifier les objectifs de diffusion du modèle

La ressource personnalisée InferenceModel définit un modèle spécifique à diffuser, qui inclut la prise en charge des modèles configurés pour LoRA et la criticité de la diffusion. Vous devez définir les modèles diffusés sur un InferencePool en créant des ressources InferenceModel. Ces ressources InferenceModel peuvent faire référence à des modèles de base ou à des adaptateurs LoRA compatibles avec les serveurs de modèles dans InferencePool.

Le champ modelName spécifie le nom du modèle de base ou de l'adaptateur LoRA. Le champ Criticality spécifie la criticité de diffusion du modèle. Le champ poolRef spécifie le InferencePool sur lequel ce modèle est diffusé.

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: VALUE
      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
    • VALUE: 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 est le point d'entrée du trafic externe dans votre cluster Kubernetes. Il définit les écouteurs qui acceptent les connexions entrantes.

Le GKE Inference Gateway fonctionne avec les classes Gateway suivantes:

  • gke-l7-rilb: pour les équilibreurs de charge d'application internes régionaux.
  • gke-l7-regional-external-managed

Pour en savoir plus, consultez la documentation sur les classes de passerelle.

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: GATEWAY_CLASS
      listeners:
        - protocol: HTTP
          port: 80
          name: http
    

    Remplacez GATEWAY_NAME par un nom unique pour votre ressource de passerelle (par exemple, inference-gateway) et GATEWAY_CLASS par la classe de passerelle que vous souhaitez utiliser (par exemple, gke-l7-regional-external-managed).

  2. Appliquez le fichier manifeste à votre cluster :

    kubectl apply -f gateway.yaml
    

Remarque: Pour en savoir plus sur la configuration de TLS afin de sécuriser votre passerelle avec HTTPS, consultez la documentation GKE sur la configuration TLS.

Créer le HTTPRoute

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

  1. Pour créer un HTTPRoute, 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é la passerelle d'inférence GKE, vous pouvez envoyer des requêtes d'inférence à votre modèle déployé. Vous pouvez ainsi générer du texte en fonction de votre requête d'entrée et des paramètres spécifiés.

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

  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 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 ${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.

L'exemple suivant montre comment envoyer un exemple de requête à la passerelle d'inférence GKE:

curl -i -X POST ${IP}:${PORT}/v1/completions -H 'Content-Type: application/json' -H 'Authorization: Bearer $(gcloud auth print-access-token)' -d '{
    "model": "food-review",
    "prompt": "What is the best pizza in the world?",
    "max_tokens": 2048,
    "temperature": "0"
}'

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.

Étapes suivantes