@bendyline/gezel-inference 1.0.8 → 1.0.9
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/dist/catalog/chat-models/ge/gemma4-12b-q4/manifest.json +46 -3
- package/dist/catalog/chat-models/ge/gemma4-12b-q4/versions/1.2.1/manifest.json +141 -0
- package/dist/catalog/chat-models/ge/gemma4-e4b-q4/manifest.json +5 -0
- package/dist/catalog/chat-models/index.json +1 -1
- package/dist/catalog/chat-models/or/ornith1.5-9b-q4/manifest.json +5 -0
- package/dist/catalog/chat-models/or/ornith1.5-9b-q8/manifest.json +5 -0
- package/dist/catalog/chat-models/qw/qwen3.5-9b-q4/manifest.json +5 -0
- package/dist/catalog/chat-models/qw/qwen3.8-27b-q4/manifest.json +5 -0
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/manifest.json +24 -7
- package/dist/catalog/chat-models/qw/qwen3.8-flash-next-q2/versions/1.0.3/manifest.json +47 -0
- package/dist/catalog/chat-models/raw-index.json +1 -1
- package/dist/catalog/provenance.json +1 -1
- package/dist/engines/electron-native-reuse.d.ts +5 -4
- package/dist/engines/electron-native-reuse.js +1 -1
- package/dist/engines/native-file-manifest.json +12344 -698
- package/dist/engines/native-manifest.d.ts +4 -4
- package/dist/engines/native-manifest.js +40 -36
- package/dist/engines/resolver.d.ts +18 -17
- package/dist/engines/resolver.js +36 -1
- package/dist/http/model-inventory-cache.d.ts +1 -1
- package/dist/http/routes/engines.js +3 -3
- package/dist/models/catalog-drift.d.ts +2 -0
- package/dist/models/catalog-drift.js +1 -1
- package/dist/models/catalog-payload-identity.d.ts +2 -2
- package/dist/models/catalog-payload-identity.js +10 -5
- package/dist/providers/active-install-message.js +1 -1
- package/dist/providers/catalog-model-config.d.ts +28 -0
- package/dist/providers/ds4/build-provider.js +35 -13
- package/dist/providers/ds4/residency.d.ts +77 -0
- package/dist/providers/ds4/residency.js +87 -6
- package/dist/providers/image/sd-cpp.js +3 -2
- package/dist/providers/llama-cpp/backend-health.d.ts +3 -2
- package/dist/providers/llama-cpp/backend-health.js +6 -3
- package/dist/providers/llama-cpp/backend-quarantine.js +1 -1
- package/dist/providers/llama-cpp/build-provider.js +168 -29
- package/dist/providers/llama-cpp/devices.js +4 -1
- package/dist/providers/llama-cpp/engine-flags.d.ts +8 -1
- package/dist/providers/llama-cpp/engine-flags.js +13 -8
- package/dist/providers/llama-cpp/gpu-startup-watch.d.ts +4 -4
- package/dist/providers/llama-cpp/gpu-startup-watch.js +7 -5
- package/dist/providers/llama-cpp/models.d.ts +10 -0
- package/dist/providers/llama-cpp/models.js +64 -10
- package/dist/providers/llama-cpp/offload-planner.d.ts +6 -0
- package/dist/providers/llama-cpp/offload-planner.js +1 -1
- package/dist/providers/llama-cpp/spec-draft.d.ts +45 -23
- package/dist/providers/llama-cpp/spec-draft.js +113 -24
- package/dist/providers/mlx/python/spec_decode.py +23 -2
- package/dist/providers/mlx/python/tool_args_json.py +59 -21
- package/dist/providers/mlx/venv.d.ts +19 -1
- package/dist/providers/mlx/venv.js +21 -2
- package/dist/providers/native/device-capacity.d.ts +4 -0
- package/dist/providers/native/device-capacity.js +5 -0
- package/dist/providers/native/local-engine-runtime.d.ts +16 -1
- package/dist/providers/native/local-engine-runtime.js +142 -39
- package/dist/providers/native/supervisor.d.ts +8 -1
- package/dist/providers/native/supervisor.js +16 -7
- package/dist/providers/types.d.ts +4 -0
- package/dist/remotes/types.d.ts +1 -1
- package/package.json +4 -4
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
* but logs that it could not anchor to a baked-in digest.
|
|
41
41
|
*/
|
|
42
42
|
/** Native release version this build pins. Placeholder until first public release. */
|
|
43
|
-
export declare const NATIVE_ENGINE_RELEASE = "0.1.
|
|
43
|
+
export declare const NATIVE_ENGINE_RELEASE = "0.1.62";
|
|
44
44
|
/** sha256 of the pinned release's `SHA256SUMS` asset. All-zeros = unpinned. */
|
|
45
|
-
export declare const SHA256SUMS_DIGEST = "
|
|
46
|
-
/** Exact SHA256 values for every engine archive published by native-v0.1.
|
|
45
|
+
export declare const SHA256SUMS_DIGEST = "9c2e726c1cef4152b5ffb8cee8e9970cf24127786d3fafcce3582dcf0df9badb";
|
|
46
|
+
/** Exact SHA256 values for every engine archive published by native-v0.1.62. */
|
|
47
47
|
export declare const NATIVE_ENGINE_ARCHIVE_SHA256: Readonly<Record<string, string>>;
|
|
48
|
-
/** Download size in bytes of every engine archive published by native-v0.1.
|
|
48
|
+
/** Download size in bytes of every engine archive published by native-v0.1.62. */
|
|
49
49
|
export declare const NATIVE_ENGINE_ARCHIVE_BYTES: Readonly<Record<string, number>>;
|
|
50
50
|
/**
|
|
51
51
|
* True only when the pinned release's standalone macOS archives were
|
|
@@ -40,47 +40,51 @@
|
|
|
40
40
|
* but logs that it could not anchor to a baked-in digest.
|
|
41
41
|
*/
|
|
42
42
|
/** Native release version this build pins. Placeholder until first public release. */
|
|
43
|
-
export const NATIVE_ENGINE_RELEASE = '0.1.
|
|
43
|
+
export const NATIVE_ENGINE_RELEASE = '0.1.62';
|
|
44
44
|
/** sha256 of the pinned release's `SHA256SUMS` asset. All-zeros = unpinned. */
|
|
45
|
-
export const SHA256SUMS_DIGEST = '
|
|
45
|
+
export const SHA256SUMS_DIGEST = '9c2e726c1cef4152b5ffb8cee8e9970cf24127786d3fafcce3582dcf0df9badb';
|
|
46
46
|
// BEGIN PINNED NATIVE ARCHIVE HASHES
|
|
47
|
-
/** Exact SHA256 values for every engine archive published by native-v0.1.
|
|
47
|
+
/** Exact SHA256 values for every engine archive published by native-v0.1.62. */
|
|
48
48
|
export const NATIVE_ENGINE_ARCHIVE_SHA256 = Object.freeze({
|
|
49
|
-
'gezel-native-0.1.
|
|
50
|
-
'gezel-native-0.1.
|
|
51
|
-
'gezel-native-0.1.
|
|
52
|
-
'gezel-native-0.1.
|
|
53
|
-
'gezel-native-0.1.
|
|
54
|
-
'gezel-native-0.1.
|
|
55
|
-
'gezel-native-0.1.
|
|
56
|
-
'gezel-native-0.1.
|
|
57
|
-
'gezel-native-0.1.
|
|
58
|
-
'gezel-native-0.1.
|
|
59
|
-
'gezel-native-0.1.
|
|
60
|
-
'gezel-native-0.1.
|
|
61
|
-
'gezel-native-0.1.
|
|
62
|
-
'gezel-native-0.1.
|
|
63
|
-
'gezel-native-0.1.
|
|
64
|
-
'gezel-native-0.1.
|
|
49
|
+
'gezel-native-0.1.62-darwin-arm64-metal.tar.gz': '0ac76122fdc7bd33e6774fb5f62dea6ff22220c483c78026667e33ff8014936d',
|
|
50
|
+
'gezel-native-0.1.62-darwin-arm64.tar.gz': '23607c3e5c3e6ac050f0594bcf4ca997cff91c57a4b65af985511e1d87843764',
|
|
51
|
+
'gezel-native-0.1.62-linux-arm64-cpu.tar.gz': 'e9a69cdb07f5ad0103da8d99715e4a1bd257219c55457716ff93e34ee4a544ab',
|
|
52
|
+
'gezel-native-0.1.62-linux-arm64-cuda.tar.gz': '6389e97d85a2d4b53b4a1c6735669e5cd6022f393fdccabe4c18c9957f9073fc',
|
|
53
|
+
'gezel-native-0.1.62-linux-arm64.tar.gz': 'cd263de007b14be6de5b828985d3066490a339f097ef199086cd51692495b9f0',
|
|
54
|
+
'gezel-native-0.1.62-linux-x64-cpu.tar.gz': '2f1b382a02082767187340f8ecd037dfa72953004977e5716ca95127429e4f0b',
|
|
55
|
+
'gezel-native-0.1.62-linux-x64-cuda.tar.gz': '8f28018fdfd5a38e48dc886a92eab392f92193d3a58c322c85dcd16c6f80fd13',
|
|
56
|
+
'gezel-native-0.1.62-linux-x64-rocm.tar.gz': '37b88b81bdcbe06fa3c5ebe3b07f0d0112b555449cc2d29775d5ad8373150f18',
|
|
57
|
+
'gezel-native-0.1.62-linux-x64-vulkan.tar.gz': 'c39fff97dceeacb377a1948ebe9f9553a98485cf21cda9492fbfbe18dd279193',
|
|
58
|
+
'gezel-native-0.1.62-linux-x64.tar.gz': '2d0c927f98379c0cd1dd05d68f2cc4b87178ede077a65e948bf36e124d560993',
|
|
59
|
+
'gezel-native-0.1.62-win32-arm64-cpu.zip': 'f867d50591df2da2c2d78cbf844a5b87679da9f5abc9a29ed6b06905c5423bed',
|
|
60
|
+
'gezel-native-0.1.62-win32-arm64-cuda.zip': 'd42c79845f64ee1fb5e97ea45dde44c6b4705ad6bc4cd6ce9360caffc27cf67f',
|
|
61
|
+
'gezel-native-0.1.62-win32-arm64.zip': 'd4e660181cd387051d4f8728d6ae008004969786f68da15c76e44704db247af0',
|
|
62
|
+
'gezel-native-0.1.62-win32-x64-cpu.zip': '85a350c01454e77d49e2a7e463089025d71b6f7cd25daa30b5b0fe8498cf3f2a',
|
|
63
|
+
'gezel-native-0.1.62-win32-x64-cuda.zip': 'edddeeb820f4612453c036bccd4882c507811464520eb772dfa5bf7b4aa2658f',
|
|
64
|
+
'gezel-native-0.1.62-win32-x64-rocm.zip': '8640280b49fbc4bc6152b734fcb2dd02b0b9c3375797685470da52406a46aa34',
|
|
65
|
+
'gezel-native-0.1.62-win32-x64-vulkan.zip': 'a57071775f8876800d6e5689d38a3f7362c4b585e8137596ee19e45ee38b6991',
|
|
66
|
+
'gezel-native-0.1.62-win32-x64.zip': '357e6c79a4d02968a2ba67299e78efed8dc2ab2d4b40a1e8f866073506b6b2b6',
|
|
65
67
|
});
|
|
66
|
-
/** Download size in bytes of every engine archive published by native-v0.1.
|
|
68
|
+
/** Download size in bytes of every engine archive published by native-v0.1.62. */
|
|
67
69
|
export const NATIVE_ENGINE_ARCHIVE_BYTES = Object.freeze({
|
|
68
|
-
'gezel-native-0.1.
|
|
69
|
-
'gezel-native-0.1.
|
|
70
|
-
'gezel-native-0.1.
|
|
71
|
-
'gezel-native-0.1.
|
|
72
|
-
'gezel-native-0.1.
|
|
73
|
-
'gezel-native-0.1.
|
|
74
|
-
'gezel-native-0.1.
|
|
75
|
-
'gezel-native-0.1.
|
|
76
|
-
'gezel-native-0.1.
|
|
77
|
-
'gezel-native-0.1.
|
|
78
|
-
'gezel-native-0.1.
|
|
79
|
-
'gezel-native-0.1.
|
|
80
|
-
'gezel-native-0.1.
|
|
81
|
-
'gezel-native-0.1.
|
|
82
|
-
'gezel-native-0.1.
|
|
83
|
-
'gezel-native-0.1.
|
|
70
|
+
'gezel-native-0.1.62-darwin-arm64-metal.tar.gz': 7577614,
|
|
71
|
+
'gezel-native-0.1.62-darwin-arm64.tar.gz': 42917428,
|
|
72
|
+
'gezel-native-0.1.62-linux-arm64-cpu.tar.gz': 9518882,
|
|
73
|
+
'gezel-native-0.1.62-linux-arm64-cuda.tar.gz': 624413294,
|
|
74
|
+
'gezel-native-0.1.62-linux-arm64.tar.gz': 43076642,
|
|
75
|
+
'gezel-native-0.1.62-linux-x64-cpu.tar.gz': 13762290,
|
|
76
|
+
'gezel-native-0.1.62-linux-x64-cuda.tar.gz': 1016218245,
|
|
77
|
+
'gezel-native-0.1.62-linux-x64-rocm.tar.gz': 313875007,
|
|
78
|
+
'gezel-native-0.1.62-linux-x64-vulkan.tar.gz': 26687129,
|
|
79
|
+
'gezel-native-0.1.62-linux-x64.tar.gz': 58389984,
|
|
80
|
+
'gezel-native-0.1.62-win32-arm64-cpu.zip': 6219263,
|
|
81
|
+
'gezel-native-0.1.62-win32-arm64-cuda.zip': 245764366,
|
|
82
|
+
'gezel-native-0.1.62-win32-arm64.zip': 42822090,
|
|
83
|
+
'gezel-native-0.1.62-win32-x64-cpu.zip': 9357113,
|
|
84
|
+
'gezel-native-0.1.62-win32-x64-cuda.zip': 761458453,
|
|
85
|
+
'gezel-native-0.1.62-win32-x64-rocm.zip': 241630451,
|
|
86
|
+
'gezel-native-0.1.62-win32-x64-vulkan.zip': 21898409,
|
|
87
|
+
'gezel-native-0.1.62-win32-x64.zip': 56194044,
|
|
84
88
|
});
|
|
85
89
|
// END PINNED NATIVE ARCHIVE HASHES
|
|
86
90
|
/**
|
|
@@ -24,7 +24,7 @@ export type EngineResolveEvent = NativeEngineResolveEvent | EngineExtractingEven
|
|
|
24
24
|
export interface ResolveEngineOptions {
|
|
25
25
|
engine: NativeBinaryName;
|
|
26
26
|
home: string;
|
|
27
|
-
/** GPU backend for llama-server (`cuda`/`vulkan`/`metal`/`cpu`); omit for single-variant engines. */
|
|
27
|
+
/** GPU backend for llama-server (`cuda`/`rocm`/`vulkan`/`metal`/`cpu`); omit for single-variant engines. */
|
|
28
28
|
variant?: string;
|
|
29
29
|
/** Native release version; defaults to the source pin / `GEZEL_NATIVE_ENGINE_VERSION`. */
|
|
30
30
|
version?: string;
|
|
@@ -100,22 +100,23 @@ export declare function resolveEngine(opts: ResolveEngineOptions): AsyncGenerato
|
|
|
100
100
|
*/
|
|
101
101
|
export declare function resolveEngineToCompletion(opts: ResolveEngineOptions, onEvent?: (e: EngineResolveEvent) => void): Promise<EngineResolveResult>;
|
|
102
102
|
/**
|
|
103
|
-
* The
|
|
103
|
+
* The llama-server build an on-demand install fetches when the probe found
|
|
104
|
+
* `detected`: the first build down discovery's own fallback chain (ROCm and
|
|
105
|
+
* CUDA → Vulkan → CPU) that the pinned release publishes for this platform.
|
|
106
|
+
* Without this, a probe answer the release has no archive for — ROCm before
|
|
107
|
+
* the release that first carries it, Vulkan on Linux ARM — failed the install
|
|
108
|
+
* outright instead of taking the next build down.
|
|
104
109
|
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* copy of the NVIDIA redistributables with llama-server's CUDA build
|
|
109
|
-
* instead of shipping them twice (see scripts/native-payload.mjs).
|
|
110
|
-
* - **llama-server on macOS** ships only in the `-metal` archive; there is no
|
|
111
|
-
* `darwin-arm64-cpu` asset, and the bare `darwin-arm64` key holds
|
|
112
|
-
* ds4/sd/whisper/uv but no llama-server. Omitting the variant there fails
|
|
113
|
-
* the extract with "none of [gezel-llama-server, llama-server] were inside
|
|
114
|
-
* it" — a loud error, but an avoidable one.
|
|
115
|
-
*
|
|
116
|
-
* Deriving both here is the point: every call site would otherwise have to
|
|
117
|
-
* remember, and one eventually won't. Where the variant is a genuine choice
|
|
118
|
-
* (llama-server on Linux/Windows: cuda / vulkan / cpu) this returns undefined
|
|
119
|
-
* and the decision stays with the caller.
|
|
110
|
+
* ROCm also has to be worth its several hundred megabytes before anything
|
|
111
|
+
* downloads: `rocmWorthDownloading` (rocm-devices.ts), which says no on
|
|
112
|
+
* Windows. An explicit `llamaCppBackendOverride` never comes through here.
|
|
120
113
|
*/
|
|
114
|
+
export declare function llamaDownloadVariant(detected: string | undefined, opts?: {
|
|
115
|
+
platform?: NodeJS.Platform;
|
|
116
|
+
platformKey?: string | null;
|
|
117
|
+
version?: string;
|
|
118
|
+
/** Archive names the release publishes; null when unpinned (every build counts). */
|
|
119
|
+
archives?: Readonly<Record<string, string>> | null;
|
|
120
|
+
rocmWorth?: () => boolean;
|
|
121
|
+
}): string | undefined;
|
|
121
122
|
export declare function impliedEngineVariant(engine: NativeBinaryName, platform: NodeJS.Platform): string | undefined;
|
package/dist/engines/resolver.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createReadStream, existsSync, readdirSync } from 'node:fs';
|
|
|
3
3
|
import { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
5
|
import { HttpStatusError, createLogger, nowIso, resolveDistributionProfile, retryTransient, } from '@bendyline/gezel';
|
|
6
|
-
import { DUCKDB_APPLE_TEAM_ID, DUCKDB_ARCHIVE_SHA256, DUCKDB_ASSET, DUCKDB_BINARY_SHA256, DUCKDB_VERSION, DUCKDB_WINDOWS_PUBLISHER, MXC_EXECUTOR_NAME, MXC_EXECUTOR_SHA256, MXC_LICENSE_SHA256, MXC_TARBALL_INTEGRITY, MXC_TARBALL_LICENSE_ENTRY, MXC_TARBALL_SHA256, MXC_TARBALL_URL, MXC_VERIFIED_SENTINEL, MXC_VERSION, MXC_WINDOWS_PUBLISHER, duckdbAssetUrl, duckdbBinaryName, duckdbInstallDir, duckdbPlatformKey, mxcArch, mxcInstallDir, mxcTarballEntry, resolvePlatformKey, } from '@bendyline/gezel/native';
|
|
6
|
+
import { DUCKDB_APPLE_TEAM_ID, DUCKDB_ARCHIVE_SHA256, DUCKDB_ASSET, DUCKDB_BINARY_SHA256, DUCKDB_VERSION, DUCKDB_WINDOWS_PUBLISHER, MXC_EXECUTOR_NAME, MXC_EXECUTOR_SHA256, MXC_LICENSE_SHA256, MXC_TARBALL_INTEGRITY, MXC_TARBALL_LICENSE_ENTRY, MXC_TARBALL_SHA256, MXC_TARBALL_URL, MXC_VERIFIED_SENTINEL, MXC_VERSION, MXC_WINDOWS_PUBLISHER, duckdbAssetUrl, duckdbBinaryName, duckdbInstallDir, duckdbPlatformKey, mxcArch, mxcInstallDir, mxcTarballEntry, resolveAvailableLlamaBinary, resolvePlatformKey, rocmWorthDownloading, } from '@bendyline/gezel/native';
|
|
7
7
|
import * as tar from 'tar';
|
|
8
8
|
import { downloadWithRetry, friendlyErrors, } from '../utils/download-with-retry.js';
|
|
9
9
|
import { extractZip } from '../utils/extract-zip.js';
|
|
@@ -744,6 +744,41 @@ function stripVer(v) {
|
|
|
744
744
|
* (llama-server on Linux/Windows: cuda / vulkan / cpu) this returns undefined
|
|
745
745
|
* and the decision stays with the caller.
|
|
746
746
|
*/
|
|
747
|
+
const LLAMA_DOWNLOAD_BACKENDS = ['cuda', 'rocm', 'vulkan', 'metal', 'cpu'];
|
|
748
|
+
/**
|
|
749
|
+
* The llama-server build an on-demand install fetches when the probe found
|
|
750
|
+
* `detected`: the first build down discovery's own fallback chain (ROCm and
|
|
751
|
+
* CUDA → Vulkan → CPU) that the pinned release publishes for this platform.
|
|
752
|
+
* Without this, a probe answer the release has no archive for — ROCm before
|
|
753
|
+
* the release that first carries it, Vulkan on Linux ARM — failed the install
|
|
754
|
+
* outright instead of taking the next build down.
|
|
755
|
+
*
|
|
756
|
+
* ROCm also has to be worth its several hundred megabytes before anything
|
|
757
|
+
* downloads: `rocmWorthDownloading` (rocm-devices.ts), which says no on
|
|
758
|
+
* Windows. An explicit `llamaCppBackendOverride` never comes through here.
|
|
759
|
+
*/
|
|
760
|
+
export function llamaDownloadVariant(detected, opts = {}) {
|
|
761
|
+
const platform = opts.platform ?? process.platform;
|
|
762
|
+
if (platform === 'darwin')
|
|
763
|
+
return impliedEngineVariant('llama-server', platform);
|
|
764
|
+
const preferred = LLAMA_DOWNLOAD_BACKENDS.find((backend) => backend === detected);
|
|
765
|
+
if (!preferred)
|
|
766
|
+
return detected;
|
|
767
|
+
const platformKey = opts.platformKey === undefined ? resolvePlatformKey() : opts.platformKey;
|
|
768
|
+
const version = stripVer(opts.version ?? effectiveEngineRelease());
|
|
769
|
+
const ext = platform === 'win32' ? 'zip' : 'tar.gz';
|
|
770
|
+
const archives = opts.archives === undefined
|
|
771
|
+
? isPlaceholderDigest(SHA256SUMS_DIGEST) || process.env.GEZEL_NATIVE_ENGINE_VERSION
|
|
772
|
+
? null
|
|
773
|
+
: NATIVE_ENGINE_ARCHIVE_SHA256
|
|
774
|
+
: opts.archives;
|
|
775
|
+
const rocmWorth = opts.rocmWorth ?? (() => rocmWorthDownloading({ platform }));
|
|
776
|
+
const resolved = resolveAvailableLlamaBinary(preferred, (backend) => {
|
|
777
|
+
const name = `gezel-native-${version}-${platformKey}-${backend}.${ext}`;
|
|
778
|
+
return !archives || archives[name] ? name : null;
|
|
779
|
+
}, true, (backend) => backend !== 'rocm' || rocmWorth());
|
|
780
|
+
return resolved?.backend ?? preferred;
|
|
781
|
+
}
|
|
747
782
|
export function impliedEngineVariant(engine, platform) {
|
|
748
783
|
if (engine === 'ds4-server' && platform === 'linux')
|
|
749
784
|
return 'cuda';
|
|
@@ -4,5 +4,5 @@ export interface CacheEntry {
|
|
|
4
4
|
at: number;
|
|
5
5
|
models: ModelInfo[];
|
|
6
6
|
}
|
|
7
|
-
export declare const cache: Map<"copilot" | "openai" | "anthropic" | "anthropic-cli" | "codex-cli" | "ollama" | "llama-cpp" | "mlx" | "ds4" | "apple-foundation-models" | "android-mlkit"
|
|
7
|
+
export declare const cache: Map<"copilot" | "openai" | "anthropic" | "anthropic-cli" | "codex-cli" | "ollama" | "llama-cpp" | "mlx" | "ds4" | "remote" | "apple-foundation-models" | "android-mlkit", CacheEntry>;
|
|
8
8
|
export declare function invalidateModelsCache(provider?: ProviderName): void;
|
|
@@ -40,7 +40,7 @@ export function enginesRoutes(ctx) {
|
|
|
40
40
|
*/
|
|
41
41
|
app.get('/binaries/status', (c) => {
|
|
42
42
|
const backendRaw = process.env.GEZEL_LLAMA_SERVER_BACKEND ?? process.env.GEZEL_LLAMA_DETECTED_BACKEND;
|
|
43
|
-
const llamaBackend = ['cuda', 'vulkan', 'metal', 'cpu'].find((value) => value === backendRaw);
|
|
43
|
+
const llamaBackend = ['cuda', 'rocm', 'vulkan', 'metal', 'cpu'].find((value) => value === backendRaw);
|
|
44
44
|
const platformKey = resolvePlatformKey();
|
|
45
45
|
return c.json({
|
|
46
46
|
release: effectiveEngineRelease(),
|
|
@@ -64,7 +64,7 @@ export function enginesRoutes(ctx) {
|
|
|
64
64
|
});
|
|
65
65
|
/**
|
|
66
66
|
* Start (or attach to) a download+verify of `engine` (optionally a GPU
|
|
67
|
-
* `?variant=cuda|vulkan|metal|cpu`) and stream progress as SSE. The
|
|
67
|
+
* `?variant=cuda|rocm|vulkan|metal|cpu`) and stream progress as SSE. The
|
|
68
68
|
* manual trigger behind Settings → On-device → "Download engine". The
|
|
69
69
|
* lazy on-device-chat path uses the same registry. Idempotent — a
|
|
70
70
|
* second call while one is in flight attaches to the running job.
|
|
@@ -231,7 +231,7 @@ export function enginesRoutes(ctx) {
|
|
|
231
231
|
app.delete('/llama-cpp/quarantine/:backend', async (c) => {
|
|
232
232
|
const backend = c.req.param('backend');
|
|
233
233
|
if (!isLlamaBackend(backend)) {
|
|
234
|
-
return c.json({ error: 'backend must be "cuda", "vulkan", "metal", or "cpu"' }, 400);
|
|
234
|
+
return c.json({ error: 'backend must be "cuda", "rocm", "vulkan", "metal", or "cpu"' }, 400);
|
|
235
235
|
}
|
|
236
236
|
const override = (await ctx.store.readConfig()).llamaCppBackendOverride;
|
|
237
237
|
const { restored } = liftLlamaQuarantine(ctx.home, backend, {
|
|
@@ -36,6 +36,8 @@ export interface EvaluateCatalogDriftOptions {
|
|
|
36
36
|
installedVersion?: string;
|
|
37
37
|
installed: InstalledPayloadRecord;
|
|
38
38
|
manifest: ChatModelManifest;
|
|
39
|
+
/** The backend a llama.cpp copy runs on. Defaults to the process's own. */
|
|
40
|
+
llamaCppBackend?: string | undefined;
|
|
39
41
|
/**
|
|
40
42
|
* False for models resolved out of a read-only overlay (the machine asset
|
|
41
43
|
* store) and while an install is in flight for this id — the verdict still
|
|
@@ -30,7 +30,7 @@ export async function evaluateCatalogDrift(opts) {
|
|
|
30
30
|
if (!opts.installedVersion || !currentVersion || opts.installedVersion === currentVersion) {
|
|
31
31
|
return { updateAvailable: false };
|
|
32
32
|
}
|
|
33
|
-
const catalog = describeCatalogPayload(opts.manifest, opts.engine);
|
|
33
|
+
const catalog = describeCatalogPayload(opts.manifest, opts.engine, opts.llamaCppBackend);
|
|
34
34
|
if (!catalog) {
|
|
35
35
|
// The catalog no longer describes this engine's payload at all (a source
|
|
36
36
|
// block was pulled). Nothing to download, so nothing to offer.
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* over what the install already recorded, and its answers steer UI, never
|
|
31
31
|
* trust.
|
|
32
32
|
*/
|
|
33
|
-
import type
|
|
33
|
+
import { type ChatModelManifest, type GezmodelEngine } from '@bendyline/gezel';
|
|
34
34
|
/** One file the catalog expects to land in the model directory. */
|
|
35
35
|
export interface CatalogPayloadFile {
|
|
36
36
|
/** Name as it lands on disk ('/'-joined for nested files, as in `fileSha256`). */
|
|
@@ -103,5 +103,5 @@ export declare function catalogPayloadFingerprint(payload: CatalogPayload): stri
|
|
|
103
103
|
* The single place that knows each source block's shape, so callers compare
|
|
104
104
|
* like for like without re-deriving filenames.
|
|
105
105
|
*/
|
|
106
|
-
export declare function describeCatalogPayload(manifest: ChatModelManifest, engine: GezmodelEngine): CatalogPayload | null;
|
|
106
|
+
export declare function describeCatalogPayload(manifest: ChatModelManifest, engine: GezmodelEngine, llamaCppBackend?: string | undefined): CatalogPayload | null;
|
|
107
107
|
export declare function comparePayloadIdentity(opts: ComparePayloadOptions): Promise<PayloadIdentityResult>;
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
import { createHash } from 'node:crypto';
|
|
34
34
|
import { stat } from 'node:fs/promises';
|
|
35
35
|
import { basename, join } from 'node:path';
|
|
36
|
+
import { llamaCppDraftModelApplies, } from '@bendyline/gezel';
|
|
37
|
+
import { currentLlamaCppBackend } from '../providers/llama-cpp/backend-health.js';
|
|
36
38
|
/**
|
|
37
39
|
* Stable hash of a catalog payload description. Deliberately excludes
|
|
38
40
|
* `revision`: it is a fetch coordinate, and identical hashes mean identical
|
|
@@ -53,7 +55,7 @@ export function catalogPayloadFingerprint(payload) {
|
|
|
53
55
|
* The single place that knows each source block's shape, so callers compare
|
|
54
56
|
* like for like without re-deriving filenames.
|
|
55
57
|
*/
|
|
56
|
-
export function describeCatalogPayload(manifest, engine) {
|
|
58
|
+
export function describeCatalogPayload(manifest, engine, llamaCppBackend = currentLlamaCppBackend()) {
|
|
57
59
|
if (engine === 'mlx') {
|
|
58
60
|
const src = manifest.mlx;
|
|
59
61
|
if (!src)
|
|
@@ -96,10 +98,13 @@ export function describeCatalogPayload(manifest, engine) {
|
|
|
96
98
|
sizeBytes: src.approxSizeBytes,
|
|
97
99
|
});
|
|
98
100
|
}
|
|
99
|
-
// Draft companions exist on both engine sources
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
|
|
101
|
+
// Draft companions exist on both engine sources, so read them off the
|
|
102
|
+
// already engine-selected `src`. A llama.cpp drafter limited to some backends
|
|
103
|
+
// is no part of this install elsewhere: counting it would offer every other
|
|
104
|
+
// machine an update for a file it never downloads.
|
|
105
|
+
const draftApplies = engine !== 'llama-cpp' ||
|
|
106
|
+
llamaCppDraftModelApplies(manifest.llamaCpp?.draftModel, llamaCppBackend);
|
|
107
|
+
if (src.draftModel && draftApplies) {
|
|
103
108
|
files.push({
|
|
104
109
|
name: basename(src.draftModel.filename),
|
|
105
110
|
sha256: src.draftModel.sha256,
|
|
@@ -37,7 +37,7 @@ export function notReadyError(message, code) {
|
|
|
37
37
|
*/
|
|
38
38
|
export function noModelYetMessage(engineLabel, active) {
|
|
39
39
|
if (!active) {
|
|
40
|
-
return `${engineLabel}: no model is installed yet. Download one from Settings → Artificial
|
|
40
|
+
return `${engineLabel}: no model is installed yet. Download one from Settings → Artificial intelligence, then try again.`;
|
|
41
41
|
}
|
|
42
42
|
if (active.phase !== 'downloading') {
|
|
43
43
|
const verb = active.phase === 'verifying' ? 'being verified' : 'being prepared';
|
|
@@ -59,5 +59,33 @@ export declare function resolveCatalogLlamaCppEngineConfig(catalog: CatalogServi
|
|
|
59
59
|
mtp?: boolean | undefined;
|
|
60
60
|
draftModelId?: string | undefined;
|
|
61
61
|
nMax?: number | undefined;
|
|
62
|
+
sampling?: "greedy" | "probabilistic" | undefined;
|
|
63
|
+
byBackend?: {
|
|
64
|
+
cuda?: {
|
|
65
|
+
type?: "none" | "draft-mtp" | "draft-eagle3" | "draft-dflash" | "draft-simple" | "ngram-mod" | "ngram-simple" | "ngram-map-k" | "ngram-map-k4v" | "ngram-cache" | undefined;
|
|
66
|
+
nMax?: number | undefined;
|
|
67
|
+
sampling?: "greedy" | "probabilistic" | undefined;
|
|
68
|
+
} | undefined;
|
|
69
|
+
rocm?: {
|
|
70
|
+
type?: "none" | "draft-mtp" | "draft-eagle3" | "draft-dflash" | "draft-simple" | "ngram-mod" | "ngram-simple" | "ngram-map-k" | "ngram-map-k4v" | "ngram-cache" | undefined;
|
|
71
|
+
nMax?: number | undefined;
|
|
72
|
+
sampling?: "greedy" | "probabilistic" | undefined;
|
|
73
|
+
} | undefined;
|
|
74
|
+
vulkan?: {
|
|
75
|
+
type?: "none" | "draft-mtp" | "draft-eagle3" | "draft-dflash" | "draft-simple" | "ngram-mod" | "ngram-simple" | "ngram-map-k" | "ngram-map-k4v" | "ngram-cache" | undefined;
|
|
76
|
+
nMax?: number | undefined;
|
|
77
|
+
sampling?: "greedy" | "probabilistic" | undefined;
|
|
78
|
+
} | undefined;
|
|
79
|
+
metal?: {
|
|
80
|
+
type?: "none" | "draft-mtp" | "draft-eagle3" | "draft-dflash" | "draft-simple" | "ngram-mod" | "ngram-simple" | "ngram-map-k" | "ngram-map-k4v" | "ngram-cache" | undefined;
|
|
81
|
+
nMax?: number | undefined;
|
|
82
|
+
sampling?: "greedy" | "probabilistic" | undefined;
|
|
83
|
+
} | undefined;
|
|
84
|
+
cpu?: {
|
|
85
|
+
type?: "none" | "draft-mtp" | "draft-eagle3" | "draft-dflash" | "draft-simple" | "ngram-mod" | "ngram-simple" | "ngram-map-k" | "ngram-map-k4v" | "ngram-cache" | undefined;
|
|
86
|
+
nMax?: number | undefined;
|
|
87
|
+
sampling?: "greedy" | "probabilistic" | undefined;
|
|
88
|
+
} | undefined;
|
|
89
|
+
} | undefined;
|
|
62
90
|
} | undefined;
|
|
63
91
|
} | undefined>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { basename, dirname, join } from 'node:path';
|
|
2
|
-
import { DEFAULT_LOCAL_ENGINE_IDLE_TIMEOUT_MS, createLogger, } from '@bendyline/gezel';
|
|
2
|
+
import { DEFAULT_LOCAL_ENGINE_IDLE_TIMEOUT_MS, createLogger, ds4SsdStreamingSupported, } from '@bendyline/gezel';
|
|
3
3
|
import { gezelPaths } from '@bendyline/gezel/paths';
|
|
4
4
|
import { LlamaCppProvider } from '../llama-cpp/index.js';
|
|
5
5
|
import { minViableLocalContextTokens, pressureIdleGraceMs } from '../native/capacity-broker.js';
|
|
@@ -282,7 +282,7 @@ export async function buildDs4Provider(opts) {
|
|
|
282
282
|
// build). `shouldUseDs4SsdStreaming` still refuses a model that cannot fit,
|
|
283
283
|
// which is what keeps the flip safe: overriding that on a 90.89 GiB build
|
|
284
284
|
// OOM-killed the engine mid-load on a 121.63 GiB host.
|
|
285
|
-
const { ds4VisionResidentBytes, planDs4ExpertCache, shouldUseDs4SsdStreaming } = await import('./residency.js');
|
|
285
|
+
const { ds4VisionResidentBytes, planDs4ExpertCache, planDs4MeasuredLaunch, shouldUseDs4SsdStreaming, } = await import('./residency.js');
|
|
286
286
|
let visionEncoderSizeBytes = installedModel?.visionEncoderSizeBytes;
|
|
287
287
|
if (vision.enabled && vision.visionEncoderPath && !visionEncoderSizeBytes) {
|
|
288
288
|
const { stat: statVisionEncoder } = await import('node:fs/promises');
|
|
@@ -291,11 +291,10 @@ export async function buildDs4Provider(opts) {
|
|
|
291
291
|
.catch(() => undefined);
|
|
292
292
|
}
|
|
293
293
|
const visionResidentBytes = ds4VisionResidentBytes(vision.enabled ? visionEncoderSizeBytes : undefined);
|
|
294
|
+
const streamingSupported = ds4SsdStreamingSupported(ds4Source, process.platform);
|
|
294
295
|
const ssdStreaming = shouldUseDs4SsdStreaming({
|
|
295
296
|
configured: config.ds4SsdStreaming,
|
|
296
|
-
...(
|
|
297
|
-
? { ssdStreamingSupported: ds4Source.ssdStreamingSupported }
|
|
298
|
-
: {}),
|
|
297
|
+
...(streamingSupported !== undefined ? { ssdStreamingSupported: streamingSupported } : {}),
|
|
299
298
|
modelSizeBytes: residentWeightBytes,
|
|
300
299
|
totalRamBytes,
|
|
301
300
|
...(visionResidentBytes > 0 ? { companionBytes: visionResidentBytes } : {}),
|
|
@@ -304,15 +303,30 @@ export async function buildDs4Provider(opts) {
|
|
|
304
303
|
log.warn(`[ds4] ignored unsafe full-residency override for ${effectiveModelId ?? modelPath}; ` +
|
|
305
304
|
`model=${modelSizeBytes ?? 'unknown'} bytes, system=${Math.round(totalRamGb)} GiB`);
|
|
306
305
|
}
|
|
307
|
-
if (config.ds4SsdStreaming === true &&
|
|
308
|
-
log.warn(`[ds4] ignored SSD-streaming override for ${effectiveModelId ?? modelPath}; this model
|
|
306
|
+
if (config.ds4SsdStreaming === true && streamingSupported === false) {
|
|
307
|
+
log.warn(`[ds4] ignored SSD-streaming override for ${effectiveModelId ?? modelPath}; ds4 cannot stream this model's routed experts on this backend`);
|
|
309
308
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
309
|
+
// A measured footprint prices the launch for its mode; a measured streamed
|
|
310
|
+
// footprint also sizes the expert cache against the local-model budget.
|
|
311
|
+
const modelBudgetBytes = ssdStreaming && ds4Source?.streamingMemory
|
|
312
|
+
? await (await import('../native/device-capacity.js')).deviceModelBudgetBytes(config)
|
|
313
|
+
: undefined;
|
|
314
|
+
const measuredLaunchWith = (extraResidentBytes) => planDs4MeasuredLaunch({
|
|
315
|
+
source: ds4Source,
|
|
316
|
+
numCtx,
|
|
317
|
+
ssdStreaming,
|
|
314
318
|
totalRamBytes: totalRamGb * 1024 ** 3,
|
|
319
|
+
budgetBytes: modelBudgetBytes,
|
|
320
|
+
sidecarBytes: visionResidentBytes + extraResidentBytes,
|
|
321
|
+
configuredCacheGb: config.ds4CacheExpertsGb,
|
|
315
322
|
});
|
|
323
|
+
const cachePlanWith = (extraResidentBytes) => measuredLaunchWith(extraResidentBytes)?.cache ??
|
|
324
|
+
planDs4ExpertCache({
|
|
325
|
+
configuredGb: config.ds4CacheExpertsGb,
|
|
326
|
+
catalogCacheBytes: ds4Source?.cacheExpertsBytes,
|
|
327
|
+
catalogResidentBytes: (ds4Source?.residentBytes ?? 0) + visionResidentBytes + extraResidentBytes,
|
|
328
|
+
totalRamBytes: totalRamGb * 1024 ** 3,
|
|
329
|
+
});
|
|
316
330
|
// DSpark speculative decoding. Resolved here, beside the residency decision
|
|
317
331
|
// it depends on: ds4 aborts at startup if an external `--mtp-model` is
|
|
318
332
|
// combined with `--ssd-streaming` for any family but DeepSeek V4.1.
|
|
@@ -386,7 +400,9 @@ export async function buildDs4Provider(opts) {
|
|
|
386
400
|
throw err;
|
|
387
401
|
}
|
|
388
402
|
if (cachePlan.clamped) {
|
|
389
|
-
log.warn(`[ds4] clamped expert cache ${cachePlan.requestedGb} → ${cachePlan.cacheGb} GiB to
|
|
403
|
+
log.warn(`[ds4] clamped expert cache ${cachePlan.requestedGb} → ${cachePlan.cacheGb} GiB to ${cachePlan.limit === 'model-budget'
|
|
404
|
+
? "fit this device's local-model budget"
|
|
405
|
+
: 'preserve system headroom'}`);
|
|
390
406
|
}
|
|
391
407
|
const cacheExpertsGb = cachePlan.cacheGb;
|
|
392
408
|
const kvDir = join(home, 'engines', 'ds4', 'kv');
|
|
@@ -433,6 +449,11 @@ export async function buildDs4Provider(opts) {
|
|
|
433
449
|
? 'interactive'
|
|
434
450
|
: 'background',
|
|
435
451
|
requirement: async () => {
|
|
452
|
+
// A measured launch is reserved at exactly its working set: no
|
|
453
|
+
// full-residency floor, and the expert cache this launch was given.
|
|
454
|
+
const measured = measuredLaunchWith(dspark.enabled ? dsparkCompanionBytes : 0);
|
|
455
|
+
if (measured)
|
|
456
|
+
return { bytes: measured.workingSetBytes, exclusive: !ssdStreaming };
|
|
436
457
|
const { ds4AdmissionGpuBytes, ds4BaseResidentBytes, ds4ResidentLine, ds4ProjectedResidentBytes, ds4ResidentBytesForMode, } = await import('./residency.js');
|
|
437
458
|
const line = ds4ResidentLine(ds4Source ?? {});
|
|
438
459
|
const projected = line ? ds4ProjectedResidentBytes(line, numCtx) : ds4Source?.residentBytes;
|
|
@@ -444,7 +465,7 @@ export async function buildDs4Provider(opts) {
|
|
|
444
465
|
modelSizeBytes: residentWeightBytes,
|
|
445
466
|
});
|
|
446
467
|
const workingSetBytes = base + visionResidentBytes + (dspark.enabled ? dsparkCompanionBytes : 0);
|
|
447
|
-
const bytes = ds4ResidentBytesForMode(workingSetBytes, ssdStreaming,
|
|
468
|
+
const bytes = ds4ResidentBytesForMode(workingSetBytes, ssdStreaming, streamingSupported);
|
|
448
469
|
const gpuBytes = ds4AdmissionGpuBytes({
|
|
449
470
|
workingSetBytes,
|
|
450
471
|
reservationBytes: bytes,
|
|
@@ -528,6 +549,7 @@ export async function buildDs4Provider(opts) {
|
|
|
528
549
|
`backend=${backendFlag.slice(2)} ctx=${numCtx} ` +
|
|
529
550
|
`prefillChunk=${ds4Source?.prefillChunk ?? 'engine-default'} ` +
|
|
530
551
|
`ssdStreaming=${ssdStreaming} cacheExpertsGiB=${ssdStreaming ? cacheExpertsGb : 0} ` +
|
|
552
|
+
`memory=${measuredLaunchWith(0) ? 'measured' : 'catalog'} ` +
|
|
531
553
|
`vision=${vision.enabled} mtp=${mtp.enabled} exactSampling=${mtp.exactSampling} (${mtp.reason}) ` +
|
|
532
554
|
`dspark=${dspark.enabled} (${dspark.reason})`);
|
|
533
555
|
return { command: binary, args, baseUrl: `http://127.0.0.1:${port}`, cwd: ds4BundleDir };
|
|
@@ -4,6 +4,10 @@ export { DS4_FULL_RESIDENCY_HEADROOM_BYTES };
|
|
|
4
4
|
* Conservative floor for the full-residency working set. Exclusivity is an
|
|
5
5
|
* explicit device lease at process startup, not a consequence of this number:
|
|
6
6
|
* the automatic model budget can exceed 96 GiB on larger machines.
|
|
7
|
+
*
|
|
8
|
+
* Only for a launch nobody measured: an entry with `fullResidencyMemory` is
|
|
9
|
+
* reserved at that working set ({@link planDs4MeasuredLaunch}). Flooring a
|
|
10
|
+
* 45 GiB Qwen3.8 launch here put it over a 96 GiB Mac's 80 GiB budget.
|
|
7
11
|
*/
|
|
8
12
|
export declare const DS4_FULL_RESIDENCY_RESERVATION_BYTES: number;
|
|
9
13
|
/**
|
|
@@ -73,12 +77,27 @@ export interface Ds4ExpertCachePlanOptions {
|
|
|
73
77
|
catalogCacheBytes?: number;
|
|
74
78
|
catalogResidentBytes?: number;
|
|
75
79
|
totalRamBytes?: number;
|
|
80
|
+
/**
|
|
81
|
+
* A measured streamed footprint at the launch window, sidecars included
|
|
82
|
+
* ({@link ds4StreamingFixedBytes}). With {@link budgetBytes} it replaces the
|
|
83
|
+
* catalog subtraction and the generic 24 GiB headroom.
|
|
84
|
+
*/
|
|
85
|
+
measuredFixedBytes?: number;
|
|
86
|
+
/** This device's local-model budget, the ceiling the capacity broker admits under. */
|
|
87
|
+
budgetBytes?: number;
|
|
88
|
+
/** Smallest cache the entry says is worth streaming with. */
|
|
89
|
+
minCacheBytes?: number;
|
|
76
90
|
}
|
|
77
91
|
export interface Ds4ExpertCachePlan {
|
|
78
92
|
cacheGb: number;
|
|
79
93
|
requestedGb: number;
|
|
80
94
|
clamped: boolean;
|
|
81
95
|
safe: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* What bounded the cache: the device's local-model budget beside a measured
|
|
98
|
+
* footprint, or the generic {@link DS4_FULL_RESIDENCY_HEADROOM_BYTES}.
|
|
99
|
+
*/
|
|
100
|
+
limit: 'model-budget' | 'headroom';
|
|
82
101
|
}
|
|
83
102
|
/**
|
|
84
103
|
* Pick a bounded routed-expert cache for streaming mode. Catalog guidance is
|
|
@@ -86,8 +105,66 @@ export interface Ds4ExpertCachePlan {
|
|
|
86
105
|
* the old RAM-tier heuristic which incorrectly gave both models 64 GiB on a
|
|
87
106
|
* 128 GiB Mac. Manual values are still accepted, but clamped so fixed model
|
|
88
107
|
* state + the cache cannot consume the runtime/OS reserve.
|
|
108
|
+
*
|
|
109
|
+
* The 24 GiB headroom guards a footprint guessed as `residentBytes −
|
|
110
|
+
* cacheExpertsBytes`, which omits graph and staging memory ds4 also holds.
|
|
111
|
+
* An entry with a measured streamed footprint has no such gap, so its cache
|
|
112
|
+
* may use whatever this device's local-model budget leaves beside it. A fixed
|
|
113
|
+
* 24 GiB refused Qwen3.8 on 32 GiB Macs whose budget held it with room to spare.
|
|
89
114
|
*/
|
|
90
115
|
export declare function planDs4ExpertCache(opts: Ds4ExpertCachePlanOptions): Ds4ExpertCachePlan;
|
|
116
|
+
/** A measured ds4 memory line from the catalog: bytes at a window, plus a per-token slope. */
|
|
117
|
+
export interface Ds4MeasuredLine {
|
|
118
|
+
bytes: number;
|
|
119
|
+
ctxTokens: number;
|
|
120
|
+
bytesPerToken: number;
|
|
121
|
+
}
|
|
122
|
+
/** Evaluate a measured line at a window, never below its context-free part. */
|
|
123
|
+
export declare function ds4MeasuredBytesAt(line: Ds4MeasuredLine, ctxTokens: number): number;
|
|
124
|
+
/** The memory fields of a catalog `ds4` block that price a launch. */
|
|
125
|
+
export interface Ds4MemorySource {
|
|
126
|
+
cacheExpertsBytes?: number | undefined;
|
|
127
|
+
fullResidencyMemory?: {
|
|
128
|
+
workingSetBytes: number;
|
|
129
|
+
ctxTokens: number;
|
|
130
|
+
bytesPerToken: number;
|
|
131
|
+
} | undefined;
|
|
132
|
+
streamingMemory?: {
|
|
133
|
+
fixedBytes: number;
|
|
134
|
+
ctxTokens: number;
|
|
135
|
+
bytesPerToken: number;
|
|
136
|
+
minCacheBytes?: number;
|
|
137
|
+
} | undefined;
|
|
138
|
+
}
|
|
139
|
+
/** Measured streamed footprint without the expert cache, at a window; undefined when unmeasured. */
|
|
140
|
+
export declare function ds4StreamingFixedBytes(source: Ds4MemorySource | undefined, ctxTokens: number): number | undefined;
|
|
141
|
+
export interface Ds4MeasuredLaunchOptions {
|
|
142
|
+
source: Ds4MemorySource | undefined;
|
|
143
|
+
numCtx: number;
|
|
144
|
+
ssdStreaming: boolean;
|
|
145
|
+
totalRamBytes: number;
|
|
146
|
+
/** Local-model budget, needed to size a streamed launch's cache. */
|
|
147
|
+
budgetBytes?: number | undefined;
|
|
148
|
+
/** Resident memory beside the model: a vision encoder, a DSpark companion. */
|
|
149
|
+
sidecarBytes?: number;
|
|
150
|
+
configuredCacheGb?: number | undefined;
|
|
151
|
+
}
|
|
152
|
+
export interface Ds4MeasuredLaunch {
|
|
153
|
+
/** What the launch holds, sidecars included. The broker reserves exactly this. */
|
|
154
|
+
workingSetBytes: number;
|
|
155
|
+
/** The part of {@link workingSetBytes} the window does not move. */
|
|
156
|
+
contextFreeBytes: number;
|
|
157
|
+
bytesPerToken: number;
|
|
158
|
+
/** Streamed launches only. */
|
|
159
|
+
cache?: Ds4ExpertCachePlan;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Price a launch from the entry's measurement for the chosen mode. Undefined
|
|
163
|
+
* when that mode is unmeasured (or a streamed launch has no budget to size
|
|
164
|
+
* against), so callers keep their catalog-`residentBytes` path, including the
|
|
165
|
+
* 96 GiB full-residency floor that stands in for a missing measurement.
|
|
166
|
+
*/
|
|
167
|
+
export declare function planDs4MeasuredLaunch(opts: Ds4MeasuredLaunchOptions): Ds4MeasuredLaunch | undefined;
|
|
91
168
|
/** Effective capacity-broker reservation for the chosen DS4 residency mode. */
|
|
92
169
|
export declare function ds4ResidentBytesForMode(catalogResidentBytes: number, ssdStreaming: boolean, ssdStreamingSupported?: boolean): number;
|
|
93
170
|
/** Allowance for ds4's compute and staging buffers beyond weights and KV rows. */
|