fix: gpu selector by cluster
This commit is contained in:
@@ -5,12 +5,16 @@ import ContainerInstall from './container-install';
|
||||
|
||||
type ViewModalProps = {
|
||||
open: boolean;
|
||||
token: string;
|
||||
registrationInfo: {
|
||||
token: string;
|
||||
image: string;
|
||||
server_url: string;
|
||||
};
|
||||
onCancel: () => void;
|
||||
};
|
||||
|
||||
const AddWorker: React.FC<ViewModalProps> = (props) => {
|
||||
const { open, onCancel, token = '${token}' } = props || {};
|
||||
const { open, onCancel, registrationInfo } = props || {};
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
@@ -30,7 +34,7 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
|
||||
maxContentHeight={450}
|
||||
footer={null}
|
||||
>
|
||||
<ContainerInstall token={token} />
|
||||
<ContainerInstall registrationInfo={registrationInfo} />
|
||||
</ScrollerModal>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,7 +9,11 @@ import { addWorkerGuide, containerInstallOptions } from '../config';
|
||||
import './styles/installation.less';
|
||||
|
||||
type ViewModalProps = {
|
||||
token: string;
|
||||
registrationInfo: {
|
||||
token: string;
|
||||
image: string;
|
||||
server_url: string;
|
||||
};
|
||||
};
|
||||
|
||||
const npuOptions = [
|
||||
@@ -18,6 +22,7 @@ const npuOptions = [
|
||||
];
|
||||
|
||||
const AddWorker: React.FC<ViewModalProps> = (props) => {
|
||||
const { registrationInfo } = props || {};
|
||||
const intl = useIntl();
|
||||
|
||||
const origin = window.location.origin;
|
||||
@@ -40,12 +45,18 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
|
||||
const tag = activeKey === 'cuda' ? version : `${version}-${activeKey}`;
|
||||
|
||||
return commandCode?.registerWorker({
|
||||
server: origin,
|
||||
server: registrationInfo.server_url || origin,
|
||||
tag: tag,
|
||||
token: props.token || '${token}',
|
||||
token: registrationInfo.token || '${token}',
|
||||
workerip: '${workerip}'
|
||||
});
|
||||
}, [versionInfo, activeKey, props.token, npuKey]);
|
||||
}, [
|
||||
versionInfo,
|
||||
activeKey,
|
||||
registrationInfo.token,
|
||||
registrationInfo.server_url,
|
||||
npuKey
|
||||
]);
|
||||
|
||||
const handleOnChange = (value: string | number) => {
|
||||
setNpuKey(value as string);
|
||||
@@ -53,7 +64,7 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
|
||||
|
||||
return (
|
||||
<div className="container-install">
|
||||
<h3 className="m-t-10 font-size-14 font-600">
|
||||
<h3 className="m-t-0 font-size-14 font-600">
|
||||
1. {intl.formatMessage({ id: 'resources.worker.add.step2' })}{' '}
|
||||
<span
|
||||
className="font-size-12"
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
} from '@/pages/llmodels/config/button-actions';
|
||||
import { SourceType } from '@/pages/llmodels/config/types';
|
||||
import DownloadModal from '@/pages/llmodels/download';
|
||||
import { useGenerateWorkerOptions } from '@/pages/llmodels/hooks/use-form-initial-values';
|
||||
import { convertFileSize } from '@/utils';
|
||||
import {
|
||||
CheckCircleFilled,
|
||||
@@ -32,19 +33,14 @@ import { ConfigProvider, Empty, Table, Tag, Typography, message } from 'antd';
|
||||
import dayjs from 'dayjs';
|
||||
import { useAtom } from 'jotai';
|
||||
import _ from 'lodash';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
checkCurrentbackend,
|
||||
useGenerateFormEditInitialValues,
|
||||
useGenerateModelFileOptions
|
||||
} from '../../llmodels/hooks';
|
||||
import { checkCurrentbackend } from '../../llmodels/hooks';
|
||||
import {
|
||||
MODEL_FILES_API,
|
||||
deleteModelFile,
|
||||
downloadModelFile,
|
||||
queryModelFilesList,
|
||||
queryWorkersList,
|
||||
retryDownloadModelFile
|
||||
} from '../apis';
|
||||
import {
|
||||
@@ -53,10 +49,7 @@ import {
|
||||
ModelfileStateMapValue,
|
||||
WorkerStatusMap
|
||||
} from '../config';
|
||||
import {
|
||||
ModelFile as ListItem,
|
||||
ListItem as WorkerListItem
|
||||
} from '../config/types';
|
||||
import { ModelFile as ListItem } from '../config/types';
|
||||
|
||||
const { Paragraph } = Typography;
|
||||
|
||||
@@ -287,7 +280,8 @@ const ResolvedPathColumn = (props: { record: ListItem }) => {
|
||||
};
|
||||
|
||||
const ModelFiles = () => {
|
||||
const { getGPUList } = useGenerateFormEditInitialValues();
|
||||
const { getWorkerOptionList, workerOptions, clusterList, workersList } =
|
||||
useGenerateWorkerOptions();
|
||||
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();
|
||||
const [modelsExpandKeys, setModelsExpandKeys] = useAtom(modelsExpandKeysAtom);
|
||||
const navigate = useNavigate();
|
||||
@@ -311,63 +305,36 @@ const ModelFiles = () => {
|
||||
watch: true,
|
||||
contentForDelete: 'resources.modelfiles.modelfile'
|
||||
});
|
||||
const { getModelFileList, generateModelFileOptions } =
|
||||
useGenerateModelFileOptions();
|
||||
|
||||
const intl = useIntl();
|
||||
const { showSuccess } = useAppUtils();
|
||||
const [workersList, setWorkersList] = useState<any[]>([]);
|
||||
const [downloadModalStatus, setDownlaodMoalStatus] = useState<{
|
||||
show: boolean;
|
||||
width: number | string;
|
||||
source: string;
|
||||
hasLinuxWorker: boolean;
|
||||
gpuOptions: any[];
|
||||
}>({
|
||||
show: false,
|
||||
width: 600,
|
||||
hasLinuxWorker: false,
|
||||
source: modelSourceMap.huggingface_value,
|
||||
gpuOptions: []
|
||||
source: modelSourceMap.huggingface_value
|
||||
});
|
||||
const [openDeployModal, setOpenDeployModal] = useState<{
|
||||
show: boolean;
|
||||
width: number | string;
|
||||
source: SourceType;
|
||||
gpuOptions: any[];
|
||||
modelFileOptions?: any[];
|
||||
initialValues: any;
|
||||
isGGUF?: boolean;
|
||||
}>({
|
||||
show: false,
|
||||
width: 600,
|
||||
source: modelSourceMap.local_path_value as SourceType,
|
||||
gpuOptions: [],
|
||||
modelFileOptions: [],
|
||||
initialValues: {},
|
||||
isGGUF: false
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const fetchWorkerList = async () => {
|
||||
try {
|
||||
const res = await queryWorkersList({
|
||||
page: 1,
|
||||
perPage: 100
|
||||
});
|
||||
|
||||
const list = res.items?.map((item: WorkerListItem) => {
|
||||
return {
|
||||
...item,
|
||||
value: item.id,
|
||||
label: item.name
|
||||
};
|
||||
});
|
||||
setWorkersList(list);
|
||||
} catch (error) {
|
||||
// console.log('error', error);
|
||||
}
|
||||
};
|
||||
fetchWorkerList();
|
||||
getWorkerOptionList();
|
||||
}, []);
|
||||
|
||||
const extractFileName = (name: string) => {
|
||||
@@ -440,16 +407,10 @@ const ModelFiles = () => {
|
||||
showSuccess();
|
||||
} else if (val === 'deploy') {
|
||||
saveScrollHeight();
|
||||
const [modelFileList, gpuList] = await Promise.all([
|
||||
getModelFileList(),
|
||||
getGPUList()
|
||||
]);
|
||||
const dataList = generateModelFileOptions(modelFileList, workersList);
|
||||
const initialValues = generateInitialValues(record, gpuList);
|
||||
|
||||
const initialValues = generateInitialValues(record, []);
|
||||
setOpenDeployModal({
|
||||
...openDeployModal,
|
||||
modelFileOptions: dataList,
|
||||
gpuOptions: gpuList,
|
||||
initialValues: initialValues,
|
||||
isGGUF: initialValues.isGGUF,
|
||||
show: true
|
||||
@@ -472,18 +433,15 @@ const ModelFiles = () => {
|
||||
return <div></div>;
|
||||
};
|
||||
|
||||
const handleClickDropdown = useCallback(
|
||||
(item: any) => {
|
||||
const config = modalConfig[item.key];
|
||||
const hasLinuxWorker = workersList.some(
|
||||
(worker) => _.toLower(worker.labels?.os) === 'linux'
|
||||
);
|
||||
if (config) {
|
||||
setDownlaodMoalStatus({ ...config, hasLinuxWorker, gpuOptions: [] });
|
||||
}
|
||||
},
|
||||
[workersList]
|
||||
);
|
||||
const handleClickDropdown = (item: any) => {
|
||||
const config = modalConfig[item.key];
|
||||
const hasLinuxWorker = workersList.some(
|
||||
(worker) => _.toLower(worker.labels?.os) === 'linux'
|
||||
);
|
||||
if (config) {
|
||||
setDownlaodMoalStatus({ ...config, hasLinuxWorker });
|
||||
}
|
||||
};
|
||||
|
||||
const handleDownloadCancel = () => {
|
||||
setDownlaodMoalStatus({
|
||||
@@ -709,6 +667,7 @@ const ModelFiles = () => {
|
||||
width={downloadModalStatus.width}
|
||||
hasLinuxWorker={downloadModalStatus.hasLinuxWorker}
|
||||
workersList={readyWorkers}
|
||||
workerOptions={workerOptions}
|
||||
></DownloadModal>
|
||||
<DeployModal
|
||||
deploymentType="modelFiles"
|
||||
@@ -719,10 +678,9 @@ const ModelFiles = () => {
|
||||
action={PageAction.CREATE}
|
||||
source={openDeployModal.source}
|
||||
width={openDeployModal.width}
|
||||
gpuOptions={openDeployModal.gpuOptions}
|
||||
modelFileOptions={openDeployModal.modelFileOptions || []}
|
||||
initialValues={openDeployModal.initialValues}
|
||||
isGGUF={openDeployModal.isGGUF}
|
||||
clusterList={clusterList}
|
||||
></DeployModal>
|
||||
</PageContainer>
|
||||
</>
|
||||
|
||||
@@ -7,6 +7,7 @@ import ProgressBar from '@/components/progress-bar';
|
||||
import InfoColumn from '@/components/simple-table/info-column';
|
||||
import StatusTag from '@/components/status-tag';
|
||||
import useTableFetch from '@/hooks/use-table-fetch';
|
||||
import { queryClusterList } from '@/pages/cluster-management/apis';
|
||||
import { convertFileSize } from '@/utils';
|
||||
import {
|
||||
CodeOutlined,
|
||||
@@ -18,7 +19,7 @@ import { PageContainer } from '@ant-design/pro-components';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { ConfigProvider, Empty, Table, Tooltip, message } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
WORKERS_API,
|
||||
deleteWorker,
|
||||
@@ -27,7 +28,6 @@ import {
|
||||
} from '../apis';
|
||||
import { WorkerStatusMapValue, status } from '../config';
|
||||
import { Filesystem, GPUDeviceItem, ListItem } from '../config/types';
|
||||
import AddWorker from './add-worker';
|
||||
import UpdateLabels from './update-labels';
|
||||
|
||||
const { Column } = Table;
|
||||
@@ -115,6 +115,7 @@ const Workers: React.FC = () => {
|
||||
handlePageChange,
|
||||
handleTableChange,
|
||||
handleSearch,
|
||||
handleQueryChange,
|
||||
handleNameChange
|
||||
} = useTableFetch<ListItem>({
|
||||
fetchAPI: queryWorkersList,
|
||||
@@ -125,7 +126,6 @@ const Workers: React.FC = () => {
|
||||
});
|
||||
|
||||
const intl = useIntl();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [updateLabelsData, setUpdateLabelsData] = useState<{
|
||||
open: boolean;
|
||||
data: ListItem;
|
||||
@@ -133,35 +133,65 @@ const Workers: React.FC = () => {
|
||||
open: false,
|
||||
data: {} as ListItem
|
||||
});
|
||||
const [clusterData, setClusterData] = useState<{
|
||||
list: Global.BaseOption<number>[];
|
||||
data: Record<number, string>;
|
||||
}>({
|
||||
list: [],
|
||||
data: {}
|
||||
});
|
||||
|
||||
const handleAddWorker = () => {
|
||||
setOpen(true);
|
||||
const getClusterList = async () => {
|
||||
try {
|
||||
const params = {
|
||||
page: 1,
|
||||
perPage: 100
|
||||
};
|
||||
const res = await queryClusterList(params);
|
||||
const clusterMap = res?.items?.reduce(
|
||||
(acc: Record<number, string>, item: any) => {
|
||||
acc[item.id] = item.name;
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
const list = res?.items?.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}));
|
||||
setClusterData({
|
||||
list,
|
||||
data: clusterMap
|
||||
});
|
||||
} catch (error) {
|
||||
setClusterData({
|
||||
list: [],
|
||||
data: {}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleUpdateLabelsOk = useCallback(
|
||||
async (values: Record<string, any>) => {
|
||||
try {
|
||||
console.log('updateLabelsData.data', updateLabelsData.data);
|
||||
await updateWorker(updateLabelsData.data.id, {
|
||||
...updateLabelsData.data,
|
||||
labels: values.labels
|
||||
});
|
||||
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||
fetchData();
|
||||
setUpdateLabelsData({ open: false, data: {} as ListItem });
|
||||
} catch (error) {
|
||||
console.log('error', error);
|
||||
}
|
||||
},
|
||||
[updateLabelsData, fetchData]
|
||||
);
|
||||
const handleUpdateLabelsOk = async (values: Record<string, any>) => {
|
||||
try {
|
||||
console.log('updateLabelsData.data', updateLabelsData.data);
|
||||
await updateWorker(updateLabelsData.data.id, {
|
||||
...updateLabelsData.data,
|
||||
labels: values.labels
|
||||
});
|
||||
message.success(intl.formatMessage({ id: 'common.message.success' }));
|
||||
fetchData();
|
||||
setUpdateLabelsData({ open: false, data: {} as ListItem });
|
||||
} catch (error) {
|
||||
console.log('error', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancelUpdateLabels = useCallback(() => {
|
||||
const handleCancelUpdateLabels = () => {
|
||||
setUpdateLabelsData({
|
||||
...updateLabelsData,
|
||||
open: false
|
||||
});
|
||||
}, []);
|
||||
};
|
||||
|
||||
const handleUpdateLabels = (record: ListItem) => {
|
||||
console.log('record', record);
|
||||
@@ -210,6 +240,17 @@ const Workers: React.FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const handleClusterChange = (value: number) => {
|
||||
handleQueryChange({
|
||||
page: 1,
|
||||
cluster_id: value
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getClusterList();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageContainer
|
||||
@@ -232,9 +273,10 @@ const Workers: React.FC = () => {
|
||||
buttonText={intl.formatMessage({ id: 'resources.button.create' })}
|
||||
handleDeleteByBatch={handleDeleteBatch}
|
||||
handleSearch={handleSearch}
|
||||
handleClickPrimary={handleAddWorker}
|
||||
handleSelectChange={handleClusterChange}
|
||||
handleInputChange={handleNameChange}
|
||||
rowSelection={rowSelection}
|
||||
selectOptions={clusterData.list}
|
||||
width={{ input: 200 }}
|
||||
></FilterBar>
|
||||
<ConfigProvider renderEmpty={renderEmpty}>
|
||||
@@ -309,7 +351,7 @@ const Workers: React.FC = () => {
|
||||
render={(text, record: ListItem) => {
|
||||
return (
|
||||
<AutoTooltip ghost maxWidth={240}>
|
||||
<span>digital-ocean-cluster</span>
|
||||
<span>{clusterData.data[record.cluster_id]}</span>
|
||||
</AutoTooltip>
|
||||
);
|
||||
}}
|
||||
@@ -496,7 +538,6 @@ const Workers: React.FC = () => {
|
||||
</Table>
|
||||
</ConfigProvider>
|
||||
<DeleteModal ref={modalRef}></DeleteModal>
|
||||
<AddWorker open={open} onCancel={() => setOpen(false)}></AddWorker>
|
||||
<UpdateLabels
|
||||
open={updateLabelsData.open}
|
||||
onOk={handleUpdateLabelsOk}
|
||||
|
||||
Reference in New Issue
Block a user