diff --git a/src/locales/en-US/resources.ts b/src/locales/en-US/resources.ts
index 73abd7f5..465c9907 100644
--- a/src/locales/en-US/resources.ts
+++ b/src/locales/en-US/resources.ts
@@ -67,9 +67,10 @@ export default {
'The default storage directory is /var/lib/gpustack/cache or the directory specified with --data-dir.',
'resources.modelfiles.retry.download': 'Retry Download',
'resources.modelfiles.storagePath.holder':
- 'Waiting for download to complete...',
+ 'Waiting for the download to complete...',
'resources.filter.worker': 'Filter by Worker',
'resources.filter.source': 'Filter by Source',
'resources.modelfiles.delete.tips': 'Also delete the file from disk!',
- 'resources.modelfiles.copy.tips': 'Copy Full Path'
+ 'resources.modelfiles.copy.tips': 'Copy Full Path',
+ 'resources.filter.path': 'Filter by Path'
};
diff --git a/src/locales/ja-JP/resources.ts b/src/locales/ja-JP/resources.ts
index a6910c27..e0afeb28 100644
--- a/src/locales/ja-JP/resources.ts
+++ b/src/locales/ja-JP/resources.ts
@@ -72,7 +72,8 @@ export default {
'resources.filter.worker': 'Filter by Worker',
'resources.filter.source': 'Filter by Source',
'resources.modelfiles.delete.tips': 'Also delete the file from disk!',
- 'resources.modelfiles.copy.tips': 'Copy Full Path'
+ 'resources.modelfiles.copy.tips': 'Copy Full Path',
+ 'resources.filter.path': 'Filter by Path'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -91,4 +92,5 @@ export default {
// 13. 'resources.worker.add.step1',
// 14. 'resources.worker.add.step2.tips',
// 15. 'resources.modelfiles.copy.tips',
+// 16. 'resources.filter.path',
// ========== End of To-Do List ==========
diff --git a/src/locales/ru-RU/resources.ts b/src/locales/ru-RU/resources.ts
index ab26a27d..875c10e8 100644
--- a/src/locales/ru-RU/resources.ts
+++ b/src/locales/ru-RU/resources.ts
@@ -13,10 +13,14 @@ export default {
'resources.form.enablePartialOffload': 'Разрешить оффлоуд на CPU',
'resources.form.placementStrategy': 'Стратегия размещения',
'resources.form.workerSelector': 'Селектор воркеров',
- 'resources.form.enableDistributedInferenceAcrossWorkers': 'Разрешить распределённый инференс между воркерами',
- 'resources.form.spread.tips': 'Равномерно распределяет ресурсы между воркерами. Может увеличить фрагментацию ресурсов на отдельных воркерах.',
- 'resources.form.binpack.tips': 'Максимизирует утилизацию ресурсов, уменьшая фрагментацию на воркерах/GPU.',
- 'resources.form.workerSelector.description': 'Система выбирает подходящие GPU/воркеры для развертывания моделей на основе меток.',
+ 'resources.form.enableDistributedInferenceAcrossWorkers':
+ 'Разрешить распределённый инференс между воркерами',
+ 'resources.form.spread.tips':
+ 'Равномерно распределяет ресурсы между воркерами. Может увеличить фрагментацию ресурсов на отдельных воркерах.',
+ 'resources.form.binpack.tips':
+ 'Максимизирует утилизацию ресурсов, уменьшая фрагментацию на воркерах/GPU.',
+ 'resources.form.workerSelector.description':
+ 'Система выбирает подходящие GPU/воркеры для развертывания моделей на основе меток.',
'resources.table.ip': 'IP-адрес',
'resources.table.cpu': 'CPU',
'resources.table.memory': 'ОЗУ',
@@ -37,14 +41,19 @@ export default {
'resources.table.wokers': 'воркеры',
'resources.worker.linuxormaxos': 'Linux или macOS',
'resources.table.unified': 'Объединённая память',
- 'resources.worker.add.step1': 'Получить токен (Запустить на сервере)',
+ 'resources.worker.add.step1':
+ 'Получить токен (Запустить на сервере)',
'resources.worker.add.step2': 'Зарегистрировать воркер',
- 'resources.worker.add.step2.tips': 'Примечание: выполнить на подключаемом воркере, mytoken это токен, полученный на первом шаге',
- 'resources.worker.add.step3': 'После успешной регистрации обновите список воркеров.',
+ 'resources.worker.add.step2.tips':
+ 'Примечание: выполнить на подключаемом воркере, mytoken это токен, полученный на первом шаге',
+ 'resources.worker.add.step3':
+ 'После успешной регистрации обновите список воркеров.',
'resources.worker.container.supported': 'Только для Linux.',
'resources.worker.current.version': 'Текущая версия: {version}',
- 'resources.worker.driver.install': 'Установите необходимые драйверы и библиотеки перед установкой GPUStack.',
- 'resources.worker.select.command': 'Выберите метку для генерации команды и скопируйте её.',
+ 'resources.worker.driver.install':
+ 'Установите необходимые драйверы и библиотеки перед установкой GPUStack.',
+ 'resources.worker.select.command':
+ 'Выберите метку для генерации команды и скопируйте её.',
'resources.worker.script.install': 'Установка скриптом',
'resources.worker.container.install': 'Установка контейнером (только Linux)',
'resources.worker.cann.tips': `Укажите индексы GPU через ASCEND_VISIBLE_DEVICES=0,1,2,3 или ASCEND_VISIBLE_DEVICES=0-3.`,
@@ -54,15 +63,17 @@ export default {
'resources.modelfiles.size': 'Размер',
'resources.modelfiles.selecttarget': 'Выбрать назначение',
'resources.modelfiles.form.localdir': 'Локальный каталог',
- 'resources.modelfiles.form.localdir.tips': 'Каталог по умолчанию --data-dir.',
+ 'resources.modelfiles.form.localdir.tips':
+ 'Каталог по умолчанию --data-dir.',
'resources.modelfiles.retry.download': 'Повторить загрузку',
'resources.modelfiles.storagePath.holder': 'Ожидание завершения загрузки...',
'resources.filter.worker': 'Фильтровать по узлу',
'resources.filter.source': 'Фильтровать по источнику',
'resources.modelfiles.delete.tips': 'Также удалить файл с диска!',
- 'resources.modelfiles.copy.tips': 'Скопировать полный путь'
+ 'resources.modelfiles.copy.tips': 'Скопировать полный путь',
+ 'resources.filter.path': 'Filter by Path'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
-
+// 1. 'resources.filter.path'
// ========== End of To-Do List ==========
diff --git a/src/locales/zh-CN/resources.ts b/src/locales/zh-CN/resources.ts
index cbb17457..8fd977ac 100644
--- a/src/locales/zh-CN/resources.ts
+++ b/src/locales/zh-CN/resources.ts
@@ -69,5 +69,6 @@ export default {
'resources.filter.worker': '按 worker 筛选',
'resources.filter.source': '按来源筛选',
'resources.modelfiles.delete.tips': '同时从磁盘删除文件!',
- 'resources.modelfiles.copy.tips': '复制完整路径'
+ 'resources.modelfiles.copy.tips': '复制完整路径',
+ 'resources.filter.path': '路径查询'
};
diff --git a/src/pages/llmodels/components/deploy-builtin-modal.tsx b/src/pages/llmodels/components/deploy-builtin-modal.tsx
index 2d4084bc..b957c5ad 100644
--- a/src/pages/llmodels/components/deploy-builtin-modal.tsx
+++ b/src/pages/llmodels/components/deploy-builtin-modal.tsx
@@ -83,6 +83,8 @@ const AddModal: React.FC = (props) => {
setWarningStatus,
handleEvaluate,
generateGPUIds,
+ cancelEvaluate,
+ submitAnyway,
handleOnValuesChange,
warningStatus
} = useCheckCompatibility();
@@ -99,7 +101,6 @@ const AddModal: React.FC = (props) => {
const axiosToken = useRef(null);
const selectSpecRef = useRef({} as CatalogSpec);
const specListRef = useRef([]);
- const submitAnyway = useRef(null);
const handleSumit = () => {
form.current?.submit?.();
@@ -111,9 +112,11 @@ const AddModal: React.FC = (props) => {
};
const generateSubmitData = (formData: FormData) => {
+ const gpuSelector = generateGPUIds(formData);
const data = {
..._.omit(selectSpecRef.current, ['name']),
- ...formData
+ ...formData,
+ ...gpuSelector
};
return data;
@@ -233,6 +236,12 @@ const AddModal: React.FC = (props) => {
return evalutionData;
};
+ const handleCheckFormData = () => {
+ const values = form.current?.getFieldsValue();
+ const allValues = generateSubmitData(values);
+ handleCheckCompatibility(allValues);
+ };
+
const handleSourceChange = (source: string) => {
const defaultSpec = _.get(sourceGroupMap.current, `${source}.0`, {});
initFormDataBySource(defaultSpec);
@@ -245,8 +254,7 @@ const AddModal: React.FC = (props) => {
});
// set form value
initFormDataBySource(defaultSpec);
- const data = generateSubmitData(form.current.getFieldsValue());
- handleCheckCompatibility(data);
+ handleCheckFormData();
};
const checkSize = (list: any[]) => {
@@ -314,7 +322,7 @@ const AddModal: React.FC = (props) => {
form.current.setFieldsValue({
...data
});
- handleCheckCompatibility(data);
+ handleCheckFormData();
};
const fetchSpecData = async () => {
@@ -364,12 +372,14 @@ const AddModal: React.FC = (props) => {
'name',
_.toLower(current.name).replace(/\s/g, '-') || ''
);
- if (defaultSpec.backend === backendOptionsMap.vllm) {
- setIsGGUF(false);
- }
+
+ const allValues = generateSubmitData(defaultSpec);
+ handleCheckCompatibility(allValues);
if (defaultSpec.backend === backendOptionsMap.llamaBox) {
setIsGGUF(true);
+ } else {
+ setIsGGUF(false);
}
console.log('values====', form.current.form.getFieldsValue());
} catch (error) {
@@ -386,8 +396,7 @@ const AddModal: React.FC = (props) => {
form.current.setFieldsValue({
...data
});
- const allValues = generateSubmitData(data);
- handleCheckCompatibility(allValues);
+ handleCheckFormData();
};
const handleOnSizeChange = (val: number) => {
@@ -408,21 +417,12 @@ const AddModal: React.FC = (props) => {
form.current.setFieldsValue({
...data
});
- const allValues = generateSubmitData(data);
- handleCheckCompatibility(allValues);
+ handleCheckFormData();
};
const handleOk = async (values: FormData) => {
const data = generateSubmitData(values);
-
- if (submitAnyway.current) {
- onOk(data);
- return;
- }
- const evaluateResult = await handleCheckCompatibility(data);
- if (evaluateResult?.compatible) {
- onOk(data);
- }
+ onOk(data);
};
const handleCancel = useCallback(() => {
@@ -436,6 +436,7 @@ const AddModal: React.FC = (props) => {
}
return () => {
axiosToken.current?.cancel?.();
+ cancelEvaluate();
setWarningStatus({
show: false,
title: '',
diff --git a/src/pages/llmodels/components/deploy-modal.tsx b/src/pages/llmodels/components/deploy-modal.tsx
index 98cdf455..3943b6dc 100644
--- a/src/pages/llmodels/components/deploy-modal.tsx
+++ b/src/pages/llmodels/components/deploy-modal.tsx
@@ -117,16 +117,7 @@ const AddModal: FC = (props) => {
const handleOnOk = async (allValues: FormData) => {
const result = getSourceRepoConfigValue(props.source, allValues).values;
- if (submitAnyway.current) {
- onOk(result);
- return;
- }
-
- const evalutionData = await handleEvaluate(result);
- handleShowCompatibleAlert?.(evalutionData);
- if (evalutionData?.compatible) {
- onOk(result);
- }
+ onOk(result);
};
const handleSubmitAnyway = async () => {
@@ -198,22 +189,25 @@ const AddModal: FC = (props) => {
onCancel?.();
}, [onCancel]);
- useEffect(() => {
- if (!open) {
- return;
- }
+ const handleOnOpen = useCallback(() => {
if (props.deploymentType === 'modelFiles') {
form.current?.form?.setFieldsValue({
...props.initialValues
});
- setIsGGUF(props.isGGUF || false);
} else {
const backend =
source === modelSourceMap.ollama_library_value
? backendOptionsMap.llamaBox
: backendOptionsMap.vllm;
form.current?.setFieldValue?.('backend', backend);
- setIsGGUF(backend === backendOptionsMap.llamaBox);
+ }
+ }, [source, props.initialValues, props.deploymentType]);
+
+ useEffect(() => {
+ if (!open) {
+ return;
+ } else {
+ handleOnOpen();
}
return () => {
@@ -225,7 +219,7 @@ const AddModal: FC = (props) => {
});
checkTokenRef.current?.cancel();
};
- }, [open, props.isGGUF, source, props.initialValues, props.deploymentType]);
+ }, [open, handleOnOpen]);
return (
= ({
-
+
{dayjs(instanceData.created_at).format('YYYY-MM-DD HH:mm:ss')}
diff --git a/src/pages/llmodels/components/search-model.tsx b/src/pages/llmodels/components/search-model.tsx
index cf5574a9..a0f5ef61 100644
--- a/src/pages/llmodels/components/search-model.tsx
+++ b/src/pages/llmodels/components/search-model.tsx
@@ -123,7 +123,7 @@ const SearchModel: React.FC = (props) => {
value: item.name,
label: item.name,
isGGUF: checkIsGGUF(item),
- source: modelSourceMap.modelscope_value
+ source: modelSource
};
});
return list;
@@ -161,7 +161,7 @@ const SearchModel: React.FC = (props) => {
tags: item.Tags,
libraries: item.Libraries,
isGGUF: checkIsGGUF({ tags: item.Tags, libraries: item.Libraries }),
- source: modelSourceMap.modelscope_value
+ source: modelSource
};
});
diff --git a/src/pages/llmodels/components/table-list.tsx b/src/pages/llmodels/components/table-list.tsx
index 3e632c58..202a9a66 100644
--- a/src/pages/llmodels/components/table-list.tsx
+++ b/src/pages/llmodels/components/table-list.tsx
@@ -182,11 +182,13 @@ const Models: React.FC = ({
hasLinuxWorker?: boolean;
source: SourceType;
gpuOptions: any[];
+ isGGUF?: boolean;
modelFileOptions?: any[];
}>({
show: false,
hasLinuxWorker: false,
width: 600,
+ isGGUF: false,
source: modelSourceMap.huggingface_value as SourceType,
gpuOptions: [],
modelFileOptions: []
@@ -830,6 +832,7 @@ const Models: React.FC = ({
title={intl.formatMessage({ id: 'models.button.deploy' })}
source={openDeployModal.source}
width={openDeployModal.width}
+ isGGUF={openDeployModal.isGGUF}
hasLinuxWorker={openDeployModal.hasLinuxWorker}
gpuOptions={openDeployModal.gpuOptions}
modelFileOptions={openDeployModal.modelFileOptions || []}
diff --git a/src/pages/llmodels/components/update-modal.tsx b/src/pages/llmodels/components/update-modal.tsx
index dac0c027..6fa88b18 100644
--- a/src/pages/llmodels/components/update-modal.tsx
+++ b/src/pages/llmodels/components/update-modal.tsx
@@ -311,23 +311,12 @@ const UpdateModal: React.FC = (props) => {
submitData = {
..._.omit(formdata, ['scheduleType']),
categories: formdata.categories ? [formdata.categories] : [],
- worker_selector: null,
+ worker_selector:
+ formdata.scheduleType === 'manual' ? null : formdata.worker_selector,
...obj,
- ...(formdata.scheduleType === 'manual'
- ? generateGPUIds(formdata)
- : { gpu_selector: null })
+ ...generateGPUIds(formdata)
};
-
- if (submitAnyway.current) {
- onOk(submitData);
- return;
- }
-
- const evalutionData = await handleEvaluate(submitData);
- handleShowCompatibleAlert?.(evalutionData);
- if (evalutionData?.compatible) {
- onOk(submitData);
- }
+ onOk(submitData);
};
const onValuesChange = (changedValues: any, allValues: any) => {
diff --git a/src/pages/llmodels/config/button-actions.ts b/src/pages/llmodels/config/button-actions.ts
index a9f46104..10299bb3 100644
--- a/src/pages/llmodels/config/button-actions.ts
+++ b/src/pages/llmodels/config/button-actions.ts
@@ -29,7 +29,7 @@ const icons = {
export const modalConfig: Record<
string,
- { show: boolean; width: string | number; source: any }
+ { show: boolean; width: string | number; source: any; isGGUF?: boolean }
> = {
huggingface: {
show: true,
@@ -39,6 +39,7 @@ export const modalConfig: Record<
ollama_library: {
show: true,
width: 600,
+ isGGUF: true,
source: modelSourceMap.ollama_library_value
},
modelscope: {
diff --git a/src/pages/llmodels/hooks/index.ts b/src/pages/llmodels/hooks/index.ts
index 8b81c094..420cc273 100644
--- a/src/pages/llmodels/hooks/index.ts
+++ b/src/pages/llmodels/hooks/index.ts
@@ -413,6 +413,11 @@ export const useCheckCompatibility = () => {
const debounceHandleValuesChange = _.debounce(handleOnValuesChange, 300);
+ const cancelEvaluate = () => {
+ checkTokenRef.current?.cancel();
+ checkTokenRef.current = null;
+ };
+
useEffect(() => {
return () => {
checkTokenRef.current?.cancel();
@@ -429,6 +434,7 @@ export const useCheckCompatibility = () => {
submitAnyway,
generateGPUIds,
handleEvaluate,
- setWarningStatus
+ setWarningStatus,
+ cancelEvaluate
};
};
diff --git a/src/pages/resources/components/model-files.tsx b/src/pages/resources/components/model-files.tsx
index d35f8c00..9911739c 100644
--- a/src/pages/resources/components/model-files.tsx
+++ b/src/pages/resources/components/model-files.tsx
@@ -527,7 +527,7 @@ const ModelFiles = () => {