@bendyline/gezel-inference 1.0.7 → 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/http/routes/v1-images.d.ts +2 -1
- package/dist/http/routes/v1-images.js +36 -9
- package/dist/knowledge/manager.d.ts +3 -27
- package/dist/knowledge/manager.js +8 -364
- package/dist/knowledge/unified-search.d.ts +61 -0
- package/dist/knowledge/unified-search.js +373 -0
- 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 +19 -11
- 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/async-file-handoff.d.ts +9 -1
- package/dist/providers/mlx/async-file-handoff.js +32 -4
- package/dist/providers/mlx/provider.js +28 -16
- 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/runtime-diagnostics.d.ts +6 -0
- package/dist/providers/mlx/runtime-diagnostics.js +18 -1
- package/dist/providers/mlx/tool-call-protocol.d.ts +4 -3
- package/dist/providers/mlx/tool-call-protocol.js +4 -3
- package/dist/providers/mlx/venv.d.ts +19 -1
- package/dist/providers/mlx/venv.js +21 -2
- package/dist/providers/native/device-capacity-ledger.d.ts +4 -2
- package/dist/providers/native/device-capacity-ledger.js +35 -20
- 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/process-identity.d.ts +38 -0
- package/dist/providers/native/process-identity.js +86 -0
- 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/dist/runtime-lock.d.ts +3 -27
- package/dist/runtime-lock.js +7 -80
- package/package.json +4 -4
|
@@ -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. */
|
|
@@ -6,6 +6,10 @@ export { DS4_FULL_RESIDENCY_HEADROOM_BYTES };
|
|
|
6
6
|
* Conservative floor for the full-residency working set. Exclusivity is an
|
|
7
7
|
* explicit device lease at process startup, not a consequence of this number:
|
|
8
8
|
* the automatic model budget can exceed 96 GiB on larger machines.
|
|
9
|
+
*
|
|
10
|
+
* Only for a launch nobody measured: an entry with `fullResidencyMemory` is
|
|
11
|
+
* reserved at that working set ({@link planDs4MeasuredLaunch}). Flooring a
|
|
12
|
+
* 45 GiB Qwen3.8 launch here put it over a 96 GiB Mac's 80 GiB budget.
|
|
9
13
|
*/
|
|
10
14
|
export const DS4_FULL_RESIDENCY_RESERVATION_BYTES = 96 * GB;
|
|
11
15
|
/**
|
|
@@ -80,20 +84,97 @@ export function shouldUseDs4SsdStreaming(opts = {}) {
|
|
|
80
84
|
* the old RAM-tier heuristic which incorrectly gave both models 64 GiB on a
|
|
81
85
|
* 128 GiB Mac. Manual values are still accepted, but clamped so fixed model
|
|
82
86
|
* state + the cache cannot consume the runtime/OS reserve.
|
|
87
|
+
*
|
|
88
|
+
* The 24 GiB headroom guards a footprint guessed as `residentBytes −
|
|
89
|
+
* cacheExpertsBytes`, which omits graph and staging memory ds4 also holds.
|
|
90
|
+
* An entry with a measured streamed footprint has no such gap, so its cache
|
|
91
|
+
* may use whatever this device's local-model budget leaves beside it. A fixed
|
|
92
|
+
* 24 GiB refused Qwen3.8 on 32 GiB Macs whose budget held it with room to spare.
|
|
83
93
|
*/
|
|
84
94
|
export function planDs4ExpertCache(opts) {
|
|
85
95
|
const totalRamBytes = opts.totalRamBytes ?? totalMemoryBytes();
|
|
86
96
|
const catalogCacheBytes = opts.catalogCacheBytes ?? 0;
|
|
87
|
-
const fixedResidentBytes = Math.max(0, (opts.catalogResidentBytes ?? 0) - catalogCacheBytes);
|
|
88
97
|
const fallbackGb = totalRamBytes >= 120 * GB ? 64 : totalRamBytes >= 88 * GB ? 48 : 32;
|
|
89
98
|
const requestedGb = opts.configuredGb ?? (catalogCacheBytes > 0 ? catalogCacheBytes / GB : fallbackGb);
|
|
90
|
-
const
|
|
99
|
+
const modelBudget = opts.measuredFixedBytes !== undefined && opts.budgetBytes !== undefined;
|
|
100
|
+
const safeCacheBytes = modelBudget
|
|
101
|
+
? opts.budgetBytes - opts.measuredFixedBytes
|
|
102
|
+
: totalRamBytes -
|
|
103
|
+
Math.max(0, (opts.catalogResidentBytes ?? 0) - catalogCacheBytes) -
|
|
104
|
+
DS4_FULL_RESIDENCY_HEADROOM_BYTES;
|
|
91
105
|
const safeCacheGb = Math.floor(safeCacheBytes / GB);
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
const minCacheGb = Math.max(1, Math.ceil((opts.minCacheBytes ?? 0) / GB));
|
|
107
|
+
const limit = modelBudget ? 'model-budget' : 'headroom';
|
|
108
|
+
if (safeCacheGb < minCacheGb) {
|
|
109
|
+
return { cacheGb: minCacheGb, requestedGb, clamped: true, safe: false, limit };
|
|
110
|
+
}
|
|
111
|
+
const cacheGb = Math.max(minCacheGb, Math.min(requestedGb, safeCacheGb));
|
|
112
|
+
return { cacheGb, requestedGb, clamped: cacheGb !== requestedGb, safe: true, limit };
|
|
113
|
+
}
|
|
114
|
+
/** Evaluate a measured line at a window, never below its context-free part. */
|
|
115
|
+
export function ds4MeasuredBytesAt(line, ctxTokens) {
|
|
116
|
+
const contextFree = Math.max(0, line.bytes - line.bytesPerToken * line.ctxTokens);
|
|
117
|
+
return Math.round(contextFree + line.bytesPerToken * Math.max(0, ctxTokens));
|
|
118
|
+
}
|
|
119
|
+
function fullResidencyLine(source) {
|
|
120
|
+
const m = source?.fullResidencyMemory;
|
|
121
|
+
return m
|
|
122
|
+
? { bytes: m.workingSetBytes, ctxTokens: m.ctxTokens, bytesPerToken: m.bytesPerToken }
|
|
123
|
+
: undefined;
|
|
124
|
+
}
|
|
125
|
+
function streamingLine(source) {
|
|
126
|
+
const m = source?.streamingMemory;
|
|
127
|
+
return m
|
|
128
|
+
? { bytes: m.fixedBytes, ctxTokens: m.ctxTokens, bytesPerToken: m.bytesPerToken }
|
|
129
|
+
: undefined;
|
|
130
|
+
}
|
|
131
|
+
/** Measured streamed footprint without the expert cache, at a window; undefined when unmeasured. */
|
|
132
|
+
export function ds4StreamingFixedBytes(source, ctxTokens) {
|
|
133
|
+
const line = streamingLine(source);
|
|
134
|
+
return line ? ds4MeasuredBytesAt(line, ctxTokens) : undefined;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Price a launch from the entry's measurement for the chosen mode. Undefined
|
|
138
|
+
* when that mode is unmeasured (or a streamed launch has no budget to size
|
|
139
|
+
* against), so callers keep their catalog-`residentBytes` path, including the
|
|
140
|
+
* 96 GiB full-residency floor that stands in for a missing measurement.
|
|
141
|
+
*/
|
|
142
|
+
export function planDs4MeasuredLaunch(opts) {
|
|
143
|
+
const sidecarBytes = opts.sidecarBytes ?? 0;
|
|
144
|
+
if (!opts.ssdStreaming) {
|
|
145
|
+
const line = fullResidencyLine(opts.source);
|
|
146
|
+
if (!line)
|
|
147
|
+
return undefined;
|
|
148
|
+
const contextFreeBytes = ds4MeasuredBytesAt(line, 0) + sidecarBytes;
|
|
149
|
+
return {
|
|
150
|
+
workingSetBytes: contextFreeBytes + line.bytesPerToken * Math.max(0, opts.numCtx),
|
|
151
|
+
contextFreeBytes,
|
|
152
|
+
bytesPerToken: line.bytesPerToken,
|
|
153
|
+
};
|
|
94
154
|
}
|
|
95
|
-
const
|
|
96
|
-
|
|
155
|
+
const line = streamingLine(opts.source);
|
|
156
|
+
if (!line || opts.budgetBytes === undefined)
|
|
157
|
+
return undefined;
|
|
158
|
+
const fixedBytes = ds4MeasuredBytesAt(line, opts.numCtx) + sidecarBytes;
|
|
159
|
+
const cache = planDs4ExpertCache({
|
|
160
|
+
...(opts.configuredCacheGb !== undefined ? { configuredGb: opts.configuredCacheGb } : {}),
|
|
161
|
+
...(opts.source?.cacheExpertsBytes !== undefined
|
|
162
|
+
? { catalogCacheBytes: opts.source.cacheExpertsBytes }
|
|
163
|
+
: {}),
|
|
164
|
+
totalRamBytes: opts.totalRamBytes,
|
|
165
|
+
measuredFixedBytes: fixedBytes,
|
|
166
|
+
budgetBytes: opts.budgetBytes,
|
|
167
|
+
...(opts.source?.streamingMemory?.minCacheBytes !== undefined
|
|
168
|
+
? { minCacheBytes: opts.source.streamingMemory.minCacheBytes }
|
|
169
|
+
: {}),
|
|
170
|
+
});
|
|
171
|
+
const cacheBytes = cache.cacheGb * GB;
|
|
172
|
+
return {
|
|
173
|
+
workingSetBytes: fixedBytes + cacheBytes,
|
|
174
|
+
contextFreeBytes: ds4MeasuredBytesAt(line, 0) + sidecarBytes + cacheBytes,
|
|
175
|
+
bytesPerToken: line.bytesPerToken,
|
|
176
|
+
cache,
|
|
177
|
+
};
|
|
97
178
|
}
|
|
98
179
|
/** Effective capacity-broker reservation for the chosen DS4 residency mode. */
|
|
99
180
|
export function ds4ResidentBytesForMode(catalogResidentBytes, ssdStreaming, ssdStreamingSupported = true) {
|
|
@@ -273,13 +273,8 @@ export class StableDiffusionCppProvider {
|
|
|
273
273
|
const height = input.height ?? defaultDimension;
|
|
274
274
|
const resolvedLoras = await this.resolveLoras(modelId, input.loras ?? []);
|
|
275
275
|
let loras = resolvedLoras.loras;
|
|
276
|
-
// A speed LoRA's recipe is what makes its few steps valid, so it wins
|
|
277
|
-
// over a style's.
|
|
278
|
-
const render = loras.find((l) => l.purpose === 'speed')?.render ?? loras.find((l) => l.render)?.render;
|
|
279
|
-
const steps = input.steps ?? render?.steps ?? (await this.defaultSampleSteps(modelId));
|
|
280
276
|
const seed = input.seed ?? Math.floor(Math.random() * 2_147_483_647);
|
|
281
277
|
const started = Date.now();
|
|
282
|
-
log.info(`[sd-cpp] generate model=${modelId ?? 'default'} steps=${steps} explicitSteps=${input.steps !== undefined} size=${width}x${height}${loras.length > 0 ? ` loras=${loras.map((l) => l.id).join(',')}` : ''}`);
|
|
283
278
|
// Model selection: sd-server serves one model per process. When a
|
|
284
279
|
// request targets a different installed model than the one currently
|
|
285
280
|
// loaded, point resolveLaunch at it (via the shared launchState) and
|
|
@@ -290,8 +285,9 @@ export class StableDiffusionCppProvider {
|
|
|
290
285
|
this.launchState.modelId = modelId;
|
|
291
286
|
await this.supervisor.stop();
|
|
292
287
|
}
|
|
293
|
-
// A render the caller abandons keeps running inside sd-server,
|
|
294
|
-
// cannot interrupt one
|
|
288
|
+
// A render the caller abandons keeps running inside sd-server, whose
|
|
289
|
+
// `/sdapi` endpoints cannot interrupt one they have started, so
|
|
290
|
+
// cancelling stops the engine.
|
|
295
291
|
const request = new AbortController();
|
|
296
292
|
const stopRender = () => {
|
|
297
293
|
request.abort();
|
|
@@ -333,6 +329,15 @@ export class StableDiffusionCppProvider {
|
|
|
333
329
|
}
|
|
334
330
|
if (signal?.aborted)
|
|
335
331
|
throw new ImageGenerationCancelledError();
|
|
332
|
+
const settingsNotes = [...resolvedLoras.notes];
|
|
333
|
+
if (loras.length > 0) {
|
|
334
|
+
loras = await this.lorasTheEngineHas(baseUrl, loras, request.signal, settingsNotes);
|
|
335
|
+
}
|
|
336
|
+
// Read only after the engine's list: a fast mode's 4 steps and CFG 1
|
|
337
|
+
// on the bare model it was dropped from render mush.
|
|
338
|
+
const render = loraRenderOverrides(loras);
|
|
339
|
+
const steps = input.steps ?? render?.steps ?? (await this.defaultSampleSteps(modelId));
|
|
340
|
+
log.info(`[sd-cpp] generate model=${modelId ?? 'default'} steps=${steps} explicitSteps=${input.steps !== undefined} size=${width}x${height}${loras.length > 0 ? ` loras=${loras.map((l) => l.id).join(',')}` : ''}`);
|
|
336
341
|
// Drive sd-server's A1111-compatible endpoints (`/sdapi/v1/txt2img`
|
|
337
342
|
// and `/sdapi/v1/img2img`). Unlike the OpenAI `/v1/images/*` shape
|
|
338
343
|
// — which reads only prompt/n/size and takes steps/seed/cfg from the
|
|
@@ -341,10 +346,6 @@ export class StableDiffusionCppProvider {
|
|
|
341
346
|
// actually take effect. `cfg_scale` is set per model (distilled /
|
|
342
347
|
// Flux-flow models need CFG 1; others inherit the server default).
|
|
343
348
|
const cfg = render?.cfg ?? (modelId ? MODEL_CFG_DEFAULTS.get(modelId) : undefined);
|
|
344
|
-
const settingsNotes = [...resolvedLoras.notes];
|
|
345
|
-
if (loras.length > 0) {
|
|
346
|
-
loras = await this.lorasTheEngineHas(baseUrl, loras, request.signal, settingsNotes);
|
|
347
|
-
}
|
|
348
349
|
let inputImages = input.inputImages ?? [];
|
|
349
350
|
// Capability gate: models whose architecture doesn't honor init
|
|
350
351
|
// latents on the pinned sd-server fall back to txt2img instead of
|
|
@@ -996,6 +997,13 @@ export function withoutEngineDirectives(text) {
|
|
|
996
997
|
} while (out !== previous);
|
|
997
998
|
return out;
|
|
998
999
|
}
|
|
1000
|
+
/**
|
|
1001
|
+
* The render settings the applied LoRAs set. A speed LoRA's recipe is what
|
|
1002
|
+
* makes its few steps valid, so it wins over a style's.
|
|
1003
|
+
*/
|
|
1004
|
+
function loraRenderOverrides(applied) {
|
|
1005
|
+
return (applied.find((l) => l.purpose === 'speed')?.render ?? applied.find((l) => l.render)?.render);
|
|
1006
|
+
}
|
|
999
1007
|
/**
|
|
1000
1008
|
* Read an installed LoRA's manifest, or nothing when it is malformed. The
|
|
1001
1009
|
* filename must be a bare `.safetensors` name: the engine resolves it inside
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Whether llama-server is getting the hardware this machine has, as the
|
|
3
3
|
* engine process sees it: the CUDA build discovery passed over for the
|
|
4
|
-
* driver (`GEZEL_LLAMA_CUDA_BLOCKER`),
|
|
4
|
+
* driver (`GEZEL_LLAMA_CUDA_BLOCKER`), the ROCm build it passed over for this
|
|
5
|
+
* machine's AMD GPUs (`GEZEL_LLAMA_ROCM_BLOCKER`), a GPU build that started without its
|
|
5
6
|
* GPU (gpu-startup-watch.ts), and Linux's out-of-memory killer stopping the
|
|
6
7
|
* engine. Each is invisible otherwise — the engine keeps answering, slower,
|
|
7
8
|
* or a chat fails with a crash that reads like any other.
|
|
@@ -24,7 +25,7 @@ export declare function noteHostOutOfMemory(input: {
|
|
|
24
25
|
model?: string | undefined;
|
|
25
26
|
whileStarting: boolean;
|
|
26
27
|
}, now?: Date): void;
|
|
27
|
-
declare const BACKENDS: readonly ["cuda", "vulkan", "metal", "cpu"];
|
|
28
|
+
declare const BACKENDS: readonly ["cuda", "rocm", "vulkan", "metal", "cpu"];
|
|
28
29
|
/**
|
|
29
30
|
* The backend this process's on-device llama-server runs, for catalog
|
|
30
31
|
* backend exclusions: the build discovery resolved, else what the probe
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Whether llama-server is getting the hardware this machine has, as the
|
|
3
3
|
* engine process sees it: the CUDA build discovery passed over for the
|
|
4
|
-
* driver (`GEZEL_LLAMA_CUDA_BLOCKER`),
|
|
4
|
+
* driver (`GEZEL_LLAMA_CUDA_BLOCKER`), the ROCm build it passed over for this
|
|
5
|
+
* machine's AMD GPUs (`GEZEL_LLAMA_ROCM_BLOCKER`), a GPU build that started without its
|
|
5
6
|
* GPU (gpu-startup-watch.ts), and Linux's out-of-memory killer stopping the
|
|
6
7
|
* engine. Each is invisible otherwise — the engine keeps answering, slower,
|
|
7
8
|
* or a chat fails with a crash that reads like any other.
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
* Process-wide like the backend env it sits beside: every llama provider in
|
|
10
11
|
* this process launches the same build.
|
|
11
12
|
*/
|
|
12
|
-
import { missingMachineRuntime, readLlamaCudaBlocker, vcRedistributableUrl, } from '@bendyline/gezel/native';
|
|
13
|
+
import { missingMachineRuntime, readLlamaCudaBlocker, readRocmBlocker, vcRedistributableUrl, } from '@bendyline/gezel/native';
|
|
13
14
|
/**
|
|
14
15
|
* Reading an engine's import tables takes tens of milliseconds of synchronous
|
|
15
16
|
* file reads, and the answer only changes when someone installs the runtime.
|
|
@@ -61,7 +62,7 @@ export function noteHostOutOfMemory(input, now = new Date()) {
|
|
|
61
62
|
whileStarting: input.whileStarting,
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
|
-
const BACKENDS = ['cuda', 'vulkan', 'metal', 'cpu'];
|
|
65
|
+
const BACKENDS = ['cuda', 'rocm', 'vulkan', 'metal', 'cpu'];
|
|
65
66
|
/**
|
|
66
67
|
* The backend this process's on-device llama-server runs, for catalog
|
|
67
68
|
* backend exclusions: the build discovery resolved, else what the probe
|
|
@@ -85,6 +86,7 @@ export function llamaBackendHealthView() {
|
|
|
85
86
|
const runningRaw = process.env.GEZEL_LLAMA_SERVER_BACKEND;
|
|
86
87
|
const running = BACKENDS.find((backend) => backend === runningRaw);
|
|
87
88
|
const cudaBlocker = readLlamaCudaBlocker();
|
|
89
|
+
const rocmBlocker = readRocmBlocker();
|
|
88
90
|
// A verdict about a build the process has since moved off (a quarantine
|
|
89
91
|
// fallback, a lifted quarantine) no longer describes what runs.
|
|
90
92
|
const unused = gpuUnused && gpuUnused.backend === running ? gpuUnused : null;
|
|
@@ -92,6 +94,7 @@ export function llamaBackendHealthView() {
|
|
|
92
94
|
return {
|
|
93
95
|
...(running ? { running } : {}),
|
|
94
96
|
...(cudaBlocker ? { cudaBlocker } : {}),
|
|
97
|
+
...(rocmBlocker ? { rocmBlocker } : {}),
|
|
95
98
|
...(unused ? { gpuUnused: unused } : {}),
|
|
96
99
|
...(missingRuntime ? { missingRuntime } : {}),
|
|
97
100
|
...(outOfMemory ? { outOfMemory } : {}),
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* next engine launch instead of the next app start.
|
|
12
12
|
*/
|
|
13
13
|
import { LLAMA_QUARANTINE_STRIKES, clearLlamaQuarantine, createLlamaBuildCheck, isBinaryQuarantined, llamaVariantBinaryPath, publishLlamaCudaBlocker, readLlamaQuarantine, resolveLlamaFallbackBinary, resolveLlamaVariantBinary, } from '@bendyline/gezel/native';
|
|
14
|
-
const BACKENDS = ['cuda', 'vulkan', 'metal', 'cpu'];
|
|
14
|
+
const BACKENDS = ['cuda', 'rocm', 'vulkan', 'metal', 'cpu'];
|
|
15
15
|
export function isLlamaBackend(value) {
|
|
16
16
|
return BACKENDS.some((backend) => backend === value);
|
|
17
17
|
}
|