+21
-27
@@ -1,3 +1,5 @@
|
||||
import { voiceSettings } from './voice-settings.js';
|
||||
import { profile } from './model-profiles.js';
|
||||
import { createRequire } from 'node:module';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
@@ -17,7 +19,7 @@ const auxiliaryModels = new Map();
|
||||
|
||||
export const QVAC_MASTER = Object.freeze({
|
||||
configPath: process.env.QVAC_CONFIG_PATH,
|
||||
model: process.env.JARVIS_QVAC_MODEL || 'qwen3.5-4b',
|
||||
model: process.env.JARVIS_QVAC_MODEL || voiceSettings().chatModel || profile(voiceSettings().modelProfile).model,
|
||||
device: 'gpu',
|
||||
gpuLayers: 99,
|
||||
});
|
||||
@@ -45,34 +47,26 @@ export function assertSdkVersion() {
|
||||
|
||||
export async function acquireQvac({ auxiliaryOnly = false } = {}) {
|
||||
if (auxiliaryOnly) { await qvacSdk(); ownerCount += 1; return; }
|
||||
ownerCount += 1;
|
||||
if (!loadPromise) {
|
||||
assertSdkVersion();
|
||||
const resources = await Agent.engine.resources();
|
||||
const gpuVisible = (resources.gpus?.length || 0) > 0 ||
|
||||
Boolean(resources.drivers?.vulkan || resources.drivers?.cuda || resources.drivers?.opencl || resources.gpu);
|
||||
if (!gpuVisible) {
|
||||
ownerCount = Math.max(0, ownerCount - 1);
|
||||
throw new Error('Jarvis requires a QVAC-visible GPU backend; run npm run gpu-doctor');
|
||||
}
|
||||
loadPromise = Agent.engine.load({
|
||||
model: QVAC_MASTER.model,
|
||||
tools: true,
|
||||
device: 'gpu',
|
||||
gpu_layers: QVAC_MASTER.gpuLayers,
|
||||
mmprojUseGpu: true,
|
||||
}).then((loaded) => {
|
||||
if (loaded.device !== 'gpu') {
|
||||
throw new Error(`Jarvis requires GPU QVAC inference; loaded device was ${loaded.device}`);
|
||||
}
|
||||
// Publish the promise before the first await so concurrent callers share
|
||||
// resource discovery and loading. Count only successful acquisitions.
|
||||
loadPromise = Promise.resolve().then(async () => {
|
||||
assertSdkVersion();
|
||||
const resources = await Agent.engine.resources();
|
||||
const gpuVisible = (resources.gpus?.length || 0) > 0 ||
|
||||
Boolean(resources.drivers?.vulkan || resources.drivers?.cuda || resources.drivers?.opencl || resources.gpu);
|
||||
if (!gpuVisible) throw new Error('Jarvis requires a QVAC-visible GPU backend; run npm run gpu-doctor');
|
||||
const loaded = await Agent.engine.load({
|
||||
model: QVAC_MASTER.model, tools: true, device: 'gpu',
|
||||
gpu_layers: QVAC_MASTER.gpuLayers, mmprojUseGpu: true,
|
||||
});
|
||||
if (loaded.device !== 'gpu') throw new Error(`Jarvis requires GPU QVAC inference; loaded device was ${loaded.device}`);
|
||||
return loaded;
|
||||
}).catch((error) => {
|
||||
loadPromise = null;
|
||||
ownerCount = Math.max(0, ownerCount - 1);
|
||||
throw error;
|
||||
});
|
||||
}).catch((error) => { loadPromise = null; throw error; });
|
||||
}
|
||||
return loadPromise;
|
||||
const loaded = await loadPromise;
|
||||
ownerCount += 1;
|
||||
return loaded;
|
||||
}
|
||||
|
||||
export async function qvacSdk() {
|
||||
@@ -92,7 +86,7 @@ function resolveSdkAsset(sdk, name) {
|
||||
|
||||
function resolveModelConfigAssets(sdk, config) {
|
||||
const copy = { ...config };
|
||||
for (const key of ['vadModelSrc', 'projectionModelSrc', 'vocabModelSrc']) {
|
||||
for (const key of ['vadModelSrc', 'projectionModelSrc', 'vocabModelSrc', 's3genModelSrc']) {
|
||||
if (typeof copy[key] === 'string') copy[key] = resolveSdkAsset(sdk, copy[key]);
|
||||
}
|
||||
return copy;
|
||||
|
||||
Reference in New Issue
Block a user