From 274b4f58cc1b08d3002079f89ca5834e0e5dcebe Mon Sep 17 00:00:00 2001 From: lstocchi Date: Wed, 31 Jan 2024 16:16:38 +0100 Subject: [PATCH] fix: speed up model service on WSL Signed-off-by: lstocchi --- .../backend/src/managers/modelsManager.ts | 49 ++++++++++++++++++- packages/backend/src/utils/podman.ts | 37 ++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 packages/backend/src/utils/podman.ts diff --git a/packages/backend/src/managers/modelsManager.ts b/packages/backend/src/managers/modelsManager.ts index 6133cc54b..082f941fc 100644 --- a/packages/backend/src/managers/modelsManager.ts +++ b/packages/backend/src/managers/modelsManager.ts @@ -26,6 +26,7 @@ import type { CatalogManager } from './catalogManager'; import type { ModelInfo } from '@shared/src/models/IModelInfo'; import * as podmanDesktopApi from '@podman-desktop/api'; import type { RecipeStatusUtils } from '../utils/recipeStatusUtils'; +import { getPodmanCli } from '../utils/podman'; export type DownloadModelResult = DownloadModelSuccessfulResult | DownloadModelFailureResult; @@ -161,6 +162,7 @@ export class ModelsManager { } async downloadModel(model: ModelInfo, taskUtil: RecipeStatusUtils) { + let modelPath; if (!this.isModelOnDisk(model.id)) { // Download model taskUtil.setTask({ @@ -173,7 +175,7 @@ export class ModelsManager { }); try { - return await this.doDownloadModelWrapper(model.id, model.url, taskUtil); + modelPath = await this.doDownloadModelWrapper(model.id, model.url, taskUtil); } catch (e) { console.error(e); taskUtil.setTask({ @@ -195,8 +197,51 @@ export class ModelsManager { 'model-pulling': model.id, }, }); - return this.getLocalModelPath(model.id); + modelPath = this.getLocalModelPath(model.id); } + + // if on windows we push the model into the podman machine. + // hyper-v is not currently supported so this is why there is no check to distinguish hyper-v from WSL. + // This is a workaround to get rid of the slowness of WSL2. Instead of storing the model on our local NTFS file system, + // we push it into the ext4 file system of WSL VM. This way we cut out Windows for almost all operations except read/write to the VHD file. + if (podmanDesktopApi.env.isWindows) { + taskUtil.setTask({ + id: model.id, + state: 'loading', + name: `Copying model ${model.name} to machine`, + labels: { + 'model-pulling': model.id, + }, + }); + try { + const convertToMntPath = modelPath.replace('C:\\', '/mnt/c/').replace(/\\/g, '/'); + console.log(convertToMntPath); + modelPath = `/home/user/${path.basename(convertToMntPath)}`; + console.log(modelPath); + await podmanDesktopApi.process.exec(getPodmanCli(), ['machine', 'ssh', 'cp', convertToMntPath, modelPath]); + taskUtil.setTask({ + id: model.id, + state: 'success', + name: `Model ${model.name} successfully copied`, + labels: { + 'model-pulling': model.id, + }, + }); + } catch(e) { + console.error(e); + taskUtil.setTask({ + id: model.id, + state: 'error', + name: `Downloading model ${model.name}`, + labels: { + 'model-pulling': model.id, + }, + }); + throw e; + } + + } + return modelPath; } doDownloadModelWrapper( diff --git a/packages/backend/src/utils/podman.ts b/packages/backend/src/utils/podman.ts new file mode 100644 index 000000000..51093c83c --- /dev/null +++ b/packages/backend/src/utils/podman.ts @@ -0,0 +1,37 @@ +/********************************************************************** + * Copyright (C) 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ +import { configuration, env } from "@podman-desktop/api"; + +export function getPodmanCli(): string { + // If we have a custom binary path regardless if we are running Windows or not + const customBinaryPath = getCustomBinaryPath(); + if (customBinaryPath) { + return customBinaryPath; + } + + if (env.isWindows) { + return 'podman.exe'; + } + return 'podman'; +} + +// Get the Podman binary path from configuration podman.binary.path +// return string or undefined +export function getCustomBinaryPath(): string | undefined { + return configuration.getConfiguration('podman').get('binary.path'); +} \ No newline at end of file