Shuyu12138 commited on
Commit
cb2b51c
·
verified ·
1 Parent(s): f02de93

Release SanSi (seed 0): LoRA adapter, readouts and model card

Browse files
README.md ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - en
5
+ library_name: peft
6
+ base_model: ByteDance/Ouro-1.4B
7
+ tags:
8
+ - looped-language-model
9
+ - typed-decision
10
+ - calibration
11
+ - lora
12
+ ---
13
+
14
+ # SanSi
15
+
16
+ <p align="center">
17
+ <a href="https://minnesotanlp.github.io/Sansi/"><img src="https://img.shields.io/badge/Website-Project%20Page-1E90FF.svg?logo=googlechrome&logoColor=white" alt="Project page"/></a>
18
+ <a href="https://arxiv.org/abs/2610.07730"><img src="https://img.shields.io/badge/arXiv-2610.07730-B31B1B.svg?logo=arxiv&logoColor=white" alt="arXiv"/></a>
19
+ <a href="https://github.com/minnesotanlp/Sansi"><img src="https://img.shields.io/badge/GitHub-Code-181717.svg?logo=github" alt="Code"/></a>
20
+ <a href="https://huggingface.co/minnesotanlp/SanSi-2.6B"><img src="https://img.shields.io/badge/-SanSi--2.6B-FFD21E?logo=huggingface&logoColor=black" alt="SanSi-2.6B"/></a>
21
+ <a href="https://www.apache.org/licenses/LICENSE-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="Apache 2.0"/></a>
22
+ </p>
23
+
24
+ SanSi is the model of the paper [SanSi: A Looped Typed Decision Model for System 1.5 Thinking](https://arxiv.org/abs/2610.07730).
25
+ It is a typed decision model: given a text (the state), a question and 2 to 26 declared options, it returns a
26
+ probability for each option, without generating text. It is built on
27
+ [Ouro-1.4B](https://huggingface.co/ByteDance/Ouro-1.4B), a language model pre-trained to loop: one stack of 24 shared
28
+ layers is applied T = 8 times. The option probabilities are read after every loop, so one forward pass gives the
29
+ decision at every budget from one loop to eight.
30
+
31
+ This repository holds what was trained: LoRA adapters of rank 64 and one small readout per loop, 60.8M parameters.
32
+ The backbone stays frozen; it is downloaded from `ByteDance/Ouro-1.4B` at the revision the model was trained on.
33
+
34
+ | Model | Backbone | Trained parameters | Accuracy after loop 8 |
35
+ |---|---|---:|---:|
36
+ | **SanSi** (this model) | Ouro-1.4B | 60.8M | 72.0 |
37
+ | [SanSi-2.6B](https://huggingface.co/minnesotanlp/SanSi-2.6B) | Ouro-2.6B | 121.4M | 75.8 |
38
+
39
+ Accuracy (%) on the 10,027 test items of the paper, mean of three training seeds.
40
+
41
+ ## How to use
42
+
43
+ The loading code is in the [GitHub repository](https://github.com/minnesotanlp/Sansi). Use a GPU; the backbone runs
44
+ in bfloat16.
45
+
46
+ ```bash
47
+ git clone https://github.com/minnesotanlp/Sansi
48
+ cd Sansi
49
+ pip install -r requirements.txt
50
+ ```
51
+
52
+ ```python
53
+ from sansi.hub import load, decide
54
+
55
+ model, tok = load("minnesotanlp/SanSi") # this adapter, and Ouro-1.4B at its pinned revision
56
+
57
+ probs = decide(
58
+ model, tok,
59
+ state="Mia is taller than Sam. Sam is taller than Lee.",
60
+ question="Who is the shortest?",
61
+ options=["Mia", "Sam", "Lee"],
62
+ )
63
+ print(probs[0]) # after loop 1, at an eighth of the computation: about [0.02, 0.07, 0.91]
64
+ print(probs[-1]) # after loop 8: about [0.00, 0.00, 1.00]
65
+ ```
66
+
67
+ `decide` returns one list per loop, each with one probability per option in the order given. It writes the prompt
68
+ the model was trained on,
69
+
70
+ ```
71
+ <state>
72
+
73
+ Question: <question>
74
+ Options: (A) <option 1> (B) <option 2> ...
75
+ Answer:
76
+ ```
77
+
78
+ and reads the option letters at its last token after every loop. `decide(..., loops=4)` runs four loops only, at half
79
+ the computation (71.6% instead of 72.0% on the test items). To run a whole dataset, use `eval/evaluate.py` of the
80
+ repository. An item whose answer the state does not give was trained towards the uniform distribution: a low top
81
+ probability means that the model does not commit to an answer (the paper counts a hard answer when the top
82
+ probability reaches (1 + 1/K) / 2 for K options).
83
+
84
+ ## Results
85
+
86
+ Accuracy (%) on the 10,027 test items after every loop: the mean of the three training seeds of the paper, and this
87
+ checkpoint (seed 0).
88
+
89
+ | Loop | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
90
+ |---|---:|---:|---:|---:|---:|---:|---:|---:|
91
+ | Mean of three seeds | 58.4 | 66.9 | 70.4 | 71.6 | 71.9 | 72.1 | 72.1 | 72.0 |
92
+ | This checkpoint (seed 0) | 57.7 | 67.2 | 70.4 | 71.2 | 71.2 | 71.4 | 71.4 | 71.3 |
93
+
94
+ The main comparison of the paper: all models are trained on the same data, with the same recipe except Kev-4B (our
95
+ data), which uses Kev's code; mean of three seeds. In-distribution items come from the training sources, near
96
+ transfer from harder or reworded versions of them, far transfer from sources never trained on. Cost is the GPU time
97
+ of one pass over the test items, with one loop of Ouro-1.4B as 1.
98
+
99
+ | Model | Params | Loops | Cost | All | In-dist. | Near | Far | ECE |
100
+ |---|---:|---:|---:|---:|---:|---:|---:|---:|
101
+ | SmolLM2-1.7B | 1.7B | 1 | 1.1 | 58.4 | 76.1 | 57.7 | 52.3 | 0.069 |
102
+ | Ouro-1.4B, one loop | 1.4B | 1 | 1.0 | 58.6 | 77.3 | 59.9 | 51.3 | 0.137 |
103
+ | Qwen3.5-2B | 1.9B | 1 | 1.2 | 66.7 | 84.3 | 62.3 | 61.7 | 0.123 |
104
+ | Qwen3.5-4B | 4.2B | 1 | 2.4 | 73.8 | 88.5 | 68.9 | 70.1 | 0.113 |
105
+ | Kev-4B (our data) | 4.2B | 1 | 2.1 | 74.3 | 88.6 | 70.9 | 70.3 | 0.119 |
106
+ | **SanSi** | 1.4B | 8 | 7.7 | 72.0 | 86.6 | 67.7 | 68.0 | 0.093 |
107
+ | SanSi-2.6B | 2.7B | 8 | 14.8 | 75.8 | 88.4 | 74.4 | 71.6 | 0.078 |
108
+
109
+ ## Training
110
+
111
+ - Data: the 12,800 training items of the paper's decision suite, from 20 public sources. The GitHub repository
112
+ downloads the sources at fixed revisions and rebuilds the dataset byte for byte (`data.download_raw`,
113
+ `data.build_main`, `data.verify`).
114
+ - Model: Ouro-1.4B frozen; LoRA of rank 64 (alpha 128, dropout 0.05) on the attention and MLP projections; one
115
+ readout of rank 16 per loop.
116
+ - Loss at every loop: the cross-entropy plus the Brier score against the item's target distribution.
117
+ - 1,000 steps of 16 items; AdamW with learning rates 1e-4 (LoRA) and 1e-3 (readout), 200 warm-up steps, cosine
118
+ decay to 10%, gradient clipping at 1.0; two RTX A6000 GPUs; seed 0.
119
+
120
+ ```bash
121
+ python -m train.train --model <Ouro-1.4B> --loops 8 --seed 0 --out runs/sansi_s0
122
+ ```
123
+
124
+ ## Limitations
125
+
126
+ - English only. The model answers one question with 2 to 26 declared options per call, in the prompt format above.
127
+ - Running more loops than the eight it was trained with lowers accuracy.
128
+ - This is one training seed; the test accuracy of the three seeds of the paper has a standard deviation of 0.7 points.
129
+ - Looping does not replace parameters entirely: Qwen3.5-4B, with three times the parameters, is 1.8 points more
130
+ accurate, at a third of the computation.
131
+
132
+ ## License
133
+
134
+ The adapter and the readouts are released under the Apache 2.0 license, as are the code and the backbone Ouro-1.4B.
135
+ The training data comes from public datasets that keep their own licenses (`data/README.md` of the repository).
136
+
137
+ ## Citation
138
+
139
+ ```bibtex
140
+ @misc{gan2026sansiloopedtypeddecision,
141
+ title={SanSi: A Looped Typed Decision Model for System 1.5 Thinking},
142
+ author={Shuyu Gan and Young-Jun Lee and Dongyeop Kang},
143
+ year={2026},
144
+ eprint={2610.07730},
145
+ archivePrefix={arXiv},
146
+ primaryClass={cs.CL},
147
+ url={https://arxiv.org/abs/2610.07730},
148
+ }
149
+ ```
adapter_config.json ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alora_invocation_tokens": null,
3
+ "alpha_pattern": {},
4
+ "arrow_config": null,
5
+ "auto_mapping": {
6
+ "base_model_class": "OuroForCausalLM",
7
+ "parent_library": "transformers_modules.Ouro_hyphen_1_dot_4B.modeling_ouro"
8
+ },
9
+ "base_model_name_or_path": "ByteDance/Ouro-1.4B",
10
+ "bias": "none",
11
+ "corda_config": null,
12
+ "ensure_weight_tying": false,
13
+ "eva_config": null,
14
+ "exclude_modules": null,
15
+ "fan_in_fan_out": false,
16
+ "inference_mode": true,
17
+ "init_lora_weights": true,
18
+ "kasa_config": null,
19
+ "layer_replication": null,
20
+ "layers_pattern": null,
21
+ "layers_to_transform": null,
22
+ "loftq_config": {},
23
+ "lora_alpha": 128,
24
+ "lora_bias": false,
25
+ "lora_dropout": 0.05,
26
+ "lora_ga_config": null,
27
+ "megatron_config": null,
28
+ "megatron_core": "megatron.core",
29
+ "modules_to_save": null,
30
+ "monteclora_config": null,
31
+ "peft_type": "LORA",
32
+ "peft_version": "0.21.0",
33
+ "qalora_group_size": 16,
34
+ "r": 64,
35
+ "rank_pattern": {},
36
+ "revision": "574fa66cb8bf5abdc979642d01cf2b79b16bfab1",
37
+ "target_modules": [
38
+ "gate_proj",
39
+ "q_proj",
40
+ "down_proj",
41
+ "v_proj",
42
+ "o_proj",
43
+ "up_proj",
44
+ "k_proj"
45
+ ],
46
+ "target_parameters": null,
47
+ "task_type": null,
48
+ "trainable_token_indices": null,
49
+ "use_bdlora": null,
50
+ "use_dora": false,
51
+ "use_qalora": false,
52
+ "use_rslora": false,
53
+ "velora_config": null
54
+ }
adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:61a0a15b2a99e44c994d7aad440722606e16518c726f08ff959809e2c1c98ccb
3
+ size 242266152
readout.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:51c2b3986441aa96bb9c1789ffe141529d63bc4ab92cc5bea768eb72737a1cf3
3
+ size 1062196
sansi_config.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backbone": "ByteDance/Ouro-1.4B",
3
+ "backbone_revision": "574fa66cb8bf5abdc979642d01cf2b79b16bfab1",
4
+ "loops": 8,
5
+ "n_loop_params": 8,
6
+ "readout_rank": 16,
7
+ "seed": 0,
8
+ "training_steps": 1000,
9
+ "paper": "https://arxiv.org/abs/2610.07730",
10
+ "code": "https://github.com/minnesotanlp/Sansi"
11
+ }