Construção de um Serviço API Privado para o Modelo Cogito-v1-preview-llama-3B com Ollama e FastAPI

1. Visão Geral do Projeto

Este guia detalha a implementação prática de uma API privada para o modelo Cogito v1 preview, um recurso valioso para desenvolvedores que necessitam integrar capacidades de inteligência artificial em ambientes locais ou de rede interna. O modelo Cogito v1 preview, desenvolvido pela Deep Cogito, é um modelo de inferência híbrido que demonstra desempenho robusto em diversos benchmarks. Uma de suas características distintivas é a capacidade de operar em dois modos: resposta direta e modo de raciocínio. Neste último, o modelo realiza uma auto-reflexão antes de formular a resposta, resultando em saídas mais precisas e aprofundadas.

Com suporte para mais de 30 idiomas e uma janela de contexto de 128k, o modelo é ideal para processamento de documentos extensos e cenários multilíngues. A combinação de Ollama para a execução do modelo e FastAPI para a camada de API permite encapsular facilmente esse poderoso recurso, tornando-o acessível a outras aplicações.

2. Preparação e Instalação do Ambiente

Antes de iniciar a implantação, é necessário configurar o ambiente de desenvolvimento. Os componentes essenciais são:

  • Python 3.8+: Recomenda-se a versão estável mais recente.
  • Olllama: Ambiente de execução de modelos de linguagem.
  • FastAPI: Um framwork web moderno para construir APIs.
  • Uvicorn: Um servidor ASGI de alto desempenho.

Para começar, instale o Ollama de acordo com o seu sistema operacional:

# Instalação para Linux/macOS
curl -fsSL https://ollama.ai/install.sh | sh

# Instalação para Windows (requer WSL2 pré-instalado)
winget install Ollama.Ollama

Após a instalação do Ollama, baixe o modelo Cogito:

ollama pull cogito:3b

Verifique a instalação do modelo executando um prompt de teste:

ollama run cogito:3b "Olá, pode se apresentar?"

Se o modelo responder adequadamente, a configuração básica está concluída.

3. Configuração do Serviço FastAPI

Agora, vamos criar uma aplicação FastAPI para expor o modelo como um serviço. Primeiro, instale as bibliotecas Python necessárias:

pip install fastapi uvicorn requests pydantic

Crie o arquivo principal da aplicação, app_service.py:

from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel
import requests
import json

# Inicializa a aplicação FastAPI
app_instance = FastAPI(
    title="Serviço de Inferência Cogito",
    description="API privada para o modelo Cogito v1 (3B) via Ollama.",
    version="1.0.0"
)

# Define o esquema para a requisição de geração de texto
class TextGenerationRequest(BaseModel):
    input_text: str
    max_output_tokens: int = 512
    creativity_temp: float = 0.7

# Define o esquema para a resposta da API
class GenerationResponse(BaseModel):
    generated_content: str
    process_status: str

@app_instance.post("/generate_text", response_model=GenerationResponse, summary="Gerar Texto com o Modelo Cogito")
async def generate_text_endpoint(request_data: TextGenerationRequest):
    """
    Endpoint para interagir com o modelo Cogito e gerar texto com base em uma entrada.
    """
    try:
        # URL da API do Ollama (padrão)
        ollama_base_url = "http://localhost:11434/api/generate"
        
        # Constrói o payload para a requisição ao Ollama
        request_payload = {
            "model": "cogito:3b",
            "prompt": request_data.input_text,
            "stream": False, # Desativa o streaming para obter a resposta completa
            "options": {
                "temperature": request_data.creativity_temp,
                "num_predict": request_data.max_output_tokens
            }
        }
        
        # Envia a requisição POST para o serviço Ollama
        ollama_response = requests.post(ollama_base_url, json=request_payload)
        ollama_response.raise_for_status() # Lança uma exceção para códigos de status HTTP de erro
        
        # Parseia a resposta JSON do Ollama
        response_data = ollama_response.json()
        
        return GenerationResponse(
            generated_content=response_data.get("response", ""),
            process_status="success"
        )
        
    except requests.exceptions.RequestException as req_exc:
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE, 
            detail=f"Erro de comunicação com o serviço Ollama: {str(req_exc)}"
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, 
            detail=f"Erro interno no serviço de modelo: {str(e)}"
        )

@app_instance.get("/status", summary="Verificar o Status do Serviço")
async def service_status_check():
    """
    Endpoint de verificação de saúde do serviço API.
    """
    return {"status": "operational", "model_active": "cogito:3b"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app_instance, host="0.0.0.0", port=8000)

Este serviço API oferece dois endpoints principais:

  • /generate_text: Para interagir e gerar texto com o modelo.
  • /status: Para verificar a saúde e o status do serviço.

4. Implantação e Teste do Serviço

Antes de iniciar o serviço FastAPI, assegure-se de que o serviço Ollama esteja ativo:

# Inicia o serviço Ollama
ollama serve

Em um terminal separado, inicie o serviço FastAPI:

python app_service.py

Com o serviço em execução, você pode testar a API de diversas maneiras:

Método 1: Usando curl

curl -X POST "http://localhost:8000/generate_text" \
     -H "Content-Type: application/json" \
     -d '{
         "input_text": "Explique o conceito fundamental de aprendizado de máquina em português.",
         "max_output_tokens": 300,
         "creativity_temp": 0.7
     }'

Método 2: Usando um Cliente Python

import requests

def make_api_call():
    api_url = "http://localhost:8000/generate_text"
    request_body = {
        "input_text": "Escreva uma função em Python para calcular o n-ésimo número de Fibonacci de forma iterativa.",
        "max_output_tokens": 200,
        "creativity_temp": 0.5
    }
    
    response = requests.post(api_url, json=request_body)
    if response.status_code == 200:
        result_data = response.json()
        print("Resposta do Modelo:", result_data["generated_content"])
    else:
        print("Falha na Requisição:", response.text)

make_api_call()

Método 3: Através da Documentação Interativa

Acesse http://localhost:8000/docs no seu navegador. A interface Swagger UI, gerada automaticamente pelo FastAPI, permite explorar e testar todos os endpoints da API.

5. Extensões de Funcionalidade Avançadas

Após a configuração básica, é possível adicionar funcionalidades avançadas para aprimorar a utilidade e estabilidade do serviço.

5.1. Implementação de Limitação de Taxa de Requisições

Para prevenir o uso excessivo da API, pode-se integrar limitação de taxa:

from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded

# Configura o limitador de taxa
rate_limiter = Limiter(key_func=get_remote_address)
app_instance.state.limiter = rate_limiter
app_instance.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)

@app_instance.post("/generate_text")
@rate_limiter.limit("5/minute") # Limita a 5 requisições por minuto por IP
async def generate_text_endpoint(request_data: TextGenerationRequest):
    # Código existente do endpoint permanece inalterado
    ...

5.2. Suporte a Histórico de Conversação

Para que o modelo mantenha o contexto em diálogos multi-turno, pode-se adicionar suporte a histórico:

from typing import List, Dict

class ConversationMessage(BaseModel):
    role: str # "user" ou "assistant"
    content: str

class ConversationSessionRequest(BaseModel):
    dialog_history: List[ConversationMessage]
    max_output_tokens: int = 512

@app_instance.post("/converse", summary="Iniciar ou Continuar uma Conversa Multi-turno")
async def handle_conversation(session_request: ConversationSessionRequest):
    """
    Endpoint para gerenciar sessões de conversação com contexto.
    """
    try:
        # Constrói o prompt com o histórico da conversa
        full_conversation_prompt = ""
        for msg in session_request.dialog_history:
            full_conversation_prompt += f"{msg.role}: {msg.content}\n"
        
        full_conversation_prompt += "assistant: " # Prepara para a resposta do assistente
        
        # Envia para Ollama
        ollama_payload = {
            "model": "cogito:3b",
            "prompt": full_conversation_prompt,
            "stream": False,
            "options": {
                "num_predict": session_request.max_output_tokens
            }
        }
        
        ollama_response = requests.post("http://localhost:11434/api/generate", json=ollama_payload)
        ollama_response.raise_for_status()
        response_json = ollama_response.json()
        
        return {"response_content": response_json.get("response", ""), "status": "success"}
        
    except requests.exceptions.RequestException as req_exc:
        raise HTTPException(
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE, 
            detail=f"Erro de comunicação com o serviço Ollama: {str(req_exc)}"
        )
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))

5.3. Ajuste de Parâmetros de Geração do Modelo

Ofereça opções para controlar mais aspectos da geração de texto do modelo:

class FineTunedGenerationRequest(BaseModel):
    query_text: str
    max_tokens_to_generate: int = 512
    sampling_temperature: float = 0.7
    top_p_sampling: float = 0.9
    top_k_candidates: int = 40
    repetition_penalty: float = 1.1

@app_instance.post("/fine_tune_generate", summary="Gerar Texto com Parâmetros de Modelo Ajustados")
async def fine_tuned_generation(advanced_request: FineTunedGenerationRequest):
    ollama_payload = {
        "model": "cogito:3b",
        "prompt": advanced_request.query_text,
        "stream": False,
        "options": {
            "temperature": advanced_request.sampling_temperature,
            "num_predict": advanced_request.max_tokens_to_generate,
            "top_p": advanced_request.top_p_sampling,
            "top_k": advanced_request.top_k_candidates,
            "repeat_penalty": advanced_request.repetition_penalty
        }
    }
    
    # O restante do código é similar ao endpoint de geração básica,
    # com tratamento de exceções e retorno de resposta.
    try:
        ollama_response = requests.post("http://localhost:11434/api/generate", json=ollama_payload)
        ollama_response.raise_for_status()
        response_json = ollama_response.json()
        return {"response_content": response_json.get("response", ""), "status": "success"}
    except requests.exceptions.RequestException as req_exc:
        raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail=f"Erro Ollama: {str(req_exc)}")
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e))

6. Recomendações para Implantação em Produção

Ao mover o serviço API para um ambiente de produção, certas considerações são importantes para otimização e estabilidade.

6.1. Otimização com Gunicorn

Em produção, é aconselhável usar o Gunicorn como servidor WSGI/ASGI para melhor performance e gerenciamento de processos:

pip install gunicorn

Crie um arquivo de configuração gunicorn_config.py:

workers = 4 # Número de workers para processar requisições
worker_class = "uvicorn.workers.UvicornWorker" # Usar worker Uvicorn para ASGI
bind = "0.0.0.0:8000" # Porta e IP para o serviço escutar
timeout = 120 # Tempo limite para workers (em segundos)
keepalive = 5 # Tempo limite para conexões keep-alive (em segundos)

Inicie o serviço com Gunicorn:

gunicorn -c gunicorn_config.py app_service:app_instance

6.2. Implantação Containerizada com Docker

A containerização com Docker oferece portabilidade e isolamento. Crie um Dockerfile:

FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

# Comando para iniciar o servidor Gunicorn
CMD ["gunicorn", "-c", "gunicorn_config.py", "app_service:app_instance"]

E um docker-compose.yml para orquestrar o Ollama e o serviço API:

version: '3.8'

services:
  ollama_server:
    image: ollama/ollama:latest
    ports:
      - "11434:11434"
    volumes:
      - ollama_data_vol:/root/.ollama
    restart: unless-stopped # Reinicia o container se ele parar

  cogito_api_gateway:
    build: .
    ports:
      - "8000:8000"
    depends_on: # Garante que ollama_server inicie primeiro
      - ollama_server
    environment:
      - OLLAMA_HOST=http://ollama_server:11434 # Comunicação interna entre containers
    restart: unless-stopped

volumes:
  ollama_data_vol: # Volume para persistir os modelos Ollama

6.3. Monitoramento e Registro de Logs

Adicione middleware de logging para rastrear requisições e respostas:

import logging
from fastapi import Request

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
app_logger = logging.getLogger(__name__)

@app_instance.middleware("http")
async def log_http_requests(request: Request, call_next):
    app_logger.info(f"Requisição recebida: {request.method} {request.url}")
    response = await call_next(request)
    app_logger.info(f"Resposta enviada: Status {response.status_code}")
    return response

7. Cenários de Aplicação

Este serviço API privado oferece uma base sólida para diversas aplicações de IA:

  • Sistemas de Q&A Corporativos: Desenvolva soluções de perguntas e respostas inteligentes para documentos internos, políticas e procedimentos da empresa.
  • Assistência à Codificação: Integre-o em IDEs para fornecer explicações de código, sugestões de correção de bugs ou otimizações de código.
  • Atendimento ao Cliente Multilíngue: Aproveite as capacidades multilíngues do modelo para construir chatbots de suporte ao cliente que atendam a uma base de usuários global.
  • Geração e Edição de Conteúdo: Utilize-o para criar rascunhos de textos de marketing, descrições de produtos, modelos de e-mail e outras tarefas de criação de conteúdo.

8. Conclusão

Este guia demonstrou o processo de criação de um serviço API privado para o modelo Cogito v1 preview, utilizando Ollama e FastAPI. Os principais benefícios desta abordagem incluem:

  • Segurança dos Dados: Todo o processamento ocorre localmente, garantindo a privacidade e não expondo dados sensíveis a servidores externos.
  • Custo-Benefício: Uma vez implantado, os custos são previsíveis e não baseados em volume de uso, diferente de serviços baseados em nuvem.
  • Flexibilidade de Customização: Permite a adaptação de parâmetros do modelo e funcionalidades da API conforme as necessidades específicas do projeto.
  • Performance e Estabilidade: A implantação local minimiza a latência da rede e reduz a dependência de serviços externos, promovendo maior estabilidade.

Este serviço API estabelece uma infraestrutura confiável para uma variedade de aplicações de IA, desde sistemas de atendimento ao cliente inteligentes até ferramentas de geração de conteúdo e sistemas de consulta de conhecimento. É recomendável otimizar os parâmetros do modelo com base nos requisitos da aplicação e implementar um robusto sistema de monitoramento e manutenção para garantir a longevidade e eficiência do serviço.

Tags: Ollama FastAPI Python LLM Cogito

Publicado em 8-1 06:28