@tuned-tensor/cli 0.20.0 → 0.22.0
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 +123 -7
- package/dist/{chunk-4Q54NHKR.js → chunk-4SUXBHIY.js} +1715 -392
- package/dist/chunk-4SUXBHIY.js.map +1 -0
- package/dist/index.js +1910 -356
- package/dist/index.js.map +1 -1
- package/dist/local-runtime.js +147 -49
- package/dist/local-runtime.js.map +1 -1
- package/docs/local-runtime/architecture.md +44 -1
- package/docs/local-runtime/aws-gpu.md +2 -0
- package/docs/local-runtime/decision.md +142 -0
- package/docs/spec-architecture.html +2 -2
- package/docs/spec-workflow.md +18 -3
- package/examples/single-spec/decision/tunedtensor.json +630 -0
- package/package.json +5 -2
- package/training/adapter/src/evaluate.py +14 -7
- package/training/adapter/src/hub_download.py +384 -0
- package/training/adapter/src/model_contract.py +38 -5
- package/training/adapter/src/prefetch.py +26 -32
- package/training/adapter/src/prefetch_dataset.py +116 -0
- package/training/adapter/src/serve.py +42 -12
- package/training/adapter/src/train.py +8 -0
- package/training/decision/pyproject.toml +25 -0
- package/training/decision/src/common.py +127 -0
- package/training/decision/src/evaluate.py +70 -0
- package/training/decision/src/train.py +181 -0
- package/training/decision/uv.lock +1175 -0
- package/dist/chunk-4Q54NHKR.js.map +0 -1
package/dist/local-runtime.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DEFAULT_LOCAL_SPEC_PATH,
|
|
4
|
+
DatasetNotDownloadedError,
|
|
4
5
|
assertArtifactManifest,
|
|
5
6
|
assertFoundationSpecReady,
|
|
6
7
|
assertLocalRunInputReady,
|
|
7
8
|
assertUsableModelArtifact,
|
|
8
9
|
assessHardware,
|
|
10
|
+
auditRun,
|
|
9
11
|
baseModelRevisionSchema,
|
|
10
12
|
behaviorSpecExampleSchema,
|
|
11
13
|
behaviorSpecSchema,
|
|
@@ -18,10 +20,19 @@ import {
|
|
|
18
20
|
comparisonReportSchema,
|
|
19
21
|
compileSpecToJsonl,
|
|
20
22
|
createLocalStore,
|
|
23
|
+
createRunConsoleReporter,
|
|
24
|
+
datasetColumnsSchema,
|
|
21
25
|
datasetFormatSchema,
|
|
26
|
+
datasetInputIdentity,
|
|
22
27
|
datasetPrebuiltSchema,
|
|
28
|
+
datasetSourceSchema,
|
|
29
|
+
decisionHyperparametersSchema,
|
|
30
|
+
decisionLabels,
|
|
31
|
+
decisionPlaceholderIssues,
|
|
32
|
+
decisionQuestionSchema,
|
|
23
33
|
defaultBaseModelRevision,
|
|
24
34
|
defaultLocalHome,
|
|
35
|
+
ensureDatasetCached,
|
|
25
36
|
evalExampleResultSchema,
|
|
26
37
|
evalReportSchema,
|
|
27
38
|
evalSplitSchema,
|
|
@@ -38,9 +49,14 @@ import {
|
|
|
38
49
|
foundationPlaceholderIssues,
|
|
39
50
|
generatedPlaceholderIssues,
|
|
40
51
|
hardenExistingLocalStore,
|
|
52
|
+
huggingFaceDataset,
|
|
53
|
+
huggingFaceDatasetSourceSchema,
|
|
54
|
+
huggingFaceRepoIdSchema,
|
|
41
55
|
initLocalRunnerConfigFile,
|
|
42
56
|
initLocalSpecFile,
|
|
57
|
+
isDecisionSpecFile,
|
|
43
58
|
isFoundationSpecFile,
|
|
59
|
+
isRepoRelativePath,
|
|
44
60
|
isTerminalRunState,
|
|
45
61
|
jsonFieldMetricsSchema,
|
|
46
62
|
loadJsonFile,
|
|
@@ -49,6 +65,7 @@ import {
|
|
|
49
65
|
loadRunRequest,
|
|
50
66
|
localAdapterSpecFileSchema,
|
|
51
67
|
localBehaviorSpecFileSchema,
|
|
68
|
+
localDecisionSpecFileSchema,
|
|
52
69
|
localFoundationSpecFileSchema,
|
|
53
70
|
localPathsOverlap,
|
|
54
71
|
localRunnerConfigSchema,
|
|
@@ -60,6 +77,7 @@ import {
|
|
|
60
77
|
parseLocalRunnerConfig,
|
|
61
78
|
pipelineForRunInput,
|
|
62
79
|
prefetchBaseModel,
|
|
80
|
+
prefetchHuggingFaceDataset,
|
|
63
81
|
projectRuntimeSchema,
|
|
64
82
|
pythonEnvironmentPath,
|
|
65
83
|
reportInBackground,
|
|
@@ -71,8 +89,10 @@ import {
|
|
|
71
89
|
runGpuProcess,
|
|
72
90
|
runLocalFineTune,
|
|
73
91
|
runLocalPipeline,
|
|
92
|
+
runProvenanceSchema,
|
|
74
93
|
runReportSchema,
|
|
75
94
|
runRequestFromLocalSpec,
|
|
95
|
+
safeName,
|
|
76
96
|
sanitizeLogLine,
|
|
77
97
|
specHash,
|
|
78
98
|
specSnapshotSchema,
|
|
@@ -88,13 +108,13 @@ import {
|
|
|
88
108
|
withHuggingFaceCacheEnvironment,
|
|
89
109
|
withOfflineHuggingFaceCacheEnvironment,
|
|
90
110
|
writePrivateJsonAtomic
|
|
91
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-4SUXBHIY.js";
|
|
92
112
|
|
|
93
113
|
// src/local-runtime/index.ts
|
|
94
114
|
import { readFileSync as readFileSync3, realpathSync } from "fs";
|
|
95
115
|
import { createHash as createHash2 } from "crypto";
|
|
96
116
|
import { readFile as readFile2, stat } from "fs/promises";
|
|
97
|
-
import { basename, dirname, join as join5, resolve as resolve3 } from "path";
|
|
117
|
+
import { basename, dirname, join as join5, relative, resolve as resolve3 } from "path";
|
|
98
118
|
import { cwd } from "process";
|
|
99
119
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
100
120
|
|
|
@@ -926,8 +946,9 @@ Commands:
|
|
|
926
946
|
validate [tunedtensor.json] [--config local-runner.json]
|
|
927
947
|
run [tunedtensor.json] [--config local-runner.json] [--dry-run] [--verbose] [--quiet]
|
|
928
948
|
serve <model-id|active|base|foundation> [--config local-runner.json] [--host 127.0.0.1] [--port 8000]
|
|
929
|
-
runs list|get|events|report|compare [args] [--config local-runner.json]
|
|
949
|
+
runs list|get|events|report|compare|audit [args] [--config local-runner.json]
|
|
930
950
|
models list|get|verify|prefetch|verify-base|active|activate|rollback|serve [args] [--config local-runner.json]
|
|
951
|
+
datasets prefetch|verify [tunedtensor.json]
|
|
931
952
|
|
|
932
953
|
Global options:
|
|
933
954
|
-h, --help Show help
|
|
@@ -972,7 +993,7 @@ var COMMAND_DEFINITIONS = {
|
|
|
972
993
|
description: "Create a local tunedtensor.json behavior spec.",
|
|
973
994
|
options: [
|
|
974
995
|
{ name: "--name", value: "name", description: "Behavior spec name" },
|
|
975
|
-
{ name: "--engine", value: "engine", description: "adapter (default) or
|
|
996
|
+
{ name: "--engine", value: "engine", description: "adapter (default), foundation or decision" },
|
|
976
997
|
{ name: "--model", value: "model", description: "Base model ID" },
|
|
977
998
|
{ name: "--output", value: "path", description: "Output spec path" },
|
|
978
999
|
{ name: "--profile", value: "profile", description: "Compatibility host profile (spark); creates only tunedtensor.json" },
|
|
@@ -1031,6 +1052,7 @@ var COMMAND_GROUPS = {
|
|
|
1031
1052
|
get: { usage: "tt runs get <run-id> [--config path]", description: "Get a local run.", options: [CONFIG_OPTION], minPositionals: 1, maxPositionals: 1, missingPositionalsMessage: "runs get requires <run-id>" },
|
|
1032
1053
|
events: { usage: "tt runs events <run-id> [--config path]", description: "List run events.", options: [CONFIG_OPTION], minPositionals: 1, maxPositionals: 1, missingPositionalsMessage: "runs events requires <run-id>" },
|
|
1033
1054
|
report: { usage: "tt runs report <run-id> [--config path]", description: "Show the baseline-vs-tuned report, including deltas and regressions.", options: [CONFIG_OPTION], minPositionals: 1, maxPositionals: 1, missingPositionalsMessage: "runs report requires <run-id>" },
|
|
1055
|
+
audit: { usage: "tt runs audit <run-id> [--config path]", description: "Verify the run's event chain and report digest, and show its timeline and provenance.", options: [CONFIG_OPTION], minPositionals: 1, maxPositionals: 1, missingPositionalsMessage: "runs audit requires <run-id>" },
|
|
1034
1056
|
compare: { usage: "tt runs compare <run-id-a> <run-id-b> [--config path]", description: "Compare two run reports.", options: [CONFIG_OPTION], minPositionals: 2, maxPositionals: 2, missingPositionalsMessage: "runs compare requires <run-id-a> <run-id-b>" }
|
|
1035
1057
|
}
|
|
1036
1058
|
},
|
|
@@ -1089,6 +1111,24 @@ var COMMAND_GROUPS = {
|
|
|
1089
1111
|
missingPositionalsMessage: "models serve requires <model-id>"
|
|
1090
1112
|
}
|
|
1091
1113
|
}
|
|
1114
|
+
},
|
|
1115
|
+
datasets: {
|
|
1116
|
+
description: "Download or verify the Hugging Face dataset a behavior spec trains on.",
|
|
1117
|
+
defaultSubcommand: "prefetch",
|
|
1118
|
+
subcommands: {
|
|
1119
|
+
prefetch: {
|
|
1120
|
+
usage: "tt datasets prefetch [tunedtensor.json] [options]",
|
|
1121
|
+
description: "Download dataset_prebuilt.huggingface files into the local Hugging Face cache. Resumes after interruption.",
|
|
1122
|
+
options: [CONFIG_OPTION, VERBOSE_OPTION, QUIET_OPTION],
|
|
1123
|
+
maxPositionals: 1
|
|
1124
|
+
},
|
|
1125
|
+
verify: {
|
|
1126
|
+
usage: "tt datasets verify [tunedtensor.json] [options]",
|
|
1127
|
+
description: "Verify the cached dataset files and checksums without network access.",
|
|
1128
|
+
options: [CONFIG_OPTION, QUIET_OPTION],
|
|
1129
|
+
maxPositionals: 1
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1092
1132
|
}
|
|
1093
1133
|
};
|
|
1094
1134
|
function hasHelpFlag(argv) {
|
|
@@ -1226,6 +1266,7 @@ async function configSelectionFromArgv(argv, adjacentTo, input) {
|
|
|
1226
1266
|
async function configFromArgv(argv, adjacentTo) {
|
|
1227
1267
|
return (await configSelectionFromArgv(argv, adjacentTo)).config;
|
|
1228
1268
|
}
|
|
1269
|
+
var DECISION_SERVE_MESSAGE = "Decision models are not served through vLLM. Load the tuned model directory with `laya.load(<model_dir>)`; see docs/local-runtime/decision.md.";
|
|
1229
1270
|
async function loadCliBehaviorSpec(inputPath, runId) {
|
|
1230
1271
|
const input = await loadLocalRunInput(inputPath, {
|
|
1231
1272
|
...runId ? { runId } : {}
|
|
@@ -1235,6 +1276,11 @@ async function loadCliBehaviorSpec(inputPath, runId) {
|
|
|
1235
1276
|
`This spec uses engine "foundation". Use \`tt pipeline run --spec ${input.path}\`; the legacy adapter runner cannot execute foundation specs.`
|
|
1236
1277
|
);
|
|
1237
1278
|
}
|
|
1279
|
+
if (input.kind === "decision-spec") {
|
|
1280
|
+
throw new Error(
|
|
1281
|
+
`This spec uses engine "decision". Use \`tt pipeline run --spec ${input.path}\`; the legacy adapter runner cannot execute decision specs.`
|
|
1282
|
+
);
|
|
1283
|
+
}
|
|
1238
1284
|
if (input.kind !== "spec") {
|
|
1239
1285
|
throw new Error(`TT expects a tunedtensor.json behavior spec, not a full run request: ${input.path}`);
|
|
1240
1286
|
}
|
|
@@ -1243,38 +1289,9 @@ async function loadCliBehaviorSpec(inputPath, runId) {
|
|
|
1243
1289
|
function printJson(value) {
|
|
1244
1290
|
console.log(JSON.stringify(value, null, 2));
|
|
1245
1291
|
}
|
|
1246
|
-
function shortValue(value) {
|
|
1247
|
-
if (value === void 0 || value === null) return null;
|
|
1248
|
-
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1249
|
-
return String(value);
|
|
1250
|
-
}
|
|
1251
|
-
if (Array.isArray(value)) return `[${value.length} items]`;
|
|
1252
|
-
return null;
|
|
1253
|
-
}
|
|
1254
|
-
function formatEvent(event) {
|
|
1255
|
-
const detailText = Object.entries(event.details ?? {}).filter(([key]) => key !== "metrics").map(([key, value]) => {
|
|
1256
|
-
const formatted = key === "command" && Array.isArray(value) ? value.join(" ") : shortValue(value);
|
|
1257
|
-
return formatted ? `${key}=${formatted}` : null;
|
|
1258
|
-
}).filter((value) => Boolean(value)).slice(0, 5).join(" ");
|
|
1259
|
-
return sanitizeLogLine(`[tt] ${event.stage}: ${event.message}${detailText ? ` (${detailText})` : ""}`);
|
|
1260
|
-
}
|
|
1261
1292
|
function createConsoleReporter(options) {
|
|
1262
1293
|
if (options.quiet) return void 0;
|
|
1263
|
-
|
|
1264
|
-
return {
|
|
1265
|
-
verbose: options.verbose,
|
|
1266
|
-
onEvent(event) {
|
|
1267
|
-
process.stderr.write(`${formatEvent(event)}
|
|
1268
|
-
`);
|
|
1269
|
-
},
|
|
1270
|
-
onLog(log) {
|
|
1271
|
-
const line = sanitizeLogLine(`[tt] ${log.stage}${log.stream ? ` ${log.stream}` : ""}: ${log.message}`);
|
|
1272
|
-
if (line === lastLogLine) return;
|
|
1273
|
-
lastLogLine = line;
|
|
1274
|
-
process.stderr.write(`${line}
|
|
1275
|
-
`);
|
|
1276
|
-
}
|
|
1277
|
-
};
|
|
1294
|
+
return createRunConsoleReporter({ verbose: options.verbose });
|
|
1278
1295
|
}
|
|
1279
1296
|
async function verifyStoredModel(model, config) {
|
|
1280
1297
|
const manifestPath = join5(model.artifact_dir, "artifact-manifest.json");
|
|
@@ -1405,6 +1422,7 @@ async function modelSystemPrompt(args) {
|
|
|
1405
1422
|
if (isFoundationSpecFile(local.data)) {
|
|
1406
1423
|
throw new Error("Foundation specs have no Hugging Face base model. Use `tt serve foundation --checkpoint <model-dir> --tokenizer <tokenizer.json>`.");
|
|
1407
1424
|
}
|
|
1425
|
+
if (isDecisionSpecFile(local.data)) throw new Error(DECISION_SERVE_MESSAGE);
|
|
1408
1426
|
spec = local.data;
|
|
1409
1427
|
} else {
|
|
1410
1428
|
const runRequestPath = join5(args.store.paths.runsDir, args.model.run_id, "request.json");
|
|
@@ -1556,6 +1574,7 @@ async function serveBaseModelFromCli(args) {
|
|
|
1556
1574
|
if (spec && isFoundationSpecFile(spec)) {
|
|
1557
1575
|
throw new Error("Foundation specs have no Hugging Face base model. Use `tt serve foundation --checkpoint <model-dir> --tokenizer <tokenizer.json>`.");
|
|
1558
1576
|
}
|
|
1577
|
+
if (spec && isDecisionSpecFile(spec)) throw new Error(DECISION_SERVE_MESSAGE);
|
|
1559
1578
|
let baseModel = spec?.base_model;
|
|
1560
1579
|
if (!baseModel) {
|
|
1561
1580
|
const store = createLocalStore(args.config.storeRoot);
|
|
@@ -1689,6 +1708,7 @@ async function main(argv) {
|
|
|
1689
1708
|
const input = await loadLocalRunInput(inputPath);
|
|
1690
1709
|
if (input.kind === "foundation-spec") {
|
|
1691
1710
|
foundationSpec = input.spec;
|
|
1711
|
+
} else if (input.kind === "decision-spec") {
|
|
1692
1712
|
} else if (input.kind === "spec") {
|
|
1693
1713
|
request = input.request;
|
|
1694
1714
|
} else {
|
|
@@ -1731,8 +1751,8 @@ async function main(argv) {
|
|
|
1731
1751
|
throw new Error(`--profile must be spark, got: ${profile}`);
|
|
1732
1752
|
}
|
|
1733
1753
|
const engine = readOption(argv, "--engine") ?? "adapter";
|
|
1734
|
-
if (engine !== "adapter" && engine !== "foundation") {
|
|
1735
|
-
throw new Error(`--engine must be adapter or
|
|
1754
|
+
if (engine !== "adapter" && engine !== "foundation" && engine !== "decision") {
|
|
1755
|
+
throw new Error(`--engine must be adapter, foundation or decision, got: ${engine}`);
|
|
1736
1756
|
}
|
|
1737
1757
|
if (engine === "foundation" && readOption(argv, "--model")) {
|
|
1738
1758
|
throw new Error("Foundation specs do not take --model; they train a tokenizer and GPT from scratch.");
|
|
@@ -1740,9 +1760,9 @@ async function main(argv) {
|
|
|
1740
1760
|
if (readOption(argv, "--config")) throw new Error("tt init uses one tunedtensor.json; put overrides in runtime/evaluation instead of --config.");
|
|
1741
1761
|
const spec = await initLocalSpecFile({
|
|
1742
1762
|
outputPath,
|
|
1743
|
-
name: readOption(argv, "--name") ?? (engine === "foundation" ? "Foundation chat model" : "Local Tuned Tensor Spec"),
|
|
1763
|
+
name: readOption(argv, "--name") ?? (engine === "foundation" ? "Foundation chat model" : engine === "decision" ? "Local decision model" : "Local Tuned Tensor Spec"),
|
|
1744
1764
|
engine,
|
|
1745
|
-
baseModel: engine === "foundation" ? void 0 : readOption(argv, "--model") ?? "Qwen/Qwen3.5-2B",
|
|
1765
|
+
baseModel: engine === "foundation" ? void 0 : readOption(argv, "--model") ?? (engine === "decision" ? void 0 : "Qwen/Qwen3.5-2B"),
|
|
1746
1766
|
force: hasFlag(argv, "--force")
|
|
1747
1767
|
});
|
|
1748
1768
|
const configPath = void 0;
|
|
@@ -1770,16 +1790,52 @@ async function main(argv) {
|
|
|
1770
1790
|
});
|
|
1771
1791
|
return;
|
|
1772
1792
|
}
|
|
1793
|
+
if (loaded.kind === "decision-spec") {
|
|
1794
|
+
const validation = validateBehaviorSpec(loaded);
|
|
1795
|
+
if (!validation.valid) throw new Error(`Invalid decision spec:
|
|
1796
|
+
${validation.errors.join("\n")}`);
|
|
1797
|
+
printJson({
|
|
1798
|
+
ok: true,
|
|
1799
|
+
input_path: loaded.path,
|
|
1800
|
+
engine: "decision",
|
|
1801
|
+
base_model: loaded.spec.base_model,
|
|
1802
|
+
warnings: validation.warnings,
|
|
1803
|
+
pipeline: "tt pipeline run --spec"
|
|
1804
|
+
});
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1773
1807
|
if (loaded.kind !== "spec") {
|
|
1774
1808
|
throw new Error(`TT expects a tunedtensor.json behavior spec, not a full run request: ${loaded.path}`);
|
|
1775
1809
|
}
|
|
1776
1810
|
const input = loaded;
|
|
1777
1811
|
assertLocalRunInputReady(input.request);
|
|
1778
1812
|
const configSelection = await configSelectionFromArgv(argv, inputPath);
|
|
1779
|
-
const
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1813
|
+
const remoteDataset = huggingFaceDataset(input.request);
|
|
1814
|
+
let validated;
|
|
1815
|
+
try {
|
|
1816
|
+
validated = await validateLocalFineTuneInput({
|
|
1817
|
+
request: input.request,
|
|
1818
|
+
config: configSelection.config
|
|
1819
|
+
});
|
|
1820
|
+
} catch (error) {
|
|
1821
|
+
if (!(error instanceof DatasetNotDownloadedError) || !remoteDataset) throw error;
|
|
1822
|
+
const config2 = localRunnerConfigSchema.parse(configSelection.config);
|
|
1823
|
+
printJson({
|
|
1824
|
+
ok: true,
|
|
1825
|
+
input_path: input.path,
|
|
1826
|
+
config_path: configSelection.path ?? null,
|
|
1827
|
+
behavior_spec_id: input.request.behavior_spec_id,
|
|
1828
|
+
base_model: input.request.spec_snapshot.base_model,
|
|
1829
|
+
dataset_format: remoteDataset.format,
|
|
1830
|
+
dataset_status: "not_downloaded",
|
|
1831
|
+
dataset_huggingface: remoteDataset.huggingface,
|
|
1832
|
+
next_step: `tt datasets prefetch ${relative(cwd(), input.path) || input.path}`,
|
|
1833
|
+
artifact_root: config2.artifactRoot,
|
|
1834
|
+
store_root: config2.storeRoot,
|
|
1835
|
+
dry_run: config2.dryRun
|
|
1836
|
+
});
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1783
1839
|
const request = validated.request;
|
|
1784
1840
|
const config = validated.config;
|
|
1785
1841
|
printJson({
|
|
@@ -1789,6 +1845,7 @@ async function main(argv) {
|
|
|
1789
1845
|
behavior_spec_id: request.behavior_spec_id,
|
|
1790
1846
|
base_model: request.spec_snapshot.base_model,
|
|
1791
1847
|
dataset_format: request.dataset_prebuilt?.format ?? null,
|
|
1848
|
+
...request.dataset_source ? { dataset_status: "cached", dataset_source: request.dataset_source } : {},
|
|
1792
1849
|
artifact_root: config.artifactRoot,
|
|
1793
1850
|
store_root: config.storeRoot,
|
|
1794
1851
|
dry_run: config.dryRun
|
|
@@ -1805,15 +1862,16 @@ async function main(argv) {
|
|
|
1805
1862
|
dryRun: hasFlag(argv, "--dry-run") ? true : configInput.dryRun
|
|
1806
1863
|
});
|
|
1807
1864
|
assertLocalRunInputReady(input.request);
|
|
1808
|
-
const validated = await validateLocalFineTuneInput({
|
|
1809
|
-
request: input.request,
|
|
1810
|
-
config
|
|
1811
|
-
});
|
|
1812
|
-
let request = validated.request;
|
|
1813
1865
|
const reporter = createConsoleReporter({
|
|
1814
1866
|
verbose: hasFlag(argv, "--verbose"),
|
|
1815
1867
|
quiet: hasFlag(argv, "--quiet")
|
|
1816
1868
|
});
|
|
1869
|
+
const ensured = await ensureDatasetCached({ request: input.request, config, reporter });
|
|
1870
|
+
const validated = await validateLocalFineTuneInput({
|
|
1871
|
+
request: ensured.request,
|
|
1872
|
+
config
|
|
1873
|
+
});
|
|
1874
|
+
let request = validated.request;
|
|
1817
1875
|
if (!config.dryRun && !config.paths.baseModel && !request.hyperparameters.base_model_revision) {
|
|
1818
1876
|
const prefetch = await prefetchBaseModel({
|
|
1819
1877
|
request,
|
|
@@ -1831,12 +1889,13 @@ async function main(argv) {
|
|
|
1831
1889
|
}
|
|
1832
1890
|
});
|
|
1833
1891
|
}
|
|
1892
|
+
const specFile = /^\..+\.tt-local-/.test(basename(input.path)) ? void 0 : { path: input.path, sha256: specHash(await readFile2(input.path, "utf8")) };
|
|
1834
1893
|
if (input.spec.pipeline) {
|
|
1835
|
-
const result2 = await runLocalPipeline({ request, config, reporter, pipeline: pipelineForRunInput(input), projectSpec: input.spec });
|
|
1894
|
+
const result2 = await runLocalPipeline({ request, config, reporter, pipeline: pipelineForRunInput(input), projectSpec: input.spec, specFile });
|
|
1836
1895
|
printJson(result2);
|
|
1837
1896
|
return;
|
|
1838
1897
|
}
|
|
1839
|
-
const result = await runLocalFineTune({ request, config, reporter });
|
|
1898
|
+
const result = await runLocalFineTune({ request, config, reporter, specFile });
|
|
1840
1899
|
printJson({
|
|
1841
1900
|
status: result.report.status,
|
|
1842
1901
|
run_id: result.report.run_id,
|
|
@@ -1884,6 +1943,14 @@ async function main(argv) {
|
|
|
1884
1943
|
if (!id) throw new Error("runs report requires <run-id>");
|
|
1885
1944
|
return printJson(await store.getRunReport(id));
|
|
1886
1945
|
}
|
|
1946
|
+
if (subcommand === "audit") {
|
|
1947
|
+
const id = cli.positionals[0];
|
|
1948
|
+
if (!id) throw new Error("runs audit requires <run-id>");
|
|
1949
|
+
const audit = await auditRun(store, id);
|
|
1950
|
+
printJson(audit);
|
|
1951
|
+
if (audit.verdict === "tampered") process.exitCode = 2;
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1887
1954
|
if (subcommand === "compare") {
|
|
1888
1955
|
const idA = cli.positionals[0];
|
|
1889
1956
|
const idB = cli.positionals[1];
|
|
@@ -1896,6 +1963,23 @@ async function main(argv) {
|
|
|
1896
1963
|
}
|
|
1897
1964
|
throw new Error(`Unknown runs command: ${subcommand}`);
|
|
1898
1965
|
}
|
|
1966
|
+
if (command === "datasets") {
|
|
1967
|
+
const subcommand = cli.subcommand;
|
|
1968
|
+
const inputPath = resolve3(cli.positionals[0] ?? DEFAULT_LOCAL_SPEC_PATH);
|
|
1969
|
+
const config = await configFromArgv(argv, inputPath);
|
|
1970
|
+
const input = await loadCliBehaviorSpec(inputPath);
|
|
1971
|
+
if (subcommand !== "prefetch" && subcommand !== "verify") throw new Error(`Unknown datasets command: ${subcommand}`);
|
|
1972
|
+
const report = await prefetchHuggingFaceDataset({
|
|
1973
|
+
request: input.request,
|
|
1974
|
+
config,
|
|
1975
|
+
localOnly: subcommand === "verify",
|
|
1976
|
+
reporter: createConsoleReporter({
|
|
1977
|
+
verbose: hasFlag(argv, "--verbose"),
|
|
1978
|
+
quiet: hasFlag(argv, "--quiet")
|
|
1979
|
+
})
|
|
1980
|
+
});
|
|
1981
|
+
return printJson({ ...report, input_path: input.path });
|
|
1982
|
+
}
|
|
1899
1983
|
if (command === "models") {
|
|
1900
1984
|
const subcommand = cli.subcommand;
|
|
1901
1985
|
const modelInputPath = subcommand === "prefetch" || subcommand === "verify-base" ? resolve3(cli.positionals[0] ?? DEFAULT_LOCAL_SPEC_PATH) : void 0;
|
|
@@ -2011,8 +2095,15 @@ export {
|
|
|
2011
2095
|
comparisonReportSchema,
|
|
2012
2096
|
compileSpecToJsonl,
|
|
2013
2097
|
createLocalStore,
|
|
2098
|
+
datasetColumnsSchema,
|
|
2014
2099
|
datasetFormatSchema,
|
|
2100
|
+
datasetInputIdentity,
|
|
2015
2101
|
datasetPrebuiltSchema,
|
|
2102
|
+
datasetSourceSchema,
|
|
2103
|
+
decisionHyperparametersSchema,
|
|
2104
|
+
decisionLabels,
|
|
2105
|
+
decisionPlaceholderIssues,
|
|
2106
|
+
decisionQuestionSchema,
|
|
2016
2107
|
defaultLocalHome,
|
|
2017
2108
|
evalExampleResultSchema,
|
|
2018
2109
|
evalReportSchema,
|
|
@@ -2032,9 +2123,13 @@ export {
|
|
|
2032
2123
|
getActiveModel,
|
|
2033
2124
|
getLocalRunnerInfo,
|
|
2034
2125
|
hardenExistingLocalStore,
|
|
2126
|
+
huggingFaceDatasetSourceSchema,
|
|
2127
|
+
huggingFaceRepoIdSchema,
|
|
2035
2128
|
initLocalRunnerConfigFile,
|
|
2036
2129
|
initLocalSpecFile,
|
|
2130
|
+
isDecisionSpecFile,
|
|
2037
2131
|
isFoundationSpecFile,
|
|
2132
|
+
isRepoRelativePath,
|
|
2038
2133
|
isTerminalRunState,
|
|
2039
2134
|
jsonFieldMetricsSchema,
|
|
2040
2135
|
loadJsonFile,
|
|
@@ -2043,6 +2138,7 @@ export {
|
|
|
2043
2138
|
loadRunRequest,
|
|
2044
2139
|
localAdapterSpecFileSchema,
|
|
2045
2140
|
localBehaviorSpecFileSchema,
|
|
2141
|
+
localDecisionSpecFileSchema,
|
|
2046
2142
|
localFoundationSpecFileSchema,
|
|
2047
2143
|
localPathsOverlap,
|
|
2048
2144
|
localRunnerConfigSchema,
|
|
@@ -2057,8 +2153,10 @@ export {
|
|
|
2057
2153
|
rollbackActiveModel,
|
|
2058
2154
|
runLocalFineTune,
|
|
2059
2155
|
runLocalPipeline,
|
|
2156
|
+
runProvenanceSchema,
|
|
2060
2157
|
runReportSchema,
|
|
2061
2158
|
runRequestFromLocalSpec,
|
|
2159
|
+
safeName,
|
|
2062
2160
|
sanitizeLogLine,
|
|
2063
2161
|
serveLocalModel,
|
|
2064
2162
|
specHash,
|