fix: default benchmark form values
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
import { atom } from 'jotai';
|
||||||
|
|
||||||
|
export const benchmarkTargetInstanceAtom = atom<{
|
||||||
|
cluster_id: number | null;
|
||||||
|
model_name: string;
|
||||||
|
model_id: number | null;
|
||||||
|
model_instance_name: string;
|
||||||
|
model_instance: string[];
|
||||||
|
}>({
|
||||||
|
cluster_id: null,
|
||||||
|
model_name: '',
|
||||||
|
model_id: null,
|
||||||
|
model_instance_name: '',
|
||||||
|
model_instance: []
|
||||||
|
});
|
||||||
@@ -275,5 +275,6 @@ export default {
|
|||||||
'models.form.readyWorkers': 'workers ready',
|
'models.form.readyWorkers': 'workers ready',
|
||||||
'models.form.maxContextLength': 'Maximum Context Length',
|
'models.form.maxContextLength': 'Maximum Context Length',
|
||||||
'models.form.backend.helperText':
|
'models.form.backend.helperText':
|
||||||
'Not enabled yet. Will be enabled after deployment. '
|
'Not enabled yet. Will be enabled after deployment. ',
|
||||||
|
'models.table.instance.benchmark': 'Run Benchmark'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -275,7 +275,8 @@ export default {
|
|||||||
'models.form.readyWorkers': 'workers ready',
|
'models.form.readyWorkers': 'workers ready',
|
||||||
'models.form.maxContextLength': 'Maximum Context Length',
|
'models.form.maxContextLength': 'Maximum Context Length',
|
||||||
'models.form.backend.helperText':
|
'models.form.backend.helperText':
|
||||||
'Not enabled yet. Will be enabled after deployment. '
|
'Not enabled yet. Will be enabled after deployment. ',
|
||||||
|
'models.table.instance.benchmark': 'Run Benchmark'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -373,4 +374,5 @@ export default {
|
|||||||
// 75. 'models.form.readyWorkers': 'workers ready',
|
// 75. 'models.form.readyWorkers': 'workers ready',
|
||||||
// 76. 'models.form.maxContextLength': 'Maximum Context Length',
|
// 76. 'models.form.maxContextLength': 'Maximum Context Length',
|
||||||
// 77. 'models.form.backend.helperText': 'Not enabled yet. Will be enabled after deployment. ',
|
// 77. 'models.form.backend.helperText': 'Not enabled yet. Will be enabled after deployment. ',
|
||||||
|
// 78. 'models.table.instance.benchmark': 'Run Benchmark'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -279,10 +279,12 @@ export default {
|
|||||||
'models.form.readyWorkers': 'воркеров готово',
|
'models.form.readyWorkers': 'воркеров готово',
|
||||||
'models.form.maxContextLength': 'Maximum Context Length',
|
'models.form.maxContextLength': 'Maximum Context Length',
|
||||||
'models.form.backend.helperText':
|
'models.form.backend.helperText':
|
||||||
'Not enabled yet. Will be enabled after deployment. '
|
'Not enabled yet. Will be enabled after deployment. ',
|
||||||
|
'models.table.instance.benchmark': 'Run Benchmark'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
// 1. 'models.form.maxContextLength': 'Maximum Context Length',
|
// 1. 'models.form.maxContextLength': 'Maximum Context Length',
|
||||||
// 2. 'models.form.backend.helperText': 'Not enabled yet. Will be enabled after deployment. ',
|
// 2. 'models.form.backend.helperText': 'Not enabled yet. Will be enabled after deployment. ',
|
||||||
|
// 3. 'models.table.instance.benchmark': 'Run Benchmark'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ export default {
|
|||||||
'models.form.gpusAllocationType.custom.tips':
|
'models.form.gpusAllocationType.custom.tips':
|
||||||
'您可以指定每个副本的 GPU 数量。',
|
'您可以指定每个副本的 GPU 数量。',
|
||||||
'models.mymodels.status.inactive': '已停止',
|
'models.mymodels.status.inactive': '已停止',
|
||||||
'models.mymodels.status.degrade': '异常',
|
'models.mymodels.status.degrade': '未就绪',
|
||||||
'models.mymodels.status.active': '可用',
|
'models.mymodels.status.active': '可用',
|
||||||
'models.form.kvCache.tips':
|
'models.form.kvCache.tips':
|
||||||
'扩展 KV 缓存和推测解码仅在内置后端(vLLM / SGLang)可用,请切换后端以启用。',
|
'扩展 KV 缓存和推测解码仅在内置后端(vLLM / SGLang)可用,请切换后端以启用。',
|
||||||
@@ -258,5 +258,6 @@ export default {
|
|||||||
'你指定的模型文件路径在 GPUStack 服务器上不存在。建议在 GPUStack 服务器和 GPUStack 节点上使用相同的模型文件路径,这有助于 GPUStack 做出更优的调度与决策。',
|
'你指定的模型文件路径在 GPUStack 服务器上不存在。建议在 GPUStack 服务器和 GPUStack 节点上使用相同的模型文件路径,这有助于 GPUStack 做出更优的调度与决策。',
|
||||||
'models.form.readyWorkers': '节点就绪',
|
'models.form.readyWorkers': '节点就绪',
|
||||||
'models.form.maxContextLength': '最大上下文长度',
|
'models.form.maxContextLength': '最大上下文长度',
|
||||||
'models.form.backend.helperText': '该社区后端暂未启用,部署后将自动启用'
|
'models.form.backend.helperText': '该社区后端暂未启用,部署后将自动启用',
|
||||||
|
'models.table.instance.benchmark': '运行基准测试'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import SealSelect from '@/components/seal-form/seal-select';
|
|||||||
import { PageAction } from '@/config';
|
import { PageAction } from '@/config';
|
||||||
import useAppUtils from '@/hooks/use-app-utils';
|
import useAppUtils from '@/hooks/use-app-utils';
|
||||||
import { ClusterStatusValueMap } from '@/pages/cluster-management/config';
|
import { ClusterStatusValueMap } from '@/pages/cluster-management/config';
|
||||||
|
import { useBenchmarkTargetInstance } from '@/pages/llmodels/hooks/use-run-benchmark';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Form } from 'antd';
|
import { Form } from 'antd';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
@@ -15,6 +16,7 @@ const BasicForm: React.FC = () => {
|
|||||||
const form = Form.useFormInstance();
|
const form = Form.useFormInstance();
|
||||||
const { getRuleMessage } = useAppUtils();
|
const { getRuleMessage } = useAppUtils();
|
||||||
const { action, open, clusterList } = useFormContext();
|
const { action, open, clusterList } = useFormContext();
|
||||||
|
const { benchmarkTargetInstance } = useBenchmarkTargetInstance();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initClusterId = (list: any[]) => {
|
const initClusterId = (list: any[]) => {
|
||||||
@@ -35,9 +37,12 @@ const BasicForm: React.FC = () => {
|
|||||||
clusterList?.length > 0 &&
|
clusterList?.length > 0 &&
|
||||||
action === PageAction.CREATE
|
action === PageAction.CREATE
|
||||||
) {
|
) {
|
||||||
form.setFieldValue('cluster_id', initClusterId(clusterList));
|
form.setFieldValue(
|
||||||
|
'cluster_id',
|
||||||
|
benchmarkTargetInstance.cluster_id || initClusterId(clusterList)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, [form, action, clusterList]);
|
}, [form, action, clusterList, benchmarkTargetInstance]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -43,14 +43,46 @@ const DatasetForm: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Initialize profile when open form
|
||||||
|
const initProfile = (
|
||||||
|
value: string,
|
||||||
|
option: any,
|
||||||
|
datasetList: Global.BaseOption<number | string>[]
|
||||||
|
) => {
|
||||||
|
if (value !== ProfileValueMap.Custom) {
|
||||||
|
const dataset_id = datasetList.find(
|
||||||
|
(item) => item.label === option.config?.dataset_name
|
||||||
|
)?.value;
|
||||||
|
|
||||||
|
form.setFieldsValue({
|
||||||
|
profile: value,
|
||||||
|
dataset_id: dataset_id,
|
||||||
|
..._.omit(option?.config, ['description', 'dataset_source'])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
if (!open) {
|
||||||
cancelDatasetRequest();
|
cancelDatasetRequest();
|
||||||
cancelProfilesRequest();
|
cancelProfilesRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
fetchProfilesData();
|
const init = async () => {
|
||||||
fetchDatasetData();
|
const profiles = await fetchProfilesData();
|
||||||
|
const datasets = await fetchDatasetData();
|
||||||
|
// set default profile
|
||||||
|
if (profiles?.length > 0) {
|
||||||
|
const throughputProfile = profiles.find(
|
||||||
|
(item) => item.value === ProfileValueMap.ThroughputMedium
|
||||||
|
);
|
||||||
|
if (throughputProfile) {
|
||||||
|
initProfile(throughputProfile.value, throughputProfile, datasets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
init();
|
||||||
}
|
}
|
||||||
}, [open]);
|
}, [open]);
|
||||||
|
|
||||||
@@ -73,7 +105,12 @@ const DatasetForm: React.FC = () => {
|
|||||||
required
|
required
|
||||||
>
|
>
|
||||||
{profilesOptions?.map((item: any) => (
|
{profilesOptions?.map((item: any) => (
|
||||||
<Select.Option key={item.value} value={item.value}>
|
<Select.Option
|
||||||
|
key={item.value}
|
||||||
|
value={item.value}
|
||||||
|
label={item.label}
|
||||||
|
config={item.config}
|
||||||
|
>
|
||||||
<AutoTooltip
|
<AutoTooltip
|
||||||
ghost
|
ghost
|
||||||
showTitle={!!item.tips}
|
showTitle={!!item.tips}
|
||||||
|
|||||||
@@ -37,12 +37,9 @@ const ProviderForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
|||||||
const { action, currentData, onFinish, open, clusterList } = props;
|
const { action, currentData, onFinish, open, clusterList } = props;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const profile = Form.useWatch('profile', form);
|
|
||||||
|
|
||||||
const { getScrollElementScrollableHeight } = useWrapperContext();
|
const { getScrollElementScrollableHeight } = useWrapperContext();
|
||||||
const [activeKey, setActiveKey] = useState<string[]>([TABKeysMap.PROFILE]);
|
const [activeKey, setActiveKey] = useState<string[]>([TABKeysMap.PROFILE]);
|
||||||
const scrollTabsRef = useRef<any>(null);
|
const scrollTabsRef = useRef<any>(null);
|
||||||
const showAdvanced = profile !== 'Custom' && Boolean(profile);
|
|
||||||
|
|
||||||
const segmentOptions = [
|
const segmentOptions = [
|
||||||
{
|
{
|
||||||
@@ -88,12 +85,6 @@ const ProviderForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
|||||||
}
|
}
|
||||||
}, [form, currentData, action]);
|
}, [form, currentData, action]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!showAdvanced && activeKey?.includes(TABKeysMap.ADVANCED)) {
|
|
||||||
setActiveKey([TABKeysMap.PROFILE]);
|
|
||||||
}
|
|
||||||
}, [showAdvanced, activeKey]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollSpyTabs
|
<ScrollSpyTabs
|
||||||
ref={scrollTabsRef}
|
ref={scrollTabsRef}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
InstanceStatusMap,
|
InstanceStatusMap,
|
||||||
InstanceStatusMapValue
|
InstanceStatusMapValue
|
||||||
} from '@/pages/llmodels/config';
|
} from '@/pages/llmodels/config';
|
||||||
|
import { useBenchmarkTargetInstance } from '@/pages/llmodels/hooks/use-run-benchmark';
|
||||||
import { useQueryModelInstancesList } from '@/pages/llmodels/services/use-query-model-instances';
|
import { useQueryModelInstancesList } from '@/pages/llmodels/services/use-query-model-instances';
|
||||||
import { useQueryModelList } from '@/pages/llmodels/services/use-query-model-list';
|
import { useQueryModelList } from '@/pages/llmodels/services/use-query-model-list';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
@@ -43,12 +44,15 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
fetchInstanceList,
|
fetchInstanceList,
|
||||||
cancelRequest: cancelInstanceRequest
|
cancelRequest: cancelInstanceRequest
|
||||||
} = useQueryModelInstancesList();
|
} = useQueryModelInstancesList();
|
||||||
|
const { benchmarkTargetInstance, clearBenchmarkTargetInstance } =
|
||||||
|
useBenchmarkTargetInstance();
|
||||||
|
|
||||||
const handleOnChange = async (value: any, selectedOptions: any) => {
|
const handleOnChange = async (value: any, selectedOptions: any) => {
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
model_name: value[0],
|
model_name: value[0],
|
||||||
model_id: selectedOptions[0]?.id,
|
model_id: selectedOptions[0]?.id,
|
||||||
model_instance_name: value[1]
|
model_instance_name: value[1],
|
||||||
|
model_instance: value
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,43 +91,60 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnOpenChange = async (open: boolean) => {
|
const initModelInstance = async () => {
|
||||||
// fetch model list when dropdown is opened
|
// fetch model list when dropdown is opened
|
||||||
if (open && modelList.length === 0) {
|
const list = await fetchModelList({ page: -1 });
|
||||||
const list = await fetchModelList({ page: -1 });
|
const modelOptions = list
|
||||||
const modelOptions = list
|
.filter((model: any) => model.replicas > 0)
|
||||||
.filter((model: any) => model.replicas > 0)
|
.map((model: any) => ({
|
||||||
.map((model: any) => ({
|
label: model.name,
|
||||||
label: model.name,
|
value: model.name,
|
||||||
value: model.name,
|
id: model.id,
|
||||||
id: model.id,
|
isLeaf: false,
|
||||||
isLeaf: false,
|
children: []
|
||||||
children: []
|
}));
|
||||||
}));
|
|
||||||
|
|
||||||
if (modelOptions.length === 0) {
|
if (modelOptions.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// preload instances for the first model
|
|
||||||
const instanceList = await fetchInstanceList({ id: modelOptions[0]?.id });
|
|
||||||
const instanceOptions = instanceList.map((instance: any) =>
|
|
||||||
renderInstance(instance)
|
|
||||||
);
|
|
||||||
if (modelOptions[0]) {
|
|
||||||
modelOptions[0].children = [...instanceOptions] as never[];
|
|
||||||
}
|
|
||||||
|
|
||||||
setModelList(modelOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// preload instances for the first model
|
||||||
|
const instanceList = await fetchInstanceList({ id: modelOptions[0]?.id });
|
||||||
|
const instanceOptions = instanceList.map((instance: any) =>
|
||||||
|
renderInstance(instance)
|
||||||
|
);
|
||||||
|
if (modelOptions[0]) {
|
||||||
|
modelOptions[0].children = [...instanceOptions] as never[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// init form value for model instance
|
||||||
|
if (
|
||||||
|
benchmarkTargetInstance.model_name &&
|
||||||
|
benchmarkTargetInstance.model_instance_name
|
||||||
|
) {
|
||||||
|
form.setFieldsValue({
|
||||||
|
...benchmarkTargetInstance
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
handleOnChange(
|
||||||
|
[modelOptions[0].value, instanceOptions[0]?.value],
|
||||||
|
[modelOptions[0], instanceOptions[0]]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
setModelList(modelOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (open) {
|
||||||
|
initModelInstance();
|
||||||
|
}
|
||||||
if (!open) {
|
if (!open) {
|
||||||
cancelModelRequest();
|
cancelModelRequest();
|
||||||
cancelInstanceRequest();
|
cancelInstanceRequest();
|
||||||
|
clearBenchmarkTargetInstance();
|
||||||
}
|
}
|
||||||
}, [open]);
|
}, [open, benchmarkTargetInstance]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
@@ -154,7 +175,6 @@ const ModelInstanceForm: React.FC = () => {
|
|||||||
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
||||||
optionNode={InstanceNode}
|
optionNode={InstanceNode}
|
||||||
loadData={loadInstances}
|
loadData={loadInstances}
|
||||||
onOpenChange={handleOnOpenChange}
|
|
||||||
onChange={handleOnChange}
|
onChange={handleOnChange}
|
||||||
></SealCascader>
|
></SealCascader>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { FilterBar } from '@/components/page-tools';
|
|||||||
import { PageAction } from '@/config';
|
import { PageAction } from '@/config';
|
||||||
import { TABLE_SORT_DIRECTIONS } from '@/config/settings';
|
import { TABLE_SORT_DIRECTIONS } from '@/config/settings';
|
||||||
import useTableFetch from '@/hooks/use-table-fetch';
|
import useTableFetch from '@/hooks/use-table-fetch';
|
||||||
|
import { useBenchmarkTargetInstance } from '@/pages/llmodels/hooks/use-run-benchmark';
|
||||||
import { useQueryModelList } from '@/pages/llmodels/services/use-query-model-list';
|
import { useQueryModelList } from '@/pages/llmodels/services/use-query-model-list';
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
import { useMemoizedFn } from 'ahooks';
|
import { useMemoizedFn } from 'ahooks';
|
||||||
@@ -76,11 +77,19 @@ const Benchmark: React.FC = () => {
|
|||||||
contentHeight: 320,
|
contentHeight: 320,
|
||||||
clusterList
|
clusterList
|
||||||
});
|
});
|
||||||
|
const { benchmarkTargetInstance } = useBenchmarkTargetInstance();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchModelList({ page: -1 });
|
fetchModelList({ page: -1 });
|
||||||
fetchClusterList({ page: -1 });
|
|
||||||
fetchDatasetData();
|
fetchDatasetData();
|
||||||
|
fetchClusterList({ page: -1 }).then(() => {
|
||||||
|
if (benchmarkTargetInstance.model_name) {
|
||||||
|
openBenchmarkModal(
|
||||||
|
PageAction.CREATE,
|
||||||
|
intl.formatMessage({ id: 'benchmark.button.add' })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
return () => {
|
return () => {
|
||||||
cancelClusterRequest();
|
cancelClusterRequest();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const useQueryDataset = () => {
|
|||||||
// TODO: may be fetch data from server in the future.
|
// TODO: may be fetch data from server in the future.
|
||||||
|
|
||||||
setDatasetList([...datasetOptions]);
|
setDatasetList([...datasetOptions]);
|
||||||
|
return datasetOptions;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default function useQueryProfiles() {
|
|||||||
};
|
};
|
||||||
}) || [];
|
}) || [];
|
||||||
|
|
||||||
setProfilesOptions([
|
const options = [
|
||||||
...list,
|
...list,
|
||||||
{
|
{
|
||||||
label: intl.formatMessage({ id: 'backend.custom' }),
|
label: intl.formatMessage({ id: 'backend.custom' }),
|
||||||
@@ -55,7 +55,9 @@ export default function useQueryProfiles() {
|
|||||||
total_requests: null
|
total_requests: null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
];
|
||||||
|
setProfilesOptions(options);
|
||||||
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import StatusTag from '@/components/status-tag';
|
|||||||
import ThemeTag from '@/components/tags-wrapper/theme-tag';
|
import ThemeTag from '@/components/tags-wrapper/theme-tag';
|
||||||
import { HandlerOptions } from '@/hooks/use-chunk-fetch';
|
import { HandlerOptions } from '@/hooks/use-chunk-fetch';
|
||||||
import useDownloadStream from '@/hooks/use-download-stream';
|
import useDownloadStream from '@/hooks/use-download-stream';
|
||||||
|
import { useBenchmarkTargetInstance } from '@/pages/llmodels/hooks/use-run-benchmark';
|
||||||
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
|
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
|
||||||
import { convertFileSize } from '@/utils';
|
import { convertFileSize } from '@/utils';
|
||||||
import {
|
import {
|
||||||
@@ -333,6 +334,12 @@ const childActionList = [
|
|||||||
],
|
],
|
||||||
icon: <DownloadOutlined />
|
icon: <DownloadOutlined />
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'models.table.instance.benchmark',
|
||||||
|
key: 'benchmark',
|
||||||
|
status: [InstanceStatusMap.Running],
|
||||||
|
icon: <IconFont type="icon-speed" />
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'common.button.delrecreate',
|
label: 'common.button.delrecreate',
|
||||||
key: 'delete',
|
key: 'delete',
|
||||||
@@ -416,6 +423,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
defaultOpenId,
|
defaultOpenId,
|
||||||
handleChildSelect
|
handleChildSelect
|
||||||
}) => {
|
}) => {
|
||||||
|
const { runBenchmarkOnInstance } = useBenchmarkTargetInstance();
|
||||||
const [api, contextHolder] = notification.useNotification({
|
const [api, contextHolder] = notification.useNotification({
|
||||||
stack: { threshold: 1 }
|
stack: { threshold: 1 }
|
||||||
});
|
});
|
||||||
@@ -423,7 +431,7 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const actionItems = useMemo(() => {
|
const actionItems = useMemo(() => {
|
||||||
return _.filter(childActionList, (action: any) => {
|
return _.filter(childActionList, (action: any) => {
|
||||||
if (action.key === 'viewlog' || action.key === 'download') {
|
if (action.status && action.status.length > 0) {
|
||||||
return action.status.includes(instanceData.state);
|
return action.status.includes(instanceData.state);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -662,7 +670,9 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const handleOnSelect = (val: string) => {
|
const handleOnSelect = (val: string) => {
|
||||||
if (val === 'download') {
|
if (val === 'benchmark') {
|
||||||
|
runBenchmarkOnInstance(instanceData);
|
||||||
|
} else if (val === 'download') {
|
||||||
downloadStream({
|
downloadStream({
|
||||||
url: `${MODEL_INSTANCE_API}/${instanceData.id}/logs`,
|
url: `${MODEL_INSTANCE_API}/${instanceData.id}/logs`,
|
||||||
filename: createFileName(instanceData.name),
|
filename: createFileName(instanceData.name),
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ export interface DistributedServers {
|
|||||||
}
|
}
|
||||||
export interface ModelInstanceListItem {
|
export interface ModelInstanceListItem {
|
||||||
backend?: string;
|
backend?: string;
|
||||||
|
cluster_id: number;
|
||||||
backend_version?: string;
|
backend_version?: string;
|
||||||
source: string;
|
source: string;
|
||||||
huggingface_repo_id: string;
|
huggingface_repo_id: string;
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { benchmarkTargetInstanceAtom } from '@/atoms/benchmark';
|
||||||
|
import { useNavigate } from '@umijs/max';
|
||||||
|
import { useAtom } from 'jotai';
|
||||||
|
import { ModelInstanceListItem } from '../config/types';
|
||||||
|
|
||||||
|
export const useBenchmarkTargetInstance = () => {
|
||||||
|
const [benchmarkTargetInstance, setBenchmarkTargetInstance] = useAtom(
|
||||||
|
benchmarkTargetInstanceAtom
|
||||||
|
);
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const runBenchmarkOnInstance = (instance: ModelInstanceListItem) => {
|
||||||
|
setBenchmarkTargetInstance({
|
||||||
|
cluster_id: instance.cluster_id,
|
||||||
|
model_name: instance.model_name,
|
||||||
|
model_id: instance.model_id,
|
||||||
|
model_instance_name: instance.name,
|
||||||
|
model_instance: [instance.model_name, instance.name]
|
||||||
|
});
|
||||||
|
navigate('/models/benchmark');
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearBenchmarkTargetInstance = () => {
|
||||||
|
setBenchmarkTargetInstance({
|
||||||
|
cluster_id: null,
|
||||||
|
model_name: '',
|
||||||
|
model_id: null,
|
||||||
|
model_instance_name: '',
|
||||||
|
model_instance: []
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
benchmarkTargetInstance,
|
||||||
|
clearBenchmarkTargetInstance,
|
||||||
|
runBenchmarkOnInstance
|
||||||
|
};
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user