IA / LLMs/Artigo

    Como servir embeddings em produção

    Para servir embeddings em produção, você precisa de um endpoint HTTP que receba texto e retorne vetores de forma consistente. A opção mais simples é o Ollama, que serve qualquer modelo de embedding com um único pull e expõe uma API REST imediatamente. Para mais controle sobre o modelo e a lógica de pré-processamento, use sentence-transformers com FastAPI.

    Servir embeddings com Ollama (mais simples)

    O Ollama inclui suporte a modelos de embedding — basta baixar o modelo e chamar o endpoint /api/embeddings:

    bash
    # Baixar o modelo de embedding
    ollama pull nomic-embed-text
    
    # Gerar embedding via API
    curl http://localhost:11434/api/embeddings \
      -H "Content-Type: application/json" \
      -d '{"model": "nomic-embed-text", "prompt": "Texto para vetorizar"}'
    
    # Via endpoint compatível com OpenAI
    curl http://localhost:11434/v1/embeddings \
      -H "Content-Type: application/json" \
      -d '{"model": "nomic-embed-text", "input": "Texto para vetorizar"}'
    Dica
    O endpoint /v1/embeddings é compatível com o SDK da OpenAI — basta trocar base_url para http://localhost:11434 e usar model="nomic-embed-text".

    Modelos de embedding recomendados

    Diferentes modelos têm trade-offs de qualidade, velocidade e dimensões do vetor:

    Dica
    nomic-embed-text (768 dims): boa qualidade multilingual, rápido em CPU, pull via Ollama. mxbai-embed-large (1024 dims): melhor qualidade, ~2× mais lento, pull via Ollama. all-MiniLM-L6-v2 (384 dims): muito rápido, qualidade menor, via sentence-transformers. bge-m3 (1024 dims): excelente para português e inglês, via sentence-transformers ou Ollama. Use o mesmo modelo entre indexação e consulta — vetores de modelos diferentes não são comparáveis.

    Servir com sentence-transformers + FastAPI

    Para mais controle, exponha um servidor FastAPI com sentence-transformers. Útil quando você precisa de pré-processamento customizado ou modelos não disponíveis no Ollama:

    bash
    # requirements.txt
    sentence-transformers==3.x.x
    fastapi
    uvicorn
    
    # server.py
    from fastapi import FastAPI
    from sentence_transformers import SentenceTransformer
    from pydantic import BaseModel
    
    app = FastAPI()
    model = SentenceTransformer("nomic-ai/nomic-embed-text-v1", trust_remote_code=True)
    
    class EmbedRequest(BaseModel):
        texts: list[str]
    
    @app.post("/embed")
    def embed(req: EmbedRequest):
        vectors = model.encode(req.texts, normalize_embeddings=True).tolist()
        return {"embeddings": vectors, "dimensions": len(vectors[0])}
    Atenção
    O modelo é carregado em memória na inicialização. Para modelos grandes (bge-m3 ~1 GB), o cold start pode levar 10–30 segundos. Configure restart: always no Docker para evitar downtime.

    Dockerfile e docker-compose para o servidor de embeddings

    Para produção, containerize o servidor FastAPI:

    bash
    # Dockerfile
    FROM python:3.11-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    COPY server.py .
    CMD ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8000"]
    
    # docker-compose.yml
    services:
      embeddings:
        build: .
        restart: always
        ports:
          - "8000:8000"
        volumes:
          - hf_cache:/root/.cache/huggingface
    
    volumes:
      hf_cache:
    Dica
    O volume hf_cache persiste o download do modelo entre restarts — evita baixar o modelo toda vez que o container reinicia.

    Garantir consistência entre indexação e consulta

    O maior erro em pipelines RAG é usar modelos diferentes para gerar os vetores do índice e os vetores da query. Defina o modelo como constante no código:

    bash
    # config.py — única fonte de verdade
    EMBEDDING_MODEL = "nomic-embed-text"
    EMBEDDING_DIMENSIONS = 768
    VECTOR_DISTANCE = "Cosine"
    
    # Use essa constante em todos os lugares:
    # - ao criar a collection no banco vetorial
    # - ao indexar documentos
    # - ao vetorizar a query na busca

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o Ollama em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes

    Conteúdos relacionados

    [VERIFICAR antes de publicar]

    • 1. Confirme a versão estável atual do sentence-transformers em pypi.org/project/sentence-transformers.
    • 2. Confirme o limite de tokens do nomic-embed-text na versão atual — pode ter mudado.