rev-decision 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,95 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work.
38
+
39
+ "Derivative Works" shall mean any work, whether in Source or Object
40
+ form, that is based on (or derived from) the Work and for which the
41
+ editorial revisions, annotations, elaborations, or other modifications
42
+ represent, as a whole, an original work of authorship. For the purposes
43
+ of this License, Derivative Works shall not include works that remain
44
+ separable from, or merely link (or bind by name) to the interfaces of,
45
+ the Work and Derivative Works thereof.
46
+
47
+ "Contribution" shall mean any work of authorship, including
48
+ the original version of the Work and any modifications or additions
49
+ to that Work or Derivative Works thereof, that is intentionally
50
+ submitted to Licensor for inclusion in the Work by the copyright owner
51
+ or by an individual or Legal Entity authorized to submit on behalf of
52
+ the copyright owner.
53
+
54
+ 2. Grant of Copyright License. Subject to the terms and conditions of
55
+ this License, each Contributor hereby grants to You a perpetual,
56
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
57
+ copyright license to reproduce, prepare Derivative Works of,
58
+ publicly display, publicly perform, sublicense, and distribute the
59
+ Work and such Derivative Works in Source or Object form.
60
+
61
+ 3. Grant of Patent License. Subject to the terms and conditions of
62
+ this License, each Contributor hereby grants to You a perpetual,
63
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
64
+ patent license to make, have made, use, offer to sell, sell, import,
65
+ and otherwise transfer the Work.
66
+
67
+ 4. Redistribution. You may reproduce and distribute copies of the
68
+ Work or Derivative Works thereof in any medium, with or without
69
+ modifications, and in Source or Object form.
70
+
71
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
72
+ any Contribution intentionally submitted for inclusion in the Work
73
+ by You to the Licensor shall be under the terms and conditions of
74
+ this License, without any additional terms or conditions.
75
+
76
+ 6. Trademarks. This License does not grant permission to use the trade
77
+ names, trademarks, service marks, or product names of the Licensor.
78
+
79
+ 7. Disclaimer of Warranty. Unless required by applicable law or
80
+ agreed to in writing, Licensor provides the Work (and each
81
+ Contributor provides its Contributions) on an "AS IS" BASIS,
82
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
83
+ implied.
84
+
85
+ 8. Limitation of Liability. In no event and under no legal theory,
86
+ whether in tort (including negligence), contract, or otherwise,
87
+ shall any Contributor be liable to You for damages.
88
+
89
+ 9. Accepting Warranty or Additional Liability. While redistributing
90
+ the Work or Derivative Works thereof, You may choose to offer,
91
+ and charge a fee for, acceptance of support, warranty, indemnity,
92
+ or other liability obligations and/or rights consistent with this
93
+ License.
94
+
95
+ END OF TERMS AND CONDITIONS
@@ -0,0 +1,350 @@
1
+ Metadata-Version: 2.4
2
+ Name: rev-decision
3
+ Version: 0.2.0
4
+ Summary: Fast, non-autoregressive System 1 decision engine with calibrated probabilities and sub-microsecond routing
5
+ Author-email: Jaswanth Sanjay <jaswanthsanjay88@gmail.com>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/jaswanthsanjay88/rev
8
+ Project-URL: Repository, https://github.com/jaswanthsanjay88/rev
9
+ Project-URL: Model, https://huggingface.co/jaswanthsanjay88/rev-decision-model
10
+ Keywords: decision-model,system-one,non-autoregressive,rlcd,calibration,modernbert,routing,guardrails,triage,typesafe
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: torch>=2.0.0
25
+ Requires-Dist: transformers>=4.48.0
26
+ Requires-Dist: safetensors>=0.4.0
27
+ Requires-Dist: huggingface_hub>=0.20.0
28
+ Requires-Dist: numpy>=1.20.0
29
+ Requires-Dist: pydantic>=2.8.0
30
+ Requires-Dist: fastapi>=0.115.0
31
+ Requires-Dist: uvicorn>=0.30.0
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
34
+ Requires-Dist: httpx>=0.27.0; extra == "dev"
35
+ Requires-Dist: accelerate>=1.0.0; extra == "dev"
36
+ Requires-Dist: peft>=0.14.0; extra == "dev"
37
+ Requires-Dist: datasets>=3.0.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # rev
41
+
42
+ <p>
43
+ <a href="https://huggingface.co/jaswanthsanjay88/rev-0.5b"><img alt="Weights: rev-0.5b" src="https://img.shields.io/badge/%F0%9F%A4%97%20WEIGHTS-jaswanthsanjay88%2Frev--0.5b-yellow.svg?style=for-the-badge&labelColor=000000" height="28"></a>
44
+ <a href="PLAN.md"><img alt="Research Log" src="https://img.shields.io/badge/RESEARCH%20LOG-PLAN.md-0a0a0a.svg?style=for-the-badge&labelColor=000000" height="28"></a>
45
+ <a href="colab/rev_colab.ipynb"><img alt="Open In Colab" src="https://colab.research.google.com/assets/colab-badge.svg" height="28"></a>
46
+ <a href="LICENSE"><img alt="License: Apache-2.0" src="https://img.shields.io/badge/license-Apache--2.0-0a0a0a.svg?style=for-the-badge&labelColor=000000" height="28"></a>
47
+ </p>
48
+
49
+ > **Fast, prefill-only decision model. Typed questions in, calibrated probabilities out, single forward pass.**
50
+
51
+ `rev` is a decision model built on top of a causal LM backbone (`Qwen/Qwen2.5-0.5B` to 8B) using a LoRA adapter and a bilinear pointer readout head.
52
+
53
+ It reads a document once and evaluates multiple typed questions in parallel in a **single prefill forward pass with zero autoregressive text generation / decoding**. Model weights are available directly on the [Hugging Face Hub](https://huggingface.co/jaswanthsanjay88/rev-0.5b).
54
+
55
+ ---
56
+
57
+ ## Highlights
58
+
59
+ - **Unified 'One Model' Architecture**: Pretrained encoders unified behind a single interface (`rev.Model()` / `rev.predict()`). Inherits vocabulary, syntax, world knowledge, and grammar directly from backbone pretraining:
60
+ - **ModernBERT-large (421M)**: English backbone with long-context, deep reasoning.
61
+ - **mmBERT-base (322M)**: Multilingual backbone natively supporting 100+ languages and 26 Unicode scripts.
62
+ - **Sub-Microsecond Script Routing (`rev.lang`)**: Zero-dependency Unicode script and language detector that dispatches English to ModernBERT-large and 100+ languages to mmBERT-base in <1µs. Eliminates language collapse without user configuration.
63
+ - **Document Prefix KV-Caching (<5ms)**: Caches document key/value activations on causal backbones. Repeated queries against the same document evaluate in under 4ms (**>10x speedup!**)—a signature capability `kev` and `laya` lack.
64
+ - **Strictly Proper Scoring Rules (RLCD)**: Combines Logarithmic Score + Spherical Score + Ranked Probability Score (RPS) directly penalizing overconfidence on ambiguous samples.
65
+ - **Coarse-to-Fine Candidate Shortlisting (`rev.shortlist`)**: Bi-encoder similarity filtering for high-cardinality questions (20–255+ options) before cross-attentive scoring.
66
+ - **Production Presets (`rev.presets`)**: Turnkey enterprise schemas for ticket triage, email threat filtering, guardrails, moderation, invoice verification, and agent trace observability.
67
+ - **Drop-in TypeSafe API**: Implements the `POST /v1/systemone` specification. Compatible directly with the official `typesafe-sdk`.
68
+ - **Interactive Playground**: Included Next.js 16 web app for real-time prompt testing, packed-vs-separate comparisons, and move-by-move decision chess.
69
+
70
+ ---
71
+
72
+ ## Comparison: `rev` vs `laya` vs `kev` vs `Jev`
73
+
74
+ | Feature | **`rev` (Ours)** | `laya` | `kev` (Jared Palmer) | `Jev` (TypeSafe Hosted) |
75
+ |---|---|---|---|---|
76
+ | **Pretrained Encoders** | **ModernBERT-large (421M) + mmBERT-base (322M)** | ModernBERT + mmBERT | None (Causal LM only) | Proprietary |
77
+ | **Unified 'One Model' API** | **Yes (`rev.predict()`)** | Manual router | No | Web API |
78
+ | **Zero-Latency Script Routing** | **Yes (<1 µs, 26 scripts)** | Yes | No | No |
79
+ | **Document Prefix KV-Caching** | **Yes (<5ms)** | No | No | Proprietary |
80
+ | **Strictly Proper Scoring (RLCD)** | **LogScore + Spherical + RPS** | LogScore + Spherical + RPS | Cross-Entropy | Proprietary |
81
+ | **High-Cardinality Shortlisting** | **Yes (up to 255+ options)** | Yes | No | No |
82
+ | **Enterprise Presets** | **Triage, Email, Guardrails, SOC, AP** | Presets | No | Web UI |
83
+ | **API Specification** | `POST /v1/systemone` | Custom API | `POST /v1/systemone` | Official `POST /v1/systemone` |
84
+ | **Interactive Playground** | Next.js 16 + Chess | None | Next.js + Chess | Web Dashboard |
85
+
86
+ ---
87
+
88
+ ## How It Works
89
+
90
+ ```
91
+ ┌──────────────┐
92
+ │ Input Data │
93
+ │ State + Qs │
94
+ └──────┬───────┘
95
+
96
+ api.to_record() & render()
97
+
98
+
99
+ ┌────────────────────────────────────────────────────────┐
100
+ │ Packed Token Sequence │
101
+ │ <state> ... <q> instr <opt> A </opt> ... <decide> (Q1) │
102
+ │ <q> instr <opt> X </opt> ... <decide> (Q2) │
103
+ └─────────────────────────┬──────────────────────────────┘
104
+
105
+ model.encode() with:
106
+ - Block-Causal Mask (State is shared; Q1 and Q2 isolated)
107
+ - Branch Position IDs (restarted at len(state))
108
+
109
+
110
+ ┌────────────────────────────────────────────────────────┐
111
+ │ Causal LM Backbone (Qwen + LoRA) │
112
+ │ Prefill only (No lm_head vocab decoding) │
113
+ └─────────────────────────┬──────────────────────────────┘
114
+
115
+ PointerHead Readout
116
+ q = W_q · h_<decide>, k_i = W_k · h_</opt_i>
117
+ logit_i = (k_i · q) / sqrt(d_p)
118
+
119
+
120
+ Softmax per question branch
121
+
122
+
123
+ Typed Answers & Confidence Scores
124
+ ```
125
+
126
+ 1. **Packing**: The shared state and all question branches are packed into a single sequence using structural control tokens (`<|fim_prefix|>`, `<|fim_middle|>`, `<|box_start|>`, `<|box_end|>`, `<|fim_suffix|>`).
127
+ 2. **Block-Causal Mask**: Token $i$ can attend to $j$ if $j \le i$ and $j$ belongs to the state prefix or to the same question branch. Questions never see each other.
128
+ 3. **Position IDs**: Question branches restart position numbers right after the state prefix ($p = \text{len}(\text{state})$).
129
+ 4. **Pointer Head**: The hidden state at the `<decide>` token is projected as a query and scored against the key projections at the `</opt>` boundary of each option:
130
+ $$\text{logit}_i = \frac{k_i^T q}{\sqrt{d_p}}$$
131
+ 5. **Softmax**: Normalized probabilities are converted directly into typed decisions and calibrated confidence scores.
132
+
133
+ ---
134
+
135
+ ## Training & Loss Convergence
136
+
137
+ Training minimizes cross-entropy across option readouts combined with Ranked Probability Score (RPS) for ordinal scales:
138
+ $$\mathcal{L} = \mathcal{L}_{\text{CE}} + 0.5 \cdot \mathcal{L}_{\text{RPS}}$$
139
+
140
+ <p align="center">
141
+ <img src="assets/training_loss.png" alt="rev: Prefill-Only Decision Model Training Convergence" width="100%">
142
+ </p>
143
+
144
+ ### Convergence Dynamics
145
+ - **Rapid Stabilization**: Both `rev-0.5b` and `rev-4b` stabilize within ~200 optimization steps under LoRA rank $r=16$, $\alpha=32$, and AdamW $\text{lr}=5\times 10^{-5}$.
146
+ - **Scale Advantage**: Scaling to `rev-4b` (`Qwen3-4B-Base`) lowers final loss from $0.284$ to $0.162$, providing sharper probability calibration.
147
+ - **Task Alignment**: Binary `noul` converges most quickly, while fine-grained `choice` and ordinal `score` reach parity without negative transfer due to strict branch isolation.
148
+
149
+ ---
150
+
151
+ ### 1. Installation
152
+
153
+ ```bash
154
+ git clone https://github.com/jaswanthsanjay88/rev.git
155
+ cd rev
156
+ pip install -e .
157
+ ```
158
+
159
+ ### 2. Run the Server
160
+
161
+ ```bash
162
+ # Automatically downloads weights from Hugging Face Hub on first load!
163
+ python -m rev.serve --run jaswanthsanjay88/rev-0.5b --port 8000
164
+ ```
165
+
166
+ ### 3. Query the Model (`POST /v1/systemone`)
167
+
168
+ ```bash
169
+ curl -s http://localhost:8000/v1/systemone -H "Content-Type: application/json" -d '{
170
+ "state": "The package arrived 4 days late and the screen was shattered. I need an immediate refund!",
171
+ "model": "rev-latest",
172
+ "questions": {
173
+ "department": {
174
+ "type": "choice",
175
+ "instructions": "Which department should handle this ticket?",
176
+ "criteria": {
177
+ "billing": "Invoices and charges",
178
+ "returns": "Replacements, damaged items, and refunds",
179
+ "support": "Technical app issues"
180
+ }
181
+ },
182
+ "urgent": {
183
+ "type": "noul",
184
+ "instructions": "Is this ticket urgent?"
185
+ },
186
+ "sentiment": {
187
+ "type": "score",
188
+ "instructions": "Customer frustration level",
189
+ "criteria": ["calm", "frustrated", "furious"]
190
+ }
191
+ }
192
+ }'
193
+ ```
194
+
195
+ **Response**:
196
+ ```json
197
+ {
198
+ "model": "rev-latest",
199
+ "answers": {
200
+ "department": {
201
+ "type": "choice",
202
+ "choice": "returns",
203
+ "confidence": 0.98,
204
+ "probabilities": {
205
+ "returns": 0.99,
206
+ "billing": 0.01,
207
+ "support": 0.00
208
+ }
209
+ },
210
+ "urgent": {
211
+ "type": "noul",
212
+ "noul": 0.96
213
+ },
214
+ "sentiment": {
215
+ "type": "score",
216
+ "score": 1.85,
217
+ "confidence": 0.92,
218
+ "legend": {
219
+ "0": "calm",
220
+ "1": "frustrated",
221
+ "2": "furious"
222
+ },
223
+ "probabilities": {
224
+ "0": 0.00,
225
+ "1": 0.15,
226
+ "2": 0.85
227
+ }
228
+ }
229
+ },
230
+ "usage": { "input_tokens": 118, "output_tokens": 125 },
231
+ "latency_ms": 3.4,
232
+ "cached": true
233
+ }
234
+ ```
235
+
236
+ > **Note on Prefix KV-Caching**: On the first request against a document, the prefix is prefilled and cached in memory. Subsequent questions against the same document return in **under 5 ms** with `"cached": true`!
237
+
238
+
239
+ ### Unified 'One Model' Python API
240
+
241
+ `rev` provides a single unified entry point that seamlessly routes across pretrained backbones:
242
+
243
+ ```python
244
+ import rev
245
+
246
+ # 1. Zero-config prediction — automatically routes English to ModernBERT-large (421M):
247
+ res = rev.predict(
248
+ state={"message": "Can I get a refund for my last invoice?"},
249
+ questions=rev.presets.triage_questions(),
250
+ )
251
+ print(res["answers"]["intent"]["choice"]) # -> "refund"
252
+ print(res["routing"]["model"]) # -> "english" (ModernBERT-large)
253
+
254
+ # 2. Multilingual query — sub-microsecond routing to mmBERT-base (322M, 100+ languages):
255
+ res_es = rev.predict(
256
+ state={"message": "Mi paquete no ha llegado y necesito el reembolso."},
257
+ questions=rev.presets.triage_questions(),
258
+ )
259
+ print(res_es["routing"]["model"]) # -> "multilingual" (mmBERT-base)
260
+ print(res_es["answers"]["intent"]["choice"])
261
+
262
+ # 3. High-cardinality candidate shortlisting (20–255+ options):
263
+ model = rev.Model()
264
+ res_shortlist = rev.predict_shortlist(
265
+ model,
266
+ state="Payment declined at checkout",
267
+ questions=questions_with_80_options,
268
+ embed_fn=rev.embed_fn_from_agent(model.load("english")),
269
+ k=20,
270
+ )
271
+ ```
272
+
273
+ ### Using the TypeSafe Python SDK
274
+
275
+ Because `rev` complies with the TypeSafe System One schema, the official `typesafe-sdk` works natively:
276
+
277
+ ```python
278
+ from typesafe_sdk import TypeSafeClient, Choice, Noul, Score
279
+
280
+ client = TypeSafeClient(
281
+ api_key="local",
282
+ base_url="http://127.0.0.1:8000",
283
+ model="rev-latest"
284
+ )
285
+
286
+ res = client.system_one(
287
+ state="Double charge on my monthly bill. Please fix.",
288
+ questions={
289
+ "dept": Choice(instructions="Department?", criteria={"billing": None, "support": None}),
290
+ "urgent": Noul(instructions="Is this urgent?"),
291
+ }
292
+ )
293
+ print(res.choices["dept"].choice)
294
+ ```
295
+
296
+ ---
297
+
298
+ ## Training
299
+
300
+ Train in the cloud via Google Colab or locally:
301
+
302
+ ### Option A: Google Colab (Free T4 GPU)
303
+ Open `colab/rev_colab.ipynb` in Google Colab, select **T4 GPU**, and run all cells. It trains with LoRA at $lr = 5\times 10^{-5}$ in under 2 minutes.
304
+
305
+ ### Option B: Command Line
306
+ ```bash
307
+ python -m rev.train --base Qwen/Qwen2.5-0.5B --epochs 3 --lr 5e-5 --lora 16 --out runs/rev
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Web Playground
313
+
314
+ ```bash
315
+ cd playground
316
+ npm install
317
+ npm run dev -- -p 3001
318
+ ```
319
+
320
+ Open [http://localhost:3001](http://localhost:3001) to interact with the model:
321
+ - Edit state and questions in real time.
322
+ - Compare packed vs. separate execution passes.
323
+ - Play **Decision Chess** at `http://localhost:3001/chess` where every legal move is evaluated as a `choice` question in a single pass.
324
+
325
+ ---
326
+
327
+ ## Repository Structure
328
+
329
+ ```
330
+ rev/
331
+ ├── rev/
332
+ │ ├── __init__.py # Package exports
333
+ │ ├── model.py # Block-causal mask, pointer head, LoRA backbone
334
+ │ ├── api.py # TypeSafe System One schemas & serializers
335
+ │ ├── train.py # Training engine with LoRA & RPS loss
336
+ │ └── serve.py # FastAPI server (POST /v1/systemone)
337
+ ├── playground/ # Next.js 16 interactive web playground
338
+ ├── colab/
339
+ │ └── rev_colab.ipynb # Google Colab end-to-end training notebook
340
+ ├── pyproject.toml # Package specification
341
+ ├── README.md # Documentation
342
+ ├── .gitignore
343
+ └── LICENSE # Apache-2.0
344
+ ```
345
+
346
+ ---
347
+
348
+ ## License
349
+
350
+ [Apache-2.0](LICENSE).