122 lines
4.5 KiB
Markdown
122 lines
4.5 KiB
Markdown
# Visao geral da API e backend
|
|
|
|
O backend do ForgeLM e um servidor HTTP local escrito em Rust, montado sobre Axum e conectado a uma engine de inferencia em `inference-core`.
|
|
|
|
## Componentes principais
|
|
|
|
- `crates/inference-server` - inicializacao do servidor, leitura de configuracao por variaveis de ambiente e roteamento HTTP
|
|
- `crates/api-contracts` - tipos de request/response para chat, health, models e erros
|
|
- `crates/inference-core` - engine, sessoes, perfis de runtime e sampler
|
|
- `crates/metrics` - contadores de throughput e metricas de geracao
|
|
|
|
## Endpoints publicos
|
|
|
|
Hoje o servidor expoe:
|
|
|
|
- `GET /health`
|
|
- `GET /v1/models`
|
|
- `POST /v1/chat/completions`
|
|
|
|
Essa superficie e pequena de proposito: o foco atual do projeto esta em chat local, descoberta de modelos e integracao com o runtime manager do app.
|
|
|
|
## Inicializacao do servidor
|
|
|
|
O binario principal do backend esta em `crates/inference-server/src/main.rs`.
|
|
|
|
Na inicializacao, o servidor:
|
|
|
|
1. configura tracing/logs
|
|
2. le variaveis de ambiente como `LOCALLLM_MODEL`, `LOCALLLM_PROFILE`, `LOCALLLM_ADDR`, `LOCALLLM_GPU_LAYERS` e `LOCALLLM_CTX`
|
|
3. cria a configuracao da engine a partir do perfil selecionado
|
|
4. carrega e aquece o modelo (`warmup()`)
|
|
5. monta o router com CORS e estado compartilhado
|
|
6. faz bind no endereco configurado e serve as rotas HTTP
|
|
|
|
## Perfil de runtime
|
|
|
|
Os perfis atuais ficam em `crates/inference-core/src/profile.rs`:
|
|
|
|
- `Turbo4B` - foco em throughput, contexto moderado e uso de GPU agressivo
|
|
- `Balanced9B` - equilibrio entre qualidade e custo
|
|
- `CpuFallback` - fallback para maquinas sem GPU
|
|
|
|
Esses perfis definem defaults como `n_gpu_layers`, `n_ctx`, `n_batch`, `n_ubatch`, `flash_attn` e `n_threads`.
|
|
|
|
## Auth e CORS
|
|
|
|
A configuracao de compatibilidade HTTP mora em `crates/inference-server/src/compat.rs`.
|
|
|
|
- auth e opcional; se `LOCALLLM_API_KEY` nao estiver configurada, a API aceita requests sem chave
|
|
- `GET /health` nao passa por verificacao de auth
|
|
- `GET /v1/models` e `POST /v1/chat/completions` passam por `authorize_request()`
|
|
- CORS aceita `*` por default ou uma lista configuravel por `LOCALLLM_CORS_ORIGINS`
|
|
|
|
Cabecalhos aceitos para auth:
|
|
|
|
- cabecalho configurado em `LOCALLLM_AUTH_HEADER` (default: `authorization`)
|
|
- `Authorization`
|
|
- `x-api-key`
|
|
|
|
Se `LOCALLLM_AUTH_SCHEME` estiver configurado, o backend tenta remover esse prefixo antes de comparar a chave.
|
|
|
|
## Catalogo de modelos
|
|
|
|
O backend monta um catalogo de modelos em memoria a partir do nome canonico do modelo carregado e de aliases opcionais configurados por `LOCALLLM_MODEL_ALIASES`.
|
|
|
|
Regras importantes:
|
|
|
|
- o modelo carregado vira o ID canonico principal
|
|
- aliases adicionais podem apontar para o mesmo `root`
|
|
- `local-model` e `default` entram como aliases comuns quando possivel
|
|
- `GET /v1/models` retorna tanto o canonico quanto os aliases conhecidos
|
|
|
|
## Chat completions
|
|
|
|
O endpoint de chat aceita mensagens em formato semelhante ao da OpenAI, com suporte para:
|
|
|
|
- roles `system`, `developer`, `user`, `assistant` e `tool`
|
|
- `stream: true|false`
|
|
- `stop` como string unica, array de strings ou `null`
|
|
- `response_format`
|
|
- `tools` e `tool_choice`
|
|
- `stream_options.include_usage`
|
|
|
|
O servidor, porem, continua com escopo limitado. Alguns campos sao aceitos por compatibilidade de contrato, mas isso nao significa paridade total com a plataforma OpenAI.
|
|
|
|
## Streaming
|
|
|
|
No modo `stream`, o backend usa SSE e envia chunks no formato `chat.completion.chunk`.
|
|
|
|
Dois modos de streaming existem internamente:
|
|
|
|
- `LiveTokens` - emite tokens incrementais quando o fluxo suporta token streaming
|
|
- `Buffered` - produz a resposta inteira e a entrega em blocos compativeis
|
|
|
|
O chunk final pode incluir `usage` quando `stream_options.include_usage=true`.
|
|
|
|
## Erros e validacao
|
|
|
|
Os erros seguem `ErrorResponse { error: ApiError }` com:
|
|
|
|
- `message`
|
|
- `type`
|
|
- `param` opcional
|
|
- `code` opcional
|
|
|
|
Validacoes conhecidas:
|
|
|
|
- `model` inexistente retorna `model_not_found`
|
|
- `messages` vazia retorna `empty_messages`
|
|
- `n != 1` retorna `unsupported_value`
|
|
- `tools` com tool calls desabilitadas retorna `tool_calls_disabled`
|
|
|
|
## Limitacoes atuais
|
|
|
|
- nao ha endpoints publicos para embeddings, uploads, files ou responses API
|
|
- `n` diferente de `1` nao e suportado
|
|
- `response_format` e tool calling passam por compatibilidade de prompt/pos-processamento, nao por enforcement forte de decoder
|
|
- `parallel_tool_calls` existe no contrato, mas nao deve ser tratado como capacidade plena documentada
|
|
- `GET /health` e um health check operacional; nao e uma prova profunda de qualidade do modelo
|
|
|
|
Para referencia detalhada de requests e respostas, siga para `endpoints.md` e `configuration.md`.
|