Implantar o gateway de inferência do GKE


Esta página descreve como implantar o GKE Inference Gateway.

Esta página é destinada a especialistas em redes responsáveis por gerenciar a infraestrutura do GKE e administradores de plataformas que gerenciam cargas de trabalho de IA.

Antes de ler esta página, confira se você conhece os seguintes conceitos:

O Gateway de inferência do GKE aprimora o Gateway do Google Kubernetes Engine (GKE) para otimizar a veiculação de aplicativos de IA generativa. O GKE Inference Gateway permite otimizar a veiculação de cargas de trabalho de IA gerativa no GKE. Ele oferece gerenciamento e escalonamento eficientes de cargas de trabalho de IA, possibilita objetivos de desempenho específicos da carga de trabalho, como latência, e aprimora a utilização de recursos, a observabilidade e a segurança da IA.

Antes de começar

Antes de começar, veja se você realizou as seguintes tarefas:

  • Ative a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a CLI do Google Cloud para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a gcloud CLI anteriormente, instale a versão mais recente executando gcloud components update.
  • Ative a API Compute Engine, a API Network Services e a API Model Armor, se necessário.

    Acesse Ativar o acesso a APIs e siga as instruções.

Requisitos do GKE Gateway Controller

  • Versão 1.32.3 do GKE.
  • Google Cloud CLI versão 407.0.0 ou mais recente.
  • A API Gateway é compatível apenas com clusters nativos da VPC.
  • Ative uma sub-rede somente proxy.
  • O cluster precisa ter o complemento HttpLoadBalancing ativado.
  • Se você estiver usando o Istio, será necessário fazer upgrade do Istio para uma das seguintes versões:
    • 1.15.2 ou mais recente
    • 1.14.5 ou mais recente
    • 1.13.9 ou mais recente
  • Se você estiver usando a VPC compartilhada, será necessário atribuir o papel Compute Network User à conta de serviço do GKE para o projeto de serviço no projeto host.

Restrições e limitações

As seguintes restrições e limitações são válidas:

  • Não há suporte para gateways de vários clusters.
  • O Gateway de inferência do GKE só tem suporte para os recursos GatewayClass gke-l7-regional-external-managed e gke-l7-rilb.
  • Não há suporte para balanceadores de carga de aplicativo internos entre regiões.

Configurar o gateway de inferência do GKE

Para configurar o gateway de inferência do GKE, considere este exemplo. Uma equipe executa modelos vLLM e Llama3 e experimenta ativamente dois adaptadores LoRA diferentes: "food-review" e "cad-fabricator".

O fluxo de trabalho de alto nível para configurar o GKE Inference Gateway é o seguinte:

  1. Prepare o ambiente: configure a infraestrutura e os componentes necessários.
  2. Criar um pool de inferência: defina um pool de servidores de modelo usando o recurso personalizado InferencePool.
  3. Especificar objetivos de veiculação do modelo: especifique os objetivos do modelo usando o recurso personalizado InferenceModel.
  4. Crie o gateway: exponha o serviço de inferência usando a API Gateway.
  5. Crie o HTTPRoute: defina como o tráfego HTTP é encaminhado para o serviço de inferência.
  6. Enviar solicitações de inferência: faça solicitações para o modelo implantado.

Preparar o ambiente

  1. Instale o Helm.

  2. Crie um cluster do GKE:

  3. Para instalar a definição de recurso personalizado (CRDs, na sigla em inglês) InferencePool e InferenceModel no cluster do GKE, execute o seguinte comando:

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

    Substitua VERSION pela versão dos CRDs que você quer instalar (por exemplo, v0.3.0).

  4. Se você estiver usando uma versão do GKE anterior à v1.32.2-gke.1182001 e quiser usar o Model Armor com o GKE Inference Gateway, será necessário instalar os CRDs de extensão de roteamento e tráfego:

    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. Para configurar a autorização de coleta de métricas, crie o 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
    

Criar um servidor de modelo e uma implantação de modelo

Esta seção mostra como implantar um servidor de modelo e um modelo. O exemplo usa um servidor de modelo vLLM com um modelo Llama3. A implantação é marcada como app:vllm-llama3-8b-instruct. Essa implantação também usa dois adaptadores LoRA chamados food-review e cad-fabricator do Hugging Face.

É possível adaptar esse exemplo com seu próprio contêiner e modelo do servidor de modelo, porta de exibição e nome da implantação. Também é possível configurar adaptadores LoRA na implantação ou implantar o modelo base. As etapas a seguir descrevem como criar os recursos necessários do Kubernetes.

  1. Crie um secret do Kubernetes para armazenar seu token do Hugging Face. Esse token é usado para acessar os adaptadores LoRA:

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

    Substitua HF_TOKEN pelo seu token do Hugging Face.

  2. Para implantar em um tipo de acelerador nvidia-h100-80gb, salve o manifesto a seguir como vllm-llama3-8b-instruct.yaml. Esse manifesto define uma implantação do Kubernetes com o modelo e o servidor de modelo:

    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: 600
                # 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. Aplique o manifesto de exemplo ao cluster:

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

Depois de aplicar o manifesto, considere os seguintes campos e parâmetros principais:

  • replicas: especifica o número de pods para a implantação.
  • image: especifica a imagem do Docker para o servidor de modelos.
  • command: especifica o comando a ser executado quando o contêiner for iniciado.
  • args: especifica os argumentos a serem transmitidos ao comando.
  • env: especifica variáveis de ambiente para o contêiner.
  • ports: especifica as portas expostas pelo contêiner.
  • resources: especifica as solicitações e os limites de recursos do contêiner, como a GPU.
  • volumeMounts: especifica como os volumes são montados no contêiner.
  • initContainers: especifica contêineres que são executados antes do contêiner do aplicativo.
  • restartPolicy: especifica a política de reinicialização dos pods.
  • terminationGracePeriodSeconds: especifica o período de carência para a terminação do pod.
  • volumes: especifica os volumes usados pelos pods.

É possível modificar esses campos para atender aos seus requisitos específicos.

Criar um pool de inferência

O recurso personalizado InferencePool do Kubernetes define um grupo de pods com um modelo de linguagem grande (LLM) de base comum e uma configuração de computação. O campo selector especifica quais pods pertencem a esse pool. Os rótulos nesse seletor precisam corresponder exatamente aos rótulos aplicados aos pods do servidor de modelo. O campo targetPort define as portas que o servidor de modelo usa nos pods. O campo extensionRef faz referência a um serviço de extensão que oferece mais recursos para o pool de inferência. O InferencePool permite que o gateway de inferência do GKE roteie o tráfego para seus pods de servidor de modelo.

Antes de criar o InferencePool, verifique se os pods selecionados pelo InferencePool já estão em execução.

Para criar um InferencePool usando o Helm, siga estas etapas:

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

Mude o seguinte campo para corresponder à sua implantação:

  • inferencePool.modelServers.matchLabels.app: a chave do rótulo usado para selecionar os pods do servidor de modelo.

A instalação do Helm instala automaticamente a política de tempo limite, o seletor de endpoint e os pods necessários para a observabilidade.

Isso cria um objeto InferencePool: vllm-llama3-8b-instruct que faz referência aos serviços de endpoint do modelo nos pods. Ele também cria uma implantação do seletor de endpoint com o nome app:vllm-llama3-8b-instruct-epp para o InferencePool criado.

Especificar os objetivos de veiculação do modelo

O recurso personalizado InferenceModel define um modelo específico a ser veiculado que inclui suporte a modelos ajustados para LoRA e a criticidade de veiculação. É necessário definir quais modelos são veiculados em um InferencePool criando recursos InferenceModel. Esses recursos InferenceModel podem referenciar modelos básicos ou adaptadores LoRA aceitos pelos servidores de modelo no InferencePool.

O campo modelName especifica o nome do modelo de base ou do adaptador LoRA. O campo Criticality especifica a importância da veiculação do modelo. O campo poolRef especifica o InferencePool em que esse modelo é veiculado.

Para criar um InferenceModel, siga estas etapas:

  1. Salve o seguinte manifesto de amostra como 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
    

    Substitua:

    • MODEL_NAME: o nome do modelo base ou do adaptador LoRA. Por exemplo, food-review.
    • VALUE: a criticidade de veiculação escolhida. Escolha entre Critical, Standard ou Sheddable. Por exemplo, Standard.
    • INFERENCE_POOL_NAME: o nome do InferencePool que você criou na etapa anterior. Por exemplo, vllm-llama3-8b-instruct.
  2. Aplique o manifesto de exemplo ao cluster:

    kubectl apply -f inferencemodel.yaml
    

O exemplo a seguir cria um objeto InferenceModel que configura o modelo food-review LoRA no vllm-llama3-8b-instruct InferencePool com uma criticidade de envio Standard. O objeto InferenceModel também configura o modelo base a ser veiculado com um nível de prioridade 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

Criar o gateway

O recurso de gateway é o ponto de entrada do tráfego externo no cluster do Kubernetes. Ele define os listeners que aceitam conexões de entrada.

O gateway de inferência do GKE funciona com as seguintes classes de gateway:

  • gke-l7-rilb: para balanceadores de carga de aplicativo internos regionais.
  • gke-l7-regional-external-managed

Para mais informações, consulte a documentação Classes de gateway.

Para criar um gateway, siga estas etapas:

  1. Salve o seguinte manifesto de amostra como 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
    

    Substitua GATEWAY_NAME por um nome exclusivo para o recurso de gateway (por exemplo, inference-gateway) e GATEWAY_CLASS pela classe de gateway que você quer usar (por exemplo, gke-l7-regional-external-managed).

  2. Aplique o manifesto ao cluster:

    kubectl apply -f gateway.yaml
    

Observação: para mais informações sobre como configurar o TLS para proteger seu gateway com HTTPS, consulte a documentação do GKE sobre a configuração do TLS.

Criar o HTTPRoute

O recurso HTTPRoute define como o gateway do GKE encaminha solicitações HTTP para serviços de back-end, que, neste contexto, seriam o InferencePool. O recurso HTTPRoute especifica regras de correspondência (por exemplo, cabeçalhos ou caminhos) e o back-end para o qual o tráfego precisa ser encaminhado.

  1. Para criar um HTTPRoute, salve o seguinte exemplo de manifesto como 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
          kind: InferencePool
    

    Substitua:

    • HTTPROUTE_NAME: um nome exclusivo para o recurso HTTPRoute. Por exemplo, my-route.
    • GATEWAY_NAME: o nome do recurso Gateway que você criou. Por exemplo, inference-gateway.
    • PATH_PREFIX: o prefixo de caminho usado para corresponder às solicitações recebidas. Por exemplo, / para corresponder a todos.
    • INFERENCE_POOL_NAME: o nome do recurso InferencePool para onde você quer encaminhar o tráfego. Por exemplo, vllm-llama3-8b-instruct.
  2. Aplique o manifesto ao cluster:

    kubectl apply -f httproute.yaml
    

Enviar solicitação de inferência

Depois de configurar o gateway de inferência do GKE, é possível enviar solicitações de inferência para o modelo implantado. Isso permite gerar texto com base no comando de entrada e nos parâmetros especificados.

Para enviar solicitações de inferência, siga estas etapas:

  1. Para acessar o endpoint do gateway, execute o seguinte comando:

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

    Substitua:

    • GATEWAY_NAME: o nome do recurso de gateway.
    • PORT_NUMBER: o número da porta que você configurou no gateway.
  2. Para enviar uma solicitação ao endpoint /v1/completions usando curl, execute o seguinte comando:

    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"
    }'
    

    Substitua:

    • MODEL_NAME: o nome do modelo ou adaptador LoRA a ser usado.
    • PROMPT_TEXT: o comando de entrada para o modelo.
    • MAX_TOKENS: o número máximo de tokens a serem gerados na resposta.
    • TEMPERATURE: controla a aleatoriedade da saída. Use o valor 0 para saída determinista ou um número maior para uma saída mais criativa.

O exemplo a seguir mostra como enviar uma solicitação de exemplo para o gateway de inferência do 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"
}'

Esteja ciente dos seguintes comportamentos:

  • Corpo da solicitação: o corpo da solicitação pode incluir outros parâmetros, como stop e top_p. Consulte a especificação da API OpenAI para conferir uma lista completa de opções.
  • Tratamento de erros: implemente o tratamento de erros adequado no código do cliente para processar possíveis erros na resposta. Por exemplo, verifique o código de status HTTP na resposta curl. Um código de status que não é 200 geralmente indica um erro.
  • Autenticação e autorização: para implantações de produção, proteja seu endpoint de API com mecanismos de autenticação e autorização. Inclua os cabeçalhos apropriados (por exemplo, Authorization) nas suas solicitações.

A seguir