Metadata-Version: 2.4
Name: serigy-jev
Version: 0.1.0
Summary: Inference-only PT-BR fake-news classifier (load Hub weights + predict)
Author-email: Wendell Barreto <wendellbarreto@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/wendellbigato/serigy-jev
Project-URL: Hugging Face, https://huggingface.co/wendellperbar/serigy-jev
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.26.0
Requires-Dist: pydantic>=2.5.0
Requires-Dist: torch
Requires-Dist: transformers>=4.40.0
Requires-Dist: sentence-transformers>=3.0.0
Requires-Dist: safetensors>=0.4.0
Requires-Dist: huggingface_hub>=0.24.0
Requires-Dist: python-dotenv>=1.0.0
Dynamic: license-file

# Serigy-Jev — Relatório

**Sistema de detecção de fake news com confiança calibrada (ordinal + Jev)**  
**Período:** 2026-09-23 → 2026-09-24  
**Hardware do Modelo Experimental:** MacBook Air M4, 16 GB  
**Base teórica:** *Confidence-Aware Routing for Large Language Model Reliability Enhancement* (Nandakishor M, [arXiv:2510.01237](https://arxiv.org/abs/2510.01237)) — adaptado para classificação FakeBR (sem routing LLM).

| | |
|--|--|
| Notebook do bench | [`notebooks/benchmark_serigy_vs_typesafe_jev.ipynb`](notebooks/benchmark_serigy_vs_typesafe_jev.ipynb) |
| Figuras deste relatório | [`docs/report/`](docs/report/) |

---

## 1. Sumário executivo

Serigy-Jev é um **classificador local** que:

1. Extrai representações de um **sensor LLM congelado** (exemplo default: Manacá-1B) + embedding Sentence-BERT;
2. Combina três sinais de confiança $C_{\mathrm{sem}}$, $C_{\mathrm{conv}}$, $C_{\mathrm{learned}}$;
3. Emite um score de veracidade $C_{\mathrm{overall}} \in [0,1]$, uma distribuição ordinal $P(k)$ em $\{0,1,2\}$ e confiança calibrada via entropia $H_3$.

### Resultados-chave

| Cenário | Serigy·Manacá | Serigy·Qwen | TypeSafe Jev (ref.) | Laya (ref.) |
|---------|---------------|-------------|---------------------|-------------|
| FakeBR test (in-domain, n=1440) | **0.980** acerto | 0.970 | — | — |
| Lupa 2025 OOD (n=200) | **0.836** acerto | 0.735 | **1.000** | 0.639 |
| AUC Lupa | 0.949 | **0.959** | **0.999** | 0.641 |
| ECE Lupa (↓ melhor) | **0.156** | 0.239 | 0.333 | 0.428 |
| Inferência p50 Lupa | 409 ms | 455 ms | 281 ms | **85 ms** |

**Leitura do Modelo Experimental.** Com FakeBR e inferência **offline** no Mac, o Serigy fecha o pipeline e generaliza para Lupa 2025 com **~84% de acerto** nas classes fortes (Manacá), melhor ECE que TypeSafe e Laya. TypeSafe é o teto de acerto neste corpus; Laya ([site](https://laya.convaiinnovations.com)) é a referência open-weight mais rápida, porém com muito “incerto” e menor acerto zero-shot em fake news PT. O valor do baseline local é **controle, reprodutibilidade e stack forte offline**.

**Decisão de sensor:** Manacá continua default Serigy neste experimento (melhor Lupa + FakeBR + confiabilidade). Pesos Qwen permanecem em `models/qwen/`.

---

## 2. Arquitetura e fluxograma

Exemplo com **um sensor**: Manacá-1B (`AIInstituteLNCC/manaca-1b-base`, $L=24$, $d=2048$).

Fluxo de **inferência** (uma notícia → JSON). A **cabeça ordinal** é o bloco que transforma o score contínuo $C_{\mathrm{overall}} \in [0,1]$ em classe discreta $\{0,1,2\}$ (Falso / Incerto / Verdadeiro) + confiança — não é uma camada do LLM.

```mermaid
flowchart TB
  subgraph etapa1["1 · Entrada"]
    TXT["Notícia / claim<br/>texto + fonte opcional"]
  end

  subgraph etapa2["2 · Sensor congelado — Manacá-1B"]
    LLM["Manacá-1B forward<br/>h_final ∈ R^2048<br/>h_layers ∈ R^{24×2048}"]
    SBERT["Sentence-BERT MiniLM<br/>e_ref ∈ R^384"]
  end

  subgraph etapa3["3 · Três sinais de confiança ∈ 0,1"]
    CSEM["Csem — alinhamento semântico<br/>cos(P(h), e_ref)"]
    CCONV["Cconv — convergência entre camadas<br/>12 primeiras + 12 últimas"]
    CLEAR["Clearned — MLP em h_final<br/>aprendido no FakeBR"]
  end

  subgraph etapa4["4 · Fusão"]
    COV["C_overall = Σ wi · Ci<br/>score contínuo de veracidade ∈ 0,1"]
  end

  subgraph etapa5["5 · Cabeça ordinal — score → classe + confiança"]
    direction TB
    RBF["Proximidade RBF aos centros no eixo do score<br/>classe 0 Falso → centro 0.0<br/>classe 1 Incerto → centro 0.5<br/>classe 2 Verdadeiro → centro 1.0<br/>largura σ ≈ 0.1"]
    SM["softmax → distribuição P(0), P(1), P(2)"]
    ARG["veredito = argmax P(k)<br/>rótulo via critérios do pedido"]
    H3["confiança calibrada<br/>1 − H₃ / ln 3<br/>alta se P concentrada; baixa se espalhada"]
  end

  subgraph artefatos["Pesos carregados"]
    CKPT["models/manaca/serigy-jev-fakenews<br/>w, σ, MLP Clearned"]
  end

  TXT --> LLM
  TXT --> SBERT
  LLM --> CSEM
  SBERT --> CSEM
  LLM --> CCONV
  LLM --> CLEAR
  CSEM --> COV
  CCONV --> COV
  CLEAR --> COV
  COV --> RBF --> SM
  SM --> ARG
  SM --> H3
  CKPT -.-> CLEAR
  CKPT -.-> COV
  CKPT -.-> RBF
  ARG --> OUT["PredicaoResponse JSON<br/>predicao · classe_ordinal · score_final · confianca_calibrada"]
  H3 --> OUT
  COV --> OUT
```

**Leitura rápida da cabeça ordinal.** $C_{\mathrm{overall}}=0.08$ fica perto do centro $0.0$ → massa em P(0) → **Falso**. $C_{\mathrm{overall}}=0.5$ fica no meio → **Incerto**. $C_{\mathrm{overall}}=0.92$ perto de $1.0$ → **Verdadeiro**. Os números $0$, $0.5$ e $1$ são **posições no eixo do score**, não etapas de tempo.

### Layout de artefatos (exemplo Manacá)

```
models/manaca/serigy-jev-fakenews/
  serigy_jev.safetensors
  serigy_jev.json
data/cache/manaca/fakebr/
```

(O baseline Qwen fica isolado em `models/qwen/…` e não entra neste diagrama.)

---

## 3. Matemática

Resumo abaixo. Guia didático (conceitos, decisões vs alternativas, citações ao artigo): [docs/matematica_componentes.md](docs/matematica_componentes.md).

### 3.1 Sinais de confiança

**Csem** — projeta o hidden state `h` e compara com o embedding `e_ref`:

$$
\mathrm{sim} = \cos\bigl(P(h),\, e_{ref}\bigr)
$$

$$
C_{sem} = \frac{\mathrm{sim}+1}{2} \in [0,1]
$$

**Cconv** — convergência entre camadas (determinístico). No Manacá: L = 24 → 12 primeiras + 12 últimas.

**Clearned** — MLP em `h`, treinada no FakeBR para aproximar o alvo y ∈ {0, 1}.

### 3.2 Fusão

$$
C_{overall} = w_1 C_{sem} + w_2 C_{conv} + w_3 C_{learned}
$$

$$
w_i \ge 0, \qquad w_1 + w_2 + w_3 = 1
$$

Os pesos `w` são calibrados no validation (simplex, MSE vs y).

| Sensor | w_sem | w_conv | w_clearned | σ |
|--------|------:|-------:|-----------:|---:|
| Qwen | 0.095 | 0.000 | 0.905 | 0.10 |
| Manacá | 0.048 | 0.000 | 0.952 | 0.10 |

Clearned domina; Cconv fica zerado neste dataset.

### 3.3 Cabeça ordinal (RBF + softmax)

Centros da classificação:

$$
\mu_0 = 0
$$

$$
\mu_1 = 0.5
$$

$$
\mu_2 = 1
$$

Logits RBF:

$$
z_k = -\frac{(C_{overall} - \mu_k)^2}{2\sigma^2}
$$

Softmax:

$$
P(k) = \frac{e^{z_k}}{\sum_{j=0}^{2} e^{z_j}}
$$

Classe e label:

$$
\mathrm{classe\_ordinal} = \arg\max_k P(k)
$$

$$
\mathrm{predicao} = \text{label do critério } k
$$

### 3.4 Confiança calibrada (Jev / H₃)

$$
H_3 = -\sum_{k=0}^{2} P(k) \ln P(k)
$$

$$
c = 1 - \frac{H_3}{\ln 3}
$$

`c` é o campo `confianca_calibrada` no JSON.

### 3.5 Métricas do relatório

- **Acerto (classe forte):** % de acerto fake vs verdadeiro só quando o modelo **não** marca incerto (pred ∈ {0, 2}). É o “acerto no dataset” deste relatório.
- **AUC-ROC:** quão bem o `score_final` separa fake de verdadeiro (ranking).
- **Erro de calibração (ECE):** distância entre confiança e acerto real (bins) — **menor é melhor**.
- **Tempo de inferência:** latência por exemplo (ms). TypeSafe inclui rede; Serigy/Laya são locais.

---

## 4. Pipeline de dados e treino

```mermaid
flowchart LR
  A["FakeBR-UFG<br/>7200 exemplos"] --> B["serigy_train.cache_fakebr<br/>Manacá-1B + MiniLM"]
  B --> C["data/cache/manaca/fakebr"]
  C --> D["serigy_train.treinar<br/>MLX: Csem + Clearned"]
  D --> E["calibra w, σ no val"]
  E --> F["models/manaca/serigy-jev-fakenews"]
  F --> G["serigy-jev / SerigyJev"]
  G --> H["Lupa 2025 bench<br/>× TypeSafe × Laya"]
```

| Etapa | Comando típico |
|-------|----------------|
| Cache | `uv run --group train python -m serigy_train.cache_fakebr --out data/cache/manaca/fakebr` |
| Treino | `uv run --group train python -m serigy_train.treinar --cache data/cache/manaca/fakebr --out models/manaca/serigy-jev-fakenews` |
| Inferência | `uv run serigy-jev --texto "..."` / `SerigyJev(...).predict(...)` |
| Bench | notebook `benchmark_serigy_vs_typesafe_jev.ipynb` (Serigy × TypeSafe × [Laya](https://laya.convaiinnovations.com)) |

Split FakeBR: **60 / 20 / 20** (train / val / test), seed 42 → 4320 / 1440 / 1440.

---

## 5. Resultados — FakeBR (in-domain)

Treino full (500 iters max, early stop):

| | Manacá | Qwen |
|--|--------|------|
| Acerto (classe forte) **test** | **0.980** | 0.970 |
| Acerto (classe forte) val | **0.985** | 0.976 |
| MSE score test | **0.0099** | 0.0146 |
| Convergência Clearned | iter ~88 | (histórico Qwen) |
| Convergência Csem | iter ~431 | — |

Sanidade do treino: no FakeBR (in-domain) o acerto fica alto; no Lupa 2025 (OOD) mede-se a **generalização** do mesmo stack — objeto natural de pesquisa, não de disputa de ranking.

#### O que este gráfico mostra

![Generalização FakeBR → Lupa](docs/report/07_generalizacao_fakebr_lupa.png)

Barras escuras = acerto no **mesmo domínio do treino** (FakeBR teste). Barras claras = acerto em notícias **Lupa 2025**, que o modelo nunca viu. Os dois sensores caem ao sair do FakeBR — isso é esperado em OOD. Manacá generaliza melhor (0.980 → **0.836**, Δ ≈ 0.14) do que Qwen (0.970 → **0.735**, Δ ≈ 0.24). A mensagem: o Modelo Experimental **não memorizou só o FakeBR**; ainda assim, o gap OOD é o problema de pesquisa a atacar (mais dados verdadeiros contemporâneos, menos bias true→fake).

---

## 6. Resultados — Lupa 2025 (OOD) × TypeSafe × Laya

Corpus: `data/benchmarks/benchmark_fakenews_ptbr_2025_lupa.csv` (200 linhas = 100 pares fake/true).  
Summary: `data/benchmarks/runs/summary_20260924T161532.json` (Serigy × TypeSafe × [Laya](https://laya.convaiinnovations.com)).

**Cores fixas** (bandeira de Sergipe): Qwen azul · Manacá verde · TypeSafe âmbar · Laya roxo. Barras sempre **do maior para o menor** na métrica do gráfico.

### 6.1 Tabela comparativa

| Sistema | n | Acerto (classe forte) | F1 (classe forte) | % incerto | AUC-ROC | ECE ↓ | Inferência p50 (ms) |
|---------|---|----------------------|-------------------|-----------|---------|-------|---------------------|
| **typesafe-jev** | 200 | **1.000** | **1.000** | 0.100 | **0.999** | 0.333 | 281 |
| **serigy-jev-manaca** | 200 | **0.836** | **0.795** | **0.085** | 0.949 | **0.156** | 409 |
| serigy-jev-qwen | 200 | 0.735 | 0.522 | 0.170 | 0.959 | 0.239 | 455 |
| laya (multilingual) | 200 | 0.639 | 0.733 | 0.515 | 0.641 | 0.428 | **85** |

### 6.2 Figuras — o que cada uma conta

#### 1) Latência — tempo de inferência

![Latência — tempo de inferência](docs/report/01_latencia_inferencia.png)

Mede **quanto tempo cada sistema leva por notícia** (média ± desvio, em ms). Ordenado do mais lento ao mais rápido. Laya (~109 ms) é disparado o mais veloz; TypeSafe (~294 ms) inclui rede/API; Serigy roda 100% local no Mac (~414–463 ms). Use este gráfico para falar de **custo operacional e UX**, não de qualidade da classificação.

#### 2) Benchmark Fake News 2025 (acerto)

![Benchmark Fake News 2025](docs/report/02_acerto_classe_forte.png)

É o gráfico principal de **“quem acerta mais fake vs verdadeiro”** no corpus Lupa. Só entram predições em que o modelo se comprometeu (falso ou verdadeiro); respostas **incerto** saem do denominador. TypeSafe fecha 100%; Manacá **83,6%** (melhor baseline local); Qwen 73,5%; Laya 63,9%. Leitura pública: *em notícias reais de 2025, o Serigy·Manacá acerta cerca de 8 em cada 10 decisões firmes*.

#### 3a) Desempenho (acerto · AUC)

![Desempenho](docs/report/03a_desempenho.png)

Duas métricas em que **barra alta = melhor**, ordenadas dentro de cada grupo:

- **Acerto** — mesma ideia do gráfico 2 (decisão discreta).
- **AUC-ROC** — quão bem o *score contínuo* (0→1) separa fake de verdadeiro, independente do limiar. Aqui Qwen (0.96) fica ligeiramente acima do Manacá (0.95): o ranking do score do Qwen é bom, mas a **decisão final** (classes) ainda erra mais por bias a fake. TypeSafe domina os dois eixos; Laya fica atrás nos dois.

#### 3b) Confiabilidade (certeza alinhada · decide de fato)

![Confiabilidade](docs/report/03b_confiabilidade.png)

Métricas que originalmente eram “quanto menor, melhor” (ECE e % incerto) foram invertidas (`1 − valor`) para a leitura visual ser a mesma: **barra alta = melhor**.

- **Confiabilidade** — a certeza que o modelo declara combina com o acerto real (se diz ~80%, acerta ~80%). Manacá lidera (~84%); TypeSafe acerta tudo, mas a confiança não acompanha tão bem (~67%).
- **Decide de fato** — fração de vezes em que o modelo emite falso/verdadeiro em vez de “incerto”. Manacá e TypeSafe decidem com frequência; Laya se abstém em mais da metade dos casos (~48% de decisões firmes).

#### 4) Matrizes de confusão

![Matrizes](docs/report/04_matrizes_confusao.png)

Cada painel é um sistema. **Linhas** = rótulo ouro (o que a notícia *é*); **colunas** = o que o modelo *disse*. O corpus Lupa só tem ouro falso/verdadeiro — por isso a linha do meio (Incerto) fica zerada. Diagonal forte = acerto.

Leituras:

- **TypeSafe:** nenhum true→fake; usa incerto com parcimônia (6 fake→incerto, 14 true→incerto).
- **Serigy·Qwen:** 44 true→fake; só 24 true corretos (bias forte a fake).
- **Serigy·Manacá:** reduz true→fake para **26** e sobe true corretos para **58**; 4 fake→true.
- **Laya:** marca muito incerto (72 fake + 31 true); por isso o acerto “classe forte” parece melhor do que a cobertura real sugere.

#### 5) Distribuição de classes preditas

![Distribuição](docs/report/05_distribuicao_classes.png)

Frações de respostas **Falso / Incerto / Verdadeiro** de cada sistema. Não mede acerto — mede **estilo de decisão**. TypeSafe e Manacá concentram massa nas pontas (0 e 2). Laya empilha no centro (incerto). Qwen puxa mais para falso — alinhado ao bias true→fake da matriz.

#### 6) Matriz de concordância

![Matriz de concordância](docs/report/06_matriz_concordancia.png)

Cada célula = % de notícias em que **dois sistemas deram a mesma classe** (0, 1 ou 2). Diagonal = 100% (modelo consigo mesmo). TypeSafe ↔ Manacá concordam em **72%** — o baseline local “pensa” parecido com a API na maioria dos casos. Laya discorda de todos (~19–32%): outro perfil de decisão (muito incerto), não um empate técnico.

### 6.3 Interpretação (baseline local vs produto)

| Dimensão | Serigy-Jev (baseline local) | TypeSafe / TypedAI (ref.) | Laya (ref. open-weight) |
|----------|-----------------------------|---------------------------|-------------------------|
| Execução | Offline, local, pesos versionados | API, rede, modelo proprietário | Local, Apache 2.0 |
| Dados de treino deste Modelo Experimental | FakeBR (~7k) | Stack comercial (não auditável aqui) | Foundation zero-shot neste bench |
| Acerto Lupa (classe forte) | **0.836** (Manacá) | **1.000** | 0.639 |
| Confiabilidade (ECE ↓) | **0.156** (Manacá) | 0.333 | 0.428 |
| Inferência p50 | ~409 ms (Manacá) | ~281 ms (inclui rede) | **~85 ms** |
| Papel no relatório | **Baseline local** | **Teto de acerto** | **Referência latência / OSS** |

Este Modelo Experimental valida uma linha de **pesquisa e inovação aplicada**: classificador local, auditável e offline (Serigy + Manacá), com ~84% de acerto OOD, melhor ECE que as referências externas neste corpus, e hipóteses de melhoria explícitas (bias true→fake, mais verdadeiras contemporâneas, retino de $\sigma$). TypeSafe e Laya aparecem como **contexto de mercado**, não como meta a “empatar”.

---

## 7. Como reproduzir

```bash
# ambiente
uv sync --extra bench
cp .env.template .env   # HF_TOKEN, JEV_API_KEY/TYPESAFE_API_KEY opcional

# perfil Manacá (default atual) — ver .env.template
# SERIGY_SENSOR_SLUG=manaca
# SERIGY_MODEL_ID=AIInstituteLNCC/manaca-1b-base
# SERIGY_NUM_LAYERS=24
# SERIGY_CHECKPOINT_DIR=models/manaca/serigy-jev-fakenews
# SERIGY_CACHE_DIR=data/cache/manaca/fakebr

# inferência (API pública)
uv run serigy-jev --texto "..."
# ou: from serigy_jev import SerigyJev; SerigyJev(...).predict(...)

# treino / cache (só monorepo; fora do wheel PyPI)
# uv sync --group train --group dev
# uv run --group train python -m serigy_train.cache_fakebr ...
# uv run --group train python -m serigy_train.treinar ...

# benchmark 4 vias (Qwen + Manacá + TypeSafe + Laya)
# abrir notebooks/benchmark_serigy_vs_typesafe_jev.ipynb com kernel .venv
```

Figuras deste relatório: regenerar na seção §8 do notebook (salva em `docs/report/`).

Testes: `uv run --group train --group dev pytest -q`

---

## 8. Estrutura do repositório

```
src/serigy_jev/     # pacote de inferência (wheel PyPI)
  api/              # schemas, MotorInferencia, CLI local predizer
  cliente.py        # SerigyJev + serigy-jev CLI
  checkpoint.py     # load/save safetensors
  components/       # Csem, Cconv, Clearned, SistemaConfianca
  dados/            # extrator hidden states (sem FakeBR)
  utils/            # ordinal RBF, métricas, H3
src/serigy_train/   # treino/cache FakeBR (monorepo; uv group train; strip no publish)
notebooks/          # avaliação FakeBR + benchmark Lupa
models/{qwen,manaca}/serigy-jev-fakenews/
hf/                 # staging release Hub (Manacá canônico)
docs/report/        # figuras deste README
```

---

## 9. Conclusões e próximos passos

1. **Modelo Experimental validado:** pipeline cache → treino → inferência → bench (4 sistemas) no Apple Silicon.
2. **Manacá > Qwen** no Lupa (acerto 0.836 vs 0.735; ECE 0.156 vs 0.239; menos true→fake).
3. **TypeSafe** = teto de acerto; **Laya** = referência de latência OSS (~85 ms), porém fraca em acerto/incerto neste domínio.
4. **Serigy·Manacá** = melhor baseline local (acerto + confiabilidade).
5. **Próximos ganhos:** mais notícias verdadeiras / domínio atual; reduzir true→fake (26 restantes); empacotar release Manacá.

---

## 10. Modelo de distribuição — open weights

O release público do Serigy-Jev é **open weights**, não open source completo:

| Artefato | Onde | O que libera |
|----------|------|--------------|
| Pesos (`.safetensors` + `.json`) | Hub [`wendellperbar/serigy-jev`](https://huggingface.co/wendellperbar/serigy-jev) | checkpoint público |
| Inferência (API I/O) | PyPI [`serigy-jev`](https://pypi.org/project/serigy-jev/) | wheel só `serigy_jev` → `predict` |
| Treino / FakeBR / cache | monorepo (`serigy_train`, `uv sync --group train`) | **fora do wheel** PyPI |

Em resumo: o wheel público é só inferência (sem `trust_remote_code`, sem FakeBR/cache). Treino fica no repositório com `uv sync --group train`. Isso difere de **open source** completo, que publicaria treino + arquitetura no mesmo artefato PyPI.

Model card e quickstart: [`hf/README.md`](hf/README.md).

---

## 11. Licenças e créditos

**Este repositório (código Serigy-Jev, documentação e checkpoints Serigy):** [MIT License](LICENSE) — Copyright © 2026 Wendell Barreto. Uso livre, inclusive comercial, **desde que a nota de copyright e a licença sejam mantidas** (citação/atribuição).

Dependências e dados de terceiros mantêm as licenças originais:

- FakeBR: dataset UFG no Hugging Face (`fake-news-UFG/fakebr`).
- Sensores: Qwen (Tongyi) e Manacá-1B (AI Institute LNCC) — baixar do HF; não republicamos os pesos do backbone.
- Sentence-BERT MiniLM e demais libs Python: conforme cada pacote.
- TypeSafe Jev: API de terceiros usada só no braço de benchmark.
- Laya: pacote open-weight (`pip install laya`) usado só no braço de benchmark.

---

## Sobre o nome — Cacique Serigy

Segundo a [Wikipédia](https://pt.wikipedia.org/wiki/Serigy), **Serigy** foi um líder indígena brasileiro do século XVI na região do atual estado de Sergipe. O nome, em tupi, significaria **“água de siri”** (junção de *siri* + *'y*, “água”).

Seu povo vivia entre os atuais rios **Vaza-Barris** e **Sergipe**. A tradição registra resistência à colonização portuguesa — inclusive trocas com franceses — até a conquista militar sob **Cristóvão de Barros**, em **1590**. O Palácio Serigy, em Aracaju, leva esse nome em homenagem a ele.

Este projeto adota **Serigy-Jev** em referência a essa figura e ao território sergipano. Fonte: [pt.wikipedia.org/wiki/Serigy](https://pt.wikipedia.org/wiki/Serigy).
