Skip to content

Plataforma GPU

Plataforma GPU β€” Arquitetura

Objetivo

Disponibilizar uma plataforma de IA unificada para uso interno (pesquisadores, aplicacoes, agentes), com:

  • API unica OpenAI-compatible para qualquer workload de IA
  • Flexibilidade: adicionar servico novo = 4 arquivos + git push
  • Multi-site (Franca + SP) sem over-engineering
  • Governanca: quotas, custo, observabilidade e seguranca desde o dia 1

Principio central

vLLM nao e a plataforma β€” e um dos backends.

A plataforma e: gateway + K3s + GPU ops + observabilidade + storage + auth. Servicos especificos (vLLM, Docling, Whisper, Tabby) se plugam na plataforma via um service contract padrao.

Cada ferramenta resolve exatamente um problema. Nenhuma ferramenta e a plataforma inteira.


Arquitetura em 4 camadas

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ LAYER 4 β€” API & Developer Experience β”‚
β”‚ β”‚
β”‚ Traefik ──→ TensorZero ──→ backends β”‚
β”‚ (TLS) (auth, routing, A/B testing, β”‚
β”‚ rate-limit, spend tracking) β”‚
β”‚ β”‚
β”‚ Backstage (catalogo) DSPy (pipelines declarativos de IA) β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ LAYER 3 β€” AI Services β”‚
β”‚ β”‚
β”‚ Interativo (always-on) β”‚ Batch (Kueue) β”‚ CPU-only β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ vLLM β”‚ β”‚SGLang β”‚ β”‚ β”‚ Unsloth β”‚ β”‚ β”‚Qdrant β”‚ β”‚
β”‚ β”‚(chat) β”‚ β”‚(chat alt)β”‚ β”‚ β”‚(fine- β”‚ β”‚ β”‚(vectorβ”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ tuning) β”‚ β”‚ β”‚ DB) β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚Doclingβ”‚ β”‚Embeddingsβ”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚(OCR) β”‚ β”‚ (BGE-M3) β”‚ β”‚ β”‚OCR lote β”‚ β”‚ β”‚Langfuseβ”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚(obs) β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚Whisperβ”‚ β”‚ FLUX β”‚ β”‚ β”‚Promptfooβ”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚(STT) β”‚ β”‚ (imagem) β”‚ β”‚ β”‚ (eval) β”‚ β”‚ β”‚MLflow β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚(model)β”‚ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚ Tabby β”‚ β”‚pyannote β”‚ β”‚ β”‚autore- β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚(code) β”‚ β”‚(diarizac)β”‚ β”‚ β”‚search β”‚ β”‚ β”‚OpenWUIβ”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚LLM β”‚ β”‚ dflash β”‚ β”‚ β”‚ β”‚Hermes β”‚ β”‚
β”‚ β”‚Guard β”‚ β”‚(spec dec)β”‚ β”‚ β”‚ β”‚Agent β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”‚
β”‚ Quantizacao: PolarQuant (pesos Q5) + TurboQuant (KV cache 3-bit) β”‚
β”‚ Cada servico segue o SERVICE CONTRACT (secao dedicada) β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ LAYER 2 β€” Platform (comum a TODOS os workloads) β”‚
β”‚ β”‚
β”‚ GPU Sharing: KAI Scheduler (fracionario, topology-aware) + DRA β”‚
β”‚ Scheduling: Kueue (batch) + KEDA (autoscaling) + PriorityClasses β”‚
β”‚ Observab.: OpenObserve + OTel + DCGM + Langfuse + OpenCost β”‚
β”‚ Storage: SeaweedFS + HF cache PVC + Qdrant + DVC + MLflow β”‚
β”‚ Seguranca: Authentik + Kyverno + Sealed Secrets + NetworkPolicies β”‚
β”‚ Ops: Argo CD (GitOps) + Velero (backup) β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ LAYER 1 β€” GPU Infrastructure β”‚
β”‚ β”‚
β”‚ Pulumi (LXC provisioning) β†’ Proxmox β†’ NVIDIA Driver β”‚
β”‚ β†’ LXC privileged (/dev/nvidia*) β†’ nvidia-ctk β†’ K3s Agent β”‚
β”‚ Node labels: gpu.site, gpu.model, gpu.vram β”‚
β”‚ β”‚
β”‚ Franca: 3x A5500 (24GB) β”‚ SP: 3x A5000 (24GB) β”‚
β”‚ Total: 144 GB VRAM β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

LAYER 1 β€” GPU Infrastructure

Objetivo: GPU acessivel como recurso nativo do K8s (nvidia.com/gpu).

ComponenteFuncaoPor que
PulumiProvisiona LXC/VMs no Proxmox via IaC (GPU passthrough, CPU/RAM, rede)Infraestrutura reproduzivel, sem clique manual
ProxmoxHypervisor que hospeda LXC/VMs com GPUJa existe na infra
NVIDIA DriverDriver no host Proxmox (script pve-nvidia-upgrade.sh)Base de tudo β€” sem driver, sem GPU
LXC privilegedContainer com bind mount /dev/nvidia*, overhead minimo vs VMPerformance quase nativa, kernel compartilhado
NVIDIA Container Toolkit (nvidia-ctk)Runtime nvidia para containerd dentro do LXCPermite pods K8s acessarem GPU
K3s AgentWorker node GPU que se junta ao cluster existenteExtende o cluster sem substituir
Node Labelsgpu.site=franca/saopaulo, gpu.model=a5000, gpu.vram=24giScheduling por afinidade (modelos grandes β†’ GPU maior)

Divisao Pulumi vs Ansible

FerramentaEscopo
PulumiCriar LXC, configurar GPU passthrough, alocar CPU/RAM, rede
AnsibleInstalar NVIDIA driver no host, nvidia-ctk no LXC, join do K3s agent

Hardware

    • Franca: 3x NVIDIA A5500 (24 GB VRAM cada) = 72 GB
  • Sao Paulo: 3x NVIDIA A5000 (24 GB VRAM cada) = 72 GB
  • Total atual: 144 GB VRAM
  • Expansao futura: A6000 (48 GB VRAM) conforme demanda

Por que LXC e nao VM?

LXC acessa a GPU via bind mount dos devices (/dev/nvidia*), usando o driver instalado no host Proxmox. Performance quase nativa com overhead minimo. O trade-off (menos isolamento) e aceitavel em ambiente academico controlado.

1 LXC por servidor, nao por GPU. Servidores com multiplas GPUs devem ter 1 unico LXC com acesso a todas as GPUs. O DRA (Dynamic Resource Allocation) expoe as GPUs como recursos K8s, e o KAI Scheduler gerencia multiplas GPUs dentro do mesmo K3s worker com topology-awareness, permitindo tensor parallelism para modelos grandes.


LAYER 2 β€” Platform

Objetivo: Infraestrutura compartilhada que todo servico de IA usa, independente do tipo de workload.

GPU Sharing e Scheduling

ComponenteFuncaoPor que
DRA (Dynamic Resource Allocation)Alocacao granular de GPU nativa do K8s (GA no 1.31+). NVIDIA doou driver para CNCF (KubeCon EU 2026).Substitui NVIDIA Device Plugin com modelo de recursos mais expressivo
KAI SchedulerScheduler GPU da NVIDIA (open-sourced Run:ai, CNCF Sandbox). GPU fracionaria, topology-aware (NVLink/PCIe), hierarchical queues, gang scheduling, preemption inteligente.Principal β€” substitui HAMi com scheduling mais sofisticado e NVIDIA-backed
KueueFilas de jobs batch, quotas por lab/departamento, fairness, preemption controladaSem ele, fine-tuning compete sem regras com inference
KEDAAutoscaling de replicas baseado em metricas (fila vLLM, latencia, GPU util)Escala vLLM automaticamente; libera GPU para batch quando ocioso
PriorityClassescritical-inference(1000) > default-gpu(500) > batch(100)Inference always-on nunca e preemptada por batch

Observabilidade

ComponenteFuncaoPor que
DCGM ExporterMetricas GPU (utilizacao, VRAM, temperatura) β†’ OpenObserveVisibilidade de hardware GPU
OpenObserve + OTelMetricas de infra (CPU, RAM, disco, rede) + logs de todos os podsJa existe, extender com GPU
LangfuseObservabilidade LLM β€” tracing de requests, tokens, latencia, custo, qualidade por usuario/modeloMede o uso da IA, nao so da infra
PromptfooAvaliacao de modelos antes do deploy (CI/CD de prompts)Previne deploy de modelo que degradou qualidade
OpenCostCusto por namespace/lab/modelo em reaisAccountability em ambiente academico, justifica investimento

Storage

ComponenteFuncaoPor que
SeaweedFS (S3 API)Datasets, checkpoints de fine-tuning, documentos, backupsJa existe, S3-compatible
HuggingFace Cache PVCPVC compartilhado montado em todos os GPU nodes com cache de modelosEvita re-download de modelos de 20GB+ entre nodes
QdrantVector database para embeddings e busca semantica (RAG)CPU-only, nao compete por GPU
MLflowModel registry β€” versoes de modelos fine-tunados, rollback, lineageControle formal de modelos treinados com Unsloth
DVCVersionamento de datasets de treino no GitRastreabilidade de dados usados em fine-tuning

Seguranca

ComponenteFuncaoPor que
AuthentikSSO, API keys, OIDC, RBACIdentidade centralizada (ja existe)
KyvernoPolicies K8s β€” limitar VRAM maxima por job, forcar labels obrigatorios, impedir pods privileged em ai-servicesGuardrails operacionais: um job mal configurado nao derruba a inference
Sealed SecretsCredenciais criptografadas no Git (API keys OpenRouter, tokens HuggingFace, credenciais Langfuse)Eliminar plaintext no repositorio
LLM GuardContent filtering, deteccao de PII, protecao contra prompt injectionSeguranca do conteudo gerado pelos modelos
NetworkPoliciesIsolamento de namespace ai-servicesPods de IA nao acessam namespaces de outras apps

Multi-tenancy

PreocupacaoSolucao
Dados entre labs/pesquisadoresCollections separadas no Qdrant, org separation no Langfuse
Quotas de usoBudget caps por lab no TensorZero, quotas de GPU no Kueue
API keysIsolamento por usuario/grupo via Authentik
Logs/prompts (LGPD)Politica de retencao no Langfuse, anonimizacao quando necessario

Operacoes

ComponenteFuncaoPor que
Argo CDGitOps β€” cada servico = 1 Application, sync automaticoZero kubectl manual, git e a fonte de verdade
VeleroBackup de PVCs (Qdrant, Langfuse, MLflow, configs)Recuperacao de estado apos falha

Compartilhamento e segmentacao de GPU

Secao dedicada porque e uma decisao arquitetural critica: como compartilhar GPUs que nao suportam MIG entre multiplos servicos.

Tecnologias disponiveis

TecnologiaO que fazIsolamento VRAMA5500/A5000CustoStatus
KAI SchedulerScheduler GPU NVIDIA (ex-Run:ai). GPU fracionaria, topology-aware, hierarchical queues, gang schedulingSimSimFree (CNCF Sandbox)Escolhido
DRA (Dynamic Resource Allocation)Alocacao granular de GPU nativa do K8s (GA no 1.31+). NVIDIA doou driver para CNCF.Sim (via driver)SimFreeEscolhido (complementa KAI)
HAMiVirtualizacao de GPU com limite de VRAM enforced por podSim (soft)SimFree (CNCF Sandbox)Fallback
Time-slicingCompartilha GPU por tempo, N pods revezamNaoSimFreeFallback
NVIDIA MIGParticiona GPU em instancias isoladas (hardware)Sim (hardware)Nao (A100/H100 apenas)FreeN/A p/ nosso hardware
NVIDIA vGPUVirtualiza GPU com VRAM dedicada via hypervisorSim (virtualizado)SimPago (licenca Enterprise)Descartado por custo

Decisao: KAI Scheduler + DRA (primario) + HAMi (fallback)

KAI Scheduler (NVIDIA, CNCF Sandbox, KubeCon EU 2026) e o scheduler de GPU mais sofisticado disponivel em open source. Substitui HAMi com capacidades superiores:

CapacidadeHAMiKAI Scheduler
GPU fracionaria (VRAM enforced)SimSim (via DRA)
Topology-aware (NVLink, PCIe)NaoSim β€” coloca pods que precisam de multi-GPU em GPUs conectadas por NVLink
Hierarchical queuesNaoSim β€” quotas por lab/departamento com fairness
Gang schedulingNaoSim β€” multi-GPU atomico (fine-tuning distribuido)
Preemption inteligenteBasicaSim β€” respeita prioridade + fairness
ConsolidationNaoSim β€” empacota workloads para liberar GPUs inteiras para jobs grandes
ReclaimNaoSim β€” GPU ociosa de um lab e emprestada para outro
BackingComunidadeNVIDIA

KAI + DRA trabalham juntos: DRA e o driver que expoe GPUs como recursos K8s (substitui NVIDIA Device Plugin). KAI e o scheduler que decide como alocar esses recursos de forma inteligente.

# Com KAI Scheduler + DRA
# Pod declara GPU fracionaria via ResourceClaim
apiVersion: resource.k8s.io/v1beta1
kind: ResourceClaim
metadata:
name: vllm-gpu
spec:
devices:
requests:
- name: gpu
deviceClassName: gpu.nvidia.com
selectors:
- cel:
expression: "device.attributes['gpu.nvidia.com'].memory >= 8192"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm
spec:
template:
spec:
containers:
- name: vllm
resources:
claims:
- name: gpu
resourceClaims:
- name: gpu
resourceClaimTemplateName: vllm-gpu

Por que KAI em vez de HAMi:

  • NVIDIA-backed β€” alinhado com o ecossistema GPU (driver DRA, Device Plugin, DCGM)
  • CNCF Sandbox β€” governanca comunitaria, nao vendor-locked
  • Topology-aware β€” critico para fine-tuning distribuido (Unsloth multi-GPU)
  • Hierarchical queues β€” labs com quotas e fairness, sem Kueue para scheduling (Kueue mantem o papel de job queueing)
  • Consolidation β€” empacota workloads pequenos para liberar GPUs inteiras para jobs grandes

Fallback: HAMi como alternativa caso KAI apresente problemas de compatibilidade com K3s (KAI e mais testado em K8s vanilla/OpenShift).

MIG: nao aplicavel β€” requer A100, A30, ou H100. Se o hardware futuro incluir essas GPUs, MIG e a melhor opcao (isolamento real de hardware).

vGPU: funciona em A5500/A5000 com isolamento real, mas requer licenca paga da NVIDIA (vGPU Enterprise). Descartado por custo.

Exemplo pratico: 1 A5000 (24 GB) compartilhada

GPU A5000 #1 (24 GB total) β€” KAI Scheduler distribui:
β”œβ”€β”€ vLLM chat (Qwen3-8B AWQ) β†’ 14 GB VRAM (ResourceClaim)
β”œβ”€β”€ vLLM embeddings (BGE-M3) β†’ 2 GB VRAM
└── Faster-Whisper β†’ 4 GB VRAM
─────────────────────────
Total: 20 GB / 24 GB (4 GB livre)
KAI Scheduler: lab-pesquisa submete fine-tuning que precisa de 24 GB
β†’ KAI consolida vLLM+BGE+Whisper para outra GPU
β†’ libera GPU inteira para fine-tuning
β†’ quando fine-tuning termina, redistribui

Se um pod tentar alocar mais VRAM do que disponivel, KAI rejeita o scheduling (nao cabe).


Quantizacao β€” estrategia para 24 GB VRAM

Com GPUs de 24 GB (A5000), caber modelos grandes exige compressao eficiente. A estrategia combina duas tecnicas complementares que atuam em partes diferentes do modelo:

TecnicaO que comprimeAbordagemResultado
PolarQuantPesos do modeloTransformada de Hadamard β†’ quantizacao polar. Q5 praticamente lossless, sem calibracao, sem dataset de treinoModelo 70B cabe onde antes so cabia 30B
TurboQuantKV cache (memoria de contexto)Quantizacao 3-bit do KV cache (Google, ICLR 2026). Training-free, data-obliviousContexto longo (32K+ tokens) sem estourar VRAM

Por que duas tecnicas?

Pesos e KV cache sao gargalos independentes:

  • Pesos: ocupam VRAM fixa ao carregar o modelo. PolarQuant reduz isso.
  • KV cache: cresce com o tamanho do contexto (cada request aloca mais). TurboQuant comprime isso.

Aplicar as duas = modelo menor + contexto mais longo na mesma GPU.

Comparativo de quantizacao de pesos

MetodoBitsPrecisa calibracao?Qualidade vs FP16Status
PolarQuantQ5Nao (training-free)~99.5% (praticamente lossless)Recomendado
AWQQ4Sim (dataset de calibracao)~98%Fallback (ja suportado no vLLM)
GPTQQ4Sim (dataset de calibracao)~97-98%Fallback
GGUFQ4-Q8NaoVariavelUso em llama.cpp, nao em vLLM

Nota sobre TensorRT-LLM

TensorRT-LLM (NVIDIA) oferece 15-30% mais throughput via compilacao otimizada, mas tem trade-offs significativos:

  • Modelos precisam ser pre-compilados (engine build demorado)
  • Sem API OpenAI nativa β€” requer Triton Inference Server como wrapper
  • Menos flexivel no K3s (binarios pesados, ciclo de deploy lento)
  • Lock-in NVIDIA (sem suporte AMD futuro)

Decisao: acompanhar evolucao, nao adotar agora. Se throughput se tornar gargalo critico, avaliar como backend alternativo do vLLM (que ja suporta TensorRT como backend experimental).


LAYER 3 β€” AI Services

Objetivo: Servicos especializados que consomem GPU via service contract. Cada servico e 1 Deployment (ou Job) no K8s, independente dos outros.

Servicos interativos (always-on)

Deployments que rodam continuamente, servindo requests em tempo real.

ServicoRuntimeFuncaoGPU estimada
vLLMvLLMChat, raciocinio, geracao de codigo. API OpenAI-compatible. Continuous batching interno, prefix caching.1-2 GPUs (depende do modelo)
SGLangSGLangBackend alternativo ao vLLM. OpenAI-compatible, RadixAttention (KV cache reuse entre requests), ~29% mais rapido em RAG e multi-turn. TensorZero roteia entre vLLM e SGLang via A/B testing.1-2 GPUs (depende do modelo)
Embeddings (BGE-M3)vLLMVetorizacao de texto multilingual para busca semantica e RAG. Alimenta o Qdrant.~2 GB VRAM
Docling/MarkerPyTorchParsing de PDFs, OCR, extracao de tabelas e estrutura de documentos. Nao depende de vLLM.~4-8 GB VRAM
Faster-WhisperCTranslate2Speech-to-text otimizado. Transcricao de aulas, entrevistas, reunioes.~2-4 GB VRAM
pyannotePyTorchDiarizacao de falantes (quem disse o que em reunioes/entrevistas). Complementa Whisper.~2 GB VRAM
TabbyCustomSelf-hosted Copilot. Autocomplete de codigo em IDE (VS Code, JetBrains).~4-8 GB VRAM
FLUX/SDXLDiffusersGeracao e analise de imagens. Materiais didaticos, visualizacoes cientificas.~8-12 GB VRAM
LLM GuardPyTorchGuardrails de seguranca: content filtering, deteccao de PII, prompt injection protection.~2 GB VRAM (ou CPU)
GrobidJavaParser de artigos cientificos (autores, afiliacoes, referencias, DOI). Pode rodar em CPU.CPU-only
dflashPyTorchSpeculative decoding via block diffusion. Otimizacao ortogonal β€” funciona COM vLLM ou SGLang, 6x+ speedup em geracao longa. Nao e um backend separado, e um acelerador.Usa GPU do backend

SGLang vs vLLM β€” quando usar qual?

Ambos sao backends OpenAI-compatible. TensorZero roteia entre eles.

AspectovLLMSGLang
MaturidadeReferencia, maior comunidadeMais novo, comunidade crescente
Multi-turn / RAGBom (prefix caching)~29% mais rapido (RadixAttention reutiliza KV cache entre requests)
Throughput puroExcelenteComparavel ou superior
Modelos suportadosMaior catalogoCatalogo crescente (cobre os principais)
Operador K8sNao tem oficialOME operator (deploy facilitado)

Estrategia: vLLM como backend primario (mais maduro). SGLang como alternativo para workloads RAG-heavy. TensorZero faz A/B testing automatico e roteia para o mais performante.

Servicos batch (jobs com inicio e fim)

Jobs gerenciados pelo Kueue com filas, quotas e preemption.

ServicoRuntimeFuncaoGPU estimada
UnslothPyTorchFine-tuning LoRA/QLoRA de LLMs. Ate 2x mais rapido que metodos tradicionais. Checkpointing para retomar apos preemption.1-4 GPUs (12-48 GB)
OCR em loteDocling/MarkerProcessamento batch de documentos (teses, acervos, microfilmes). Submetido via Airflow ou API.1 GPU
Dataset generationvLLM/APIGeracao de dados sinteticos via modelos cloud para fine-tuning de modelos locais.1 GPU (ou API externa)
PromptfooNode.js + APIAvaliacao automatica de modelos antes do deploy. CI/CD de prompts β€” roda como Job no pipeline.Usa vLLM existente
autoresearchvLLM + PythonPesquisa ML autonoma (pattern Karpathy): agente modifica codigo β†’ treina 5 min β†’ avalia β†’ repete. Jobs longos gerenciados pelo Kueue com checkpoint.1-2 GPUs

Servicos CPU-only (parte da plataforma, sem GPU)

ServicoFuncao
QdrantVector database para embeddings e RAG. Busca semantica, clustering, deduplicacao.
LangfuseObservabilidade LLM: tracing de requests, contagem de tokens, latencia, custo e qualidade por usuario/modelo.
MLflowModel registry: versoes de modelos fine-tunados, rollback, lineage de dados de treino.
Open WebUIInterface web para pesquisadores. Arena Mode para comparar modelos side-by-side. Chat, upload de documentos, historico.
DVCData Version Control: versionamento de datasets de treino no Git, rastreabilidade para fine-tuning.
Hermes AgentAgentes autonomos NousResearch. Multi-plataforma, memoria auto-melhoravel, skills-based. Orquestra pipelines de pesquisa combinando vLLM + Qdrant + Neo4j.

Service Contract

Para adicionar qualquer servico novo a plataforma, sao necessarias 4 coisas:

  1. Container image com CUDA runtime + endpoint de saude (GET /health β†’ 200 OK)
  2. K8s manifests em apps/<service>/
    • deployment.yaml (ou job.yaml para batch)
    • service.yaml (ClusterIP, porta 8000 por convencao)
    • Resources: nvidia.com/gpu, hami.io/gpu-mem, priorityClassName, readinessProbe
  3. Argo CD Application em apps/argocd/<service>.yaml
  4. Rota no gateway (1 entrada na config do TensorZero ou 1 IngressRoute para servicos nao-OpenAI)

Nenhuma mudanca de infra. Nenhum driver. Nenhum CRD custom.

Exemplo β€” adicionar servico de TTS (text-to-speech):

Terminal window
# 1. Criar manifests
apps/tts/deployment.yaml # image, gpu: 1, hami.io/gpu-mem: 4096, priority: default-gpu
apps/tts/service.yaml # ClusterIP, port 8000
# 2. Registrar no Argo CD
apps/argocd/tts.yaml # Application CR apontando para apps/tts/
# 3. Adicionar rota no gateway
# TensorZero config: /v1/audio/speech β†’ tts-svc.ai-services:8000
# 4. Deploy
git push β†’ Argo CD sync β†’ Pod schedulado no GPU node β†’ disponivel via gateway

LAYER 4 β€” API & Developer Experience

Objetivo: Entrada universal para consumidores + self-service para pesquisadores.

Componentes

ComponenteFuncaoPor que
TraefikTLS termination, host-based routing (ai.cppsunesp.org)Ja existe na infra, reusar
TensorZeroAI Gateway: auth, rate-limit, routing, fallback local→cloud, A/B testing de modelos, prompt versioning, spend tracking, BYOKMais que proxy: experimentacao integrada. Pesquisadores podem testar modelos diferentes sem mudar codigo.
DSPyFramework declarativo Stanford para pipelines de IA. Substitui prompt engineering por codigo Python: define modulos (ChainOfThought, ReAct, RAG) e DSPy otimiza prompts automaticamente via avaliacao.Pesquisadores descrevem o que querem (classificar, extrair, resumir), DSPy descobre como fazer com o modelo disponivel.
BackstageInternal Developer Portal: catalogo de servicos, endpoints disponiveis, documentacao, ownership por timePesquisadores sabem o que existe e como usar sem ler o repo ou perguntar

Fluxo de um request

Pesquisador / Aplicacao
β”‚
β”‚ POST https://ai.cppsunesp.org/v1/chat/completions
β”‚ { "model": "qwen3-8b", "messages": [...] }
β”‚
β–Ό
β”Œβ”€ Traefik (debian-proxy) ──────────────────────────────────────┐
β”‚ TLS termination β”‚
β”‚ Host: ai.cppsunesp.org β†’ K3s NodePort (ai-gateway) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€ TensorZero (K3s Pod) ────────────────────────────────────────┐
β”‚ 1. Autenticar (Authentik token / API key) β”‚
β”‚ 2. Rate-limit (por usuario/grupo/lab) β”‚
β”‚ 3. Rotear por modelo: β”‚
β”‚ "qwen3-8b" β†’ vllm-svc ou sglang-svc (A/B test) β”‚
β”‚ "openrouter/claude" β†’ OpenRouter API (cloud) β”‚
β”‚ "openai/gpt-4o" β†’ OpenAI API (BYOK: token pessoal) β”‚
β”‚ 4. Emitir trace β†’ Langfuse β”‚
β”‚ 5. Registrar custo β†’ OpenCost β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€ vLLM ou SGLang (K3s Pod) ────────────────────────────────────┐
β”‚ Continuous batching, KV cache, prefix caching (vLLM) β”‚
β”‚ RadixAttention, KV cache reuse entre requests (SGLang) β”‚
β”‚ Resposta JSON OpenAI-compatible β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Endpoints da API

PathBackendProtocolo
/v1/chat/completionsvLLM (chat)OpenAI-compatible
/v1/embeddingsvLLM (BGE-M3)OpenAI-compatible
/v1/audio/transcriptionsFaster-WhisperOpenAI-compatible
/v1/images/generationsFLUX/SDXLOpenAI-compatible
/v1/documents/parseDoclingCustom REST
/v1/code/completionsTabbyTabby protocol
/v1/modelsTensorZeroOpenAI-compatible (lista modelos disponiveis)
/api/jobs/*Kueue (via controller)Custom REST

TensorZero: por que, e nao LiteLLM?

AspectoLiteLLMTensorZero
Proxy OpenAISimSim
Rate-limit/quotasSimSim
Spend trackingSimSim
Fallback local→cloudSimSim
BYOKSimSim
A/B testing de modelosNaoSim, nativo
Prompt versioningNaoSim, nativo
Routing dinamico por performanceNaoSim
Dados estruturados para fine-tuningNaoSim

Em ambiente academico com experimentacao continua (testar Qwen vs DeepSeek vs Llama, otimizar prompts, medir qualidade), TensorZero agrega mais valor que um proxy simples.

MVP: Traefik β†’ vLLM direto (sem gateway). TensorZero entra quando houver 2+ servicos.


Observabilidade β€” 4 camadas

Cada camada mede algo diferente. Sao complementares, nao substitutas.

CamadaFerramentaO que medeExemplo
InfraOpenObserve + OTel + DCGMCPU, RAM, disco, rede, GPU utilization, VRAM, temperatura”GPU #2 esta a 85C”
LLMLangfuseTokens, latencia, custo, qualidade por request/usuario/modelo”Lab X consumiu 500K tokens esta semana”
EvalPromptfooQualidade de modelo antes do deploy (CI/CD de prompts)β€œQwen3-8B v2 piorou 5% em queries em portugues”
CustoOpenCostCusto por namespace/lab/modelo em reais”Namespace ai-services custa R$X/mes em GPU”

Storage

TipoFerramentaConteudoObservacoes
Object storageSeaweedFS (S3 API)Datasets, checkpoints de fine-tuning, documentos, backupsJa existe no cluster
Model cachePVC compartilhado (HuggingFace Hub cache)Pesos de modelos (~20-40 GB cada)Montado em todos os GPU nodes, evita re-download
Vector storeQdrantEmbeddings para busca semantica e RAGCPU-only, nao compete por GPU
Dataset versioningDVCVersionamento de dados de treinoRastreabilidade para fine-tuning
Model registryMLflowVersoes de modelos fine-tunados, rollback, lineageControle formal de modelos treinados

Seguranca

PreocupacaoSolucaoComponente
Credenciais em plaintextCriptografia no GitSealed Secrets
Controle de acessoSSO, API keys, RBACAuthentik (ja existe)
Policies K8sLimitar VRAM, forcar labels, impedir privilegedKyverno
Conteudo do modeloContent filtering, deteccao de PII, prompt injectionLLM Guard
Isolamento de redeNamespace isolationNetworkPolicies
Multi-tenancyCollections separadas, org separationQdrant + Langfuse
Backup/DRBackup de PVCs + dump de databasesVelero + CronJob
Rotacao de secretsRotacao automatica de API keysExternal Secrets Operator (futuro)

Batch vs Interactive

Dois fluxos distintos que compartilham a mesma GPU pool.

INTERACTIVE (Deployments always-on)
──────────────────────────────────
Request β†’ TensorZero β†’ vLLM/Whisper/Docling
β”‚
β”œβ”€β”€ vLLM gerencia fila interna (continuous batching)
β”œβ”€β”€ KEDA escala replicas (baseado em fila/latencia)
└── PriorityClass: critical-inference (1000)
BATCH (Jobs gerenciados por Kueue)
──────────────────────────────────
Submit β†’ Kueue β†’ Job K8s β†’ GPU
β”‚
β”œβ”€β”€ Fila com fairness entre labs
β”œβ”€β”€ Quotas: "Lab X max 2 GPUs para batch"
β”œβ”€β”€ Preemption: batch e evictado se inference precisa da GPU
β”œβ”€β”€ Checkpoint: estado salvo em SeaweedFS, retoma de onde parou
└── PriorityClass: batch (100)
Coexistencia:
- Inference tem prioridade absoluta sobre batch
- Batch roda quando ha GPU livre (ex: madrugada)
- KEDA escala inference para baixo quando ocioso β†’ libera GPU para batch
- Kueue re-submete batch automaticamente apos preemption

Multi-site (Franca + SP)

Documento detalhado: ver integracao-sp-franca.md para arquitetura completa, papel de cada ferramenta e fases de implementacao.

Decisao: clusters separados

Cada site roda K3s independente. A rede entre sites (via UNESP/ANSP) pode sofrer particoes. Em cluster unico, particao de rede evicta pods e e destrutiva. Em clusters separados, cada site continua autonomo.

K3s Cluster Franca K3s Cluster SP
β”œβ”€β”€ Control Plane β”œβ”€β”€ Control Plane
β”œβ”€β”€ GPU Nodes (3x A5500, 24GB) β”œβ”€β”€ GPU Nodes (3x A5000, 24GB)
β”œβ”€β”€ Argo CD (self) β”œβ”€β”€ Argo CD (self)
β”œβ”€β”€ Cilium (CNI) β”œβ”€β”€ Cilium (CNI)
β”‚ β”‚
β”‚ VyOS WireGuard (site-to-site, UNESP/ANSP)
β”‚ Cilium Cluster Mesh (Global Services, mTLS)
β”‚ Karmada (placement, failover, override por cluster)
β”‚ β”‚
β”œβ”€β”€ vLLM (modelos menores) β”œβ”€β”€ vLLM (modelos 70B+, A6000)
β”œβ”€β”€ Whisper, Docling, BGE-M3 β”œβ”€β”€ Whisper, Docling, BGE-M3
└── Servicos web (replicas) └── Servicos web (replicas)
β”‚ β”‚
└───── Kueue MultiKueue β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
(batch GPU cross-site)

Especializacao por site

SiteHardwarePapel
FrancaCPU moderado, 3x A5500 (24GB) = 72 GB VRAMWeb, orquestracao (Airflow), modelos menores
SPEpic 84-core, 3x A5000 (24GB) = 72 GB VRAMCompute pesado, modelos grandes, fine-tuning

Abordagem hibrida para chamadas cross-site

Tipo de chamadaQuem roteiaPor que
GPU (vLLM, Whisper, embeddings)TensorZeroModel-aware, A/B test, fallback cloud
Batch GPU (fine-tuning, OCR lote)Kueue MultiKueueQueue-aware, despacha para cluster com GPU livre
Dados (Trino, Neo4j, PostgreSQL, Qdrant)Cilium Global ServicesService discovery transparente cross-cluster

Futuro: 3o site (cloud)

Quando houver demanda de burst ou DR:

  • Liqo para overflow transparente de pods para cloud (virtual nodes)
  • Kueue MultiKueue para despachar batch GPU para cloud
  • Candidatos: Oracle Cloud (free tier ARM), Hetzner (~4 EUR/mes)

Estrutura do repositorio

devops/
β”œβ”€β”€ infra/
β”‚ └── gpu-nodes/ # Pulumi: provisiona LXC com GPU passthrough no Proxmox
β”‚
β”œβ”€β”€ config/
β”‚ β”œβ”€β”€ gpu-node/ # Ansible: NVIDIA driver, nvidia-ctk, K3s agent join
β”‚ β”œβ”€β”€ traefik/ # (existente) + rota ai.cppsunesp.org
β”‚ └── vyos/ # (existente)
β”‚
β”œβ”€β”€ apps/
β”‚ β”œβ”€β”€ gpu-operator/ # DRA driver + KAI Scheduler (GPU sharing)
β”‚ β”œβ”€β”€ ai-gateway/ # TensorZero (gateway)
β”‚ β”œβ”€β”€ ai-platform/ # Namespace, PriorityClasses, ResourceQuotas, Kyverno policies
β”‚ β”œβ”€β”€ dcgm-exporter/ # GPU metrics β†’ OpenObserve
β”‚ β”œβ”€β”€ kueue/ # Job scheduling (batch)
β”‚ β”œβ”€β”€ opencost/ # Cost tracking
β”‚ β”œβ”€β”€ langfuse/ # LLM observability
β”‚ β”œβ”€β”€ qdrant/ # Vector database
β”‚ β”œβ”€β”€ mlflow/ # Model registry
β”‚ β”œβ”€β”€ backstage/ # Developer portal
β”‚ β”œβ”€β”€ llm-guard/ # Safety guardrails
β”‚ β”œβ”€β”€ vllm/ # LLM inference
β”‚ β”œβ”€β”€ sglang/ # LLM inference (alternativo)
β”‚ β”œβ”€β”€ embeddings/ # BGE-M3
β”‚ β”œβ”€β”€ docling/ # Document processing
β”‚ β”œβ”€β”€ whisper/ # Audio STT
β”‚ β”œβ”€β”€ tabby/ # Code assistance
β”‚ β”œβ”€β”€ hermes-agent/ # Agentes autonomos
β”‚ β”œβ”€β”€ open-webui/ # Web interface
β”‚ β”œβ”€β”€ openobserve/ # (existente) OTel Collector
β”‚ β”œβ”€β”€ argocd/ # (existente) + 1 Application CR por servico novo
β”‚ └── ... # apps existentes (Airflow, etc.) inalteradas
β”‚
β”œβ”€β”€ roadmap/
β”‚ └── gpu-platform.md # Este documento
β”‚
└── docs/
└── openobserve-setup.md # (existente)

Fases de implementacao

Cada fase funciona independente das seguintes. A plataforma e utilizavel a partir da Fase 2.

FaseFocoComponentesResultado
0GPU no K3sPulumi (LXC), NVIDIA driver, nvidia-ctk, K3s agentnvidia-smi visivel de dentro de um Pod
1Platform baseDRA driver, KAI Scheduler, DCGM, PriorityClasses, namespace ai-services, HF cache PVC, Sealed SecretsGPU schedulavel como recurso K8s com sharing inteligente
2Primeiro servicovLLM (chat) + Open WebUI, acessivel via Traefik diretoPesquisadores usando chat via browser
3Gateway + obsTensorZero + Authentik + Langfuse + LLM GuardAPI unificada com auth, tracing e guardrails
4Expandir servicos + SGLangEmbeddings + Qdrant + Docling + Whisper + SGLang (1 git push cada). SGLang como backend alternativo, TensorZero roteia via A/B test.5+ servicos de IA operacionais, benchmarks vLLM vs SGLang
5Batch + modelosKueue + Unsloth + MLflow + DVC + PromptfooFine-tuning com filas, model registry, eval
6OperacoesOpenCost + Kyverno + Velero + KEDACusto, policies, backup, autoscaling
7Developer experienceBackstage (catalogo) + Tabby (code assist) + DSPy (pipelines declarativos)Self-service para pesquisadores
8Multi-siteVyOS WireGuard (UNESP/ANSP) + K3s SP + Cilium Cluster Mesh + Karmada + Argo CD SP + GPU nodes SP (A6000) + MultiKueueClusters separados com failover automatico, 216 GB VRAM distribuidos
9Avancadodflash (speculative decoding), Hermes Agent (agentes autonomos), autoresearch (pattern Karpathy), PolarQuant + TurboQuant (quantizacao), TensorZero A/B testing, pipeline de auto-melhoriaExperimentacao continua, modelos locais melhorando automaticamente

Catalogo de componentes (indice completo β€” 48)

Todos os componentes da plataforma, sem excecao:

#ComponenteCamadaTipoFuncao resumida
1PulumiL1 InfraIaCProvisiona LXC/VM no Proxmox
2ProxmoxL1 InfraHypervisorHospeda VMs/LXCs
3NVIDIA DriverL1 InfraDriverAcesso a GPU no host
4LXCL1 InfraContainerGPU passthrough com overhead minimo
5nvidia-ctkL1 InfraRuntimeGPU em containers
6K3s AgentL1 InfraOrchestratorWorker node GPU
7DRA (Dynamic Resource Allocation)L2 PlatformK8s nativoGPU como recurso K8s (substitui Device Plugin)
8KAI SchedulerL2 PlatformGPU SharingFracionario, topology-aware, hierarchical queues (substitui HAMi)
9DCGM ExporterL2 PlatformMetricasMetricas GPU
10KueueL2 PlatformSchedulingFilas de jobs batch
11KEDAL2 PlatformAutoscalingEscala replicas por metricas
12PriorityClassesL2 PlatformK8sPrioridade inference > batch
13OpenCostL2 PlatformFinOpsCusto por namespace/lab
14KyvernoL2 PlatformPoliciesGuardrails K8s
15Sealed SecretsL2 PlatformSegurancaCredenciais no Git
16VeleroL2 PlatformBackupBackup de PVCs
17Argo CDL2 PlatformGitOpsSync automatico
18AuthentikL2 PlatformIAMSSO, API keys, RBAC
19NetworkPoliciesL2 PlatformSegurancaIsolamento de rede
20OpenObserve + OTelL2 PlatformObservabilidadeMetricas e logs de infra
21SeaweedFSL2 PlatformStorageObject storage S3
22HF Cache PVCL2 PlatformStorageCache de modelos
23vLLML3 ServicesInferenceChat, raciocinio, codigo
24BGE-M3 (Embeddings)L3 ServicesInferenceVetorizacao de texto
25Docling/MarkerL3 ServicesInferenceOCR, parsing de PDFs
26Faster-WhisperL3 ServicesInferenceSpeech-to-text
27pyannoteL3 ServicesInferenceDiarizacao de falantes
28TabbyL3 ServicesInferenceCode assist (Copilot)
29FLUX/SDXLL3 ServicesInferenceGeracao de imagens
30LLM GuardL3 ServicesSegurancaContent filtering, PII
31GrobidL3 ServicesInferenceParser de artigos cientificos
32UnslothL3 ServicesBatchFine-tuning LoRA/QLoRA
33PromptfooL3 ServicesBatchEval de modelos (CI/CD)
34QdrantL3 ServicesDatabaseVector DB para RAG
35LangfuseL3 ServicesObservabilidadeTracing LLM
36MLflowL3 ServicesMLOpsModel registry
37Open WebUIL3 ServicesFrontendInterface para pesquisadores
38DVCL3 ServicesMLOpsVersionamento de datasets
39SGLangL3 ServicesInferenceBackend alternativo ao vLLM (RadixAttention)
40dflashL3 ServicesOtimizacaoSpeculative decoding via block diffusion (6x+)
41autoresearchL3 ServicesBatchPesquisa ML autonoma (pattern Karpathy)
42Hermes AgentL3 ServicesAgentesAgentes autonomos NousResearch
43PolarQuantL2 PlatformQuantizacaoPesos Q5 lossless via Hadamard
44TurboQuantL2 PlatformQuantizacaoKV cache 3-bit (Google ICLR 2026)
45TraefikL4 APIGatewayTLS, routing externo
46TensorZeroL4 APIAI GatewayAuth, routing, A/B testing
47DSPyL4 APIDXPipelines declarativos de IA (Stanford)
48BackstageL4 APIDXCatalogo de servicos