Guia do usuário de LLM de peso aberto no GDC com isolamento físico

Este guia de implantação fornece instruções detalhadas sobre como executar modelos de linguagem grandes (LLMs) de última geração usando software de código aberto (OSS) em ambientes isolados do Google Distributed Cloud (GDC). Em especial, este guia apresenta todas as etapas necessárias para executar as versões mais recentes dos modelos Gemma, DeepSeek e Llama, além de apresentar procedimentos comuns para disponibilizar outros LLMs disponíveis publicamente. Vamos usar back-ends de serviço em contêineres, como vLLM e Ollama, que abrangem uma ampla variedade de funcionalidades, diferentes níveis de configuração e facilidade de implantação.

Resumo do conteúdo

Este guia detalha a implantação e a operação de modelos de linguagem grandes (LLMs) de código aberto em ambientes isolados do Google Distributed Cloud (GDC).

Objetivos e infraestrutura principais

  • Objetivo: instruções detalhadas para executar LLMs de última geração, incluindo Gemma 3 (multimodal), DeepSeek-R1 e Llama (3.1/3.2) usando back-ends otimizados como vLLM e Ollama.
  • Versão mínima: versão do software GDC com isolamento físico 1.15.x*.
  • Requisitos de hardware: é necessário no mínimo uma GPU NVIDIA A100. O armazenamento de alta performance (PVC de 500 GiB ou mais) é recomendado para otimizar os tempos de carregamento de peso do modelo de 30 minutos para menos de 5 minutos.

Componentes de implantação

Componente Descrição
Back-ends de LLM vLLM (disponibilidade de alta capacidade de processamento com PagedAttention) e Ollama (gerenciamento local simplificado e suporte multimodal)
Modelos LLMs disponíveis publicamente, incluindo as famílias Gemma, DeepSeek e Llama
Aceleradores Suporta GPUs NVIDIA A100 completas ou slices de GPU de várias instâncias (MIG), dependendo da ocupação de VRAM do modelo.
Serviços do GDC Usa o GDC Container Service, Load Balancer (ELB/ILB), Harbor Container Registry

Principais procedimentos operacionais

  • Gerenciamento de modelos: o back-end de LLM gerencia o carregamento e o descarregamento de modelos com base no uso. O vLLM fixa modelos na memória para baixa latência consistente, enquanto o Ollama permite o carregamento dinâmico de modelos, mas descarrega automaticamente os modelos após 30 minutos de inatividade.
  • Personalização: os usuários podem trazer os LLMs preferidos extraindo-os da Internet, criando novas imagens do Docker e fazendo upload para o registro local do Harbor.

Pré-requisitos

Liberar

  • GDC com isolamento físico versão 1.15.1 ou mais recente.

Componentes

  • Cluster de usuário criado com recursos suficientes (CPU, memória, GPU).
  • É necessário ter no mínimo uma GPU NVIDIA A100.
  • Uma instância do Harbor disponível e acessível.
  • CLIs kubectl e gdcloud configuradas para acessar o cluster de usuário.
  • O cliente Docker está instalado e configurado para enviar ao Harbor.
  • Permissões necessárias do IAM concedidas (por exemplo, Administrador de namespace, Desenvolvedor de cluster).
  • Conta e autenticação do Hugging Face configuradas se você estiver usando modelos restritos.

Capacidade necessária

Recurso Capacidade
CPU 8 vCPUs
Memória RAM 32 GiB
Armazenamento temporário 16 Gi
GPUs 1 GPU NVIDIA A100
Volume permanente *500 GiB ou mais

Esses recursos de hardware são necessários para que os back-ends de serviço executem LLMs com aceleração de GPU. Por exemplo, um a2-ultragpu-1g-gdc forneceria recursos suficientes.

Diagrama de alto nível

Diagrama de alto nível da disponibilização de LLMs de peso aberto.

Este diagrama mostra um usuário que está consumindo APIs expostas por dois back-ends de LLM, vLLM e Ollama, para receber respostas de inferência de modelos de código aberto, como Gemma, Llama e DeepSeek. Dependendo do tamanho do modelo, medido em bilhões de parâmetros, cada LLM pode precisar de uma GPU completa ou de uma parte dela para ser executado.

Diagrama de limite de serviço e segurança para uma implantação de LLM

Esta solução depende dos seguintes serviços já incluídos na pilha de software do GDC com isolamento físico:

  • Serviço de contêiner do GDC: para executar todos os processos e escalonar usando o HPA.
  • Balanceador de carga do GDC: usando um serviço do Kubernetes para atender a todos os back-ends nesta solução e tornar os LLMs acessíveis na rede do cliente. Isso é chamado de ELB, que significa balanceador de carga externo. Por outro lado, o cliente pode optar por manter os LLMs acessíveis apenas de dentro de um cluster de usuário, o que pode ser útil quando há apenas um agente interno solicitando inferências dentro da solução. Isso é chamado de ILB, que significa balanceador de carga interno.
  • CI/CD do GDC: Harbor Container Registry para armazenar back-ends de LLM e pesos de modelo.
  • Stack de observabilidade do GDC: para coletar e pesquisar registros de back-end e fornecer painéis.

Em termos de segurança, o acesso à implantação do LLM depende de quais usuários podem acessar o serviço de balanceador de carga que expõe os back-ends de serviço do LLM, que estão sendo executados como pods em um projeto / namespace do Kubernetes.

Diagrama de arquitetura de limite de serviço e segurança.

Implantação

Pré-requisitos

Instale as seguintes ferramentas em uma estação de trabalho conectada ao seu ambiente GDC com isolamento físico:

  1. docker
  2. kubectl
  3. CLI gdcloud

Este documento contém todo o código-fonte e os arquivos de configuração necessários para implantar LLMs.

Criar um secret para extrair imagens do Harbor

Para configurar um secret de extração de imagem para uma carga de trabalho de contêiner no GDC com isolamento físico, crie um secret do Kubernetes docker-registry com credenciais para acessar seu projeto privado do Harbor. Esse secret é referenciado na especificação de implantação.

Use uma conta de robô do Harbor para acesso programático a imagens em projetos privados do Harbor.

Siga estas etapas para configurar o segredo de extração de imagens:

Criar uma conta de robô do Harbor:

  • Acesse a interface da instância do Harbor.
  • Acesse seu projeto do Harbor.
  • Selecione a guia Contas de robô.
  • Clique em + NOVA CONTA DE ROBÔ.
  • Dê um nome a ele (por exemplo, oss-llm-puller) e conceda as permissões necessárias (pelo menos acesso "pull") até um prazo de validade.
  • Armazene com segurança o nome da conta do robô (por exemplo, robot$oss-llm-puller) e o token secreto fornecido.

Autentique o Docker no Harbor:

Na máquina com o Docker instalado e acesso à rede do registro do Harbor, faça login usando as credenciais da conta de robô:

export INSTANCE_URL="your-harbor-instance-url"
# for example, harbor1-project1.org1.zone1.google.gdc.com

export ROBOT_NAME="your-robot-account-name"
# for example, robot\$oss-llm-puller (note how we escape the $ character)

export ROBOT_SECRET="your-robot-account-secret"

docker login ${INSTANCE_URL} --username ${ROBOT_NAME} --password ${ROBOT_SECRET}

# Sample output:

WARNING! Using --password via the CLI is insecure. Use --password-stdin.

WARNING! Your credentials are stored unencrypted in '$HOME/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/

Login Succeeded

Como mostrado na saída de exemplo, esse comando atualiza o arquivo de configuração do Docker local ($HOME/.docker/config.json) com os detalhes de autenticação. O arquivo config.json tem esta aparência:

{
    "auths": {
        "harbor1-project1.org1.zone1.google.gdc.com": {
            "auth": "...omitted..."
        }
    }
}

Se você usou o cliente do Docker para fazer login em outros registros no passado, mais entradas vão aparecer em "auths".

Crie o secret de extração de imagens do Kubernetes:

Use kubectl para criar um secret do tipo docker-registry no namespace do projeto usando o arquivo de configuração do Docker atualizado na etapa anterior:

# Log in to GDC air-gapped using the next commands

gdcloud auth login --login-config-cert {path to your web TLS certificate}

gdcloud clusters get-credentials {Your User Cluster}
kubectl config set-context --current --namespace=NAMESPACE

export SECRET_NAME="oss-llm-pull-secret" # You can choose another name
export NAMESPACE="your-project-namespace"
# Assuming default Docker config path. Adjust if necessary.
export DOCKER_CONFIG_PATH="$HOME/.docker/config.json"

kubectl create secret docker-registry ${SECRET_NAME} \
      --from-file=.dockerconfigjson=${DOCKER_CONFIG_PATH} \
      -n ${NAMESPACE}

Você vai referenciar esse secret mais tarde na especificação do contêiner de back-end do LLM incluindo o campo imagePullSecrets.

Ao seguir estas etapas, seu cluster do Kubernetes vai usar as credenciais fornecidas para extrair uma imagem de contêiner do seu registro particular do Harbor no ambiente isolado do GDC. Essas etapas também estão incluídas na documentação do produto.

Configurar a implantação do LLM

Você tem as seguintes duas opções para o back-end de LLM:

  • vLLM
  • Ollama

Você pode escolher um deles ou implantar os dois back-ends. Cada back-end pode executar um ou mais LLMs. Por exemplo:

  • O Gemma 3
  • DeepSeek
  • Llama
  • Outros LLMs

Na seção 1, fornecemos instruções sobre como implantar o vLLM e, na seção 2, mostramos como instalar o Ollama.

1. Implantar o vLLM como seu back-end de LLM

Obter a imagem Docker do vLLM

Em geral, o vLLM é usado para veicular modelos baixados do HuggingFace, como vamos mostrar nesta implantação de LLM. Alguns modelos são restritos. Isso significa que os usuários precisam solicitar ou concordar explicitamente em acessar os arquivos e conteúdos no Hugging Face Hub antes de fazer o download ou usar esses itens.

Faça login na sua instância do Harbor usando o Docker, conforme explicado na documentação. Em uma máquina com acesso à internet, extraia a imagem Docker vLLM e transfira para seu projeto do Harbor:

# Pull and Tag vLLM (v0.13.0 recommended for stability)
docker pull vllm/vllm-openai:v0.13.0
docker tag vllm/vllm-openai:v0.13.0 HARBOR_URL/PROJECT/vllm-openai:v0.13.0
docker push HARBOR_URL/PROJECT/vllm-openai:v0.13.0

Substitua:

  • HARBOR_URL: o URL da instância do Harbor.
  • PROJECT: o nome do projeto do Harbor.

A versão do vLLM usada neste guia de implantação é: v0.13.0

Armazenar os pesos do modelo de LLM em um PVC

Abra um novo terminal e crie uma pasta para salvar os arquivos de implantação do vLLM:

mkdir vllm-deployment
cd vllm-deployment

Em seguida, crie um arquivo YAML (por exemplo, model-pvc.yaml) para declarar uma solicitação de volume permanente (PVC) usando primitivos padrão do Kubernetes:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: model-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 500Gi
  storageClassName: standard-rwo
  volumeMode: Filesystem

Conecte-se ao cluster GDC com isolamento físico e aplique o PVC:

# Log in to GDC air-gapped using the next commands

gdcloud auth login --login-config-cert {path to your web TLS cert}

gdcloud clusters get-credentials {Your User Cluster}
kubectl config set-context --current --namespace=NAMESPACE

# Apply the PVC manifest
kubectl apply -f model-pvc.yaml

Faça o download dos pesos do modelo do Hugging Face:

# Log in to Hugging Face
hf auth login

# Download weights for Gemma 3 (for example, 4B instruction-tuned)
hf download google/gemma-3-4b-it

Exemplo de resposta:

Fetching 9 files: 100%| 9/9 [00:00<00:00, 19.34it/s]
Downloading (…)7f58a/.gitattributes: 100%| 1.62k/1.62k [00:00<00:00, 7.82MB/s]
Downloading (…)del-00002-of-00002.safetensors: 100%| 3.75G/3.75G [00:46<00:00, 81.3MB/s]
Downloading (…)del-00001-of-00002.safetensors: 100%| 4.90G/4.90G [00:54<00:00, 90.1MB/s]
Downloading (…)-3-4b-it/README.md: 100%| 23.3k/23.3k [00:00<00:00, 48.0MB/s]
Downloading (…)8a/model.safetensors.index.json: 100%| 26.3k/26.3k [00:00<00:00, 39.5MB/s]
Downloading (…)f58a/config.json: 100%| 908/908 [00:00<00:00, 4.41MB/s]
Downloading (…)generation_config.json: 100%| 210/210 [00:00<00:00, 936kB/s]
Downloading (…)tokenizer.json: 100%| 33.1M/33.1M [00:01<00:00, 17.6MB/s]
/Users/rashjab/.cache/huggingface/hub/models--google--gemma-3-4b-it/snapshots/952ec8ffca3adadfd00c6d71b40280ebdbb7f58a

Como você pode ver no exemplo de saída, o tamanho do modelo no disco é de 8,64 GB, o que se encaixa no PVC de 500 GiB que definimos antes. Sempre verifique se esse é o caso de qualquer modelo que você escolher carregar no volume permanente (PV). Por exemplo, um modelo de 15 GB usando um PVC de 500 GiB para atingir 1.500 IOPS reduz significativamente o tempo de carregamento de peso de aproximadamente 30 minutos para menos de 5 minutos.

Preencha o PV copiando os arquivos do modelo para o volume dele. Isso geralmente envolve:

  • Criar um pod "helper" temporário que monte o PV.
  • Use kubectl cp para copiar os arquivos do modelo da estação de trabalho para o volume montado do pod auxiliar.
  • Exemplo de pod auxiliar:

helper-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: model-uploader
spec:
  containers:
  - name: uploader
    image: HARBOR_URL/PROJECT/busybox:latest
    command: ["sleep", "3600"]
    volumeMounts:
    - name: model-data
      mountPath: /data
  imagePullSecrets:
  - name: oss-llm-pull-secret
  volumes:
  - name: model-data
    persistentVolumeClaim:
      claimName: model-pvc

Substitua:

  • HARBOR_URL: o URL da instância do Harbor.
  • PROJECT: o nome do projeto do Harbor.
  • oss-llm-pull-secret: se você escolheu um nome diferente para o secret de extração da imagem.
  • model-pvc: com o nome que você deu à PVC.

Envie a imagem Docker auxiliar (busybox):

docker pull busybox:latest
docker tag busybox HARBOR_URL/PROJECT/busybox:latest
docker push HARBOR_URL/PROJECT/busybox:latest

Substitua:

  • HARBOR_URL: o URL da instância do Harbor.
  • PROJECT: o nome do projeto do Harbor.

Aplique o arquivo helper-pod.yaml e copie os pesos do modelo para o PV:

kubectl apply -f helper-pod.yaml

# Wait for the pod to be Running
kubectl cp ~/.cache/huggingface/hub/ NAMESPACE/model-uploader:/data/

# After copying, delete the helper pod
kubectl delete pod model-uploader

Implantar o back-end do vLLM

Crie o arquivo de implantação para o vLLM executar o servidor de modelos. O exemplo a seguir implanta o modelo gemma-3-4b-it.

vllm-gemma-3-4b-it-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gemma-3-4b-it
  labels:
    app: gemma-3-4b-it
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gemma-3-4b-it
  template:
    metadata:
      labels:
        app: gemma-3-4b-it
    spec:
      volumes:
      - name: cache-volume
        persistentVolumeClaim:
          claimName: model-pvc # change with the name you gave initially to your PVC
      # vLLM needs to access the host's shared memory for tensor parallel inference.
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: "16Gi"
      containers:
      - name: gemma-3-4b-it
        image: HARBOR_URL/PROJECT/vllm-openai:v0.13.0
        command: ["python3"]
        args: [
          "-m",
          "vllm.entrypoints.openai.api_server",
          "--model",
          "google/gemma-3-4b-it", # Use the repo ID
          "--max-model-len",
          "32768",
          "--enforce-eager"
        ]
        env:
        - name: HF_HUB_OFFLINE
          value: "1"
        - name: HF_HOME
          value: "/model" # Tells vLLM to look for models in /model/hub
        # --- PERFORMANCE & STABILITY OPTIMIZATIONS ---
        - name: NCCL_P2P_DISABLE
          value: "1" # Prevents initialization hangs on P2P checks
        - name: NCCL_IB_DISABLE
          value: "1" # Prevents initialization hangs on InfiniBand checks
        # --- FIPS BYPASS ---
        - name: BORINGSSL_FIPS
          value: "0"
        - name: OPENSSL_FIPS
          value: "0"
        - name: OPENSSL_CONF
          value: "/dev/null"
        - name: FIPS_SIG
          value: "off"
        ports:
        - containerPort: 8000
        securityContext:
          privileged: true
          runAsUser: 0
        resources:
          limits:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
            cpu: "8"       # Increased to handle model weight verification
            memory: "64Gi"  # Increased to ensure headroom for weight loading
          requests:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
            cpu: "8"
            memory: "32Gi"
        volumeMounts:
        - name: cache-volume
          mountPath: /model
        - name: shm
          mountPath: /dev/shm
      imagePullSecrets:
      - name: oss-llm-pull-secret

Substitua:

  • HARBOR_URL: o URL da instância do Harbor.
  • PROJECT: o nome do projeto do Harbor.
  • oss-llm-pull-secret: o nome que você deu durante a criação do secret de extração da imagem.
  • claimName: o nome que você deu à criação inicial da PVC.

Em seguida, crie um arquivo de serviço do Kubernetes para expor as APIs de back-end do vLLM:

vllm-gemma-3-4b-it-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: gemma-3-4b-it
  namespace: NAMESPACE
spec:
  ports:
  - name: http-gemma-3-4b-it
    port: 80
    protocol: TCP
    targetPort: 8000
  selector:
    app: gemma-3-4b-it
  sessionAffinity: None
  type: LoadBalancer

Aplique as configurações de implantação e serviço:

kubectl apply -f vllm-gemma-3-4b-it-deployment.yaml
kubectl apply -f vllm-gemma-3-4b-it-service.yaml

Verificar e testar a implantação do vLLM

  1. Verifique o status do pod:

    kubectl get pods
    

    Aguarde até que o pod esteja no estado Running.

  2. Verifique o serviço:

    kubectl get service
    

    Exemplo de resposta:

    # NAME          TYPE         CLUSTER-IP     EXTERNAL-IP      PORT(S)        AGE
    # gemma-3-4b-it LoadBalancer 10.201.136.62  136.125.37.198   80:30109/TCP   3d1h
    

    Anote o EXTERNAL-IP do serviço vLLM (por exemplo, 136.125.37.198) da saída anterior. Você também pode imprimir com:

    kubectl get service gemma-3-4b-it \
    -o jsonpath='{.status.loadBalancer.ingress[*].ip}'
    
  3. Conferir registros:

    kubectl logs YOUR_VLLM_POD
    

    Procure mensagens indicando que o servidor foi iniciado e o modelo foi carregado (por exemplo, INFO: Application startup complete.). Como não há um download do Hugging Face, o processo será rápido se os arquivos estiverem no PVC com uma alta capacidade de volume permanente.

  4. Teste a inferência com curl:

    Depois de verificar se o pod vLLM está em execução e ter o endereço IP externo do serviço, é possível enviar uma solicitação de inferência usando curl. Como o vLLM fornece uma API compatível com a OpenAI, você pode usar o endpoint /v1/chat/completions:

    curl http://EXTERNAL_IP/v1/chat/completions \
      -H "Content-Type: application/json" \
      -d '{
        "model": "google/gemma-3-4b-it",
        "messages": [
          {"role": "user", "content": "What is Google Distributed Cloud air-gapped?"}
        ],
        "max_tokens": 100
      }'
    

    Substitua EXTERNAL_IP pelo endereço IP externo do serviço vLLM.

2. Implantar o Ollama como back-end de LLM

O Ollama é um framework conhecido para executar LLMs de código aberto localmente e em ambientes conteinerizados. Ele simplifica a execução do modelo ao processar downloads de peso, quantização e aceleração de GPU. Ela inclui uma API REST integrada para gerar conclusões, respostas de chat e embeddings.

Ao contrário de outros mecanismos de veiculação, o Ollama gerencia a execução do modelo de forma dinâmica:

  • Carregamento dinâmico de modelos: quando uma solicitação de um modelo específico é recebida, o Ollama carrega os pesos na memória (VRAM da GPU ou RAM do sistema) sob demanda.
  • Descarregamento por inatividade: se nenhuma solicitação de inferência for recebida para um modelo por 30 minutos (configurável com OLLAMA_KEEP_ALIVE), o Ollama vai descarregar o modelo da memória para liberar recursos de hardware para outras cargas de trabalho.
  • Um único modelo ativo por instância: o Ollama processa solicitações de um modelo ativo por vez em cada instância de servidor. Se vários modelos forem chamados em paralelo, o Ollama vai enfileirar as solicitações e trocar os modelos sequencialmente, o que pode introduzir latência. Para disponibilizar vários modelos simultaneamente sem troca, implante instâncias separadas do Ollama para cada modelo.

Fazer o download dos pesos do modelo e criar uma imagem Docker

Ao contrário do vLLM, que pode carregar pesos diretamente de um volume persistente, o Ollama normalmente espera que os modelos sejam armazenados no formato de diretório interno (~/.ollama/models).

Em um ambiente isolado, em que os contêineres de execução não podem baixar modelos da Internet pública, é necessário pré-empacotar os pesos do modelo na própria imagem do contêiner durante a fase de build. Essa abordagem garante que o contêiner seja totalmente independente e esteja pronto para veiculação imediatamente após a implantação, sem exigir acesso à rede externa.

Crie uma pasta para a implantação do Ollama:

mkdir ollama-gemma3
cd ollama-gemma3

Crie um Dockerfile com o seguinte conteúdo:

# Use a standard Linux base image
FROM ubuntu

# Install necessary dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    ca-certificates \
    zstd \
    && rm -rf /var/lib/apt/lists/*

# Install Ollama
# This uses Ollama's official installation script, which adds Ollama to /usr/local/bin
RUN curl -fsSL https://ollama.com/install.sh -o install.sh && \
    chmod +x install.sh && \
    ./install.sh && \
    rm install.sh

# Set environment variables for Ollama (optional, but a good practice)
# ENV OLLAMA_HOST="0.0.0.0"

# If you want to customize the model storage path within the container, set OLLAMA_MODELS, for example:
# ENV OLLAMA_MODELS="/usr/local/ollama/models"
# The default OLLAMA_MODELS is /root/.ollama
# Then, ensure you create and populate that directory.

# --- Download Gemma 3 model weights ---
# This step starts Ollama server in the background, pulls the model,
# and then kills the server to allow the Docker build to continue.
# This approach works around the Docker RUN command limitations for services.

RUN ollama serve & \
    # Give the Ollama server a moment to start up
    # Use --retry and --retry-connrefused to handle startup delays
    curl --retry 10 --retry-connrefused -s http://localhost:11434 || true && \
    # Pull the Gemma 3 model weights
    ollama pull gemma3:latest && \
    # Stop the background Ollama server process cleanly
    pkill ollama || true

# Expose Ollama's default port
EXPOSE 11434

# Command to run Ollama server when the container starts
CMD ["ollama", "serve"]

Se quiser testar um LLM de código aberto diferente, como um modelo das famílias Llama 3.2 ou DeepSeek-R1, modifique este comando do Ollama no Dockerfile anterior:

ollama pull gemma3:latest

Por exemplo, se você quiser extrair o Llama 3.2 com 3 bilhões de parâmetros, use este comando:

ollama pull llama3.2:3b

Ou, se preferir usar o DeepSeek-R1 com 8 bilhões de parâmetros, use este comando:

ollama pull deepseek-r1:8b

Também é possível fazer o download de mais de um LLM e ter os pesos do modelo em contêineres. Assim, o Ollama poderá alternar entre modelos conforme você solicitar inferências de diferentes modelos pré-carregados. Por exemplo, você pode adicionar os modelos Gemma e Llama à sua imagem Docker. Em um ambiente isolado, um back-end do Ollama não tem acesso à biblioteca do Ollama para baixar modelos a qualquer momento.

Não se esqueça de verificar e aceitar cada licença de modelo e termos de uso antes de executá-los nos seus aplicativos. Há muitos LLMs na biblioteca do Ollama. Você só vai precisar de uma conexão de Internet para baixar as ponderações do modelo ao criar a imagem Docker de back-end do LLM.

Crie a imagem Docker e envie para o Harbor

Faça login na sua instância do Harbor usando o Docker, conforme explicado na documentação. Crie a imagem do Docker Gemma 3 e faça upload dela para o repositório do Harbor:

docker build -t ollama-gemma3 .
docker tag ollama-gemma3 HARBOR_URL/PROJECT/ollama-gemma3:latest
docker push HARBOR_URL/PROJECT/ollama-gemma3:latest

Substitua:

  • HARBOR_URL: o URL da instância do Harbor.
  • PROJECT: o nome do projeto do Harbor.

Versão do Ollama usada neste guia de implantação: 0.14.1

Preparar uma implantação e um serviço do Kubernetes

Crie um arquivo chamado ollama-gemma3.yaml para definir a implantação do back-end do Ollama e a configuração do balanceador de carga para expor como um serviço:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ollama-gemma3
  namespace: osd-dev
  labels:
    app: ollama-gemma3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ollama-gemma3
  template:
    metadata:
      labels:
        app: ollama-gemma3
    spec:
      containers:
      - name: ollama-gemma3
        image: rashjab-mhs-rashjab-test2.gdc1.us-west6-a.staging.gpcdemolabs.com/rashjab-repo/ollama-gemma3:latest
        env:
        # This is the crucial fix: Tell Ollama to listen on all network interfaces
        - name: OLLAMA_HOST
          value: "0.0.0.0"
        imagePullPolicy: Always
        ports:
        - containerPort: 11434
        securityContext:
          privileged: true
          runAsUser: 0
        resources:
          limits:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
          requests:
            nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1
      imagePullSecrets:
      - name: oss-llm-pull-secret
---
apiVersion: v1
kind: Service
metadata:
  name: ollama-gemma3
  namespace: osd-dev
spec:
  type: LoadBalancer
  selector:
    app: ollama-gemma3
  ports:
  - name: ollama-gemma3-port
    port: 11434
    protocol: TCP
    targetPort: 11434

Substitua:

  • HARBOR_URL: o URL da instância do Harbor.
  • PROJECT: o nome do projeto do Harbor.
  • oss-llm-pull-secret: se você escolheu um nome diferente para o secret de extração da imagem.

Verificar a alocação da GPU

O GDC com isolamento físico é compatível com GPUs de várias instâncias (MIG) da NVIDIA, e os diferentes perfis de MIG podem ser revisados na documentação pública. Se você estiver implantando LLMs pequenos, é recomendável verificar os tamanhos deles (na memória) e particionar as GPUs de acordo. O esquema de particionamento de um pool de nós é definido no recurso personalizado Cluster. Para mais informações sobre como aplicar um esquema de particionamento de GPU, consulte Adicionar um pool de nós. Se você for um operador de aplicativos (AO), consulte o administrador da plataforma (PA) sobre os aceleradores instalados e disponíveis no seu projeto / cluster. Saiba mais sobre como configurar um contêiner para usar recursos de GPU e como verificar a alocação de recursos de GPU.

A precisão padrão do modelo Gemma 3 4B é de 16 bits. De acordo com esta tabela publicada pelo Google, o requisito de memória da GPU para esse LLM é de 6,4 GB, usando precisão BF16 (16 bits).

No ollama-gemma3.yaml anterior, anexamos uma fração de GPU de 10 GB (NVIDIA A100) ao contêiner, já que essa quantidade de memória VRAM é suficiente para carregar e executar o modelo Gemma 3 4B, conforme mostrado a seguir:

ollama-gemma3.yaml

... omitted ...

        resources:
          limits:
            nvidia.com/mig-1g.10gb-NVIDIA_A100_80GB_PCIE: 1
          requests:
            nvidia.com/mig-1g.10gb-NVIDIA_A100_80GB_PCIE: 1

... omitted ...

Implantar o back-end do Ollama e expor como um serviço

Conecte-se ao cluster e defina o contexto para o namespace do projeto:

# Log in to GDC air-gapped using the next commands

gdcloud auth login --login-config-cert {path to your web TLS certificate}

gdcloud clusters get-credentials {Your User Cluster}
kubectl config set-context --current --namespace=NAMESPACE

Aplique o manifesto do Ollama:

kubectl apply -f ollama-gemma3.yaml

Verifique se o pod do Ollama está em execução e se o serviço associado está no lugar:

kubectl get pods

Exemplo de resposta:

# NAME                             READY   STATUS    RESTARTS   AGE
# ollama-gemma3-6fc6fff74b-9qtpf   1/1     Running   0          1h
kubectl get service

Exemplo de resposta:

# NAME             TYPE          CLUSTER-IP    EXTERNAL-IP    PORT(S)          AGE
# ollama-gemma3   LoadBalancer  172.0.0.1     10.0.0.1       11434:31822/TCP  1d

Anote o EXTERNAL-IP do serviço do Ollama (por exemplo, 10.0.0.1) da saída anterior. Você também pode imprimir com:

kubectl get service ollama-gemma3 \
-o jsonpath='{.status.loadBalancer.ingress[*].ip}'

Antes de verificar se o Ollama Gemma 3 está funcionando, aplique uma política de rede, como :

apiVersion: networking.gdc.goog/v1
kind: ProjectNetworkPolicy
metadata:
  name: allow-ollama-ingress
  namespace: osd-dev
spec:
  subject:
    subjectType: UserWorkload
  policyType: Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 0.0.0.0/0 # Allows traffic from any IP. Restrict this for production.
    ports:
    - protocol: TCP
      port: 11434

Aplique a política de rede:

kubectl apply -f ollama-netpol.yaml

Verifique e teste a implantação do Ollama:

  1. Verifique se o Ollama está em execução:

    curl http://EXTERNAL_IP:11434
    

    Resposta esperada: "Ollama is running"

  2. Envie uma solicitação de conclusão:

    curl -X POST http://EXTERNAL_IP:11434/v1/completions \
      -H "Content-Type: application/json" \
      -d '{
        "model": "gemma3:latest",
        "prompt": "Google Distributed Cloud air-gapped is a",
        "max_tokens": 128,
        "temperature": 0.90
      }'
    

Solicitar inferências

Agora que os back-ends de LLM (vLLM e Ollama) estão implantados e acessíveis pelos respectivos serviços LoadBalancer, você pode começar a usá-los para inferência.

Dependendo do seu caso de uso, você tem várias opções:

  • Interface da Web interativa: para testes, prototipagem ou oferecer uma experiência semelhante ao ChatGPT para os usuários, implante a Open WebUI ou um front-end semelhante.
  • Interface de linha de comando (CLI): para verificação rápida, criação de scripts ou automação, use curl ou scripts personalizados.
  • Application Integration: conecte seus aplicativos internos, agentes de IA ou plug-ins de IDE (por exemplo, Continue para VS Code/JetBrains) diretamente aos endpoints compatíveis com a OpenAI fornecidos pelo vLLM (/v1) ou Ollama (/v1).

1. Interagir com o LLM usando uma UI

Para fornecer uma interface semelhante ao ChatGPT para interagir com seus modelos, implante a Open WebUI no seu cluster.

Criar a implantação da Open WebUI

Crie open-webui-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: open-webui
  namespace: osd-dev
  labels:
    app: open-webui
spec:
  replicas: 1
  selector:
    matchLabels:
      app: open-webui
  template:
    metadata:
      labels:
        app: open-webui
    spec:
      containers:
      - name: open-webui
        image: HARBOR_URL/PROJECT/open-webui:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        env:
        - name: OPENAI_API_BASE_URL
          value: "http://gemma-3-4b-it/v1" # Point to your vLLM service
        - name: OPENAI_API_KEY
          value: "EMPTY"
        - name: WEBUI_AUTH
          value: "False"
      imagePullSecrets:
      - name: oss-llm-pull-secret
---
apiVersion: v1
kind: Service
metadata:
  name: open-webui
  namespace: osd-dev
spec:
  type: LoadBalancer
  selector:
    app: open-webui
  ports:
  - port: 80
    targetPort: 8080

Aplicar a política de rede

Permita que sua máquina acesse o serviço Open WebUI na porta 80.

Atualize sua política de rede do projeto PNP para incluir o serviço open-webui ou aplique uma política ampla:

apiVersion: networking.gdc.goog/v1
kind: ProjectNetworkPolicy
metadata:
  name: allow-webui-ingress
  namespace: NAMESPACE
spec:
  subject:
    subjectType: UserWorkload
  policyType: Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 0.0.0.0/0 # Allows traffic from any IP then restrict this for production
    ports:
    - protocol: TCP
      port: 8080

Verificação

  1. Acesse o IP da interface da Web:

    kubectl get service open-webui -n NAMESPACE
    
  2. Acesse a UI: abra o navegador e acesse http://WEB_UI_EXTERNAL_IP

  3. Configurar: no primeiro login, crie uma conta de administrador. Nas configurações, verifique se a conexão da OpenAI aponta para http://gemma-3-4b-it/v1.

  4. Selecione o modelo: na interface de chat, selecione google/gemma-3-4b-it no menu suspenso de modelos.

    Abra o menu suspenso de seleção de modelos da WebUI.

2. Fazer solicitações HTTP usando uma CLI

  • curl:
curl -X POST http://OLLAMA_LOAD_BALANCER_IP:11434/v1/completions \
-H "Content-Type: application/json" \
-d '{
  "model": "gemma3:latest",
  "prompt": "Google Distributed Cloud air-gapped is a",
  "max_tokens": 128,
  "temperature": 0.90
}'

Validação e verificação

Verifique se todos os contêineres e serviços estão em execução:

# Log in to GDC air-gapped using the next commands

gdcloud auth login --login-config-cert {path to your web TLS cert}
gdcloud clusters get-credentials {Your User Cluster}
kubectl config set-context --current --namespace=NAMESPACE

# Pods

kubectl get pods # This command should return results like below

# NAME                                   READY   STATUS    RESTARTS   AGE
# vllm-6fc6fff74b-9qtpf                 1/1     Running   0          1h
# ollama-798fbf6ff6-9m7ln               1/1     Running   0          1h


# Services

kubectl get services # This command should return results like below

# NAME                      TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)           AGE
# vllm-service              LoadBalancer   172.0.0.1        10.0.0.1       11434:31822/TCP   1h
# ollama-service        LoadBalancer   172.0.0.2        10.0.0.2       11434:30728/TCP   1h

Etapas de remoção

  1. Remova todos os recursos do Kubernetes:

    kubectl delete -f vllm-gemma-3-4b-it-deployment.yaml
    kubectl delete -f vllm-gemma-3-4b-it-service.yaml
    
  2. Exclua manualmente os contêineres não usados do seu repositório do Harbor.

Operações

Back-end do vLLM

Princípios básicos do vLLM

O vLLM foi projetado como um mecanismo de disponibilização de modelo único de alto desempenho. Não é possível veicular vários modelos em um único processo de servidor ou definir vários modelos em um único comando de inicialização. Para disponibilizar mais de um modelo (por exemplo, um modelo de chat e um modelo de incorporação separado), inicie instâncias separadas do vLLM, cada uma no próprio pod ou contêiner, opcionalmente atribuídas a GPUs ou frações de GPU diferentes. Ao contrário de outros backends que podem trocar modelos dinamicamente, uma instância do vLLM fixa o modelo e a memória de cache KV associada na inicialização para garantir alta taxa de transferência e baixa latência consistentes.

É possível abrir um terminal em qualquer um dos pods do vLLM usando os seguintes comandos:

kubectl exec -it gemma-3-4b-random-string -n NAMESPACE -- /bin/bash

Isso vai mostrar quais modelos estão carregados, os argumentos deles e os PIDs :

ps aux | grep vllm

Saída semelhante esperada:

root           1  0.1  0.8 9436960 1550504 ?     Ssl  Feb04   9:18 python3 -m vllm.entrypoints.openai.api_server --model google/gemma-3-4b-it --max-model-len 32768 --enforce-eager
root         504  0.0  0.0   3476  1596 pts/0    S+   02:48   0:00 grep --color=auto vllm

Se você quiser uma visualização mais limpa e parecida com o Ollama, sem a confusão do próprio comando grep e dos PIDs do sistema, use este comando de uma linha:

ps aux | grep [v]llm.entrypoints | awk -F'--model ' '{print $2}' | awk '{print $1}'

Exemplo de resposta :

google/gemma-3-4b-it

Monitore o status da implantação do vLLM usando comandos kubectl padrão e consultando os endpoints da API interna.

Verificar registros do pod

Abra um terminal para conferir os registros de inicialização e veiculação:

kubectl logs -f gemma-3-4b-it-random_string -n NAMESPACE

Procure a confirmação de que o servidor está pronto:

(APIServer pid=1) INFO:     Started server process [1]
(APIServer pid=1) INFO:     Waiting for application startup.
(APIServer pid=1) INFO:     Application startup complete.

Consultar status interno

Como o vLLM fornece uma API compatível com a OpenAI, é possível verificar os modelos carregados e a integridade do sistema diretamente de um terminal dentro do cluster (por exemplo, usando um pod debug-sh).

Primeiro, inicie o pod de depuração. Estas são as instruções :

Iniciar o pod de depuração

Execute o comando a seguir para iniciar um shell efêmero no namespace do projeto. Essa configuração usa a imagem busybox (enviada anteriormente ao seu registro do Harbor) e injeta as credenciais necessárias com a flag --overrides:

kubectl run --rm -it debug-sh \
  --image=HARBOR_URL/PROJECT/busybox:latest \
  --restart=Never -n osd-dev --overrides='{
    "spec": {
      "imagePullSecrets": [{"name": "oss-llm-pull-secret"}]
    }
  }' -- sh

Principais parâmetros:

  • --rm: exclui automaticamente o pod ao sair, preservando os recursos do cluster.
  • --overrides: obrigatório em ambientes isolados para permitir que o pod se autentique com o registro privado do Harbor.

Status do servidor do modelo de consulta

Depois de entrar no pod, use o utilitário wget para consultar a API vLLM. Como o serviço vLLM mapeia a porta interna 8000 para a porta 80, é possível usar o nome DNS do serviço:

  • Listar modelos carregados: verifique se o mecanismo vLLM foi inicializado e carregou os pesos do Gemma 3.

    wget -qO- http://gemma-3-4b-it/v1/models
    

    Resposta de sucesso:

    {"object":"list","data":[{"id":"google/gemma-3-4b-it"}]}
    
  • Verifique a integridade do aplicativo: confirme se o servidor de API está pronto para processar solicitações.

    wget -qO- http://gemma-3-4b-it/health
    

    Resposta de sucesso:

    OK
    

Noções básicas do Ollama

O Ollama não permite carregar vários modelos na memória simultaneamente. Além disso, se você não usar o LLM por um determinado período (geralmente 30 minutos por padrão), o Ollama vai descarregar o modelo atual da memória.

Devido ao comportamento descrito anteriormente, a solução implementa dois ou mais back-ends do Ollama, dependendo das suas necessidades e caso de uso. Assim, muitos desenvolvedores ou usuários podem usá-los em paralelo sem ter apenas uma instância do Ollama carregando e descarregando modelos com frequência, o que produz uma latência desnecessária.

É possível abrir um terminal em qualquer um dos pods do Ollama usando os seguintes comandos:

kubectl exec -it ollama-chat-random_string -- sh
kubectl exec -it ollama-autocomplete-random_string -- sh

Dentro dos pods, use a CLI do Ollama para conferir os modelos disponíveis e ver qual deles está carregado:

  • No pod ollama-chat, você vai encontrar um modelo:

    # ollama list
    NAME                     ID              SIZE      MODIFIED
    codegemma:7b-instruct    0c96700aaada    5.0 GB    2 hours ago
    
    # ollama ps
    NAME                     ID              SIZE     PROCESSOR    UNTIL
    codegemma:7b-instruct    0c96700aaada    10 GB    100% GPU     4 minutes from now
    
  • No pod ollama-autocomplete, você vai encontrar dois modelos:

    # ollama list
    NAME                     ID              SIZE      MODIFIED
    codegemma:2b             926331004170    1.6 GB    2 hours ago
    codegemma:7b-code        aee9a63c13b9    5.0 GB    2 hours ago
    
    # ollama ps
    NAME                 ID              SIZE      PROCESSOR    UNTIL
    codegemma:7b-code    aee9a63c13b9    7.1 GB    100% GPU     4 minutes from now
    
  • Quando o Ollama descarrega o modelo atual, a saída fica vazia:

    # ollama ps
    NAME    ID    SIZE    PROCESSOR    UNTIL
    

O Ollama carrega dinamicamente um modelo quando você envia a próxima solicitação de assistência de código, sem intervenção manual.

Importância da capacidade da GPU

Se você provisionar uma fração de uma GPU com 10 GB, mas o consumo de memória do modelo for (ligeiramente) maior que isso, vai notar que parte do LLM é carregada na CPU, como mostrado abaixo:

# ollama ps
NAME                     ID              SIZE     PROCESSOR         UNTIL
codegemma:7b-instruct    0c96700aaada    10 GB    6%/94% CPU/GPU    29 minutes from now

Isso não é o ideal e produz uma latência de resposta maior. Portanto, forneça o tamanho de GPU sugerido neste guia.

LLMs

Usar um LLM diferente ou seu LLM preferido com o vLLM

Para executar diferentes tamanhos do Gemma ou de qualquer outro modelo de linguagem grande (LLM) de código aberto com vLLM no GDC com isolamento físico, como DeepSeek-R1 ou Llama 3.1, é necessário ingerir as novas ponderações de modelo no ambiente e atualizar o manifesto de implantação para apontar para os novos recursos.

Com base nos procedimentos operacionais estabelecidos para essa solução, siga estas etapas para carregar um modelo diferente :

  1. Baixar novos pesos de modelo:

    Em uma estação de trabalho com acesso à Internet, use a CLI do Hugging Face para fazer o download dos pesos do seu modelo preferido.

    • Para Gemma 3 (3-12b-it):
    hf download google/gemma-3-12b-it
    
    • Para DeepSeek-R1 (7B Distill):
    hf download deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
    
    • Para o Llama 3.1 (8B):
    hf download meta-llama/Meta-Llama-3.1-8B-Instruct
    

    Observação: aceite os termos de licença do modelo no Hugging Face antes de fazer o download.

  2. Preencha o volume permanente (PVC):

    Atualize seu model-pvc ou crie um novo com capacidade suficiente para o novo modelo. Use o método de pod auxiliar para transferir os pesos da sua estação de trabalho. Formatos maiores exigem muito mais espaço em disco. Verifique se a declaração de volume persistente (PVC, na sigla em inglês) tem capacidade suficiente para armazenar os novos pesos.

    • Gemma 3 4B: ~15,2 GB.
    • Gemma 3 27B: ~54 GB ou mais.
    • Recomendação: mantenha a recomendação de PVC de 500 GiB para garantir IOPS altos (1.500) e um carregamento mais rápido, independente do tamanho do modelo.
    # Copy the new model's hub directory to the helper pod
    kubectl cp ~/.cache/huggingface/hub/ osd-dev/model-uploader:/data/
    
  3. Atualize o manifesto de implantação do vLLM:

    Modifique o YAML de implantação do vLLM para fazer referência ao novo ID do modelo. Ao contrário do Ollama, que pode trocar modelos dinamicamente, uma instância do vLLM é dedicada a um único modelo e precisa ser atualizada ou reimplantada para mudar de modelo.

    Atualize a seção "args" da sua implantação dependendo do modelo que você está usando. Aqui, o deepseek é usado como exemplo:

    args: [
      "-m", "vllm.entrypoints.openai.api_server",
      "--model", "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", # Update to new Repo ID
      "--max-model-len", "32768",
      "--enforce-eager" # Recommended for GDC stability
    ]
    
  4. Ajuste os recursos de GPU e memória:

    Modelos maiores exigem mais VRAM para pesos e o cache KV. Se você mudar de um modelo de 4B para um de 8B ou 14B, verifique se os limites de recursos são suficientes para evitar falhas de "Sem memória".

    • Pegada de VRAM: com precisão de 16 bits, um modelo de 8B requer aproximadamente 16 GB apenas para pesos, além de memória adicional para o cache PagedAttention do vLLM.
    • Recomendação: use uma GPU A100 completa (nvidia.com/gpu-pod-NVIDIA_A100_80GB_PCIE: 1) para modelos com mais de 7 bilhões de parâmetros para garantir o desempenho ideal e espaço livre para o cache KV.
  5. Verifique o novo modelo:

    Depois que a implantação terminar de reconciliar, verifique se o novo modelo está ativo com a API interna:

    # Inside a debug-sh pod
    wget -qO- http://gemma-3-4b-it/v1/models
    

    Resposta de sucesso:

    {"object":"list","data":[{"id":"deepseek-ai/DeepSeek-R1-Distill-Qwen-7B"}]}
    

Usar um LLM diferente com o Ollama

Se quiser testar um LLM de código aberto diferente, como um modelo das famílias Llama 3.2 ou DeepSeek-R1, modifique este comando do Ollama no Dockerfile anterior:

ollama pull gemma3:latest

Por exemplo, se você quiser extrair o Llama 3.2 com 3 bilhões de parâmetros, use este comando:

ollama pull llama3.2:3b

Ou, se preferir usar o DeepSeek-R1 com 8 bilhões de parâmetros, use este comando:

ollama pull deepseek-r1:8b

Também é possível fazer o download de mais de um LLM e ter os pesos do modelo em contêineres. Assim, o Ollama poderá alternar entre modelos conforme você solicitar inferências de diferentes modelos pré-carregados. Por exemplo, você pode adicionar os modelos Gemma e Llama à sua imagem Docker. Em um ambiente isolado, um back-end do Ollama não tem acesso à biblioteca do Ollama para baixar modelos a qualquer momento.

Não se esqueça de verificar e aceitar cada licença de modelo e termos de uso antes de executá-los nos seus aplicativos. Há muitos LLMs na biblioteca do Ollama. Você só vai precisar de uma conexão de Internet para baixar as ponderações do modelo ao criar a imagem Docker de back-end do LLM.

Abrir a interface da Web

Verifique se o pod da WebUI aberta está em execução :

kubectl get pods -n NAMESPACE

Saída esperada :

NAME                             READY   STATUS    RESTARTS   AGE
open-webui-69df4664d-przjl       1/1     Running   0          6d3h

Verifique o IP do serviço :

kubectl get service -n NAMESPACE

Saída esperada:

NAME          TYPE            CLUSTER-IP       EXTERNAL-IP      PORT(S)           AGE
open-webui     LoadBalancer   10.201.137.164   136.125.37.224   80:30492/TCP      6d3h

As seções a seguir mostram como usar os principais recursos da UI.

Abra o diagrama da interface do usuário da WebUI.

Escalonar a solução com um back-end do Ollama

Verticalmente

  • Alocar uma fração maior de GPU para o LLM que se tornou um gargalo até usar uma GPU completa.
  • Se você quiser usar um LLM maior para melhorar a precisão da resposta, por exemplo, um LLM de 405 bilhões de parâmetros em vez de um de 7 bilhões, talvez seja necessário mais de uma GPU para executá-lo sem problemas.
  • Os modelos que se encaixam em mais de uma GPU têm alguma latência relacionada à comunicação entre GPUs.

Horizontalmente

  • Implante quantos pods do Ollama forem necessários para alcançar a capacidade de processamento desejada em um determinado LLM.
    • Para isso, aumente o número de réplicas no arquivo YAML de implantação do Ollama correspondente.
  • O serviço do Kubernetes, que é do tipo LoadBalancer, distribui solicitações de assistência de código entre endpoints (ou seja, pods) e retorna as respostas respectivas pelo IP externo exposto.
  • O plug-in Continuar aponta para apenas um endereço IP por funcionalidade.

Diagrama de arquitetura de escalonamento de LLM de peso aberto.

Para escalonar o back-end vLLM no ambiente isolado do GDC, siga uma estratégia semelhante à usada para o Ollama, com foco na alocação de recursos de hardware e na replicação de pods.

Escalonar a solução com um back-end vLLM

Verticalmente

  • Fazer upgrade da alocação de GPU:se a capacidade de processamento de inferência (tokens/segundo) se tornar um gargalo, aloque uma fração maior da GPU até usar uma GPU NVIDIA A100 completa.
  • Configurações de várias GPUs: para modelos enormes (por exemplo, de 70 bilhões a 405 bilhões de parâmetros) que não cabem na memória de uma única A100 de 80 GB, é necessário escalonar para várias GPUs usando o paralelismo de tensor.
  • Consideração sobre a latência: modelos que abrangem mais de uma GPU podem ter uma pequena sobrecarga relacionada à comunicação entre GPUs (por exemplo, sincronização do NCCL).

Horizontalmente

  • Aumentar a capacidade de processamento com réplicas: para lidar com um volume maior de solicitações simultâneas de usuários para o mesmo modelo, aumente a contagem de replicas no YAML de implantação do vLLM.
  • Instâncias de modelo dedicadas: como o vLLM foi projetado como um mecanismo de serviço de modelo único e fixa a memória do cache KV na inicialização, é necessário implantar um conjunto separado de pods para cada LLM diferente que você quer hospedar.
  • Balanceamento de carga: o serviço do Kubernetes do GDC (tipo LoadBalancer) distribui automaticamente as solicitações de inferência recebidas entre todos os endpoints de pod vLLM íntegros associados a esse serviço.

Solução de problemas

Erro Mitigação
FALHA NO AUTOTESTE DO FIPS Ocorre quando bibliotecas como o BoringSSL não têm assinaturas de integridade. Corrigir definindo BORINGSSL_FIPS=0 e usando imagens oficiais do vLLM
Carregamento de peso parado Verifique se há limitação de IOPS em PVCs pequenos. Um volume de 500 GiB é necessário para a inicialização do modelo de desempenho.
Conexão recusada Confirme se o PNP permite explicitamente o targetPort (8000/8080). Os firewalls do GDC não concedem acesso automático às portas de back-end para VIPs do balanceador de carga.