CyberPaul commited on
Commit
04a8382
·
verified ·
1 Parent(s): 16052e8

feat: README moderno — remove legado, foca em v1.0.0 production

Browse files
Files changed (1) hide show
  1. README.md +111 -1078
README.md CHANGED
@@ -6,7 +6,6 @@
6
 
7
  <p align="center"><em>ratio decidendi</em> — o raciocínio jurídico por trás das decisões</p>
8
 
9
-
10
  <p align="center">
11
  <em>Inteligência jurídica com seus dados sob seu controle.</em><br/>
12
  <strong>100% local • 100% offline • 100% confidencial</strong>
@@ -30,8 +29,6 @@ O **RATIO** é um sistema de RAG (Retrieval-Augmented Generation) jurídico, **l
30
 
31
  ## 🚀 v1.0.0 — Lançamento Oficial (Agosto 2026)
32
 
33
- O RATIO está oficialmente em produção com:
34
-
35
  | Componente | Status | URL |
36
  |------------|:------:|-----|
37
  | **Software Desktop** | ✅ | `RATIO_Setup_v1.0.exe` |
@@ -60,222 +57,70 @@ O RATIO está oficialmente em produção com:
60
 
61
  ## 🤖 IA Treinada — Classificador de Ratio Decidendi
62
 
63
- O RATIO agora conta com **IA própria treinada no direito brasileiro** e publicada no HuggingFace:
64
-
65
  | | |
66
  |---|---|
67
  | **Modelo** | [`CyberPaul/ratio-bert-jurisprudencia-pt`](https://huggingface.co/CyberPaul/ratio-bert-jurisprudencia-pt) |
68
  | **Base** | BERTimbau (`neuralmind/bert-base-portuguese-cased`) |
69
  | **Tarefa** | Classificação binária: a sentença é *ratio decidendi* ou não? |
70
- | **Dados** | 20.266 sentenças balanceadas de 634.368 acórdãos do STJ e STF (+51 negativos difíceis curados) |
71
- | **F1-Score** | **99,55%** (em sentenças) — estimativa honesta de 93–97% em documentos inéditos |
72
- | **Precisão / Recall** | 99,29% / 99,81% |
73
  | **Licença** | Apache 2.0 |
74
- | **Treinamento** | Local — RX 6600 XT via DirectML, ~5h |
75
 
76
  ### 🛡️ Filtro de qualidade no pipeline
77
 
78
- O classificador é integrado como **guardião de qualidade** da extração
79
- (`processors/bert_ratio_filter.py` — `BertRatioFilter`): cada sentença extraída é
80
- validada e cabeçalhos, relatórios, votações e dados processuais são removidos.
81
- Roda em lotes de 32 sentenças com detecção automática de device
82
- (**DirectML → CUDA → CPU**), aproveitando inclusive GPUs AMD (ex: RX 6600 XT) —
83
- e até CPUs, já que o modelo tem apenas ~440MB.
84
-
85
- ### 🔄 Pipeline de dados → treino → publicação
86
-
87
- ```bash
88
- # 1. Extrair ratio decidendi dos acórdãos (com filtro BERT de qualidade)
89
- python scripts/mvp_ratio_pipeline.py --full --bert-filtro --export jsonl
90
-
91
- # 2. Converter o dataset para o formato ChatML
92
- python scripts/preparar_finetune.py --output data/dataset_ratio_v3
93
-
94
- # 3. Treinar o classificador (DirectML/CUDA/CPU)
95
- python scripts/train_ratio.py --modo bert --full
96
-
97
- # 4. Publicar no HuggingFace (token no .env: HF_TOKEN)
98
- python scripts/publicar_modelo.py
99
-
100
- # 5. Manutenção do repositório (remove checkpoints intermediários)
101
- python scripts/limpar_repo_hf.py --confirm
102
- ```
103
-
104
- > 🔑 O token do HuggingFace é lido do `.env` (`HF_TOKEN`) — nunca hardcoded em código.
105
- > 🌐 Os pesos do classificador são baixados **uma única vez** na instalação do modelo; depois disso, toda inferência é 100% local/offline.
106
 
107
  ---
108
 
109
- ## 🧠 Fine-Tune Generativo — RATIO v8.2 + Gate (✅ APROVADO)
110
-
111
- Além do classificador BERT, o RATIO tem um **LLM generativo próprio** para
112
- respostas jurídicas nativas, baseado no **gemma3:4b**. O **v8.1** é o modelo
113
- aprovado, combinando fine-tune com **gate arquitetural** para abstenção.
114
 
115
  | | |
116
  |---|---|
117
  | **Base** | `unsloth/gemma-3-4b-it-bnb-4bit` (QLoRA 4-bit) |
118
- | **Dataset v8.1** | 1.259 exemplos (700 RAG + 200 abstenção + 249 adversariais + 10 controle) — [`CyberPaul/ratio-dataset-v8.1`](https://huggingface.co/datasets/CyberPaul/ratio-dataset-v8.1) |
119
- | **Dicionário Jurídico** | 4.273 termos brasileiros (`core/dicionario_juridico.py`) — busca exata + fuzzy |
120
- | **Local de treino** | Kaggle (T4 ×2, 3 épocas, MAX_SEQ_LEN 2048) |
121
- | **LoRA publicado** | [`CyberPaul/ratio-gemma3-4b-lora-v8`](https://huggingface.co/CyberPaul/ratio-gemma3-4b-lora-v8) (277 MB) |
122
- | **GGUF publicado** | [`CyberPaul/ratio-gemma3-4b-gguf-v8`](https://huggingface.co/CyberPaul/ratio-gemma3-4b-gguf-v8) (Q4_K_M 2.49 GB + F16 0.85 GB) |
123
- | **Modelo no Ollama** | `ratio-v8.2` (criado via `ollama create`) |
124
  | **Gate arquitetural** | `scripts/gate_rag.py` — intercepta armadilhas antes do LLM |
125
 
126
- ### 📊 Protocolo de Avaliação — Resultado
127
-
128
- O v8.2 é aprovado com **gate arquitetural** (Suite A + Suite B + Smoke Test):
129
-
130
- | Métrica | v8 (LEGACY) | Produção (v3) | **v8.2 + Gate** | Threshold | Status |
131
- |---------|:---:|:---:|:---:|:---:|:---:|
132
- | A1 Faithfulness | 0.987 | 0.985 | **0.983** | ≥ 0.85 | ✅ |
133
- | A2 Citation Accuracy | 0.987 | 0.947 | **0.997** | ≥ 0.90 | ✅ ⬆️ |
134
- | A3 Unsupported Claims | 0.071 | 0.091 | **0.058** | ≤ 0.10 | ✅ ⬇️ |
135
- | A4 Tese Extraction | 0.990 | 1.000 | **0.995** | ≥ 0.80 | ✅ |
136
- | A5 Format Compliance | 1.000 | 1.000 | **1.000** | ≥ 0.90 | ✅ |
137
- | B1 Hallucination Rate | 0.000 | 0.020 | **0.000** | ≤ 0.10 | ✅ |
138
- | B3 Utility Score | 0.980 | 0.960 | **0.940** | ≥ 0.70 | ✅ |
139
 
140
- > **Gate: ✅ APROVADO PARA PRODUÇÃO** — Suite A (100/100) + Suite B (50/50) + Smoke Test (10/10 com gate)
 
 
 
 
 
 
141
 
142
- ### 🛡️ Gate Arquitetural — Abstenção Sob Pressão Adversarial
143
-
144
- O modelo 3.9B (Q4_K_M) não aprende abstenção via fine-tuning quando
145
- a pergunta é adversária (processo ou súmula específico sem documento).
146
- O `gate_rag.py` resolve isso na **arquitetura**:
147
-
148
- ```
149
- Usuário → Gate (regex) → [bloqueado?] → Resposta de abstenção
150
- ↓ [não bloqueado]
151
- LLM (ratio-v8.2)
152
- ↓
153
- garantir_fonte() → Fonte: STJ.
154
- ```
155
-
156
- | Teste | Resultado |
157
- |---|---|
158
- | Falsos positivos (perguntas legítimas) | **25/25 ✅** |
159
- | Cobertura (variações de armadilha) | **23/23 ✅** |
160
- | Smoke test (10 perguntas) | **10/10 ✅ · 0 alertas** |
161
-
162
- > 📖 **Arquitetura completa:** [`ARQUITETURA_V8.md`](ARQUITETURA_V8.md) — Seção 7
163
-
164
- #### O que o dataset grounded resolveu
165
-
166
- O problema central do v7 era **alucinação** — o modelo inventava citações,
167
- processos e súmulas mesmo quando não tinha documento. O v8 resolve isso com:
168
-
169
- 1. **Dataset grounded**: `{pergunta, ementa, metadados}` como input (não só `{pergunta}`)
170
- 2. **Exemplos de abstenção**: 20% do dataset ensina o modelo a **não** inventar fonte
171
- 3. **Split por hash**: zero vazamento entre treino e holdout
172
- 4. **System prompt anti-alucinação**: condicional (com/sem documento)
173
-
174
- > 📖 **Protocolo completo:** [`scripts/eval/README_PROTOCOLO_V8.md`](scripts/eval/README_PROTOCOLO_V8.md)
175
- > 🏗️ **Arquitetura:** [`ARQUITETURA_V8.md`](ARQUITETURA_V8.md) — diagnóstico do v7, dataset grounded, lições aprendidas
176
- > 📋 **Relatório detalhado:** [`RELATORIO_PROTOCOLO_V8_20260818.md`](RELATORIO_PROTOCOLO_V8_20260818.md)
177
 
178
  ### Deploy no Ollama
179
 
180
  ```bash
181
- # 1. Baixar o GGUF do HuggingFace
182
- python scripts/upload_hf.py --repo CyberPaul/ratio-gemma3-4b-gguf-v8 --download
183
-
184
- # 2. Criar o modelo no Ollama
185
- ollama create ratio-v8 -f Modelfile-v8
186
-
187
- # 3. Confirmar
188
- ollama list | grep ratio-v8
189
  ```
190
 
191
- ### Treino (Kaggle)
192
-
193
- ```bash
194
- # Preparar dataset
195
- python scripts/preparar_dataset_v8.py --ementas data/ementas_reais.jsonl --output data/ratio_dataset_v8/
196
-
197
- # Subir pro HuggingFace
198
- python scripts/upload_hf.py --repo CyberPaul/ratio-dataset-v8 --token-file "Token Write.txt"
199
-
200
- # Rodar no Kaggle: ver INSTRUCOES_KAGGLE_V8.md
201
- ```
202
-
203
- > 📓 **Notebook Kaggle:** [`RATIO_TREINO_GEMA3_Kaggle_V8.ipynb`](RATIO_TREINO_GEMA3_Kaggle_V8.ipynb)
204
- > 📋 **Instruções:** [`INSTRUCOES_KAGGLE_V8.md`](INSTRUCOES_KAGGLE_V8.md)
205
-
206
- > ⚠️ Versões anteriores (v3–v7) foram experimental e **não aprovadas** no gate.
207
- > O v8 é o primeiro modelo fine-tune aprovado para produção.
208
- > O que se reaproveita é o **dataset** e a receita. O repo do Qwen
209
- > (`CyberPaul/ratio-qwen-7b-gguf-v2`) está marcado como **LEGACY/experimental**;
210
- > o repo duplicado `ratio-qwen-7b-final` foi removido em 08/2026.
211
- >
212
- > ✅ O dataset publicado (`CyberPaul/ratio-dataset-v3`) foi testado com
213
- > `load_dataset(...)` — 8.501 exemplos com roles system/user/assistant corretos.
214
- > O **v4** (pares pergunta-resposta sintetizados, sem cópia) será publicado como
215
- > `CyberPaul/ratio-dataset-v4` — os notebooks de treino já apontam para ele
216
- > (override via env `RATIO_DS_REPO`).
217
-
218
- ---
219
-
220
- ## 🛠️ Manutenção do perfil HuggingFace (auditar → limpar)
221
-
222
- O perfil `CyberPaul` é gerido por **duas ferramentas complementares** em `scripts/`:
223
-
224
- | Ferramenta | Função | Segurança |
225
- |---|---|---|
226
- | `auditar_repos_hf.py` | **Auditoria read-only** — lista modelos/datasets/spaces com tamanho real, downloads, datas e **flag de repo privado** | Não altera nada |
227
- | `limpar_repos_hf.py` | **Limpeza** — remove repos/arquivos obsoletos (ex.: duplicados, quantizações pesadas de modelos LEGACY) | **Dry-run por padrão**; só executa com `--confirm` |
228
-
229
- ```bash
230
- # 1. Auditar (visão completa do perfil)
231
- python scripts/auditar_repos_hf.py # relatório em texto
232
- python scripts/auditar_repos_hf.py --json # saída JSON (para scripts/CI)
233
-
234
- # 2. Limpar (só depois de auditar e decidir o que remover)
235
- python scripts/limpar_repos_hf.py # dry-run: mostra o plano, não executa
236
- python scripts/limpar_repos_hf.py --confirm # executa de verdade
237
- ```
238
-
239
- > 📌 **Estado do perfil (30/08/2026):** modelos públicos no HuggingFace:
240
- > - `CyberPaul/ratio-gemma3-4b-lora-v8` + `CyberPaul/ratio-gemma3-4b-gguf-v8` — **✅ APROVADO (v8.1 + gate)**
241
- > - `CyberPaul/ratio-dataset-v8.1` — dataset v8.1 (1.259 exemplos com adversariais)
242
- > - `CyberPaul/ratio-bert-jurisprudencia-pt` — classificador BERT (F1 99,55%)
243
- > - `CyberPaul/ratio-dataset-v8` — dataset v8 original (LEGACY)
244
- > - `CyberPaul/ratio-gemma3-4b-lora` + `ratio-gemma3-4b-gguf` — LEGACY (v1–v7, experimental)
245
- > - `CyberPaul/ratio-qwen-7b-gguf-v2` — LEGACY (Qwen, mantido só como registro)
246
-
247
  ---
248
 
249
  ## 🌐 Landing Page Comercial
250
 
251
- A landing page comercial do RATIO está online em **[ratio.singularislabs.com.br](https://ratio.singularislabs.com.br/)**. O código-fonte está na pasta `landing-page/RATIOlanding2/`:
252
 
253
- - **Verificador de Compatibilidade de Hardware** — sliders de RAM/VRAM + seletor de SO que recomendam a configuração e o modelo de IA ideais
254
- - **Showcase da IA treinada** — métricas reais (99,55% F1), pipeline e CTA para o modelo no HuggingFace
255
- - **Planos, FAQ (com busca/filtro) e Trial** — tudo pronto para conversão
256
  - **SEO otimizado** — meta tags, Open Graph e conteúdo semântico
257
 
258
- ### 🧪 Testes da landing page (Vitest + Testing Library)
259
 
260
- A landing page possui **36 testes automatizados em 5 arquivos**, com cobertura real de **~91%** e thresholds de cobertura configurados em `vite.config.ts` (prontos para uso como guarda no CI):
261
 
262
  ```bash
263
  cd landing-page/RATIOlanding2
264
- npm test # suíte completa (36 testes)
265
- npm run test:watch # modo watch
266
- npm run test:coverage # relatório de cobertura
267
  ```
268
 
269
- | Arquivo de teste | Testes | Valida |
270
- |---|---|---|
271
- | `constants.test.ts` | 5 | Paridade `SECTION_IDS`↔`NAV_ANCHORS`, URL HF derivada do ID |
272
- | `ScaleLabels.test.tsx` | 5 | Posicionamento dos ticks, highlight, alinhamento de bordas |
273
- | `HardwareCalculator.test.tsx` | 12 | Slider→badge, VRAM no macOS, links HF, troca de SO, recomendação do fine-tune (ratio-gemma3:4b) |
274
- | `ModelShowcase.test.tsx` | 7 | Métricas, pipeline (4 passos), CTAs Classificador + LLM (GGUF), honestidade científica |
275
- | `FaqSection.test.tsx` | 7 | Busca, filtros, accordion, callback do trial |
276
-
277
- > 📖 Guia de execução do servidor: [`landing-page/RATIOlanding2/GUIA_SERVER.md`](landing-page/RATIOlanding2/GUIA_SERVER.md)
278
-
279
  ---
280
 
281
  ## 🎯 Planos e Preços
@@ -304,126 +149,50 @@ Na primeira execução, o RATIO cria automaticamente uma licença **TRIAL de 14
304
 
305
  ### 🔒 Privacidade Primeiro
306
  - **100% offline** — Seus documentos nunca saem do seu computador
307
- - **Sem APIs de terceiros** — Todo processamento é local via Ollama + modelos locais (transformers)
308
  - **LGPD compliant** — Arquitetura desenhada para conformidade desde a fundação
309
  - **Hardware binding** — Licença vinculada à máquina, sem risco de uso não autorizado
310
 
311
  ### 🧠 RAG Jurídico Inteligente
312
- - **Busca Híbrida** — Combinação de busca semântica vetorial + BM25 para precisão máxima em terminologia jurídica
313
- - **Chunking Semântico Jurídico** — Divisão inteligente por Artigos, Parágrafos, Incisos e Cláusulas
314
  - **Streaming Token a Token** — Respostas em tempo real via WebSocket
315
- - **Citação de Fontes** — Toda resposta inclui referência exata ao documento e página
316
- - **Filtro BERT de Ratio Decidendi** — IA própria que valida cada sentença extraída (99,55% F1), removendo cabeçalhos, relatórios e votações
317
 
318
  ### 📄 Ingestão Multi-Formato
319
  - **PDF** (texto nativo + OCR para escaneados)
320
  - **DOCX, XLSX, PPTX** (Word, Excel, PowerPoint)
321
  - **Imagens** (PNG, JPG — OCR automático)
322
  - **URLs e YouTube** (web scraping e transcrição automática)
323
- - **Google Drive** (importação via OAuth2 —PDFs, DOCXs e TXTs)
324
- - **OneDrive** (importação via OAuth2 — PDFs, DOCXs e TXTs)
325
 
326
  ### 🖥️ Interface Premium
327
- - **Onboarding interativo** — Wizard de 5 passos na primeira execução (inclui download do modelo de IA)
328
  - **Visualizador de PDF** com highlight automático da página citada
329
  - **Chat com streaming** e cards de fonte clicáveis
330
- - **Exportação de consultas em PDF** para arquivamento
331
  - **Tema dark/light** — Alternável com um clique
332
- - **Indicador de status** — Ollama, prontidão do modelo (Frio/Pronto com botão de aquecimento ⚡), modelo ativo e licença visíveis na navbar
333
 
334
  ---
335
 
336
  ## 🏗️ Arquitetura
337
 
338
- > 📖 Detalhes da arquitetura do fine-tune generativo v8: [`ARQUITETURA_V8.md`](ARQUITETURA_V8.md)
339
-
340
  ```text
341
  Projeto RATIO/
342
- │
343
- ├── core/ # Núcleo do sistema
344
- │ ├── auth.py # Autenticação por API Key (timing-safe)
345
- │ ├── license.py # 🆕 Sistema de licenciamento (trial, ativação, validação)
346
- │ ├── chunker.py # Chunking semântico jurídico customizado
347
- │ ├── document_store.py # Gestão de bases + indexação ChromaDB
348
- │ ├── ingestor.py # Extrator multi-formato (PDF, DOCX, imagens, URLs, Google Drive, OneDrive)
349
- │ ├── rag_engine.py # Pipeline RAG completo com streaming
350
- │ └── retriever.py # Busca híbrida (vetorial + BM25)
351
- │
352
- ├── engine/ # Motor de inferência
353
- │ ├── llm_client.py # Cliente Ollama + detecção de modelo + warmup() + monitor de integridade
354
- │ ├── modelo_installer.py # 🆕 Download/instalação de modelos com progresso (wizard 1º uso)
355
- │ └── exportador.py # Exportação de conversas em PDF (ReportLab)
356
- │
357
- ├── processors/ # 🆕 Processadores de extração e filtragem
358
- │ ├── ratio_extractor.py # Extrator de ratio decidendi por tribunal (STF/STJ/TJSP/TRF2)
359
- │ └── bert_ratio_filter.py # 🆕 Filtro BERT (99,55% F1) — valida sentença a sentença
360
- │
361
- ├── scripts/ # 🆕 Pipeline de dados, treino e publicação
362
- │ ├── mvp_ratio_pipeline.py # Extrai datasets (--bert-filtro ativa o filtro de qualidade)
363
- │ ├── preparar_finetune.py # Converte dataset instruction → ChatML
364
- │ ├── train_ratio.py # Fine-tuning BERTimbau (DirectML/CUDA/CPU)
365
- │ ├── publicar_modelo.py # Publica o modelo no HuggingFace
366
- │ ├── limpar_repo_hf.py # Limpa checkpoints intermediários do repositório
367
- │ ├── readme_ratio.py # README canônico do modelo publicado
368
- │ ├── testar_modelo_publicado.py # Smoke test de inferência do modelo publicado
369
- │ ├── subir_dataset_hf.py # 🆕 Sobe dataset p/ HF (v3 por padrão; v4 via --repo/--data)
370
- │ ├── validar_token_hf.py # 🆕 Valida o HF_TOKEN (env > .env) sem expor o valor
371
- │ ├── deploy_gguf_ollama.py # 🆕 Baixa o GGUF do fine-tune e cria o modelo no Ollama
372
- │ ├── gerar_notebook_colab.py # 🆕 Converte o script de treino em .ipynb para o Colab
373
- │ ├── atualizar_repos_gguf.py # 🆕 Atualiza README + Modelfile (corrigido) dos repos GGUF no HF
374
- │ ├── atualizar_readme.py # 🆕 Publica o README canônico do fine-tune no HuggingFace
375
- │ ├── auditar_repos_hf.py # 🆕 Auditoria read-only do perfil (tamanho, DL, privado, status)
376
- │ ├── limpar_repos_hf.py # 🆕 Limpeza de repos HF obsoletos (dry-run + --confirm)
377
- │ └── _hf_token.py # 🆕 Helper compartilhado de token (env > .env)
378
- │
379
- ├── script_treino_gemma3_colab.txt # 🆕 Treino do gemma3:4b no Colab (Unsloth + QLoRA + GGUF)
380
- │
381
- ├── models/ # 🆕 Checkpoints e modelos treinados
382
- │ └── ratio-gemma3/ # 🆕 GGUF + Modelfile do fine-tune (deployado: ratio-gemma3:4b)
383
- │
384
- ├── frontend/ # Interface do usuário
385
- │ ├── src/
386
- │ │ ├── components/
387
- │ │ │ ├── OnboardingWizard.tsx # 🆕 Wizard de primeira execução (5 passos)
388
- │ │ │ ├── ModelSetupWizard.tsx # 🆕 Download/instalação do modelo (progresso via WebSocket)
389
- │ │ │ ├── HealthStatus.tsx # 🆕 Indicador de status (Ollama + prontidão + licença)
390
- │ │ │ ├── ChatInterface.tsx # Chat com streaming + fontes
391
- │ │ │ ├── DocumentViewer.tsx # Visualizador PDF com highlight
392
- │ │ │ ├── UploadZone.tsx # Upload drag-and-drop multi-formato
393
- │ │ │ ├── HelpModal.tsx # Ajuda + dicionário jurídico
394
- │ │ │ └── SourceCard.tsx # Card de fonte com score de relevância
395
- │ │ ├── config.ts # 🆕 Configurações centralizadas (API Key, URLs)
396
- │ │ ├── warmup.ts # 🆕 Pré-aquecimento do modelo (botão + automático)
397
- │ │ ├── hooks/ # Hooks globais (useTema)
398
- │ │ └── App.tsx # Layout 3 colunas + integração onboarding
399
- │ └── package.json
400
- │
401
- ├── tests/ # Testes automatizados
402
- │ ├── test_api.py
403
- │ ├── test_chunker.py
404
- │ ├── test_ingestor.py
405
- │ ├── test_retriever.py
406
- │ ├── test_bert_filter.py # 🆕 Testes do filtro BERT (mocks, sem download)
407
- │ ├── test_license.py # 🆕 26 testes do sistema de licenças (trial, ativação, validação, API)
408
- │ └── test_llm_client.py # Seleção automática (gemma3:4b em 1º) + monitor ciente da fonte
409
- │
410
- ├── api.py # Ponto de entrada FastAPI (HTTP + WebSocket)
411
- ├── Makefile # Comandos de automação
412
- ├── data_collection/ # 🆕 Coletores STF/STJ/TST + formatação de dataset
413
- ├── iniciar.bat # 🆕 Execução com 1 clique (Ollama + backend + frontend)
414
- ├── iniciar_backend.bat # 🆕 Launcher do backend (define RATIO_MODELO)
415
- ├── restart_backend.ps1 # 🆕 Reinício confiável (kill por porta + assert do modelo)
416
- ├── setup_ratio.bat # 🆕 Setup rápido do ambiente
417
- ├── build_ratio.bat # 🆕 Build do instalador (frontend + PyInstaller + setup.iss)
418
- ├── installer/ # 🆕 Instalador moderno (Inno Setup 6.3+)
419
- │ ├── setup.iss.tpl # Template: wizard moderno + página de compatibilidade de hardware
420
- │ ├── gerar_setup_iss.py # Renderiza dist/RATIO/setup.iss (+ gera o .ico do logo)
421
- │ └── instalar_inno.bat # Baixa o Inno Setup 6 e compila o instalador .exe
422
- ├── license-server/ # 🆕 Central de Licenças (webhook Hotmart, emails, painel)
423
- │ ├── README.md # Setup, deploy e API da Central de Licenças
424
- │ └── app/ # FastAPI + SQLite + scheduler de renovações
425
- ├── commercial/ # 🆕 Vendas: guia Hotmart + proposta comercial
426
- └── .env # Variáveis de ambiente
427
  ```
428
 
429
  ---
@@ -432,13 +201,11 @@ Projeto RATIO/
432
 
433
  ### 🖥️ Compatibilidade
434
 
435
- | Sistema Operacional | Status | Método de Instalação | Guia |
436
- |---------------------|:------:|----------------------|------|
437
- | **Windows 10/11** | ✅ Suportado | Instalador (.exe) — Inno Setup 6.3+ | `RATIO_Setup_v1.0.exe` |
438
- | **macOS 12+** | ✅ Suportado | Script de instalação (bash) | [`README_INSTALL_MAC.md`](installer/README_INSTALL_MAC.md) |
439
- | **Linux** | ✅ Suportado | Script de instalação (bash) | [`README_INSTALL_LINUX.md`](installer/README_INSTALL_LINUX.md) |
440
-
441
- > **Navegador:** O RATIO abre automaticamente no navegador padrão do sistema (Chrome, Edge, Firefox ou Safari). Não é necessário instalar navegador separado. Funciona em qualquer navegador moderno (Chrome 90+, Edge 90+, Firefox 90+, Safari 15+).
442
 
443
  ### 🔧 Setup Automático (Recomendado)
444
 
@@ -448,15 +215,6 @@ Projeto RATIO/
448
  | **macOS** | `chmod +x install_mac.sh && ./install_mac.sh` |
449
  | **Linux** | `chmod +x install_linux.sh && ./install_linux.sh` |
450
 
451
- Os scripts verificam e instalam automaticamente:
452
-
453
- O script verifica e instala:
454
- 1. ✅ Python 3.10+
455
- 2. ✅ Node.js 18+
456
- 3. ✅ Dependências Python (pip install -r requirements.txt)
457
- 4. ✅ Dependências do Frontend (npm install)
458
- 5. ✅ Ollama (com opção de baixar modelo recomendado)
459
-
460
  ### ⚙️ Setup Manual
461
 
462
  #### 1. Pré-requisitos
@@ -464,869 +222,144 @@ O script verifica e instala:
464
  - **Python 3.10+** — [python.org](https://python.org)
465
  - **Node.js 18+** — [nodejs.org](https://nodejs.org)
466
  - **Ollama** — [ollama.com](https://ollama.com)
467
- - **Tesseract OCR** (opcional, para OCR em PDFs escaneados)
468
 
469
  #### 2. Configurar Backend
470
 
471
  ```bash
472
- # Instalar dependências
473
- make install
474
- # ou
475
  pip install -r requirements.txt
476
-
477
- # Configurar variáveis de ambiente
478
  copy .env.example .env
479
  ```
480
 
481
- Edite o arquivo `.env`:
482
 
483
  ```ini
484
  RATIO_API_KEY=sua_chave_secreta_aqui
485
- RATIO_AUTH_ENABLED=true # true = auth ativa (false para dev local)
486
  OLLAMA_BASE_URL=http://localhost:11434
487
- RATIO_MODELO=gemma3:4b # modelo ativo (padrão atual — ver "Modelo de IA")
488
- RATIO_NUM_CTX=4096 # janela de contexto (4K basta para RAG e é mais rápido em CPU)
489
  RATIO_HOST=127.0.0.1
490
  RATIO_PORT=8000
491
- HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxx # (opcional) usado para publicar/baixar modelos do HuggingFace
492
- RATIO_LICENSE_SERVER=https://api.singularislabs.com.br # (opcional) Central de Licenças — ativação online
493
- ```
494
-
495
- > 💡 **Filtro BERT:** para usar o filtro de qualidade, instale também `transformers` e `torch` (o pipeline funciona sem eles — o filtro é opcional via `--bert-filtro`).
496
-
497
- #### 3. Configurar Frontend
498
-
499
- ```bash
500
- cd frontend
501
- npm install
502
- cd ..
503
  ```
504
 
505
- #### 4. Executar
506
 
507
- **Método recomendado (1 clique):** execute `iniciar.bat` — ele sobe o Ollama, o backend e o frontend e abre o navegador.
508
 
509
- **Modo manual (desenvolvimento):**
510
 
511
  ```bash
512
- # Terminal 1 — Backend (porta 8000)
513
- make run-api
514
-
515
- # Terminal 2 — Frontend (porta 5173)
516
- make run-frontend
517
  ```
518
 
519
- > 💡 `make run-api` usa `--reload` e é um comando de **desenvolvimento**. Para
520
- > uso diário, prefira `iniciar.bat` (execução com 1 clique) ou
521
- > `restart_backend.ps1` (reinício confiável sem `--reload`).
522
-
523
  Acesse: **http://localhost:5173** 🎉
524
 
525
- Na **primeira execução**, o wizard de **onboarding** aparecerá automaticamente guiando você por:
526
- - Verificação do ambiente
527
- - Download/instalação do modelo de IA (se nenhum estiver instalado)
528
- - Ativação de licença (ou trial grátis)
529
- - Criação da primeira base de conhecimento
530
-
531
- ---
532
-
533
- ## 🛠️ Comandos
534
-
535
- | Comando | Descrição |
536
- |---------|-----------|
537
- | `setup_ratio.bat` | 🆕 Configuração completa do ambiente |
538
- | `build_ratio.bat` | 🆕 Build: frontend + PyInstaller + setup.iss (Inno moderno) |
539
- | `installer\instalar_inno.bat` | 🆕 Baixa o Inno Setup 6 e compila o instalador .exe |
540
- | `make install` | Instala dependências Python |
541
- | `make install-dev` | Instala deps de desenvolvimento (pytest, httpx) |
542
- | `make check-deps` | Diagnóstico do ambiente |
543
- | `run_tests.bat` | 🆕 Roda toda a suíte de testes (622 testes) com 1 clique |
544
- | `make run-api` | Inicia servidor FastAPI (porta 8000) |
545
- | `make run-frontend` | Inicia servidor Vite (porta 5173) |
546
- | `iniciar.bat` | 🆕 Execução com 1 clique (Ollama + backend + frontend + navegador) |
547
- | `restart_backend.ps1` | 🆕 Reinício confiável do backend (kill por porta + verificação do modelo) |
548
-
549
  ---
550
 
551
  ## 🔐 Licenciamento
552
 
553
  O RATIO tem licenciamento local (trial, ativação, hardware binding) com validação
554
- opcional contra a **Central de Licenças** (`license-server/`) — o servidor que
555
- recebe as vendas da Hotmart por webhook, emite as chaves, dispara os emails
556
- automáticos e controla renovações.
557
 
558
  ### Como funciona
559
 
560
  1. **Primeira execução** → Trial de 14 dias criado automaticamente
561
- 2. **Compra (Hotmart)** → webhook cria a licença e a chave é enviada por email (automático)
562
- 3. **Ativação** → inserir chave na tela de licenciamento ou via API (online no servidor, se configurado)
563
- 4. **Validação** → a cada inicialização, o sistema valida:
564
- - Integridade do arquivo de licença (checksum SHA256)
565
- - Vínculo com o hardware da máquina (MAC + username)
566
- - Data de expiração
567
-
568
- ### Central de Licenças (`license-server/`)
569
 
570
- O RATIO agora tem um servidor próprio de gestão de licenças:
571
 
572
  | Recurso | Detalhe |
573
  |---|---|
574
- | **Webhook Hotmart** | `POST /webhooks/hotmart` — venda cria licença, cancelamento/reembolso revoga, recorrência renova |
575
- | **Emails automáticos** | chave pro cliente · aviso de venda pro admin · lembrete de renovação (14/7/3/1 dias) com link de checkout |
576
- | **Ativação** | `POST /v1/activate` — valida chave + hardware, devolve payload assinado |
577
  | **Heartbeat** | `POST /v1/check` — vigência/revogação em tempo real |
578
- | **Painel admin** | `/admin` — vendas, receita mensal estimada, vencimentos, cadastro manual, ações |
579
-
580
- > 📖 **Guia de setup e deploy:** [`license-server/README.md`](license-server/README.md)
581
- > e o passo a passo completo de venda no [`commercial/hotmart-setup-guide.md`](commercial/hotmart-setup-guide.md).
582
-
583
- ### Ativação online (cliente)
584
-
585
- No `.env` do computador que roda o RATIO:
586
-
587
- ```ini
588
- RATIO_LICENSE_SERVER=https://api.singularislabs.com.br
589
- ```
590
-
591
- Com isso, a ativação valida contra o servidor (fonte da verdade: plano, vigência,
592
- revogação). **Se o servidor estiver inalcançável, o RATIO cai no fluxo local**
593
- (pelo prefixo da chave) — a ativação nunca trava por falta de internet.
594
-
595
- ### Tipos de licença e formato da chave
596
-
597
- O **prefixo da chave** define o plano (implementado em `core/license.py`):
598
-
599
- | Prefixo | Tipo | Duração | Principais recursos |
600
- |:-------:|------|:-------:|---------------------|
601
- | `S...` | SOLO | 365 dias | RAG completo, bases ilimitadas, export PDF, suporte prioritário |
602
- | `E...` | ESCRITÓRIO | 365 dias | Tudo do SOLO + multi-usuário + prompts customizados |
603
- | `P...` | ENTERPRISE | **Perpétuo** | Tudo do ESCRITÓRIO + acesso API + suporte dedicado |
604
-
605
- A licença é armazenada em `~/.ratio/license.json` e fica **vinculada ao hardware**
606
- (qualquer tentativa de copiar o arquivo para outra máquina é rejeitada).
607
-
608
- ### Ativação via API
609
-
610
- ```bash
611
- curl -X POST http://127.0.0.1:8000/api/license/activate \
612
- -H "Content-Type: application/json" \
613
- -H "X-API-Key: sua-chave" \
614
- -d '{"key": "S1234-56789-ABCDE-FGHIJ-KLMNO"}'
615
- ```
616
-
617
- ### Health Check
618
-
619
- ```bash
620
- curl http://127.0.0.1:8000/api/health \
621
- -H "X-API-Key: sua-chave"
622
- ```
623
-
624
- Resposta esperada:
625
- ```json
626
- {
627
- "status": "ok",
628
- "ollama": {"disponivel": true, "modelo_ativo": "gemma3:4b"},
629
- "bases": 3,
630
- "license": {"valid": true, "type": "SOLO", "days_remaining": 364},
631
- "versao": "1.0.0"
632
- }
633
- ```
634
-
635
- ### Verificar status da licença
636
 
637
- ```bash
638
- curl http://127.0.0.1:8000/api/license/status \
639
- -H "X-API-Key: sua-chave"
640
- ```
641
 
642
- ### Testes automatizados (26)
643
-
644
- O sistema de licenças é coberto por **26 testes automatizados** em
645
- [`tests/test_license.py`](tests/test_license.py) — trial, validação, detecção de
646
- adulteração, vínculo de hardware, ativação dos 3 planos, expiração e os endpoints
647
- HTTP. Os testes **nunca tocam a licença real** (usam pasta temporária):
648
-
649
- ```bash
650
- pytest tests/test_license.py -v
651
- ```
652
-
653
- > ✅ **Estado atual (08/2026):** a ativação agora valida contra a **Central de
654
- > Licenças** quando `RATIO_LICENSE_SERVER` está configurado (fonte da verdade para
655
- > plano, vigência e revogação), com **fallback local** pelo prefixo da chave
656
- > quando o servidor está inalcançável. O servidor é o que permite venda real:
657
- > chaves emitidas por webhook da Hotmart, revogação por cancelamento/reembolso e
658
- > lembretes de renovação automáticos.
659
-
660
- ---
661
-
662
- ## 📦 Distribuição
663
-
664
- ### Gerar Instalador Windows (moderno)
665
-
666
- ```bash
667
- build_ratio.bat :: 1) Frontend + PyInstaller + dist\RATIO\setup.iss
668
- installer\instalar_inno.bat :: 2) Baixa o Inno Setup 6 (se preciso) e compila o .exe
669
- ```
670
-
671
- O `build_ratio.bat`:
672
- 1. Compila o frontend (Vite build);
673
- 2. Empacota o backend com PyInstaller (incluindo o Modelfile do fine-tune);
674
- 3. Renderiza o **setup.iss moderno** (WizardStyle=modern, página de
675
- compatibilidade de hardware, ícone gerado do logo).
676
-
677
- > O instalador final sai em `dist\RATIO_Setup_v1.0.0.exe`. Requer **Inno Setup
678
- > 6.3+** — o `installer\instalar_inno.bat` baixa e instala automaticamente se
679
- > necessário. Detalhes na seção [🛠️ Instalador Moderno](#-instalador-moderno-inno-setup-63).
680
-
681
- ### 🔜 Alternativa: Docker (Em Breve)
682
-
683
- Para escritórios com equipe de TI, uma versão Docker será disponibilizada em breve.
684
- O deploy conteinerizado permitirá execução em servidores internos com:
685
- - Orquestração automática de serviços
686
- - Persistência de dados em volumes
687
- - Suporte a GPU para aceleração de inferência
688
 
689
  ---
690
 
691
  ## 🔒 Segurança e Privacidade
692
 
693
  - **LGPD compliant** — Dados nunca saem da máquina do usuário
694
- - **100% local** — Nenhum dado trafega para servidores externos (apenas metadados de licença na ativação, se houver Central de Licenças configurada)
695
  - **API Key timing-safe** — Comparação em tempo constante (`secrets.compare_digest`)
696
  - **WebSocket autenticado** — Validação de token no handshake
697
- - **Hardware binding** — Licença vinculada ao hardware, impedindo uso não autorizado
698
- - **Trial com Registry** — Histórico de trials no Windows Registry (sobrevive desinstalação)
699
- - **Grace period 72h** — Cache encriptado para funcionar offline quando servidor indisponível
700
  - **Rate limiting** — 5 tentativas de ativação por hora
701
- - **Upload limit** — Arquivos acima de 100 MB rejeitados (proteção DoS)
702
- - **Citation checker** — Verifica referências citadas pelo modelo contra o documento
703
  - **Gate arquitetural** — Intercepta perguntas que pedem confirmação de processo sem documento
704
- - **Report de bugs** — Sistema integrado com ID único e coleta automática de sistema
705
  - **Dashboard de segurança** — Monitoramento de tentativas de cracking em tempo real
706
 
707
- ## 🐛 Report de Bugs
708
-
709
- O RATIO tem um sistema integrado de report de bugs:
710
-
711
- 1. Clique no ícone 🐛 na navbar
712
- 2. Descreva o problema (obrigatório)
713
- 3. Adicione passos para reproduzir (opcional)
714
- 4. O sistema coleta info automaticamente (SO, versão, modelo, logs)
715
- 5. Envie — você recebe um ID único (ex: `RATIO-20260825-A3F2`)
716
-
717
- Os reports são salvos em `~/.ratio/bug_reports/` e podem ser enviados por email para suporte.
718
-
719
  ---
720
 
721
  ## 🧪 Testes
722
 
723
  ```bash
724
- # Instalar dependências de teste
725
- make install-dev
726
-
727
- # Executar toda a suíte (622 testes)
728
  pytest tests/ -v
729
 
730
  # Suíte completa com 1 clique (Windows)
731
  run_tests.bat
732
 
733
- # Testes do filtro BERT (com mocks, sem baixar modelo)
734
- pytest tests/test_bert_filter.py -v
735
-
736
- # Testes do sistema de licenças (26 testes, não tocam a licença real)
737
- pytest tests/test_license.py -v
738
-
739
- # Testes do citation checker (12 testes)
740
- pytest tests/test_citation_checker.py -v
741
-
742
- # Testes do fuzzy matching (23 testes)
743
- pytest tests/test_fuzzy_citations.py -v
744
-
745
- # Testes do detector de saudações (32 testes)
746
- pytest tests/test_saudacao.py -v
747
-
748
- # Testes do auto-update (28 testes)
749
- pytest tests/test_updater.py -v
750
- ```
751
-
752
- > 🧪 **Testes da landing page** (Vitest + Testing Library): veja a seção [Landing Page Comercial](#-landing-page-comercial) acima.
753
-
754
- ### 📋 Checklist de Produção v1.0.0
755
-
756
- | Item | Status | Versão |
757
- |------|:------:|--------|
758
- | Dataset v8.1 grounded | ✅ | v8.1 |
759
- | Fine-tune aprovado (Gate) | ✅ | v8.2 |
760
- | BERTimbau filter (99.55% F1) | ✅ | v8.2 |
761
- | Gate arquitetural (25/25 + 23/23) | ✅ | v8.2 |
762
- | Citation checker com fuzzy matching | ✅ | v8.2 |
763
- | Dicionário jurídico (4.273 termos) | ✅ | v8.2 |
764
- | Cloud storage (Google Drive/OneDrive) | ✅ | v8.2 |
765
- | Bug report integrado (ID único) | ✅ | v8.2 |
766
- | License-server com security dashboard | ✅ | v1.0 |
767
- | Wizard de instalação (Inno Setup) | ✅ | v8.2 |
768
- | Suite de testes completa (622 testes) | ✅ | v1.0 |
769
- | README HuggingFace atualizado | ✅ | v1.0 |
770
- | Landing page com 16 FAQs | ✅ | v8.2 |
771
- | Documentação completa | ✅ | v1.0 |
772
- | Hotmart (4 planos) | ✅ | v1.0 |
773
- | Google Search Console | ✅ | v1.0 |
774
- | Google Analytics 4 | ✅ | v1.0 |
775
- | Google Business Profile | ✅ | v1.0 |
776
- | SEO (7 páginas) | ✅ | v1.0 |
777
-
778
- ---
779
-
780
- ## 🧠 Modelo de IA e Solução de Problemas
781
-
782
- ### Modelo ativo (gemma3:4b)
783
-
784
- O modelo usado nas respostas do RAG é definido pela variável `RATIO_MODELO`,
785
- configurada no `iniciar_backend.bat`. O padrão atual é **`gemma3:4b`** (base
786
- oficial Google) — **correção de 06/08/2026** (ver "Fine-Tune Generativo").
787
-
788
- > 📌 **Fine-Tune `ratio-v8.2` (status 19/08/2026):** o fine-tune v8.1 **foi aprovado
789
- > no gate de avaliação completo** com gate arquitetural (`gate_rag.py`).
790
- > Suite A 100/100 + Suite B 50/50 + Smoke Test 10/10 (0 alertas).
791
- > O gate resolve a limitação de abstenção de modelos ≤4B params.
792
- > O `gemma3:4b` base responde corretamente e é o padrão; o
793
- > fine-tune está **fora da seleção automática** (catálogo como experimental;
794
- > testar: `RATIO_MODELO=ratio-gemma3:4b`).
795
-
796
- > ⚠️ **Importante (diagnóstico de 08/2026):** a **família qwen2.5 (7B)** produz
797
- > saída garbage nesta máquina (Ollama + backend AMD/RX 6600 XT). O arquivo GGUF
798
- > **não está corrompido** — o SHA-256 confere exatamente com o HuggingFace — mas a
799
- > **execução** falha (repetição de sílabas, ex.: "Respostaposta", "8888878").
800
- > Testes decisivos: gemma3:4b responde perfeitamente na mesma máquina, e até o
801
- > `qwen2.5:3b` **oficial** apresenta artefatos. **Re-baixar o modelo não resolve** —
802
- > é problema de execução da família qwen2.5 neste hardware/backend.
803
-
804
- ### Detecção automática de modelo
805
-
806
- Se `RATIO_MODELO` não estiver definido, o `engine/llm_client.py` seleciona o
807
- melhor modelo instalado em **3 passadas**:
808
- 1. Match exato contra a lista de preferidos;
809
- 2. Match por família (ex: `llama3.1` casa `llama3.1:8b-instruct`), com
810
- **denylist** que exclui modelos de código/embedding/visão (`coder`, `embed`,
811
- `vision`, `r1`, etc.);
812
- 3. Fallback para qualquer modelo instalado.
813
-
814
- Isso evita que um modelo de **código** (ex: `qwen2.5-coder:3b`) seja usado para
815
- perguntas jurídicas — problema que causava respostas incoerentes.
816
-
817
- ### Backend não responde ou modelo errado?
818
-
819
- Use o `restart_backend.ps1` — ele mata os processos do backend na porta
820
- `127.0.0.1:8000` (2 passadas, inclusive workers órfãos do `--reload`), confirma
821
- a porta livre, sobe o backend via `iniciar_backend.bat` e **verifica no
822
- `/api/health` que o `modelo_ativo` é o esperado**:
823
-
824
- ```powershell
825
- powershell -ExecutionPolicy Bypass -File restart_backend.ps1
826
  ```
827
 
828
- > ⚠️ O backend **não** deve ser iniciado com `--reload` (sem `watchfiles` o
829
- > reload não funciona e o processo reloader complica o reinício). O launcher
830
- > `iniciar_backend.bat` já cuida disso.
831
-
832
- ### RX 6600 XT / Vulkan (testado em 08/2026 — driver atualizado 05/08)
833
-
834
- O Vulkan **funciona e está estável** nesta RX 6600 XT. Com o driver AMD
835
- Adrenalin atualizado (05/08/2026), o Ollama 0.32.5+ enxerga os **7,2 GiB de
836
- VRAM livre** corretamente e o modelo `ratio-gemma3:4b` carrega **100% na GPU
837
- (35/35 camadas)** de forma reprodutível — 3/3 reinícios limpos.
838
-
839
- **A causa da antiga "instabilidade" era outra:** a cada kill do `ollama.exe`
840
- (ex.: `taskkill /F /IM ollama.exe`), os processos filhos `llama-server.exe`
841
- ficam **órfãos** segurando o modelo na VRAM (~1,6 GB cada). Reinícios
842
- acumulados devoravam a VRAM (11 órfãos ≈ 6,6 GB!), e o servidor novo reagia
843
- **corretamente** reduzindo o offload (13/35 e até 0/35 camadas) — não era
844
- falha de detecção nem do driver. **FIX:** limpar os órfãos ao reiniciar —
845
- `taskkill /F /IM llama-server.exe` (já embutido no `iniciar.bat` e no
846
- `scripts/testar_vulkan.ps1`).
847
-
848
- > ⚠️ **Dica:** se o RATIO estiver lento e o `/api/ps` mostrar offload parcial,
849
- > é sinal de VRAM ocupada (órfãos ou navegador com vídeo/3D aberto).
850
- > `taskkill /F /IM llama-server.exe` resolve na hora.
851
-
852
- Para conferir onde o modelo carregou:
853
-
854
- ```bash
855
- curl http://127.0.0.1:11434/api/ps # size_vram ≈ size → 100% GPU
856
- ```
857
-
858
- > ⚠️ **Cuidado:** o CLI `ollama ps` pode **travar indefinidamente** quando o
859
- > servidor está ocupado/travado no load — prefira a API HTTP `/api/ps`.
860
- > O aviso "AMD driver is too old" ainda aparece 1x no log de start — é quirk
861
- > de detecção de versão do `amd.go` do Ollama e **não afeta a inferência**.
862
- > Relatório completo do A/B: [`teste_ab_vulkan_20260805.txt`](teste_ab_vulkan_20260805.txt).
863
-
864
  ---
865
 
866
- ## ⚡ Otimização de Velocidade (benchmark 08/2026)
867
-
868
- Diagnóstico real na máquina de desenvolvimento (Ryzen 5 5600GT, 6c/12t, 31 GB
869
- RAM, Ollama 0.32.5) com contexto de ~874 tokens (típico do RAG):
870
-
871
- | Configuração | Prompt eval | Geração | Total |
872
- |---|---|---|---|
873
- | **Antes** (default 131072 ctx) | 239 tok/s | 13,6 tok/s | 7,15s |
874
- | **Depois** (`num_ctx 4096`) | **~4.700 tok/s** | **16,3 tok/s** | **3,10s** |
875
-
876
- Ganho medido: **-57% no tempo total** e **+20% na geração** — só com
877
- configuração, sem tocar em código ou modelo.
878
-
879
- > ⚠️ **Ressalva de confound:** a medição "Depois" rodou no servidor de longa
880
- > duração, que carregava o modelo **100% na GPU** — parte do salto de prompt
881
- > eval (239 → 4.700 tok/s) pode ter vindo do **offload GPU**, não só do
882
- > `num_ctx`. O `num_ctx 4096` continua sendo a configuração correta (evita KV
883
- > cache gigante), mas o ganho exato é difícil de isolar — o teste A/B abaixo
884
- > separa CPU vs GPU de forma controlada.
885
-
886
- ### Teste A/B: GPU Vulkan vs CPU (05/08/2026 — driver atualizado, VRAM livre)
887
-
888
- A/B completo com **medição sempre a frio** (`--keep-alive 0` → modelo
889
- descarregado a cada chamada; todas as rodadas válidas). Config de produção:
890
- KV cache `q4_0`, flash attention, `num_ctx 4096` (Modelfile).
891
-
892
- | Onde o modelo rodou | Prompt eval | Geração | Total (ctx 874) | VRAM usada |
893
- |---|---|---|---|---|
894
- | **CPU puro** (`OLLAMA_VULKAN=0`) | 61–70 tok/s | ~11 tok/s | ~25,7s | 0 / 2,75 GB |
895
- | **100% GPU** (Vulkan, KV f16) | ~312 tok/s | ~28 tok/s | ~9s | 2,75 / 2,75 GB |
896
- | **100% GPU** (Vulkan, prod q4_0+flash) | **~300–350 tok/s** | **~44–57 tok/s** | **~8s** | 2,75 / 2,75 GB |
897
-
898
- - **Ganho real**: prompt eval **~5x** (61–70 → ~330) **e** geração **~5x**
899
- (~11 → ~55) — contraria a conclusão antiga de que "a geração não melhora
900
- na GPU" (a medição antiga não era representativa: usava rodada quente, com
901
- KV cache reusada, e o prompt eval saía inflado).
902
- - **Tempo total (o que o usuário sente)**: ctx 874 → 25,7s → **~8s** (~3,2x);
903
- ctx 2000 → 56,8s → **~14s** (~4x).
904
- - **Estabilidade**: 3/3 reinícios limpos com 35/35 camadas (desde que não
905
- haja `llama-server` órfãos nem navegador com vídeo/3D consumindo VRAM).
906
- - Ferramentas: `scripts/benchmark_modelo.py` (medição, com `--keep-alive 0`)
907
- e `scripts/testar_vulkan.ps1` (A/B automático CPU vs GPU, mata órfãos).
908
-
909
- ### O que foi feito (e o que NÃO fazer)
910
-
911
- 1. **`PARAMETER num_ctx 4096` no Modelfile** (`models/ratio-gemma3/Modelfile`)
912
- — o default do Gemma3 é 131.072 tokens de contexto, que alocava uma KV
913
- cache gigante desnecessária em RAM. Fixar em 4096 (igual ao
914
- `RATIO_NUM_CTX` do backend) eliminou o desperdício e acelerou o prompt
915
- eval drasticamente. O modelo foi recriado com `ollama create`.
916
-
917
- 2. **`OLLAMA_KEEP_ALIVE=30m` no `iniciar.bat`** — mantém o modelo carregado
918
- entre perguntas (evita reload de ~2s a cada chamada).
919
-
920
- 3. **NÃO mexa em `num_thread`/`num_batch`** — o benchmark provou que
921
- overrides **pioram** o desempenho (12,6–13,7 tok/s + ~8s de reload por
922
- mudança). O padrão do Ollama 0.32.5 já é o ótimo para esta CPU. O gargalo
923
- real é banda de memória do processador, não configuração.
924
-
925
- ### Como reproduzir a medição
926
-
927
- ```bash
928
- # Benchmark padrão (ratio-gemma3:4b, ~874 tokens de contexto, 2 rodadas)
929
- python scripts/benchmark_modelo.py
930
-
931
- # Contexto maior (simula RAG longo)
932
- python scripts/benchmark_modelo.py --ctx 3000
933
-
934
- # Testar outros modelos / configurações
935
- python scripts/benchmark_modelo.py --modelo gemma3:4b --rodadas 3
936
- python scripts/benchmark_modelo.py --threads 6 # demonstra que override piora
937
- ```
938
-
939
- > 💡 **GPU Vulkan (RX 6600 XT):** com o driver atualizado (05/08/2026) e sem
940
- > órfãos do `llama-server` na VRAM, o modelo carrega 100% na GPU de forma
941
- > estável: prompt eval ~330 tok/s (vs ~61–70 em CPU, **~5x**) e geração ~55
942
- > tok/s (vs ~11, **~5x**) — o gargalo do RAG cai de ~26s para ~8s por resposta.
943
- > Se estiver lento, confira `/api/ps` e limpe órfãos com
944
- > `taskkill /F /IM llama-server.exe`. Ver seção "RX 6600 XT / Vulkan" acima.
945
- > Outros caminhos: encurtar o prompt do RAG no `core/rag_engine.py` (menos
946
- > chunks por pergunta) e quantização Q4_0 (com leve perda de qualidade).
947
-
948
- ---
949
-
950
- ## 🔥 Prontidão do Modelo e Pré-Aquecimento (08/2026)
951
-
952
- O RATIO usa **lazy loading** do Ollama: o modelo só entra na VRAM quando a
953
- primeira pergunta chega (~3s de cold start). Para o usuário não ser pego de
954
- surpresa — e para eliminar esse atraso — o frontend ganhou um **indicador de
955
- prontidão** na navbar e um **sistema duplo de pré-aquecimento**.
956
-
957
- ### Badge de prontidão (navbar)
958
-
959
- | Estado | Badge | Significado |
960
- |---|---|---|
961
- | 🥶 **Frio** | 🌡️ âmbar + botão ⚡ | Modelo descarregado — a próxima pergunta paga ~3s de carga |
962
- | 🔥 **Pronto** | 🔥 verde | Modelo carregado na VRAM — respostas rápidas (~0,4s) |
963
-
964
- - O badge consulta `/api/health` a cada **30s** (o backend devolve
965
- `modelo_quente` e `modelo_expira_em` lendo o `/api/ps` do Ollama).
966
- - **Re-check imediato:** quando uma resposta do chat termina (WebSocket), o
967
- badge re-verifica na hora — sem esperar o polling — e vira "Pronto".
968
- Se o modelo já estiver quente, o re-check é **pulado** (zero chamadas
969
- redundantes) e o indicador "..." só aparece na primeira verificação.
970
- - **Tooltip:** passar o mouse sobre o badge "Frio" abre um tooltip que
971
- explica o que o botão ⚡ faz (pré-carrega na VRAM, elimina o atraso da
972
- primeira pergunta e descarrega sozinho após 30 min sem uso).
973
-
974
- ### Como aquece (3 mecanismos)
975
-
976
- 1. **🔥 Backend startup** — 1s após iniciar o RATIO, o `api.py` dispara
977
- `llm.warmup()` em background (fire-and-forget). Elimina o cold start
978
- da primeira pergunta real.
979
- 2. **🔥 Automático ao selecionar base** — trocar de coleção é o sinal mais
980
- forte de que o usuário vai perguntar; o `App.tsx` dispara o warmup
981
- (fire-and-forget) assim que a base muda.
982
- 3. **🔥 Botão ⚡ na navbar** — manual: aquece antes de selecionar base, ou
983
- re-aquece após os 30 min de inatividade sem trocar de base.
984
-
985
- ### API
986
-
987
- ```bash
988
- # Aquece o modelo ativo (chamada mínima de geração, keep_alive 30m)
989
- curl -X POST http://127.0.0.1:8000/api/warmup -H "X-API-Key: sua-chave"
990
- # → { "success": true, "modelo": "gemma3:4b", "load_s": 3.09 }
991
-
992
- # Health com prontidão
993
- curl http://127.0.0.1:8000/api/health -H "X-API-Key: sua-chave"
994
- # → "ollama": { "disponivel": true, "modelo_quente": true,
995
- # "modelo_expira_em": "2026-08-06T03:49:00Z", ... }
996
- ```
997
-
998
- - **Implementação:** `engine/llm_client.py` (`warmup()` + `health_check()`
999
- com `/api/ps`), `api.py` (`POST /api/warmup`), `frontend/src/warmup.ts`
1000
- (helper compartilhado), `HealthStatus.tsx` (badge + botão + tooltip
1001
- Radix) e `App.tsx` (auto-warmup ao trocar de base).
1002
- - **Testes:** 2 novos em `tests/test_api.py` (sucesso + falha tratada sem
1003
- 500). A suíte passou de 62 para **77 testes**.
1004
-
1005
- ---
1006
-
1007
- ## 🛠️ Instalador Moderno (Inno Setup 6.3+)
1008
-
1009
- O `build_ratio.bat` agora gera um **instalador profissional** (template em
1010
- [`installer/setup.iss.tpl`](installer/setup.iss.tpl), renderizado por
1011
- [`installer/gerar_setup_iss.py`](installer/gerar_setup_iss.py)):
1012
-
1013
- | Recurso | Detalhe |
1014
- |---|---|
1015
- | **Wizard moderno** | `WizardStyle=modern` (estilo Windows 11) — compilado com **zero warnings** no ISCC 6.7 |
1016
- | **Compatibilidade de hardware** | Página customizada (Pascal Script) que verifica **RAM** (API física), **disco** (espaço para app + modelo), **Windows** (build ≥ 19041), **GPU/VRAM** (PowerShell/Get-CimInstance) e **Ollama** — itens em verde/vermelho; abaixo do mínimo exige confirmação do usuário para continuar |
1017
- | **Ícone de marca** | `image/RATIO_Logo.ico` gerado automaticamente do logo PNG (Pillow, multi-tamanho) |
1018
- | **Instalação por usuário** | `PrivilegesRequired=lowest` — sem UAC; eleva só se o usuário escolher Program Files |
1019
- | **Download do modelo** | **Não** no instalador: acontece no wizard de 1º uso do app (escolha do usuário, progresso bonito, medição de VRAM real) |
1020
- | **Limpeza** | Desinstalador mata os processos do RATIO; os dados do usuário ficam em `%LOCALAPPDATA%\RATIO` (preservados na desinstalação) |
1021
-
1022
- ### Gerar o instalador
1023
-
1024
- ```bat
1025
- build_ratio.bat :: 1) Frontend + PyInstaller + dist\RATIO\setup.iss
1026
- installer\instalar_inno.bat :: 2) Baixa o Inno Setup 6 (se preciso) e compila o .exe
1027
- ```
1028
-
1029
- > O instalador final (`.exe`) sai em `dist\RATIO_Setup_v1.0.0.exe` (**~138 MB**,
1030
- > compilado com Inno Setup 6.7, zero warnings). Requer **Inno Setup 6.3+**
1031
- > (recursos `WizardStyle`/`ExecAndCaptureOutput`/`GetWindowsVersionEx`).
1032
-
1033
- ### Validado de ponta a ponta (08/2026)
1034
-
1035
- O executável standalone (`RATIO.exe`) e o instalador passaram por **E2E
1036
- completo contra o binário real**:
1037
-
1038
- | Etapa | Resultado |
1039
- |---|---|
1040
- | Inicialização | `Uvicorn running` — ChromaDB/SQLite OK (sem `CRITICAL ERROR`) |
1041
- | `/api/health` | 200 — Ollama + catálogo + licença |
1042
- | Criar base | 200 — coleção ChromaDB criada |
1043
- | Upload PDF | 200 — **10 chunks com embeddings ONNX** (MiniLM) dentro do exe |
1044
- | Query WebSocket | Fontes recuperadas (score ~1.0) + tokens do LLM + evento fim |
1045
- | `pytest tests/` | **622/622 passando** |
1046
-
1047
- **Bugs de empacotamento corrigidos durante a compilação:**
1048
-
1049
- 1. **`api.py` sem `__main__`** — o PyInstaller executa `api.py` como script
1050
- principal e terminava sem subir o servidor (o dev sempre rodou `uvicorn api:app`).
1051
- Agora existe `if __name__ == "__main__": uvicorn.run(app, ...)` passando o
1052
- **objeto `app`** (a string `"api:app"` não resolve dentro do bundle — o módulo
1053
- vira `__main__`).
1054
- 2. **ChromaDB → `ProtocolResolver.SYSTEM cannot be loaded`** — o chromadb 1.4 usa
1055
- `niquests`/`urllib3_future` como cliente HTTP, e o resolver `.system` é
1056
- carregado via `importlib` dinâmico (invisível ao PyInstaller). Fix:
1057
- `--collect-submodules urllib3_future niquests` + hidden-imports dos resolvers
1058
- nos **dois namespaces** (`urllib3_future.contrib.resolver.*` e o alias
1059
- `urllib3.contrib.resolver.*`).
1060
- 3. **numpy 2.x `_core._exceptions`** — o hook antigo não coleta o subpacote
1061
- `_core`; `--collect-submodules numpy` resolve.
1062
- 4. **Embeddings ONNX ausentes** — `onnxruntime`/`tokenizers`/`tqdm` são imports
1063
- dinâmicos do chromadb; sem eles a **ingestão quebra no 1º upload**. Fix:
1064
- `--collect-all onnxruntime`. O modelo ONNX MiniLM é baixado uma única vez
1065
- na 1ª ingestão.
1066
- 5. **`build_ratio.bat` — comentários `::` dentro do comando `pyinstaller`**
1067
- (linhas continuadas com `^`) eram passados como **argumentos literais** ao
1068
- PyInstaller e quebravam o build. Todos os comentários foram movidos para
1069
- **antes** do comando — validado com teste real de parsing do cmd.
1070
-
1071
- **Redução de tamanho:** o bundle de ~2,87 GB (com torch/transformers) caiu para
1072
- **415 MB** com as exclusões (`--exclude-module` de torch, transformers, spacy,
1073
- cv2, pandas, PySide6, matplotlib, etc. — libs usadas só em treino ou deps
1074
- opcionais do chromadb). O instalador final tem **~138 MB** (compressão LZMA2).
1075
-
1076
- ---
1077
-
1078
- ## 🩹 Correção da Tela Preta do Dashboard (06/08/2026)
1079
-
1080
- Ao abrir o RATIO instalado, o dashboard aparecia **preto/vazio**. Investigação
1081
- com navegador real (Chrome headless + dev server) revelou **4 causas**, todas
1082
- corrigidas e validadas:
1083
-
1084
- 1. **Bug crítico no frontend (TDZ) — a causa da "tela preta" pura.** Em
1085
- `frontend/src/components/ChatInterface.tsx`, o `useCallback` de
1086
- `verificarProntidao` usava `apiKey` no array de dependências **antes** da
1087
- declaração `const apiKey = API_KEY` (que vinha depois) → `ReferenceError:
1088
- Cannot access 'apiKey' before initialization` → o React derrubava a UI
1089
- inteira. **O bug existia desde o início — a UI nunca tinha sido testada em
1090
- navegador (os E2E eram via API).** Fix: `apiKey` declarada no topo do
1091
- componente (o dev server expõe o erro com arquivo/linha exatos;
1092
- `Cannot access 'X' before initialization` no bundle minificado era o mesmo
1093
- bug).
1094
- 2. **Frontend não era servido pelo executável.** O `api.py` não tinha rota
1095
- `/` nem `StaticFiles` — o bundle instalado incluía a UI, mas ninguém a
1096
- servia (em dev o Vite roda na 5173). Fix: `api.py` agora monta
1097
- `frontend/dist` (`StaticFiles` com `html=True`), resolvendo o caminho no
1098
- dev e no bundle PyInstaller (`_MEIPASS`), com override `RATIO_FRONTEND_DIR`.
1099
- 3. **Chave de API incompatível.** Sem `.env`, o backend gera **chave
1100
- temporária por sessão**, mas o frontend mandava a chave hardcoded
1101
- `desenvolvimento_local_key` → 401 em todas as chamadas. Fix: novo endpoint
1102
- público `GET /api/session` (restrito a **loopback** — o RATIO é local) que
1103
- devolve a chave da sessão; o frontend a busca em `carregarApiKey()`
1104
- (`config.ts`) **antes de renderizar** (`main.tsx`).
1105
- 4. **Diretório de dados em Program Files.** `DATA_DIR` era `./data` (relativo
1106
- ao CWD); instalado em Program Files sem admin, a gravação falhava →
1107
- `CRITICAL ERROR` e o backend **morria no boot**. Fix: empacotado →
1108
- `%LOCALAPPDATA%\RATIO\data` (gravável por usuário comum); dev mantém
1109
- `./data`; override `RATIO_DATA_DIR`.
1110
-
1111
- 5. **Corrida de boot (gap coberto após revisão crítica).** Se o usuário
1112
- abrisse o navegador enquanto o backend ainda subia (~35s no instalado),
1113
- a busca da chave falhava e ficava no fallback → 401 até refresh manual.
1114
- Fix: `carregarApiKey()` agora **re-tenta com backoff** (14× 2,5s ≈ 35s)
1115
- em background e dispara o evento `ratio:api-key-pronta` — o `App.tsx`
1116
- recarrega bases/health com a chave correta quando ela chega. O
1117
- `/api/session` também passou a validar o **header `Host`** (defesa extra
1118
- contra DNS rebinding — além do IP de peer loopback).
1119
-
1120
- **Bônus de build:** removido o `manualChunks` do pdf-viewer no
1121
- `vite.config.ts` (o `pdfjs-dist` tem ciclos internos que quebram a ordem de
1122
- avaliação quando forçado para um chunk separado). E o `gerar_setup_iss.py`
1123
- ganhou o override `RATIO_DIST_DIR` (útil quando `dist/RATIO` está
1124
- temporariamente bloqueado por watcher/antivírus no Windows).
1125
-
1126
- **Validação em navegador real (06/08/2026):** `GET /` servindo `index.html` ✓
1127
- · `/api/session` devolvendo a chave da sessão ✓ · assets (logo + bundle) 200 ✓
1128
- · base criada via API listada na sidebar ✓ · header "Ratio Decidendi Engine"
1129
- ✓ · **zero erros de console** ✓. `pytest tests/` continua **622/622**.
1130
-
1131
- ---
1132
-
1133
- ## 🩺 Monitor de Integridade (sessões longas)
1134
-
1135
- **Sobre a pergunta da "dissonância cognitiva":** LLMs **não têm** dissonância
1136
- cognitiva humana (não há self persistente nem crenças em conflito), mas
1137
- apresentam **fenômenos reais de degradação** em sessões longas (horas de uso
1138
- direto): contexto saturado, repetição de tokens, e — o mais comum no RATIO —
1139
- **degradação de recursos** (órfãos do `llama-server` ocupando VRAM, vazamento
1140
- de memória, offload parcial). O RATIO monitora **sinais mensuráveis** e avisa o
1141
- usuário:
1142
-
1143
- | Sinal | Como é medido | Limiar |
1144
- |---|---|---|
1145
- | `velocidade_baixa` | tok/s de geração (`eval_duration`/`eval_count` do Ollama) em janela rolante de 20 | média das últimas 3 < **50% da mediana** (mín. 5 amostras — mediana evita falso positivo por outlier) |
1146
- | `repeticoes` | fração de trigramas de palavras repetidos no texto da resposta | ≥ **0.12** |
1147
- | `offload_parcial` | `/api/ps`: `size_vram` < 90% do `size` no modelo ativo | qualquer amostra |
1148
-
1149
- ### Como aparece para o usuário
1150
-
1151
- - Banner vermelho no chat: *"Desempenho do modelo degradado — [sinais]"* com
1152
- botão **"Reiniciar modelo"** (`POST /api/reiniciar-modelo`: descarrega com
1153
- `keep_alive=0` e recarrega — limpa KV cache e estado do `llama-server`;
1154
- zera a linha de base de estatísticas).
1155
- - O `/api/health` devolve o bloco `saude` (`degradado`, `sinais`, `tok_s_atual`,
1156
- `tok_s_baseline`, `taxa_repeticoes`, `vram_uso_gb`...).
1157
-
1158
- ### Correção de qualidade de geração (06/08/2026 — causa raiz encontrada)
1159
-
1160
- O usuário relatou resposta **repetitiva** para `"Qual o propósito do direito?"`
1161
- com o banner de degradação. Reprodução completa via WebSocket (mesma base,
1162
- mesma pergunta) revelou a cadeia real:
1163
-
1164
- 1. **CAUSA RAIZ: overfit de cópia do fine-tune `ratio-gemma3:4b`** — o dataset
1165
- de treino ensinou o padrão "copie o texto longo do prompt" (respostas
1166
- reproduziam a ementa verbatim); com system ou texto longo, o modelo ecoa/
1167
- copia em vez de responder (7 testes A/B — ver
1168
- [`DIAGNOSTICO_FINETUNE_20260806.md`](DIAGNOSTICO_FINETUNE_20260806.md)).
1169
- O `gemma3:4b` base não tem esse defeito.
1170
- 2. **A repetição observada vinha da FONTE copiada** — o documento recuperado
1171
- (glossário jurídico) contém a cláusula repetida duas vezes no próprio
1172
- verbete; o modelo (fiel demais) copiava o trecho, e o monitor marcava como
1173
- degradação um texto que era fidelidade ao documento.
1174
- 3. **Duplicação de processos ao abrir o `iniciar.bat` duas vezes** — o
1175
- `iniciar.bat` tentava subir um 2º Ollama (erro `bind: address already
1176
- in use` na janela "RATIO Ollama") e um 2º backend na porta 8000
1177
- (`Errno 10048` na janela "RATIO Backend").
1178
-
1179
- | Correção | Detalhe |
1180
- |---|---|
1181
- | **Modelo padrão → `gemma3:4b` (base)** | fine-tune removido da seleção automática (`MODELOS_PREFERIDOS`) — o base responde corretamente (sintetiza e cita fontes); fine-tune segue experimental no catálogo |
1182
- | **Monitor ciente da fonte** | `taxa_repeticao_nao_explicada()` — repetição que EXISTE no contexto recuperado (fidelidade) não dispara o banner; só loop/amplificação fora da fonte é degradação |
1183
- | **Regra 7 reforçada** | proibida transcrição de trechos (>10 palavras) — resposta com palavras próprias, começando pela resposta direta |
1184
- | **Temperatura 0.5 + repeat_penalty 1.2 + num_predict 2048** | mantidos (defensivos para qualquer modelo) |
1185
- | **Pre-flight em `iniciar.bat`/`iniciar_backend.bat`** | portas 11434 (Ollama), 8000 (backend) e 5173 (frontend): se já ativos, reutiliza a instância existente em vez de subir outra (erros `bind: address already in use`/`Errno 10048` eliminados) |
1186
-
1187
- Validado de ponta a ponta (mesma pergunta, mesma base): resposta **sintetizada
1188
- com citação de fontes** ✓ · repetição bruta 0.128 (fonte-aware **0.0** → banner
1189
- **não** dispara) ✓ · `modelo_ativo: gemma3:4b` no exe instalado ✓ · `pytest`
1190
- **622/622** ✓.
1191
-
1192
- > 💡 Se o aviso persistir com `offload_parcial`, a VRAM está ocupada — feche
1193
- > navegador com vídeo/3D e limpe órfãos: `taskkill /F /IM llama-server.exe`
1194
- > (ver seção "RX 6600 XT / Vulkan").
1195
-
1196
- ---
1197
-
1198
- ## 🤖 Wizard de Modelo (1º uso)
1199
-
1200
- Se o Ollama estiver online mas **nenhum modelo instalado**, o RATIO oferece o
1201
- download dentro do app (onboarding passo **"Modelo de IA"** + banner flutuante):
1202
-
1203
- | Modelo | Tipo | Tamanho | Descrição |
1204
- |---|---|---|---|
1205
- | `ratio-v8.2` | GGUF do HuggingFace + `ollama create` | ~2,5 GB | **✅ APROVADO** — fine-tune v8.1 + gate arquitetural |
1206
- | `ratio-v8` | GGUF legado | ~2,5 GB | Fine-tune v8 sem gate — **LEGACY** (substituído pelo v8.1) |
1207
- | `gemma3:4b` | `ollama pull` | ~3,3 GB | Base oficial Google (fallback) |
1208
- | `ratio-gemma3:4b` | GGUF legado | ~2,5 GB | Fine-tune v1–v7 — **LEGACY** (experimental) |
1209
-
1210
- - **API:** `GET /api/modelo/catalogo` · `POST /api/modelo/instalar`
1211
- (ou mensagem WS `instalar_modelo`) · progresso em tempo real via eventos
1212
- `modelo_progresso` (etapa + percentual + MB).
1213
- - O GGUF é salvo em **`~/.ratio/models`** (gravável mesmo com o RATIO em
1214
- Program Files) e o `ollama create` usa o Modelfile do fine-tune.
1215
- - Guarda anti-duplicidade: uma instalação em andamento não é repetida.
1216
- - Implementação: [`engine/modelo_installer.py`](engine/modelo_installer.py) +
1217
- [`frontend/src/components/ModelSetupWizard.tsx`](frontend/src/components/ModelSetupWizard.tsx).
1218
-
1219
- ---
1220
-
1221
- ## 🌡️ Aviso de Modelo Frio no Chat
1222
 
1223
- Ao enviar uma pergunta com o modelo **não carregado** na VRAM, o chat exibe na
1224
- área de streaming: *"Modelo frio — carregando na VRAM. A primeira resposta
1225
- leva ~3s a mais."* O aviso some assim que o primeiro token chega (o modelo
1226
- carregou). Combina com o badge de prontidão da navbar e o botão ⚡ de
1227
- pré-aquecimento (seção acima).
 
 
 
1228
 
1229
  ---
1230
 
1231
- ## 🛡️ Defesas contra Alucinação (v8.1)
1232
-
1233
- O RATIO opera com **5 camadas de defesa** contra alucinação de referências
1234
- jurídicas:
1235
-
1236
- | Camada | Componente | O que faz |
1237
- |---|---|---|
1238
- | **1** | Dataset Grounded | Modelo aprende a ler antes de responder |
1239
- | **2** | System Prompt | Regra #8: "NUNCA cite artigo fora do documento" |
1240
- | **3** | Gate Arquitetural | Regex bloqueia processo/súmula sem documento |
1241
- | **4** | Interceptação de Saudações | "Oi"/"Olá" não invocam RAG |
1242
- | **5** | Citation Checker | Pós-verificação: detecta + marca resposta |
1243
-
1244
- ### Interceptação de Saudações
1245
-
1246
- Quando o usuário digita apenas uma saudação ("Oi", "Olá", "Bom dia"),
1247
- o RATIO responde com orientação **sem invocar o modelo**:
1248
-
1249
- ```
1250
- Usuário: "Oi"
1251
- RATIO: "Olá! Sou o RATIO... carregue um documento jurídico."
1252
- ```
1253
-
1254
- Isso evita que o modelo gere análise jurídica com referências inventadas
1255
- para saudações simples. Detector de regex com **21 padrões** (PT + EN).
1256
-
1257
- ### Citation Checker com Gravidade
1258
-
1259
- Ap cada resposta RAG, o citation checker verifica se as referências
1260
- citadas (artigo, REsp, súmula) existem no documento:
1261
-
1262
- ```
1263
- gravidade = "nenhuma" → zero alucinações
1264
- | "leve" → 1-2 artigos genéricos
1265
- | "moderada" → 1+ referência forte inventada
1266
- | "grave" → 2+ referências fortes inventadas
1267
- ```
1268
-
1269
- Quando `gravidade >= moderada`, o evento WebSocket `fim` inclui
1270
- `{"bloqueado": true}` para que o frontend exiba a resposta com
1271
- alerta visual.
1272
-
1273
- ### Fuzzy Matching — Sugestão de Referência Correta
1274
-
1275
- Quando o citation checker detecta referência inventada, busca número
1276
- similar no documento (distância Levenshtein ≤ 3):
1277
-
1278
- ```
1279
- ⚠️ Referências NÃO confirmadas: resp 1562098
1280
- 💡 Possível referência correta: resp 1562098 → você quis dizer resp 1561061?
1281
- ```
1282
-
1283
- Isso transforma um erro silencioso em uma **orientação útil** ao advogado.
1284
-
1285
- ---
1286
 
1287
- ## 📋 Roadmap
1288
-
1289
- ### 🔜 Curto Prazo (MVP)
1290
- - ✅ Sistema de licenciamento (trial + ativação)
1291
- - ✅ Onboarding interativo
1292
- - ✅ Health check visual (Ollama + modelo + licença)
1293
- - ✅ Script de setup automático
1294
- - ✅ Build de instalador Windows
1295
- - ✅ Landing page comercial (verificador de hardware + SEO + testes)
1296
- - ✅ Central de Licenças + webhook Hotmart (vendas automáticas, emails e renovações)
1297
-
1298
- ### 📈 Médio Prazo
1299
- - ✅ Fine-tuning em jurisprudência brasileira (BERTimbau → ratio decidendi, 99,55% F1)
1300
- - ✅ Interceptação de saudações (evita alucinação em "Oi"/"Olá")
1301
- - ✅ Citation checker com gravidade + flag bloqueado
1302
- - ✅ Warm-up automático no startup (3 mecanismos)
1303
- - ✅ Auto-update com verificação de versão
1304
- - Templates de prompt por área do direito
1305
- - Histórico de conversas persistente
1306
- - Integração com JusBrasil/TJSP
1307
- - Modo multi-documento (comparação de contratos)
1308
-
1309
- ### 🚀 Longo Prazo
1310
- - ✅ Modelo próprio fine-tuned em direito BR (classificador: `CyberPaul/ratio-bert-jurisprudencia-pt`)
1311
- - ✅ LLM generativo fine-tuned para RAG (respostas jurídicas nativas — deployado: `ratio-v8`, publicado: `CyberPaul/ratio-gemma3-4b-gguf-v8`)
1312
- - SaaS opcional (para quem prefere não instalar)
1313
- - API para integração com sistemas jurídicos (Themis, SAJ)
1314
- - Marketplace de bases jurídicas pré-indexadas
1315
 
1316
  ---
1317
 
1318
- ## 💬 Suporte
1319
 
1320
- Dúvidas, sugestões ou problemas? Abra uma issue ou entre em contato.
1321
 
1322
- - **Email:** contato@singularislabs.com.br
1323
- - **Site:** https://ratio.singularislabs.com.br
1324
- - **Empresa:** Singularis Labs (CNPJ: 68.801.082/0001-07)
 
 
 
1325
 
1326
  ---
1327
 
1328
  <p align="center">
1329
- <strong>RATIO</strong> (/ˈrɑː.ti.oʊ/)<br/>
1330
- <em>Encontre o raciocínio por trás dos documentos.</em><br/><br/>
1331
- <sub>Processamento local • Dados protegidos • Funcionamento offline</sub>
1332
  </p>
 
6
 
7
  <p align="center"><em>ratio decidendi</em> — o raciocínio jurídico por trás das decisões</p>
8
 
 
9
  <p align="center">
10
  <em>Inteligência jurídica com seus dados sob seu controle.</em><br/>
11
  <strong>100% local • 100% offline • 100% confidencial</strong>
 
29
 
30
  ## 🚀 v1.0.0 — Lançamento Oficial (Agosto 2026)
31
 
 
 
32
  | Componente | Status | URL |
33
  |------------|:------:|-----|
34
  | **Software Desktop** | ✅ | `RATIO_Setup_v1.0.exe` |
 
57
 
58
  ## 🤖 IA Treinada — Classificador de Ratio Decidendi
59
 
 
 
60
  | | |
61
  |---|---|
62
  | **Modelo** | [`CyberPaul/ratio-bert-jurisprudencia-pt`](https://huggingface.co/CyberPaul/ratio-bert-jurisprudencia-pt) |
63
  | **Base** | BERTimbau (`neuralmind/bert-base-portuguese-cased`) |
64
  | **Tarefa** | Classificação binária: a sentença é *ratio decidendi* ou não? |
65
+ | **Dados** | 20.266 sentenças balanceadas de 634.368 acórdãos do STJ e STF |
66
+ | **F1-Score** | **99,55%** (em sentenças) — estimativa de 93–97% em documentos inéditos |
 
67
  | **Licença** | Apache 2.0 |
 
68
 
69
  ### 🛡️ Filtro de qualidade no pipeline
70
 
71
+ O classificador é integrado como **guardião de qualidade** da extração (`processors/bert_ratio_filter.py`). Cada sentença extraída é validada — cabeçalhos, relatórios, votações e dados processuais são removidos. Roda em lotes de 32 com detecção automática de device (DirectML → CUDA → CPU).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
  ---
74
 
75
+ ## 🧠 Fine-Tune Generativo — RATIO v8.2 + Gate
 
 
 
 
76
 
77
  | | |
78
  |---|---|
79
  | **Base** | `unsloth/gemma-3-4b-it-bnb-4bit` (QLoRA 4-bit) |
80
+ | **Dataset** | 1.259 exemplos (700 RAG + 200 abstenção + 249 adversariais) |
81
+ | **LoRA** | [`CyberPaul/ratio-gemma3-4b-lora-v8`](https://huggingface.co/CyberPaul/ratio-gemma3-4b-lora-v8) (277 MB) |
82
+ | **GGUF** | [`CyberPaul/ratio-gemma3-4b-gguf-v8`](https://huggingface.co/CyberPaul/ratio-gemma3-4b-gguf-v8) (Q4_K_M 2.49 GB) |
 
 
 
83
  | **Gate arquitetural** | `scripts/gate_rag.py` — intercepta armadilhas antes do LLM |
84
 
85
+ ### 📊 Protocolo de Avaliação
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ | Métrica | v8.2 + Gate | Threshold | Status |
88
+ |---------|:-----------:|:---------:|:------:|
89
+ | Faithfulness | **0.983** | ≥ 0.85 | ✅ |
90
+ | Citation Accuracy | **0.997** | ≥ 0.90 | ✅ |
91
+ | Unsupported Claims | **0.058** | ≤ 0.10 | ✅ |
92
+ | Hallucination Rate | **0.000** | ≤ 0.10 | ✅ |
93
+ | Utility Score | **0.940** | ≥ 0.70 | ✅ |
94
 
95
+ > **Gate: ✅ APROVADO PARA PRODUÇÃO** — Suite A (100/100) + Suite B (50/50) + Smoke Test (10/10)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  ### Deploy no Ollama
98
 
99
  ```bash
100
+ python scripts/deploy_gguf_ollama.py
101
+ ollama list | grep ratio-gemma3
 
 
 
 
 
 
102
  ```
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  ---
105
 
106
  ## 🌐 Landing Page Comercial
107
 
108
+ A landing page está online em **[ratio.singularislabs.com.br](https://ratio.singularislabs.com.br/)**. Código-fonte em `landing-page/RATIOlanding2/`.
109
 
110
+ - **Verificador de Compatibilidade de Hardware** — sliders de RAM/VRAM + seletor de SO
111
+ - **Showcase da IA treinada** — métricas reais (99,55% F1)
112
+ - **Planos, FAQ e Trial** — tudo pronto para conversão
113
  - **SEO otimizado** — meta tags, Open Graph e conteúdo semântico
114
 
115
+ ### 🧪 Testes da landing page (Vitest)
116
 
117
+ A landing page possui **36 testes automatizados** com cobertura de **~91%**.
118
 
119
  ```bash
120
  cd landing-page/RATIOlanding2
121
+ npm test
 
 
122
  ```
123
 
 
 
 
 
 
 
 
 
 
 
124
  ---
125
 
126
  ## 🎯 Planos e Preços
 
149
 
150
  ### 🔒 Privacidade Primeiro
151
  - **100% offline** — Seus documentos nunca saem do seu computador
152
+ - **Sem APIs de terceiros** — Todo processamento é local via Ollama
153
  - **LGPD compliant** — Arquitetura desenhada para conformidade desde a fundação
154
  - **Hardware binding** — Licença vinculada à máquina, sem risco de uso não autorizado
155
 
156
  ### 🧠 RAG Jurídico Inteligente
157
+ - **Busca Híbrida** — Busca semântica vetorial + BM25 para precisão máxima
158
+ - **Chunking Semântico Jurídico** — Divisão por Artigos, Parágrafos, Incisos e Cláusulas
159
  - **Streaming Token a Token** — Respostas em tempo real via WebSocket
160
+ - **Citação de Fontes** — Referência exata ao documento e página
161
+ - **Filtro BERT** — IA própria que valida cada sentença extraída (99,55% F1)
162
 
163
  ### 📄 Ingestão Multi-Formato
164
  - **PDF** (texto nativo + OCR para escaneados)
165
  - **DOCX, XLSX, PPTX** (Word, Excel, PowerPoint)
166
  - **Imagens** (PNG, JPG — OCR automático)
167
  - **URLs e YouTube** (web scraping e transcrição automática)
168
+ - **Google Drive** (importação via OAuth2)
169
+ - **OneDrive** (importação via OAuth2)
170
 
171
  ### 🖥️ Interface Premium
172
+ - **Onboarding interativo** — Wizard de 5 passos na primeira execução
173
  - **Visualizador de PDF** com highlight automático da página citada
174
  - **Chat com streaming** e cards de fonte clicáveis
175
+ - **Exportação de consultas em PDF**
176
  - **Tema dark/light** — Alternável com um clique
 
177
 
178
  ---
179
 
180
  ## 🏗️ Arquitetura
181
 
 
 
182
  ```text
183
  Projeto RATIO/
184
+ ├── core/ # Núcleo (auth, license, chunker, rag_engine, retriever)
185
+ ├── engine/ # Motor de inferência (llm_client, modelo_installer, exportador)
186
+ ├── processors/ # Processadores (bert_ratio_filter, ratio_extractor)
187
+ ├── scripts/ # Pipeline de dados, treino e publicação
188
+ ├── frontend/ # Interface React + TypeScript
189
+ ├── tests/ # 622 testes automatizados
190
+ ├── license-server/ # Central de Licenças (webhook Hotmart, emails, painel)
191
+ ├── landing-page/ # Landing page comercial (React + Vite)
192
+ ├── installer/ # Instalador Windows (Inno Setup 6.3+)
193
+ ├── api.py # Ponto de entrada FastAPI (HTTP + WebSocket)
194
+ ├── iniciar.bat # Execução com 1 clique
195
+ └── build_ratio.bat # Build do instalador
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  ```
197
 
198
  ---
 
201
 
202
  ### 🖥️ Compatibilidade
203
 
204
+ | Sistema Operacional | Status | Método |
205
+ |---------------------|:------:|--------|
206
+ | **Windows 10/11** | ✅ | Instalador (.exe) — `RATIO_Setup_v1.0.exe` |
207
+ | **macOS 12+** | ✅ | Script de instalação (bash) |
208
+ | **Linux** | ✅ | Script de instalação (bash) |
 
 
209
 
210
  ### 🔧 Setup Automático (Recomendado)
211
 
 
215
  | **macOS** | `chmod +x install_mac.sh && ./install_mac.sh` |
216
  | **Linux** | `chmod +x install_linux.sh && ./install_linux.sh` |
217
 
 
 
 
 
 
 
 
 
 
218
  ### ⚙️ Setup Manual
219
 
220
  #### 1. Pré-requisitos
 
222
  - **Python 3.10+** — [python.org](https://python.org)
223
  - **Node.js 18+** — [nodejs.org](https://nodejs.org)
224
  - **Ollama** — [ollama.com](https://ollama.com)
225
+ - **Tesseract OCR** (opcional, para PDFs escaneados)
226
 
227
  #### 2. Configurar Backend
228
 
229
  ```bash
 
 
 
230
  pip install -r requirements.txt
 
 
231
  copy .env.example .env
232
  ```
233
 
234
+ Edite o `.env`:
235
 
236
  ```ini
237
  RATIO_API_KEY=sua_chave_secreta_aqui
 
238
  OLLAMA_BASE_URL=http://localhost:11434
239
+ RATIO_MODELO=gemma3:4b
240
+ RATIO_NUM_CTX=4096
241
  RATIO_HOST=127.0.0.1
242
  RATIO_PORT=8000
243
+ RATIO_LICENSE_SERVER=https://api.singularislabs.com.br
 
 
 
 
 
 
 
 
 
 
 
244
  ```
245
 
246
+ #### 3. Executar
247
 
248
+ **Método recomendado:** execute `iniciar.bat` — sobe Ollama, backend e frontend automaticamente.
249
 
250
+ **Modo manual:**
251
 
252
  ```bash
253
+ make run-api # Terminal 1 — Backend (porta 8000)
254
+ make run-frontend # Terminal 2 — Frontend (porta 5173)
 
 
 
255
  ```
256
 
 
 
 
 
257
  Acesse: **http://localhost:5173** 🎉
258
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  ---
260
 
261
  ## 🔐 Licenciamento
262
 
263
  O RATIO tem licenciamento local (trial, ativação, hardware binding) com validação
264
+ opcional contra a **Central de Licenças** (`api.singularislabs.com.br`).
 
 
265
 
266
  ### Como funciona
267
 
268
  1. **Primeira execução** → Trial de 14 dias criado automaticamente
269
+ 2. **Compra (Hotmart)** → webhook cria a licença e a chave é enviada por email
270
+ 3. **Ativação** → inserir chave na tela de licenciamento
271
+ 4. **Validação** → integridade (checksum SHA256), hardware (MAC + username), data de expiração
 
 
 
 
 
272
 
273
+ ### Central de Licenças
274
 
275
  | Recurso | Detalhe |
276
  |---|---|
277
+ | **Webhook Hotmart** | Venda cria licença, cancelamento/reembolso revoga |
278
+ | **Emails automáticos** | Chave pro cliente · aviso pro admin · lembretes de renovação |
279
+ | **Ativação** | `POST /v1/activate` — valida chave + hardware |
280
  | **Heartbeat** | `POST /v1/check` — vigência/revogação em tempo real |
281
+ | **Painel admin** | `/admin` — vendas, receita, vencimentos, cadastro manual |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
+ ### Tipos de licença
 
 
 
284
 
285
+ | Prefixo | Tipo | Duração | Recursos |
286
+ |:-------:|------|:-------:|----------|
287
+ | `RATIO-TRIAL-...` | TRIAL | 14 dias | Funcionalidades básicas |
288
+ | `S...` | SOLO | 365 dias | RAG completo, bases ilimitadas |
289
+ | `E...` | ESCRITÓRIO | 365 dias | Multi-usuário, prompts customizados |
290
+ | `P...` | ENTERPRISE | **Perpétuo** | API access, suporte dedicado |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
 
292
  ---
293
 
294
  ## 🔒 Segurança e Privacidade
295
 
296
  - **LGPD compliant** — Dados nunca saem da máquina do usuário
 
297
  - **API Key timing-safe** — Comparação em tempo constante (`secrets.compare_digest`)
298
  - **WebSocket autenticado** — Validação de token no handshake
299
+ - **Hardware binding** — Licença vinculada ao hardware
300
+ - **Grace period 72h** — Cache encriptado para funcionar offline
 
301
  - **Rate limiting** — 5 tentativas de ativação por hora
 
 
302
  - **Gate arquitetural** — Intercepta perguntas que pedem confirmação de processo sem documento
 
303
  - **Dashboard de segurança** — Monitoramento de tentativas de cracking em tempo real
304
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  ---
306
 
307
  ## 🧪 Testes
308
 
309
  ```bash
310
+ # Toda a suíte (622 testes)
 
 
 
311
  pytest tests/ -v
312
 
313
  # Suíte completa com 1 clique (Windows)
314
  run_tests.bat
315
 
316
+ # Testes específicos
317
+ pytest tests/test_license.py -v # 26 testes de licenciamento
318
+ pytest tests/test_bert_filter.py -v # Testes do filtro BERT
319
+ pytest tests/test_citation_checker.py -v # Citation checker
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
320
  ```
321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
322
  ---
323
 
324
+ ## 🛠️ Comandos
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
+ | Comando | Descrição |
327
+ |---------|-----------|
328
+ | `setup_ratio.bat` | Configuração completa do ambiente |
329
+ | `build_ratio.bat` | Build: frontend + PyInstaller + Inno Setup |
330
+ | `iniciar.bat` | Execução com 1 clique (recomendado) |
331
+ | `make run-api` | Inicia backend FastAPI (porta 8000) |
332
+ | `make run-frontend` | Inicia frontend Vite (porta 5173) |
333
+ | `run_tests.bat` | Roda toda a suíte de testes |
334
 
335
  ---
336
 
337
+ ## 📞 Contato
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
+ | Canal | Link |
340
+ |-------|------|
341
+ | **Site** | [ratio.singularislabs.com.br](https://ratio.singularislabs.com.br) |
342
+ | **Email** | [contato@singularislabs.com.br](mailto:contato@singularislabs.com.br) |
343
+ | **GitHub** | [Churinti/singularis-labs](https://github.com/Churinti/singularis-labs) (privado) |
344
+ | **HuggingFace** | [CyberPaul](https://huggingface.co/CyberPaul) |
345
+ | **Hotmart** | [pay.hotmart.com](https://pay.hotmart.com/U107349593U) |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
 
347
  ---
348
 
349
+ ## 📜 Licença
350
 
351
+ O código-fonte do RATIO é proprietário. Os modelos publicados no HuggingFace possuem licenças específicas:
352
 
353
+ | Modelo | Licença |
354
+ |--------|---------|
355
+ | `ratio-bert-jurisprudencia-pt` | Apache 2.0 |
356
+ | `ratio-gemma3-4b-lora-v8` | Gemma Terms of Use |
357
+ | `ratio-gemma3-4b-gguf-v8` | Gemma Terms of Use |
358
+ | `ratio-dataset-v8.1` | Apache 2.0 |
359
 
360
  ---
361
 
362
  <p align="center">
363
+ <strong>Singularis Labs</strong> • São Gonçalo, RJ • CNPJ: 68.801.082/0001-07<br/>
364
+ <a href="https://ratio.singularislabs.com.br">ratio.singularislabs.com.br</a>
 
365
  </p>