Initial ForgeLM import

This commit is contained in:
Evandro Fonseca Junior committed 2026-03-29 19:10:57 -03:00
commit a392b9dc60
4296 files changed
+1212675

No files matched your search

+101
View File
@@ -0,0 +1,101 @@
# Configuracao do servidor
Esta pagina resume a configuracao atual do backend local do ForgeLM.
## Variaveis de ambiente principais
### Modelo e bind
- `LOCALLLM_MODEL` - caminho do arquivo `.gguf` a ser carregado
- `LOCALLLM_ADDR` - endereco de bind do servidor, default `0.0.0.0:8080`
- `LOCALLLM_MODEL_ALIASES` - aliases separados por virgula para o modelo canonico
### Perfil de runtime
- `LOCALLLM_PROFILE` - `balanced_9b`, `cpu_fallback` ou default `Turbo4B`
- `LOCALLLM_GPU_LAYERS`
- `LOCALLLM_CTX`
- `LOCALLLM_BATCH`
- `LOCALLLM_UBATCH`
- `LOCALLLM_THREADS`
- `LOCALLLM_THREADS_BATCH`
Esses campos sobrepoem os defaults do perfil selecionado.
## Perfis conhecidos
### Turbo4B
- `n_gpu_layers = 999`
- `n_ctx = 4096`
- `n_batch = 512`
- `n_ubatch = 128`
- `flash_attn = true`
- `n_threads = 8`
### Balanced9B
- `n_gpu_layers = 999`
- `n_ctx = 2048`
- `n_batch = 256`
- `n_ubatch = 64`
- `flash_attn = true`
- `n_threads = 8`
### CpuFallback
- `n_gpu_layers = 0`
- `n_ctx = 2048`
- `n_batch = 128`
- `n_ubatch = 32`
- `flash_attn = false`
- `n_threads = available_parallelism()`
## Auth
- `LOCALLLM_API_KEY` - habilita auth por chave quando definido
- `LOCALLLM_AUTH_HEADER` - nome do cabecalho preferencial; default `authorization`
- `LOCALLLM_AUTH_SCHEME` - prefixo opcional para remover antes da comparacao
Se `LOCALLLM_API_KEY` estiver vazio ou ausente, a API funciona sem auth para `GET /v1/models` e `POST /v1/chat/completions`.
## CORS
- `LOCALLLM_CORS_ORIGINS` - lista separada por virgula
Comportamento atual:
- sem configuracao explicita, o servidor libera `*`
- quando a variavel existe, o backend constroi uma allowlist literal
## Prompt de sistema e tool calling
- `LOCALLLM_SYSTEM_PROMPT` - prompt de sistema default injetado quando a request nao traz mensagem `system` ou `developer`
- `LOCALLLM_ENABLE_TOOL_CALLS` - habilita/desabilita tool calling no servidor
## Exemplo de ambiente minimo
```bash
set LOCALLLM_MODEL=D:\modelos\meu-modelo.gguf
set LOCALLLM_ADDR=0.0.0.0:8080
cargo run -p inference-server
```
## Exemplo com auth
```bash
set LOCALLLM_MODEL=D:\modelos\meu-modelo.gguf
set LOCALLLM_API_KEY=dev-secret
set LOCALLLM_AUTH_SCHEME=Bearer
cargo run -p inference-server
```
## Alias de modelos
Quando `LOCALLLM_MODEL_ALIASES` esta definido, o backend expoe aliases adicionais em `GET /v1/models`. Esses aliases apontam para o mesmo `root` do modelo canonico e sao resolvidos pelo backend durante a validacao do campo `model`.
## Observacoes operacionais
- o banner do servidor imprime `127.0.0.1:<porta>` como endereco recomendado para consumo local quando o bind usa `0.0.0.0`
- o app Tauri usa readiness por `GET /health` ao iniciar o runtime local
- o backend nao persiste configuracao propria em arquivo; a persistencia de runtime local do app acontece no backend Tauri, nao dentro do `inference-server`
+225
View File
@@ -0,0 +1,225 @@
# Endpoints HTTP
Esta pagina documenta a superficie HTTP publica atual do ForgeLM.
## Base URL
- default de bind: `0.0.0.0:8080`
- endereco recomendado para consumo local: `http://127.0.0.1:8080`
Quando esta documentacao usa `127.0.0.1`, ela esta descrevendo o endereco tipico de consumo local, nao necessariamente o bind literal do processo.
## GET /health
Retorna um snapshot simples do estado do processo.
### Auth
- nao exige auth
### Exemplo
```bash
curl http://127.0.0.1:8080/health
```
### Resposta
```json
{
"status": "ok",
"model_loaded": true,
"model_id": "meu-modelo",
"uptime_secs": 42
}
```
### Observacoes
- hoje `model_loaded` funciona como um sinal operacional simples do processo em pe
- o app desktop usa `GET /health` como parte do readiness check do runtime local
## GET /v1/models
Lista o modelo canonico e aliases conhecidos.
### Auth
- exige auth apenas se `LOCALLLM_API_KEY` estiver configurada
### Cabecalhos aceitos
- `Authorization: Bearer <token>`
- `x-api-key: <token>`
- ou o cabecalho custom configurado em `LOCALLLM_AUTH_HEADER`
### Exemplo
```bash
curl http://127.0.0.1:8080/v1/models
```
### Resposta
```json
{
"object": "list",
"data": [
{
"id": "default",
"object": "model",
"created": 1710000000,
"owned_by": "local",
"root": "meu-modelo",
"parent": "meu-modelo",
"permission": []
}
]
}
```
### Observacoes
- `root` aponta para o modelo canonico
- `parent` e usado quando um ID e alias do modelo canonico
- o app desktop usa esse endpoint para preencher o seletor de modelo
## POST /v1/chat/completions
Endpoint principal de inferencia.
### Auth
- exige auth apenas se `LOCALLLM_API_KEY` estiver configurada
### Campos principais da request
```json
{
"model": "default",
"messages": [
{ "role": "user", "content": "Explique este projeto" }
],
"max_tokens": 1024,
"temperature": 0.15,
"top_p": 0.95,
"stream": false,
"stop": [],
"n": 1,
"seed": null,
"user": null,
"response_format": null,
"tools": [],
"tool_choice": null,
"parallel_tool_calls": null,
"stream_options": null
}
```
### Defaults importantes
- `max_tokens`: `1024`
- `temperature`: `0.15`
- `top_p`: `0.95`
- `n`: `1`
### Regras de validacao
- `model` deve existir no catalogo de modelos
- `messages` nao pode ser vazio
- `n` precisa ser `1`
- `tools` podem ser rejeitadas se tool calling estiver desabilitado
### Exemplo sem streaming
```bash
curl http://127.0.0.1:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "default",
"messages": [{"role": "user", "content": "Diga ola"}],
"stream": false
}'
```
### Resposta sem streaming
```json
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1710000000,
"model": "meu-modelo",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Ola!"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 8,
"total_tokens": 20,
"tokens_per_second": 31.5
}
}
```
### Exemplo com streaming
```bash
curl http://127.0.0.1:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-N \
-d '{
"model": "default",
"messages": [{"role": "user", "content": "Escreva um resumo"}],
"stream": true,
"stream_options": {"include_usage": true}
}'
```
### Streaming SSE
O backend envia eventos `data: ...` no formato `chat.completion.chunk` e termina com:
```text
data: [DONE]
```
O ultimo chunk pode incluir `usage` se `include_usage=true`.
### Erros
Exemplo de payload de erro:
```json
{
"error": {
"message": "Only n=1 is currently supported",
"type": "invalid_request_error",
"param": "n",
"code": "unsupported_value"
}
}
```
### Limitacoes atuais
- o servidor nao implementa toda a plataforma OpenAI
- `parallel_tool_calls` nao deve ser tratado como recurso plenamente suportado
- o campo `content` de mensagens pode aceitar arrays de partes textuais, mas o backend reduz isso a texto consolidado
- reasoning nativo nao aparece como campo separado na API HTTP; o app desktop separa `<think>...</think>` no frontend
## Codigos de status mais comuns
- `200 OK` - sucesso
- `400 Bad Request` - payload invalido ou modo nao suportado
- `401 Unauthorized` - chave ausente/invalida quando auth esta habilitada
- `404 Not Found` - modelo nao encontrado
Para configuracao do servidor e variaveis de ambiente, veja `configuration.md`.
+121
View File
@@ -0,0 +1,121 @@
# 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`.