tensorless 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tensorless-0.1.0/LICENSE +21 -0
- tensorless-0.1.0/MANIFEST.in +5 -0
- tensorless-0.1.0/PKG-INFO +111 -0
- tensorless-0.1.0/README.md +97 -0
- tensorless-0.1.0/docs/api_reference.md +103 -0
- tensorless-0.1.0/docs/architecture.md +125 -0
- tensorless-0.1.0/docs/automatic_mode.md +100 -0
- tensorless-0.1.0/docs/checkpointing.md +76 -0
- tensorless-0.1.0/docs/cli.md +87 -0
- tensorless-0.1.0/docs/configuration.md +93 -0
- tensorless-0.1.0/docs/contributing.md +80 -0
- tensorless-0.1.0/docs/examples.md +112 -0
- tensorless-0.1.0/docs/inference.md +104 -0
- tensorless-0.1.0/docs/installation.md +63 -0
- tensorless-0.1.0/docs/limitations.md +74 -0
- tensorless-0.1.0/docs/quickstart.md +96 -0
- tensorless-0.1.0/docs/roadmap.md +49 -0
- tensorless-0.1.0/docs/tl_format.md +84 -0
- tensorless-0.1.0/docs/training.md +105 -0
- tensorless-0.1.0/docs/troubleshooting.md +98 -0
- tensorless-0.1.0/docs/tutorial.md +161 -0
- tensorless-0.1.0/examples/tabular_classification_example.py +50 -0
- tensorless-0.1.0/examples/tabular_regression_example.py +49 -0
- tensorless-0.1.0/examples/text_classification_example.py +53 -0
- tensorless-0.1.0/examples/text_generation_example.py +48 -0
- tensorless-0.1.0/pyproject.toml +24 -0
- tensorless-0.1.0/setup.cfg +4 -0
- tensorless-0.1.0/tensorless/__init__.py +40 -0
- tensorless-0.1.0/tensorless/_version.py +6 -0
- tensorless-0.1.0/tensorless/api.py +230 -0
- tensorless-0.1.0/tensorless/auto/__init__.py +4 -0
- tensorless-0.1.0/tensorless/auto/config.py +113 -0
- tensorless-0.1.0/tensorless/auto/detector.py +95 -0
- tensorless-0.1.0/tensorless/checkpoint/__init__.py +3 -0
- tensorless-0.1.0/tensorless/checkpoint/manager.py +66 -0
- tensorless-0.1.0/tensorless/cli/__init__.py +3 -0
- tensorless-0.1.0/tensorless/cli/main.py +121 -0
- tensorless-0.1.0/tensorless/config.py +121 -0
- tensorless-0.1.0/tensorless/data/__init__.py +11 -0
- tensorless-0.1.0/tensorless/data/fingerprint.py +71 -0
- tensorless-0.1.0/tensorless/data/inspector.py +161 -0
- tensorless-0.1.0/tensorless/data/loader.py +255 -0
- tensorless-0.1.0/tensorless/data/tabular.py +179 -0
- tensorless-0.1.0/tensorless/devices/__init__.py +3 -0
- tensorless-0.1.0/tensorless/devices/device.py +107 -0
- tensorless-0.1.0/tensorless/errors.py +36 -0
- tensorless-0.1.0/tensorless/models/__init__.py +5 -0
- tensorless-0.1.0/tensorless/models/mlp.py +64 -0
- tensorless-0.1.0/tensorless/models/registry.py +53 -0
- tensorless-0.1.0/tensorless/models/transformer.py +175 -0
- tensorless-0.1.0/tensorless/runtime.py +158 -0
- tensorless-0.1.0/tensorless/serialization/__init__.py +3 -0
- tensorless-0.1.0/tensorless/serialization/tl_format.py +89 -0
- tensorless-0.1.0/tensorless/tokenization/__init__.py +3 -0
- tensorless-0.1.0/tensorless/tokenization/char_tokenizer.py +84 -0
- tensorless-0.1.0/tensorless/training/__init__.py +4 -0
- tensorless-0.1.0/tensorless/training/data_prep.py +215 -0
- tensorless-0.1.0/tensorless/training/early_stopping.py +31 -0
- tensorless-0.1.0/tensorless/training/trainer.py +234 -0
- tensorless-0.1.0/tensorless.egg-info/PKG-INFO +111 -0
- tensorless-0.1.0/tensorless.egg-info/SOURCES.txt +73 -0
- tensorless-0.1.0/tensorless.egg-info/dependency_links.txt +1 -0
- tensorless-0.1.0/tensorless.egg-info/entry_points.txt +2 -0
- tensorless-0.1.0/tensorless.egg-info/requires.txt +4 -0
- tensorless-0.1.0/tensorless.egg-info/top_level.txt +1 -0
- tensorless-0.1.0/tests/test_auto_detection.py +22 -0
- tensorless-0.1.0/tests/test_checkpoint_resume.py +62 -0
- tensorless-0.1.0/tests/test_cli.py +37 -0
- tensorless-0.1.0/tests/test_data_loading.py +76 -0
- tensorless-0.1.0/tests/test_end_to_end.py +50 -0
- tensorless-0.1.0/tests/test_fingerprint.py +40 -0
- tensorless-0.1.0/tests/test_serialization.py +49 -0
- tensorless-0.1.0/tests/test_train_tabular.py +46 -0
- tensorless-0.1.0/tests/test_train_text_classification.py +34 -0
- tensorless-0.1.0/tests/test_train_text_generation.py +78 -0
tensorless-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tensorless Contributors
|
|
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.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tensorless
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ML with maximum automation and minimum setup.
|
|
5
|
+
Author: Tensorless Contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: torch>=2.0
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# Tensorless
|
|
16
|
+
|
|
17
|
+
**ML with maximum automation and minimum setup.**
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
import tensorless as tl
|
|
21
|
+
|
|
22
|
+
tl.train("./data")
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
That's it. Tensorless inspects your dataset, figures out what kind of
|
|
26
|
+
task you're trying to solve, builds and configures a model, trains it,
|
|
27
|
+
validates it, checkpoints it, and saves a single portable `model.tl`
|
|
28
|
+
file you can move anywhere.
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
model = tl.run("model.tl") # interactive chat, if it's a text model
|
|
32
|
+
# or
|
|
33
|
+
model = tl.load("model.tl")
|
|
34
|
+
model.predict(...)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Simple by default. Powerful when you need it:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
tl.train(
|
|
41
|
+
"./data",
|
|
42
|
+
d_model=512,
|
|
43
|
+
layers=6,
|
|
44
|
+
learning_rate=3e-4,
|
|
45
|
+
batch_size=32,
|
|
46
|
+
)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Why Tensorless
|
|
50
|
+
|
|
51
|
+
Most ML frameworks assume you already know what model you want, how big
|
|
52
|
+
it should be, which optimizer and learning rate to use, and how to wire
|
|
53
|
+
up checkpointing and resumption yourself. Tensorless flips that: it
|
|
54
|
+
makes a reasonable, working choice for all of that automatically, and
|
|
55
|
+
lets you override exactly the parts you care about.
|
|
56
|
+
|
|
57
|
+
It also remembers what it already did. Run `tl.train("./data")` twice on
|
|
58
|
+
the same dataset and it won't retrain — it'll just hand you back the
|
|
59
|
+
model it already trained. Change the data, and it retrains. Get
|
|
60
|
+
interrupted partway through a long run, and the next call resumes right
|
|
61
|
+
where it left off. This is the **Smart Auto Check**, and it's the core
|
|
62
|
+
idea the whole framework is built around.
|
|
63
|
+
|
|
64
|
+
## Install
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install -e .
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
See [docs/installation.md](docs/installation.md) for details and
|
|
71
|
+
requirements.
|
|
72
|
+
|
|
73
|
+
## Documentation
|
|
74
|
+
|
|
75
|
+
| Doc | What's in it |
|
|
76
|
+
|---|---|
|
|
77
|
+
| [Installation](docs/installation.md) | Requirements, install steps, verifying your setup |
|
|
78
|
+
| [Quick Start](docs/quickstart.md) | The fastest path to a trained model |
|
|
79
|
+
| [Beginner Tutorial](docs/tutorial.md) | A guided, from-scratch walkthrough |
|
|
80
|
+
| [Automatic Mode](docs/automatic_mode.md) | How auto-detection and auto-configuration work, and the Smart Auto Check |
|
|
81
|
+
| [Training](docs/training.md) | `tl.train()` in depth, all supported tasks and data formats |
|
|
82
|
+
| [Inference](docs/inference.md) | `tl.run()`, `tl.load()`, and the prediction API |
|
|
83
|
+
| [Checkpointing & Resume](docs/checkpointing.md) | How checkpoints work and how resumption is decided |
|
|
84
|
+
| [The `.tl` Format](docs/tl_format.md) | What's inside a `.tl` file and why it's portable |
|
|
85
|
+
| [Configuration](docs/configuration.md) | Every override you can pass, and what it does |
|
|
86
|
+
| [CLI](docs/cli.md) | `tensorless train / run / inspect / info` |
|
|
87
|
+
| [API Reference](docs/api_reference.md) | Full function/class signatures |
|
|
88
|
+
| [Examples](docs/examples.md) | Worked examples for each supported task |
|
|
89
|
+
| [Troubleshooting](docs/troubleshooting.md) | Common errors and what to do about them |
|
|
90
|
+
| [Architecture](docs/architecture.md) | How the codebase is organized, for contributors |
|
|
91
|
+
| [Contributing](docs/contributing.md) | How to add models, backends, or data formats |
|
|
92
|
+
| [Roadmap](docs/roadmap.md) | What's planned |
|
|
93
|
+
| [Limitations](docs/limitations.md) | What Tensorless deliberately doesn't do (yet) |
|
|
94
|
+
|
|
95
|
+
## Supported today
|
|
96
|
+
|
|
97
|
+
- **Text generation** (language modeling) from `.txt`/`.md` files or JSON/JSONL with a `text` field
|
|
98
|
+
- **Text classification** from a directory of class subfolders (`positive/`, `negative/`, ...) or labeled JSON/JSONL
|
|
99
|
+
- **Tabular classification and regression** from CSV/TSV/JSON/JSONL with a target column
|
|
100
|
+
|
|
101
|
+
## Project status
|
|
102
|
+
|
|
103
|
+
Tensorless is an early-stage, actively developed framework. The core
|
|
104
|
+
loop — inspect, auto-configure, train, checkpoint, save, reload, infer —
|
|
105
|
+
is real and tested end-to-end (see [tests/](tests/)). See
|
|
106
|
+
[docs/limitations.md](docs/limitations.md) for what's intentionally out
|
|
107
|
+
of scope right now, and [docs/roadmap.md](docs/roadmap.md) for what's next.
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Tensorless
|
|
2
|
+
|
|
3
|
+
**ML with maximum automation and minimum setup.**
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
import tensorless as tl
|
|
7
|
+
|
|
8
|
+
tl.train("./data")
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
That's it. Tensorless inspects your dataset, figures out what kind of
|
|
12
|
+
task you're trying to solve, builds and configures a model, trains it,
|
|
13
|
+
validates it, checkpoints it, and saves a single portable `model.tl`
|
|
14
|
+
file you can move anywhere.
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
model = tl.run("model.tl") # interactive chat, if it's a text model
|
|
18
|
+
# or
|
|
19
|
+
model = tl.load("model.tl")
|
|
20
|
+
model.predict(...)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Simple by default. Powerful when you need it:
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
tl.train(
|
|
27
|
+
"./data",
|
|
28
|
+
d_model=512,
|
|
29
|
+
layers=6,
|
|
30
|
+
learning_rate=3e-4,
|
|
31
|
+
batch_size=32,
|
|
32
|
+
)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Why Tensorless
|
|
36
|
+
|
|
37
|
+
Most ML frameworks assume you already know what model you want, how big
|
|
38
|
+
it should be, which optimizer and learning rate to use, and how to wire
|
|
39
|
+
up checkpointing and resumption yourself. Tensorless flips that: it
|
|
40
|
+
makes a reasonable, working choice for all of that automatically, and
|
|
41
|
+
lets you override exactly the parts you care about.
|
|
42
|
+
|
|
43
|
+
It also remembers what it already did. Run `tl.train("./data")` twice on
|
|
44
|
+
the same dataset and it won't retrain — it'll just hand you back the
|
|
45
|
+
model it already trained. Change the data, and it retrains. Get
|
|
46
|
+
interrupted partway through a long run, and the next call resumes right
|
|
47
|
+
where it left off. This is the **Smart Auto Check**, and it's the core
|
|
48
|
+
idea the whole framework is built around.
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install -e .
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
See [docs/installation.md](docs/installation.md) for details and
|
|
57
|
+
requirements.
|
|
58
|
+
|
|
59
|
+
## Documentation
|
|
60
|
+
|
|
61
|
+
| Doc | What's in it |
|
|
62
|
+
|---|---|
|
|
63
|
+
| [Installation](docs/installation.md) | Requirements, install steps, verifying your setup |
|
|
64
|
+
| [Quick Start](docs/quickstart.md) | The fastest path to a trained model |
|
|
65
|
+
| [Beginner Tutorial](docs/tutorial.md) | A guided, from-scratch walkthrough |
|
|
66
|
+
| [Automatic Mode](docs/automatic_mode.md) | How auto-detection and auto-configuration work, and the Smart Auto Check |
|
|
67
|
+
| [Training](docs/training.md) | `tl.train()` in depth, all supported tasks and data formats |
|
|
68
|
+
| [Inference](docs/inference.md) | `tl.run()`, `tl.load()`, and the prediction API |
|
|
69
|
+
| [Checkpointing & Resume](docs/checkpointing.md) | How checkpoints work and how resumption is decided |
|
|
70
|
+
| [The `.tl` Format](docs/tl_format.md) | What's inside a `.tl` file and why it's portable |
|
|
71
|
+
| [Configuration](docs/configuration.md) | Every override you can pass, and what it does |
|
|
72
|
+
| [CLI](docs/cli.md) | `tensorless train / run / inspect / info` |
|
|
73
|
+
| [API Reference](docs/api_reference.md) | Full function/class signatures |
|
|
74
|
+
| [Examples](docs/examples.md) | Worked examples for each supported task |
|
|
75
|
+
| [Troubleshooting](docs/troubleshooting.md) | Common errors and what to do about them |
|
|
76
|
+
| [Architecture](docs/architecture.md) | How the codebase is organized, for contributors |
|
|
77
|
+
| [Contributing](docs/contributing.md) | How to add models, backends, or data formats |
|
|
78
|
+
| [Roadmap](docs/roadmap.md) | What's planned |
|
|
79
|
+
| [Limitations](docs/limitations.md) | What Tensorless deliberately doesn't do (yet) |
|
|
80
|
+
|
|
81
|
+
## Supported today
|
|
82
|
+
|
|
83
|
+
- **Text generation** (language modeling) from `.txt`/`.md` files or JSON/JSONL with a `text` field
|
|
84
|
+
- **Text classification** from a directory of class subfolders (`positive/`, `negative/`, ...) or labeled JSON/JSONL
|
|
85
|
+
- **Tabular classification and regression** from CSV/TSV/JSON/JSONL with a target column
|
|
86
|
+
|
|
87
|
+
## Project status
|
|
88
|
+
|
|
89
|
+
Tensorless is an early-stage, actively developed framework. The core
|
|
90
|
+
loop — inspect, auto-configure, train, checkpoint, save, reload, infer —
|
|
91
|
+
is real and tested end-to-end (see [tests/](tests/)). See
|
|
92
|
+
[docs/limitations.md](docs/limitations.md) for what's intentionally out
|
|
93
|
+
of scope right now, and [docs/roadmap.md](docs/roadmap.md) for what's next.
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
MIT
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## `tensorless.train(path, **kwargs) -> LoadedModel`
|
|
4
|
+
|
|
5
|
+
Train a model on the dataset at `path`. See
|
|
6
|
+
[configuration.md](configuration.md) for every valid keyword argument.
|
|
7
|
+
Implements the Smart Auto Check (see [automatic_mode.md](automatic_mode.md)).
|
|
8
|
+
|
|
9
|
+
Raises:
|
|
10
|
+
- `tensorless.DataError` — dataset missing, empty, malformed, or unsupported format
|
|
11
|
+
- `tensorless.ConfigError` — invalid/unknown config argument, or dataset changed with `ask_on_data_change=True`
|
|
12
|
+
- `tensorless.CheckpointError` — an existing checkpoint is corrupt or unreadable
|
|
13
|
+
- `tensorless.SerializationError` — an existing `.tl` file is corrupt
|
|
14
|
+
|
|
15
|
+
## `tensorless.inspect(path) -> InspectionReport`
|
|
16
|
+
|
|
17
|
+
Load and analyze a dataset without training. Prints a human-readable
|
|
18
|
+
report and returns a structured object.
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
@dataclass
|
|
22
|
+
class InspectionReport:
|
|
23
|
+
path: str
|
|
24
|
+
fingerprint: str
|
|
25
|
+
kind: str # "text" | "text_labeled" | "tabular"
|
|
26
|
+
task: str # "text-generation" | "text-classification" | "classification" | "regression"
|
|
27
|
+
n_examples: int
|
|
28
|
+
n_files: int
|
|
29
|
+
columns: List[str]
|
|
30
|
+
sample: Any
|
|
31
|
+
warnings: List[str]
|
|
32
|
+
recommendations: List[str]
|
|
33
|
+
stats: Dict[str, Any]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## `tensorless.load(path, device=None) -> LoadedModel`
|
|
37
|
+
|
|
38
|
+
Load a trained `.tl` file for inference. `device` overrides the device
|
|
39
|
+
recorded at training time (e.g. load a GPU-trained model on a CPU-only
|
|
40
|
+
machine with `device="cpu"`).
|
|
41
|
+
|
|
42
|
+
Raises `tensorless.SerializationError` if the file is missing, corrupt,
|
|
43
|
+
or from an unsupported future format version.
|
|
44
|
+
|
|
45
|
+
## `tensorless.run(path, prompt=None) -> Any`
|
|
46
|
+
|
|
47
|
+
Convenience wrapper around `load()` for quick command-line-style usage.
|
|
48
|
+
See [inference.md](inference.md#tlrun--the-cli-friendly-shortcut).
|
|
49
|
+
|
|
50
|
+
## `class tensorless.runtime.LoadedModel`
|
|
51
|
+
|
|
52
|
+
Returned by both `train()` and `load()`.
|
|
53
|
+
|
|
54
|
+
| Method | Applies to | Description |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `.generate(prompt="", max_new_tokens=200, temperature=0.8, top_k=40)` | `text-generation` | Generate a text continuation |
|
|
57
|
+
| `.chat()` | `text-generation` | Interactive terminal chat loop |
|
|
58
|
+
| `.predict(x)` | all tasks | Unified prediction API; `x` is a string (text tasks) or dict/list-of-dicts (tabular tasks) |
|
|
59
|
+
| `.info()` | all | Dict summary: task, model type, versions, config, metrics, param count |
|
|
60
|
+
|
|
61
|
+
Attributes: `.task`, `.model_type`, `.config`, `.meta`, `.metrics`,
|
|
62
|
+
`.dataset_fingerprint`, `.model` (the underlying `torch.nn.Module`),
|
|
63
|
+
`.tokenizer` (`CharTokenizer` or `None`), `.preprocessor`
|
|
64
|
+
(`TabularPreprocessor` or `None`).
|
|
65
|
+
|
|
66
|
+
## `class tensorless.TrainConfig`
|
|
67
|
+
|
|
68
|
+
The dataclass of every trainable override; see
|
|
69
|
+
[configuration.md](configuration.md) for field-by-field defaults.
|
|
70
|
+
|
|
71
|
+
## Errors — `tensorless.errors`
|
|
72
|
+
|
|
73
|
+
All Tensorless exceptions inherit from `TensorlessError`:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
try:
|
|
77
|
+
tl.train("./data")
|
|
78
|
+
except tl.TensorlessError as e:
|
|
79
|
+
...
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
| Class | Raised when |
|
|
83
|
+
|---|---|
|
|
84
|
+
| `DataError` | Dataset can't be read, is empty, or is malformed |
|
|
85
|
+
| `ConfigError` | Invalid/unknown configuration, or a Smart-Auto-Check conflict |
|
|
86
|
+
| `ModelError` | Unsupported task/model combination, or a runtime prediction-API misuse |
|
|
87
|
+
| `CheckpointError` | Checkpoint missing, corrupt, or incompatible |
|
|
88
|
+
| `SerializationError` | `.tl` file can't be written or read |
|
|
89
|
+
|
|
90
|
+
## Lower-level modules
|
|
91
|
+
|
|
92
|
+
These aren't part of the stable public API but are documented here for
|
|
93
|
+
contributors — see [architecture.md](architecture.md) for how they fit
|
|
94
|
+
together:
|
|
95
|
+
|
|
96
|
+
- `tensorless.data.loader.load_dataset(path) -> Dataset`
|
|
97
|
+
- `tensorless.data.fingerprint.fingerprint_path(path) -> str`
|
|
98
|
+
- `tensorless.auto.detector.detect_task(ds) -> str`
|
|
99
|
+
- `tensorless.auto.config.resolve_config(ds, TrainConfig) -> ResolvedConfig`
|
|
100
|
+
- `tensorless.models.registry.build_model(task, model_type, cfg, meta) -> nn.Module`
|
|
101
|
+
- `tensorless.training.trainer.run_training(...) -> dict`
|
|
102
|
+
- `tensorless.checkpoint.manager.CheckpointManager`
|
|
103
|
+
- `tensorless.serialization.tl_format.save_tl(path, payload)` / `load_tl(path) -> dict`
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This page is for people extending or contributing to Tensorless, not
|
|
4
|
+
end users.
|
|
5
|
+
|
|
6
|
+
## Package layout
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
tensorless/
|
|
10
|
+
├── __init__.py public API surface: train, run, load, inspect
|
|
11
|
+
├── api.py orchestration for train()/run(): Smart Auto Check + wiring
|
|
12
|
+
├── config.py TrainConfig (user-facing) / ResolvedConfig (fully resolved)
|
|
13
|
+
├── errors.py exception hierarchy
|
|
14
|
+
├── runtime.py LoadedModel: rebuilds a model from a .tl payload for inference
|
|
15
|
+
├── _version.py package + .tl format version numbers
|
|
16
|
+
├── data/
|
|
17
|
+
│ ├── loader.py path -> Dataset (txt/json/jsonl/csv/dirs)
|
|
18
|
+
│ ├── fingerprint.py content-based dataset hashing
|
|
19
|
+
│ ├── inspector.py tl.inspect() report generation
|
|
20
|
+
│ └── tabular.py TabularPreprocessor: numeric/categorical encoding
|
|
21
|
+
├── auto/
|
|
22
|
+
│ ├── detector.py Dataset -> task string
|
|
23
|
+
│ └── config.py Dataset + TrainConfig -> ResolvedConfig
|
|
24
|
+
├── tokenization/
|
|
25
|
+
│ └── char_tokenizer.py CharTokenizer: vocab build/encode/decode/save/load
|
|
26
|
+
├── models/
|
|
27
|
+
│ ├── transformer.py TinyTransformer (GPT-style decoder)
|
|
28
|
+
│ ├── mlp.py TabularMLP
|
|
29
|
+
│ └── registry.py build_model(task, model_type, cfg, meta)
|
|
30
|
+
├── training/
|
|
31
|
+
│ ├── data_prep.py Dataset -> DataLoaders per task
|
|
32
|
+
│ ├── trainer.py the training loop (run_training)
|
|
33
|
+
│ └── early_stopping.py EarlyStopping
|
|
34
|
+
├── checkpoint/
|
|
35
|
+
│ └── manager.py CheckpointManager: atomic save/load/clear
|
|
36
|
+
├── serialization/
|
|
37
|
+
│ └── tl_format.py save_tl/load_tl: the .tl file format
|
|
38
|
+
├── devices/
|
|
39
|
+
│ └── device.py hardware auto-detection + torch.device resolution
|
|
40
|
+
└── cli/
|
|
41
|
+
└── main.py argparse-based CLI
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Data flow for `tl.train("./data")`
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
path
|
|
48
|
+
│
|
|
49
|
+
▼
|
|
50
|
+
data.loader.load_dataset(path) -> Dataset (kind, texts/records, columns)
|
|
51
|
+
│
|
|
52
|
+
▼
|
|
53
|
+
auto.detector.detect_task(ds) -> "text-generation" | "text-classification"
|
|
54
|
+
│ | "classification" | "regression"
|
|
55
|
+
▼
|
|
56
|
+
auto.config.resolve_config(ds, TrainConfig) -> ResolvedConfig (every field concrete)
|
|
57
|
+
│
|
|
58
|
+
▼
|
|
59
|
+
training.data_prep.prepare_*(ds, cfg) -> PreparedData (train/val DataLoaders,
|
|
60
|
+
│ meta, tokenizer/preprocessor)
|
|
61
|
+
▼
|
|
62
|
+
models.registry.build_model(task, model_type, cfg, meta) -> nn.Module
|
|
63
|
+
│
|
|
64
|
+
▼
|
|
65
|
+
training.trainer.run_training(...) -> trains, checkpoints periodically,
|
|
66
|
+
│ returns final weights + metrics
|
|
67
|
+
▼
|
|
68
|
+
serialization.tl_format.save_tl(out, payload) -> model.tl
|
|
69
|
+
│
|
|
70
|
+
▼
|
|
71
|
+
runtime.LoadedModel(payload) -> returned to the caller
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`api.train()` wraps this whole flow with the Smart Auto Check (see
|
|
75
|
+
[automatic_mode.md](automatic_mode.md)): before any of the above runs,
|
|
76
|
+
it checks for an existing complete `.tl` file or a resumable checkpoint
|
|
77
|
+
matching the dataset's fingerprint.
|
|
78
|
+
|
|
79
|
+
## Design principles
|
|
80
|
+
|
|
81
|
+
- **Every automatic decision is explainable.** Auto-detection and
|
|
82
|
+
auto-configuration are simple, inspectable heuristics (see
|
|
83
|
+
`auto/detector.py`, `auto/config.py`), not opaque search or ML-driven
|
|
84
|
+
meta-learning. Anyone reading the code can predict what Tensorless
|
|
85
|
+
will choose for a given dataset.
|
|
86
|
+
- **Never silently touch user data.** `data/loader.py` only reads;
|
|
87
|
+
nothing in the training path writes to or deletes files under the
|
|
88
|
+
dataset path.
|
|
89
|
+
- **Fail with actionable errors.** All user-facing errors are
|
|
90
|
+
`TensorlessError` subclasses with messages that say what's wrong and
|
|
91
|
+
usually what to do about it (see `errors.py` and
|
|
92
|
+
[troubleshooting.md](troubleshooting.md)).
|
|
93
|
+
- **Checkpoints are self-describing.** A checkpoint carries its own
|
|
94
|
+
config, meta, and dataset fingerprint, so resuming never depends on
|
|
95
|
+
external state being reconstructed correctly by the caller.
|
|
96
|
+
- **A `.tl` file is the unit of portability.** Nothing about inference
|
|
97
|
+
should require the original dataset, training script, or checkpoint
|
|
98
|
+
directory to still exist.
|
|
99
|
+
|
|
100
|
+
## Extending Tensorless
|
|
101
|
+
|
|
102
|
+
### Adding a new model type
|
|
103
|
+
|
|
104
|
+
1. Implement your `nn.Module` in `models/your_model.py`.
|
|
105
|
+
2. Register it in `models/registry.py`'s `build_model()`.
|
|
106
|
+
3. Add a branch in `training/trainer.py`'s `_compute_loss()` for how to
|
|
107
|
+
compute loss for your task/model_type combination.
|
|
108
|
+
4. If it needs new data prep, add a `prepare_*()` function in
|
|
109
|
+
`training/data_prep.py`.
|
|
110
|
+
5. If it changes what needs to go in the `.tl` file, extend the `meta`
|
|
111
|
+
dict produced by data prep — `build_model()` receives it and can pull
|
|
112
|
+
out whatever fields it needs.
|
|
113
|
+
|
|
114
|
+
### Adding a new data format
|
|
115
|
+
|
|
116
|
+
Add a branch to `data/loader.py`'s `load_dataset()` / `_load_directory()`
|
|
117
|
+
for the new extension, producing a `Dataset` with the appropriate `kind`.
|
|
118
|
+
|
|
119
|
+
### Adding a new backend/device
|
|
120
|
+
|
|
121
|
+
Extend `devices/device.py`'s `_*_available()` checks and
|
|
122
|
+
`auto_select_device()` / `get_torch_device()`.
|
|
123
|
+
|
|
124
|
+
See [contributing.md](contributing.md) for the contribution process
|
|
125
|
+
itself (tests, PRs, etc).
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Automatic Mode
|
|
2
|
+
|
|
3
|
+
Tensorless's whole premise is that `tl.train("./data")` should just
|
|
4
|
+
work. This page explains exactly what "automatic" means at each stage,
|
|
5
|
+
so the behavior is predictable rather than magic.
|
|
6
|
+
|
|
7
|
+
## 1. Task detection
|
|
8
|
+
|
|
9
|
+
`tensorless/auto/detector.py` looks at the *shape* of your loaded
|
|
10
|
+
dataset (see [training.md](training.md#supported-data-formats) for how
|
|
11
|
+
data is loaded) and picks one of four tasks:
|
|
12
|
+
|
|
13
|
+
| Dataset shape | Detected task |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Plain text (one or more `.txt`/`.md` files, or JSON/JSONL records with a `text` field and no label) | `text-generation` |
|
|
16
|
+
| Text with labels (class subfolders, or JSON/JSONL with `text` + `label`) | `text-classification` |
|
|
17
|
+
| Tabular data whose target column is numeric with many distinct values | `regression` |
|
|
18
|
+
| Tabular data whose target column is categorical, or numeric with few distinct integer values | `classification` |
|
|
19
|
+
|
|
20
|
+
The target column for tabular data is chosen by looking for a column
|
|
21
|
+
named `label`, `target`, `class`, `category`, `y`, or `output` (case
|
|
22
|
+
insensitive); if none of those exist, the **last column** in the file is
|
|
23
|
+
used, which is a common convention in tabular datasets.
|
|
24
|
+
|
|
25
|
+
You can always override detection explicitly: `tl.train("./data",
|
|
26
|
+
task="regression")`.
|
|
27
|
+
|
|
28
|
+
## 2. Architecture selection
|
|
29
|
+
|
|
30
|
+
Once the task is known, `tensorless/auto/config.py` picks:
|
|
31
|
+
|
|
32
|
+
- **model type**: `transformer` for text tasks, `mlp` for tabular tasks
|
|
33
|
+
- **size** (`d_model`, `layers`, `heads`): scaled to dataset size, from
|
|
34
|
+
a tiny 2-layer/64-dim model for a few hundred examples up to an
|
|
35
|
+
8-layer/384-dim model for 50,000+ examples
|
|
36
|
+
|
|
37
|
+
This is a heuristic, not a search — the goal is "a model that trains
|
|
38
|
+
quickly and doesn't wildly overfit or underfit for typical dataset
|
|
39
|
+
sizes," not the best possible architecture. Override any of it:
|
|
40
|
+
`tl.train("./data", d_model=512, layers=6)`.
|
|
41
|
+
|
|
42
|
+
## 3. Hyperparameter selection
|
|
43
|
+
|
|
44
|
+
Batch size, epoch count, learning rate, warmup steps, and the
|
|
45
|
+
validation split are all similarly scaled to dataset size. See
|
|
46
|
+
[configuration.md](configuration.md) for the exact defaults and how to
|
|
47
|
+
override each one.
|
|
48
|
+
|
|
49
|
+
## 4. Hardware selection
|
|
50
|
+
|
|
51
|
+
`tensorless/devices/device.py` picks, in order: TPU (if `torch_xla` is
|
|
52
|
+
installed and usable) → CUDA GPU (if available) → Apple MPS (if
|
|
53
|
+
available) → CPU. Precision is chosen alongside it: `bf16` on TPU,
|
|
54
|
+
`bf16` or `fp16` on GPU depending on hardware support, and `fp32`
|
|
55
|
+
everywhere else for stability.
|
|
56
|
+
|
|
57
|
+
This selection isn't blind — Tensorless actually checks each backend is
|
|
58
|
+
usable (not just importable) before choosing it, and if a device you
|
|
59
|
+
explicitly request isn't available, it downgrades gracefully rather
|
|
60
|
+
than erroring.
|
|
61
|
+
|
|
62
|
+
## 5. The Smart Auto Check
|
|
63
|
+
|
|
64
|
+
This is the part that makes repeated `tl.train("./data")` calls safe and
|
|
65
|
+
cheap. Every dataset gets a **fingerprint**: a hash of every file's
|
|
66
|
+
content, size, and relative path under the given directory (see
|
|
67
|
+
`tensorless/data/fingerprint.py`). This fingerprint is content-based, not
|
|
68
|
+
timestamp-based, so touching a file without changing it, or copying a
|
|
69
|
+
dataset to a new machine, doesn't trigger a false "changed" signal.
|
|
70
|
+
|
|
71
|
+
When you call `tl.train(path, out="model.tl")`, Tensorless checks, in
|
|
72
|
+
order:
|
|
73
|
+
|
|
74
|
+
1. **Does `model.tl` already exist, with a fingerprint matching the
|
|
75
|
+
current dataset, and `training_complete=True`?**
|
|
76
|
+
→ Return it immediately. No training happens.
|
|
77
|
+
|
|
78
|
+
2. **Is there a checkpoint at `model.tl.ckpt/` whose fingerprint matches
|
|
79
|
+
the current dataset?**
|
|
80
|
+
- If that checkpoint's training wasn't finished
|
|
81
|
+
(`training_complete=False`) → **resume** from it.
|
|
82
|
+
- If it was actually finished but the final `.tl` file is missing
|
|
83
|
+
(e.g. the process died right after the last checkpoint write, before
|
|
84
|
+
the `.tl` file could be written) → package that checkpoint into
|
|
85
|
+
`model.tl` directly, no retraining needed.
|
|
86
|
+
|
|
87
|
+
3. **Is there a checkpoint whose fingerprint does *not* match?** → The
|
|
88
|
+
dataset changed since that checkpoint was created.
|
|
89
|
+
- By default, Tensorless retrains from scratch automatically (and
|
|
90
|
+
prints a message explaining why).
|
|
91
|
+
- Pass `ask_on_data_change=True` to instead raise a `ConfigError`
|
|
92
|
+
and let you decide, rather than silently retraining.
|
|
93
|
+
|
|
94
|
+
4. **None of the above?** → Train from scratch.
|
|
95
|
+
|
|
96
|
+
`force=True` skips all of this and always retrains from scratch,
|
|
97
|
+
clearing any existing checkpoint first.
|
|
98
|
+
|
|
99
|
+
See [checkpointing.md](checkpointing.md) for what's actually inside a
|
|
100
|
+
checkpoint and exactly how resumption reconstructs training state.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Checkpointing & Resume
|
|
2
|
+
|
|
3
|
+
## Where checkpoints live
|
|
4
|
+
|
|
5
|
+
Every training run writes to a checkpoint directory, by default
|
|
6
|
+
`<out>.ckpt/` (e.g. `model.tl.ckpt/checkpoint.pt`). You never need to
|
|
7
|
+
create or manage this directory yourself.
|
|
8
|
+
|
|
9
|
+
## What's in a checkpoint
|
|
10
|
+
|
|
11
|
+
`tensorless/checkpoint/manager.py` writes a single file,
|
|
12
|
+
`checkpoint.pt`, containing:
|
|
13
|
+
|
|
14
|
+
- `model_state_dict` — model weights
|
|
15
|
+
- `optimizer_state_dict` — optimizer momentum/variance buffers
|
|
16
|
+
- `scheduler_state_dict` — learning rate schedule position
|
|
17
|
+
- `epoch`, `global_step` — where training left off
|
|
18
|
+
- `early_stopping_best`, `early_stopping_bad_checks` — early stopping state
|
|
19
|
+
- `config` — the fully resolved training configuration used
|
|
20
|
+
- `meta` — task-specific sizing info (vocab size, number of classes, etc.)
|
|
21
|
+
- `tokenizer_state` / `preprocessor_state` — whichever applies to the task
|
|
22
|
+
- `dataset_fingerprint` — the fingerprint of the dataset this checkpoint
|
|
23
|
+
was trained on (see [automatic_mode.md](automatic_mode.md#5-the-smart-auto-check))
|
|
24
|
+
- `training_complete` — whether this checkpoint represents a finished run
|
|
25
|
+
|
|
26
|
+
This is everything needed to either resume training or reconstruct the
|
|
27
|
+
final `.tl` file — nothing about resumption depends on the original
|
|
28
|
+
dataset still being on disk in the same location, only on it being
|
|
29
|
+
fingerprint-identical to what was originally used.
|
|
30
|
+
|
|
31
|
+
## When checkpoints are written
|
|
32
|
+
|
|
33
|
+
- Every `checkpoint_every` steps (default: 50) during training, with
|
|
34
|
+
`training_complete=False`
|
|
35
|
+
- At the end of every epoch, with `training_complete` set to whether
|
|
36
|
+
that was the last epoch
|
|
37
|
+
- On early stopping, with `training_complete=True`
|
|
38
|
+
|
|
39
|
+
Writes are atomic: Tensorless writes to a temporary file in the same
|
|
40
|
+
directory and renames it into place, so a crash mid-write never leaves a
|
|
41
|
+
corrupt checkpoint that would block resumption.
|
|
42
|
+
|
|
43
|
+
## How resumption works
|
|
44
|
+
|
|
45
|
+
When `tl.train()` finds a checkpoint whose `dataset_fingerprint` matches
|
|
46
|
+
the current dataset and `training_complete=False`, it:
|
|
47
|
+
|
|
48
|
+
1. Loads the tokenizer/preprocessor state from the checkpoint (so the
|
|
49
|
+
vocabulary or column encoding is identical to the original run)
|
|
50
|
+
2. Rebuilds the exact same model architecture from the checkpoint's
|
|
51
|
+
saved `config`
|
|
52
|
+
3. Loads model, optimizer, and scheduler state
|
|
53
|
+
4. Continues the training loop from the saved `epoch` / `global_step`
|
|
54
|
+
|
|
55
|
+
**Important:** any config overrides you pass to the resuming
|
|
56
|
+
`tl.train()` call (e.g. a different `d_model`) are ignored in favor of
|
|
57
|
+
the checkpoint's original config. This is intentional — a resumed run
|
|
58
|
+
must use the same architecture as the interrupted run, or the saved
|
|
59
|
+
weights simply won't fit. If you want different hyperparameters,
|
|
60
|
+
either delete the checkpoint directory first or pass `force=True`.
|
|
61
|
+
|
|
62
|
+
## Manually clearing a checkpoint
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from tensorless.checkpoint.manager import CheckpointManager
|
|
66
|
+
CheckpointManager("model.tl.ckpt").clear()
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
or simply delete the directory:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
rm -rf model.tl.ckpt
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`tl.train(..., force=True)` does this for you automatically before
|
|
76
|
+
retraining.
|