Home Projetos & Releases BigBangcraft Blog Sobre & Carreira
DevOps & Cloud • Hub 8 min de leitura 15 visualizações
Raw .md

Migrando prompts extensos de APIs em nuvem para Ollama: armadilhas de infraestrutura e memória

PD

Pedro Dalben

CTO no Integrar Plus • Publicado em 14 de September de 2026

Migrando prompts extensos de APIs em nuvem para Ollama: armadilhas de infraestrutura e memória

Autor: Pedro Dalben (CTO no Integrar Plus)

Publicado em: 14 de September de 2026

URL Canônica Oficial: https://pedrodalben.com.br/blog/migrando-prompts-extensos-de-apis-em-nuvem-para-ollama-armadilhas-de-infraestrutura-e-memoria


Migrar tarefas de inteligência artificial de APIs proprietárias para uma infraestrutura própria é um movimento natural quando buscamos previsibilidade de custos, soberania sobre os dados e menor dependência de terceiros. No entanto, existe uma distância considerável entre o consumo de modelos de fronteira em nuvem, como o Claude Opus, e a operação independente de modelos abertos através do Ollama em servidores dedicados.

O ponto de atrito mais crítico dessa transição costuma ser o tamanho do contexto de entrada. Em APIs gerenciadas, enviar um preprompt de 35 KB contendo regras de negócio, esquemas relacionais e exemplos estruturados parece trivial. A nuvem mascara a complexidade computacional distribuindo a carga em clusters com paralelismo massivo de tensores e cache de prefixo transparente. Ao mover essa mesma carga de trabalho para uma máquina própria com Ollama, a realidade do hardware se impõe imediatamente.

A seguir, analiso os principais gargalos técnicos e trade-offs arquiteturais envolvidos ao executar prompts massivos em nós de inferência auto-hospedados.

O perigo do truncamento silencioso de contexto

O primeiro obstáculo prático não costuma se manifestar como uma falha visível de infraestrutura ou uma resposta HTTP com código de erro. Ele se manifesta como perda silenciosa de precisão lógica.

O Ollama utiliza o motor do llama.cpp sob o capô. Por padrão histórico e conservadorismo de recursos, diversas distribuições e imagens padrão definem a janela de contexto (num_ctx) para valores baixos, frequentemente fixados em 2.048 ou 4.096 tokens, a depender do modelo base.

Um arquivo de texto de 35 KB em português ou com estruturas de código pode consumir facilmente entre 7.000 e 10.000 tokens, variando conforme o vocabulário do tokenizer. Quando o tamanho somado do preprompt e da mensagem do usuário ultrapassa o limite configurado de contexto, o motor simplesmente descarta o início da mensagem ou trunca as instruções do sistema para manter a execução dentro da janela alocada.

O resultado é um modelo que passa a alucinar, esquecer regras de validação ou quebrar formatos de saída, sem disparar exceções no log da aplicação. Para contornar esse comportamento, é obrigatório explicitar o tamanho da janela na definição do modelo por meio de um Modelfile customizado:

FROM llama3.1:8b

PARAMETER num_ctx 16384
PARAMETER temperature 0.2

Essa linha única resolve o truncamento, mas cria imediatamente o segundo e maior gargalo da operação: a explosão do consumo de memória.

A física da memória: alocação de KV Cache

Ao contrário da inferência tradicional em aplicações web, onde o uso de memória por processo é relativamente linear e previsível, em modelos de linguagem o consumo de memória escala diretamente com o tamanho da janela de contexto ativa.

Durante a passagem do prompt, o modelo precisa manter na memória de vídeo (VRAM) as matrizes de chaves e valores da atenção para cada camada da rede neural, estrutura conhecida como KV Cache. A fórmula básica para o dimensionamento do KV Cache depende de:

  1. Número de camadas do modelo.
  2. Dimensão oculta dos cabeçotes de atenção.
  3. Quantidade de tokens de contexto reservados (num_ctx).
  4. Precisão numérica (FP16, FP8 ou quantizações inteiras).

Ao carregar os pesos de um modelo de 8 bilhões de parâmetros quantizado em 4 bits (Q4KM), a ocupação básica da VRAM fica em torno de 5 GB a 6 GB. No entanto, ao expandir o num_ctx para 16.384 ou 32.768 posições para acomodar um preprompt de 35 KB mais a margem de saída, o KV Cache pode exigir vários gigabytes adicionais de memória dedicada.

Em um servidor de aplicação com placas intermediárias ou GPUs para estações de trabalho, essa expansão consome a folga operacional. Se a VRAM total for ultrapassada, o Ollama delega camadas excedentes para a CPU e para a memória RAM do sistema (offloading de camadas). No momento em que uma única camada de atenção precisa ser processada na memória RAM via barramento PCIe, a latência de processamento é multiplicada em ordens de magnitude.

Prefill contra Decode: o impacto na latência de resposta

A execução de um modelo ocorre em duas fases distintas: a fase de pré-preenchimento (prefill ou avaliação do prompt) e a fase de decodificação (geração sequencial de tokens).

A fase de prefill é intensiva em operações matemáticas e altamente paralelizável, pois todos os tokens de entrada já são conhecidos. Processar um prompt longo significa que o hardware passará segundos calculando as projeções de atenção para esses milhares de tokens antes de gerar o primeiro caractere de resposta (Time to First Token - TTFT).

Modelos proprietários de nuvem atenuam esse impacto utilizando caches de prompt em nível de cluster. Se cem chamadas consecutivas utilizam o mesmo preprompt de 35 KB, a nuvem reutiliza as representações de atenção pré-computadas.

No Ollama, embora exista cache de contexto em memória para sessões sequenciais na mesma conexão, o comportamento degrada rapidamente quando a infraestrutura recebe requisições concorrentes.

Concorrência e concorrência na fila de background

Em uma arquitetura clássica baseada em filas de background (como Solid Queue ou Sidekiq no ecossistema Rails), é comum termos múltiplos workers processando tarefas simultaneamente.

Se quatro workers disparam requisições quase simultâneas para uma única instância do Ollama, e cada requisição carrega variações de dados anexadas ao preprompt de 35 KB, ocorrem dois problemas críticos:

Cenário de Operação Alocação de Memória Impacto Operacional
Sessões Concorrentes Múltiplas Espaço multiplicado por cada slot de contexto ativo Exaustão imediata de VRAM e queda para CPU
Sessão Serial com Invalidação Um slot único que descarta o cache anterior a cada troca de prefixo Taxa de prefill repetida a cada execução

Se a sua fila despachar trabalhos em paralelo para um Ollama configurado com suporte a múltiplos slots concorrentes, a memória do KV Cache precisará ser duplicada para cada slot. Sem VRAM suficiente para suportar múltiplos contextos longos, as requisições entrarão em fila interna, gerando timeouts na ponta da aplicação web.

Para controlar essa restrição em um cluster próprio, a melhor abordagem arquitetural é desacoplar o despacho de chamadas LLM da concorrência geral de background:

class HeavyLlmProcessingJob < ApplicationJob
  # Limita o processamento a uma fila de concorrencia estrita
  limits_concurrency to: 1, key: -> { "ollama_inference_node" }

  def perform(payload_id)
    payload = Payload.find(payload_id)
    InferenceClient.post_prompt(payload.content)
  end
end

Definir semáforos estritos ou filas com concorrência unitária por placa aceleradora impede que a fila sature a capacidade de transferência do nó de inferência.

A capacidade de aderência a instruções longas

Além das restrições estritas de hardware, existe o trade-off de modelagem. Modelos massivos de fronteira como o Claude Opus possuem uma capacidade ímpar de compreender diretrizes complexas e dispersas em um texto denso de dezenas de kilobytes.

Ao transferir esse mesmo prompt monolítico para modelos abertos menores (como variantes de 7B, 8B ou 14B de parâmetros), observa-se com frequência o fenômeno de perda no meio (lost in the middle). O modelo atende às regras localizadas no início e no final do contexto, mas ignora instruções cruciais posicionadas no meio do preprompt volumoso.

Tentar resolver isso aumentando a temperatura ou inflando ainda mais o texto com avisos redundantes apenas agrava o custo de prefill e a ocupação de memória.

Decisões pragmáticas de desenho

A migração de cargas de trabalho intensivas em contexto para servidores próprios não deve ser tratada como uma simples substituição de endpoint HTTP. A viabilidade técnica exige repensar a distribuição das instruções:

  1. Decomposição em pipelines curtos: Em vez de manter um preprompt de 35 KB contendo todas as regras do negócio em um único disparo, particione a tarefa em etapas menores encadeadas por jobs na fila, onde cada estágio opera com instruções objetivas de poucos centenas de tokens.
  2. Transferência de contexto para bases relacionais: Deixe a recuperação estruturada para consultas rápidas no PostgreSQL em vez de enviar catálogos ou tabelas inteiras dentro do texto do sistema.
  3. Parametrização estrita de runtime: Nunca execute contêineres de inferência sem fixar os limites de contexto, o número de slots concorrentes e a alocação de memória reservada.

Hospedar a própria pilha de inteligência artificial oferece soberania operacional e custos previsíveis a longo prazo, mas exige tratar o modelo de linguagem pelo que ele realmente é no nível do sistema operacional: um processo intensivo de cálculo matricial limitado rigorosamente pela largura de banda e pela capacidade finita da memória física da sua infraestrutura.

Fontes

PD

Sobre Pedro Dalben

CTO e arquiteto full stack especializado em Ruby on Rails, Vue.js, sistemas multi-tenant e infraestrutura distribuída.