Initial ForgeLM import
This commit is contained in:
commit
a392b9dc60
4296 files changed
+1212675
No files matched your search
@@ -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`
|
||||
@@ -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`.
|
||||
@@ -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`.
|
||||
Reference in new issue
Block a user