Add model references, feature guide and executable selective-routing example
Browse filesDocumentation and synthetic usage extension; frozen utility-router weights, config and original code remain byte-identical; no verifier weights or real dataset examples.
- MODEL_MANIFEST.json +46 -18
- MODEL_REFERENCE.md +19 -0
- README.md +24 -1
- USAGE_VALIDATION.json +28 -0
- docs/FEATURES.md +45 -0
- docs/USAGE.md +58 -0
- examples/selective_replacement.py +55 -0
MODEL_MANIFEST.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
{
|
| 2 |
-
"schema": "
|
| 3 |
"model": "FactCascade",
|
| 4 |
"license": "Apache-2.0",
|
| 5 |
"checkpoint": "router.json",
|
|
@@ -9,36 +9,31 @@
|
|
| 9 |
"pickle_or_verifier_weights_included": false,
|
| 10 |
"dataset_examples_or_gold_included": false,
|
| 11 |
"members_exclude_manifest_itself": true,
|
| 12 |
-
"file_count_including_manifest":
|
| 13 |
"files": [
|
| 14 |
{
|
| 15 |
-
"path": "
|
| 16 |
-
"bytes":
|
| 17 |
-
"C_E_direct_byte_equal": true
|
| 18 |
-
},
|
| 19 |
-
{
|
| 20 |
-
"path": "NOTICE",
|
| 21 |
-
"bytes": 218,
|
| 22 |
"C_E_direct_byte_equal": true
|
| 23 |
},
|
| 24 |
{
|
| 25 |
-
"path": "
|
| 26 |
-
"bytes":
|
| 27 |
"C_E_direct_byte_equal": true
|
| 28 |
},
|
| 29 |
{
|
| 30 |
-
"path": "
|
| 31 |
-
"bytes":
|
| 32 |
"C_E_direct_byte_equal": true
|
| 33 |
},
|
| 34 |
{
|
| 35 |
-
"path": "
|
| 36 |
-
"bytes":
|
| 37 |
"C_E_direct_byte_equal": true
|
| 38 |
},
|
| 39 |
{
|
| 40 |
-
"path": "
|
| 41 |
-
"bytes":
|
| 42 |
"C_E_direct_byte_equal": true
|
| 43 |
},
|
| 44 |
{
|
|
@@ -106,6 +101,26 @@
|
|
| 106 |
"bytes": 3886,
|
| 107 |
"C_E_direct_byte_equal": true
|
| 108 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
{
|
| 110 |
"path": "requirements.txt",
|
| 111 |
"bytes": 14,
|
|
@@ -115,7 +130,20 @@
|
|
| 115 |
"path": "router.json",
|
| 116 |
"bytes": 140644,
|
| 117 |
"C_E_direct_byte_equal": true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
}
|
| 119 |
],
|
| 120 |
-
"validation": "VALIDATION.json"
|
|
|
|
|
|
|
|
|
|
| 121 |
}
|
|
|
|
| 1 |
{
|
| 2 |
+
"schema": "FACTCASCADE_PUBLIC_ROUTER_MANIFEST_V2",
|
| 3 |
"model": "FactCascade",
|
| 4 |
"license": "Apache-2.0",
|
| 5 |
"checkpoint": "router.json",
|
|
|
|
| 9 |
"pickle_or_verifier_weights_included": false,
|
| 10 |
"dataset_examples_or_gold_included": false,
|
| 11 |
"members_exclude_manifest_itself": true,
|
| 12 |
+
"file_count_including_manifest": 27,
|
| 13 |
"files": [
|
| 14 |
{
|
| 15 |
+
"path": "config.json",
|
| 16 |
+
"bytes": 2929,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
"C_E_direct_byte_equal": true
|
| 18 |
},
|
| 19 |
{
|
| 20 |
+
"path": "docs/FEATURES.md",
|
| 21 |
+
"bytes": 4016,
|
| 22 |
"C_E_direct_byte_equal": true
|
| 23 |
},
|
| 24 |
{
|
| 25 |
+
"path": "docs/USAGE.md",
|
| 26 |
+
"bytes": 4069,
|
| 27 |
"C_E_direct_byte_equal": true
|
| 28 |
},
|
| 29 |
{
|
| 30 |
+
"path": "example.py",
|
| 31 |
+
"bytes": 385,
|
| 32 |
"C_E_direct_byte_equal": true
|
| 33 |
},
|
| 34 |
{
|
| 35 |
+
"path": "examples/selective_replacement.py",
|
| 36 |
+
"bytes": 2768,
|
| 37 |
"C_E_direct_byte_equal": true
|
| 38 |
},
|
| 39 |
{
|
|
|
|
| 101 |
"bytes": 3886,
|
| 102 |
"C_E_direct_byte_equal": true
|
| 103 |
},
|
| 104 |
+
{
|
| 105 |
+
"path": "LICENSE",
|
| 106 |
+
"bytes": 11358,
|
| 107 |
+
"C_E_direct_byte_equal": true
|
| 108 |
+
},
|
| 109 |
+
{
|
| 110 |
+
"path": "MODEL_REFERENCE.md",
|
| 111 |
+
"bytes": 2483,
|
| 112 |
+
"C_E_direct_byte_equal": true
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"path": "NOTICE",
|
| 116 |
+
"bytes": 218,
|
| 117 |
+
"C_E_direct_byte_equal": true
|
| 118 |
+
},
|
| 119 |
+
{
|
| 120 |
+
"path": "README.md",
|
| 121 |
+
"bytes": 5934,
|
| 122 |
+
"C_E_direct_byte_equal": true
|
| 123 |
+
},
|
| 124 |
{
|
| 125 |
"path": "requirements.txt",
|
| 126 |
"bytes": 14,
|
|
|
|
| 130 |
"path": "router.json",
|
| 131 |
"bytes": 140644,
|
| 132 |
"C_E_direct_byte_equal": true
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"path": "USAGE_VALIDATION.json",
|
| 136 |
+
"bytes": 939,
|
| 137 |
+
"C_E_direct_byte_equal": true
|
| 138 |
+
},
|
| 139 |
+
{
|
| 140 |
+
"path": "VALIDATION.json",
|
| 141 |
+
"bytes": 738,
|
| 142 |
+
"C_E_direct_byte_equal": true
|
| 143 |
}
|
| 144 |
],
|
| 145 |
+
"validation": "VALIDATION.json",
|
| 146 |
+
"synthetic_usage_example_included": true,
|
| 147 |
+
"real_dataset_examples_or_gold_included": false,
|
| 148 |
+
"original_frozen_weight_revision": "08bd580bb9f81908295354a678b4c048ac72e40a"
|
| 149 |
}
|
MODEL_REFERENCE.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Model reference and exact frozen dependencies
|
| 2 |
+
|
| 3 |
+
System: **FactCascade: Utility-Guided Routing for Selective Factuality Verification**.
|
| 4 |
+
|
| 5 |
+
| Component | Checkpoint | Frozen revision | Link |
|
| 6 |
+
|---|---|---|---|
|
| 7 |
+
| FactCascade utility router | `router.json` | Original weight release `08bd580bb9f81908295354a678b4c048ac72e40a` | [Pinned router](https://huggingface.co/nhnk/FactCascade/blob/08bd580bb9f81908295354a678b4c048ac72e40a/router.json) |
|
| 8 |
+
| FT5 | `lytang/MiniCheck-Flan-T5-Large` | `a496016e7b493686ed6e1c52250b9b9d39b0dcb2` | [Hugging Face](https://huggingface.co/lytang/MiniCheck-Flan-T5-Large/tree/a496016e7b493686ed6e1c52250b9b9d39b0dcb2) |
|
| 9 |
+
| B192 / DeBERTa | `lytang/MiniCheck-DeBERTa-v3-Large` | `2f2d01a54fa022a7ffadb76260e1ea8bc88c82bb` | [Hugging Face](https://huggingface.co/lytang/MiniCheck-DeBERTa-v3-Large/tree/2f2d01a54fa022a7ffadb76260e1ea8bc88c82bb) |
|
| 10 |
+
| Bespoke | `bespokelabs/Bespoke-MiniCheck-7B` | `17b48556b0a54218e8fc2f0dbf0c50fa65a0cfba` | [Hugging Face](https://huggingface.co/bespokelabs/Bespoke-MiniCheck-7B/tree/17b48556b0a54218e8fc2f0dbf0c50fa65a0cfba) |
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
The original trained utility checkpoint is a portable JSON NumPy histogram gradient booster:31 ordered features,100 trees,maximum depth2. Learning recipe:learning_rate0.05,min_samples_leaf30,max_bins255,random_state0; full-DEV3337rows/1397groups. Learned tree/bin/preprocessing parameters are already included; no fit is needed.
|
| 14 |
+
|
| 15 |
+
`config.json` is authoritative for feature order, threshold operators, component-wise quota920/3337,midrank equal-weight fusion and stable row-key ties. FT5 fallback>0.763,FT5 standalone>0.5,B192>=0.398,Bespoke>0.5. A router output estimates signed correctness change; it is not a support probability.
|
| 16 |
+
|
| 17 |
+
The pinned original weight revision remains a stable reference after documentation changes. No verifier weights are mirrored here. Use each upstream publisher's native adapter and license; the pinned Bespoke model card states CC BY-NC4.0. The FactCascade router/own-code Apache-2.0 license does not relicense any dependency. Config checkpoint dtype/context metadata are not verified deployment precision/capacity guarantees.
|
| 18 |
+
|
| 19 |
+
This full-DEV frozen router is distinct from later diagnostic OOF/source-heldout fits and saved FCE predicted-correctness baseline heads. Those heads are not included. `VALIDATION.json` describes original parameter serialization parity; [USAGE_VALIDATION.json](USAGE_VALIDATION.json) documents the additional synthetic usage example only.
|
README.md
CHANGED
|
@@ -17,6 +17,29 @@ This repository provides the **trained frozen utility-router checkpoint** and th
|
|
| 17 |
|
| 18 |
The router estimates the expected signed change in correctness when a Bespoke decision replaces a cheap-verifier fallback. The frozen FactCascade allocation combines equal-weight empirical midranks of this estimate and the raw FT5/DeBERTa score gap, then selects a half-up quota of `920/3337` per component, with stable row-key ties. `config.json` gives the exact feature order, thresholds, quota and pinned verifier revisions.
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
## Load the existing trained checkpoint
|
| 21 |
|
| 22 |
Download the repository files, install `numpy==1.26.4`, and run:
|
|
@@ -49,4 +72,4 @@ This checkpoint is the original frozen full-DEV utility model. It is distinct fr
|
|
| 49 |
|
| 50 |
FactCascade requires scores from [MiniCheck-Flan-T5-Large](https://huggingface.co/lytang/MiniCheck-Flan-T5-Large), [MiniCheck-DeBERTa-v3-Large](https://huggingface.co/lytang/MiniCheck-DeBERTa-v3-Large) and [Bespoke-MiniCheck-7B](https://huggingface.co/bespokelabs/Bespoke-MiniCheck-7B); exact revisions are in `config.json`. Obtain those models separately and follow their licenses. In particular, the pinned Bespoke model card specifies CC BY-NC 4.0. The Apache-2.0 license here covers the FactCascade router checkpoint and own code, and does not relicense upstream verifier models or datasets.
|
| 51 |
|
| 52 |
-
Only model parameters, own code, frozen configuration and aggregate validation metadata are released. No claim/evidence text, labels, dataset rows, saved example scores, private paths or credentials are included.
|
|
|
|
| 17 |
|
| 18 |
The router estimates the expected signed change in correctness when a Bespoke decision replaces a cheap-verifier fallback. The frozen FactCascade allocation combines equal-weight empirical midranks of this estimate and the raw FT5/DeBERTa score gap, then selects a half-up quota of `920/3337` per component, with stable row-key ties. `config.json` gives the exact feature order, thresholds, quota and pinned verifier revisions.
|
| 19 |
|
| 20 |
+
## Repository contents and quick start
|
| 21 |
+
|
| 22 |
+
| Files | Purpose |
|
| 23 |
+
|---|---|
|
| 24 |
+
| `router.json` | Existing trained utility-router weights and DEV-only preprocessing |
|
| 25 |
+
| `config.json` | Frozen31feature order,policy,thresholds and upstream verifier revisions |
|
| 26 |
+
| `factcascade/` | NumPy feature,checkpoint loading,rank fusion,quota,replacement,metrics and adapter code |
|
| 27 |
+
| [MODEL_REFERENCE.md](MODEL_REFERENCE.md) | Model names,exact checkpoint revisions,pinned Hugging Face links and license scope |
|
| 28 |
+
| [docs/USAGE.md](docs/USAGE.md) | Download/setup,inputs,batch routing and selective replacement integration |
|
| 29 |
+
| [docs/FEATURES.md](docs/FEATURES.md) | All31slot definitions and DEV/external adapter differences |
|
| 30 |
+
| [examples/selective_replacement.py](examples/selective_replacement.py) | Runnable synthetic feature-to-routing-to-replacement example |
|
| 31 |
+
| `VALIDATION.json`, `USAGE_VALIDATION.json` | Original serialization parity and synthetic usage checks,respectively |
|
| 32 |
+
|
| 33 |
+
```bash
|
| 34 |
+
hf download nhnk/FactCascade --local-dir FactCascade
|
| 35 |
+
cd FactCascade
|
| 36 |
+
python -m pip install -r requirements.txt
|
| 37 |
+
python -B example.py
|
| 38 |
+
python -B examples/selective_replacement.py
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
The synthetic example uses invented scores/text and executes no verifier. Real deployment supplies the pinned native FT5/B192 observations and then calls Bespoke on the selected rows. Changing packet segmentation or batch boundaries changes the scientific operation;see the usage guide. The original checkpoint revision remains `08bd580bb9f81908295354a678b4c048ac72e40a`;this extension changes documentation/examples,not trained parameters.
|
| 42 |
+
|
| 43 |
## Load the existing trained checkpoint
|
| 44 |
|
| 45 |
Download the repository files, install `numpy==1.26.4`, and run:
|
|
|
|
| 72 |
|
| 73 |
FactCascade requires scores from [MiniCheck-Flan-T5-Large](https://huggingface.co/lytang/MiniCheck-Flan-T5-Large), [MiniCheck-DeBERTa-v3-Large](https://huggingface.co/lytang/MiniCheck-DeBERTa-v3-Large) and [Bespoke-MiniCheck-7B](https://huggingface.co/bespokelabs/Bespoke-MiniCheck-7B); exact revisions are in `config.json`. Obtain those models separately and follow their licenses. In particular, the pinned Bespoke model card specifies CC BY-NC 4.0. The Apache-2.0 license here covers the FactCascade router checkpoint and own code, and does not relicense upstream verifier models or datasets.
|
| 74 |
|
| 75 |
+
Only model parameters, own code, frozen configuration and aggregate validation metadata are released. No real dataset claim/evidence text, gold labels, dataset rows, saved real example scores, private paths or credentials are included. The usage example contains explicitly invented toy text and observations.
|
USAGE_VALIDATION.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"schema": "FACTCASCADE_SYNTHETIC_USAGE_VALIDATION_V1",
|
| 3 |
+
"frozen_checkpoint_revision": "08bd580bb9f81908295354a678b4c048ac72e40a",
|
| 4 |
+
"router_config_existing_code_bytes_unchanged": true,
|
| 5 |
+
"synthetic_example": {
|
| 6 |
+
"features_shape": [
|
| 7 |
+
8,
|
| 8 |
+
31
|
| 9 |
+
],
|
| 10 |
+
"components": 2,
|
| 11 |
+
"selected_rows": 2,
|
| 12 |
+
"selective_replacement_pass": true,
|
| 13 |
+
"unrouted_fallback_unchanged": true,
|
| 14 |
+
"native_verifier_calls": 0,
|
| 15 |
+
"fitting_calls": 0,
|
| 16 |
+
"benchmark_rows": 0
|
| 17 |
+
},
|
| 18 |
+
"demo_purpose": "API integration/synthetic semantics only; no quality/generalization/runtime claims",
|
| 19 |
+
"real_dataset_rows_labels_or_verifier_weights": 0,
|
| 20 |
+
"new_fits_native_verifier_inference_GPU_hash_operations": 0,
|
| 21 |
+
"edge_semantics": {
|
| 22 |
+
"stable_ties_in_two_components": "PASS",
|
| 23 |
+
"singleton_half_up_quota": "PASS",
|
| 24 |
+
"strict_and_inclusive_threshold_boundaries": "PASS",
|
| 25 |
+
"incorrect_feature_count_rejected": "PASS",
|
| 26 |
+
"synthetic_only": true
|
| 27 |
+
}
|
| 28 |
+
}
|
docs/FEATURES.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Exact ordered feature schema
|
| 2 |
+
|
| 3 |
+
`build_features` returns31float64 slots in the following order. `UtilityModel.load` validates that order against the saved checkpoint; preprocessing uses the saved DEV-only medians,means and scales. Never reorder columns or fit a new scaler on an evaluation cohort.
|
| 4 |
+
|
| 5 |
+
Here s=selected FT5 score,f=full FT5 score,d=B192 score. The implementation `factcascade/features.py` is authoritative for regex/token/overlap details and missing-data behavior.
|
| 6 |
+
|
| 7 |
+
| Slot | Name | Meaning |
|
| 8 |
+
|---|---|---|
|
| 9 |
+
| 1 | `ft5_score` | Selected FT5 support score s. |
|
| 10 |
+
| 2 | `ft5_abs_distance_to_calibrated_threshold` | abs(s-0.763). |
|
| 11 |
+
| 3 | `b192_score` | B192 support score d. |
|
| 12 |
+
| 4 | `ft5_b192_delta` | s-d. |
|
| 13 |
+
| 5 | `ft5_b192_disagreement` | Indicator of (s>0.763) differing from (d>=0.398). |
|
| 14 |
+
| 6 | `table_or_mixed_indicator` | TABLE_OR_MIXED modality flag. |
|
| 15 |
+
| 7 | `ft5_margin_x_table` | abs(s-0.763) multiplied by table flag. |
|
| 16 |
+
| 8 | `ft5_full_score` | Full-packet FT5 support score f. |
|
| 17 |
+
| 9 | `selected_full_score_delta` | f-s. |
|
| 18 |
+
| 10 | `selected_full_disagreement` | Indicator of (f>0.763) differing from (s>0.763). |
|
| 19 |
+
| 11 | `log_ft5_selected_chunks` | log1p(selected FT5 chunk count). |
|
| 20 |
+
| 12 | `log_ft5_full_chunks` | log1p(full FT5 chunk count). |
|
| 21 |
+
| 13 | `log_claim_word_count` | log1p(claim whitespace word count). |
|
| 22 |
+
| 14 | `log_selected_evidence_words` | log1p(selected-evidence whitespace word count). |
|
| 23 |
+
| 15 | `log_full_evidence_words` | log1p(full-evidence whitespace word count). |
|
| 24 |
+
| 16 | `log_selected_source_count` | log1p(selected-source count). |
|
| 25 |
+
| 17 | `selected_source_coverage_ratio` | Supplied selected-source coverage ratio. |
|
| 26 |
+
| 18 | `ft5_selected_margin_to_050` | abs(s-0.5). |
|
| 27 |
+
| 19 | `ft5_selected_margin_to_0763` | abs(s-0.763). |
|
| 28 |
+
| 20 | `ft5_full_minus_selected` | f-s. |
|
| 29 |
+
| 21 | `b192_minus_ft5_selected` | d-s. |
|
| 30 |
+
| 22 | `b192_ft5_decision_disagreement` | Historical extra-block disagreement: DEV uses s>0.763, external uses s>0.5, against d>=0.398. |
|
| 31 |
+
| 23 | `full_only_support_signal` | Indicator of f>0.763 and s<=0.763. |
|
| 32 |
+
| 24 | `b192_disagreement_x_table_or_mixed` | Slot22 disagreement multiplied by table flag. |
|
| 33 |
+
| 25 | `selected_full_discrepancy_x_evidence_length_ratio` | abs(f-s)*log1p(full words)/max(1,log1p(selected words)). |
|
| 34 |
+
| 26 | `claim_negation_proxy_count` | Negation matches plus bounded content terms in negation scope; surface proxy. |
|
| 35 |
+
| 27 | `claim_comparator_quantifier_count` | Comparator/quantifier regex match count. |
|
| 36 |
+
| 28 | `claim_numeral_unit_count` | Numeral/unit regex match count. |
|
| 37 |
+
| 29 | `claim_titlecase_entity_proxy_count` | Titlecase entity surface-proxy count,capped at20; no NER model. |
|
| 38 |
+
| 30 | `claim_selected_number_overlap_ratio` | Claim numeric strings shared with selected evidence / claim numeric-string count;0 if empty. |
|
| 39 |
+
| 31 | `claim_entity_selected_minus_full_overlap` | Claim-entity overlap with selected evidence minus overlap with full evidence;0 for empty claim entity set. |
|
| 40 |
+
|
| 41 |
+
Some original names use "disagreement" for a label-derived indicator:slot5 uses the calibrated fallback convention,while slot22 uses the adapter-specific historical convention. Allocation independently uses the raw score gap abs(s-d) in equal-weight rank fusion. These quantities must not be conflated or silently recalibrated.
|
| 42 |
+
|
| 43 |
+
Required build_features keyword arguments:claim,selected_evidence,full_evidence,selected_ft5_score,full_ft5_score,deberta_score,selected_chunks,full_chunks. Optional values are selected_source_count,source_coverage,table_or_mixed,adapter;use registered source geometry and explicit adapter. `adapter="external"` is default,while "dev" preserves the historical extra-block convention. The trained loader supports saved missing-value imputation;the convenience constructor validates supplied scores/counts/text and returns a finite feature vector.
|
| 44 |
+
|
| 45 |
+
This API consumes native verifier observations;it does not run inference,generate evidence,select a source protocol or infer that two adapters are scientifically interchangeable.
|
docs/USAGE.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Using the frozen FactCascade router
|
| 2 |
+
|
| 3 |
+
## Download the release
|
| 4 |
+
|
| 5 |
+
Download this repository with the Hugging Face browser or CLI, then work from its root:
|
| 6 |
+
|
| 7 |
+
```bash
|
| 8 |
+
hf download nhnk/FactCascade --local-dir FactCascade
|
| 9 |
+
cd FactCascade
|
| 10 |
+
python -m pip install -r requirements.txt
|
| 11 |
+
python -B example.py
|
| 12 |
+
python -B examples/selective_replacement.py
|
| 13 |
+
```
|
| 14 |
+
|
| 15 |
+
The first example loads the existing trained JSON checkpoint. The second constructs synthetic31-slot features, routes two components under the frozen quota and replaces only selected rows. All verifier observations/text in that example are invented; no native verifier, real benchmark, gold label, fit or quality measurement is executed.
|
| 16 |
+
|
| 17 |
+
The original router/config/code can also be retrieved at weight-release revision `08bd580bb9f81908295354a678b4c048ac72e40a`. Documentation/examples were extended in later commits while keeping those bytes unchanged. Use a pinned release revision when reproducing a workflow.
|
| 18 |
+
|
| 19 |
+
## Supply the required observations
|
| 20 |
+
|
| 21 |
+
For each row, obtain canonical selected-packet FT5, full-packet FT5 and B192 support scores using the native frozen adapters. Provide claim text,selected/full evidence,chunk counts,selected-source count,coverage ratio and modality. See [FEATURES.md](FEATURES.md) and `factcascade/features.py`.
|
| 22 |
+
|
| 23 |
+
Scores must be finite support observations in[0,1]; they are not arbitrary logits. FT5 segmentation/full-packet aggregation, geometry/source-coverage definitions and component membership must match the intended source protocol. `build_features(adapter="external")` and `adapter="dev"` retain different historical conventions for one extra-feature disagreement signal; use the exact appropriate adapter. This repo does not reconstruct evidence packets or run upstream verifier inference.
|
| 24 |
+
|
| 25 |
+
```python
|
| 26 |
+
import numpy as np
|
| 27 |
+
from factcascade.features import build_features
|
| 28 |
+
from factcascade.utility_model import UtilityModel
|
| 29 |
+
from factcascade.routing import route_batch, apply_replacement
|
| 30 |
+
|
| 31 |
+
# observations is a caller-supplied list of canonical score/geometry/text mappings.
|
| 32 |
+
X = np.vstack([build_features(**row) for row in observations])
|
| 33 |
+
model = UtilityModel.load("router.json")
|
| 34 |
+
routing = route_batch(
|
| 35 |
+
selected_ft5_scores=selected_scores,
|
| 36 |
+
deberta_scores=deberta_scores,
|
| 37 |
+
batch_ids=component_ids,
|
| 38 |
+
features=X, utility_model=model, row_keys=stable_row_keys,
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
# Caller executes the pinned native Bespoke verifier ONLY on selected indices.
|
| 42 |
+
indices = np.flatnonzero(routing.route_mask)
|
| 43 |
+
bespoke_scores = np.full(len(X), np.nan)
|
| 44 |
+
bespoke_scores[indices] = run_native_bespoke_for_indices(indices)
|
| 45 |
+
predictions = apply_replacement(selected_scores, bespoke_scores, routing.route_mask)
|
| 46 |
+
```
|
| 47 |
+
|
| 48 |
+
The second snippet is an integration sketch;caller-supplied observations and `run_native_bespoke_for_indices` are placeholders,not an included inference service. The executable self-contained synthetic version is `examples/selective_replacement.py`.
|
| 49 |
+
|
| 50 |
+
## Allocation and replacement semantics
|
| 51 |
+
|
| 52 |
+
Ranking is batch/component-relative. Equal utility/disagreement midranks are averaged,then top-k selected with integer half-up quota920/3337 and stable ascending row-key tie breaks. Changing component boundaries,online window size or tie keys changes routes. This is batch allocation,not independent per-row online threshold routing.
|
| 53 |
+
|
| 54 |
+
Unrouted decisions remain `selected_FT5_score>0.763`. Routed decisions become `Bespoke_score>0.5`. Unrouted expensive scores may beNaN; the API does not require all-row Bespoke scoring. Selected rows may still receive harmful reversals; selection does not certify correctness.
|
| 55 |
+
|
| 56 |
+
## Reproduction scope
|
| 57 |
+
|
| 58 |
+
The released weights come from the historical unweighted signed-correctness target and full-DEV fit. They are not newly fitted diagnostics. Synthetically verified API/serialization behavior is not additional generalization evidence. No real examples/labels/verifierweights or complete inference environment are published;dataset licenses and upstreammodel terms remain separate. This lightweight router release is distinct from the cached reviewer reproduction capsule.
|
examples/selective_replacement.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Synthetic feature -> frozen router -> selected replacement example.
|
| 2 |
+
|
| 3 |
+
No pretrained verifier is loaded. All observations/text are invented toy inputs;
|
| 4 |
+
there is no benchmark data, gold label, metric evaluation or fitting.
|
| 5 |
+
"""
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
import sys
|
| 8 |
+
ROOT = Path(__file__).resolve().parents[1]
|
| 9 |
+
sys.path.insert(0, str(ROOT))
|
| 10 |
+
import numpy as np
|
| 11 |
+
from factcascade.features import build_features
|
| 12 |
+
from factcascade.utility_model import UtilityModel
|
| 13 |
+
from factcascade.routing import route_batch, apply_replacement
|
| 14 |
+
from factcascade.quota import half_up_quota
|
| 15 |
+
|
| 16 |
+
def run_demo():
|
| 17 |
+
selected = np.array([0.80, 0.70, 0.95, 0.30, 0.65, 0.90, 0.55, 0.80])
|
| 18 |
+
full = np.array([0.90, 0.75, 0.95, 0.45, 0.70, 0.95, 0.80, 0.85])
|
| 19 |
+
deberta = np.array([0.70, 0.20, 0.80, 0.70, 0.60, 0.10, 0.40, 0.85])
|
| 20 |
+
batches = ['toy-a'] * 4 + ['toy-b'] * 4
|
| 21 |
+
keys = [f'toy-{i:02d}' for i in range(8)]
|
| 22 |
+
x = np.vstack([
|
| 23 |
+
build_features(
|
| 24 |
+
claim=f'Example Town has {i + 1} bridges.',
|
| 25 |
+
selected_evidence=f'The invented example lists {i + 1} bridges in Example Town.',
|
| 26 |
+
full_evidence=f'The invented example lists {i + 1} bridges in Example Town. This is synthetic.',
|
| 27 |
+
selected_ft5_score=float(selected[i]), full_ft5_score=float(full[i]),
|
| 28 |
+
deberta_score=float(deberta[i]), selected_chunks=1, full_chunks=1,
|
| 29 |
+
selected_source_count=1, source_coverage=1.0, adapter='external',
|
| 30 |
+
) for i in range(8)
|
| 31 |
+
])
|
| 32 |
+
model = UtilityModel.load(ROOT / 'router.json')
|
| 33 |
+
routed = route_batch(
|
| 34 |
+
selected_ft5_scores=selected, deberta_scores=deberta,
|
| 35 |
+
batch_ids=batches, features=x, utility_model=model, row_keys=keys,
|
| 36 |
+
)
|
| 37 |
+
# In a real application, call Bespoke only for these indices, using the
|
| 38 |
+
# frozen native input protocol. Here substitute invented observations.
|
| 39 |
+
idx = np.flatnonzero(routed.route_mask)
|
| 40 |
+
expensive = np.full(8, np.nan)
|
| 41 |
+
expensive[idx] = np.array([0.82, 0.28])
|
| 42 |
+
final = apply_replacement(selected, expensive, routed.route_mask)
|
| 43 |
+
for batch in set(batches):
|
| 44 |
+
member = np.array([b == batch for b in batches])
|
| 45 |
+
assert int(routed.route_mask[member].sum()) == half_up_quota(int(member.sum()))
|
| 46 |
+
assert np.array_equal(final[~routed.route_mask], (selected > 0.763)[~routed.route_mask])
|
| 47 |
+
assert np.array_equal(final[routed.route_mask], expensive[routed.route_mask] > 0.5)
|
| 48 |
+
assert x.shape == (8, 31) and len(idx) == 2
|
| 49 |
+
return dict(features_shape=list(x.shape), components=2, selected_rows=int(len(idx)),
|
| 50 |
+
selective_replacement_pass=True, unrouted_fallback_unchanged=True,
|
| 51 |
+
native_verifier_calls=0, fitting_calls=0, benchmark_rows=0)
|
| 52 |
+
|
| 53 |
+
if __name__ == '__main__':
|
| 54 |
+
import json
|
| 55 |
+
print(json.dumps(run_demo(), indent=2))
|