@tuned-tensor/cli 0.13.1-beta.4 → 0.13.1-beta.6
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/README.md +22 -8
- package/dist/{chunk-7VIUHQBI.js → chunk-W7MOBPCO.js} +1544 -814
- package/dist/chunk-W7MOBPCO.js.map +1 -0
- package/dist/index.js +275 -33
- package/dist/index.js.map +1 -1
- package/dist/local-runtime.js +99 -6
- package/dist/local-runtime.js.map +1 -1
- package/docs/local-runtime/architecture.md +10 -6
- package/docs/local-runtime/foundation-long-runs.md +108 -0
- package/docs/local-runtime/spark.md +6 -0
- package/package.json +1 -1
- package/training/foundation/src/checkpoint.py +235 -0
- package/training/foundation/src/common.py +30 -2
- package/training/foundation/src/data.py +89 -3
- package/training/foundation/src/evaluate.py +10 -2
- package/training/foundation/src/pretrain.py +426 -27
- package/training/foundation/src/train_tokenizer.py +29 -5
- package/dist/chunk-7VIUHQBI.js.map +0 -1
package/dist/local-runtime.js
CHANGED
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
assertFoundationSpecReady,
|
|
6
6
|
assertLocalRunInputReady,
|
|
7
7
|
assertUsableModelArtifact,
|
|
8
|
+
assessHardware,
|
|
8
9
|
baseModelRevisionSchema,
|
|
9
10
|
behaviorSpecExampleSchema,
|
|
10
11
|
buildBundledPythonCommand,
|
|
12
|
+
buildFoundationPythonCommand,
|
|
11
13
|
buildModelPrefetchPayload,
|
|
12
14
|
buildSystemMessage,
|
|
13
15
|
canonicalLocalPipeline,
|
|
@@ -46,6 +48,7 @@ import {
|
|
|
46
48
|
localAdapterSpecFileSchema,
|
|
47
49
|
localBehaviorSpecFileSchema,
|
|
48
50
|
localFoundationSpecFileSchema,
|
|
51
|
+
localPathsOverlap,
|
|
49
52
|
localRunnerConfigSchema,
|
|
50
53
|
localRuntimePackageRoot,
|
|
51
54
|
localStorePaths,
|
|
@@ -70,10 +73,11 @@ import {
|
|
|
70
73
|
verifyLocalBaseModel,
|
|
71
74
|
verifyModelPrefetchCacheReport,
|
|
72
75
|
withBundledPythonEnvironment,
|
|
76
|
+
withFoundationPythonEnvironment,
|
|
73
77
|
withHuggingFaceCacheEnvironment,
|
|
74
78
|
withOfflineHuggingFaceCacheEnvironment,
|
|
75
79
|
writePrivateJsonAtomic
|
|
76
|
-
} from "./chunk-
|
|
80
|
+
} from "./chunk-W7MOBPCO.js";
|
|
77
81
|
|
|
78
82
|
// src/local-runtime/index.ts
|
|
79
83
|
import { readFileSync, realpathSync } from "fs";
|
|
@@ -145,7 +149,7 @@ function compareRuns(a, b) {
|
|
|
145
149
|
|
|
146
150
|
// src/local-runtime/doctor.ts
|
|
147
151
|
import { constants } from "fs";
|
|
148
|
-
import { access, mkdir, statfs, unlink, writeFile } from "fs/promises";
|
|
152
|
+
import { access, lstat, mkdir, statfs, unlink, writeFile } from "fs/promises";
|
|
149
153
|
import { homedir } from "os";
|
|
150
154
|
import { join, resolve } from "path";
|
|
151
155
|
import { spawn } from "child_process";
|
|
@@ -265,6 +269,23 @@ async function writableDirectoryCheck(name, path) {
|
|
|
265
269
|
};
|
|
266
270
|
}
|
|
267
271
|
}
|
|
272
|
+
function foundationPythonProbePlan(requireBf16) {
|
|
273
|
+
const source = [
|
|
274
|
+
"import json",
|
|
275
|
+
"import numpy, safetensors, tokenizers, torch",
|
|
276
|
+
"assert torch.cuda.is_available(), 'TT Foundation training requires CUDA but torch.cuda.is_available() is false'",
|
|
277
|
+
...requireBf16 ? ["assert torch.cuda.is_bf16_supported(), 'TT Foundation BF16 training was requested but this device does not support BF16'"] : [],
|
|
278
|
+
"props = torch.cuda.get_device_properties(0)",
|
|
279
|
+
"print(json.dumps({'python_ok': True, 'torch': torch.__version__, 'cuda_available': True, 'bf16': torch.cuda.is_bf16_supported(), 'cuda_device': torch.cuda.get_device_name(0), 'compute_capability': list(torch.cuda.get_device_capability(0)), 'total_memory_bytes': props.total_memory}))"
|
|
280
|
+
].join("; ");
|
|
281
|
+
const entrypoint = buildFoundationPythonCommand("-c", [source]);
|
|
282
|
+
return {
|
|
283
|
+
name: "python-runtime",
|
|
284
|
+
command: entrypoint.command,
|
|
285
|
+
args: entrypoint.commandArgs,
|
|
286
|
+
env: withFoundationPythonEnvironment(process.env)
|
|
287
|
+
};
|
|
288
|
+
}
|
|
268
289
|
function pythonProbeSource(device) {
|
|
269
290
|
return [
|
|
270
291
|
"import json",
|
|
@@ -310,6 +331,26 @@ function foundationPlaceholderCheck(spec) {
|
|
|
310
331
|
message: issues.length > 0 ? "The spec still contains generated placeholder content; edit it before training." : `${spec.examples.length} spec example(s); foundation engine`
|
|
311
332
|
};
|
|
312
333
|
}
|
|
334
|
+
async function foundationCorpusCheck(name, path) {
|
|
335
|
+
const resolvedPath = resolve(path);
|
|
336
|
+
try {
|
|
337
|
+
const info = await lstat(resolvedPath);
|
|
338
|
+
const supported = info.isFile() || info.isDirectory();
|
|
339
|
+
return {
|
|
340
|
+
name,
|
|
341
|
+
ok: supported && !info.isSymbolicLink(),
|
|
342
|
+
message: supported && !info.isSymbolicLink() ? `${resolvedPath} is available for streaming.` : `${resolvedPath} must be a regular file or directory, not a symbolic link.`,
|
|
343
|
+
details: { path: resolvedPath }
|
|
344
|
+
};
|
|
345
|
+
} catch (error) {
|
|
346
|
+
return {
|
|
347
|
+
name,
|
|
348
|
+
ok: false,
|
|
349
|
+
message: `${resolvedPath}: ${error instanceof Error ? error.message : String(error)}`,
|
|
350
|
+
details: { path: resolvedPath }
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
}
|
|
313
354
|
function placeholderSpecCheck(request) {
|
|
314
355
|
const placeholder = request.spec_snapshot.examples.some(
|
|
315
356
|
(example) => /replace this with/i.test(example.input) || /replace this with/i.test(example.output)
|
|
@@ -359,11 +400,33 @@ async function runDoctor(config, request, foundationSpec) {
|
|
|
359
400
|
}
|
|
360
401
|
if (foundationSpec) {
|
|
361
402
|
checks.push(foundationPlaceholderCheck(foundationSpec));
|
|
403
|
+
if (foundationSpec.foundation.corpus_path) {
|
|
404
|
+
checks.push(await foundationCorpusCheck("pretraining-corpus", foundationSpec.foundation.corpus_path));
|
|
405
|
+
}
|
|
406
|
+
if (foundationSpec.foundation.validation_path) {
|
|
407
|
+
checks.push(await foundationCorpusCheck("validation-corpus", foundationSpec.foundation.validation_path));
|
|
408
|
+
}
|
|
409
|
+
if (foundationSpec.foundation.corpus_path && foundationSpec.foundation.validation_path && localPathsOverlap(
|
|
410
|
+
foundationSpec.foundation.corpus_path,
|
|
411
|
+
foundationSpec.foundation.validation_path
|
|
412
|
+
)) {
|
|
413
|
+
checks.push({
|
|
414
|
+
name: "held-out-corpus",
|
|
415
|
+
ok: false,
|
|
416
|
+
message: "foundation.corpus_path and foundation.validation_path must be distinct."
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
if (foundationSpec.foundation.checkpoint_backup_dir) {
|
|
420
|
+
checks.push(await writableDirectoryCheck(
|
|
421
|
+
"checkpoint-backup",
|
|
422
|
+
foundationSpec.foundation.checkpoint_backup_dir
|
|
423
|
+
));
|
|
424
|
+
}
|
|
362
425
|
} else if (request) {
|
|
363
426
|
checks.push(placeholderSpecCheck(request));
|
|
364
427
|
resolveTrainingModel(request.spec_snapshot.base_model);
|
|
365
428
|
}
|
|
366
|
-
const pythonPlans = buildDoctorPythonPlans(config);
|
|
429
|
+
const pythonPlans = foundationSpec && !config.dryRun ? [foundationPythonProbePlan(foundationSpec.foundation.bf16 !== false)] : buildDoctorPythonPlans(config);
|
|
367
430
|
if (pythonPlans.length > 0) {
|
|
368
431
|
const uvVersion = await runCommand("uv", ["--version"]);
|
|
369
432
|
checks.push({
|
|
@@ -416,20 +479,20 @@ async function runDoctor(config, request, foundationSpec) {
|
|
|
416
479
|
message: config.dryRun ? "GPU checks skipped because dryRun is enabled." : `nvidia-smi is not required for device=${device}.`
|
|
417
480
|
});
|
|
418
481
|
}
|
|
419
|
-
const trainingCommand = buildBundledPythonCommand("train.py").displayCommand;
|
|
482
|
+
const trainingCommand = foundationSpec ? buildFoundationPythonCommand("pretrain.py").displayCommand : buildBundledPythonCommand("train.py").displayCommand;
|
|
420
483
|
checks.push({
|
|
421
484
|
name: "effective-plan",
|
|
422
485
|
ok: true,
|
|
423
486
|
message: "Resolved the configured training and evaluation plan.",
|
|
424
487
|
details: {
|
|
425
488
|
training_command: trainingCommand ?? null,
|
|
426
|
-
evaluation_provider: "transformers",
|
|
489
|
+
evaluation_provider: foundationSpec ? "foundation" : "transformers",
|
|
427
490
|
evaluation_device: device,
|
|
428
491
|
artifact_root: resolve(config.artifactRoot),
|
|
429
492
|
store_root: resolve(config.storeRoot ?? defaultLocalHome()),
|
|
430
493
|
model_cache: resolve(config.paths.modelCache ?? process.env.HF_HOME ?? join(homedir(), ".cache", "huggingface")),
|
|
431
494
|
base_model: request?.spec_snapshot.base_model ?? null,
|
|
432
|
-
scoring_mode: config.evaluation.scoring.mode
|
|
495
|
+
scoring_mode: foundationSpec ? "bpb/chat" : config.evaluation.scoring.mode
|
|
433
496
|
}
|
|
434
497
|
});
|
|
435
498
|
return checks;
|
|
@@ -741,6 +804,7 @@ Commands:
|
|
|
741
804
|
info Show package and runner information
|
|
742
805
|
init [--name "My Local Model"] [--model Qwen/Qwen3.5-2B] [--output tunedtensor.json] [--profile spark] [--force]
|
|
743
806
|
doctor [tunedtensor.json] [--config local-runner.json]
|
|
807
|
+
hardware [--config local-runner.json] [--quick]
|
|
744
808
|
validate [tunedtensor.json] [--config local-runner.json]
|
|
745
809
|
run [tunedtensor.json] [--config local-runner.json] [--dry-run] [--verbose] [--quiet]
|
|
746
810
|
serve <model-id|active|base> [--config local-runner.json] [--host 127.0.0.1] [--port 8000]
|
|
@@ -801,6 +865,15 @@ var COMMAND_DEFINITIONS = {
|
|
|
801
865
|
options: [CONFIG_OPTION],
|
|
802
866
|
maxPositionals: 1
|
|
803
867
|
},
|
|
868
|
+
hardware: {
|
|
869
|
+
usage: "tt hardware [--config path] [--quick]",
|
|
870
|
+
description: "Inventory this host and report what TT can train, fine-tune, or infer.",
|
|
871
|
+
options: [
|
|
872
|
+
CONFIG_OPTION,
|
|
873
|
+
{ name: "--quick", description: "Skip the bundled torch/uv runtime probe" }
|
|
874
|
+
],
|
|
875
|
+
maxPositionals: 0
|
|
876
|
+
},
|
|
804
877
|
validate: {
|
|
805
878
|
usage: "tt validate [tunedtensor.json] [options]",
|
|
806
879
|
description: "Validate a local behavior spec without executing it.",
|
|
@@ -1430,9 +1503,28 @@ async function main(argv) {
|
|
|
1430
1503
|
config_path: configSelection.path ?? null,
|
|
1431
1504
|
checks
|
|
1432
1505
|
});
|
|
1506
|
+
try {
|
|
1507
|
+
await assessHardware({
|
|
1508
|
+
config: configSelection.config,
|
|
1509
|
+
quick: true
|
|
1510
|
+
});
|
|
1511
|
+
} catch {
|
|
1512
|
+
}
|
|
1433
1513
|
if (!ok) process.exitCode = 1;
|
|
1434
1514
|
return;
|
|
1435
1515
|
}
|
|
1516
|
+
if (command === "hardware") {
|
|
1517
|
+
const configSelection = await configSelectionFromArgv(argv);
|
|
1518
|
+
const report = await assessHardware({
|
|
1519
|
+
config: configSelection.config,
|
|
1520
|
+
quick: hasFlag(argv, "--quick")
|
|
1521
|
+
});
|
|
1522
|
+
printJson({
|
|
1523
|
+
...report,
|
|
1524
|
+
config_path: configSelection.path ?? null
|
|
1525
|
+
});
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1436
1528
|
if (command === "init") {
|
|
1437
1529
|
const outputPath = resolve3(readOption(argv, "--output") ?? DEFAULT_LOCAL_SPEC_PATH);
|
|
1438
1530
|
const profile = readOption(argv, "--profile");
|
|
@@ -1758,6 +1850,7 @@ export {
|
|
|
1758
1850
|
localAdapterSpecFileSchema,
|
|
1759
1851
|
localBehaviorSpecFileSchema,
|
|
1760
1852
|
localFoundationSpecFileSchema,
|
|
1853
|
+
localPathsOverlap,
|
|
1761
1854
|
localRunnerConfigSchema,
|
|
1762
1855
|
localStorePaths,
|
|
1763
1856
|
normalizeChatJsonlForRelocation,
|