From d7efd9813aa7248a6f57a1e038ada17b772d98ae Mon Sep 17 00:00:00 2001 From: Louis Date: Tue, 14 Nov 2023 19:38:08 +0700 Subject: [PATCH] chore: handle GGUFv1 error --- plugins/inference-plugin/src/module.ts | 48 +++++++++++++++++++++++++- web/hooks/useActiveModel.ts | 1 - 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/plugins/inference-plugin/src/module.ts b/plugins/inference-plugin/src/module.ts index 98fe43694..ba6afdf90 100644 --- a/plugins/inference-plugin/src/module.ts +++ b/plugins/inference-plugin/src/module.ts @@ -38,7 +38,8 @@ function initModel(modelFile: string): Promise { return ( // 1. Check if the port is used, if used, attempt to unload model / kill nitro process - checkAndUnloadNitro() + validateModelVersion() + .then(checkAndUnloadNitro) // 2. Spawn the Nitro subprocess .then(spawnNitroProcess) // 3. Wait until the port is used (Nitro http server is up) @@ -47,6 +48,9 @@ function initModel(modelFile: string): Promise { .then(loadLLMModel) // 5. Check if the model is loaded successfully .then(validateModelStatus) + .catch((err) => { + return { error: err }; + }) ); } @@ -71,6 +75,10 @@ function loadLLMModel(): Promise { body: JSON.stringify(config), retries: 3, retryDelay: 500, + }).catch((err) => { + console.error(err); + // Fetch error, Nitro server might not started properly + throw new Error("Model loading failed."); }); } @@ -193,6 +201,44 @@ function spawnNitroProcess() { }); } +/** + * Validate the model version, if it is GGUFv1, reject the promise + * @returns A Promise that resolves when the model is loaded successfully, or rejects with an error message if the model is not found or fails to load. + */ +function validateModelVersion(): Promise { + // Read the file + return new Promise((resolve, reject) => { + fs.open(currentModelFile, "r", (err, fd) => { + if (err) { + console.error(err.message); + return; + } + + // Buffer to store the byte + const buffer = Buffer.alloc(1); + + // Model version will be the 5th byte of the file + fs.read(fd, buffer, 0, 1, 4, (err, bytesRead, buffer) => { + if (err) { + console.error(err.message); + } else { + // Interpret the byte as ASCII + if (buffer[0] === 0x01) { + // This is GGUFv1, which is deprecated + reject("GGUFv1 model is deprecated, please try another model."); + } + } + + // Close the file descriptor + fs.close(fd, (err) => { + if (err) console.error(err.message); + }); + resolve(); + }); + }); + }); +} + /** * Cleans up any registered resources. * Its module specific function, should be called when application is closed diff --git a/web/hooks/useActiveModel.ts b/web/hooks/useActiveModel.ts index a6a617623..73c28ddb3 100644 --- a/web/hooks/useActiveModel.ts +++ b/web/hooks/useActiveModel.ts @@ -46,7 +46,6 @@ export function useActiveModel() { const res = await initModel(`models/${modelId}`) if (res?.error) { const errorMessage = `${res.error}` - console.error(errorMessage) alert(errorMessage) setStateModel(() => ({ state: 'start',