Add SV0: Swedish one-pass form specialist (fp16 + int8 Core ML, eval receipts, MIT)
Browse files- .gitattributes +4 -34
- LICENSE +21 -0
- README.md +115 -0
- THIRD_PARTY_NOTICES.md +34 -0
- coreml/conversion.json +48 -0
- coreml/sv0_forms_fp16_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel +3 -0
- coreml/sv0_forms_fp16_options40.mlpackage/Data/com.apple.CoreML/weights/weight.bin +3 -0
- coreml/sv0_forms_fp16_options40.mlpackage/Manifest.json +18 -0
- coreml/sv0_forms_int4_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel +3 -0
- coreml/sv0_forms_int4_options40.mlpackage/Data/com.apple.CoreML/weights/weight.bin +3 -0
- coreml/sv0_forms_int4_options40.mlpackage/Manifest.json +18 -0
- coreml/sv0_forms_int8_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel +3 -0
- coreml/sv0_forms_int8_options40.mlpackage/Data/com.apple.CoreML/weights/weight.bin +3 -0
- coreml/sv0_forms_int8_options40.mlpackage/Manifest.json +18 -0
- eval/RESULTS-SV0-COREML.md +94 -0
- eval/RESULTS-SV0-pytorch.md +94 -0
- eval/corpus-manifest.json +44 -0
- eval/results-coreml.json +246 -0
- eval/results-pytorch.json +282 -0
- example.py +109 -0
- sv0-forms.json +162 -0
- sv0-forms.safetensors +3 -0
.gitattributes
CHANGED
|
@@ -1,35 +1,5 @@
|
|
| 1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
coreml/**/weight.bin filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
coreml/sv0_forms_fp16_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
coreml/sv0_forms_int4_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
coreml/sv0_forms_int8_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Precisit AB
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
language:
|
| 4 |
+
- sv
|
| 5 |
+
library_name: coreml
|
| 6 |
+
pipeline_tag: text-classification
|
| 7 |
+
tags:
|
| 8 |
+
- jev
|
| 9 |
+
- system-one
|
| 10 |
+
- one-pass-scorer
|
| 11 |
+
- computer-use
|
| 12 |
+
- form-filling
|
| 13 |
+
- swedish
|
| 14 |
+
- coreml
|
| 15 |
+
- apple-silicon
|
| 16 |
+
base_model: []
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
# One-Pass SV-Forms (SV0) — a Swedish one-pass form specialist (research checkpoint)
|
| 20 |
+
|
| 21 |
+
**This is a research checkpoint, not a product.** It is a 706 048-parameter model that scores a
|
| 22 |
+
supplied list of options in **one forward pass** — the "Jev"/System One shape — trained on
|
| 23 |
+
**synthetic** Swedish forms by a synthetic-data recipe we are publishing alongside it. It
|
| 24 |
+
generates no text, needs no tokenizer, and runs in ~1 ms per decision on an Apple laptop or
|
| 25 |
+
phone (Core ML package: 1.4 MB fp16, 787 KB int8).
|
| 26 |
+
|
| 27 |
+
| | |
|
| 28 |
+
| --- | --- |
|
| 29 |
+
| Task | given a UI element (role, label, state) plus the entities extracted from a document, pick one option: `fyll <entity>` / `kryssa` / `klicka` / `hoppa över` |
|
| 30 |
+
| Architecture | byte-level embeddings + 2-layer Transformer encoder (width 128, 4 heads) + option-attention head; `tinyx` |
|
| 31 |
+
| Parameters | 706 048 (2.83 MB fp16 checkpoint) |
|
| 32 |
+
| Context / option budget | 224 bytes of context, 96 bytes per option, **up to 40 options** |
|
| 33 |
+
| Training data | 900 synthetic Swedish form episodes (21 306 decisions), generated locally; **no real form, person or customer data** |
|
| 34 |
+
| Licence | MIT (weights and code) |
|
| 35 |
+
| Lineage | independent implementation of the same contract as [Cua's CUA-S1](https://huggingface.co/cua-ai/cua-s1-forms) and [jevlike](https://github.com/vinnylarouge/jevlike); trained from scratch, not a fine-tune of either |
|
| 36 |
+
|
| 37 |
+
## Measured results (our harness, Apple M4)
|
| 38 |
+
|
| 39 |
+
| Run | decisions | top-1 | majority-class baseline | ECE | silently skipped a required fill |
|
| 40 |
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
| 41 |
+
| Held-out synthetic test (form-signature disjoint) | 2 315 | **83.02 %** | 50.45 % | 0.017 | **76 (7.5 % of fills)** |
|
| 42 |
+
| Hand-written out-of-distribution Swedish demo | 50 | **86.00 %** | 64.00 % | 0.092 | 3 (of 32 fills) |
|
| 43 |
+
| Shuffled-context control (test) | 2 315 | 34.08 % | 50.45 % | 0.497 | 264 |
|
| 44 |
+
|
| 45 |
+
Per-action accuracy on the test split: `check` 98.3 %, `click` 93.7 %, `skip` 88.0 %,
|
| 46 |
+
`fill` 75.5 %. The shuffled-context control is the interesting one: rotating contexts between
|
| 47 |
+
rows drops the model below the majority baseline, i.e. it really reads the element label and the
|
| 48 |
+
document rather than exploiting option statistics.
|
| 49 |
+
|
| 50 |
+
For comparison, the released English checkpoint of the same family scores **21.4 %** on exactly
|
| 51 |
+
these Swedish rows — below the majority baseline, at its own shuffled-control floor. The
|
| 52 |
+
language was the barrier, not the contract.
|
| 53 |
+
|
| 54 |
+
Core ML export (same checkpoint, converted with coremltools 9.0):
|
| 55 |
+
|
| 56 |
+
| Variant | package | top-1 | argmax parity vs PyTorch | median latency | p95 |
|
| 57 |
+
| --- | ---: | ---: | ---: | ---: | ---: |
|
| 58 |
+
| fp16 (CPU + ANE) | 1.4 MB | 83.00 % | 0.99870 | 1.31 ms | 1.46 ms |
|
| 59 |
+
| **int8 (CPU + ANE)** | **787 KB** | **83.09 %** | 0.99611 | 1.32 ms | 1.40 ms |
|
| 60 |
+
| int4 (CPU + ANE) | 481 KB | 50.87 % | 0.48702 | 1.97 ms | 2.10 ms |
|
| 61 |
+
| PyTorch reference | 2.83 MB | 83.02 % | — | — | — |
|
| 62 |
+
|
| 63 |
+
We publish the int4 result because it is the most useful thing in this table: the same 4-bit
|
| 64 |
+
palettisation costs 0.06 pp on a converged model and destroys this one, and it also fails ANE
|
| 65 |
+
compilation. **Quantisation headroom is a property of the training run, not of the architecture.**
|
| 66 |
+
Use int8. `int4-weights/` ships the collapsed variant for reproducibility only.
|
| 67 |
+
|
| 68 |
+
## What it is NOT
|
| 69 |
+
|
| 70 |
+
- **Not trained or tested on real Swedish forms.** The corpus is synthetic (`Label: value`
|
| 71 |
+
document entities, `.invalid` e-mail domains, fictional names, locally generated
|
| 72 |
+
personnummer-shaped strings with no link to any real person) and the only non-synthetic
|
| 73 |
+
evidence is a 50-decision set we wrote ourselves.
|
| 74 |
+
- **Not a general-purpose assistant or an autonomous agent.** It does not generate text, cannot
|
| 75 |
+
invent a value it was not given, and does not decide execution order.
|
| 76 |
+
- **Not finished.** Validation was still improving when the run stopped (48 % → 63 % → 79 % →
|
| 77 |
+
83 % top-1 over four epochs), so treat 83 % as a floor for this recipe, not a ceiling.
|
| 78 |
+
- **Not safe to run unsupervised on real data.** 7.5 % of required fills are answered "skip" —
|
| 79 |
+
a required field that silently stays empty. Any real integration must verify outcomes outside
|
| 80 |
+
the model (fail-closed execution, dry run, one submit, human review before consequential
|
| 81 |
+
actions) — see the runtime contract in Cua's `planner.py` for a good pattern.
|
| 82 |
+
|
| 83 |
+
## Intended use
|
| 84 |
+
|
| 85 |
+
Research on bounded, high-volume Swedish interface workflows where the option set is supplied by
|
| 86 |
+
deterministic code: filling forms from an extracted document, triaging/routing where the choices
|
| 87 |
+
are known in advance, or as a **criteria-decision** layer where a calibrated distribution per
|
| 88 |
+
question is more useful than generated prose. Also as a worked example of how to build and
|
| 89 |
+
measure a language-local one-pass specialist.
|
| 90 |
+
|
| 91 |
+
## Usage
|
| 92 |
+
|
| 93 |
+
```python
|
| 94 |
+
from pathlib import Path
|
| 95 |
+
from huggingface_hub import hf_hub_download
|
| 96 |
+
|
| 97 |
+
# the checkpoint format is <name>.safetensors + <name>.json (architecture + hashes)
|
| 98 |
+
weights = Path(hf_hub_download("precisit/one-pass-sv-forms", "sv0-forms.safetensors"))
|
| 99 |
+
hf_hub_download("precisit/one-pass-sv-forms", "sv0-forms.json", local_dir=weights.parent)
|
| 100 |
+
# then either use the Core ML packages (no Python runtime needed) or the PyTorch code in
|
| 101 |
+
# precisit/onepass — both are in this repository.
|
| 102 |
+
```
|
| 103 |
+
|
| 104 |
+
The context string and options must be built exactly as in training (byte ids = UTF-8 byte + 1,
|
| 105 |
+
zero-padded; `UPPGIFT fyll i formuläret från dokumentet och skicka sedan in` / `FORM <title>` /
|
| 106 |
+
`ELEMENT <role> "<label>" value="…"`). A mismatch there is the most likely cause of poor output —
|
| 107 |
+
the recipe and the generator are in the toolkit repository.
|
| 108 |
+
|
| 109 |
+
## Licence and attribution
|
| 110 |
+
|
| 111 |
+
MIT. The architecture, training loop and evaluation metrics come from Cua's MIT-licensed
|
| 112 |
+
`libs/cua-s1` (see `THIRD_PARTY_NOTICES.md`); the option-attention head design is credited there
|
| 113 |
+
to `jevlike` (MIT). The Swedish catalogue, synthetic generator, training run, measurements and
|
| 114 |
+
Core ML export are ours — **Precisit AB, 2026**. No TypeSafe AI code, weights or data was used;
|
| 115 |
+
"Jev" is their product and this is an independent implementation of a similar interface.
|
THIRD_PARTY_NOTICES.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Third-party notices
|
| 2 |
+
|
| 3 |
+
This release is an independent implementation of a public model interface. It uses code and
|
| 4 |
+
design from two MIT-licensed projects, and it is **not** affiliated with, derived from, or
|
| 5 |
+
endorsed by TypeSafe AI (the makers of "Jev").
|
| 6 |
+
|
| 7 |
+
## trycua/cua — libs/cua-s1 (MIT)
|
| 8 |
+
|
| 9 |
+
- Source: https://github.com/trycua/cua/tree/main/libs/cua-s1
|
| 10 |
+
- Revision used: `9bbfa7d` (the commit that links the Hugging Face artifacts)
|
| 11 |
+
- What we use: the `tinyx` architecture (`cua_s1/model.py`), the checkpoint format
|
| 12 |
+
(`cua_s1/checkpoint.py`), the synthetic-data generator logic (`cua_s1/synth.py`), the
|
| 13 |
+
training loop (`training/train.py`) and the evaluation metrics (`evals/metrics.py`).
|
| 14 |
+
The files are vendored unmodified in the toolkit repository under `vendor/`, and the
|
| 15 |
+
generated corpus follows the same row/dataset format.
|
| 16 |
+
- Copyright and licence text: see the upstream repository's `LICENSE` (MIT).
|
| 17 |
+
|
| 18 |
+
Our model is **trained from scratch** on our own Swedish synthetic corpus: it shares the
|
| 19 |
+
architecture, the trainer and the data format, not any weights or data with Cua's release.
|
| 20 |
+
|
| 21 |
+
## vinnylarouge/jevlike (MIT), via Cua's attribution
|
| 22 |
+
|
| 23 |
+
- Source: https://github.com/vinnylarouge/jevlike
|
| 24 |
+
- The option-attention head design (`AttentionHead`) and the byte-level collation shape used by
|
| 25 |
+
the `tinyx` model originate in `jevlike`; Cua's `model.py` credits commit `94f5fd1`
|
| 26 |
+
(MIT, Copyright 2026 Minimal Labs) and we keep that attribution intact in the vendored code.
|
| 27 |
+
|
| 28 |
+
## What was NOT used
|
| 29 |
+
|
| 30 |
+
- No TypeSafe AI code, weights, data or API output. "Jev" and "System One" are TypeSafe AI's
|
| 31 |
+
terms; this release is an independent model that implements a similar input/output contract.
|
| 32 |
+
- No real personal data. The training corpus is synthetic: fictional names, `.invalid`
|
| 33 |
+
e-mail domains, locally generated personnummer-shaped identifiers that do not correspond to
|
| 34 |
+
any individual, and invented organisations.
|
coreml/conversion.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"checkpoint_sha256": "b9030d7a7b7abfaf70dd1cc2a390568eaa3a55849daa0757b60d01dbab162356",
|
| 3 |
+
"created_utc": "2026-09-21T08:00:57Z",
|
| 4 |
+
"limits": {
|
| 5 |
+
"context_bytes": 224,
|
| 6 |
+
"max_options": 40,
|
| 7 |
+
"option_bytes": 96
|
| 8 |
+
},
|
| 9 |
+
"model": "sv0-forms (spike jev-sv0)",
|
| 10 |
+
"model_config": {
|
| 11 |
+
"context_tokens": 224,
|
| 12 |
+
"encoder": "tinyx",
|
| 13 |
+
"heads": 4,
|
| 14 |
+
"layers": 2,
|
| 15 |
+
"option_tokens": 96,
|
| 16 |
+
"rank": 128,
|
| 17 |
+
"width": 128
|
| 18 |
+
},
|
| 19 |
+
"parameters": 706048,
|
| 20 |
+
"tooling": {
|
| 21 |
+
"coremltools": "9.0",
|
| 22 |
+
"python": "3.12.14",
|
| 23 |
+
"torch": "2.7.0"
|
| 24 |
+
},
|
| 25 |
+
"trace_check": null,
|
| 26 |
+
"variants": {
|
| 27 |
+
"fp16": {
|
| 28 |
+
"minimum_target": "iOS17/macOS14",
|
| 29 |
+
"path": "sv0_forms_fp16_options40.mlpackage",
|
| 30 |
+
"precision": "float16"
|
| 31 |
+
},
|
| 32 |
+
"int4": {
|
| 33 |
+
"granularity": "per_grouped_channel",
|
| 34 |
+
"group_size": 32,
|
| 35 |
+
"minimum_target": "iOS18/macOS15",
|
| 36 |
+
"mode": "KMEANS",
|
| 37 |
+
"path": "sv0_forms_int4_options40.mlpackage",
|
| 38 |
+
"precision": "int4_weights_float16_compute"
|
| 39 |
+
},
|
| 40 |
+
"int8": {
|
| 41 |
+
"granularity": "per_tensor",
|
| 42 |
+
"minimum_target": "iOS17/macOS14",
|
| 43 |
+
"mode": "UNIFORM",
|
| 44 |
+
"path": "sv0_forms_int8_options40.mlpackage",
|
| 45 |
+
"precision": "int8_weights_float16_compute"
|
| 46 |
+
}
|
| 47 |
+
}
|
| 48 |
+
}
|
coreml/sv0_forms_fp16_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bfe30d2473f7c9a0d804f7b3306f252fcad4a307fa9202d7bf218049be41401a
|
| 3 |
+
size 58608
|
coreml/sv0_forms_fp16_options40.mlpackage/Data/com.apple.CoreML/weights/weight.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cf1b0db68a002fd003cf68278f5e8c049c9360b9b5b3754205692e20a63bb43c
|
| 3 |
+
size 1448256
|
coreml/sv0_forms_fp16_options40.mlpackage/Manifest.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"9B448D09-24D9-4E7E-B194-43D3D4AEE91F": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Specification",
|
| 7 |
+
"name": "model.mlmodel",
|
| 8 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 9 |
+
},
|
| 10 |
+
"D3C625CB-29B6-456F-8FB3-B1111990E4E6": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Weights",
|
| 13 |
+
"name": "weights",
|
| 14 |
+
"path": "com.apple.CoreML/weights"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": "9B448D09-24D9-4E7E-B194-43D3D4AEE91F"
|
| 18 |
+
}
|
coreml/sv0_forms_int4_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e145df71d2ee1a4566126487afd80cd6409aeda278d42494640f49dc17016168
|
| 3 |
+
size 58303
|
coreml/sv0_forms_int4_options40.mlpackage/Data/com.apple.CoreML/weights/weight.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:53d889e570414557693f59309731d573aa6ddee95746dc9b9735a63afa2ad9ec
|
| 3 |
+
size 433664
|
coreml/sv0_forms_int4_options40.mlpackage/Manifest.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"495DA951-9B89-4CE4-8656-67B3D2E0038C": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Specification",
|
| 7 |
+
"name": "model.mlmodel",
|
| 8 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 9 |
+
},
|
| 10 |
+
"7B688A87-1DA1-4178-9B4F-2F6A9FD6C274": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Weights",
|
| 13 |
+
"name": "weights",
|
| 14 |
+
"path": "com.apple.CoreML/weights"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": "495DA951-9B89-4CE4-8656-67B3D2E0038C"
|
| 18 |
+
}
|
coreml/sv0_forms_int8_options40.mlpackage/Data/com.apple.CoreML/model.mlmodel
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4c63811d8b278b206c03cfc40c7d311a1e91997e9f710d524a1372477a28be74
|
| 3 |
+
size 62987
|
coreml/sv0_forms_int8_options40.mlpackage/Data/com.apple.CoreML/weights/weight.bin
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:36c31c5e396138a45eb191fec6f637d3831ffaca6005ebed12b305979be6b732
|
| 3 |
+
size 742528
|
coreml/sv0_forms_int8_options40.mlpackage/Manifest.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"BAE712EF-2551-49DE-BA14-3D8AB687D268": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Weights",
|
| 7 |
+
"name": "weights",
|
| 8 |
+
"path": "com.apple.CoreML/weights"
|
| 9 |
+
},
|
| 10 |
+
"E219151B-08B6-4AFD-BFEA-72D3F71825A6": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Specification",
|
| 13 |
+
"name": "model.mlmodel",
|
| 14 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": "E219151B-08B6-4AFD-BFEA-72D3F71825A6"
|
| 18 |
+
}
|
eval/RESULTS-SV0-COREML.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# RESULTS-SV0-COREML — the Swedish SV0 specialist exported to Core ML
|
| 2 |
+
|
| 3 |
+
**Verdict: PARTIAL — fp16 and int8 export cleanly and run on the Neural Engine at the same
|
| 4 |
+
accuracy as PyTorch; int4 is _not_ usable for this checkpoint (83 % → 51 % top-1) and does not
|
| 5 |
+
compile for the ANE.** Recommended deployment artifact: **int8, 787 KB, ~1.3 ms per decision.**
|
| 6 |
+
|
| 7 |
+
## What was exported
|
| 8 |
+
|
| 9 |
+
`export_sv_coreml.py` in this directory converts `runs/sv-tinyx/model` (the SV0 checkpoint,
|
| 10 |
+
706 048 parameters) with coremltools 9.0, mirroring the fixed-shape contract of the
|
| 11 |
+
FluidInference CUA-S1 release: `context_ids (1, 224)` / `option_ids (1, 40, 96)` /
|
| 12 |
+
`option_mask (1, 40)`, all int32 byte-ids (byte + 1, 0 = pad), output `logits (1, 40)`.
|
| 13 |
+
`max_options` is **40** here rather than their 32 because our corpus tops out at 37 options —
|
| 14 |
+
the ceiling is baked into the export, so it must be sized from the widest real input.
|
| 15 |
+
|
| 16 |
+
Variants: fp16 (iOS17), int8 (UNIFORM, per-tensor, iOS17), int4 (KMEANS, per-grouped-channel,
|
| 17 |
+
group 32, iOS18). `conversion.json` records hashes, config and tooling versions.
|
| 18 |
+
|
| 19 |
+
## Export-time checks (all passed before any measurement)
|
| 20 |
+
|
| 21 |
+
| Check | Result |
|
| 22 |
+
| --- | --- |
|
| 23 |
+
| Export forward vs vendored model, 256 real rows, max abs logit difference | **0.0** (bit-identical) |
|
| 24 |
+
| Traced graph vs model, 64 real rows | max abs Δ 7.2 × 10⁻⁶, argmax agreement **1.0** |
|
| 25 |
+
|
| 26 |
+
## Measurements (Apple M4, macOS 26.6.2; 2 312 scored rows after 3 warm-up rows; same grader as the spike)
|
| 27 |
+
|
| 28 |
+
| Variant | package | test top-1 | demo top-1 | silent skips (of 1 008 fills) | argmax parity vs PyTorch | mismatches | median | p95 |
|
| 29 |
+
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
|
| 30 |
+
| PyTorch (MPS), reference | 2 828 784 B | **83.02 %** | 86 % | 76 | — | — | — | — |
|
| 31 |
+
| **fp16, CPU + ANE** | 1 507 481 B (1.44 MB) | 83.00 % | 85.11 % | 76 | 0.99870 | 3 / 2 312 | 1.307 ms | 1.460 ms |
|
| 32 |
+
| fp16, CPU only | 1 507 481 B | 83.04 % | — | 76 | 0.99913 | 2 / 2 312 | 1.734 ms | 1.917 ms |
|
| 33 |
+
| **int8, CPU + ANE** | **806 132 B (787 KB)** | **83.09 %** | 85.11 % | 76 | 0.99611 | 9 / 2 312 | 1.316 ms | 1.402 ms |
|
| 34 |
+
| int4, CPU + ANE | 492 584 B (481 KB) | **50.87 %** | 27.66 % | 954 | 0.48702 | 1 186 / 2 312 | 1.968 ms | 2.099 ms |
|
| 35 |
+
|
| 36 |
+
Fills per-action on fp16: `fill` 75.40 %, `skip` 88.26 %, `check` 96.55 %, `click` 93.67 % —
|
| 37 |
+
within a few rows of the PyTorch run, i.e. the export is behaviour-preserving.
|
| 38 |
+
|
| 39 |
+
## What the numbers say
|
| 40 |
+
|
| 41 |
+
1. **The export works, and the ANE helps here too**: fp16 median 1.307 ms with the ANE vs
|
| 42 |
+
1.734 ms CPU-only, p95 1.460 ms vs 1.917 ms. Smaller absolute win than on the English model
|
| 43 |
+
(whose weights are better conditioned), but the same direction.
|
| 44 |
+
2. **int8 is free and is the artifact to ship**: 787 KB (52 % of fp16), top-1 83.09 % — one
|
| 45 |
+
decision *better* than PyTorch on this split — 9 argmax deviations out of 2 312, identical
|
| 46 |
+
silent-skip count, and the same ANE behaviour.
|
| 47 |
+
3. **int4 does not transfer to an undertrained model.** On Cua's English checkpoint the same
|
| 48 |
+
kind of palettisation cost 14 decisions in 24 367 (0.06 pp); here it costs 1 186 in 2 312
|
| 49 |
+
(51 pp) and raises silent skips from 76 to 954. Two mechanisms are plausible and both point
|
| 50 |
+
the same way: a model that has not converged stores information in fine weight differences
|
| 51 |
+
that a 4-bit palette cannot represent, and the per-grouped-channel kmeans graph also fails
|
| 52 |
+
to compile for the ANE (`ANECCompile() FAILED`, seen repeatedly during save and load), which
|
| 53 |
+
is why its latency is worst despite being the smallest artifact. **Quantisation headroom is
|
| 54 |
+
a property of the training run, not of the architecture** — that is the transferable finding.
|
| 55 |
+
4. **fp16 parity is 99.87 %, not 100 %**, and that is expected rather than alarming: three
|
| 56 |
+
rows change their argmax under fp16 rounding on a model whose decision margins are thin
|
| 57 |
+
(83 % top-1). On the well-trained English model the same conversion showed zero deviations.
|
| 58 |
+
Parity must therefore be *measured* per checkpoint, not assumed — exactly what this harness
|
| 59 |
+
does.
|
| 60 |
+
|
| 61 |
+
## Pitfalls found while exporting (all cost a failed run)
|
| 62 |
+
|
| 63 |
+
- **`torch.jit.trace` under `torch.no_grad()` takes PyTorch's fused sparsity fast path**
|
| 64 |
+
(`torch._transformer_encoder_layer_fwd`), which coremltools cannot convert. Trace with grad
|
| 65 |
+
*enabled*.
|
| 66 |
+
- **The coremltools torch frontend has no `__or__` for bool tensors** → use
|
| 67 |
+
`torch.logical_or` / `torch.logical_not`. (`&`, `~` alone, and in-place `mask[:, 0] = True`
|
| 68 |
+
all fail; probe the op support in a 5-line script before rewriting a model.)
|
| 69 |
+
- **`clamp_min(1)` with a Python int trips `assert x.dtype == y.dtype`** in the frontend; pass a
|
| 70 |
+
same-dtype tensor constant.
|
| 71 |
+
- **`per_grouped_channel` palettisation requires an iOS18 deployment target**, so the int4
|
| 72 |
+
variant needs its own fp16 base converted at iOS18 (the upstream release does the same).
|
| 73 |
+
- **k-means palettisation needs `scikit-learn`**, which is not a coremltools dependency; the
|
| 74 |
+
error arrives mid-run, after the fp16 conversion has already succeeded — hence the
|
| 75 |
+
`REUSE_FP16=1` cache flag in the export script.
|
| 76 |
+
- **Palettizer API in coremltools 9.0**: wrap the op config —
|
| 77 |
+
`OptimizationConfig(global_config=OpPalettizerConfig(...))` — and note the mode names are
|
| 78 |
+
upper-case (`UNIFORM`, `KMEANS`) while granularity is `per_tensor` / `per_grouped_channel`
|
| 79 |
+
only.
|
| 80 |
+
- **Check that the traced graph is the model** before converting: `torch.jit.trace(..., check_trace=False)`
|
| 81 |
+
suppresses a noisy replay check, so the export script compares logits itself and aborts on
|
| 82 |
+
mismatch.
|
| 83 |
+
|
| 84 |
+
## Reproduction
|
| 85 |
+
|
| 86 |
+
```bash
|
| 87 |
+
# (in the spike venv with coremltools 9.0, torch 2.7, safetensors, scikit-learn)
|
| 88 |
+
python check_export_forward.py # export forward is bit-identical to the model
|
| 89 |
+
REUSE_FP16=1 python export_sv_coreml.py # fp16 + int8 + int4 mlpackages, conversion.json
|
| 90 |
+
python eval_sv_coreml.py # accuracy, silent skips, parity, latency -> RESULTS-sv0-coreml.json
|
| 91 |
+
```
|
| 92 |
+
|
| 93 |
+
Artifacts (not in Git): `sv-coreml/*.mlpackage`, `RESULTS-sv0-coreml.json`,
|
| 94 |
+
`export.log`, `eval-coreml.log`.
|
eval/RESULTS-SV0-pytorch.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# RESULTS-SV0 — Swedish Jev-shaped form specialist
|
| 2 |
+
|
| 3 |
+
**Verdict: VALIDATED, with documented limits.**
|
| 4 |
+
The Cua-S1 contract trains on our own Swedish synthetic data with the upstream MIT code,
|
| 5 |
+
on one laptop, and reaches **83.02 %** top-1 on a held-out, form-disjoint synthetic test
|
| 6 |
+
(2 315 decisions) and **86 %** on a hand-written out-of-distribution Swedish demo (50
|
| 7 |
+
decisions) — against **21.4 %** / **20 %** for the released English `cua-s1-forms`
|
| 8 |
+
checkpoint on the very same rows. The result is undertrained (validation was still
|
| 9 |
+
improving at the last epoch), so 83 % is a floor, not a ceiling.
|
| 10 |
+
|
| 11 |
+
## Protocol as run
|
| 12 |
+
|
| 13 |
+
| Item | Setting |
|
| 14 |
+
| --- | --- |
|
| 15 |
+
| Architecture | `tinyx` (byte-level 2-layer Transformer encoder, width 128, 4 heads) + jevlike `AttentionHead`, context 224 / option 96 bytes — identical to upstream |
|
| 16 |
+
| Code | `trycua/cua` → `libs/cua-s1` @ `9bbfa7d`, vendored unmodified (`vendor/`, MIT) |
|
| 17 |
+
| Corpus | `sv_synth.py` + `concepts_sv.py` (ours): 900 episodes, seed 2026, splits by form field signature |
|
| 18 |
+
| Rows | train 21 306 / validation 2 855 / test 2 315 decisions; 725 / 96 / 79 distinct form signatures, **zero overlap** between splits |
|
| 19 |
+
| Training | AdamW lr 2e-3, cosine + 5 % warmup, wd 1e-2, 4 epochs, batch 64, seed 7, MPS, 1 927 s |
|
| 20 |
+
| Checkpoint rule | best validation NLL (upstream's rule) — epoch 4 |
|
| 21 |
+
| Grader | `eval_sv.py`, unchanged for both checkpoints |
|
| 22 |
+
|
| 23 |
+
## Numbers
|
| 24 |
+
|
| 25 |
+
| Run | decisions | top-1 | majority baseline | ECE | skipped a required fill | per action |
|
| 26 |
+
| --- | ---: | ---: | ---: | ---: | ---: | --- |
|
| 27 |
+
| Swedish specialist — synthetic test (form-disjoint) | 2 315 | **83.02 %** | 50.45 % | 0.01656 | 76 | `check` 98.28 % (n=58), `click` 93.67 % (n=79), `fill` 75.55 % (n=1010), `skip` 88.01 % (n=1168) |
|
| 28 |
+
| Swedish specialist — handwritten OOD demo (50) | 50 | **86.00 %** | 64.00 % | 0.09176 | 3 | `check` 100 % (n=3), `click` 100 % (n=3), `fill` 81.25 % (n=32), `skip` 91.67 % (n=12) |
|
| 29 |
+
| Swedish specialist — shuffled-context control (test) | 2 315 | 34.08 % | 50.45 % | 0.49735 | 264 | `check` 15.52 %, `click` 0 %, `fill` 1.29 %, `skip` 65.67 % |
|
| 30 |
+
| Swedish specialist — shuffled-context control (demo) | 50 | 6.00 % | 64.00 % | 0.78579 | 6 | all actions ≤ 25 % |
|
| 31 |
+
| English reference (`cua-s1-forms`) — synthetic test | 2 315 | 21.38 % | 50.45 % | 0.64072 | 371 | `check` 93.10 %, `click` 26.58 %, `fill` 5.54 %, `skip` 31.16 % |
|
| 32 |
+
| English reference — handwritten OOD demo | 50 | 20.00 % | 64.00 % | 0.66098 | 16 | `check` 66.67 %, `click` 33.33 %, `fill` 15.62 %, `skip` 16.67 % |
|
| 33 |
+
| English reference — shuffled-context control (test) | 2 315 | 17.50 % | 50.45 % | 0.67954 | 363 | `check` 60.35 %, `click` 6.33 %, `fill` 1.78 %, `skip` 29.71 % |
|
| 34 |
+
|
| 35 |
+
Per-epoch validation: 48.23 % → 62.98 % → 78.63 % → **83.01 %** top-1 (train NLL
|
| 36 |
+
2.06 → 0.45; val NLL 1.75 → 0.52). Still improving when the run stopped.
|
| 37 |
+
|
| 38 |
+
## Reading the numbers
|
| 39 |
+
|
| 40 |
+
1. **The contract transfers; the language boundary was the real barrier.** The English
|
| 41 |
+
checkpoint on Swedish rows sits at **21.4 %**, barely above its own shuffled-context
|
| 42 |
+
control (17.5 %) and *below* the majority-action baseline (50.5 %), with ECE 0.64 — it
|
| 43 |
+
is not reading the content, it is guessing confidently. On the hand-written demo it
|
| 44 |
+
scores 20 % against a 64 % baseline, i.e. worse than always answering "fill". The
|
| 45 |
+
Swedish specialist, same architecture, same grader, same rows: 83 % / 86 %.
|
| 46 |
+
2. **The shuffled control is the floor that matters.** Our specialist drops from 83.02 %
|
| 47 |
+
to 34.08 % when contexts are rotated between rows (below the 50.45 % majority
|
| 48 |
+
baseline), which is the evidence that it uses the element label and the document, not
|
| 49 |
+
option statistics. The English reference barely moves (21.4 % → 17.5 %) — its score was
|
| 50 |
+
near the floor to begin with.
|
| 51 |
+
3. **`fill` is the weak action, and the silent-skip failure mode persists.** 75.5 % of
|
| 52 |
+
fills are right; 76 of 1 010 fill decisions (7.5 %) are answered `hoppa över` instead.
|
| 53 |
+
In a real workflow that is the dangerous class: a required field that looks done and is
|
| 54 |
+
not. It is much smaller than the English reference's (371/1 010), but it is not zero,
|
| 55 |
+
and it is the reason a production integration needs a per-item check outside the model.
|
| 56 |
+
4. **Calibration is good in-distribution and degrades out-of-distribution** (ECE 0.017 →
|
| 57 |
+
0.092), which is exactly the wrong direction for confidence routing if the threshold is
|
| 58 |
+
tuned on synthetic data.
|
| 59 |
+
5. **It is undertrained.** Both the validation curve and the comparison with the reference
|
| 60 |
+
(trained on ~150 k rows vs our 21 k) say the remaining error is largely a data-scale
|
| 61 |
+
effect. The next honest step is more episodes, not a different architecture.
|
| 62 |
+
|
| 63 |
+
## What this does not establish
|
| 64 |
+
|
| 65 |
+
- Nothing about real Swedish forms. The demo set is hand-written by the same person who
|
| 66 |
+
wrote the catalogue, so it shares the author's vocabulary; a genuine test needs real
|
| 67 |
+
blanketter (Skolverket/Försäkringskassan/kommunala) or our own live forms.
|
| 68 |
+
- Nothing about the runtime: this spike scores decisions, it does not drive a GUI.
|
| 69 |
+
Fill/click execution, retries and fail-closed behaviour were not exercised (upstream's
|
| 70 |
+
`planner.py` refuses to execute without a compatible driver contract).
|
| 71 |
+
- Nothing about English transfer in the other direction: we never trained a Swedish model
|
| 72 |
+
on English rows, and the corpus changes *language and label vocabulary at once*, so the
|
| 73 |
+
ablation "language vs vocabulary" is still open.
|
| 74 |
+
- Reproducibility is bounded by the environment: torch 2.14 on Apple Silicon MPS, seed 7,
|
| 75 |
+
`deterministic=False` (deterministic algorithms were too slow on MPS), so the exact
|
| 76 |
+
numbers are one draw, not a bit-reproducible receipt.
|
| 77 |
+
|
| 78 |
+
## Follow-ups worth pre-registering
|
| 79 |
+
|
| 80 |
+
1. **Scale test**: 4 000–10 000 episodes, 6 epochs, batch 32–64 on a machine with room —
|
| 81 |
+
does top-1 cross ~95 % and does the silent-skip rate fall below 2 % of fills?
|
| 82 |
+
2. **Language ✕ vocabulary ablation**: Swedish documents + English labels, and the mirror,
|
| 83 |
+
to attribute the win.
|
| 84 |
+
3. **Real-form OOD**: hand-build 3–5 authentic Swedish blanketter (never in the catalogue)
|
| 85 |
+
and score before touching the corpus again.
|
| 86 |
+
4. **Abstention outside the model**: a spread/top-probability gate plus a "required field
|
| 87 |
+
still empty" check, measured on the silent-skip class specifically.
|
| 88 |
+
|
| 89 |
+
## Reproduction
|
| 90 |
+
|
| 91 |
+
See `README.md` in this directory. Runtime: ~5 min generation, 32 min training, seconds of
|
| 92 |
+
scoring on one Apple Silicon laptop. Corpus and checkpoint are not in Git
|
| 93 |
+
(`~/agent-data/jevlike-sv-spike/`); `data/sv/manifest.json` carries the SHA-256 of each split
|
| 94 |
+
(test `92c0dfec…d272`).
|
eval/corpus-manifest.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"episodes": 900,
|
| 3 |
+
"format": "cua-s1-choice-jsonl",
|
| 4 |
+
"format_version": 1,
|
| 5 |
+
"generator": {
|
| 6 |
+
"config": {
|
| 7 |
+
"filled_field_probability": 0.6,
|
| 8 |
+
"hard_negative_probability": 0.35,
|
| 9 |
+
"max_distractor_entities": 3,
|
| 10 |
+
"max_extra_entities": 5,
|
| 11 |
+
"missing_entity_probability": 0.12,
|
| 12 |
+
"partial_form_probability": 0.3,
|
| 13 |
+
"stale_value_probability": 0.05
|
| 14 |
+
},
|
| 15 |
+
"format": "spike.sv_synth",
|
| 16 |
+
"task_line": "UPPGIFT fyll i formul\u00e4ret fr\u00e5n dokumentet och skicka sedan in"
|
| 17 |
+
},
|
| 18 |
+
"ratios": {
|
| 19 |
+
"test": 0.1,
|
| 20 |
+
"train": 0.8,
|
| 21 |
+
"validation": 0.1
|
| 22 |
+
},
|
| 23 |
+
"seed": 2026,
|
| 24 |
+
"splits": {
|
| 25 |
+
"test": {
|
| 26 |
+
"episodes": 79,
|
| 27 |
+
"file": "test.jsonl",
|
| 28 |
+
"rows": 2315,
|
| 29 |
+
"sha256": "92c0dfec00239b6e1d5cc6db4f098d12fc90bc5a8832428d9df0f6aea380d272"
|
| 30 |
+
},
|
| 31 |
+
"train": {
|
| 32 |
+
"episodes": 725,
|
| 33 |
+
"file": "train.jsonl",
|
| 34 |
+
"rows": 21306,
|
| 35 |
+
"sha256": "b3a7ef25e4edb47b18be2601d1060a3589c7ed8563397fab25e27088017ee3fa"
|
| 36 |
+
},
|
| 37 |
+
"validation": {
|
| 38 |
+
"episodes": 96,
|
| 39 |
+
"file": "validation.jsonl",
|
| 40 |
+
"rows": 2855,
|
| 41 |
+
"sha256": "09298b6319b8471379b8f9e87f983558f5fa194b38271eac195670a8eb2ef5f1"
|
| 42 |
+
}
|
| 43 |
+
}
|
| 44 |
+
}
|
eval/results-coreml.json
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"checkpoint": "runs/sv-tinyx/model",
|
| 3 |
+
"limits": {
|
| 4 |
+
"context_bytes": 224,
|
| 5 |
+
"max_options": 40,
|
| 6 |
+
"option_bytes": 96
|
| 7 |
+
},
|
| 8 |
+
"torch_baseline": {
|
| 9 |
+
"per_action": {
|
| 10 |
+
"check": {
|
| 11 |
+
"acc": 0.9827586206896551,
|
| 12 |
+
"n": 58
|
| 13 |
+
},
|
| 14 |
+
"click": {
|
| 15 |
+
"acc": 0.9367088607594937,
|
| 16 |
+
"n": 79
|
| 17 |
+
},
|
| 18 |
+
"fill": {
|
| 19 |
+
"acc": 0.7554455445544555,
|
| 20 |
+
"n": 1010
|
| 21 |
+
},
|
| 22 |
+
"skip": {
|
| 23 |
+
"acc": 0.8801369863013698,
|
| 24 |
+
"n": 1168
|
| 25 |
+
}
|
| 26 |
+
},
|
| 27 |
+
"rows": 2315,
|
| 28 |
+
"silent_skip_rate_of_fills": 0.07524752475247524,
|
| 29 |
+
"silent_skips": 76,
|
| 30 |
+
"top1": 0.8302375809935205
|
| 31 |
+
},
|
| 32 |
+
"variants": {
|
| 33 |
+
"fp16": {
|
| 34 |
+
"handwritten_demo__ane": {
|
| 35 |
+
"compute_units": "ComputeUnit.CPU_AND_NE",
|
| 36 |
+
"latency_ms_median": 1.2992918491363525,
|
| 37 |
+
"latency_ms_p95": 1.4392081648111343,
|
| 38 |
+
"mismatches_vs_torch": 0,
|
| 39 |
+
"parity_with_torch": 1.0,
|
| 40 |
+
"per_action": {
|
| 41 |
+
"check": {
|
| 42 |
+
"acc": 1.0,
|
| 43 |
+
"n": 3
|
| 44 |
+
},
|
| 45 |
+
"click": {
|
| 46 |
+
"acc": 1.0,
|
| 47 |
+
"n": 3
|
| 48 |
+
},
|
| 49 |
+
"fill": {
|
| 50 |
+
"acc": 0.7931034482758621,
|
| 51 |
+
"n": 29
|
| 52 |
+
},
|
| 53 |
+
"skip": {
|
| 54 |
+
"acc": 0.9166666666666666,
|
| 55 |
+
"n": 12
|
| 56 |
+
}
|
| 57 |
+
},
|
| 58 |
+
"rows": 47,
|
| 59 |
+
"silent_skip_rate_of_fills": 0.10344827586206896,
|
| 60 |
+
"silent_skips": 3,
|
| 61 |
+
"top1": 0.851063829787234
|
| 62 |
+
},
|
| 63 |
+
"package_bytes": 1507481,
|
| 64 |
+
"synthetic_test__ane": {
|
| 65 |
+
"compute_units": "ComputeUnit.CPU_AND_NE",
|
| 66 |
+
"latency_ms_median": 1.3071454595774412,
|
| 67 |
+
"latency_ms_p95": 1.4601247385144234,
|
| 68 |
+
"mismatches_vs_torch": 3,
|
| 69 |
+
"parity_with_torch": 0.9987024221453287,
|
| 70 |
+
"per_action": {
|
| 71 |
+
"check": {
|
| 72 |
+
"acc": 0.9827586206896551,
|
| 73 |
+
"n": 58
|
| 74 |
+
},
|
| 75 |
+
"click": {
|
| 76 |
+
"acc": 0.9367088607594937,
|
| 77 |
+
"n": 79
|
| 78 |
+
},
|
| 79 |
+
"fill": {
|
| 80 |
+
"acc": 0.753968253968254,
|
| 81 |
+
"n": 1008
|
| 82 |
+
},
|
| 83 |
+
"skip": {
|
| 84 |
+
"acc": 0.8808911739502999,
|
| 85 |
+
"n": 1167
|
| 86 |
+
}
|
| 87 |
+
},
|
| 88 |
+
"rows": 2312,
|
| 89 |
+
"silent_skip_rate_of_fills": 0.07539682539682539,
|
| 90 |
+
"silent_skips": 76,
|
| 91 |
+
"top1": 0.8300173010380623
|
| 92 |
+
},
|
| 93 |
+
"synthetic_test__cpu": {
|
| 94 |
+
"compute_units": "ComputeUnit.CPU_ONLY",
|
| 95 |
+
"latency_ms_median": 1.733562909066677,
|
| 96 |
+
"latency_ms_p95": 1.9167079590260983,
|
| 97 |
+
"mismatches_vs_torch": 2,
|
| 98 |
+
"parity_with_torch": 0.9991349480968859,
|
| 99 |
+
"per_action": {
|
| 100 |
+
"check": {
|
| 101 |
+
"acc": 0.9827586206896551,
|
| 102 |
+
"n": 58
|
| 103 |
+
},
|
| 104 |
+
"click": {
|
| 105 |
+
"acc": 0.9367088607594937,
|
| 106 |
+
"n": 79
|
| 107 |
+
},
|
| 108 |
+
"fill": {
|
| 109 |
+
"acc": 0.7549603174603174,
|
| 110 |
+
"n": 1008
|
| 111 |
+
},
|
| 112 |
+
"skip": {
|
| 113 |
+
"acc": 0.8808911739502999,
|
| 114 |
+
"n": 1167
|
| 115 |
+
}
|
| 116 |
+
},
|
| 117 |
+
"rows": 2312,
|
| 118 |
+
"silent_skip_rate_of_fills": 0.07539682539682539,
|
| 119 |
+
"silent_skips": 76,
|
| 120 |
+
"top1": 0.8304498269896193
|
| 121 |
+
}
|
| 122 |
+
},
|
| 123 |
+
"int4": {
|
| 124 |
+
"handwritten_demo__ane": {
|
| 125 |
+
"compute_units": "ComputeUnit.CPU_AND_NE",
|
| 126 |
+
"latency_ms_median": 1.8591247498989105,
|
| 127 |
+
"latency_ms_p95": 1.993041019886732,
|
| 128 |
+
"mismatches_vs_torch": 32,
|
| 129 |
+
"parity_with_torch": 0.3191489361702128,
|
| 130 |
+
"per_action": {
|
| 131 |
+
"check": {
|
| 132 |
+
"acc": 0.0,
|
| 133 |
+
"n": 3
|
| 134 |
+
},
|
| 135 |
+
"click": {
|
| 136 |
+
"acc": 0.0,
|
| 137 |
+
"n": 3
|
| 138 |
+
},
|
| 139 |
+
"fill": {
|
| 140 |
+
"acc": 0.034482758620689655,
|
| 141 |
+
"n": 29
|
| 142 |
+
},
|
| 143 |
+
"skip": {
|
| 144 |
+
"acc": 1.0,
|
| 145 |
+
"n": 12
|
| 146 |
+
}
|
| 147 |
+
},
|
| 148 |
+
"rows": 47,
|
| 149 |
+
"silent_skip_rate_of_fills": 0.9655172413793104,
|
| 150 |
+
"silent_skips": 28,
|
| 151 |
+
"top1": 0.2765957446808511
|
| 152 |
+
},
|
| 153 |
+
"package_bytes": 492584,
|
| 154 |
+
"synthetic_test__ane": {
|
| 155 |
+
"compute_units": "ComputeUnit.CPU_AND_NE",
|
| 156 |
+
"latency_ms_median": 1.9683334976434708,
|
| 157 |
+
"latency_ms_p95": 2.099000383168459,
|
| 158 |
+
"mismatches_vs_torch": 1186,
|
| 159 |
+
"parity_with_torch": 0.4870242214532872,
|
| 160 |
+
"per_action": {
|
| 161 |
+
"check": {
|
| 162 |
+
"acc": 0.0,
|
| 163 |
+
"n": 58
|
| 164 |
+
},
|
| 165 |
+
"click": {
|
| 166 |
+
"acc": 0.0,
|
| 167 |
+
"n": 79
|
| 168 |
+
},
|
| 169 |
+
"fill": {
|
| 170 |
+
"acc": 0.018849206349206348,
|
| 171 |
+
"n": 1008
|
| 172 |
+
},
|
| 173 |
+
"skip": {
|
| 174 |
+
"acc": 0.9914310197086547,
|
| 175 |
+
"n": 1167
|
| 176 |
+
}
|
| 177 |
+
},
|
| 178 |
+
"rows": 2312,
|
| 179 |
+
"silent_skip_rate_of_fills": 0.9464285714285714,
|
| 180 |
+
"silent_skips": 954,
|
| 181 |
+
"top1": 0.5086505190311419
|
| 182 |
+
}
|
| 183 |
+
},
|
| 184 |
+
"int8": {
|
| 185 |
+
"handwritten_demo__ane": {
|
| 186 |
+
"compute_units": "ComputeUnit.CPU_AND_NE",
|
| 187 |
+
"latency_ms_median": 1.31650036200881,
|
| 188 |
+
"latency_ms_p95": 1.4507090672850609,
|
| 189 |
+
"mismatches_vs_torch": 0,
|
| 190 |
+
"parity_with_torch": 1.0,
|
| 191 |
+
"per_action": {
|
| 192 |
+
"check": {
|
| 193 |
+
"acc": 1.0,
|
| 194 |
+
"n": 3
|
| 195 |
+
},
|
| 196 |
+
"click": {
|
| 197 |
+
"acc": 1.0,
|
| 198 |
+
"n": 3
|
| 199 |
+
},
|
| 200 |
+
"fill": {
|
| 201 |
+
"acc": 0.7931034482758621,
|
| 202 |
+
"n": 29
|
| 203 |
+
},
|
| 204 |
+
"skip": {
|
| 205 |
+
"acc": 0.9166666666666666,
|
| 206 |
+
"n": 12
|
| 207 |
+
}
|
| 208 |
+
},
|
| 209 |
+
"rows": 47,
|
| 210 |
+
"silent_skip_rate_of_fills": 0.10344827586206896,
|
| 211 |
+
"silent_skips": 3,
|
| 212 |
+
"top1": 0.851063829787234
|
| 213 |
+
},
|
| 214 |
+
"package_bytes": 806132,
|
| 215 |
+
"synthetic_test__ane": {
|
| 216 |
+
"compute_units": "ComputeUnit.CPU_AND_NE",
|
| 217 |
+
"latency_ms_median": 1.315583474934101,
|
| 218 |
+
"latency_ms_p95": 1.401625107973814,
|
| 219 |
+
"mismatches_vs_torch": 9,
|
| 220 |
+
"parity_with_torch": 0.9961072664359861,
|
| 221 |
+
"per_action": {
|
| 222 |
+
"check": {
|
| 223 |
+
"acc": 0.9827586206896551,
|
| 224 |
+
"n": 58
|
| 225 |
+
},
|
| 226 |
+
"click": {
|
| 227 |
+
"acc": 0.9367088607594937,
|
| 228 |
+
"n": 79
|
| 229 |
+
},
|
| 230 |
+
"fill": {
|
| 231 |
+
"acc": 0.753968253968254,
|
| 232 |
+
"n": 1008
|
| 233 |
+
},
|
| 234 |
+
"skip": {
|
| 235 |
+
"acc": 0.882604970008569,
|
| 236 |
+
"n": 1167
|
| 237 |
+
}
|
| 238 |
+
},
|
| 239 |
+
"rows": 2312,
|
| 240 |
+
"silent_skip_rate_of_fills": 0.07539682539682539,
|
| 241 |
+
"silent_skips": 76,
|
| 242 |
+
"top1": 0.8308823529411765
|
| 243 |
+
}
|
| 244 |
+
}
|
| 245 |
+
}
|
| 246 |
+
}
|
eval/results-pytorch.json
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"device": "mps",
|
| 3 |
+
"reference": {
|
| 4 |
+
"checkpoint": "/tmp/cua1ckpt/cua-s1-forms.safetensors",
|
| 5 |
+
"checkpoint_bytes": 2828784,
|
| 6 |
+
"config": {
|
| 7 |
+
"context_tokens": 224,
|
| 8 |
+
"encoder": "tinyx",
|
| 9 |
+
"heads": 4,
|
| 10 |
+
"hf_model": "Qwen/Qwen2.5-0.5B",
|
| 11 |
+
"layers": 2,
|
| 12 |
+
"option_tokens": 96,
|
| 13 |
+
"rank": 128,
|
| 14 |
+
"width": 128
|
| 15 |
+
},
|
| 16 |
+
"label": "cua-s1-forms-english",
|
| 17 |
+
"sv_handwritten_demo": {
|
| 18 |
+
"action_mix": {
|
| 19 |
+
"check": 3,
|
| 20 |
+
"click": 3,
|
| 21 |
+
"fill": 32,
|
| 22 |
+
"skip": 12
|
| 23 |
+
},
|
| 24 |
+
"ece": 0.660977,
|
| 25 |
+
"examples": 50,
|
| 26 |
+
"majority_baseline": 0.64,
|
| 27 |
+
"per_action": {
|
| 28 |
+
"check": {
|
| 29 |
+
"acc": 0.66667,
|
| 30 |
+
"n": 3
|
| 31 |
+
},
|
| 32 |
+
"click": {
|
| 33 |
+
"acc": 0.33333,
|
| 34 |
+
"n": 3
|
| 35 |
+
},
|
| 36 |
+
"fill": {
|
| 37 |
+
"acc": 0.15625,
|
| 38 |
+
"n": 32
|
| 39 |
+
},
|
| 40 |
+
"skip": {
|
| 41 |
+
"acc": 0.16667,
|
| 42 |
+
"n": 12
|
| 43 |
+
}
|
| 44 |
+
},
|
| 45 |
+
"skipped_when_fill_expected": 16,
|
| 46 |
+
"top1": 0.2
|
| 47 |
+
},
|
| 48 |
+
"sv_handwritten_demo__shuffled_context": {
|
| 49 |
+
"action_mix": {
|
| 50 |
+
"check": 3,
|
| 51 |
+
"click": 3,
|
| 52 |
+
"fill": 32,
|
| 53 |
+
"skip": 12
|
| 54 |
+
},
|
| 55 |
+
"ece": 0.760258,
|
| 56 |
+
"examples": 50,
|
| 57 |
+
"majority_baseline": 0.64,
|
| 58 |
+
"per_action": {
|
| 59 |
+
"check": {
|
| 60 |
+
"acc": 0.66667,
|
| 61 |
+
"n": 3
|
| 62 |
+
},
|
| 63 |
+
"click": {
|
| 64 |
+
"acc": 0.0,
|
| 65 |
+
"n": 3
|
| 66 |
+
},
|
| 67 |
+
"fill": {
|
| 68 |
+
"acc": 0.0,
|
| 69 |
+
"n": 32
|
| 70 |
+
},
|
| 71 |
+
"skip": {
|
| 72 |
+
"acc": 0.25,
|
| 73 |
+
"n": 12
|
| 74 |
+
}
|
| 75 |
+
},
|
| 76 |
+
"skipped_when_fill_expected": 13,
|
| 77 |
+
"top1": 0.1
|
| 78 |
+
},
|
| 79 |
+
"sv_synthetic_test": {
|
| 80 |
+
"action_mix": {
|
| 81 |
+
"check": 58,
|
| 82 |
+
"click": 79,
|
| 83 |
+
"fill": 1010,
|
| 84 |
+
"skip": 1168
|
| 85 |
+
},
|
| 86 |
+
"ece": 0.640725,
|
| 87 |
+
"examples": 2315,
|
| 88 |
+
"majority_baseline": 0.50454,
|
| 89 |
+
"per_action": {
|
| 90 |
+
"check": {
|
| 91 |
+
"acc": 0.93103,
|
| 92 |
+
"n": 58
|
| 93 |
+
},
|
| 94 |
+
"click": {
|
| 95 |
+
"acc": 0.26582,
|
| 96 |
+
"n": 79
|
| 97 |
+
},
|
| 98 |
+
"fill": {
|
| 99 |
+
"acc": 0.05545,
|
| 100 |
+
"n": 1010
|
| 101 |
+
},
|
| 102 |
+
"skip": {
|
| 103 |
+
"acc": 0.31164,
|
| 104 |
+
"n": 1168
|
| 105 |
+
}
|
| 106 |
+
},
|
| 107 |
+
"skipped_when_fill_expected": 371,
|
| 108 |
+
"top1": 0.21382
|
| 109 |
+
},
|
| 110 |
+
"sv_synthetic_test__shuffled_context": {
|
| 111 |
+
"action_mix": {
|
| 112 |
+
"check": 58,
|
| 113 |
+
"click": 79,
|
| 114 |
+
"fill": 1010,
|
| 115 |
+
"skip": 1168
|
| 116 |
+
},
|
| 117 |
+
"ece": 0.679541,
|
| 118 |
+
"examples": 2315,
|
| 119 |
+
"majority_baseline": 0.50454,
|
| 120 |
+
"per_action": {
|
| 121 |
+
"check": {
|
| 122 |
+
"acc": 0.60345,
|
| 123 |
+
"n": 58
|
| 124 |
+
},
|
| 125 |
+
"click": {
|
| 126 |
+
"acc": 0.06329,
|
| 127 |
+
"n": 79
|
| 128 |
+
},
|
| 129 |
+
"fill": {
|
| 130 |
+
"acc": 0.01782,
|
| 131 |
+
"n": 1010
|
| 132 |
+
},
|
| 133 |
+
"skip": {
|
| 134 |
+
"acc": 0.29709,
|
| 135 |
+
"n": 1168
|
| 136 |
+
}
|
| 137 |
+
},
|
| 138 |
+
"skipped_when_fill_expected": 363,
|
| 139 |
+
"top1": 0.17495
|
| 140 |
+
},
|
| 141 |
+
"trainable_params": 706048
|
| 142 |
+
},
|
| 143 |
+
"sv": {
|
| 144 |
+
"checkpoint": "runs/sv-tinyx/model/model.safetensors",
|
| 145 |
+
"checkpoint_bytes": 2828784,
|
| 146 |
+
"config": {
|
| 147 |
+
"context_tokens": 224,
|
| 148 |
+
"encoder": "tinyx",
|
| 149 |
+
"heads": 4,
|
| 150 |
+
"layers": 2,
|
| 151 |
+
"option_tokens": 96,
|
| 152 |
+
"rank": 128,
|
| 153 |
+
"width": 128
|
| 154 |
+
},
|
| 155 |
+
"label": "swedish-specialist",
|
| 156 |
+
"sv_handwritten_demo": {
|
| 157 |
+
"action_mix": {
|
| 158 |
+
"check": 3,
|
| 159 |
+
"click": 3,
|
| 160 |
+
"fill": 32,
|
| 161 |
+
"skip": 12
|
| 162 |
+
},
|
| 163 |
+
"ece": 0.09176,
|
| 164 |
+
"examples": 50,
|
| 165 |
+
"majority_baseline": 0.64,
|
| 166 |
+
"per_action": {
|
| 167 |
+
"check": {
|
| 168 |
+
"acc": 1.0,
|
| 169 |
+
"n": 3
|
| 170 |
+
},
|
| 171 |
+
"click": {
|
| 172 |
+
"acc": 1.0,
|
| 173 |
+
"n": 3
|
| 174 |
+
},
|
| 175 |
+
"fill": {
|
| 176 |
+
"acc": 0.8125,
|
| 177 |
+
"n": 32
|
| 178 |
+
},
|
| 179 |
+
"skip": {
|
| 180 |
+
"acc": 0.91667,
|
| 181 |
+
"n": 12
|
| 182 |
+
}
|
| 183 |
+
},
|
| 184 |
+
"skipped_when_fill_expected": 3,
|
| 185 |
+
"top1": 0.86
|
| 186 |
+
},
|
| 187 |
+
"sv_handwritten_demo__shuffled_context": {
|
| 188 |
+
"action_mix": {
|
| 189 |
+
"check": 3,
|
| 190 |
+
"click": 3,
|
| 191 |
+
"fill": 32,
|
| 192 |
+
"skip": 12
|
| 193 |
+
},
|
| 194 |
+
"ece": 0.785789,
|
| 195 |
+
"examples": 50,
|
| 196 |
+
"majority_baseline": 0.64,
|
| 197 |
+
"per_action": {
|
| 198 |
+
"check": {
|
| 199 |
+
"acc": 0.0,
|
| 200 |
+
"n": 3
|
| 201 |
+
},
|
| 202 |
+
"click": {
|
| 203 |
+
"acc": 0.0,
|
| 204 |
+
"n": 3
|
| 205 |
+
},
|
| 206 |
+
"fill": {
|
| 207 |
+
"acc": 0.0,
|
| 208 |
+
"n": 32
|
| 209 |
+
},
|
| 210 |
+
"skip": {
|
| 211 |
+
"acc": 0.25,
|
| 212 |
+
"n": 12
|
| 213 |
+
}
|
| 214 |
+
},
|
| 215 |
+
"skipped_when_fill_expected": 6,
|
| 216 |
+
"top1": 0.06
|
| 217 |
+
},
|
| 218 |
+
"sv_synthetic_test": {
|
| 219 |
+
"action_mix": {
|
| 220 |
+
"check": 58,
|
| 221 |
+
"click": 79,
|
| 222 |
+
"fill": 1010,
|
| 223 |
+
"skip": 1168
|
| 224 |
+
},
|
| 225 |
+
"ece": 0.016565,
|
| 226 |
+
"examples": 2315,
|
| 227 |
+
"majority_baseline": 0.50454,
|
| 228 |
+
"per_action": {
|
| 229 |
+
"check": {
|
| 230 |
+
"acc": 0.98276,
|
| 231 |
+
"n": 58
|
| 232 |
+
},
|
| 233 |
+
"click": {
|
| 234 |
+
"acc": 0.93671,
|
| 235 |
+
"n": 79
|
| 236 |
+
},
|
| 237 |
+
"fill": {
|
| 238 |
+
"acc": 0.75545,
|
| 239 |
+
"n": 1010
|
| 240 |
+
},
|
| 241 |
+
"skip": {
|
| 242 |
+
"acc": 0.88014,
|
| 243 |
+
"n": 1168
|
| 244 |
+
}
|
| 245 |
+
},
|
| 246 |
+
"skipped_when_fill_expected": 76,
|
| 247 |
+
"top1": 0.83024
|
| 248 |
+
},
|
| 249 |
+
"sv_synthetic_test__shuffled_context": {
|
| 250 |
+
"action_mix": {
|
| 251 |
+
"check": 58,
|
| 252 |
+
"click": 79,
|
| 253 |
+
"fill": 1010,
|
| 254 |
+
"skip": 1168
|
| 255 |
+
},
|
| 256 |
+
"ece": 0.497346,
|
| 257 |
+
"examples": 2315,
|
| 258 |
+
"majority_baseline": 0.50454,
|
| 259 |
+
"per_action": {
|
| 260 |
+
"check": {
|
| 261 |
+
"acc": 0.15517,
|
| 262 |
+
"n": 58
|
| 263 |
+
},
|
| 264 |
+
"click": {
|
| 265 |
+
"acc": 0.0,
|
| 266 |
+
"n": 79
|
| 267 |
+
},
|
| 268 |
+
"fill": {
|
| 269 |
+
"acc": 0.01287,
|
| 270 |
+
"n": 1010
|
| 271 |
+
},
|
| 272 |
+
"skip": {
|
| 273 |
+
"acc": 0.65668,
|
| 274 |
+
"n": 1168
|
| 275 |
+
}
|
| 276 |
+
},
|
| 277 |
+
"skipped_when_fill_expected": 264,
|
| 278 |
+
"top1": 0.34082
|
| 279 |
+
},
|
| 280 |
+
"trainable_params": 706048
|
| 281 |
+
}
|
| 282 |
+
}
|
example.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Minimal inference example for precisit/sv0-forms.
|
| 2 |
+
|
| 3 |
+
Two routes: the Core ML package (no PyTorch needed) and the PyTorch checkpoint through the
|
| 4 |
+
vendored Cua-S1 loader. Both take the same byte-level inputs; the encoder is:
|
| 5 |
+
|
| 6 |
+
ids = utf-8 bytes, truncated to the limit, each byte + 1, zero-padded
|
| 7 |
+
context: 224 bytes | option: 96 bytes | up to 40 options (the export's ceiling)
|
| 8 |
+
|
| 9 |
+
Run: python example.py (Core ML, needs coremltools)
|
| 10 |
+
python example.py --torch (PyTorch, needs torch + safetensors + the vendored package)
|
| 11 |
+
"""
|
| 12 |
+
|
| 13 |
+
from __future__ import annotations
|
| 14 |
+
|
| 15 |
+
import argparse
|
| 16 |
+
import json
|
| 17 |
+
from pathlib import Path
|
| 18 |
+
|
| 19 |
+
HERE = Path(__file__).resolve().parent
|
| 20 |
+
CONTEXT_BYTES, OPTION_BYTES, MAX_OPTIONS = 224, 96, 40
|
| 21 |
+
|
| 22 |
+
TASK = "UPPGIFT fyll i formuläret från dokumentet och skicka sedan in"
|
| 23 |
+
FORM = "Exempelkliniken - Ny patientregistrering"
|
| 24 |
+
ELEMENT = ('Edit "E-post" value=""',)
|
| 25 |
+
OPTIONS = [
|
| 26 |
+
"fyll Förnamn: Anna",
|
| 27 |
+
"fyll Efternamn: Lindqvist",
|
| 28 |
+
"fyll E-post: anna.lindqvist@exempel.invalid",
|
| 29 |
+
"fyll Telefon: 070-341 22 87",
|
| 30 |
+
"kryssa",
|
| 31 |
+
"klicka",
|
| 32 |
+
"hoppa över",
|
| 33 |
+
]
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def context_string() -> str:
|
| 37 |
+
role, label, state = ELEMENT[0], "E-post", 'value=""'
|
| 38 |
+
return f"{TASK}\nFORM {FORM}\nELEMENT {role} \"{label}\" {state}"
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def byte_ids(text: str, length: int) -> list[int]:
|
| 42 |
+
return [byte + 1 for byte in text.encode("utf-8", errors="replace")[:length]]
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def pad(ids: list[int], length: int) -> list[int]:
|
| 46 |
+
return ids + [0] * (length - len(ids))
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def via_coreml() -> None:
|
| 50 |
+
import coremltools as ct
|
| 51 |
+
import numpy as np
|
| 52 |
+
|
| 53 |
+
package = HERE / "coreml" / "sv0_forms_int8_options40.mlpackage"
|
| 54 |
+
model = ct.models.MLModel(str(package), compute_units=ct.ComputeUnit.CPU_AND_NE)
|
| 55 |
+
context = np.array([pad(byte_ids(context_string(), CONTEXT_BYTES), CONTEXT_BYTES)], dtype=np.int32)
|
| 56 |
+
options = np.zeros((1, MAX_OPTIONS, OPTION_BYTES), dtype=np.int32)
|
| 57 |
+
for index, option in enumerate(OPTIONS):
|
| 58 |
+
encoded = pad(byte_ids(option, OPTION_BYTES), OPTION_BYTES)
|
| 59 |
+
options[0, index] = np.array(encoded, dtype=np.int32)
|
| 60 |
+
mask = np.zeros((1, MAX_OPTIONS), dtype=np.int32)
|
| 61 |
+
mask[0, : len(OPTIONS)] = 1
|
| 62 |
+
output = model.predict({"context_ids": context, "option_ids": options, "option_mask": mask})
|
| 63 |
+
scores = output["logits"][0][: len(OPTIONS)] # raw logits; softmax them if you need probabilities
|
| 64 |
+
best = int(scores.argmax())
|
| 65 |
+
print(f"chosen: {OPTIONS[best]!r} (logit {float(scores[best]):.3f})")
|
| 66 |
+
print("logits:", {option: round(float(score), 3) for option, score in zip(OPTIONS, scores)})
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def via_torch() -> None:
|
| 70 |
+
import torch
|
| 71 |
+
from huggingface_hub import hf_hub_download
|
| 72 |
+
|
| 73 |
+
try:
|
| 74 |
+
from cua_s1.model import ChoiceExample, load_checkpoint, select_device # type: ignore
|
| 75 |
+
except ImportError: # pragma: no cover
|
| 76 |
+
raise SystemExit(
|
| 77 |
+
"The PyTorch route needs the vendored Cua-S1 loader: clone the toolkit repository "
|
| 78 |
+
"(precisit/onepass) and put its `vendor/` directory on sys.path, or import this "
|
| 79 |
+
"repository's Core ML packages instead — they need no PyTorch."
|
| 80 |
+
)
|
| 81 |
+
|
| 82 |
+
weights = HERE / "sv0-forms.safetensors"
|
| 83 |
+
if not weights.exists(): # when the script is run outside the repository
|
| 84 |
+
weights = Path(hf_hub_download("precisit/one-pass-sv-forms", "sv0-forms.safetensors"))
|
| 85 |
+
hf_hub_download("precisit/one-pass-sv-forms", "sv0-forms.json", local_dir=weights.parent)
|
| 86 |
+
device = select_device("auto")
|
| 87 |
+
model, collator, _ = load_checkpoint(weights, device)
|
| 88 |
+
batch = collator([ChoiceExample(context=context_string(), options=tuple(OPTIONS), label=0)])
|
| 89 |
+
with torch.no_grad():
|
| 90 |
+
scores = model({key: value.to(device) for key, value in batch.items()})[0].softmax(-1)
|
| 91 |
+
best = int(scores.argmax())
|
| 92 |
+
print(f"chosen: {OPTIONS[best]!r} (probability {float(scores[best]):.3f})")
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def metadata() -> None:
|
| 96 |
+
print(json.dumps(json.loads((HERE / "sv0-forms.json").read_text(encoding="utf-8"))["metadata"], indent=2))
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
if __name__ == "__main__":
|
| 100 |
+
parser = argparse.ArgumentParser(description=__doc__)
|
| 101 |
+
parser.add_argument("--torch", action="store_true", help="use the PyTorch checkpoint instead of Core ML")
|
| 102 |
+
parser.add_argument("--metadata", action="store_true", help="print the training metadata and exit")
|
| 103 |
+
arguments = parser.parse_args()
|
| 104 |
+
if arguments.metadata:
|
| 105 |
+
metadata()
|
| 106 |
+
elif arguments.torch:
|
| 107 |
+
via_torch()
|
| 108 |
+
else:
|
| 109 |
+
via_coreml()
|
sv0-forms.json
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"config": {
|
| 3 |
+
"context_tokens": 224,
|
| 4 |
+
"encoder": "tinyx",
|
| 5 |
+
"heads": 4,
|
| 6 |
+
"layers": 2,
|
| 7 |
+
"option_tokens": 96,
|
| 8 |
+
"rank": 128,
|
| 9 |
+
"width": 128
|
| 10 |
+
},
|
| 11 |
+
"format": "cua-s1",
|
| 12 |
+
"format_version": 1,
|
| 13 |
+
"metadata": {
|
| 14 |
+
"batch_size": 64,
|
| 15 |
+
"best_validation": {
|
| 16 |
+
"ece": 0.018766840075841174,
|
| 17 |
+
"examples": 2855,
|
| 18 |
+
"nll": 0.51966637646463,
|
| 19 |
+
"per_action": {
|
| 20 |
+
"check": {
|
| 21 |
+
"acc": 1.0,
|
| 22 |
+
"n": 87
|
| 23 |
+
},
|
| 24 |
+
"click": {
|
| 25 |
+
"acc": 0.9479166666666666,
|
| 26 |
+
"n": 96
|
| 27 |
+
},
|
| 28 |
+
"fill": {
|
| 29 |
+
"acc": 0.7756680731364276,
|
| 30 |
+
"n": 1422
|
| 31 |
+
},
|
| 32 |
+
"skip": {
|
| 33 |
+
"acc": 0.8712,
|
| 34 |
+
"n": 1250
|
| 35 |
+
}
|
| 36 |
+
},
|
| 37 |
+
"top1": 0.8301225900650024
|
| 38 |
+
},
|
| 39 |
+
"deterministic": false,
|
| 40 |
+
"epochs": 4,
|
| 41 |
+
"history": [
|
| 42 |
+
{
|
| 43 |
+
"epoch": 1,
|
| 44 |
+
"train_nll": 2.060510016020325,
|
| 45 |
+
"validation": {
|
| 46 |
+
"ece": 0.05491860159418138,
|
| 47 |
+
"examples": 2855,
|
| 48 |
+
"nll": 1.748936438351713,
|
| 49 |
+
"per_action": {
|
| 50 |
+
"check": {
|
| 51 |
+
"acc": 0.4367816091954023,
|
| 52 |
+
"n": 87
|
| 53 |
+
},
|
| 54 |
+
"click": {
|
| 55 |
+
"acc": 0.3958333333333333,
|
| 56 |
+
"n": 96
|
| 57 |
+
},
|
| 58 |
+
"fill": {
|
| 59 |
+
"acc": 0.06118143459915612,
|
| 60 |
+
"n": 1422
|
| 61 |
+
},
|
| 62 |
+
"skip": {
|
| 63 |
+
"acc": 0.9712,
|
| 64 |
+
"n": 1250
|
| 65 |
+
}
|
| 66 |
+
},
|
| 67 |
+
"top1": 0.4823117256164551
|
| 68 |
+
}
|
| 69 |
+
},
|
| 70 |
+
{
|
| 71 |
+
"epoch": 2,
|
| 72 |
+
"train_nll": 1.3498624871227647,
|
| 73 |
+
"validation": {
|
| 74 |
+
"ece": 0.029052662350295577,
|
| 75 |
+
"examples": 2855,
|
| 76 |
+
"nll": 1.1316383522153945,
|
| 77 |
+
"per_action": {
|
| 78 |
+
"check": {
|
| 79 |
+
"acc": 0.9770114942528736,
|
| 80 |
+
"n": 87
|
| 81 |
+
},
|
| 82 |
+
"click": {
|
| 83 |
+
"acc": 0.8854166666666666,
|
| 84 |
+
"n": 96
|
| 85 |
+
},
|
| 86 |
+
"fill": {
|
| 87 |
+
"acc": 0.4212376933895921,
|
| 88 |
+
"n": 1422
|
| 89 |
+
},
|
| 90 |
+
"skip": {
|
| 91 |
+
"acc": 0.8232,
|
| 92 |
+
"n": 1250
|
| 93 |
+
}
|
| 94 |
+
},
|
| 95 |
+
"top1": 0.6297723054885864
|
| 96 |
+
}
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"epoch": 3,
|
| 100 |
+
"train_nll": 0.7656327178699136,
|
| 101 |
+
"validation": {
|
| 102 |
+
"ece": 0.02394736194401048,
|
| 103 |
+
"examples": 2855,
|
| 104 |
+
"nll": 0.6415376866970296,
|
| 105 |
+
"per_action": {
|
| 106 |
+
"check": {
|
| 107 |
+
"acc": 0.9770114942528736,
|
| 108 |
+
"n": 87
|
| 109 |
+
},
|
| 110 |
+
"click": {
|
| 111 |
+
"acc": 0.9791666666666666,
|
| 112 |
+
"n": 96
|
| 113 |
+
},
|
| 114 |
+
"fill": {
|
| 115 |
+
"acc": 0.7088607594936709,
|
| 116 |
+
"n": 1422
|
| 117 |
+
},
|
| 118 |
+
"skip": {
|
| 119 |
+
"acc": 0.8464,
|
| 120 |
+
"n": 1250
|
| 121 |
+
}
|
| 122 |
+
},
|
| 123 |
+
"top1": 0.7863397598266602
|
| 124 |
+
}
|
| 125 |
+
},
|
| 126 |
+
{
|
| 127 |
+
"epoch": 4,
|
| 128 |
+
"train_nll": 0.4496109453594249,
|
| 129 |
+
"validation": {
|
| 130 |
+
"ece": 0.018766840075841174,
|
| 131 |
+
"examples": 2855,
|
| 132 |
+
"nll": 0.51966637646463,
|
| 133 |
+
"per_action": {
|
| 134 |
+
"check": {
|
| 135 |
+
"acc": 1.0,
|
| 136 |
+
"n": 87
|
| 137 |
+
},
|
| 138 |
+
"click": {
|
| 139 |
+
"acc": 0.9479166666666666,
|
| 140 |
+
"n": 96
|
| 141 |
+
},
|
| 142 |
+
"fill": {
|
| 143 |
+
"acc": 0.7756680731364276,
|
| 144 |
+
"n": 1422
|
| 145 |
+
},
|
| 146 |
+
"skip": {
|
| 147 |
+
"acc": 0.8712,
|
| 148 |
+
"n": 1250
|
| 149 |
+
}
|
| 150 |
+
},
|
| 151 |
+
"top1": 0.8301225900650024
|
| 152 |
+
}
|
| 153 |
+
}
|
| 154 |
+
],
|
| 155 |
+
"learning_rate": 0.002,
|
| 156 |
+
"seed": 7,
|
| 157 |
+
"task": "form-specialist-choice-classification",
|
| 158 |
+
"warmup": 0.05,
|
| 159 |
+
"workers": 0
|
| 160 |
+
},
|
| 161 |
+
"state_signature": "86e836863df8a0b0caa34ac5eab18bcd4fb44e420f83e271c96379fac0b0aec4"
|
| 162 |
+
}
|
sv0-forms.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b9030d7a7b7abfaf70dd1cc2a390568eaa3a55849daa0757b60d01dbab162356
|
| 3 |
+
size 2828784
|