yafitzdev commited on
Commit
64cd34f
·
verified ·
1 Parent(s): 55a0162

Improve Pyrrho v2 model card

Browse files
Files changed (1) hide show
  1. README.md +180 -42
README.md CHANGED
@@ -3,32 +3,126 @@ license: cc-by-nc-4.0
3
  base_model: answerdotai/ModernBERT-base
4
  library_name: transformers
5
  pipeline_tag: text-classification
 
 
6
  tags:
7
  - rag
8
  - governance
 
 
9
  - pyrrho
10
  - fitz-gov-v2
11
  - modernbert
12
  - multi-label-classification
 
 
 
 
 
13
  ---
14
 
15
  # pyrrho-v2-nano-g1
16
 
17
- `pyrrho-v2-nano-g1` is the Pyrrho v2 ModernBERT-base classifier for Fitz RAG
18
- governance. It emits four native v2 heads:
 
19
 
20
- - `evidence_verdict`: `INSUFFICIENT`, `DISPUTED`, `SUFFICIENT`
21
- - `failure_mode`: `none`, `unresolved_conflict`, `missing_or_incomplete_evidence`, `wrong_scope_or_version`, `ambiguous_request`
22
- - `retrieval_intents`: multi-label `needs_lookup`, `needs_temporal_resolution`, `needs_comparison_or_set`, `needs_broad_coverage`
23
- - `evidence_kinds`: multi-label `needs_text`, `needs_table_or_record`, `needs_code_or_symbol`, `needs_config_or_setting`, `needs_log_or_run_result`, `needs_document_layout`
24
 
25
- The model is intended for local governance in `fitz-sage`: decide whether
26
- retrieved evidence is sufficient, insufficient, or disputed, and expose
27
- actionable retrieval/failure metadata.
 
28
 
29
- ## Inputs
30
 
31
- Governance input:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  ```text
34
  Question: <user query>
@@ -38,38 +132,29 @@ Sources:
38
  [2] <retrieved source text>
39
  ```
40
 
41
- ## Output Decoding
42
-
43
- The 18 logits are not one flat softmax. Decode them by group:
44
 
45
  ```python
46
  import torch
47
- from transformers import AutoModelForSequenceClassification, PreTrainedTokenizerFast
48
 
49
- model_id = "yafitzdev/pyrrho-v2-nano-g1"
50
- tokenizer = PreTrainedTokenizerFast.from_pretrained(model_id)
51
- model = AutoModelForSequenceClassification.from_pretrained(model_id).eval()
52
 
53
- text = "Question: What is the capital of France?\n\nSources:\n[1] Paris is the capital of France."
54
- encoded = tokenizer(text, return_tensors="pt", truncation=True, max_length=2048)
55
- with torch.no_grad():
56
- logits = model(**encoded).logits[0]
57
-
58
- verdict_labels = ["INSUFFICIENT", "DISPUTED", "SUFFICIENT"]
59
- failure_labels = [
60
  "none",
61
  "unresolved_conflict",
62
  "missing_or_incomplete_evidence",
63
  "wrong_scope_or_version",
64
  "ambiguous_request",
65
  ]
66
- intent_labels = [
67
  "needs_lookup",
68
  "needs_temporal_resolution",
69
  "needs_comparison_or_set",
70
  "needs_broad_coverage",
71
  ]
72
- kind_labels = [
73
  "needs_text",
74
  "needs_table_or_record",
75
  "needs_code_or_symbol",
@@ -78,32 +163,61 @@ kind_labels = [
78
  "needs_document_layout",
79
  ]
80
 
81
- verdict = verdict_labels[int(torch.softmax(logits[0:3], dim=-1).argmax())]
82
- failure = failure_labels[int(torch.softmax(logits[3:8], dim=-1).argmax())]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  intents = [
84
- label for label, score in zip(intent_labels, torch.sigmoid(logits[8:12]))
85
  if float(score) >= 0.5
86
  ]
87
  kinds = [
88
- label for label, score in zip(kind_labels, torch.sigmoid(logits[12:18]))
89
  if float(score) >= 0.5
90
  ]
 
 
 
 
 
91
  ```
92
 
93
- ## Training Snapshot
 
 
94
 
95
- - Dataset: `fitz-gov-v2`
96
- - Clean active training rows: 41,358
97
- - Training source pointer: `fitz_gov_v2_41358_20260703`
98
- - Base model: `answerdotai/ModernBERT-base`
99
- - Seed: 42
100
 
101
- ## Local Evaluation
 
 
 
 
102
 
103
  Held-out training eval from `outputs/modernbert_base_v2_alpha_41358_active_20260704_seed42`:
104
 
105
  | Metric | Value |
106
- | --- | ---: |
107
  | overall score | 0.9497 |
108
  | verdict accuracy | 0.9727 |
109
  | false sufficient rate | 0.0455 |
@@ -113,16 +227,26 @@ Held-out training eval from `outputs/modernbert_base_v2_alpha_41358_active_20260
113
  | evidence-kind exact match | 0.9809 |
114
  | evidence-kind macro F1 | 0.9950 |
115
 
116
- Fitz-sage benchmark check for this release candidate:
117
 
118
  | Benchmark | Result |
119
- | --- | ---: |
120
  | balanced fixed-evidence governance sanity suite | 120/120 |
121
  | live fitz-sage benchmark | 86/120 |
122
 
123
- The live benchmark result is the practical integration target; the fixed-evidence
124
  suite is a minimal sanity check for the governance head.
125
 
 
 
 
 
 
 
 
 
 
 
126
  ## Artifacts
127
 
128
  This repository contains:
@@ -133,6 +257,20 @@ This repository contains:
133
  - tokenizer/config files
134
  - `manifest.json`: release metadata
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  ## License
137
 
138
  CC BY-NC 4.0. Free for research, evaluation, and personal use; commercial use
 
3
  base_model: answerdotai/ModernBERT-base
4
  library_name: transformers
5
  pipeline_tag: text-classification
6
+ language:
7
+ - en
8
  tags:
9
  - rag
10
  - governance
11
+ - hallucination-detection
12
+ - evidence-verification
13
  - pyrrho
14
  - fitz-gov-v2
15
  - modernbert
16
  - multi-label-classification
17
+ datasets:
18
+ - yafitzdev/fitz-gov-v2
19
+ metrics:
20
+ - accuracy
21
+ - f1
22
  ---
23
 
24
  # pyrrho-v2-nano-g1
25
 
26
+ `pyrrho-v2-nano-g1` is a small local RAG governance co-processor. It reads a user
27
+ question plus retrieved source passages, then returns whether the evidence is
28
+ `SUFFICIENT`, `DISPUTED`, or `INSUFFICIENT` before an answer is generated.
29
 
30
+ It is not an answer generator, not a retriever, and not an open-world fact
31
+ checker. It sits between retrieval and generation, or beside a retrieval
32
+ pipeline as a fast evidence-quality layer, so downstream systems can answer,
33
+ show a dispute, retry retrieval, or ask for missing evidence.
34
 
35
+ Compared with the older Pyrrho v1 line, v2 exposes a smaller native head shape:
36
+ one evidence verdict, one failure reason, and two compact multi-label metadata
37
+ heads. The goal is a cleaner governance contract for `fitz-sage` and other RAG
38
+ systems.
39
 
40
+ ## Native V2 Heads
41
 
42
+ | Head | Labels / values | Intended use |
43
+ |---|---|---|
44
+ | `evidence_verdict` | `SUFFICIENT`, `DISPUTED`, `INSUFFICIENT` | Post-retrieval evidence sufficiency and conflict decision. |
45
+ | `failure_mode` | `none`, `unresolved_conflict`, `missing_or_incomplete_evidence`, `wrong_scope_or_version`, `ambiguous_request` | Actionable reason when evidence is disputed or insufficient. |
46
+ | `retrieval_intents` | `needs_lookup`, `needs_temporal_resolution`, `needs_comparison_or_set`, `needs_broad_coverage` | Query/evidence task metadata for retry and retrieval policy. |
47
+ | `evidence_kinds` | `needs_text`, `needs_table_or_record`, `needs_code_or_symbol`, `needs_config_or_setting`, `needs_log_or_run_result`, `needs_document_layout` | Evidence-surface metadata for routing, audit, and missing-source hints. |
48
+
49
+ ## Output Contract
50
+
51
+ The raw Hugging Face model output is an 18-logit vector. It is not one flat
52
+ softmax. Decode it by head:
53
+
54
+ | Logit slice | Head | Decoding |
55
+ |---|---|---|
56
+ | `0:3` | `evidence_verdict` | softmax over `INSUFFICIENT`, `DISPUTED`, `SUFFICIENT` |
57
+ | `3:8` | `failure_mode` | softmax over the five failure labels |
58
+ | `8:12` | `retrieval_intents` | sigmoid multi-label scores |
59
+ | `12:18` | `evidence_kinds` | sigmoid multi-label scores |
60
+
61
+ Most integrations should expose a structured decision object derived from those
62
+ logits:
63
+
64
+ | Field | Meaning |
65
+ |---|---|
66
+ | `evidence_verdict.final_label` | Final v2 verdict: `SUFFICIENT`, `DISPUTED`, or `INSUFFICIENT`. |
67
+ | `evidence_verdict.probabilities` | Softmax probability distribution over the three verdict labels. |
68
+ | `failure_mode.final_label` | Most likely failure reason, or `none` for sufficient evidence. |
69
+ | `retrieval_intents.final_labels` | Intent labels above the configured sigmoid threshold. |
70
+ | `evidence_kinds.final_labels` | Evidence-kind labels above the configured sigmoid threshold. |
71
+ | `confidence` | Probability or score assigned to the selected label. |
72
+
73
+ Example normalized output:
74
+
75
+ ```json
76
+ {
77
+ "schema_version": "pyrrho_v2_prediction",
78
+ "evidence_verdict": {
79
+ "final_label": "DISPUTED",
80
+ "confidence": 0.86,
81
+ "probabilities": {
82
+ "INSUFFICIENT": 0.08,
83
+ "DISPUTED": 0.86,
84
+ "SUFFICIENT": 0.06
85
+ }
86
+ },
87
+ "failure_mode": {
88
+ "final_label": "unresolved_conflict",
89
+ "confidence": 0.81
90
+ },
91
+ "retrieval_intents": {
92
+ "final_labels": ["needs_comparison_or_set"],
93
+ "scores": {
94
+ "needs_comparison_or_set": 0.77
95
+ }
96
+ },
97
+ "evidence_kinds": {
98
+ "final_labels": ["needs_text", "needs_table_or_record"],
99
+ "scores": {
100
+ "needs_text": 0.91,
101
+ "needs_table_or_record": 0.63
102
+ }
103
+ }
104
+ }
105
+ ```
106
+
107
+ The model does not generate answers, citations, source spans, retrieval results,
108
+ or natural-language explanations. It classifies and scores the `(query,
109
+ retrieved_contexts)` evidence state.
110
+
111
+ ## Intended Use
112
+
113
+ Use this model when a RAG or retrieval system needs fast local signals about:
114
+
115
+ - whether retrieved evidence is enough to answer,
116
+ - whether retrieved evidence contains an unresolved conflict,
117
+ - why evidence is insufficient or disputed,
118
+ - whether another retrieval pass should focus on lookup, time, comparison, or broad coverage,
119
+ - which source surface appears relevant or missing,
120
+ - how to log governance decisions for later audit.
121
+
122
+ This model is not intended to verify facts outside the provided sources, replace
123
+ a retriever, write answers, or replace human review in high-stakes settings.
124
+
125
+ ## Input Format
126
 
127
  ```text
128
  Question: <user query>
 
132
  [2] <retrieved source text>
133
  ```
134
 
135
+ ## Quick Start
 
 
136
 
137
  ```python
138
  import torch
139
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
140
 
141
+ MODEL_ID = "yafitzdev/pyrrho-v2-nano-g1"
 
 
142
 
143
+ VERDICT_LABELS = ["INSUFFICIENT", "DISPUTED", "SUFFICIENT"]
144
+ FAILURE_LABELS = [
 
 
 
 
 
145
  "none",
146
  "unresolved_conflict",
147
  "missing_or_incomplete_evidence",
148
  "wrong_scope_or_version",
149
  "ambiguous_request",
150
  ]
151
+ INTENT_LABELS = [
152
  "needs_lookup",
153
  "needs_temporal_resolution",
154
  "needs_comparison_or_set",
155
  "needs_broad_coverage",
156
  ]
157
+ KIND_LABELS = [
158
  "needs_text",
159
  "needs_table_or_record",
160
  "needs_code_or_symbol",
 
163
  "needs_document_layout",
164
  ]
165
 
166
+ query = "Has the company achieved profitability?"
167
+ contexts = [
168
+ "The company posted net income of $4 million in Q2.",
169
+ "The company recorded a quarterly loss of $12 million in Q3.",
170
+ ]
171
+ text = "Question: " + query + "\n\nSources:\n" + "\n".join(
172
+ f"[{i}] {context}" for i, context in enumerate(contexts, start=1)
173
+ )
174
+
175
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
176
+ model = AutoModelForSequenceClassification.from_pretrained(MODEL_ID).eval()
177
+
178
+ inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=2048)
179
+ with torch.no_grad():
180
+ logits = model(**inputs).logits[0]
181
+
182
+ verdict_probs = torch.softmax(logits[0:3], dim=-1)
183
+ failure_probs = torch.softmax(logits[3:8], dim=-1)
184
+ intent_scores = torch.sigmoid(logits[8:12])
185
+ kind_scores = torch.sigmoid(logits[12:18])
186
+
187
+ verdict = VERDICT_LABELS[int(verdict_probs.argmax())]
188
+ failure = FAILURE_LABELS[int(failure_probs.argmax())]
189
  intents = [
190
+ label for label, score in zip(INTENT_LABELS, intent_scores)
191
  if float(score) >= 0.5
192
  ]
193
  kinds = [
194
+ label for label, score in zip(KIND_LABELS, kind_scores)
195
  if float(score) >= 0.5
196
  ]
197
+
198
+ print(verdict)
199
+ print(failure)
200
+ print(intents)
201
+ print(kinds)
202
  ```
203
 
204
+ ## CPU ONNX
205
+
206
+ The repository includes both FP32 and INT8 ONNX exports:
207
 
208
+ - `model.onnx`
209
+ - `model_quantized.onnx`
 
 
 
210
 
211
+ For CPU inference, load `model_quantized.onnx` through `onnxruntime` or an
212
+ Optimum ONNX runtime wrapper. Decode the resulting 18 logits using the same
213
+ slices shown above.
214
+
215
+ ## Evaluation
216
 
217
  Held-out training eval from `outputs/modernbert_base_v2_alpha_41358_active_20260704_seed42`:
218
 
219
  | Metric | Value |
220
+ |---|---:|
221
  | overall score | 0.9497 |
222
  | verdict accuracy | 0.9727 |
223
  | false sufficient rate | 0.0455 |
 
227
  | evidence-kind exact match | 0.9809 |
228
  | evidence-kind macro F1 | 0.9950 |
229
 
230
+ Fitz-sage release-candidate checks:
231
 
232
  | Benchmark | Result |
233
+ |---|---:|
234
  | balanced fixed-evidence governance sanity suite | 120/120 |
235
  | live fitz-sage benchmark | 86/120 |
236
 
237
+ The live benchmark result is the practical integration target. The fixed-evidence
238
  suite is a minimal sanity check for the governance head.
239
 
240
+ ## Training Data
241
+
242
+ | Field | Value |
243
+ |---|---|
244
+ | Dataset | [`fitz-gov-v2`](https://huggingface.co/datasets/yafitzdev/fitz-gov-v2) |
245
+ | Clean active training rows | 41,358 |
246
+ | Training source pointer | `fitz_gov_v2_41358_20260703` |
247
+ | Base model | `answerdotai/ModernBERT-base` |
248
+ | Seed | 42 |
249
+
250
  ## Artifacts
251
 
252
  This repository contains:
 
257
  - tokenizer/config files
258
  - `manifest.json`: release metadata
259
 
260
+ ## Limitations
261
+
262
+ 1. **Evidence-bounded judgment.** Pyrrho judges only the retrieved evidence it
263
+ is given. It does not retrieve new evidence or verify claims against outside
264
+ knowledge.
265
+ 2. **English synthetic training data.** The v2 dataset is English synthetic RAG
266
+ governance data. Multilingual behavior is not established.
267
+ 3. **Metadata heads are policy signals, not formal proof.** `retrieval_intents`
268
+ and `evidence_kinds` are useful routing and audit hints. They do not prove
269
+ SQL correctness, code execution behavior, or complete corpus coverage.
270
+ 4. **RAG integration still matters.** Bad retrieval can produce bad evidence
271
+ packs. Pyrrho can flag insufficiency or conflict, but it cannot recover
272
+ source material that was never retrieved.
273
+
274
  ## License
275
 
276
  CC BY-NC 4.0. Free for research, evaluation, and personal use; commercial use