@tuned-tensor/cli 0.11.0 → 0.12.0-beta.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/README.md +44 -29
- package/dist/{chunk-DAP2Z7EZ.js → chunk-HDGBDHOB.js} +474 -74
- package/dist/chunk-HDGBDHOB.js.map +1 -0
- package/dist/index.js +366 -199
- package/dist/index.js.map +1 -1
- package/dist/local-runtime.js +52 -19
- package/dist/local-runtime.js.map +1 -1
- package/docs/local-runtime/architecture.md +8 -2
- package/docs/local-runtime/spark.md +39 -2
- package/package.json +6 -2
- package/training/local-runner/pyproject.toml +2 -2
- package/training/local-runner/src/evaluate.py +44 -18
- package/training/local-runner/src/model_contract.py +134 -14
- package/training/local-runner/src/prefetch.py +25 -8
- package/training/local-runner/src/serve.py +14 -6
- package/training/local-runner/src/sft_data.py +7 -3
- package/training/local-runner/src/train.py +48 -14
- package/training/local-runner/uv.lock +54 -54
- package/dist/chunk-DAP2Z7EZ.js.map +0 -1
package/dist/local-runtime.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
createLocalStore,
|
|
16
16
|
datasetFormatSchema,
|
|
17
17
|
datasetPrebuiltSchema,
|
|
18
|
+
defaultBaseModelRevision,
|
|
18
19
|
defaultLocalHome,
|
|
19
20
|
evalExampleResultSchema,
|
|
20
21
|
evalReportSchema,
|
|
@@ -46,6 +47,8 @@ import {
|
|
|
46
47
|
prefetchBaseModel,
|
|
47
48
|
reportInBackground,
|
|
48
49
|
resolveLocalRunInputPaths,
|
|
50
|
+
resolveModelLoader,
|
|
51
|
+
resolveRequestedBaseModelRevision,
|
|
49
52
|
resolveTrainingModel,
|
|
50
53
|
runLocalFineTune,
|
|
51
54
|
runLocalPipeline,
|
|
@@ -58,11 +61,12 @@ import {
|
|
|
58
61
|
validateLocalFineTuneInput,
|
|
59
62
|
validateLocalPipeline,
|
|
60
63
|
verifyLocalBaseModel,
|
|
64
|
+
verifyModelPrefetchCacheReport,
|
|
61
65
|
withBundledPythonEnvironment,
|
|
62
66
|
withHuggingFaceCacheEnvironment,
|
|
63
67
|
withOfflineHuggingFaceCacheEnvironment,
|
|
64
68
|
writeJsonAtomic
|
|
65
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-HDGBDHOB.js";
|
|
66
70
|
|
|
67
71
|
// src/local-runtime/index.ts
|
|
68
72
|
import { readFileSync, realpathSync } from "fs";
|
|
@@ -293,10 +297,10 @@ function placeholderSpecCheck(request) {
|
|
|
293
297
|
message: placeholder ? "The spec still contains generated placeholder content; edit it before training." : `${request.spec_snapshot.examples.length} spec example(s); base model ${request.spec_snapshot.base_model}`
|
|
294
298
|
};
|
|
295
299
|
}
|
|
296
|
-
async function localBaseModelCheck(path) {
|
|
300
|
+
async function localBaseModelCheck(path, expectedModelId, modelCache) {
|
|
297
301
|
const resolvedPath = resolve(path);
|
|
298
302
|
try {
|
|
299
|
-
const verified = await verifyLocalBaseModel(resolvedPath);
|
|
303
|
+
const verified = await verifyLocalBaseModel(resolvedPath, expectedModelId, modelCache);
|
|
300
304
|
return {
|
|
301
305
|
name: "local-base-model",
|
|
302
306
|
ok: true,
|
|
@@ -323,7 +327,13 @@ async function runDoctor(config, request) {
|
|
|
323
327
|
"model-cache",
|
|
324
328
|
config.paths.modelCache ?? process.env.HF_HOME ?? join(homedir(), ".cache", "huggingface")
|
|
325
329
|
));
|
|
326
|
-
if (config.paths.baseModel)
|
|
330
|
+
if (config.paths.baseModel) {
|
|
331
|
+
checks.push(await localBaseModelCheck(
|
|
332
|
+
config.paths.baseModel,
|
|
333
|
+
request?.spec_snapshot.base_model,
|
|
334
|
+
config.paths.modelCache
|
|
335
|
+
));
|
|
336
|
+
}
|
|
327
337
|
if (request) {
|
|
328
338
|
checks.push(placeholderSpecCheck(request));
|
|
329
339
|
resolveTrainingModel(request.spec_snapshot.base_model);
|
|
@@ -451,16 +461,21 @@ function buildModelServerLaunch(args) {
|
|
|
451
461
|
);
|
|
452
462
|
}
|
|
453
463
|
const localBaseModelPath = recordedBaseModelPath ?? configuredBaseModelPath;
|
|
454
|
-
|
|
464
|
+
const requestedBaseModelRevision = resolveRequestedBaseModelRevision(
|
|
465
|
+
args.baseModel,
|
|
466
|
+
options.baseModelRevision
|
|
467
|
+
);
|
|
468
|
+
const baseModelRevision = localBaseModelPath ? defaultBaseModelRevision(args.baseModel) : requestedBaseModelRevision;
|
|
455
469
|
const entrypoint = buildBundledPythonCommand("serve.py");
|
|
456
470
|
const env = withBundledPythonEnvironment(
|
|
457
471
|
withOfflineHuggingFaceCacheEnvironment({
|
|
458
472
|
...minimalMachineLearningEnvironment(process.env),
|
|
459
473
|
...artifactPath ? { TT_MODEL_ARTIFACT: artifactPath } : {},
|
|
460
|
-
TT_BASE_MODEL:
|
|
461
|
-
...
|
|
474
|
+
TT_BASE_MODEL: args.baseModel,
|
|
475
|
+
...localBaseModelPath ? { TT_MODEL_SOURCE: localBaseModelPath } : {},
|
|
476
|
+
...baseModelRevision ? { TT_BASE_MODEL_REVISION: baseModelRevision } : {},
|
|
462
477
|
TT_MODEL_NAME: args.modelName,
|
|
463
|
-
TT_MODEL_LOADER:
|
|
478
|
+
TT_MODEL_LOADER: resolveModelLoader(args.baseModel),
|
|
464
479
|
TT_HOST: host,
|
|
465
480
|
TT_PORT: String(port),
|
|
466
481
|
TT_DEVICE: options.device ?? args.config.evaluation.inference.device,
|
|
@@ -500,7 +515,15 @@ function buildLocalBaseModelServerLaunch(args) {
|
|
|
500
515
|
options: args.options
|
|
501
516
|
});
|
|
502
517
|
}
|
|
518
|
+
async function verifyLocalModelServerLaunch(launch) {
|
|
519
|
+
const modelSource = launch.env.TT_MODEL_SOURCE;
|
|
520
|
+
const expectedModelId = launch.env.TT_BASE_MODEL;
|
|
521
|
+
if (modelSource && expectedModelId) {
|
|
522
|
+
await verifyLocalBaseModel(modelSource, expectedModelId, launch.env.HF_HOME);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
503
525
|
async function serveLocalModel(launch) {
|
|
526
|
+
await verifyLocalModelServerLaunch(launch);
|
|
504
527
|
await new Promise((resolveServer, reject) => {
|
|
505
528
|
const child = spawn2(launch.command, launch.commandArgs, {
|
|
506
529
|
env: launch.env,
|
|
@@ -1012,7 +1035,7 @@ function createConsoleReporter(options) {
|
|
|
1012
1035
|
}
|
|
1013
1036
|
};
|
|
1014
1037
|
}
|
|
1015
|
-
async function verifyStoredModel(model) {
|
|
1038
|
+
async function verifyStoredModel(model, config) {
|
|
1016
1039
|
const manifestPath = join3(model.artifact_dir, "artifact-manifest.json");
|
|
1017
1040
|
const integrity = await assertArtifactManifest(manifestPath, {
|
|
1018
1041
|
requiredPaths: ["stage-metadata.json", "training-report.json"],
|
|
@@ -1025,7 +1048,11 @@ async function verifyStoredModel(model) {
|
|
|
1025
1048
|
}
|
|
1026
1049
|
const artifact = await assertUsableModelArtifact(model.artifact_uri);
|
|
1027
1050
|
if (typeof manifest.model.base_model_artifact_uri === "string" && typeof manifest.model.base_model_fingerprint === "string") {
|
|
1028
|
-
const actualBaseFingerprint = await fingerprintLocalBaseModel(
|
|
1051
|
+
const actualBaseFingerprint = await fingerprintLocalBaseModel(
|
|
1052
|
+
manifest.model.base_model_artifact_uri,
|
|
1053
|
+
typeof manifest.model.base_model === "string" ? manifest.model.base_model : void 0,
|
|
1054
|
+
config.paths.modelCache
|
|
1055
|
+
);
|
|
1029
1056
|
if (actualBaseFingerprint !== manifest.model.base_model_fingerprint) {
|
|
1030
1057
|
throw new Error("Recorded local base-model content no longer matches the model artifact contract.");
|
|
1031
1058
|
}
|
|
@@ -1054,7 +1081,7 @@ async function verifyActivationEvidence(model) {
|
|
|
1054
1081
|
verifyModel: true
|
|
1055
1082
|
});
|
|
1056
1083
|
}
|
|
1057
|
-
async function verifyModelArtifactPath(input) {
|
|
1084
|
+
async function verifyModelArtifactPath(input, config) {
|
|
1058
1085
|
const inputPath = resolve3(input);
|
|
1059
1086
|
let manifestPath;
|
|
1060
1087
|
let artifactUri = inputPath;
|
|
@@ -1096,7 +1123,11 @@ async function verifyModelArtifactPath(input) {
|
|
|
1096
1123
|
if (!manifest.model) throw new Error(`Artifact manifest does not contain a model contract: ${manifestPath}`);
|
|
1097
1124
|
const artifact = await assertUsableModelArtifact(artifactUri);
|
|
1098
1125
|
if (typeof manifest.model.base_model_artifact_uri === "string" && typeof manifest.model.base_model_fingerprint === "string") {
|
|
1099
|
-
const actualBaseFingerprint = await fingerprintLocalBaseModel(
|
|
1126
|
+
const actualBaseFingerprint = await fingerprintLocalBaseModel(
|
|
1127
|
+
manifest.model.base_model_artifact_uri,
|
|
1128
|
+
typeof manifest.model.base_model === "string" ? manifest.model.base_model : void 0,
|
|
1129
|
+
config.paths.modelCache
|
|
1130
|
+
);
|
|
1100
1131
|
if (actualBaseFingerprint !== manifest.model.base_model_fingerprint) {
|
|
1101
1132
|
throw new Error("Recorded local base-model content no longer matches the model artifact contract.");
|
|
1102
1133
|
}
|
|
@@ -1157,7 +1188,7 @@ function modelServeDevice(argv) {
|
|
|
1157
1188
|
async function serveStoredModelFromCli(args) {
|
|
1158
1189
|
const store = createLocalStore(args.config.storeRoot);
|
|
1159
1190
|
const model = await store.getModel(args.modelId);
|
|
1160
|
-
const verified = await verifyStoredModel(model);
|
|
1191
|
+
const verified = await verifyStoredModel(model, args.config);
|
|
1161
1192
|
const launch = buildLocalModelServerLaunch({
|
|
1162
1193
|
model,
|
|
1163
1194
|
config: args.config,
|
|
@@ -1241,7 +1272,7 @@ async function serveBaseModelFromCli(args) {
|
|
|
1241
1272
|
options: {
|
|
1242
1273
|
...serveOptionsFromArgv(args.argv),
|
|
1243
1274
|
systemPrompt: explicitSpecPath && !hasFlag(args.argv, "--no-spec-prompt") ? buildSystemMessage(spec) : void 0,
|
|
1244
|
-
baseModelRevision: spec?.hyperparameters?.base_model_revision
|
|
1275
|
+
baseModelRevision: spec?.hyperparameters?.base_model_revision ?? defaultBaseModelRevision(baseModel)
|
|
1245
1276
|
}
|
|
1246
1277
|
});
|
|
1247
1278
|
if (hasFlag(args.argv, "--print-command")) {
|
|
@@ -1490,10 +1521,10 @@ async function main(argv) {
|
|
|
1490
1521
|
const id = cli.positionals[0];
|
|
1491
1522
|
if (!id) throw new Error("models verify requires <model-id-or-artifact-path>");
|
|
1492
1523
|
if (await stat(resolve3(id)).then(() => true, () => false)) {
|
|
1493
|
-
return printJson({ ok: true, model: null, ...await verifyModelArtifactPath(id) });
|
|
1524
|
+
return printJson({ ok: true, model: null, ...await verifyModelArtifactPath(id, config) });
|
|
1494
1525
|
}
|
|
1495
1526
|
const model = await store.getModel(id);
|
|
1496
|
-
const verified = await verifyStoredModel(model);
|
|
1527
|
+
const verified = await verifyStoredModel(model, config);
|
|
1497
1528
|
return printJson({ ok: true, model, ...verified });
|
|
1498
1529
|
}
|
|
1499
1530
|
if (subcommand === "active") {
|
|
@@ -1508,7 +1539,7 @@ async function main(argv) {
|
|
|
1508
1539
|
const id = cli.positionals[0];
|
|
1509
1540
|
if (!id) throw new Error("models activate requires <model-id>");
|
|
1510
1541
|
const model = await store.getModel(id);
|
|
1511
|
-
const verified = await verifyStoredModel(model);
|
|
1542
|
+
const verified = await verifyStoredModel(model, config);
|
|
1512
1543
|
await verifyActivationEvidence(model);
|
|
1513
1544
|
const pointer = await activateModel(store, model.id);
|
|
1514
1545
|
return printJson({
|
|
@@ -1522,7 +1553,7 @@ async function main(argv) {
|
|
|
1522
1553
|
const current = await getActiveModel(store);
|
|
1523
1554
|
if (current.pointer?.previous_model_id) {
|
|
1524
1555
|
const previous = await store.getModel(current.pointer.previous_model_id);
|
|
1525
|
-
await verifyStoredModel(previous);
|
|
1556
|
+
await verifyStoredModel(previous, config);
|
|
1526
1557
|
await verifyActivationEvidence(previous);
|
|
1527
1558
|
}
|
|
1528
1559
|
const pointer = await rollbackActiveModel(store);
|
|
@@ -1625,6 +1656,8 @@ export {
|
|
|
1625
1656
|
trainingReportSchema,
|
|
1626
1657
|
validateLocalFineTuneInput,
|
|
1627
1658
|
validateLocalPipeline,
|
|
1628
|
-
verifyLocalBaseModel
|
|
1659
|
+
verifyLocalBaseModel,
|
|
1660
|
+
verifyLocalModelServerLaunch,
|
|
1661
|
+
verifyModelPrefetchCacheReport
|
|
1629
1662
|
};
|
|
1630
1663
|
//# sourceMappingURL=local-runtime.js.map
|