Skip to content

Commit 42137a0

Browse files
authored
fix(wsl): model mounting (#2385)
* fix(wsl): model mounting Signed-off-by: axel7083 <[email protected]> * fix: remove unnecessary trailing slash Signed-off-by: axel7083 <[email protected]> * fix: remove unnecessary trailing slash Signed-off-by: axel7083 <[email protected]> * fix: remove unnecessary trailing slash Signed-off-by: axel7083 <[email protected]> --------- Signed-off-by: axel7083 <[email protected]>
1 parent 989cff1 commit 42137a0

File tree

5 files changed

+64
-7
lines changed

5 files changed

+64
-7
lines changed

packages/backend/src/utils/modelsUtils.spec.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ import { process as apiProcess } from '@podman-desktop/api';
2020
import {
2121
deleteRemoteModel,
2222
getLocalModelFile,
23+
getMountPath,
2324
getRemoteModelFile,
2425
isModelUploaded,
2526
MACHINE_BASE_FOLDER,
2627
} from './modelsUtils';
2728
import type { ModelInfo } from '@shared/src/models/IModelInfo';
2829
import { getPodmanCli } from './podman';
30+
import { join, posix } from 'node:path';
2931

3032
vi.mock('@podman-desktop/api', () => {
3133
return {
@@ -72,6 +74,48 @@ describe('getLocalModelFile', () => {
7274
});
7375
});
7476

77+
describe('getMountPath', () => {
78+
const DUMMY_MODEL: ModelInfo = {
79+
id: 'dummyModelId',
80+
file: undefined,
81+
properties: {},
82+
description: '',
83+
name: 'dummy-model',
84+
};
85+
86+
const DOWNLOADED_MODEL: ModelInfo & { file: { path: string; file: string } } = {
87+
...DUMMY_MODEL,
88+
file: {
89+
path: 'dummyPath',
90+
file: 'dummy.guff',
91+
},
92+
};
93+
94+
const UPLOADED_MODEL: ModelInfo & { file: { path: string; file: string } } = {
95+
...DUMMY_MODEL,
96+
file: {
97+
path: MACHINE_BASE_FOLDER,
98+
file: 'dummy.guff',
99+
},
100+
};
101+
102+
test('file in ModelInfo undefined', () => {
103+
expect(() => {
104+
getMountPath(DUMMY_MODEL);
105+
}).toThrowError('model is not available locally.');
106+
});
107+
108+
test('should join path with respect to system host', () => {
109+
const path = getMountPath(DOWNLOADED_MODEL);
110+
expect(path).toBe(join(DOWNLOADED_MODEL.file.path, DOWNLOADED_MODEL.file.file));
111+
});
112+
113+
test('uploaded model should use posix for join path', () => {
114+
const path = getMountPath(UPLOADED_MODEL);
115+
expect(path).toBe(posix.join(MACHINE_BASE_FOLDER, UPLOADED_MODEL.file.file));
116+
});
117+
});
118+
75119
describe('getRemoteModelFile', () => {
76120
test('file in ModelInfo undefined', () => {
77121
expect(() => {
@@ -91,7 +135,7 @@ describe('getRemoteModelFile', () => {
91135
},
92136
} as unknown as ModelInfo);
93137

94-
expect(path).toBe(`${MACHINE_BASE_FOLDER}dummy.guff`);
138+
expect(path).toBe(posix.join(MACHINE_BASE_FOLDER, 'dummy.guff'));
95139
});
96140
});
97141

packages/backend/src/utils/modelsUtils.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { join, posix } from 'node:path';
2020
import { getPodmanCli } from './podman';
2121
import { process } from '@podman-desktop/api';
2222

23-
export const MACHINE_BASE_FOLDER = '/home/user/ai-lab/models/';
23+
export const MACHINE_BASE_FOLDER = '/home/user/ai-lab/models';
2424

2525
/**
2626
* Given a model info object return the path where is it located locally
@@ -31,6 +31,19 @@ export function getLocalModelFile(modelInfo: ModelInfo): string {
3131
return join(modelInfo.file.path, modelInfo.file.file);
3232
}
3333

34+
/**
35+
* Return the path to mount where the model is located
36+
* @param modelInfo
37+
*/
38+
export function getMountPath(modelInfo: ModelInfo): string {
39+
if (modelInfo.file === undefined) throw new Error('model is not available locally.');
40+
// if the model is uploaded we need to use posix join
41+
if (modelInfo.file.path === MACHINE_BASE_FOLDER) {
42+
return posix.join(MACHINE_BASE_FOLDER, modelInfo.file.file);
43+
}
44+
return join(modelInfo.file.path, modelInfo.file.file);
45+
}
46+
3447
/**
3548
* Given a model info object return the theoretical path where the model
3649
* should be in the podman machine

packages/backend/src/workers/provider/LlamaCppPython.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import type {
2424
} from '@podman-desktop/api';
2525
import type { InferenceServerConfig } from '@shared/src/models/InferenceServerConfig';
2626
import { InferenceProvider } from './InferenceProvider';
27-
import { getLocalModelFile, getModelPropertiesForEnvironment } from '../../utils/modelsUtils';
27+
import { getModelPropertiesForEnvironment, getMountPath } from '../../utils/modelsUtils';
2828
import { DISABLE_SELINUX_LABEL_SECURITY_OPTION } from '../../utils/utils';
2929
import { LABEL_INFERENCE_SERVER } from '../../utils/inferenceUtils';
3030
import type { TaskRegistry } from '../../registries/TaskRegistry';
@@ -83,7 +83,7 @@ export class LlamaCppPython extends InferenceProvider {
8383
};
8484

8585
// get model mount settings
86-
const filename = getLocalModelFile(modelInfo);
86+
const filename = getMountPath(modelInfo);
8787
const target = `/models/${modelInfo.file.file}`;
8888

8989
// mount the file directory to avoid adding other files to the containers

packages/backend/src/workers/provider/WhisperCpp.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import type { ContainerProviderConnection, MountConfig } from '@podman-desktop/a
2525
import { DISABLE_SELINUX_LABEL_SECURITY_OPTION } from '../../utils/utils';
2626
import { whispercpp } from '../../assets/inference-images.json';
2727
import type { PodmanConnection } from '../../managers/podmanConnection';
28-
import { getLocalModelFile } from '../../utils/modelsUtils';
28+
import { getMountPath } from '../../utils/modelsUtils';
2929

3030
export class WhisperCpp extends InferenceProvider {
3131
constructor(
@@ -69,7 +69,7 @@ export class WhisperCpp extends InferenceProvider {
6969
if (!connection) throw new Error('no running connection could be found');
7070

7171
// get model mount settings
72-
const filename = getLocalModelFile(modelInfo);
72+
const filename = getMountPath(modelInfo);
7373
const target = `/models/${modelInfo.file.file}`;
7474

7575
// mount the file directory to avoid adding other files to the containers

packages/backend/src/workers/uploader/WSLUploader.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ describe('upload', () => {
119119
'machine2',
120120
'mkdir',
121121
'-p',
122-
'/home/user/ai-lab/models/',
122+
'/home/user/ai-lab/models',
123123
]);
124124
expect(process.exec).toBeCalledWith('podman.exe', [
125125
'machine',

0 commit comments

Comments
 (0)