tensorless-pytorch 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_pytorch-0.1.0/LICENSE +21 -0
- tensorless_pytorch-0.1.0/MANIFEST.in +5 -0
- tensorless_pytorch-0.1.0/PKG-INFO +82 -0
- tensorless_pytorch-0.1.0/README.md +68 -0
- tensorless_pytorch-0.1.0/docs/api_reference.md +103 -0
- tensorless_pytorch-0.1.0/docs/architecture.md +126 -0
- tensorless_pytorch-0.1.0/docs/automatic_mode.md +109 -0
- tensorless_pytorch-0.1.0/docs/checkpointing.md +80 -0
- tensorless_pytorch-0.1.0/docs/cli.md +87 -0
- tensorless_pytorch-0.1.0/docs/configuration.md +95 -0
- tensorless_pytorch-0.1.0/docs/contributing.md +80 -0
- tensorless_pytorch-0.1.0/docs/examples.md +112 -0
- tensorless_pytorch-0.1.0/docs/inference.md +104 -0
- tensorless_pytorch-0.1.0/docs/installation.md +43 -0
- tensorless_pytorch-0.1.0/docs/limitations.md +72 -0
- tensorless_pytorch-0.1.0/docs/quickstart.md +96 -0
- tensorless_pytorch-0.1.0/docs/roadmap.md +36 -0
- tensorless_pytorch-0.1.0/docs/tl_format.md +84 -0
- tensorless_pytorch-0.1.0/docs/training.md +121 -0
- tensorless_pytorch-0.1.0/docs/troubleshooting.md +98 -0
- tensorless_pytorch-0.1.0/docs/tutorial.md +161 -0
- tensorless_pytorch-0.1.0/examples/tabular_classification_example.py +50 -0
- tensorless_pytorch-0.1.0/examples/tabular_regression_example.py +49 -0
- tensorless_pytorch-0.1.0/examples/text_classification_example.py +53 -0
- tensorless_pytorch-0.1.0/examples/text_generation_example.py +48 -0
- tensorless_pytorch-0.1.0/pyproject.toml +27 -0
- tensorless_pytorch-0.1.0/setup.cfg +4 -0
- tensorless_pytorch-0.1.0/tensorless/__init__.py +41 -0
- tensorless_pytorch-0.1.0/tensorless/_version.py +6 -0
- tensorless_pytorch-0.1.0/tensorless/api.py +246 -0
- tensorless_pytorch-0.1.0/tensorless/auto/__init__.py +4 -0
- tensorless_pytorch-0.1.0/tensorless/auto/config.py +135 -0
- tensorless_pytorch-0.1.0/tensorless/auto/detector.py +95 -0
- tensorless_pytorch-0.1.0/tensorless/checkpoint/__init__.py +3 -0
- tensorless_pytorch-0.1.0/tensorless/checkpoint/manager.py +66 -0
- tensorless_pytorch-0.1.0/tensorless/cli/__init__.py +3 -0
- tensorless_pytorch-0.1.0/tensorless/cli/main.py +121 -0
- tensorless_pytorch-0.1.0/tensorless/config.py +125 -0
- tensorless_pytorch-0.1.0/tensorless/data/__init__.py +11 -0
- tensorless_pytorch-0.1.0/tensorless/data/english_grammar.txt +262 -0
- tensorless_pytorch-0.1.0/tensorless/data/fingerprint.py +71 -0
- tensorless_pytorch-0.1.0/tensorless/data/inspector.py +161 -0
- tensorless_pytorch-0.1.0/tensorless/data/loader.py +255 -0
- tensorless_pytorch-0.1.0/tensorless/data/tabular.py +213 -0
- tensorless_pytorch-0.1.0/tensorless/devices/__init__.py +3 -0
- tensorless_pytorch-0.1.0/tensorless/devices/device.py +107 -0
- tensorless_pytorch-0.1.0/tensorless/errors.py +36 -0
- tensorless_pytorch-0.1.0/tensorless/models/__init__.py +5 -0
- tensorless_pytorch-0.1.0/tensorless/models/mlp.py +64 -0
- tensorless_pytorch-0.1.0/tensorless/models/registry.py +53 -0
- tensorless_pytorch-0.1.0/tensorless/models/transformer.py +175 -0
- tensorless_pytorch-0.1.0/tensorless/runtime.py +158 -0
- tensorless_pytorch-0.1.0/tensorless/serialization/__init__.py +3 -0
- tensorless_pytorch-0.1.0/tensorless/serialization/tl_format.py +119 -0
- tensorless_pytorch-0.1.0/tensorless/tokenization/__init__.py +11 -0
- tensorless_pytorch-0.1.0/tensorless/tokenization/bpe_tokenizer.py +128 -0
- tensorless_pytorch-0.1.0/tensorless/tokenization/char_tokenizer.py +84 -0
- tensorless_pytorch-0.1.0/tensorless/training/__init__.py +4 -0
- tensorless_pytorch-0.1.0/tensorless/training/data_prep.py +238 -0
- tensorless_pytorch-0.1.0/tensorless/training/early_stopping.py +31 -0
- tensorless_pytorch-0.1.0/tensorless/training/trainer.py +260 -0
- tensorless_pytorch-0.1.0/tensorless_pytorch.egg-info/PKG-INFO +82 -0
- tensorless_pytorch-0.1.0/tensorless_pytorch.egg-info/SOURCES.txt +75 -0
- tensorless_pytorch-0.1.0/tensorless_pytorch.egg-info/dependency_links.txt +1 -0
- tensorless_pytorch-0.1.0/tensorless_pytorch.egg-info/entry_points.txt +2 -0
- tensorless_pytorch-0.1.0/tensorless_pytorch.egg-info/requires.txt +4 -0
- tensorless_pytorch-0.1.0/tensorless_pytorch.egg-info/top_level.txt +1 -0
- tensorless_pytorch-0.1.0/tests/test_auto_detection.py +22 -0
- tensorless_pytorch-0.1.0/tests/test_checkpoint_resume.py +80 -0
- tensorless_pytorch-0.1.0/tests/test_cli.py +37 -0
- tensorless_pytorch-0.1.0/tests/test_data_loading.py +76 -0
- tensorless_pytorch-0.1.0/tests/test_end_to_end.py +50 -0
- tensorless_pytorch-0.1.0/tests/test_fingerprint.py +40 -0
- tensorless_pytorch-0.1.0/tests/test_serialization.py +91 -0
- tensorless_pytorch-0.1.0/tests/test_train_tabular.py +85 -0
- tensorless_pytorch-0.1.0/tests/test_train_text_classification.py +34 -0
- tensorless_pytorch-0.1.0/tests/test_train_text_generation.py +125 -0
|
@@ -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,82 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tensorless-pytorch
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Automatic PyTorch training with portable models and minimal setup.
|
|
5
|
+
Author: Tensorless PyTorch 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 PyTorch
|
|
16
|
+
|
|
17
|
+
Tensorless PyTorch is a lightweight toolkit for turning ordinary text and
|
|
18
|
+
tabular data into portable PyTorch models with minimal setup. It supports text
|
|
19
|
+
generation, text classification, tabular classification, and regression.
|
|
20
|
+
|
|
21
|
+
The distribution is installed as `tensorless-pytorch`; the stable Python import
|
|
22
|
+
remains `tensorless` for compatibility.
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install tensorless-pytorch
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Train on your data
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import tensorless as tl
|
|
34
|
+
|
|
35
|
+
model = tl.train("./corpus.txt", task="text-generation")
|
|
36
|
+
print(model.generate("The", max_new_tokens=40))
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Text files are trained as next-token language models. BPE is the default
|
|
40
|
+
tokenizer; use `tokenizer="char"` for a character-level model. Tensorless PyTorch
|
|
41
|
+
derives model size, batch size, epochs, validation, device, and BPE vocabulary
|
|
42
|
+
size from the data, while every setting can be overridden.
|
|
43
|
+
|
|
44
|
+
Long text is tokenized lazily and fed through PyTorch in fixed-size batches.
|
|
45
|
+
CUDA training automatically uses `fp16` or `bf16` when supported, including
|
|
46
|
+
gradient scaling and checkpointed scaler state. Reduce `batch_size` if memory
|
|
47
|
+
is limited.
|
|
48
|
+
|
|
49
|
+
## English starter pretraining
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import tensorless as tl
|
|
53
|
+
|
|
54
|
+
model = tl.pretrain(out="english.tl", epochs=20, max_seq_len=128)
|
|
55
|
+
print(model.generate("A complete sentence", max_new_tokens=30))
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This offline starter corpus contains English prose and grammar examples. It is
|
|
59
|
+
for demos and smoke tests, not a replacement for a large language dataset. For
|
|
60
|
+
real pretraining, pass your own `.txt` corpus to `tl.train()` and increase the
|
|
61
|
+
training settings as your hardware allows.
|
|
62
|
+
|
|
63
|
+
## Other tasks
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
tl.train("reviews/", task="text-classification")
|
|
67
|
+
tl.train("housing.csv", task="regression")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Tabular preprocessing automatically handles numeric values, ISO dates, and
|
|
71
|
+
high-cardinality categories. Missing and rare values are handled using the
|
|
72
|
+
fitted training data, and the same preprocessing is stored in the `.tl` file.
|
|
73
|
+
|
|
74
|
+
Models are saved as `.tl` files and can be loaded later:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
model = tl.load("model.tl")
|
|
78
|
+
print(model.info())
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
See the [documentation](docs/quickstart.md) for data formats, configuration,
|
|
82
|
+
mixed precision, checkpointing, and the command-line interface.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Tensorless PyTorch
|
|
2
|
+
|
|
3
|
+
Tensorless PyTorch is a lightweight toolkit for turning ordinary text and
|
|
4
|
+
tabular data into portable PyTorch models with minimal setup. It supports text
|
|
5
|
+
generation, text classification, tabular classification, and regression.
|
|
6
|
+
|
|
7
|
+
The distribution is installed as `tensorless-pytorch`; the stable Python import
|
|
8
|
+
remains `tensorless` for compatibility.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install tensorless-pytorch
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Train on your data
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
import tensorless as tl
|
|
20
|
+
|
|
21
|
+
model = tl.train("./corpus.txt", task="text-generation")
|
|
22
|
+
print(model.generate("The", max_new_tokens=40))
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Text files are trained as next-token language models. BPE is the default
|
|
26
|
+
tokenizer; use `tokenizer="char"` for a character-level model. Tensorless PyTorch
|
|
27
|
+
derives model size, batch size, epochs, validation, device, and BPE vocabulary
|
|
28
|
+
size from the data, while every setting can be overridden.
|
|
29
|
+
|
|
30
|
+
Long text is tokenized lazily and fed through PyTorch in fixed-size batches.
|
|
31
|
+
CUDA training automatically uses `fp16` or `bf16` when supported, including
|
|
32
|
+
gradient scaling and checkpointed scaler state. Reduce `batch_size` if memory
|
|
33
|
+
is limited.
|
|
34
|
+
|
|
35
|
+
## English starter pretraining
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import tensorless as tl
|
|
39
|
+
|
|
40
|
+
model = tl.pretrain(out="english.tl", epochs=20, max_seq_len=128)
|
|
41
|
+
print(model.generate("A complete sentence", max_new_tokens=30))
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
This offline starter corpus contains English prose and grammar examples. It is
|
|
45
|
+
for demos and smoke tests, not a replacement for a large language dataset. For
|
|
46
|
+
real pretraining, pass your own `.txt` corpus to `tl.train()` and increase the
|
|
47
|
+
training settings as your hardware allows.
|
|
48
|
+
|
|
49
|
+
## Other tasks
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
tl.train("reviews/", task="text-classification")
|
|
53
|
+
tl.train("housing.csv", task="regression")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Tabular preprocessing automatically handles numeric values, ISO dates, and
|
|
57
|
+
high-cardinality categories. Missing and rare values are handled using the
|
|
58
|
+
fitted training data, and the same preprocessing is stored in the `.tl` file.
|
|
59
|
+
|
|
60
|
+
Models are saved as `.tl` files and can be loaded later:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
model = tl.load("model.tl")
|
|
64
|
+
print(model.info())
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
See the [documentation](docs/quickstart.md) for data formats, configuration,
|
|
68
|
+
mixed precision, checkpointing, and the command-line interface.
|
|
@@ -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 PyTorch 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,126 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This page is for people extending or contributing to Tensorless PyTorch, 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
|
+
│ └── bpe_tokenizer.py BPETokenizer: corpus-trained subword encoding
|
|
27
|
+
├── models/
|
|
28
|
+
│ ├── transformer.py TinyTransformer (GPT-style decoder)
|
|
29
|
+
│ ├── mlp.py TabularMLP
|
|
30
|
+
│ └── registry.py build_model(task, model_type, cfg, meta)
|
|
31
|
+
├── training/
|
|
32
|
+
│ ├── data_prep.py Dataset -> DataLoaders per task
|
|
33
|
+
│ ├── trainer.py the training loop (run_training)
|
|
34
|
+
│ └── early_stopping.py EarlyStopping
|
|
35
|
+
├── checkpoint/
|
|
36
|
+
│ └── manager.py CheckpointManager: atomic save/load/clear
|
|
37
|
+
├── serialization/
|
|
38
|
+
│ └── tl_format.py save_tl/load_tl: the .tl file format
|
|
39
|
+
├── devices/
|
|
40
|
+
│ └── device.py hardware auto-detection + torch.device resolution
|
|
41
|
+
└── cli/
|
|
42
|
+
└── main.py argparse-based CLI
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Data flow for `tl.train("./data")`
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
path
|
|
49
|
+
│
|
|
50
|
+
▼
|
|
51
|
+
data.loader.load_dataset(path) -> Dataset (kind, texts/records, columns)
|
|
52
|
+
│
|
|
53
|
+
▼
|
|
54
|
+
auto.detector.detect_task(ds) -> "text-generation" | "text-classification"
|
|
55
|
+
│ | "classification" | "regression"
|
|
56
|
+
▼
|
|
57
|
+
auto.config.resolve_config(ds, TrainConfig) -> ResolvedConfig (every field concrete)
|
|
58
|
+
│
|
|
59
|
+
▼
|
|
60
|
+
training.data_prep.prepare_*(ds, cfg) -> PreparedData (train/val DataLoaders,
|
|
61
|
+
│ meta, tokenizer/preprocessor)
|
|
62
|
+
▼
|
|
63
|
+
models.registry.build_model(task, model_type, cfg, meta) -> nn.Module
|
|
64
|
+
│
|
|
65
|
+
▼
|
|
66
|
+
training.trainer.run_training(...) -> trains, checkpoints periodically,
|
|
67
|
+
│ returns final weights + metrics
|
|
68
|
+
▼
|
|
69
|
+
serialization.tl_format.save_tl(out, payload) -> model.tl
|
|
70
|
+
│
|
|
71
|
+
▼
|
|
72
|
+
runtime.LoadedModel(payload) -> returned to the caller
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`api.train()` wraps this whole flow with the Smart Auto Check (see
|
|
76
|
+
[automatic_mode.md](automatic_mode.md)): before any of the above runs,
|
|
77
|
+
it checks for an existing complete `.tl` file or a resumable checkpoint
|
|
78
|
+
matching the dataset's fingerprint.
|
|
79
|
+
|
|
80
|
+
## Design principles
|
|
81
|
+
|
|
82
|
+
- **Every automatic decision is explainable.** Auto-detection and
|
|
83
|
+
auto-configuration are simple, inspectable heuristics (see
|
|
84
|
+
`auto/detector.py`, `auto/config.py`), not opaque search or ML-driven
|
|
85
|
+
meta-learning. Anyone reading the code can predict what Tensorless PyTorch
|
|
86
|
+
will choose for a given dataset.
|
|
87
|
+
- **Never silently touch user data.** `data/loader.py` only reads;
|
|
88
|
+
nothing in the training path writes to or deletes files under the
|
|
89
|
+
dataset path.
|
|
90
|
+
- **Fail with actionable errors.** All user-facing errors are
|
|
91
|
+
`TensorlessError` subclasses with messages that say what's wrong and
|
|
92
|
+
usually what to do about it (see `errors.py` and
|
|
93
|
+
[troubleshooting.md](troubleshooting.md)).
|
|
94
|
+
- **Checkpoints are self-describing.** A checkpoint carries its own
|
|
95
|
+
config, meta, and dataset fingerprint, so resuming never depends on
|
|
96
|
+
external state being reconstructed correctly by the caller.
|
|
97
|
+
- **A `.tl` file is the unit of portability.** Nothing about inference
|
|
98
|
+
should require the original dataset, training script, or checkpoint
|
|
99
|
+
directory to still exist.
|
|
100
|
+
|
|
101
|
+
## Extending Tensorless PyTorch
|
|
102
|
+
|
|
103
|
+
### Adding a new model type
|
|
104
|
+
|
|
105
|
+
1. Implement your `nn.Module` in `models/your_model.py`.
|
|
106
|
+
2. Register it in `models/registry.py`'s `build_model()`.
|
|
107
|
+
3. Add a branch in `training/trainer.py`'s `_compute_loss()` for how to
|
|
108
|
+
compute loss for your task/model_type combination.
|
|
109
|
+
4. If it needs new data prep, add a `prepare_*()` function in
|
|
110
|
+
`training/data_prep.py`.
|
|
111
|
+
5. If it changes what needs to go in the `.tl` file, extend the `meta`
|
|
112
|
+
dict produced by data prep — `build_model()` receives it and can pull
|
|
113
|
+
out whatever fields it needs.
|
|
114
|
+
|
|
115
|
+
### Adding a new data format
|
|
116
|
+
|
|
117
|
+
Add a branch to `data/loader.py`'s `load_dataset()` / `_load_directory()`
|
|
118
|
+
for the new extension, producing a `Dataset` with the appropriate `kind`.
|
|
119
|
+
|
|
120
|
+
### Adding a new backend/device
|
|
121
|
+
|
|
122
|
+
Extend `devices/device.py`'s `_*_available()` checks and
|
|
123
|
+
`auto_select_device()` / `get_torch_device()`.
|
|
124
|
+
|
|
125
|
+
See [contributing.md](contributing.md) for the contribution process
|
|
126
|
+
itself (tests, PRs, etc).
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Automatic Mode
|
|
2
|
+
|
|
3
|
+
Tensorless PyTorch'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 effective text examples up to an
|
|
35
|
+
8-layer/384-dim model for 50,000+ examples
|
|
36
|
+
|
|
37
|
+
For text corpora, effective examples include corpus character count, so a
|
|
38
|
+
single large `.txt` file is not treated like one training example. BPE
|
|
39
|
+
vocabulary size is also bounded from corpus character diversity rather than
|
|
40
|
+
always using a fixed oversized vocabulary.
|
|
41
|
+
|
|
42
|
+
This is a heuristic, not a search — the goal is "a model that trains
|
|
43
|
+
quickly and doesn't wildly overfit or underfit for typical dataset
|
|
44
|
+
sizes," not the best possible architecture. Override any of it:
|
|
45
|
+
`tl.train("./data", d_model=512, layers=6)`.
|
|
46
|
+
|
|
47
|
+
For a packaged English grammar starter corpus, use
|
|
48
|
+
`tl.pretrain(out="english.tl")`. It is intended for demos and smoke tests;
|
|
49
|
+
larger local corpora should be passed to `tl.train()`.
|
|
50
|
+
|
|
51
|
+
## 3. Hyperparameter selection
|
|
52
|
+
|
|
53
|
+
Batch size, epoch count, learning rate, warmup steps, and the
|
|
54
|
+
validation split are all similarly scaled to dataset size. See
|
|
55
|
+
[configuration.md](configuration.md) for the exact defaults and how to
|
|
56
|
+
override each one.
|
|
57
|
+
|
|
58
|
+
## 4. Hardware selection
|
|
59
|
+
|
|
60
|
+
`tensorless/devices/device.py` picks, in order: TPU (if `torch_xla` is
|
|
61
|
+
installed and usable) → CUDA GPU (if available) → Apple MPS (if
|
|
62
|
+
available) → CPU. Precision is chosen alongside it: `bf16` on TPU,
|
|
63
|
+
`bf16` or `fp16` on GPU depending on hardware support, and `fp32`
|
|
64
|
+
everywhere else for stability.
|
|
65
|
+
|
|
66
|
+
This selection isn't blind — Tensorless PyTorch actually checks each backend is
|
|
67
|
+
usable (not just importable) before choosing it, and if a device you
|
|
68
|
+
explicitly request isn't available, it downgrades gracefully rather
|
|
69
|
+
than erroring.
|
|
70
|
+
|
|
71
|
+
## 5. The Smart Auto Check
|
|
72
|
+
|
|
73
|
+
This is the part that makes repeated `tl.train("./data")` calls safe and
|
|
74
|
+
cheap. Every dataset gets a **fingerprint**: a hash of every file's
|
|
75
|
+
content, size, and relative path under the given directory (see
|
|
76
|
+
`tensorless/data/fingerprint.py`). This fingerprint is content-based, not
|
|
77
|
+
timestamp-based, so touching a file without changing it, or copying a
|
|
78
|
+
dataset to a new machine, doesn't trigger a false "changed" signal.
|
|
79
|
+
|
|
80
|
+
When you call `tl.train(path, out="model.tl")`, Tensorless PyTorch checks, in
|
|
81
|
+
order:
|
|
82
|
+
|
|
83
|
+
1. **Does `model.tl` already exist, with a fingerprint matching the
|
|
84
|
+
current dataset, and `training_complete=True`?**
|
|
85
|
+
→ Return it immediately. No training happens.
|
|
86
|
+
|
|
87
|
+
2. **Is there a checkpoint at `model.tl.ckpt/` whose fingerprint matches
|
|
88
|
+
the current dataset?**
|
|
89
|
+
- If that checkpoint's training wasn't finished
|
|
90
|
+
(`training_complete=False`) → **resume** from it.
|
|
91
|
+
- If it was actually finished but the final `.tl` file is missing
|
|
92
|
+
(e.g. the process died right after the last checkpoint write, before
|
|
93
|
+
the `.tl` file could be written) → package that checkpoint into
|
|
94
|
+
`model.tl` directly, no retraining needed.
|
|
95
|
+
|
|
96
|
+
3. **Is there a checkpoint whose fingerprint does *not* match?** → The
|
|
97
|
+
dataset changed since that checkpoint was created.
|
|
98
|
+
- By default, Tensorless PyTorch retrains from scratch automatically (and
|
|
99
|
+
prints a message explaining why).
|
|
100
|
+
- Pass `ask_on_data_change=True` to instead raise a `ConfigError`
|
|
101
|
+
and let you decide, rather than silently retraining.
|
|
102
|
+
|
|
103
|
+
4. **None of the above?** → Train from scratch.
|
|
104
|
+
|
|
105
|
+
`force=True` skips all of this and always retrains from scratch,
|
|
106
|
+
clearing any existing checkpoint first.
|
|
107
|
+
|
|
108
|
+
See [checkpointing.md](checkpointing.md) for what's actually inside a
|
|
109
|
+
checkpoint and exactly how resumption reconstructs training state.
|
|
@@ -0,0 +1,80 @@
|
|
|
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 PyTorch 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
|
+
When loading `.tl` files, Tensorless PyTorch fills compatible fields introduced by
|
|
44
|
+
older versions with safe defaults. Files created by a newer unsupported format
|
|
45
|
+
version are rejected with an upgrade message instead of being partially read.
|
|
46
|
+
|
|
47
|
+
## How resumption works
|
|
48
|
+
|
|
49
|
+
When `tl.train()` finds a checkpoint whose `dataset_fingerprint` matches
|
|
50
|
+
the current dataset and `training_complete=False`, it:
|
|
51
|
+
|
|
52
|
+
1. Loads the tokenizer/preprocessor state from the checkpoint (so the
|
|
53
|
+
vocabulary or column encoding is identical to the original run)
|
|
54
|
+
2. Rebuilds the exact same model architecture from the checkpoint's
|
|
55
|
+
saved `config`
|
|
56
|
+
3. Loads model, optimizer, and scheduler state
|
|
57
|
+
4. Continues the training loop from the saved `epoch` / `global_step`
|
|
58
|
+
|
|
59
|
+
**Important:** any config overrides you pass to the resuming
|
|
60
|
+
`tl.train()` call (e.g. a different `d_model`) are ignored in favor of
|
|
61
|
+
the checkpoint's original config. This is intentional — a resumed run
|
|
62
|
+
must use the same architecture as the interrupted run, or the saved
|
|
63
|
+
weights simply won't fit. If you want different hyperparameters,
|
|
64
|
+
either delete the checkpoint directory first or pass `force=True`.
|
|
65
|
+
|
|
66
|
+
## Manually clearing a checkpoint
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from tensorless.checkpoint.manager import CheckpointManager
|
|
70
|
+
CheckpointManager("model.tl.ckpt").clear()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
or simply delete the directory:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
rm -rf model.tl.ckpt
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`tl.train(..., force=True)` does this for you automatically before
|
|
80
|
+
retraining.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Command-Line Interface
|
|
2
|
+
|
|
3
|
+
Installing Tensorless PyTorch (`pip install tensorless-pytorch`) puts a `tensorless` command
|
|
4
|
+
on your `PATH`.
|
|
5
|
+
|
|
6
|
+
## `tensorless train`
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
tensorless train <path> [options]
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
| Option | Description |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `--out PATH` | Output `.tl` path (default: `model.tl`) |
|
|
15
|
+
| `--force` | Retrain even if a matching model/checkpoint exists |
|
|
16
|
+
| `--d-model N` | Hidden dimension |
|
|
17
|
+
| `--layers N` | Number of layers |
|
|
18
|
+
| `--heads N` | Attention heads |
|
|
19
|
+
| `--batch-size N` | Batch size |
|
|
20
|
+
| `--epochs N` | Max epochs |
|
|
21
|
+
| `--learning-rate F` | Learning rate |
|
|
22
|
+
| `--device {cpu,cuda,tpu,mps}` | Force a device |
|
|
23
|
+
| `--quiet` | Suppress training logs |
|
|
24
|
+
|
|
25
|
+
For any configuration option not exposed as a CLI flag, use the Python
|
|
26
|
+
API — the CLI covers the common cases; `tl.train()` covers everything in
|
|
27
|
+
[configuration.md](configuration.md).
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
tensorless train ./data --out sentiment.tl --epochs 20 --batch-size 32
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## `tensorless run`
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
tensorless run <model.tl> [--prompt TEXT]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- Text-generation model, no `--prompt`: starts an interactive chat.
|
|
42
|
+
- Text-generation model, with `--prompt`: prints one generated
|
|
43
|
+
continuation.
|
|
44
|
+
- Text-classification model, with `--prompt`: prints the predicted
|
|
45
|
+
class.
|
|
46
|
+
- Tabular (classification/regression) model: the CLI can't accept
|
|
47
|
+
structured input as a single string, so it prints a pointer to the
|
|
48
|
+
Python API (`tl.load(path).predict({...})`).
|
|
49
|
+
|
|
50
|
+
## `tensorless inspect`
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
tensorless inspect <path>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Loads the dataset, runs task detection, and prints a report: detected
|
|
57
|
+
kind and task, example count, columns (for tabular data), and any
|
|
58
|
+
warnings/recommendations — without training anything.
|
|
59
|
+
|
|
60
|
+
## `tensorless info`
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
tensorless info <model.tl>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Prints a JSON summary of a trained model: task, model type, versions,
|
|
67
|
+
whether training completed, final metrics, and a truncated dataset
|
|
68
|
+
fingerprint.
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"task": "classification",
|
|
73
|
+
"model_type": "mlp",
|
|
74
|
+
"tensorless_version": "0.1.0",
|
|
75
|
+
"tl_format_version": 1,
|
|
76
|
+
"training_complete": true,
|
|
77
|
+
"metrics": {"final_train_loss": 0.42, "final_val_loss": 0.51, "global_step": 96, "elapsed_seconds": 0.14},
|
|
78
|
+
"dataset_fingerprint": "de779ad33e2dc1d4"
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Exit codes
|
|
83
|
+
|
|
84
|
+
All commands return `0` on success. Errors raised as `TensorlessError`
|
|
85
|
+
subclasses (bad data, bad config, corrupt checkpoint/model, etc.) are
|
|
86
|
+
caught, printed to stderr as `tensorless: error: <message>`, and result
|
|
87
|
+
in exit code `1`.
|