@tuned-tensor/local 0.1.9 → 0.2.1
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.
- package/CHANGELOG.md +21 -0
- package/README.md +10 -407
- package/dist/contracts.d.ts +19 -3
- package/dist/contracts.js +9 -4
- package/dist/contracts.js.map +1 -1
- package/dist/doctor.js +41 -24
- package/dist/doctor.js.map +1 -1
- package/dist/evaluation.js +30 -16
- package/dist/evaluation.js.map +1 -1
- package/dist/orchestrator.js +1 -1
- package/dist/orchestrator.js.map +1 -1
- package/dist/process-runner.d.ts +11 -0
- package/dist/process-runner.js +22 -0
- package/dist/process-runner.js.map +1 -1
- package/dist/process-training.js +16 -15
- package/dist/process-training.js.map +1 -1
- package/dist/store.d.ts +3 -10
- package/dist/store.js +244 -33
- package/dist/store.js.map +1 -1
- package/docs/architecture.md +30 -18
- package/docs/spark.md +29 -1
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to TT Local will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.2.1 - 2026-07-04
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added command-based local training with `training.backend: "command"` and
|
|
10
|
+
`training.command`, while preserving the existing uv script/module path.
|
|
11
|
+
- Added `evaluation.inference.provider: "batch_command"` with
|
|
12
|
+
`evaluation.inference.command` for custom batch evaluators that consume the
|
|
13
|
+
same `--input`/`--output` JSON files as the bundled Transformers evaluator.
|
|
14
|
+
|
|
15
|
+
## 0.2.0 - 2026-07-04
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Added a hybrid local state store: `metadata.sqlite` now indexes specs, runs,
|
|
20
|
+
run events, and models for CLI/dashboard queries while preserving the
|
|
21
|
+
transparent JSON/JSONL artifact layout. `tt-local store rebuild-index`
|
|
22
|
+
rebuilds SQLite metadata from canonical per-object files. The SQLite index
|
|
23
|
+
uses `better-sqlite3` instead of Node's experimental built-in SQLite API,
|
|
24
|
+
avoiding runtime experimental warnings on Node 22.
|
|
25
|
+
|
|
5
26
|
## 0.1.9 - 2026-07-03
|
|
6
27
|
|
|
7
28
|
### Added
|
package/README.md
CHANGED
|
@@ -1,419 +1,33 @@
|
|
|
1
1
|
# TT Local
|
|
2
2
|
|
|
3
|
-
Tuning tensors locally.
|
|
4
|
-
|
|
5
3
|
[](https://github.com/tunedtensor/tuned-tensor-local/actions/workflows/ci.yml)
|
|
6
4
|
[](https://www.npmjs.com/package/@tuned-tensor/local)
|
|
7
5
|
|
|
8
|
-
TT Local
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
It does not require the hosted Tuned Tensor CLI, cloud orchestration, Docker,
|
|
13
|
-
or a managed database.
|
|
14
|
-
|
|
15
|
-
## What Happens In A Run
|
|
6
|
+
TT Local runs Tuned Tensor-style fine-tuning jobs on your own machine. It keeps
|
|
7
|
+
specs, datasets, model artifacts, events, reports, and dashboard state on local
|
|
8
|
+
disk.
|
|
16
9
|
|
|
17
|
-
|
|
10
|
+
Usage docs:
|
|
18
11
|
|
|
19
|
-
|
|
20
|
-
2. Compile examples into a local training dataset.
|
|
21
|
-
3. Evaluate the original Hugging Face base model.
|
|
22
|
-
4. Fine-tune locally with uv, Transformers, and PEFT.
|
|
23
|
-
5. Evaluate the fine-tuned Hugging Face/PEFT artifact.
|
|
24
|
-
6. Compare baseline vs tuned outputs and write a report.
|
|
25
|
-
|
|
26
|
-
OpenRouter can optionally score generated outputs as an LLM judge. It does not
|
|
27
|
-
generate the baseline or tuned responses.
|
|
12
|
+
https://tunedtensor.com/docs/local-training
|
|
28
13
|
|
|
29
14
|
## Install
|
|
30
15
|
|
|
31
|
-
Install the published CLI:
|
|
32
|
-
|
|
33
16
|
```bash
|
|
34
17
|
npm install -g @tuned-tensor/local
|
|
35
18
|
tt-local info
|
|
36
19
|
```
|
|
37
20
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
git clone https://github.com/tunedtensor/tuned-tensor-local.git
|
|
42
|
-
cd tuned-tensor-local
|
|
43
|
-
npm install
|
|
44
|
-
npm run build
|
|
45
|
-
npm link
|
|
46
|
-
tt-local info
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Real training also needs `uv`:
|
|
21
|
+
The bundled SFT and Transformers evaluator path also needs `uv`:
|
|
50
22
|
|
|
51
23
|
```bash
|
|
52
24
|
uv --version
|
|
53
25
|
```
|
|
54
26
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## First Run: Safe Dry Run
|
|
62
|
-
|
|
63
|
-
The included example config is a dry run. It validates the end-to-end local
|
|
64
|
-
workflow and writes artifacts without downloading models or starting GPU
|
|
65
|
-
training.
|
|
66
|
-
|
|
67
|
-
Create a local behavior spec:
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
tt-local init --name "Support Bot" --model Qwen/Qwen3.5-2B
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Edit `tunedtensor.json` and replace the placeholder example with your task:
|
|
27
|
+
Custom training or evaluation workflows can use command entrypoints instead of
|
|
28
|
+
`uv`.
|
|
74
29
|
|
|
75
|
-
|
|
76
|
-
{
|
|
77
|
-
"input": "Classify sentiment: I love this product.",
|
|
78
|
-
"output": "positive"
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Validate the spec and config:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
tt-local validate --config examples/local-runner.json
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Run the dry workflow:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
tt-local run --config examples/local-runner.json
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Inspect the result:
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
tt-local runs list --config examples/local-runner.json
|
|
98
|
-
tt-local runs report <run-id> --config examples/local-runner.json
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
Start the local dashboard:
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
tt-local serve --config examples/local-runner.json
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Open the printed local URL in your browser.
|
|
108
|
-
|
|
109
|
-
## Run Real Training
|
|
110
|
-
|
|
111
|
-
Create a config such as `local-runner.json` or `spark-runner.json`:
|
|
112
|
-
|
|
113
|
-
```json
|
|
114
|
-
{
|
|
115
|
-
"artifactRoot": "/home/eve/tt-local-artifacts",
|
|
116
|
-
"storeRoot": "/home/eve/tt-local-store",
|
|
117
|
-
"dryRun": false,
|
|
118
|
-
"training": {
|
|
119
|
-
"backend": "uv",
|
|
120
|
-
"project": "training/sft-local",
|
|
121
|
-
"script": "training/sft-local/src/train.py"
|
|
122
|
-
},
|
|
123
|
-
"evaluation": {
|
|
124
|
-
"inference": {
|
|
125
|
-
"provider": "transformers",
|
|
126
|
-
"project": "training/sft-local",
|
|
127
|
-
"script": "training/sft-local/src/evaluate.py",
|
|
128
|
-
"maxNewTokens": 256,
|
|
129
|
-
"temperature": 0,
|
|
130
|
-
"topP": 1
|
|
131
|
-
},
|
|
132
|
-
"scoring": {
|
|
133
|
-
"mode": "llm_judge",
|
|
134
|
-
"fallback": "exact_match"
|
|
135
|
-
},
|
|
136
|
-
"maxExamples": 10
|
|
137
|
-
},
|
|
138
|
-
"paths": {
|
|
139
|
-
"modelCache": "/home/eve/.cache/huggingface"
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
If you use OpenRouter judging, set an API key:
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
export OPENROUTER_API_KEY="your_openrouter_key"
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
`tt-local` also loads a `.env` file from the working directory. Existing
|
|
151
|
-
environment variables win.
|
|
152
|
-
|
|
153
|
-
Run the job:
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
tt-local doctor --config spark-runner.json
|
|
157
|
-
tt-local validate --config spark-runner.json
|
|
158
|
-
tt-local run --config spark-runner.json
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
`tt-local run` prints live stage updates to stderr and writes the final JSON
|
|
162
|
-
summary to stdout. Use `--verbose` to stream Python subprocess output, or
|
|
163
|
-
`--quiet` for JSON-only automation.
|
|
164
|
-
|
|
165
|
-
Watch progress:
|
|
166
|
-
|
|
167
|
-
```bash
|
|
168
|
-
tt-local runs watch <run-id> --config spark-runner.json
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
View the final report:
|
|
172
|
-
|
|
173
|
-
```bash
|
|
174
|
-
tt-local runs report <run-id> --config spark-runner.json
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
Compare two completed runs:
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
tt-local runs compare <run-id-a> <run-id-b> --config spark-runner.json
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
The comparison aligns shared eval prompts, separates newly added eval examples,
|
|
184
|
-
and measures judge score noise for identical baseline outputs.
|
|
185
|
-
|
|
186
|
-
## Configuration Basics
|
|
187
|
-
|
|
188
|
-
The main config fields are:
|
|
189
|
-
|
|
190
|
-
- `artifactRoot`: datasets, logs, model outputs, eval JSON, and run reports.
|
|
191
|
-
- `storeRoot`: run/spec/model metadata used by CLI listing and the dashboard.
|
|
192
|
-
- `dryRun`: when `true`, skips model loading and training.
|
|
193
|
-
- `training`: uv/Python training entrypoint and environment.
|
|
194
|
-
- `evaluation.inference`: how baseline and candidate outputs are generated.
|
|
195
|
-
- `evaluation.scoring`: how generated outputs are scored.
|
|
196
|
-
- `paths.modelCache`: Hugging Face cache location.
|
|
197
|
-
|
|
198
|
-
Supported inference providers:
|
|
199
|
-
|
|
200
|
-
- `"transformers"`: run the included local evaluator with Hugging Face/PEFT.
|
|
201
|
-
- `"command"`: call `baselineCommand` or `candidateCommand` for custom inference.
|
|
202
|
-
- `"none"`: skip inference and record empty local responses.
|
|
203
|
-
|
|
204
|
-
Supported scoring modes:
|
|
205
|
-
|
|
206
|
-
- `"exact_match"`: normalized exact match.
|
|
207
|
-
- `"llm_judge"`: OpenRouter judge, with exact-match fallback by default.
|
|
208
|
-
- `"json_fields"`: field-level comparison for structured JSON outputs.
|
|
209
|
-
|
|
210
|
-
When `evaluation.scoring.mode` is `"llm_judge"`, `fallback` controls judge
|
|
211
|
-
failures. `"exact_match"` keeps the run going and records fallback reasoning.
|
|
212
|
-
`"fail"` fails the run.
|
|
213
|
-
|
|
214
|
-
## Evaluation Behavior
|
|
215
|
-
|
|
216
|
-
`evaluation.maxExamples` caps how many examples are scored. If it is unset,
|
|
217
|
-
the request hyperparameter `max_eval_examples` is used. An explicit
|
|
218
|
-
`maxExamples` in the config wins. When capped, the runner uses a deterministic
|
|
219
|
-
seeded sample rather than a prefix, so sorted or grouped eval files do not
|
|
220
|
-
bias results. The seed defaults to a hash of the run id and can be pinned with
|
|
221
|
-
`evaluation.sampleSeed`.
|
|
222
|
-
|
|
223
|
-
For spec-based runs without `dataset_prebuilt`, the runner holds out about 20%
|
|
224
|
-
of the spec examples for evaluation, with at least one training example and one
|
|
225
|
-
holdout when possible. With only one spec example, evaluation runs on that
|
|
226
|
-
example and reports `eval_split: "spec_examples"`.
|
|
227
|
-
|
|
228
|
-
For prebuilt datasets, `dataset_prebuilt.training` is always copied into the
|
|
229
|
-
run artifact as the training set. Evaluation uses `dataset_prebuilt.test` when
|
|
230
|
-
present, then `dataset_prebuilt.validation`. If neither is provided, a real
|
|
231
|
-
run fails because evaluation would otherwise measure the training split. Set
|
|
232
|
-
`evaluation.allowPrebuiltTrainingEval: true` to allow that explicitly.
|
|
233
|
-
|
|
234
|
-
Baseline evaluations are cached under `<storeRoot>/cache/baseline-evals/`.
|
|
235
|
-
Re-running an unchanged spec with the same model, eval examples, generation
|
|
236
|
-
settings, and scoring config reuses the previous baseline report. Set
|
|
237
|
-
`evaluation.baselineCache: false` to disable.
|
|
238
|
-
|
|
239
|
-
Training progress from Python metric lines and tqdm progress bars is recorded
|
|
240
|
-
as run events, so `tt-local runs watch` and per-run `progress.jsonl` show
|
|
241
|
-
epoch, loss, step, percentage, and ETA when the trainer emits them.
|
|
242
|
-
|
|
243
|
-
## Structured JSON Scoring
|
|
244
|
-
|
|
245
|
-
For structured tasks, use field-level scoring instead of whole-output exact
|
|
246
|
-
matching:
|
|
247
|
-
|
|
248
|
-
```json
|
|
249
|
-
{
|
|
250
|
-
"evaluation": {
|
|
251
|
-
"scoring": {
|
|
252
|
-
"mode": "json_fields",
|
|
253
|
-
"fields": ["triage", "priority", "should_process"]
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
If `fields` is omitted, the evaluator scores every key in the expected JSON
|
|
260
|
-
object. A configured field missing from the expected JSON is always scored as
|
|
261
|
-
incorrect, so a misconfigured field list cannot inflate scores.
|
|
262
|
-
|
|
263
|
-
Reports still include `exact_match_rate`, but `avg_score`, `pass_rate`, and
|
|
264
|
-
`json_field_metrics` are based on the selected JSON fields.
|
|
265
|
-
|
|
266
|
-
## Labeling Data With A Teacher Model
|
|
267
|
-
|
|
268
|
-
`tt-local label` turns unlabeled inputs into training examples by asking a
|
|
269
|
-
stronger teacher model on OpenRouter to answer each row under your spec's
|
|
270
|
-
system message — the same instructions the fine-tuned model will see at
|
|
271
|
-
inference:
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
export OPENROUTER_API_KEY=... # or put it in .env
|
|
275
|
-
tt-local label rows.jsonl --output labeled.jsonl
|
|
276
|
-
tt-local label rows.csv --input-column text --model anthropic/claude-fable-5
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
Sources are JSONL (`{"input": "..."}` per line; rows that already carry an
|
|
280
|
-
`"output"` skip the teacher) or CSV with a header row and `--input-column`.
|
|
281
|
-
The system message comes from `tunedtensor.json` (or `--spec <path>`);
|
|
282
|
-
pass `--system-prompt "..."` to override it. Use `--dry-run` to parse,
|
|
283
|
-
sanitize, and estimate without calling the teacher.
|
|
284
|
-
|
|
285
|
-
Because rows are sent to OpenRouter, each row is sanitized first:
|
|
286
|
-
secret-like content (API keys, private keys, connection strings) blocks the
|
|
287
|
-
row, and PII (emails, phone numbers, SSNs, card numbers) is redacted before
|
|
288
|
-
sending. The labeled `{"input", "output"}` JSONL, a full per-row
|
|
289
|
-
`rows.jsonl` (including failures for review), and a job report are written
|
|
290
|
-
under `<artifactRoot>/labeling/<job-id>/`.
|
|
291
|
-
|
|
292
|
-
Teacher behavior is configured in the runner config; the model falls back to
|
|
293
|
-
`llm.model`:
|
|
294
|
-
|
|
295
|
-
```json
|
|
296
|
-
{
|
|
297
|
-
"labeling": {
|
|
298
|
-
"model": "anthropic/claude-fable-5",
|
|
299
|
-
"maxTokens": 2048,
|
|
300
|
-
"temperature": 0.2,
|
|
301
|
-
"concurrency": 4,
|
|
302
|
-
"maxAttempts": 3
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
## Thinking-Mode Models
|
|
308
|
-
|
|
309
|
-
Some models, such as `Qwen/Qwen3.5-4B`, may open a hidden thinking block by
|
|
310
|
-
default and consume the token budget before producing a visible answer. Forward
|
|
311
|
-
template kwargs to both evaluation and training:
|
|
312
|
-
|
|
313
|
-
```json
|
|
314
|
-
{
|
|
315
|
-
"evaluation": {
|
|
316
|
-
"inference": {
|
|
317
|
-
"chatTemplateKwargs": { "enable_thinking": false }
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
In `tunedtensor.json`, also set:
|
|
324
|
-
|
|
325
|
-
```json
|
|
326
|
-
{
|
|
327
|
-
"hyperparameters": {
|
|
328
|
-
"chat_template_kwargs": { "enable_thinking": false }
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
## Multimodal Examples
|
|
334
|
-
|
|
335
|
-
Multimodal runs use chat JSONL with structured user content. For
|
|
336
|
-
`image_text_to_text` models such as `Qwen/Qwen3-VL-2B-Instruct`, image parts
|
|
337
|
-
are loaded by the local trainer and evaluator:
|
|
338
|
-
|
|
339
|
-
```json
|
|
340
|
-
{
|
|
341
|
-
"messages": [
|
|
342
|
-
{ "role": "system", "content": "Answer chart questions concisely." },
|
|
343
|
-
{
|
|
344
|
-
"role": "user",
|
|
345
|
-
"content": [
|
|
346
|
-
{ "type": "image", "image": "charts/example.png" },
|
|
347
|
-
{ "type": "text", "text": "What is the blue value?" }
|
|
348
|
-
]
|
|
349
|
-
},
|
|
350
|
-
{ "role": "assistant", "content": "42" }
|
|
351
|
-
]
|
|
352
|
-
}
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
Image values in prebuilt JSONL may be absolute paths, paths relative to the
|
|
356
|
-
JSONL file, `file://` URIs, HTTP(S) URLs, or `data:` URIs. Behavior spec
|
|
357
|
-
examples can also use `input_assets` with `image`, `path`, `uri`, or
|
|
358
|
-
`data_uri`.
|
|
359
|
-
|
|
360
|
-
## Where Files Go
|
|
361
|
-
|
|
362
|
-
If `storeRoot` is omitted, `tt-local` uses `TT_LOCAL_HOME` or
|
|
363
|
-
`~/.tuned-tensor-local`.
|
|
364
|
-
|
|
365
|
-
Per-run artifacts include:
|
|
366
|
-
|
|
367
|
-
- `progress.jsonl`: stage changes and parsed training progress.
|
|
368
|
-
- `baseline-eval.json` and `candidate-eval.json`: generated outputs and scores.
|
|
369
|
-
- `baseline-eval.json.inference.log` and `candidate-eval.json.inference.log`:
|
|
370
|
-
local inference subprocess output.
|
|
371
|
-
- `training/training.log`: uv fine-tuning output.
|
|
372
|
-
- `run-report.json`: baseline, candidate, comparison, and artifact references.
|
|
373
|
-
|
|
374
|
-
## Useful Commands
|
|
375
|
-
|
|
376
|
-
```bash
|
|
377
|
-
tt-local init --name "Support Bot" --model Qwen/Qwen3.5-2B
|
|
378
|
-
tt-local doctor --config spark-runner.json
|
|
379
|
-
tt-local validate --config spark-runner.json
|
|
380
|
-
tt-local run --config spark-runner.json
|
|
381
|
-
tt-local run --config spark-runner.json --verbose
|
|
382
|
-
tt-local label rows.jsonl --output labeled.jsonl
|
|
383
|
-
tt-local runs list --config spark-runner.json
|
|
384
|
-
tt-local runs get <run-id> --config spark-runner.json
|
|
385
|
-
tt-local runs events <run-id> --config spark-runner.json
|
|
386
|
-
tt-local runs watch <run-id> --config spark-runner.json
|
|
387
|
-
tt-local runs report <run-id> --config spark-runner.json
|
|
388
|
-
tt-local runs compare <run-id-a> <run-id-b> --config spark-runner.json
|
|
389
|
-
tt-local models list --config spark-runner.json
|
|
390
|
-
tt-local serve --config spark-runner.json
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
## DGX Spark Notes
|
|
394
|
-
|
|
395
|
-
On the Spark host, confirm the GPU and uv are available:
|
|
396
|
-
|
|
397
|
-
```bash
|
|
398
|
-
nvidia-smi
|
|
399
|
-
uv --version
|
|
400
|
-
uv run python --version
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
Then clone, install, build, and link the CLI on the Spark:
|
|
404
|
-
|
|
405
|
-
```bash
|
|
406
|
-
git clone https://github.com/tunedtensor/tuned-tensor-local.git
|
|
407
|
-
cd tuned-tensor-local
|
|
408
|
-
npm install
|
|
409
|
-
npm run build
|
|
410
|
-
npm link
|
|
411
|
-
tt-local doctor --config examples/local-runner.json
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
Spark-specific details live in [docs/spark.md](docs/spark.md).
|
|
415
|
-
|
|
416
|
-
## Development
|
|
30
|
+
## Local Development
|
|
417
31
|
|
|
418
32
|
```bash
|
|
419
33
|
npm install
|
|
@@ -422,18 +36,7 @@ npm test
|
|
|
422
36
|
npm run build
|
|
423
37
|
```
|
|
424
38
|
|
|
425
|
-
|
|
426
|
-
runs when a GitHub Release is published and requires an `NPM_TOKEN` repository
|
|
427
|
-
secret.
|
|
428
|
-
|
|
429
|
-
## Notes
|
|
430
|
-
|
|
431
|
-
- Real training uses `training/sft-local/src/train.py`.
|
|
432
|
-
- Real evaluation uses `training/sft-local/src/evaluate.py`.
|
|
433
|
-
- The default evaluation path uses Hugging Face/PEFT artifacts directly; it
|
|
434
|
-
does not convert models to GGUF.
|
|
435
|
-
- `validate` and `run` warn about unknown hyperparameter keys and ignore them.
|
|
436
|
-
- Release notes are in [CHANGELOG.md](CHANGELOG.md).
|
|
39
|
+
Release notes are in [CHANGELOG.md](CHANGELOG.md).
|
|
437
40
|
|
|
438
41
|
## License
|
|
439
42
|
|
package/dist/contracts.d.ts
CHANGED
|
@@ -271,6 +271,7 @@ export declare const evalReportSchema: z.ZodObject<{
|
|
|
271
271
|
inference_provider: z.ZodOptional<z.ZodEnum<{
|
|
272
272
|
command: "command";
|
|
273
273
|
none: "none";
|
|
274
|
+
batch_command: "batch_command";
|
|
274
275
|
transformers: "transformers";
|
|
275
276
|
}>>;
|
|
276
277
|
scoring_mode: z.ZodOptional<z.ZodEnum<{
|
|
@@ -331,7 +332,10 @@ export declare const comparisonReportSchema: z.ZodObject<{
|
|
|
331
332
|
}, z.core.$strip>>;
|
|
332
333
|
}, z.core.$strip>;
|
|
333
334
|
export declare const trainingReportSchema: z.ZodObject<{
|
|
334
|
-
provider: z.
|
|
335
|
+
provider: z.ZodEnum<{
|
|
336
|
+
"local-uv": "local-uv";
|
|
337
|
+
"local-command": "local-command";
|
|
338
|
+
}>;
|
|
335
339
|
training_job_name: z.ZodString;
|
|
336
340
|
model_artifact_uri: z.ZodOptional<z.ZodString>;
|
|
337
341
|
base_model_artifact_uri: z.ZodOptional<z.ZodString>;
|
|
@@ -407,6 +411,7 @@ export declare const runReportSchema: z.ZodObject<{
|
|
|
407
411
|
inference_provider: z.ZodOptional<z.ZodEnum<{
|
|
408
412
|
command: "command";
|
|
409
413
|
none: "none";
|
|
414
|
+
batch_command: "batch_command";
|
|
410
415
|
transformers: "transformers";
|
|
411
416
|
}>>;
|
|
412
417
|
scoring_mode: z.ZodOptional<z.ZodEnum<{
|
|
@@ -487,6 +492,7 @@ export declare const runReportSchema: z.ZodObject<{
|
|
|
487
492
|
inference_provider: z.ZodOptional<z.ZodEnum<{
|
|
488
493
|
command: "command";
|
|
489
494
|
none: "none";
|
|
495
|
+
batch_command: "batch_command";
|
|
490
496
|
transformers: "transformers";
|
|
491
497
|
}>>;
|
|
492
498
|
scoring_mode: z.ZodOptional<z.ZodEnum<{
|
|
@@ -540,7 +546,10 @@ export declare const runReportSchema: z.ZodObject<{
|
|
|
540
546
|
}, z.core.$strip>>;
|
|
541
547
|
}, z.core.$strip>;
|
|
542
548
|
training: z.ZodObject<{
|
|
543
|
-
provider: z.
|
|
549
|
+
provider: z.ZodEnum<{
|
|
550
|
+
"local-uv": "local-uv";
|
|
551
|
+
"local-command": "local-command";
|
|
552
|
+
}>;
|
|
544
553
|
training_job_name: z.ZodString;
|
|
545
554
|
model_artifact_uri: z.ZodOptional<z.ZodString>;
|
|
546
555
|
base_model_artifact_uri: z.ZodOptional<z.ZodString>;
|
|
@@ -595,7 +604,11 @@ export declare const localRunnerConfigSchema: z.ZodObject<{
|
|
|
595
604
|
artifactRoot: z.ZodDefault<z.ZodString>;
|
|
596
605
|
dryRun: z.ZodDefault<z.ZodBoolean>;
|
|
597
606
|
training: z.ZodDefault<z.ZodObject<{
|
|
598
|
-
backend: z.ZodDefault<z.
|
|
607
|
+
backend: z.ZodDefault<z.ZodEnum<{
|
|
608
|
+
command: "command";
|
|
609
|
+
uv: "uv";
|
|
610
|
+
}>>;
|
|
611
|
+
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
599
612
|
project: z.ZodOptional<z.ZodString>;
|
|
600
613
|
cwd: z.ZodOptional<z.ZodString>;
|
|
601
614
|
module: z.ZodOptional<z.ZodString>;
|
|
@@ -615,12 +628,15 @@ export declare const localRunnerConfigSchema: z.ZodObject<{
|
|
|
615
628
|
provider: z.ZodDefault<z.ZodEnum<{
|
|
616
629
|
command: "command";
|
|
617
630
|
none: "none";
|
|
631
|
+
batch_command: "batch_command";
|
|
618
632
|
transformers: "transformers";
|
|
619
633
|
}>>;
|
|
634
|
+
command: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
620
635
|
project: z.ZodOptional<z.ZodString>;
|
|
621
636
|
cwd: z.ZodOptional<z.ZodString>;
|
|
622
637
|
module: z.ZodOptional<z.ZodString>;
|
|
623
638
|
script: z.ZodDefault<z.ZodString>;
|
|
639
|
+
args: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
624
640
|
with: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
625
641
|
env: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
626
642
|
maxNewTokens: z.ZodDefault<z.ZodNumber>;
|
package/dist/contracts.js
CHANGED
|
@@ -133,7 +133,7 @@ export const evalReportSchema = z.object({
|
|
|
133
133
|
artifact_uri: z.string(),
|
|
134
134
|
scoring_method: z.enum(["heuristic", "command", "llm_judge", "exact_match", "json_fields"]),
|
|
135
135
|
judge_model_id: z.string().nullable().optional(),
|
|
136
|
-
inference_provider: z.enum(["none", "command", "transformers"]).optional(),
|
|
136
|
+
inference_provider: z.enum(["none", "command", "batch_command", "transformers"]).optional(),
|
|
137
137
|
scoring_mode: z.enum(["exact_match", "llm_judge", "json_fields"]).optional(),
|
|
138
138
|
json_field_metrics: jsonFieldMetricsSchema.optional(),
|
|
139
139
|
generation_config: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -157,7 +157,7 @@ export const comparisonReportSchema = z.object({
|
|
|
157
157
|
})),
|
|
158
158
|
});
|
|
159
159
|
export const trainingReportSchema = z.object({
|
|
160
|
-
provider: z.
|
|
160
|
+
provider: z.enum(["local-uv", "local-command"]),
|
|
161
161
|
training_job_name: z.string(),
|
|
162
162
|
model_artifact_uri: z.string().optional(),
|
|
163
163
|
base_model_artifact_uri: z.string().optional(),
|
|
@@ -220,7 +220,8 @@ export const localRunnerConfigSchema = z.object({
|
|
|
220
220
|
artifactRoot: z.string().default(".tt-local/artifacts"),
|
|
221
221
|
dryRun: z.boolean().default(false),
|
|
222
222
|
training: z.object({
|
|
223
|
-
backend: z.
|
|
223
|
+
backend: z.enum(["uv", "command"]).default("uv"),
|
|
224
|
+
command: commandSchema.optional(),
|
|
224
225
|
project: z.string().optional(),
|
|
225
226
|
cwd: z.string().optional(),
|
|
226
227
|
module: z.string().optional(),
|
|
@@ -242,11 +243,13 @@ export const localRunnerConfigSchema = z.object({
|
|
|
242
243
|
baselineCommand: commandSchema.optional(),
|
|
243
244
|
candidateCommand: commandSchema.optional(),
|
|
244
245
|
inference: z.object({
|
|
245
|
-
provider: z.enum(["transformers", "command", "none"]).default("transformers"),
|
|
246
|
+
provider: z.enum(["transformers", "batch_command", "command", "none"]).default("transformers"),
|
|
247
|
+
command: commandSchema.optional(),
|
|
246
248
|
project: z.string().optional(),
|
|
247
249
|
cwd: z.string().optional(),
|
|
248
250
|
module: z.string().optional(),
|
|
249
251
|
script: z.string().default("training/sft-local/src/evaluate.py"),
|
|
252
|
+
args: z.array(z.string()).default([]),
|
|
250
253
|
with: z.array(z.string()).default([]),
|
|
251
254
|
env: z.record(z.string(), z.string()).default({}),
|
|
252
255
|
maxNewTokens: z.number().int().min(1).default(256),
|
|
@@ -258,6 +261,7 @@ export const localRunnerConfigSchema = z.object({
|
|
|
258
261
|
}).default({
|
|
259
262
|
provider: "transformers",
|
|
260
263
|
script: "training/sft-local/src/evaluate.py",
|
|
264
|
+
args: [],
|
|
261
265
|
with: [],
|
|
262
266
|
env: {},
|
|
263
267
|
maxNewTokens: 256,
|
|
@@ -283,6 +287,7 @@ export const localRunnerConfigSchema = z.object({
|
|
|
283
287
|
inference: {
|
|
284
288
|
provider: "transformers",
|
|
285
289
|
script: "training/sft-local/src/evaluate.py",
|
|
290
|
+
args: [],
|
|
286
291
|
with: [],
|
|
287
292
|
env: {},
|
|
288
293
|
maxNewTokens: 256,
|