UNPKG

inference-server

Version:

Libraries and server to build AI applications. Adapters to various native bindings allowing local inference. Integrate it with your application, or use as a microservice.

117 lines 4.49 kB
import path from 'node:path'; import chalk from 'chalk'; import { ModelStore } from '../store.js'; import { builtInEngineNames } from '../engines/index.js'; import { validateModelOptions } from '../lib/validateModelOptions.js'; import { resolveModelFileLocation } from '../lib/resolveModelFileLocation.js'; import { getCacheDirPath } from '../lib/getCacheDirPath.js'; import { LogLevels } from '../lib/logger.js'; import { loadConfig } from '../cli/lib/loadConfig.js'; async function prepareAllModels(options, concurrency) { let modelsCachePath = getCacheDirPath('models'); if (options.cachePath) { modelsCachePath = path.join(options.cachePath, 'models'); } const modelsWithDefaults = {}; const usedEngines = []; for (const modelId in options.models) { const modelOptions = options.models[modelId]; const isBuiltIn = builtInEngineNames.includes(modelOptions.engine); if (isBuiltIn) { const builtInModelOptions = modelOptions; // can validate and resolve location of model files if a built-in engine is used validateModelOptions(modelId, builtInModelOptions); modelsWithDefaults[modelId] = { id: modelId, minInstances: 0, maxInstances: 1, modelsCachePath, prepare: 'blocking', location: resolveModelFileLocation({ url: builtInModelOptions.url, filePath: builtInModelOptions.location, modelsCachePath, }), ...builtInModelOptions, }; } } const customEngines = Object.keys(options.engines ?? {}); const loadedEngines = {}; for (const ref of usedEngines) { const isBuiltIn = builtInEngineNames.includes(ref.engine); const isCustom = customEngines.includes(ref.engine); if (!isBuiltIn && !isCustom) { throw new Error(`Engine "${ref.engine}" used by model "${ref.model}" does not exist`); } if (isCustom) { loadedEngines[ref.engine] = options.engines[ref.engine]; } } const store = new ModelStore({ log: LogLevels.info, prepareConcurrency: concurrency, models: modelsWithDefaults, modelsCachePath, }); const importPromises = []; for (const key of builtInEngineNames) { // skip unused engines const modelUsingEngine = Object.keys(store.models).find((modelId) => store.models[modelId].engine === key); if (!modelUsingEngine) { continue; } importPromises.push(new Promise(async (resolve, reject) => { try { const engine = await import(`../engines/${key}/engine.js`); loadedEngines[key] = engine; resolve({ key, engine, }); } catch (err) { reject(err); } })); } await Promise.all(importPromises); await store.init(loadedEngines); } async function prepareModels(configPath, concurrency) { try { const config = await loadConfig(configPath); if (!config) { throw new Error('No configuration file found. Please provide a config file path or create one of: infs.config.js, infs.config.mjs, infs.config.json, or add an "infs" key to package.json'); } console.log(chalk.blue(`Using config from: ${configPath}`)); await prepareAllModels(config.options, concurrency); console.log(chalk.green('\nModel preparation complete!')); } catch (error) { console.error(chalk.red(`Error: ${error.message}`)); process.exit(1); } } export const prepareCommand = { command: 'prepare <configPath>', aliases: ['prep', 'download'], describe: 'Prepare models defined in configuration', builder: (yargs) => { return yargs .positional('configPath', { type: 'string', describe: 'Path to config file (defaults to infs.config.js)', }) .option('concurrency', { alias: 'c', type: 'number', describe: 'Number of models to prepare concurrently', default: 1, }); }, handler: async (argv) => { await prepareModels(argv.configPath, argv.concurrency); }, }; //# sourceMappingURL=prepareCommand.js.map