fix: deploy from model files source incorrect
This commit is contained in:
@@ -32,6 +32,11 @@ export default {
|
|||||||
colorBgSpotlight: '#3e3e3e'
|
colorBgSpotlight: '#3e3e3e'
|
||||||
// sizePopupArrow: 0
|
// sizePopupArrow: 0
|
||||||
},
|
},
|
||||||
|
Button: {
|
||||||
|
primaryShadow: 'none',
|
||||||
|
defaultShadow: 'none',
|
||||||
|
dangerShadow: 'none'
|
||||||
|
},
|
||||||
Cascader: {
|
Cascader: {
|
||||||
dropdownHeight: 240
|
dropdownHeight: 240
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -923,3 +923,10 @@ body {
|
|||||||
.ant-notification .ant-notification-notice-close {
|
.ant-notification .ant-notification-notice-close {
|
||||||
width: fit-content !important;
|
width: fit-content !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.desc-block {
|
||||||
|
border-radius: var(--border-radius-2px);
|
||||||
|
background-color: rgb(89 89 89);
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -106,13 +106,16 @@ export default function useTableFetch<ListItem>(options: {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePageChange = (page: number, pageSize: number) => {
|
const handleQueryChange = (params: any) => {
|
||||||
setQueryParams({
|
setQueryParams({
|
||||||
...queryParams,
|
...queryParams,
|
||||||
page: page,
|
...params
|
||||||
perPage: pageSize || 10
|
|
||||||
});
|
});
|
||||||
fetchData({ query: { ...queryParams, page, perPage: pageSize || 10 } });
|
fetchData({ query: { ...queryParams, ...params } });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePageChange = (page: number, pageSize: number) => {
|
||||||
|
handleQueryChange({ page, perPage: pageSize || 10 });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTableChange = (pagination: any, filters: any, sorter: any) => {
|
const handleTableChange = (pagination: any, filters: any, sorter: any) => {
|
||||||
@@ -124,18 +127,10 @@ export default function useTableFetch<ListItem>(options: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const debounceUpdateFilter = _.debounce((e: any) => {
|
const debounceUpdateFilter = _.debounce((e: any) => {
|
||||||
setQueryParams({
|
handleQueryChange({
|
||||||
...queryParams,
|
|
||||||
page: 1,
|
page: 1,
|
||||||
search: e.target.value
|
search: e.target.value
|
||||||
});
|
});
|
||||||
fetchData({
|
|
||||||
query: {
|
|
||||||
...queryParams,
|
|
||||||
page: 1,
|
|
||||||
search: e.target.value
|
|
||||||
}
|
|
||||||
});
|
|
||||||
createModelsChunkRequest({
|
createModelsChunkRequest({
|
||||||
...queryParams,
|
...queryParams,
|
||||||
search: e.target.value
|
search: e.target.value
|
||||||
@@ -198,6 +193,7 @@ export default function useTableFetch<ListItem>(options: {
|
|||||||
handlePageChange,
|
handlePageChange,
|
||||||
handleTableChange,
|
handleTableChange,
|
||||||
handleSearch,
|
handleSearch,
|
||||||
|
handleQueryChange,
|
||||||
handleNameChange
|
handleNameChange
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export default {
|
|||||||
'resources.modelfiles.selecttarget': 'Select Target',
|
'resources.modelfiles.selecttarget': 'Select Target',
|
||||||
'resources.modelfiles.form.localdir': 'Local Directory',
|
'resources.modelfiles.form.localdir': 'Local Directory',
|
||||||
'resources.modelfiles.form.localdir.tips':
|
'resources.modelfiles.form.localdir.tips':
|
||||||
'The default storage directory is /var/lib/gpustack/cache.',
|
'The default storage directory is <span class="desc-block">/var/lib/gpustack/cache</span> or the directory specified with <span class="desc-block">--data-dir</span>.',
|
||||||
'resources.modelfiles.retry.download': 'Retry Download',
|
'resources.modelfiles.retry.download': 'Retry Download',
|
||||||
'resources.modelfiles.storagePath.holder':
|
'resources.modelfiles.storagePath.holder':
|
||||||
'Waiting for download to complete...',
|
'Waiting for download to complete...',
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ export default {
|
|||||||
'resources.modelfiles.selecttarget': 'Select Target',
|
'resources.modelfiles.selecttarget': 'Select Target',
|
||||||
'resources.modelfiles.form.localdir': 'Local Directory',
|
'resources.modelfiles.form.localdir': 'Local Directory',
|
||||||
'resources.modelfiles.form.localdir.tips':
|
'resources.modelfiles.form.localdir.tips':
|
||||||
'The default storage directory is /var/lib/gpustack/cache.',
|
'The default storage directory is <span class="desc-block>/var/lib/gpustack/cache</span> or the directory specified with <span class="desc-block">--data-dir</span>.',
|
||||||
'resources.modelfiles.retry.download': 'Retry Download',
|
'resources.modelfiles.retry.download': 'Retry Download',
|
||||||
'resources.modelfiles.storagePath.holder':
|
'resources.modelfiles.storagePath.holder':
|
||||||
'Waiting for download to complete...',
|
'Waiting for download to complete...',
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export default {
|
|||||||
'resources.modelfiles.selecttarget': '选择目标位置',
|
'resources.modelfiles.selecttarget': '选择目标位置',
|
||||||
'resources.modelfiles.form.localdir': '本地目录',
|
'resources.modelfiles.form.localdir': '本地目录',
|
||||||
'resources.modelfiles.form.localdir.tips':
|
'resources.modelfiles.form.localdir.tips':
|
||||||
'默认存储目录为 /var/lib/gpustack/cache',
|
'默认存储目录为 <span class="desc-block">/var/lib/gpustack/cache</span>,或使用 <span class="desc-block">--data-dir</span> 指定的目录',
|
||||||
'resources.modelfiles.retry.download': '重新下载',
|
'resources.modelfiles.retry.download': '重新下载',
|
||||||
'resources.modelfiles.storagePath.holder': '等待下载完成...',
|
'resources.modelfiles.storagePath.holder': '等待下载完成...',
|
||||||
'resources.filter.worker': '按 worker 筛选',
|
'resources.filter.worker': '按 worker 筛选',
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
|||||||
ref,
|
ref,
|
||||||
() => {
|
() => {
|
||||||
return {
|
return {
|
||||||
|
form: form,
|
||||||
submit: handleSumit,
|
submit: handleSumit,
|
||||||
setFieldsValue: (values: FormData) => {
|
setFieldsValue: (values: FormData) => {
|
||||||
form.setFieldsValue(values);
|
form.setFieldsValue(values);
|
||||||
@@ -288,30 +289,6 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
|||||||
label={intl.formatMessage({ id: 'models.form.filePath' })}
|
label={intl.formatMessage({ id: 'models.form.filePath' })}
|
||||||
description={<TooltipList list={localPathTipsList}></TooltipList>}
|
description={<TooltipList list={localPathTipsList}></TooltipList>}
|
||||||
></SealAutoComplete>
|
></SealAutoComplete>
|
||||||
{/* <SealCascader
|
|
||||||
required
|
|
||||||
showSearch
|
|
||||||
description={<TooltipList list={localPathTipsList}></TooltipList>}
|
|
||||||
expandTrigger="hover"
|
|
||||||
multiple={false}
|
|
||||||
onSearch={handleOnSearch}
|
|
||||||
popupClassName="cascader-popup-wrapper gpu-selector"
|
|
||||||
maxTagCount={1}
|
|
||||||
label={intl.formatMessage({ id: 'models.form.gpuselector' })}
|
|
||||||
options={modelFileOptions}
|
|
||||||
showCheckedStrategy="SHOW_CHILD"
|
|
||||||
value={form.getFieldValue('local_path')}
|
|
||||||
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
|
||||||
displayRender={() => (
|
|
||||||
<Input
|
|
||||||
style={{
|
|
||||||
border: 'none',
|
|
||||||
outline: 'none',
|
|
||||||
width: '100%'
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
></SealCascader> */}
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -488,7 +465,6 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleOnSelectModel();
|
handleOnSelectModel();
|
||||||
}, [props.selectedModel.name]);
|
}, [props.selectedModel.name]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Form
|
||||||
name="deployModel"
|
name="deployModel"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ type AddModalProps = {
|
|||||||
gpuOptions: any[];
|
gpuOptions: any[];
|
||||||
modelFileOptions: any[];
|
modelFileOptions: any[];
|
||||||
initialValues?: any;
|
initialValues?: any;
|
||||||
|
deploymentType?: 'modelList' | 'modelFiles';
|
||||||
onOk: (values: FormData) => void;
|
onOk: (values: FormData) => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
};
|
};
|
||||||
@@ -39,6 +40,7 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
source,
|
source,
|
||||||
action,
|
action,
|
||||||
width = 600,
|
width = 600,
|
||||||
|
deploymentType = 'modelList',
|
||||||
initialValues
|
initialValues
|
||||||
} = props || {};
|
} = props || {};
|
||||||
const SEARCH_SOURCE = [
|
const SEARCH_SOURCE = [
|
||||||
@@ -147,8 +149,10 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
} else if (source === modelSourceMap.ollama_library_value) {
|
} else if (source === modelSourceMap.ollama_library_value) {
|
||||||
form.current?.setFieldValue?.('backend', backendOptionsMap.llamaBox);
|
form.current?.setFieldValue?.('backend', backendOptionsMap.llamaBox);
|
||||||
setIsGGUF(true);
|
setIsGGUF(true);
|
||||||
} else {
|
}
|
||||||
form.current?.setFieldsValue({
|
|
||||||
|
if (props.deploymentType === 'modelFiles' && open) {
|
||||||
|
form.current?.form?.setFieldsValue({
|
||||||
...props.initialValues
|
...props.initialValues
|
||||||
});
|
});
|
||||||
setIsGGUF(props.isGGUF || false);
|
setIsGGUF(props.isGGUF || false);
|
||||||
@@ -157,7 +161,7 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
return () => {
|
return () => {
|
||||||
setSelectedModel({});
|
setSelectedModel({});
|
||||||
};
|
};
|
||||||
}, [open, source, props.isGGUF, props.initialValues]);
|
}, [open, source, props.isGGUF, props.initialValues, props.deploymentType]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
@@ -198,7 +202,8 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
footer={false}
|
footer={false}
|
||||||
>
|
>
|
||||||
<div style={{ display: 'flex', height: '100%' }}>
|
<div style={{ display: 'flex', height: '100%' }}>
|
||||||
{SEARCH_SOURCE.includes(props.source) && (
|
{SEARCH_SOURCE.includes(props.source) &&
|
||||||
|
deploymentType === 'modelList' && (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@@ -283,7 +288,8 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
{SEARCH_SOURCE.includes(source) && (
|
{SEARCH_SOURCE.includes(source) &&
|
||||||
|
deploymentType === 'modelList' && (
|
||||||
<TitleWrapper>
|
<TitleWrapper>
|
||||||
{intl.formatMessage({ id: 'models.form.configurations' })}
|
{intl.formatMessage({ id: 'models.form.configurations' })}
|
||||||
<span style={{ display: 'flex', height: 24 }}></span>
|
<span style={{ display: 'flex', height: 24 }}></span>
|
||||||
|
|||||||
@@ -6,64 +6,6 @@ import { ModelInstanceListItem } from '../config/types';
|
|||||||
import '../style/instance-item.less';
|
import '../style/instance-item.less';
|
||||||
import InstanceItem from './instance-item';
|
import InstanceItem from './instance-item';
|
||||||
|
|
||||||
const testInstanceData = {
|
|
||||||
source: 'huggingface',
|
|
||||||
huggingface_repo_id: 'Qwen/Qwen2.5-3B-Instruct',
|
|
||||||
huggingface_filename: null,
|
|
||||||
ollama_library_model_name: null,
|
|
||||||
model_scope_model_id: null,
|
|
||||||
model_scope_file_path: null,
|
|
||||||
local_path: null,
|
|
||||||
name: 'qwen2.5-XVCXa',
|
|
||||||
worker_id: 1,
|
|
||||||
worker_name: 'sealgpuhost4080',
|
|
||||||
worker_ip: '192.168.50.12',
|
|
||||||
pid: 208852,
|
|
||||||
port: 40063,
|
|
||||||
download_progress: 72.11,
|
|
||||||
resolved_path: null,
|
|
||||||
state: 'downloading',
|
|
||||||
state_message: '',
|
|
||||||
computed_resource_claim: {
|
|
||||||
is_unified_memory: false,
|
|
||||||
offload_layers: null,
|
|
||||||
total_layers: null,
|
|
||||||
ram: null,
|
|
||||||
vram: {
|
|
||||||
'0': 1717148058
|
|
||||||
},
|
|
||||||
tensor_split: null
|
|
||||||
},
|
|
||||||
gpu_indexes: [0],
|
|
||||||
model_id: 1,
|
|
||||||
model_name: 'qwen2.5',
|
|
||||||
distributed_servers: {
|
|
||||||
rpc_servers: null,
|
|
||||||
ray_actors: [
|
|
||||||
{
|
|
||||||
worker_id: 2,
|
|
||||||
worker_ip: '192.168.50.13',
|
|
||||||
total_gpus: 1,
|
|
||||||
gpu_indexes: [0],
|
|
||||||
computed_resource_claim: {
|
|
||||||
is_unified_memory: false,
|
|
||||||
offload_layers: null,
|
|
||||||
total_layers: null,
|
|
||||||
ram: null,
|
|
||||||
vram: {
|
|
||||||
'0': 23181498777
|
|
||||||
},
|
|
||||||
tensor_split: null
|
|
||||||
},
|
|
||||||
download_progress: 27.49
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
id: 1,
|
|
||||||
created_at: '2025-03-24T12:06:30Z',
|
|
||||||
updated_at: '2025-03-24T12:09:01Z'
|
|
||||||
};
|
|
||||||
|
|
||||||
interface InstanceItemProps {
|
interface InstanceItemProps {
|
||||||
list: ModelInstanceListItem[];
|
list: ModelInstanceListItem[];
|
||||||
workerList: WorkerListItem[];
|
workerList: WorkerListItem[];
|
||||||
|
|||||||
@@ -171,9 +171,15 @@ const TargetForm: React.FC<TargetFormProps> = forwardRef((props, ref) => {
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<SealInput.Input
|
<SealInput.Input
|
||||||
description={intl.formatMessage({
|
description={
|
||||||
|
<span
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: intl.formatMessage({
|
||||||
id: 'resources.modelfiles.form.localdir.tips'
|
id: 'resources.modelfiles.form.localdir.tips'
|
||||||
})}
|
})
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
|
}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id: 'resources.modelfiles.form.localdir'
|
id: 'resources.modelfiles.form.localdir'
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import DeployModal from '@/pages/llmodels/components/deploy-modal';
|
|||||||
import {
|
import {
|
||||||
backendOptionsMap,
|
backendOptionsMap,
|
||||||
getSourceRepoConfigValue,
|
getSourceRepoConfigValue,
|
||||||
modelSourceMap
|
modelSourceMap,
|
||||||
|
setSourceRepoConfigValue
|
||||||
} from '@/pages/llmodels/config';
|
} from '@/pages/llmodels/config';
|
||||||
import { identifyModelTask } from '@/pages/llmodels/config/audio-catalog';
|
import { identifyModelTask } from '@/pages/llmodels/config/audio-catalog';
|
||||||
import {
|
import {
|
||||||
@@ -66,8 +67,7 @@ import {
|
|||||||
ListItem as WorkerListItem
|
ListItem as WorkerListItem
|
||||||
} from '../config/types';
|
} from '../config/types';
|
||||||
|
|
||||||
const pattern = /^(.*)-(\d+)-of-(\d+)\.(.*)$/;
|
const filterPattern = /^(.*?)(?:-\d+-of-\d+)?(\.gguf)?$/;
|
||||||
const filterPattern = /^(.*)-\d+-of-\d+(\.gguf)?$/;
|
|
||||||
|
|
||||||
const getWorkerName = (
|
const getWorkerName = (
|
||||||
id: number,
|
id: number,
|
||||||
@@ -122,7 +122,7 @@ const ModelFiles = () => {
|
|||||||
handleTableChange,
|
handleTableChange,
|
||||||
handleSearch,
|
handleSearch,
|
||||||
handleNameChange,
|
handleNameChange,
|
||||||
setQueryParams
|
handleQueryChange
|
||||||
} = useTableFetch<ListItem>({
|
} = useTableFetch<ListItem>({
|
||||||
fetchAPI: queryModelFilesList,
|
fetchAPI: queryModelFilesList,
|
||||||
deleteAPI: deleteModelFile,
|
deleteAPI: deleteModelFile,
|
||||||
@@ -198,18 +198,10 @@ const ModelFiles = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleWorkerChange = (value: number) => {
|
const handleWorkerChange = (value: number) => {
|
||||||
setQueryParams({
|
handleQueryChange({
|
||||||
...queryParams,
|
|
||||||
page: 1,
|
page: 1,
|
||||||
worker_id: value
|
worker_id: value
|
||||||
});
|
});
|
||||||
fetchData({
|
|
||||||
query: {
|
|
||||||
...queryParams,
|
|
||||||
page: 1,
|
|
||||||
worker_id: value
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
const generateInitialValues = (record: ListItem) => {
|
const generateInitialValues = (record: ListItem) => {
|
||||||
const isGGUF = _.includes(record.resolved_paths?.[0], 'gguf');
|
const isGGUF = _.includes(record.resolved_paths?.[0], 'gguf');
|
||||||
@@ -229,9 +221,12 @@ const ModelFiles = () => {
|
|||||||
).pop()
|
).pop()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const result = setSourceRepoConfigValue(record.source, record);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
source: modelSourceMap.local_path_value,
|
...result.values,
|
||||||
local_path: record.resolved_paths?.[0],
|
source: record.source,
|
||||||
|
local_path: record.local_path,
|
||||||
name: extractFileName(name),
|
name: extractFileName(name),
|
||||||
backend:
|
backend:
|
||||||
isGGUF || isOllama
|
isGGUF || isOllama
|
||||||
@@ -248,17 +243,7 @@ const ModelFiles = () => {
|
|||||||
if (!parts.length) {
|
if (!parts.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const partsList = parts.map((item: string) => {
|
|
||||||
const match = item.match(pattern);
|
|
||||||
if (!match) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
part: parseInt(match[2], 10),
|
|
||||||
total: parseInt(match[3], 10),
|
|
||||||
name: _.split(match[1], '/').pop()
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return (
|
return (
|
||||||
<Tag
|
<Tag
|
||||||
className="flex-center"
|
className="flex-center"
|
||||||
@@ -295,8 +280,11 @@ const ModelFiles = () => {
|
|||||||
]);
|
]);
|
||||||
const dataList = generateModelFileOptions(modelFileList, workersList);
|
const dataList = generateModelFileOptions(modelFileList, workersList);
|
||||||
const initialValues = generateInitialValues(record);
|
const initialValues = generateInitialValues(record);
|
||||||
|
console.log('initialValues:', initialValues);
|
||||||
setOpenDeployModal({
|
setOpenDeployModal({
|
||||||
...openDeployModal,
|
...openDeployModal,
|
||||||
|
source: record.source,
|
||||||
|
width: 600,
|
||||||
modelFileOptions: dataList,
|
modelFileOptions: dataList,
|
||||||
gpuOptions: gpuList,
|
gpuOptions: gpuList,
|
||||||
initialValues: initialValues,
|
initialValues: initialValues,
|
||||||
@@ -393,7 +381,11 @@ const ModelFiles = () => {
|
|||||||
dataIndex: 'source',
|
dataIndex: 'source',
|
||||||
render: (text: string, record: ListItem) => (
|
render: (text: string, record: ListItem) => (
|
||||||
<span className="flex flex-column" style={{ width: '100%' }}>
|
<span className="flex flex-column" style={{ width: '100%' }}>
|
||||||
|
{record.source === modelSourceMap.local_path_value ? (
|
||||||
|
intl.formatMessage({ id: 'models.form.localPath' })
|
||||||
|
) : (
|
||||||
<AutoTooltip ghost>{generateSource(record)}</AutoTooltip>
|
<AutoTooltip ghost>{generateSource(record)}</AutoTooltip>
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -581,6 +573,7 @@ const ModelFiles = () => {
|
|||||||
workersList={workersList}
|
workersList={workersList}
|
||||||
></DownloadModal>
|
></DownloadModal>
|
||||||
<DeployModal
|
<DeployModal
|
||||||
|
deploymentType="modelFiles"
|
||||||
open={openDeployModal.show}
|
open={openDeployModal.show}
|
||||||
action={PageAction.CREATE}
|
action={PageAction.CREATE}
|
||||||
title={intl.formatMessage({ id: 'models.button.deploy' })}
|
title={intl.formatMessage({ id: 'models.button.deploy' })}
|
||||||
|
|||||||
Reference in New Issue
Block a user