Skip to main content

sysone

Fine-tune and calibrate "system one" decision models: small transformers that answer typed questions (choice, score, yes/no) about a piece of text in a single forward pass. You pick a base model, call fit on labelled rows and predict on new ones. sysone handles tokenization, position ids, attention masks, layer freezing, the decision head and the training loop.

Supported base models: ModernBERT (EncoderModel) and Qwen3 (DecoderModel). Others can be added by writing one architecture class.

Install

pip install sysone
pip install "sysone[pandas]"   # also installs pandas, for the comparison tables of `compare`

On Linux and Windows this also installs bitsandbytes, for 4-bit training (tuning="qlora").

Quickstart

from sysone import DecoderModel

questions = {
    "team":     {"type": "choice", "instructions": "Which team should handle it?",
                 "criteria": ["sales", "operations", "servicing"]},
    "severity": {"type": "score", "instructions": "How severe is it?",
                 "criteria": ["none", "minor", "major", "critical"]},
    "refund":   {"type": "noul", "instructions": "Is the customer asking for a refund?"},
}

rows = [
    {"state": "Hi, my order is stuck in the warehouse and our line is down.",
     "category": "operations",
     "questions": questions,
     "expected": {"team": "operations", "severity": 3, "refund": False}},
    # ... more rows; rows may mix different question sets
]

model = DecoderModel(tuning="head").fit(rows)

model.predict("I'd like my money back for the broken unit.", questions)
# {"answers": {"team": {"type": "choice", "choice": "servicing", "probabilities": {...}, "confidence": ...},
#              "severity": {"type": "score", "score": 1.2, "legend": {...}, ...},
#              "refund": {"type": "noul", "noul": 0.97, ...}},
#  "usage": {"input_tokens": 118, "output_tokens": 0}}

model.save("my-model")
model = DecoderModel.load("my-model")

To measure the model on held-out labelled rows, and compare it with simple baselines:

from sysone import baselines, compare

results = baselines(test_rows, train=rows)      # random guess, average answer
results["trained"] = model.evaluate(test_rows)
compare(results)                                # accuracy per question type, as a table

Answers follow the Jev /v1/systemone response shape. Training data can be records like the above, records plus a shared question catalog, a long DataFrame, or a .jsonl / .csv / .parquet file. Labels go in expected, in a label inside each question, or as soft gold probabilities.

Example notebooks, each comparing accuracy before and after training:

Notebooks other than the quickstart are named <model type>_<dataset>.ipynb.

Status

This is an early version (0.3). Training covers every tuning mode:

  • "head": the backbone is frozen, its outputs are computed once and cached (in memory, and on disk with cache_dir), and only the decision head trains;
  • "lora", "qlora" and "full": adapters or whole layers of the backbone train along with the head. These run on a laptop GPU (Apple MPS) for small datasets; a CUDA GPU is recommended for full-size runs. "qlora" needs bitsandbytes and an NVIDIA GPU and falls back to "lora" elsewhere, with a warning. It has trained, saved and reloaded in real 4-bit on a Colab GPU.

DecoderModel (Qwen3) defaults to "qlora". EncoderModel (ModernBERT) defaults to "full": adapters barely moved ModernBERT, while full tuning reached 0.79 test accuracy on typed-decisions.

Training stops at epochs, by early stopping, or at target_loss. A run that is interrupted (Ctrl-C), or saved and loaded, resumes exactly where it stopped. With checkpoint_dir, fit also saves the model when it ends or is interrupted, and every checkpoint_every steps if set, so a disconnected notebook can pick the run up again; nothing is written to disk by default.

Score questions add an ordinal term to the loss (ordinal_weight), so a near miss costs less than a far one. After training, probabilities are calibrated with temperatures fitted on the validation slice, so answer_confidence matches how often answers are right; reports include Brier score and expected calibration error, before and after calibration. head="full" is designed but not yet implemented.

See docs/DESIGN.md for the full design: every parameter, the layouts, architectures, heads, training and checkpoint format.

Development

uv sync                  # or: pip install -e . with the dev dependencies
uv run pytest            # fast tests on tiny random-weight models, no downloads
uv run pytest -m slow    # end-to-end tests on the real base models (~1.8 GB download)
uv run ruff check src tests

Metadata

Release files for sysone 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sysone 0.3.0
File Size Uploaded Provenance
sysone-0.3.0.tar.gz 101.4 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sysone 0.3.0
File Interpreter ABI Platform
sysone-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 164.4 kB

Release files / sysone-0.3.0.tar.gz

Download URL sysone-0.3.0.tar.gz
Size 101.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1e7596b7c521773c21977011d4be754bba51ec01c46580f20d2e19a4b93e2eb7
BLAKE2b-256 checksum
How to use checksums
234ae826646b9becde31db56d849c4d6fb4da84db3825e68ef522c27f32ae450
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / sysone-0.3.0-py3-none-any.whl

Download URL sysone-0.3.0-py3-none-any.whl
Size 63.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
150d3bfcb34d653630a7fc6fc04311b5eafbfa549de9cd868f12309383840e91
BLAKE2b-256 checksum
How to use checksums
a3017b9df62c50cd09c94f215755b05506a166c7a01ec84f13553d5f8003a914
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Security for sysone 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page