ianblenke commited on
Commit
7e069b3
·
verified ·
1 Parent(s): f6534c4

Exp 164: upload constraint-propagation-arithmetic (Exp 151 artifact)

Browse files
Files changed (3) hide show
  1. README.md +163 -0
  2. config.json +38 -0
  3. model.safetensors +3 -0
README.md ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ tags:
3
+ - energy-based-model
4
+ - ising-model
5
+ - constraint-satisfaction
6
+ - arithmetic-verification
7
+ - carnot
8
+ license: apache-2.0
9
+ ---
10
+
11
+ > **Research Artifact — Not Production-Ready**
12
+ >
13
+ > This model verifies arithmetic responses using structural binary features,
14
+ > not semantic understanding. It achieves AUROC 0.997 on the held-out test
15
+ > set (Exp 89 self-bootstrap reference: 1.0). Factual or freeform answers
16
+ > are outside its scope.
17
+
18
+ # constraint-propagation-arithmetic
19
+
20
+ **Learned Ising constraint model for arithmetic response verification.**
21
+
22
+ This model was trained via discriminative Contrastive Divergence (Exp 62/89)
23
+ on 400 verified (question, correct answer, wrong answer) triples for arithmetic
24
+ problems: addition, multiplication, and modular arithmetic. It assigns a scalar
25
+ energy to any binary feature vector encoding a response. Lower energy means
26
+ the response is more likely correct.
27
+
28
+ ## What It Is
29
+
30
+ An Ising Energy-Based Model (EBM) with quadratic energy:
31
+
32
+ ```
33
+ E(x) = -(b^T s + s^T J s) s = 2x - 1 ∈ {-1, +1}^200
34
+ ```
35
+
36
+ Where:
37
+ - `x` is a 200-dimensional **binary feature vector** encoding structural
38
+ properties of an LLM response (presence of numbers, operators, answer
39
+ patterns — see *Feature Encoding* below).
40
+ - `J` is a 200×200 **coupling matrix** (symmetric, zero diagonal) — encodes
41
+ which feature pairs co-occur in arithmetic-correct responses.
42
+ - `b` is a 200-dim **bias vector** — encodes which features tend to be
43
+ active in correct responses.
44
+
45
+ Lower energy = response looks structurally like a correct arithmetic answer.
46
+
47
+ ## How It Was Trained
48
+
49
+ **Algorithm:** Discriminative Contrastive Divergence (full-batch)
50
+
51
+ | Hyperparameter | Value |
52
+ |---|---|
53
+ | Training pairs | 400 (80% of 500 generated) |
54
+ | Feature dimension | 200 binary features |
55
+ | Learning rate | 0.01 |
56
+ | L1 regularization | 0.0 |
57
+ | Weight decay | 0.005 |
58
+ | Epochs | 300 |
59
+ | Source | Exp 62 (domain CD) + Exp 89 (self-bootstrap) |
60
+
61
+ **Training data:** Programmatically generated (no LLM) triples of the form
62
+ `(question, correct_answer, wrong_answer)` for three sub-types:
63
+ - Addition: "What is A + B?" — wrong answers off-by-one, off-by-ten, carry errors.
64
+ - Multiplication: "What is A * B?" — wrong answers from adjacent products.
65
+ - Modular arithmetic: "What is A mod B?" — wrong answers ±1 or ±2.
66
+
67
+ ## Benchmark Results
68
+
69
+ | Metric | This export | Exp 89 reference |
70
+ |--------|-------------|-----------------|
71
+ | AUROC (test) | **0.9970** | 1.0000 |
72
+ | Accuracy (test) | **99.0%** | 100.0% |
73
+ | Test set size | 100 | 29 |
74
+ | Baseline AUROC | 0.5 | 0.5 |
75
+
76
+ The slight gap from Exp 89 is expected: Exp 89 used pipeline-extracted
77
+ constraint features (245 dims) while this export uses the simpler 200-dim
78
+ structural encoding from Exp 62.
79
+
80
+ ## Feature Encoding
81
+
82
+ Each response is encoded as a 200-dimensional binary vector. The `encode_answer`
83
+ function in `scripts/experiment_62_domain_constraint_learning.py` generates
84
+ these features:
85
+
86
+ | Group | Features | Examples |
87
+ |-------|----------|---------|
88
+ | Numeric (20) | digit/operator presence | has_number, has_plus, has_equals |
89
+ | Structural (40) | word/char counts, punctuation | short_answer, has_period |
90
+ | Domain-specific (80) | arithmetic/logic/code patterns | has_equation, has_if_then |
91
+ | Consistency (60) | question-answer agreement | q_numbers_in_answer |
92
+
93
+ ## Usage
94
+
95
+ ```python
96
+ import numpy as np
97
+ from carnot.inference.constraint_models import ConstraintPropagationModel
98
+
99
+ # Load model (local directory or HuggingFace Hub)
100
+ model = ConstraintPropagationModel.from_pretrained(
101
+ "exports/constraint-propagation-models/arithmetic"
102
+ )
103
+
104
+ # Encode a response as a 200-dim binary feature vector
105
+ from scripts.export_constraint_models import encode_answer
106
+ x = encode_answer("What is 47 + 28?", "The answer is 75.")
107
+
108
+ # Verify
109
+ energy = model.energy(x) # lower = more likely correct
110
+ score = model.score(x) # in (0,1); higher = more likely correct
111
+ print(f"Energy: {energy:.2f}, Score: {score:.3f}")
112
+ ```
113
+
114
+ ## Inspect Coupling Matrix
115
+
116
+ ```python
117
+ from safetensors.numpy import load_file
118
+ tensors = load_file("model.safetensors")
119
+ J = tensors["coupling"] # shape (200, 200), float32
120
+ b = tensors["bias"] # shape (200,), float32
121
+ print(f"Sparsity: {(J == 0).mean():.1%}")
122
+ print(f"Max |J_ij|: {abs(J).max():.4f}")
123
+ ```
124
+
125
+ ## Limitations
126
+
127
+ 1. **Structural features only**: Verifies whether a response *looks like* a
128
+ correct arithmetic answer (contains the right numbers, uses the right
129
+ phrasing). Does not parse or evaluate arithmetic expressions.
130
+ 2. **Template-generated training data**: Training pairs come from programmatic
131
+ generators, not real LLM outputs. May not generalize to unusual phrasings.
132
+ 3. **200-dim binary features**: Fine-grained semantic nuances are not captured.
133
+ A plausible wrong answer with the same structural features as a correct one
134
+ will have similar energy.
135
+ 4. **Feature encoder required**: You must encode responses with the same 200-dim
136
+ encoder used during training. Using a different encoder will produce garbage.
137
+ 5. **factual/scheduling not supported**: AUROC near 0.5 for those domains in
138
+ Exp 89 — the structural features don't discriminate factual correctness.
139
+
140
+ ## Files
141
+
142
+ | File | Description |
143
+ |------|-------------|
144
+ | `model.safetensors` | Coupling matrix J (200×200) and bias b (200,) as float32 |
145
+ | `config.json` | Training metadata, benchmark results, limitations |
146
+ | `README.md` | This file |
147
+
148
+ ## Citation
149
+
150
+ ```bibtex
151
+ @misc{carnot2026constraint_arith,
152
+ title = {Carnot Constraint Propagation Model: Arithmetic},
153
+ author = {Carnot-EBM},
154
+ year = {2026},
155
+ url = {https://github.com/ianblenke/carnot}
156
+ }
157
+ ```
158
+
159
+ ## Spec
160
+
161
+ - REQ-VERIFY-002: Energy-based verification of LLM responses.
162
+ - REQ-VERIFY-003: Correctness score derived from model energy.
163
+ - FR-11: Self-bootstrapped improvement of the verifier from pipeline outputs.
config.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model_type": "ising_constraint_model",
3
+ "domain": "arithmetic",
4
+ "feature_dim": 200,
5
+ "carnot_version": "0.1.0",
6
+ "spec": [
7
+ "REQ-VERIFY-002",
8
+ "REQ-VERIFY-003",
9
+ "FR-11"
10
+ ],
11
+ "training": {
12
+ "n_pairs": 500,
13
+ "n_train": 400,
14
+ "n_test": 100,
15
+ "algorithm": "discriminative_cd",
16
+ "lr": 0.01,
17
+ "l1_lambda": 0.0,
18
+ "weight_decay": 0.005,
19
+ "n_epochs": 300,
20
+ "source_experiments": [
21
+ "Exp-62",
22
+ "Exp-89"
23
+ ]
24
+ },
25
+ "benchmark": {
26
+ "auroc_reproduced": 0.997,
27
+ "accuracy_reproduced": 0.99,
28
+ "auroc_exp89_reference": 1.0,
29
+ "accuracy_exp89_reference": 1.0,
30
+ "n_test_exp89": 29
31
+ },
32
+ "limitations": [
33
+ "Feature encoder uses binary structural features \u2014 not embeddings.",
34
+ "Only learns from structural patterns, not semantics.",
35
+ "Exp 89 AUROC (1.0) was for self-bootstrapped pipeline data; this export uses simpler Exp 62-style deterministic encoding.",
36
+ "factual and scheduling domains not included (near-zero AUROC in Exp 89)."
37
+ ]
38
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4dbc574ab72ceb17da085ba4bc7058d16f3946990a73f81b293f28f914a1d594
3
+ size 160944