sysone 0.2.0__py3-none-any.whl
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.
- sysone/__init__.py +22 -0
- sysone/_util.py +102 -0
- sysone/answers.py +57 -0
- sysone/architectures/__init__.py +12 -0
- sysone/architectures/base.py +144 -0
- sysone/architectures/modernbert.py +43 -0
- sysone/architectures/qwen.py +48 -0
- sysone/architectures/registry.py +53 -0
- sysone/base.py +890 -0
- sysone/cache.py +196 -0
- sysone/checkpoint.py +96 -0
- sysone/data.py +190 -0
- sysone/encoding.py +80 -0
- sysone/evaluation.py +167 -0
- sysone/features.py +98 -0
- sysone/heads.py +66 -0
- sysone/layout.py +129 -0
- sysone/losses.py +17 -0
- sysone/models.py +24 -0
- sysone/prompts.py +60 -0
- sysone/questions.py +186 -0
- sysone/training.py +399 -0
- sysone/tuning.py +210 -0
- sysone/version.py +1 -0
- sysone-0.2.0.dist-info/METADATA +144 -0
- sysone-0.2.0.dist-info/RECORD +28 -0
- sysone-0.2.0.dist-info/WHEEL +4 -0
- sysone-0.2.0.dist-info/licenses/LICENSE +21 -0
sysone/tuning.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""How much of the backbone learns: layer plans, freezing, and LoRA / QLoRA adapters.
|
|
2
|
+
|
|
3
|
+
The kept layers are split from the top down:
|
|
4
|
+
|
|
5
|
+
bottom ── frozen ── adapters (n_lora) ── fully trained (n_full) ── top
|
|
6
|
+
|
|
7
|
+
The head always trains. With `train_embeddings` the token embeddings train too.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import contextlib
|
|
13
|
+
import re
|
|
14
|
+
import sys
|
|
15
|
+
import warnings
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
|
|
18
|
+
import torch
|
|
19
|
+
from torch import nn
|
|
20
|
+
|
|
21
|
+
from ._util import resolve_count
|
|
22
|
+
from .architectures.base import Architecture
|
|
23
|
+
|
|
24
|
+
#: (trainable_layers, lora_layers) when the user leaves them at None.
|
|
25
|
+
_DEFAULT_LAYERS = {"head": (0, 0), "qlora": (0, 0.6), "lora": (0, 0.6), "full": ("all", 0)}
|
|
26
|
+
#: Adapter weights carry this in their parameter names (peft's naming).
|
|
27
|
+
_ADAPTER_NAME = re.compile(r"\.lora_[AB]\.")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class LayerPlan:
|
|
32
|
+
n_layers: int # layers kept by num_layers
|
|
33
|
+
n_full: int # fully trained top layers
|
|
34
|
+
n_lora: int # layers with adapters, directly below the fully trained ones
|
|
35
|
+
train_embeddings: bool = False
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def full_range(self) -> range:
|
|
39
|
+
return range(self.n_layers - self.n_full, self.n_layers)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def lora_range(self) -> range:
|
|
43
|
+
top = self.n_layers - self.n_full
|
|
44
|
+
return range(top - self.n_lora, top)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def learns(self) -> bool:
|
|
48
|
+
"""True when anything in the backbone trains, so its outputs change every step."""
|
|
49
|
+
return bool(self.n_full or self.n_lora or self.train_embeddings)
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def lowest_trained(self) -> int:
|
|
53
|
+
"""The lowest layer gradients flow through (`n_layers` when the backbone is frozen)."""
|
|
54
|
+
if self.train_embeddings:
|
|
55
|
+
return 0
|
|
56
|
+
return self.n_layers - self.n_full - self.n_lora
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def layer_plan(tuning: str, n_layers: int, trainable_layers, lora_layers, train_embeddings: bool) -> LayerPlan:
|
|
60
|
+
full_default, lora_default = _DEFAULT_LAYERS[tuning]
|
|
61
|
+
n_full = resolve_count(full_default if trainable_layers is None else trainable_layers, n_layers,
|
|
62
|
+
"trainable_layers")
|
|
63
|
+
n_lora = resolve_count(lora_default if lora_layers is None else lora_layers, n_layers, "lora_layers")
|
|
64
|
+
if n_full + n_lora > n_layers:
|
|
65
|
+
raise ValueError("trainable_layers + lora_layers = %d + %d is more than the %d kept layers"
|
|
66
|
+
% (n_full, n_lora, n_layers))
|
|
67
|
+
return LayerPlan(n_layers, n_full, n_lora, bool(train_embeddings))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def quantization_available(device: torch.device) -> bool:
|
|
71
|
+
"""4-bit and 8-bit loading need bitsandbytes and, in practice, an NVIDIA GPU."""
|
|
72
|
+
if device.type != "cuda":
|
|
73
|
+
return False
|
|
74
|
+
try:
|
|
75
|
+
import bitsandbytes # noqa: F401
|
|
76
|
+
except ImportError:
|
|
77
|
+
return False
|
|
78
|
+
return True
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def effective_tuning(tuning: str, device: torch.device, stacklevel: int = 2) -> str:
|
|
82
|
+
"""`tuning`, except that "qlora" trains as "lora" where quantized loading is unavailable."""
|
|
83
|
+
if tuning == "qlora" and not quantization_available(device):
|
|
84
|
+
warnings.warn("tuning='qlora' needs bitsandbytes and an NVIDIA GPU, which aren't available here "
|
|
85
|
+
"(device=%s); using tuning='lora' instead: the same adapters, with the frozen weights "
|
|
86
|
+
"unquantized, so only memory use differs" % device, UserWarning, stacklevel=stacklevel + 1)
|
|
87
|
+
return "lora"
|
|
88
|
+
return tuning
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def quantization_config(bits: int, quant_type: str, compute_dtype: torch.dtype):
|
|
92
|
+
from transformers import BitsAndBytesConfig
|
|
93
|
+
|
|
94
|
+
if bits == 4:
|
|
95
|
+
return BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type=quant_type,
|
|
96
|
+
bnb_4bit_compute_dtype=compute_dtype)
|
|
97
|
+
return BitsAndBytesConfig(load_in_8bit=True)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def lora_config(arch: Architecture, backbone: nn.Module, plan: LayerPlan, targets, rank: int, alpha, dropout: float):
|
|
101
|
+
from peft import LoraConfig
|
|
102
|
+
|
|
103
|
+
modules = arch.adapter_modules(backbone, targets, plan.lora_range)
|
|
104
|
+
if not modules:
|
|
105
|
+
raise ValueError("lora_targets=%r found no linear modules in layers %d-%d"
|
|
106
|
+
% (targets, plan.lora_range.start, plan.lora_range.stop - 1))
|
|
107
|
+
return LoraConfig(r=rank, lora_alpha=2 * rank if alpha is None else alpha, lora_dropout=dropout,
|
|
108
|
+
target_modules=modules, bias="none")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def add_adapters(backbone: nn.Module, config) -> None:
|
|
112
|
+
"""Put LoRA adapters on `backbone` in place; the model stays a plain Hugging Face model."""
|
|
113
|
+
from peft import inject_adapter_in_model
|
|
114
|
+
|
|
115
|
+
with _ignore_incompatible_torchao():
|
|
116
|
+
inject_adapter_in_model(config, backbone)
|
|
117
|
+
backbone.sysone_lora_config = config
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@contextlib.contextmanager
|
|
121
|
+
def _ignore_incompatible_torchao():
|
|
122
|
+
"""peft refuses to add any adapter when an older torchao is installed (Google Colab ships one),
|
|
123
|
+
although sysone never uses torchao. In that case, tell peft torchao isn't available while
|
|
124
|
+
adapters are added, instead of asking the user to uninstall it."""
|
|
125
|
+
from peft import import_utils
|
|
126
|
+
|
|
127
|
+
if not hasattr(import_utils, "is_torchao_available"): # older peft: no such check
|
|
128
|
+
yield
|
|
129
|
+
return
|
|
130
|
+
try:
|
|
131
|
+
import_utils.is_torchao_available()
|
|
132
|
+
problem = None
|
|
133
|
+
except ImportError as exc:
|
|
134
|
+
problem = exc
|
|
135
|
+
if problem is None:
|
|
136
|
+
yield
|
|
137
|
+
return
|
|
138
|
+
warnings.warn("ignoring the installed torchao (%s); sysone doesn't use it" % problem, UserWarning, stacklevel=4)
|
|
139
|
+
original = import_utils.is_torchao_available
|
|
140
|
+
holders = [m for name, m in list(sys.modules.items())
|
|
141
|
+
if name.startswith("peft") and getattr(m, "is_torchao_available", None) is original]
|
|
142
|
+
for module in holders:
|
|
143
|
+
module.is_torchao_available = _torchao_unavailable
|
|
144
|
+
try:
|
|
145
|
+
yield
|
|
146
|
+
finally:
|
|
147
|
+
for module in holders:
|
|
148
|
+
module.is_torchao_available = original
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _torchao_unavailable() -> bool:
|
|
152
|
+
return False
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def is_adapter(name: str) -> bool:
|
|
156
|
+
return bool(_ADAPTER_NAME.search(name))
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def trained_parameters(arch: Architecture, backbone: nn.Module, plan: LayerPlan) -> dict[str, list]:
|
|
160
|
+
"""`{"adapter": [(name, param)], "full": [(name, param)]}`: the backbone weights that train,
|
|
161
|
+
in a fixed order. "full" holds fully trained layers and embeddings."""
|
|
162
|
+
layers = arch.layers(backbone)
|
|
163
|
+
full = {id(p) for i in plan.full_range for p in layers[i].parameters()}
|
|
164
|
+
if plan.train_embeddings:
|
|
165
|
+
full |= {id(p) for p in arch.embeddings(backbone).parameters()}
|
|
166
|
+
groups: dict[str, list] = {"adapter": [], "full": []}
|
|
167
|
+
for name, p in backbone.named_parameters():
|
|
168
|
+
if is_adapter(name):
|
|
169
|
+
groups["adapter"].append((name, p))
|
|
170
|
+
elif id(p) in full:
|
|
171
|
+
groups["full"].append((name, p))
|
|
172
|
+
return groups
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def round_trained(groups: dict[str, list], dtype: torch.dtype) -> None:
|
|
176
|
+
"""Store fully trained layers in the backbone's precision once training ends, as they are saved,
|
|
177
|
+
so a model predicts the same before and after `save` / `load`. Adapters stay in fp32."""
|
|
178
|
+
for _, p in groups.get("full", []):
|
|
179
|
+
p.requires_grad_(False)
|
|
180
|
+
p.data = p.data.to(dtype)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def set_trainable(arch: Architecture, backbone: nn.Module, plan: LayerPlan) -> dict[str, list]:
|
|
184
|
+
"""Freeze everything except the planned weights, which are kept in fp32 for the optimizer."""
|
|
185
|
+
backbone.requires_grad_(False)
|
|
186
|
+
groups = trained_parameters(arch, backbone, plan)
|
|
187
|
+
for _, p in groups["adapter"] + groups["full"]:
|
|
188
|
+
if p.dtype != torch.float32:
|
|
189
|
+
p.data = p.data.float()
|
|
190
|
+
p.requires_grad_(True)
|
|
191
|
+
return groups
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def wants_checkpointing(setting, plan: LayerPlan, backbone: nn.Module, seq_len: int, micro_batch: int) -> bool:
|
|
195
|
+
"""Whether to turn on gradient checkpointing.
|
|
196
|
+
|
|
197
|
+
"auto" turns it on when the activations kept for the backward pass would take more memory
|
|
198
|
+
than the backbone's weights: about `34·s·h + 5·a·s²` bytes per example and layer in half
|
|
199
|
+
precision, for the layers gradients flow through.
|
|
200
|
+
"""
|
|
201
|
+
if setting != "auto":
|
|
202
|
+
return bool(setting)
|
|
203
|
+
if not plan.learns:
|
|
204
|
+
return False
|
|
205
|
+
config = backbone.config
|
|
206
|
+
layers = plan.n_layers - plan.lowest_trained
|
|
207
|
+
per_layer = 34 * seq_len * config.hidden_size + 5 * config.num_attention_heads * seq_len * seq_len
|
|
208
|
+
activations = micro_batch * layers * per_layer
|
|
209
|
+
weights = sum(p.numel() * p.element_size() for p in backbone.parameters())
|
|
210
|
+
return activations > weights
|
sysone/version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.0"
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sysone
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Fine-tune and calibrate system-one decision models with a scikit-learn style fit / predict interface.
|
|
5
|
+
Project-URL: Homepage, https://github.com/ForwardMetric/sysone
|
|
6
|
+
Project-URL: Repository, https://github.com/ForwardMetric/sysone
|
|
7
|
+
Project-URL: Issues, https://github.com/ForwardMetric/sysone/issues
|
|
8
|
+
Project-URL: Design, https://github.com/ForwardMetric/sysone/blob/main/docs/DESIGN.md
|
|
9
|
+
Author: Goutham Balaraman
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: calibration,classification,decision models,fine-tuning,lora,modernbert,qlora,qwen,transformers
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Requires-Dist: bitsandbytes>=0.45; sys_platform == 'linux' or sys_platform == 'win32'
|
|
27
|
+
Requires-Dist: huggingface-hub>=0.25
|
|
28
|
+
Requires-Dist: numpy>=1.26
|
|
29
|
+
Requires-Dist: peft>=0.13
|
|
30
|
+
Requires-Dist: safetensors>=0.4
|
|
31
|
+
Requires-Dist: torch>=2.4
|
|
32
|
+
Requires-Dist: transformers>=5.0
|
|
33
|
+
Provides-Extra: pandas
|
|
34
|
+
Requires-Dist: pandas>=2.0; extra == 'pandas'
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# sysone
|
|
38
|
+
|
|
39
|
+
Fine-tune and calibrate "system one" decision models: small transformers that answer typed
|
|
40
|
+
questions (choice, score, yes/no) about a piece of text in a single forward pass. You pick a base
|
|
41
|
+
model, call `fit` on labelled rows and `predict` on new ones. sysone handles tokenization,
|
|
42
|
+
position ids, attention masks, layer freezing, the decision head and the training loop.
|
|
43
|
+
|
|
44
|
+
Supported base models: **ModernBERT** (`EncoderModel`) and **Qwen3** (`DecoderModel`). Others can
|
|
45
|
+
be added by writing one architecture class.
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install sysone
|
|
51
|
+
pip install "sysone[pandas]" # also installs pandas, for the comparison tables of `compare`
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
On Linux and Windows this also installs bitsandbytes, for 4-bit training (`tuning="qlora"`).
|
|
55
|
+
|
|
56
|
+
## Quickstart
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from sysone import DecoderModel
|
|
60
|
+
|
|
61
|
+
questions = {
|
|
62
|
+
"team": {"type": "choice", "instructions": "Which team should handle it?",
|
|
63
|
+
"criteria": ["sales", "operations", "servicing"]},
|
|
64
|
+
"severity": {"type": "score", "instructions": "How severe is it?",
|
|
65
|
+
"criteria": ["none", "minor", "major", "critical"]},
|
|
66
|
+
"refund": {"type": "noul", "instructions": "Is the customer asking for a refund?"},
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
rows = [
|
|
70
|
+
{"state": "Hi, my order is stuck in the warehouse and our line is down.",
|
|
71
|
+
"category": "operations",
|
|
72
|
+
"questions": questions,
|
|
73
|
+
"expected": {"team": "operations", "severity": 3, "refund": False}},
|
|
74
|
+
# ... more rows; rows may mix different question sets
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
model = DecoderModel(tuning="head").fit(rows)
|
|
78
|
+
|
|
79
|
+
model.predict("I'd like my money back for the broken unit.", questions)
|
|
80
|
+
# {"answers": {"team": {"type": "choice", "choice": "servicing", "probabilities": {...}, "confidence": ...},
|
|
81
|
+
# "severity": {"type": "score", "score": 1.2, "legend": {...}, ...},
|
|
82
|
+
# "refund": {"type": "noul", "noul": 0.97, ...}},
|
|
83
|
+
# "usage": {"input_tokens": 118, "output_tokens": 0}}
|
|
84
|
+
|
|
85
|
+
model.save("my-model")
|
|
86
|
+
model = DecoderModel.load("my-model")
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
To measure the model on held-out labelled rows, and compare it with simple baselines:
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from sysone import baselines, compare
|
|
93
|
+
|
|
94
|
+
results = baselines(test_rows, train=rows) # random guess, average answer
|
|
95
|
+
results["trained"] = model.evaluate(test_rows)
|
|
96
|
+
compare(results) # accuracy per question type, as a table
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Answers follow the Jev `/v1/systemone` response shape. Training data can be records like the
|
|
100
|
+
above, records plus a shared question catalog, a long DataFrame, or a `.jsonl` / `.csv` /
|
|
101
|
+
`.parquet` file. Labels go in `expected`, in a `label` inside each question, or as soft `gold`
|
|
102
|
+
probabilities.
|
|
103
|
+
|
|
104
|
+
Example notebooks, each comparing accuracy before and after training:
|
|
105
|
+
|
|
106
|
+
- [quickstart.ipynb](https://github.com/ForwardMetric/sysone/blob/main/examples/quickstart.ipynb): synthetic support tickets, a few minutes;
|
|
107
|
+
- bev-decision-150K, 18 domains, hard labels:
|
|
108
|
+
[decoder_bev_decision.ipynb](https://github.com/ForwardMetric/sysone/blob/main/examples/decoder_bev_decision.ipynb) (Qwen3) and
|
|
109
|
+
[encoder_bev_decision.ipynb](https://github.com/ForwardMetric/sysone/blob/main/examples/encoder_bev_decision.ipynb) (ModernBERT);
|
|
110
|
+
- typed-decisions, soft labels from several raters:
|
|
111
|
+
[decoder_typed_decisions.ipynb](https://github.com/ForwardMetric/sysone/blob/main/examples/decoder_typed_decisions.ipynb) (Qwen3) and
|
|
112
|
+
[encoder_typed_decisions.ipynb](https://github.com/ForwardMetric/sysone/blob/main/examples/encoder_typed_decisions.ipynb) (ModernBERT).
|
|
113
|
+
|
|
114
|
+
Notebooks other than the quickstart are named `<model type>_<dataset>.ipynb`.
|
|
115
|
+
|
|
116
|
+
## Status
|
|
117
|
+
|
|
118
|
+
This is an early version (0.2). Training covers every `tuning` mode:
|
|
119
|
+
|
|
120
|
+
- `"head"`: the backbone is frozen, its outputs are computed once and cached (in memory, and on
|
|
121
|
+
disk with `cache_dir`), and only the decision head trains;
|
|
122
|
+
- `"lora"`, `"qlora"` and `"full"`: adapters or whole layers of the backbone train along with the
|
|
123
|
+
head. These run on a laptop GPU (Apple MPS) for small datasets; a CUDA GPU is recommended for
|
|
124
|
+
full-size runs. `"qlora"` needs bitsandbytes and an NVIDIA GPU and falls back to `"lora"`
|
|
125
|
+
elsewhere, with a warning. It has trained in real 4-bit on a Colab GPU.
|
|
126
|
+
|
|
127
|
+
`DecoderModel` (Qwen3) defaults to `"qlora"`. `EncoderModel` (ModernBERT) defaults to `"full"`:
|
|
128
|
+
adapters barely moved ModernBERT, while full tuning reached 0.79 test accuracy on typed-decisions.
|
|
129
|
+
|
|
130
|
+
Training stops at `epochs`, by early stopping, or at `target_loss`. A run that is interrupted
|
|
131
|
+
(Ctrl-C), or saved and loaded, resumes exactly where it stopped. Calibration and `head="full"` are
|
|
132
|
+
designed but not yet implemented.
|
|
133
|
+
|
|
134
|
+
See [docs/DESIGN.md](https://github.com/ForwardMetric/sysone/blob/main/docs/DESIGN.md) for the full design: every parameter, the layouts,
|
|
135
|
+
architectures, heads, training and checkpoint format.
|
|
136
|
+
|
|
137
|
+
## Development
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
uv sync # or: pip install -e . with the dev dependencies
|
|
141
|
+
uv run pytest # fast tests on tiny random-weight models, no downloads
|
|
142
|
+
uv run pytest -m slow # end-to-end tests on the real base models (~1.8 GB download)
|
|
143
|
+
uv run ruff check src tests
|
|
144
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
sysone/__init__.py,sha256=dSv6QpRXTyVFbHBtjbO9FBqerurg_df3OA0QkDPNyNA,623
|
|
2
|
+
sysone/_util.py,sha256=7kB_8dq4GKr-3LDMr4vWdGw6oCewf0nfqraJLCXSLTU,3595
|
|
3
|
+
sysone/answers.py,sha256=LuqmHerUsD-7fTiHQd_rZMCU24_O-IoOZUmLcj8w8sk,2023
|
|
4
|
+
sysone/base.py,sha256=RTrLLwHysrCuhJiCzPlp0QQoI4aMc_SBMXKbxN9prNM,44033
|
|
5
|
+
sysone/cache.py,sha256=Pxo74YQ6in55aJg6ejcdFVArLIJ9wGHJTexOo04TrCs,7947
|
|
6
|
+
sysone/checkpoint.py,sha256=_Sv13u4-pWDpdOJu1s6SHDKprQBqHXZNQWzL5BCjEF4,3897
|
|
7
|
+
sysone/data.py,sha256=mGuUfOkCdbmJqalunaiR3xM1CkcNOMO_1kH-zOPIB5c,8002
|
|
8
|
+
sysone/encoding.py,sha256=OALfxVoDqiwnXfg0Sjgaf6dqRwAsYDn3ZoMOL-Ti7fc,3628
|
|
9
|
+
sysone/evaluation.py,sha256=hICp7VzkRmNT_FW04nnV-fy7Or-rhz_nsMY9FWGWR60,7718
|
|
10
|
+
sysone/features.py,sha256=kgod_IvBxRCkwkY0RIbk8BYMH56qEsuO05OfTcO44Fs,4024
|
|
11
|
+
sysone/heads.py,sha256=FeTWnYvKiQO1bdm3ZAyCxJAZHiWl0bgX2LgVcXC9Tcg,3070
|
|
12
|
+
sysone/layout.py,sha256=tDW40SYMSGpT4JbsXqrGEV7xwxsppQBlGnNd_QsQKyo,5473
|
|
13
|
+
sysone/losses.py,sha256=58gubFLKxZN8S0hM5xyFu3DY50Jup7dKFvlvufVAmQQ,626
|
|
14
|
+
sysone/models.py,sha256=OmA25u1iLNPxKx4EOHUX6JsMeH4weXopOIIsXWat62A,961
|
|
15
|
+
sysone/prompts.py,sha256=0UjA-QpVqePrh1zuvbqlvTkW1P9ZuzA7cFo5NuyZG5I,2190
|
|
16
|
+
sysone/questions.py,sha256=HfgRQCiALD_hG0YMjb39Ic0Cbc5BDeLROLejusK-iQw,8252
|
|
17
|
+
sysone/training.py,sha256=w59lLbjGzKlQ38EyhLYgdv8eNEnbetgSdVdZdBYB144,18043
|
|
18
|
+
sysone/tuning.py,sha256=dZApkJG1SVazXNCDkl0heo_73qDgEaFG0aIS8jq1ezc,8457
|
|
19
|
+
sysone/version.py,sha256=Zn1KFblwuFHiDRdRAiRnDBRkbPttWh44jKa5zG2ov0E,22
|
|
20
|
+
sysone/architectures/__init__.py,sha256=WwbBxetVcw9lsFsvGPHkomTOaS30e2JGp2HUE11mIKQ,317
|
|
21
|
+
sysone/architectures/base.py,sha256=dzMKKb8ALf5ghp8dYCGdGNXkN5Jk6V556tknwV_yEes,7359
|
|
22
|
+
sysone/architectures/modernbert.py,sha256=AoQbZxRjQ2eChR8rlZ6tjVa8_MYApwJhPi6BM-6bSJk,1708
|
|
23
|
+
sysone/architectures/qwen.py,sha256=--tfHT140dQXEmvKBm6ek9gAaoMM15dK0_kjX6zUHMM,1924
|
|
24
|
+
sysone/architectures/registry.py,sha256=7W_hr-hHX3JRKhEBsZLdVh836_C7FqHCm_CXoXre6HI,2044
|
|
25
|
+
sysone-0.2.0.dist-info/METADATA,sha256=P6urB5koPoo7uEGvxVcPnekBjXGOKOzKlgTFzAAdgGg,6714
|
|
26
|
+
sysone-0.2.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
27
|
+
sysone-0.2.0.dist-info/licenses/LICENSE,sha256=vc1flUELWk-ba73Rv_DNFquov4HjzJGku7jzHqSBRiI,1074
|
|
28
|
+
sysone-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Goutham Balaraman
|
|
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.
|