@simulatte/doppler 0.1.6 → 0.1.7
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 +126 -0
- package/README.md +16 -23
- package/package.json +14 -1
- package/src/adapters/adapter-registry.js +12 -1
- package/src/adapters/lora-loader.js +23 -6
- package/src/bridge/extension-client.d.ts +5 -0
- package/src/bridge/extension-client.js +40 -0
- package/src/bridge/index.d.ts +2 -1
- package/src/bridge/index.js +6 -4
- package/src/browser/browser-converter.js +26 -1
- package/src/browser/file-picker.js +6 -0
- package/src/browser/safetensors-parser-browser.js +84 -1
- package/src/browser/shard-io-browser.js +2 -2
- package/src/browser/tensor-source-download.js +8 -2
- package/src/browser/tensor-source-http.d.ts +1 -0
- package/src/browser/tensor-source-http.js +5 -1
- package/src/client/doppler-api.browser.js +20 -4
- package/src/client/doppler-api.js +19 -3
- package/src/client/doppler-provider/generation.js +12 -0
- package/src/client/doppler-provider/model-manager.d.ts +10 -0
- package/src/client/doppler-provider/model-manager.js +91 -19
- package/src/client/doppler-provider/source-runtime.d.ts +2 -1
- package/src/client/doppler-provider/source-runtime.js +132 -13
- package/src/client/doppler-registry.json +8 -7
- package/src/config/backward-registry-loader.js +17 -2
- package/src/config/execution-v0-contract-check.js +113 -15
- package/src/config/kernel-path-contract-check.js +57 -29
- package/src/config/kernel-path-loader.js +5 -36
- package/src/config/kernels/kernel-ref-digests.js +1 -1
- package/src/config/kernels/registry.js +14 -1
- package/src/config/kernels/registry.json +7 -5
- package/src/config/loader.d.ts +1 -1
- package/src/config/loader.js +12 -2
- package/src/config/merge-contract-check.js +59 -4
- package/src/config/merge-helpers.js +128 -7
- package/src/config/merge.d.ts +1 -0
- package/src/config/merge.js +10 -0
- package/src/config/param-validator.js +47 -2
- package/src/config/presets/kernel-paths/{gemma2-q4k-dequant-f32a.json → gemma2-q4k-dequant-f32a-nosubgroups.json} +3 -3
- package/src/config/presets/kernel-paths/gemma3-f16-fused-f32a-online-streamingprefill.json +223 -0
- package/src/config/presets/kernel-paths/{gemma3-q4k-dequant-f32a.json → gemma3-q4k-dequant-f32a-nosubgroups.json} +3 -3
- package/src/config/presets/kernel-paths/registry.json +29 -8
- package/src/config/presets/models/gemma2.json +2 -2
- package/src/config/presets/runtime/experiments/bench/gemma3-bench-q4k.json +1 -1
- package/src/config/presets/runtime/experiments/debug/gemma3-debug-q4k.json +1 -1
- package/src/config/presets/runtime/experiments/verify/gemma3-verify.json +1 -1
- package/src/config/presets/runtime/kernels/dequant-f16-q4k.json +6 -13
- package/src/config/presets/runtime/kernels/dequant-f32-q4k.json +6 -13
- package/src/config/presets/runtime/kernels/embeddinggemma-q4k-dequant-f32a.json +37 -0
- package/src/config/presets/runtime/kernels/fused-q4k.json +6 -13
- package/src/config/presets/runtime/kernels/gemma2-q4k-dequant-f16a.json +33 -0
- package/src/config/presets/runtime/kernels/gemma2-q4k-dequant-f32a-nosubgroups.json +33 -0
- package/src/config/presets/runtime/kernels/gemma2-q4k-fused-f32a.json +33 -0
- package/src/config/presets/runtime/kernels/safe-q4k.json +6 -13
- package/src/config/presets/runtime/platform/metal-apple-q4k.json +1 -1
- package/src/config/runtime.js +6 -1
- package/src/config/schema/debug.schema.d.ts +5 -0
- package/src/config/schema/doppler.schema.js +16 -21
- package/src/config/schema/inference-defaults.schema.js +3 -3
- package/src/config/schema/kernel-path.schema.d.ts +5 -1
- package/src/config/schema/kernel-thresholds.schema.js +12 -4
- package/src/config/schema/manifest.schema.d.ts +2 -1
- package/src/config/schema/manifest.schema.js +16 -3
- package/src/config/training-defaults.js +30 -22
- package/src/converter/conversion-plan.js +94 -9
- package/src/converter/core.d.ts +7 -0
- package/src/converter/core.js +14 -9
- package/src/converter/execution-v0-manifest.js +4 -1
- package/src/converter/index.d.ts +1 -0
- package/src/converter/index.js +1 -0
- package/src/converter/manifest-inference.js +43 -12
- package/src/converter/parsers/diffusion.js +0 -3
- package/src/converter/quantization-info.js +35 -15
- package/src/converter/shard-packer.d.ts +1 -1
- package/src/converter/shard-packer.js +4 -1
- package/src/debug/config.js +123 -11
- package/src/debug/signals.js +7 -1
- package/src/debug/tensor.d.ts +2 -0
- package/src/debug/tensor.js +13 -2
- package/src/distribution/p2p-control-plane.js +52 -12
- package/src/distribution/p2p-observability.js +43 -7
- package/src/distribution/p2p-webrtc-browser.js +20 -0
- package/src/distribution/shard-delivery.js +77 -26
- package/src/formats/gguf/types.js +33 -16
- package/src/formats/rdrr/groups.d.ts +12 -4
- package/src/formats/rdrr/groups.js +3 -6
- package/src/formats/rdrr/parsing.js +39 -2
- package/src/formats/rdrr/types.d.ts +2 -1
- package/src/gpu/command-recorder.js +86 -61
- package/src/gpu/device.d.ts +1 -0
- package/src/gpu/device.js +73 -19
- package/src/gpu/kernel-tuner/benchmarks.js +326 -316
- package/src/gpu/kernel-tuner/cache.js +71 -4
- package/src/gpu/kernel-tuner/tuner.js +22 -4
- package/src/gpu/kernels/attention.js +15 -34
- package/src/gpu/kernels/backward/adam.js +62 -58
- package/src/gpu/kernels/backward/attention_backward.js +257 -169
- package/src/gpu/kernels/backward/conv2d_backward.js +14 -1
- package/src/gpu/kernels/cast.js +191 -149
- package/src/gpu/kernels/check-stop.js +33 -44
- package/src/gpu/kernels/conv2d.js +27 -17
- package/src/gpu/kernels/cross_entropy_loss.js +21 -15
- package/src/gpu/kernels/depthwise_conv2d.js +36 -26
- package/src/gpu/kernels/dequant.js +178 -126
- package/src/gpu/kernels/energy.d.ts +3 -21
- package/src/gpu/kernels/energy.js +111 -88
- package/src/gpu/kernels/feature-check.js +1 -1
- package/src/gpu/kernels/fused_ffn.js +84 -65
- package/src/gpu/kernels/fused_matmul_residual.js +56 -33
- package/src/gpu/kernels/fused_matmul_rmsnorm.js +62 -45
- package/src/gpu/kernels/gather.js +33 -15
- package/src/gpu/kernels/gelu.js +19 -11
- package/src/gpu/kernels/grouped_pointwise_conv2d.js +33 -23
- package/src/gpu/kernels/groupnorm.js +34 -23
- package/src/gpu/kernels/kv-quantize.js +5 -2
- package/src/gpu/kernels/layernorm.js +35 -19
- package/src/gpu/kernels/logit-merge.js +5 -3
- package/src/gpu/kernels/matmul.js +58 -39
- package/src/gpu/kernels/modulate.js +23 -15
- package/src/gpu/kernels/moe.js +221 -175
- package/src/gpu/kernels/pixel_shuffle.js +22 -14
- package/src/gpu/kernels/relu.js +18 -10
- package/src/gpu/kernels/repeat_channels.js +25 -17
- package/src/gpu/kernels/residual.js +37 -27
- package/src/gpu/kernels/rmsnorm.js +57 -41
- package/src/gpu/kernels/rope.js +3 -0
- package/src/gpu/kernels/sample.js +27 -38
- package/src/gpu/kernels/sana_linear_attention.js +18 -10
- package/src/gpu/kernels/scale.js +18 -11
- package/src/gpu/kernels/shader-cache.js +4 -2
- package/src/gpu/kernels/silu.js +120 -72
- package/src/gpu/kernels/softmax.js +44 -25
- package/src/gpu/kernels/split_qkv.js +23 -13
- package/src/gpu/kernels/transpose.js +18 -10
- package/src/gpu/kernels/transpose.wgsl +5 -3
- package/src/gpu/kernels/upsample2d.js +21 -13
- package/src/gpu/kernels/utils.js +20 -13
- package/src/gpu/partitioned-buffer-pool.js +10 -2
- package/src/gpu/perf-guards.js +2 -9
- package/src/gpu/profiler.js +27 -22
- package/src/gpu/readback-utils.d.ts +16 -0
- package/src/gpu/readback-utils.js +41 -0
- package/src/gpu/submit-tracker.js +13 -0
- package/src/gpu/uniform-cache.d.ts +1 -0
- package/src/gpu/uniform-cache.js +30 -9
- package/src/hotswap/intent-bundle.js +6 -0
- package/src/hotswap/manifest.d.ts +10 -1
- package/src/hotswap/manifest.js +12 -2
- package/src/hotswap/runtime.js +30 -8
- package/src/index-browser.d.ts +44 -0
- package/src/index-browser.js +14 -0
- package/src/inference/browser-harness-contract-helpers.d.ts +5 -0
- package/src/inference/browser-harness-contract-helpers.js +28 -0
- package/src/inference/browser-harness-diffusion-energy-suites.d.ts +2 -0
- package/src/inference/browser-harness-diffusion-energy-suites.js +269 -0
- package/src/inference/browser-harness-model-helpers.d.ts +16 -0
- package/src/inference/browser-harness-model-helpers.js +217 -0
- package/src/inference/browser-harness-report-helpers.d.ts +7 -0
- package/src/inference/browser-harness-report-helpers.js +42 -0
- package/src/inference/browser-harness-runtime-helpers.d.ts +61 -0
- package/src/inference/browser-harness-runtime-helpers.js +415 -0
- package/src/inference/browser-harness-suite-helpers.d.ts +28 -0
- package/src/inference/browser-harness-suite-helpers.js +268 -0
- package/src/inference/browser-harness-text-helpers.d.ts +27 -0
- package/src/inference/browser-harness-text-helpers.js +788 -0
- package/src/inference/browser-harness.d.ts +6 -0
- package/src/inference/browser-harness.js +130 -1996
- package/src/inference/kv-cache/base.js +140 -94
- package/src/inference/kv-cache/tiered.js +5 -3
- package/src/inference/moe-router.js +88 -56
- package/src/inference/multi-model-network.js +5 -3
- package/src/inference/network-evolution.d.ts +11 -2
- package/src/inference/network-evolution.js +20 -21
- package/src/inference/pipelines/context.d.ts +3 -0
- package/src/inference/pipelines/context.js +142 -2
- package/src/inference/pipelines/diffusion/helpers.js +7 -2
- package/src/inference/pipelines/diffusion/pipeline.js +2 -1
- package/src/inference/pipelines/diffusion/sd3-transformer.js +10 -10
- package/src/inference/pipelines/diffusion/vae.js +3 -7
- package/src/inference/pipelines/energy/pipeline.js +27 -21
- package/src/inference/pipelines/energy/quintel.d.ts +5 -0
- package/src/inference/pipelines/energy/quintel.js +11 -0
- package/src/inference/pipelines/energy-head/row-head-pipeline.js +17 -13
- package/src/inference/pipelines/structured/json-head-pipeline.js +26 -11
- package/src/inference/pipelines/text/attention/projections.js +151 -101
- package/src/inference/pipelines/text/attention/record.js +62 -8
- package/src/inference/pipelines/text/attention/run.js +62 -8
- package/src/inference/pipelines/text/config.js +3 -4
- package/src/inference/pipelines/text/embed.js +2 -8
- package/src/inference/pipelines/text/execution-plan.js +41 -19
- package/src/inference/pipelines/text/execution-v0-contract-helpers.d.ts +59 -0
- package/src/inference/pipelines/text/execution-v0-contract-helpers.js +937 -0
- package/src/inference/pipelines/text/execution-v0-runtime-builders.d.ts +15 -0
- package/src/inference/pipelines/text/execution-v0-runtime-builders.js +279 -0
- package/src/inference/pipelines/text/execution-v0.js +62 -1013
- package/src/inference/pipelines/text/generator-steps.d.ts +46 -0
- package/src/inference/pipelines/text/generator-steps.js +298 -207
- package/src/inference/pipelines/text/generator.js +6 -23
- package/src/inference/pipelines/text/init.js +78 -20
- package/src/inference/pipelines/text/kernel-path-auto-select.js +2 -0
- package/src/inference/pipelines/text/kernel-trace.d.ts +2 -0
- package/src/inference/pipelines/text/kernel-trace.js +6 -0
- package/src/inference/pipelines/text/layer.js +3 -9
- package/src/inference/pipelines/text/linear-attention.d.ts +10 -0
- package/src/inference/pipelines/text/linear-attention.js +80 -6
- package/src/inference/pipelines/text/logits/gpu.js +10 -5
- package/src/inference/pipelines/text/logits/index.js +10 -11
- package/src/inference/pipelines/text/logits/utils.d.ts +7 -0
- package/src/inference/pipelines/text/logits/utils.js +9 -0
- package/src/inference/pipelines/text/lora-apply.js +50 -32
- package/src/inference/pipelines/text/model-load.js +279 -104
- package/src/inference/pipelines/text/moe-cache.js +5 -4
- package/src/inference/pipelines/text/moe-cpu-gptoss.js +74 -69
- package/src/inference/pipelines/text/moe-cpu.js +42 -38
- package/src/inference/pipelines/text/moe-gpu.js +110 -86
- package/src/inference/pipelines/text/ops.js +90 -90
- package/src/inference/pipelines/text/probes.js +9 -9
- package/src/inference/pipelines/text/weights.js +17 -7
- package/src/inference/pipelines/text.js +13 -1
- package/src/inference/speculative.d.ts +2 -2
- package/src/inference/speculative.js +4 -18
- package/src/inference/test-harness.d.ts +1 -1
- package/src/inference/test-harness.js +15 -5
- package/src/inference/tokenizer.d.ts +0 -5
- package/src/inference/tokenizer.js +4 -23
- package/src/inference/tokenizers/bpe.js +9 -0
- package/src/inference/tokenizers/bundled.js +20 -0
- package/src/inference/tokenizers/sentencepiece.js +12 -0
- package/src/loader/doppler-loader.js +38 -22
- package/src/loader/dtype-utils.js +3 -44
- package/src/loader/embedding-loader.js +7 -3
- package/src/loader/experts/expert-cache.js +13 -6
- package/src/loader/experts/expert-loader.js +10 -6
- package/src/loader/final-weights-loader.js +8 -4
- package/src/loader/layer-loader.js +2 -1
- package/src/loader/loader-state.js +2 -2
- package/src/loader/memory-monitor.js +8 -0
- package/src/loader/multi-model-loader.d.ts +14 -0
- package/src/loader/multi-model-loader.js +70 -24
- package/src/loader/shard-cache.js +81 -12
- package/src/loader/shard-resolver.js +25 -3
- package/src/loader/tensors/tensor-loader.js +209 -144
- package/src/loader/tensors/tensor-reader.js +76 -19
- package/src/loader/weight-downcast.js +1 -1
- package/src/memory/buffer-pool.d.ts +9 -1
- package/src/memory/buffer-pool.js +109 -44
- package/src/memory/unified-detect.js +1 -1
- package/src/rules/inference/kernel-path.rules.json +24 -8
- package/src/rules/rule-registry.js +25 -1
- package/src/storage/backends/opfs-store.js +68 -24
- package/src/storage/downloader.js +364 -83
- package/src/storage/index.d.ts +3 -0
- package/src/storage/index.js +3 -0
- package/src/storage/preflight.d.ts +2 -2
- package/src/storage/preflight.js +24 -2
- package/src/storage/quickstart-downloader.js +11 -5
- package/src/storage/registry.js +10 -4
- package/src/storage/reports.js +1 -1
- package/src/storage/shard-manager.d.ts +15 -1
- package/src/storage/shard-manager.js +51 -3
- package/src/storage/source-artifact-store.d.ts +52 -0
- package/src/storage/source-artifact-store.js +234 -0
- package/src/tooling/command-api-constants.d.ts +9 -0
- package/src/tooling/command-api-constants.js +9 -0
- package/src/tooling/command-api-family-normalizers.d.ts +9 -0
- package/src/tooling/command-api-family-normalizers.js +343 -0
- package/src/tooling/command-api-helpers.d.ts +25 -0
- package/src/tooling/command-api-helpers.js +262 -0
- package/src/tooling/command-api.js +16 -602
- package/src/tooling/command-envelope.js +4 -1
- package/src/tooling/command-runner-shared.js +52 -18
- package/src/tooling/lean-execution-contract.js +150 -3
- package/src/tooling/node-browser-command-runner.js +161 -271
- package/src/tooling/node-command-runner.js +29 -3
- package/src/tooling/node-converter.js +27 -1
- package/src/tooling/node-source-runtime.d.ts +1 -1
- package/src/tooling/node-source-runtime.js +84 -3
- package/src/tooling/node-webgpu.js +24 -21
- package/src/tooling/opfs-cache.js +21 -4
- package/src/tooling/runtime-input-composition.d.ts +38 -0
- package/src/tooling/runtime-input-composition.js +86 -0
- package/src/tooling/source-runtime-bundle.d.ts +40 -5
- package/src/tooling/source-runtime-bundle.js +261 -34
- package/src/tooling/source-runtime-materializer.d.ts +6 -0
- package/src/tooling/source-runtime-materializer.js +93 -0
- package/src/training/attention-backward.js +32 -17
- package/src/training/autograd.js +80 -52
- package/src/training/checkpoint-watch.d.ts +2 -1
- package/src/training/checkpoint-watch.js +39 -6
- package/src/training/checkpoint.js +40 -11
- package/src/training/clip.js +2 -1
- package/src/training/datasets/token-batch.js +20 -8
- package/src/training/distillation/checkpoint-watch.js +1 -0
- package/src/training/distillation/student-fixture.d.ts +22 -0
- package/src/training/distillation/student-fixture.js +846 -0
- package/src/training/distillation/suite-data.d.ts +45 -0
- package/src/training/distillation/suite-data.js +189 -0
- package/src/training/lora-pipeline.js +4 -7
- package/src/training/lora.js +26 -12
- package/src/training/loss.js +5 -6
- package/src/training/objectives/cross_entropy.js +2 -5
- package/src/training/objectives/distill_kd.js +4 -8
- package/src/training/objectives/distill_triplet.js +4 -8
- package/src/training/objectives/ul_stage2_base.js +4 -8
- package/src/training/operator-command.js +2 -0
- package/src/training/optimizer.js +19 -7
- package/src/training/runner.js +2 -1
- package/src/training/suite.js +18 -978
- package/src/training/tensor-factory.d.ts +9 -0
- package/src/training/tensor-factory.js +13 -0
- package/src/training/trainer.js +3 -5
- package/src/training/ul_dataset.js +3 -5
- package/src/training/workloads.js +70 -79
- package/src/version.js +1 -1
- package/tools/convert-safetensors-node.js +22 -16
- package/tools/doppler-cli.js +44 -25
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { acquireBuffer, releaseBuffer, uploadData } from '../memory/buffer-pool.js';
|
|
2
|
+
import { createTensor } from '../gpu/tensor.js';
|
|
3
|
+
|
|
4
|
+
export function createUploadedTensor(data, dtype, shape, label, usage = undefined) {
|
|
5
|
+
const buffer = acquireBuffer(data.byteLength, usage, label);
|
|
6
|
+
try {
|
|
7
|
+
uploadData(buffer, data);
|
|
8
|
+
return createTensor(buffer, dtype, [...shape], label);
|
|
9
|
+
} catch (error) {
|
|
10
|
+
releaseBuffer(buffer);
|
|
11
|
+
throw error;
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/training/trainer.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { AutogradTape } from './autograd.js';
|
|
2
2
|
import { loadBackwardRegistry } from '../config/backward-registry-loader.js';
|
|
3
3
|
import { runScale } from '../gpu/kernels/index.js';
|
|
4
|
-
import {
|
|
5
|
-
import { createTensor } from '../gpu/tensor.js';
|
|
4
|
+
import { releaseBuffer } from '../memory/buffer-pool.js';
|
|
6
5
|
import { createCrossEntropyObjective } from './objectives/cross_entropy.js';
|
|
6
|
+
import { createUploadedTensor } from './tensor-factory.js';
|
|
7
7
|
|
|
8
8
|
function createLossGradient(loss, lossScale) {
|
|
9
9
|
const lossElements = loss.shape.reduce((acc, value) => acc * value, 1);
|
|
10
10
|
const gradData = new Float32Array(lossElements);
|
|
11
11
|
gradData.fill(lossScale);
|
|
12
|
-
|
|
13
|
-
uploadData(gradBuf, gradData);
|
|
14
|
-
return createTensor(gradBuf, 'f32', [...loss.shape], 'loss_grad_output');
|
|
12
|
+
return createUploadedTensor(gradData, 'f32', loss.shape, 'loss_grad_output');
|
|
15
13
|
}
|
|
16
14
|
|
|
17
15
|
function normalizeLossResult(value) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { createTensor } from '../gpu/tensor.js';
|
|
1
|
+
import { readBuffer, releaseBuffer } from '../memory/buffer-pool.js';
|
|
3
2
|
import { resolveUlScheduledLambda } from './ul_schedule.js';
|
|
3
|
+
import { createUploadedTensor } from './tensor-factory.js';
|
|
4
4
|
|
|
5
5
|
function xorshift32(value) {
|
|
6
6
|
let x = value >>> 0;
|
|
@@ -79,9 +79,7 @@ export async function buildNoisyLatentsFromInputTensor(inputTensor, ulConfig, op
|
|
|
79
79
|
noisy[i] = alpha * inputData[i] + sigma * n;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
const
|
|
83
|
-
uploadData(noisyBuffer, noisy);
|
|
84
|
-
const noisyTensor = createTensor(noisyBuffer, 'f32', [...inputTensor.shape], 'ul_noisy_latents');
|
|
82
|
+
const noisyTensor = createUploadedTensor(noisy, 'f32', inputTensor.shape, 'ul_noisy_latents');
|
|
85
83
|
const cleanStats = summarizeArray(inputData);
|
|
86
84
|
const noiseStats = summarizeArray(noise);
|
|
87
85
|
const noisyStats = summarizeArray(noisy);
|
|
@@ -4,6 +4,11 @@ import { resolve } from 'node:path';
|
|
|
4
4
|
import { isPlainObject } from '../utils/plain-object.js';
|
|
5
5
|
import { sha256Hex } from '../utils/sha256.js';
|
|
6
6
|
import { VALID_LORA_TARGET_MODULES } from '../config/schema/adapter.schema.js';
|
|
7
|
+
import {
|
|
8
|
+
DEFAULT_TRAINING_GRADIENT_CONFIG,
|
|
9
|
+
DEFAULT_TRAINING_OPTIMIZER_CONFIG,
|
|
10
|
+
DEFAULT_TRAINING_PRECISION_CONFIG,
|
|
11
|
+
} from '../config/schema/training.schema.js';
|
|
7
12
|
|
|
8
13
|
export const TRAINING_WORKLOAD_SCHEMA_VERSION = 1;
|
|
9
14
|
export const TRAINING_WORKLOAD_KINDS = Object.freeze(['lora', 'distill', 'ul']);
|
|
@@ -140,64 +145,57 @@ function inferLegacyKind(payload, contextLabel) {
|
|
|
140
145
|
if (explicitKind) return explicitKind;
|
|
141
146
|
const workloadKind = typeof payload?.workloadKind === 'string' ? payload.workloadKind.trim() : '';
|
|
142
147
|
if (workloadKind) return workloadKind;
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
const trainingTests = Array.isArray(payload?.trainingTests)
|
|
149
|
+
? payload.trainingTests.map((entry) => String(entry))
|
|
150
|
+
: null;
|
|
151
|
+
const hasLegacyUlShape = trainingTests
|
|
152
|
+
&& trainingTests.length > 0
|
|
153
|
+
&& trainingTests.every((entry) => entry === 'ul-stage1' || entry === 'ul-stage2')
|
|
154
|
+
&& Number.isInteger(Number(payload?.trainingBenchSteps));
|
|
155
|
+
if (hasLegacyUlShape) {
|
|
147
156
|
return 'ul';
|
|
148
157
|
}
|
|
149
|
-
if (Array.isArray(payload?.trainingTests) && payload.trainingTests.every((entry) => LEGACY_DISTILL_TEST_IDS.includes(String(entry)))) {
|
|
150
|
-
return 'distill';
|
|
151
|
-
}
|
|
152
158
|
throw new Error(`${contextLabel}.kind is required.`);
|
|
153
159
|
}
|
|
154
160
|
|
|
155
161
|
function normalizeScheduler(value, label) {
|
|
156
|
-
const scheduler = asObject(value, label
|
|
162
|
+
const scheduler = asObject(value, label);
|
|
157
163
|
return {
|
|
158
|
-
enabled: scheduler.enabled
|
|
159
|
-
type: asNonEmptyString(scheduler.type
|
|
160
|
-
warmupSteps: asNonNegativeInteger(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
stepSize: asPositiveInteger(scheduler.stepSize ?? 1, `${label}.stepSize`, { optional: true }) ?? 1,
|
|
166
|
-
gamma: asFiniteNumber(scheduler.gamma ?? 1, `${label}.gamma`, { optional: true }) ?? 1,
|
|
167
|
-
totalSteps: asPositiveInteger(scheduler.totalSteps ?? 1, `${label}.totalSteps`, { optional: true }) ?? 1,
|
|
168
|
-
minLr: asFiniteNumber(scheduler.minLr ?? 0, `${label}.minLr`, { optional: true }) ?? 0,
|
|
164
|
+
enabled: asBoolean(scheduler.enabled, `${label}.enabled`),
|
|
165
|
+
type: asNonEmptyString(scheduler.type, `${label}.type`),
|
|
166
|
+
warmupSteps: asNonNegativeInteger(scheduler.warmupSteps, `${label}.warmupSteps`),
|
|
167
|
+
stepSize: asPositiveInteger(scheduler.stepSize, `${label}.stepSize`),
|
|
168
|
+
gamma: asFiniteNumber(scheduler.gamma, `${label}.gamma`),
|
|
169
|
+
totalSteps: asPositiveInteger(scheduler.totalSteps, `${label}.totalSteps`),
|
|
170
|
+
minLr: asFiniteNumber(scheduler.minLr, `${label}.minLr`),
|
|
169
171
|
};
|
|
170
172
|
}
|
|
171
173
|
|
|
172
174
|
function normalizeTrainingConfig(value, label) {
|
|
173
175
|
const training = asObject(value, label);
|
|
174
176
|
const optimizer = asObject(training.optimizer, `${label}.optimizer`);
|
|
175
|
-
const precision =
|
|
176
|
-
|
|
177
|
-
: { activations: training.precision ?? 'f16' };
|
|
178
|
-
const gradientClipping = isPlainObject(training.gradientClipping)
|
|
179
|
-
? training.gradientClipping
|
|
180
|
-
: { maxNorm: training.gradientClipping ?? 1 };
|
|
177
|
+
const precision = asObject(training.precision, `${label}.precision`);
|
|
178
|
+
const gradientClipping = asObject(training.gradientClipping, `${label}.gradientClipping`);
|
|
181
179
|
return {
|
|
182
180
|
optimizer: {
|
|
183
|
-
type: asNonEmptyString(optimizer.type
|
|
181
|
+
type: asNonEmptyString(optimizer.type, `${label}.optimizer.type`),
|
|
184
182
|
lr: asFiniteNumber(optimizer.lr, `${label}.optimizer.lr`),
|
|
185
|
-
beta1: asFiniteNumber(optimizer.beta1
|
|
186
|
-
beta2: asFiniteNumber(optimizer.beta2
|
|
187
|
-
eps: asFiniteNumber(optimizer.eps
|
|
188
|
-
weightDecay: asFiniteNumber(optimizer.weightDecay
|
|
183
|
+
beta1: asFiniteNumber(optimizer.beta1, `${label}.optimizer.beta1`),
|
|
184
|
+
beta2: asFiniteNumber(optimizer.beta2, `${label}.optimizer.beta2`),
|
|
185
|
+
eps: asFiniteNumber(optimizer.eps, `${label}.optimizer.eps`),
|
|
186
|
+
weightDecay: asFiniteNumber(optimizer.weightDecay, `${label}.optimizer.weightDecay`),
|
|
189
187
|
scheduler: normalizeScheduler(optimizer.scheduler, `${label}.optimizer.scheduler`),
|
|
190
188
|
},
|
|
191
189
|
batchSize: asPositiveInteger(training.batchSize, `${label}.batchSize`),
|
|
192
|
-
accumSteps: asPositiveInteger(training.accumSteps
|
|
190
|
+
accumSteps: asPositiveInteger(training.accumSteps, `${label}.accumSteps`),
|
|
193
191
|
steps: asPositiveInteger(training.steps, `${label}.steps`),
|
|
194
192
|
precision: {
|
|
195
|
-
activations: asNonEmptyString(precision.activations
|
|
196
|
-
gradients: asNonEmptyString(precision.gradients
|
|
197
|
-
loraParams: asNonEmptyString(precision.loraParams
|
|
193
|
+
activations: asNonEmptyString(precision.activations, `${label}.precision.activations`),
|
|
194
|
+
gradients: asNonEmptyString(precision.gradients, `${label}.precision.gradients`),
|
|
195
|
+
loraParams: asNonEmptyString(precision.loraParams, `${label}.precision.loraParams`),
|
|
198
196
|
},
|
|
199
197
|
gradientClipping: {
|
|
200
|
-
maxNorm: asFiniteNumber(gradientClipping.maxNorm
|
|
198
|
+
maxNorm: asFiniteNumber(gradientClipping.maxNorm, `${label}.gradientClipping.maxNorm`),
|
|
201
199
|
},
|
|
202
200
|
};
|
|
203
201
|
}
|
|
@@ -215,7 +213,7 @@ function normalizeEvalDatasets(value, label) {
|
|
|
215
213
|
id: asNonEmptyString(dataset.id, `${label}[${index}].id`),
|
|
216
214
|
datasetPath: asNonEmptyString(dataset.datasetPath ?? dataset.path, `${label}[${index}].datasetPath`),
|
|
217
215
|
evalKind: asEnum(
|
|
218
|
-
dataset.evalKind ?? dataset.kind
|
|
216
|
+
dataset.evalKind ?? dataset.kind,
|
|
219
217
|
`${label}[${index}].evalKind`,
|
|
220
218
|
TRAINING_EVAL_KINDS
|
|
221
219
|
),
|
|
@@ -230,11 +228,7 @@ function normalizeEvalDatasets(value, label) {
|
|
|
230
228
|
`${label}[${index}].decodePolicy.maxTokens`,
|
|
231
229
|
{ optional: true }
|
|
232
230
|
),
|
|
233
|
-
stopOnEos: asBoolean(
|
|
234
|
-
decodePolicy.stopOnEos ?? true,
|
|
235
|
-
`${label}[${index}].decodePolicy.stopOnEos`,
|
|
236
|
-
{ optional: true }
|
|
237
|
-
) ?? true,
|
|
231
|
+
stopOnEos: asBoolean(decodePolicy.stopOnEos, `${label}[${index}].decodePolicy.stopOnEos`),
|
|
238
232
|
}
|
|
239
233
|
: null,
|
|
240
234
|
scoreboardColumns: asStringArray(
|
|
@@ -267,11 +261,11 @@ function normalizeStagePlan(value, label) {
|
|
|
267
261
|
return value.map((entry, index) => {
|
|
268
262
|
const stage = asObject(entry, `${label}[${index}]`);
|
|
269
263
|
const selectionMetric = asNonEmptyString(
|
|
270
|
-
stage.selectionMetric ?? stage.metric
|
|
264
|
+
stage.selectionMetric ?? stage.metric,
|
|
271
265
|
`${label}[${index}].selectionMetric`
|
|
272
266
|
);
|
|
273
267
|
const selectionGoal = asEnum(
|
|
274
|
-
stage.selectionGoal ?? stage.goal
|
|
268
|
+
stage.selectionGoal ?? stage.goal,
|
|
275
269
|
`${label}[${index}].selectionGoal`,
|
|
276
270
|
TRAINING_SELECTION_GOALS
|
|
277
271
|
);
|
|
@@ -281,15 +275,12 @@ function normalizeStagePlan(value, label) {
|
|
|
281
275
|
objective: asNonEmptyString(stage.objective, `${label}[${index}].objective`),
|
|
282
276
|
steps: asPositiveInteger(stage.steps, `${label}[${index}].steps`),
|
|
283
277
|
checkpointEvery: asPositiveInteger(
|
|
284
|
-
stage.checkpointEvery
|
|
278
|
+
stage.checkpointEvery,
|
|
285
279
|
`${label}[${index}].checkpointEvery`
|
|
286
280
|
),
|
|
287
281
|
selectionMetric,
|
|
288
282
|
selectionGoal,
|
|
289
|
-
evalSchedule: asNonEmptyString(
|
|
290
|
-
stage.evalSchedule ?? 'on_checkpoint',
|
|
291
|
-
`${label}[${index}].evalSchedule`
|
|
292
|
-
),
|
|
283
|
+
evalSchedule: asNonEmptyString(stage.evalSchedule, `${label}[${index}].evalSchedule`),
|
|
293
284
|
};
|
|
294
285
|
});
|
|
295
286
|
}
|
|
@@ -306,29 +297,29 @@ function normalizeLoraConfig(value, label) {
|
|
|
306
297
|
}
|
|
307
298
|
}
|
|
308
299
|
return {
|
|
309
|
-
datasetFormat: asNonEmptyString(lora.datasetFormat
|
|
310
|
-
taskType: asNonEmptyString(lora.taskType
|
|
300
|
+
datasetFormat: asNonEmptyString(lora.datasetFormat, `${label}.datasetFormat`),
|
|
301
|
+
taskType: asNonEmptyString(lora.taskType, `${label}.taskType`),
|
|
311
302
|
adapter: {
|
|
312
303
|
rank: asPositiveInteger(adapter.rank, `${label}.adapter.rank`),
|
|
313
304
|
alpha: asFiniteNumber(adapter.alpha, `${label}.adapter.alpha`),
|
|
314
|
-
dropout: asFiniteNumber(adapter.dropout
|
|
305
|
+
dropout: asFiniteNumber(adapter.dropout, `${label}.adapter.dropout`),
|
|
315
306
|
targetModules,
|
|
316
307
|
},
|
|
317
308
|
freeze: normalizeFreezeConfig(lora.freeze, `${label}.freeze`),
|
|
318
309
|
export: exportConfig
|
|
319
310
|
? {
|
|
320
|
-
enabled: exportConfig.enabled
|
|
321
|
-
atCheckpoints: exportConfig.atCheckpoints
|
|
322
|
-
select: asNonEmptyString(exportConfig.select
|
|
311
|
+
enabled: asBoolean(exportConfig.enabled, `${label}.export.enabled`),
|
|
312
|
+
atCheckpoints: asBoolean(exportConfig.atCheckpoints, `${label}.export.atCheckpoints`),
|
|
313
|
+
select: asNonEmptyString(exportConfig.select, `${label}.export.select`),
|
|
323
314
|
id: asNonEmptyString(exportConfig.id, `${label}.export.id`, { optional: true }),
|
|
324
315
|
name: asNonEmptyString(exportConfig.name, `${label}.export.name`, { optional: true }),
|
|
325
|
-
format: asNonEmptyString(exportConfig.format
|
|
316
|
+
format: asNonEmptyString(exportConfig.format, `${label}.export.format`),
|
|
326
317
|
}
|
|
327
318
|
: null,
|
|
328
319
|
activation: activation
|
|
329
320
|
? {
|
|
330
|
-
enabled: activation.enabled
|
|
331
|
-
autoActivate: activation.autoActivate
|
|
321
|
+
enabled: asBoolean(activation.enabled, `${label}.activation.enabled`),
|
|
322
|
+
autoActivate: asBoolean(activation.autoActivate, `${label}.activation.autoActivate`),
|
|
332
323
|
smokePrompt: asNonEmptyString(activation.smokePrompt, `${label}.activation.smokePrompt`, { optional: true }),
|
|
333
324
|
}
|
|
334
325
|
: null,
|
|
@@ -339,27 +330,21 @@ function normalizeDistillConfig(value, label) {
|
|
|
339
330
|
const distill = asObject(value, label);
|
|
340
331
|
return {
|
|
341
332
|
stagePlan: normalizeStagePlan(distill.stagePlan, `${label}.stagePlan`),
|
|
342
|
-
studentGraphMode: asNonEmptyString(
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
),
|
|
346
|
-
|
|
347
|
-
alphaKd: asFiniteNumber(distill.alphaKd ?? 1, `${label}.alphaKd`, { optional: true }) ?? 1,
|
|
348
|
-
alphaCe: asFiniteNumber(distill.alphaCe ?? 0, `${label}.alphaCe`, { optional: true }) ?? 0,
|
|
349
|
-
tripletMargin: asFiniteNumber(distill.tripletMargin ?? 0.2, `${label}.tripletMargin`, { optional: true }) ?? 0.2,
|
|
333
|
+
studentGraphMode: asNonEmptyString(distill.studentGraphMode, `${label}.studentGraphMode`),
|
|
334
|
+
temperature: asFiniteNumber(distill.temperature, `${label}.temperature`),
|
|
335
|
+
alphaKd: asFiniteNumber(distill.alphaKd, `${label}.alphaKd`),
|
|
336
|
+
alphaCe: asFiniteNumber(distill.alphaCe, `${label}.alphaCe`),
|
|
337
|
+
tripletMargin: asFiniteNumber(distill.tripletMargin, `${label}.tripletMargin`),
|
|
350
338
|
sourceLangs: asStringArray(distill.sourceLangs, `${label}.sourceLangs`, { optional: true, allowEmpty: true }),
|
|
351
339
|
targetLangs: asStringArray(distill.targetLangs, `${label}.targetLangs`, { optional: true, allowEmpty: true }),
|
|
352
340
|
pairAllowlist: asStringArray(distill.pairAllowlist, `${label}.pairAllowlist`, { optional: true, allowEmpty: true }),
|
|
353
|
-
strictPairContract: asBoolean(
|
|
354
|
-
distill.strictPairContract ?? false,
|
|
355
|
-
`${label}.strictPairContract`,
|
|
356
|
-
{ optional: true }
|
|
357
|
-
) ?? false,
|
|
341
|
+
strictPairContract: asBoolean(distill.strictPairContract, `${label}.strictPairContract`),
|
|
358
342
|
subsetSpec: asObject(distill.subsetSpec, `${label}.subsetSpec`, { optional: true }),
|
|
359
343
|
};
|
|
360
344
|
}
|
|
361
345
|
|
|
362
346
|
function normalizeLegacyUlPayload(payload, contextLabel) {
|
|
347
|
+
const optimizerOverrides = isPlainObject(payload.training?.optimizer) ? payload.training.optimizer : {};
|
|
363
348
|
return {
|
|
364
349
|
schemaVersion: asPositiveInteger(payload.schemaVersion, `${contextLabel}.schemaVersion`),
|
|
365
350
|
kind: 'ul',
|
|
@@ -393,19 +378,25 @@ function normalizeLegacyUlPayload(payload, contextLabel) {
|
|
|
393
378
|
TRAINING_WORKLOAD_SURFACE_SUPPORT
|
|
394
379
|
),
|
|
395
380
|
training: normalizeTrainingConfig({
|
|
396
|
-
optimizer:
|
|
397
|
-
|
|
398
|
-
|
|
381
|
+
optimizer: {
|
|
382
|
+
...DEFAULT_TRAINING_OPTIMIZER_CONFIG,
|
|
383
|
+
...optimizerOverrides,
|
|
384
|
+
scheduler: {
|
|
385
|
+
...DEFAULT_TRAINING_OPTIMIZER_CONFIG.scheduler,
|
|
386
|
+
...(isPlainObject(optimizerOverrides.scheduler) ? optimizerOverrides.scheduler : {}),
|
|
387
|
+
},
|
|
399
388
|
},
|
|
400
389
|
batchSize: payload.training?.batchSize ?? 1,
|
|
401
|
-
accumSteps: payload.training?.accumSteps ??
|
|
390
|
+
accumSteps: payload.training?.accumSteps ?? DEFAULT_TRAINING_GRADIENT_CONFIG.accumSteps,
|
|
402
391
|
steps: payload.training?.steps ?? payload.trainingBenchSteps ?? 1,
|
|
403
|
-
precision:
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
392
|
+
precision: {
|
|
393
|
+
...DEFAULT_TRAINING_PRECISION_CONFIG,
|
|
394
|
+
...(payload.training?.precision ?? {}),
|
|
395
|
+
},
|
|
396
|
+
gradientClipping: {
|
|
397
|
+
maxNorm: payload.training?.gradientClipping?.maxNorm
|
|
398
|
+
?? DEFAULT_TRAINING_GRADIENT_CONFIG.maxNorm,
|
|
407
399
|
},
|
|
408
|
-
gradientClipping: payload.training?.gradientClipping ?? { maxNorm: 1 },
|
|
409
400
|
}, `${contextLabel}.training`),
|
|
410
401
|
pipeline: {
|
|
411
402
|
legacyWorkloadType: 'ul',
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const DOPPLER_VERSION = '0.1.
|
|
1
|
+
export const DOPPLER_VERSION = '0.1.7';
|
|
2
2
|
export const DOPPLER_PROVIDER_VERSION = DOPPLER_VERSION;
|
|
@@ -14,42 +14,43 @@ function parseArgs(argv) {
|
|
|
14
14
|
const positional = [];
|
|
15
15
|
for (let i = 0; i < argv.length; i += 1) {
|
|
16
16
|
const arg = argv[i];
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const nextValue = () => {
|
|
18
|
+
const value = argv[i + 1];
|
|
19
|
+
if (value == null || String(value).startsWith('--')) {
|
|
20
|
+
throw new Error(`Missing value for ${arg}.`);
|
|
21
|
+
}
|
|
19
22
|
i += 1;
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
if (arg === '--output-dir') {
|
|
26
|
+
out.outputDir = nextValue();
|
|
20
27
|
continue;
|
|
21
28
|
}
|
|
22
29
|
if (arg === '--config') {
|
|
23
|
-
out.configPath =
|
|
24
|
-
i += 1;
|
|
30
|
+
out.configPath = nextValue();
|
|
25
31
|
continue;
|
|
26
32
|
}
|
|
27
33
|
if (arg === '--converter-config') {
|
|
28
34
|
throw new Error('--converter-config has been removed. Use --config <path.json>.');
|
|
29
35
|
}
|
|
30
36
|
if (arg === '--workers') {
|
|
31
|
-
execution.workers =
|
|
32
|
-
i += 1;
|
|
37
|
+
execution.workers = nextValue();
|
|
33
38
|
continue;
|
|
34
39
|
}
|
|
35
40
|
if (arg === '--worker-policy') {
|
|
36
|
-
execution.workerCountPolicy =
|
|
37
|
-
i += 1;
|
|
41
|
+
execution.workerCountPolicy = nextValue();
|
|
38
42
|
continue;
|
|
39
43
|
}
|
|
40
44
|
if (arg === '--row-chunk-rows') {
|
|
41
|
-
execution.rowChunkRows =
|
|
42
|
-
i += 1;
|
|
45
|
+
execution.rowChunkRows = nextValue();
|
|
43
46
|
continue;
|
|
44
47
|
}
|
|
45
48
|
if (arg === '--row-chunk-min-tensor-bytes') {
|
|
46
|
-
execution.rowChunkMinTensorBytes =
|
|
47
|
-
i += 1;
|
|
49
|
+
execution.rowChunkMinTensorBytes = nextValue();
|
|
48
50
|
continue;
|
|
49
51
|
}
|
|
50
52
|
if (arg === '--max-in-flight-jobs') {
|
|
51
|
-
execution.maxInFlightJobs =
|
|
52
|
-
i += 1;
|
|
53
|
+
execution.maxInFlightJobs = nextValue();
|
|
53
54
|
continue;
|
|
54
55
|
}
|
|
55
56
|
if (arg === '--use-gpu-cast') {
|
|
@@ -57,12 +58,17 @@ function parseArgs(argv) {
|
|
|
57
58
|
continue;
|
|
58
59
|
}
|
|
59
60
|
if (arg === '--gpu-cast-min-tensor-bytes') {
|
|
60
|
-
execution.gpuCastMinTensorBytes =
|
|
61
|
-
i += 1;
|
|
61
|
+
execution.gpuCastMinTensorBytes = nextValue();
|
|
62
62
|
continue;
|
|
63
63
|
}
|
|
64
|
+
if (arg.startsWith('--')) {
|
|
65
|
+
throw new Error(`Unknown flag: ${arg}`);
|
|
66
|
+
}
|
|
64
67
|
positional.push(arg);
|
|
65
68
|
}
|
|
69
|
+
if (positional.length > 1) {
|
|
70
|
+
throw new Error(`Unexpected positional arguments: ${positional.slice(1).join(', ')}`);
|
|
71
|
+
}
|
|
66
72
|
out.inputDir = positional[0] ?? null;
|
|
67
73
|
out.execution = Object.keys(execution).length > 0 ? execution : null;
|
|
68
74
|
return out;
|
package/tools/doppler-cli.js
CHANGED
|
@@ -22,8 +22,6 @@ const DEFAULT_CLI_POLICY = {
|
|
|
22
22
|
allowed: ['auto', 'node', 'browser'],
|
|
23
23
|
},
|
|
24
24
|
bench: {
|
|
25
|
-
modelId: 'gemma-3-270m-it-wf16-ef16-hf16',
|
|
26
|
-
surface: 'browser',
|
|
27
25
|
cacheMode: 'warm',
|
|
28
26
|
},
|
|
29
27
|
cacheMode: null,
|
|
@@ -82,7 +80,7 @@ function usage() {
|
|
|
82
80
|
' - run: CLI-only run controls (surface, browser options, and bench save/compare/manifest settings).',
|
|
83
81
|
'',
|
|
84
82
|
'Example:',
|
|
85
|
-
' doppler verify --config \'{"request":{"suite":"inference","modelId":"gemma-3-270m-it-
|
|
83
|
+
' doppler verify --config \'{"request":{"suite":"inference","modelId":"gemma-3-270m-it-f16-af32"}}\' --json',
|
|
86
84
|
].join('\n');
|
|
87
85
|
}
|
|
88
86
|
|
|
@@ -439,10 +437,6 @@ export async function resolveBrowserModelUrl(request, browserOptions = {}) {
|
|
|
439
437
|
const staticRootDir = resolveStaticRootDir(browserOptions);
|
|
440
438
|
const externalModel = await resolveExternalModelDirectory(resolveRdrrRoot(browserOptions), modelId);
|
|
441
439
|
const candidates = [
|
|
442
|
-
{
|
|
443
|
-
modelUrl: `/models/curated/${encodedModelId}`,
|
|
444
|
-
manifestPath: path.join(staticRootDir, 'models', 'curated', modelId, 'manifest.json'),
|
|
445
|
-
},
|
|
446
440
|
{
|
|
447
441
|
modelUrl: `/models/local/${encodedModelId}`,
|
|
448
442
|
manifestPath: path.join(staticRootDir, 'models', 'local', modelId, 'manifest.json'),
|
|
@@ -528,6 +522,9 @@ function parseSurface(value, command, policy = DEFAULT_CLI_POLICY) {
|
|
|
528
522
|
if (command === 'convert' && normalized === 'browser') {
|
|
529
523
|
throw new Error('convert is not supported on browser relay. Use --surface node or --surface auto.');
|
|
530
524
|
}
|
|
525
|
+
if ((command === 'lora' || command === 'distill') && normalized === 'browser') {
|
|
526
|
+
throw new Error(`${command} is not supported on browser relay. Use --surface node or --surface auto.`);
|
|
527
|
+
}
|
|
531
528
|
return normalized;
|
|
532
529
|
}
|
|
533
530
|
|
|
@@ -587,13 +584,10 @@ function resolveBenchRunOptions(runConfig, policy = DEFAULT_CLI_POLICY) {
|
|
|
587
584
|
function resolveSurfaceForCommand(command, parsed, runConfig, policy = DEFAULT_CLI_POLICY) {
|
|
588
585
|
const fromCli = asStringOrNull(parsed.flags.surface);
|
|
589
586
|
const fromRun = asStringOrNull(runConfig?.surface);
|
|
590
|
-
|
|
591
|
-
? asStringOrNull(policy?.defaults?.bench?.surface)
|
|
592
|
-
: null;
|
|
593
|
-
return parseSurface(fromCli ?? fromRun ?? fromPolicy, command, policy);
|
|
587
|
+
return parseSurface(fromCli ?? fromRun ?? null, command, policy);
|
|
594
588
|
}
|
|
595
589
|
|
|
596
|
-
async function buildRequest(parsed, policy = DEFAULT_CLI_POLICY) {
|
|
590
|
+
export async function buildRequest(parsed, policy = DEFAULT_CLI_POLICY) {
|
|
597
591
|
const command = parsed.command;
|
|
598
592
|
if (!command || !TOOLING_COMMANDS.includes(command)) {
|
|
599
593
|
throw new Error(`Unsupported command "${command || ''}"`);
|
|
@@ -612,21 +606,15 @@ async function buildRequest(parsed, policy = DEFAULT_CLI_POLICY) {
|
|
|
612
606
|
}
|
|
613
607
|
requestInput.command = command;
|
|
614
608
|
|
|
615
|
-
if (command === 'bench' && !asStringOrNull(requestInput.modelId) && !asStringOrNull(requestInput.modelUrl)) {
|
|
616
|
-
const benchDefaultModelId = asStringOrNull(policy?.defaults?.bench?.modelId);
|
|
617
|
-
if (benchDefaultModelId) {
|
|
618
|
-
requestInput.modelId = benchDefaultModelId;
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
|
|
622
609
|
applyRuntimeFlagOverride(requestInput, runtimeOverride);
|
|
623
610
|
|
|
624
611
|
const surfaceFromCli = asStringOrNull(parsed.flags.surface) !== null;
|
|
612
|
+
const surface = resolveSurfaceForCommand(command, parsed, envelope.run, policy);
|
|
625
613
|
|
|
626
614
|
return {
|
|
627
615
|
request: normalizeToolingCommandRequest(requestInput),
|
|
628
616
|
runConfig: envelope.run,
|
|
629
|
-
surface
|
|
617
|
+
surface,
|
|
630
618
|
surfaceFromCli,
|
|
631
619
|
benchRunOptions: resolveBenchRunOptions(envelope.run, policy),
|
|
632
620
|
};
|
|
@@ -723,6 +711,32 @@ function isTrainingCommandFlow(request) {
|
|
|
723
711
|
return request.command === 'bench' && request.workloadType === 'training';
|
|
724
712
|
}
|
|
725
713
|
|
|
714
|
+
function resolveErrorSurface(error, fallbackSurface = null) {
|
|
715
|
+
return (
|
|
716
|
+
asStringOrNull(fallbackSurface)
|
|
717
|
+
|| asStringOrNull(error?.surface)
|
|
718
|
+
|| asStringOrNull(error?.details?.surface)
|
|
719
|
+
|| null
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
export function createCliToolingErrorEnvelope(error, context = {}) {
|
|
724
|
+
return createToolingErrorEnvelope(error, {
|
|
725
|
+
surface: resolveErrorSurface(error, context.surface),
|
|
726
|
+
request: context.request ?? null,
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
export function finalizeCliCommandResponse(response, request) {
|
|
731
|
+
if (!isPlainObject(response) || !Object.prototype.hasOwnProperty.call(response, 'request')) {
|
|
732
|
+
return response;
|
|
733
|
+
}
|
|
734
|
+
return {
|
|
735
|
+
...response,
|
|
736
|
+
request,
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
|
|
726
740
|
async function runCommandOnSurface(request, surface, runConfig, jsonOutput) {
|
|
727
741
|
if (surface === 'node') {
|
|
728
742
|
const nodeRequest = await resolveNodeModelUrl(request);
|
|
@@ -732,7 +746,8 @@ async function runCommandOnSurface(request, surface, runConfig, jsonOutput) {
|
|
|
732
746
|
console.error(`[surface] node resolved modelUrl=${nodeRequest.modelUrl}`);
|
|
733
747
|
}
|
|
734
748
|
}
|
|
735
|
-
|
|
749
|
+
const response = await runNodeCommand(nodeRequest, buildNodeRunOptions(jsonOutput));
|
|
750
|
+
return finalizeCliCommandResponse(response, request);
|
|
736
751
|
}
|
|
737
752
|
|
|
738
753
|
const browserOptions = buildBrowserRunOptions(runConfig, jsonOutput, request);
|
|
@@ -746,7 +761,8 @@ async function runCommandOnSurface(request, surface, runConfig, jsonOutput) {
|
|
|
746
761
|
}
|
|
747
762
|
}
|
|
748
763
|
|
|
749
|
-
|
|
764
|
+
const response = await runBrowserCommandInNode(browserRequest, browserOptions);
|
|
765
|
+
return finalizeCliCommandResponse(response, request);
|
|
750
766
|
}
|
|
751
767
|
|
|
752
768
|
async function runWithAutoSurface(request, runConfig, jsonOutput, policy = DEFAULT_CLI_POLICY) {
|
|
@@ -763,9 +779,12 @@ async function runWithAutoSurface(request, runConfig, jsonOutput, policy = DEFAU
|
|
|
763
779
|
}
|
|
764
780
|
if (isTrainingCommandFlow(request)) {
|
|
765
781
|
const downgradeError = new Error(
|
|
766
|
-
|
|
782
|
+
(request.command === 'lora' || request.command === 'distill')
|
|
783
|
+
? 'Training command auto-surface downgrade is blocked. Re-run with --surface node after fixing Node WebGPU support.'
|
|
784
|
+
: 'Training command auto-surface downgrade is blocked. Re-run with --surface node after fixing Node WebGPU support, or explicitly choose --surface browser.'
|
|
767
785
|
);
|
|
768
786
|
downgradeError.code = 'training_surface_downgrade_blocked';
|
|
787
|
+
downgradeError.surface = 'node';
|
|
769
788
|
downgradeError.command = request.command;
|
|
770
789
|
downgradeError.suite = request.suite;
|
|
771
790
|
downgradeError.workloadType = request.workloadType || null;
|
|
@@ -1021,7 +1040,7 @@ async function runManifestSweep(manifest, commandContext, jsonOutput, policy = D
|
|
|
1021
1040
|
results.push({
|
|
1022
1041
|
label,
|
|
1023
1042
|
response: null,
|
|
1024
|
-
error:
|
|
1043
|
+
error: createCliToolingErrorEnvelope(error, {
|
|
1025
1044
|
surface: surface === 'auto' ? null : surface,
|
|
1026
1045
|
request,
|
|
1027
1046
|
}),
|
|
@@ -1404,7 +1423,7 @@ async function main() {
|
|
|
1404
1423
|
printMetricsSummary(response.result);
|
|
1405
1424
|
} catch (error) {
|
|
1406
1425
|
if (jsonOutputRequested) {
|
|
1407
|
-
console.log(JSON.stringify(
|
|
1426
|
+
console.log(JSON.stringify(createCliToolingErrorEnvelope(error, errorContext), null, 2));
|
|
1408
1427
|
process.exitCode = 1;
|
|
1409
1428
|
return;
|
|
1410
1429
|
}
|