chore: deploy form context provider

This commit is contained in:
jialin
2025-10-13 14:40:26 +08:00
parent 42217cf079
commit a9de153c00
17 changed files with 237 additions and 224 deletions
+48 -12
View File
@@ -400,16 +400,52 @@ export async function evaluationsModelSpec(
}
export async function queryBackendList() {
return request<{
items: {
backend_name: string;
backend_show_name: string;
from_config: boolean;
default_version: string;
default_backend_param: string[];
versions: string[];
}[];
}>(BACKEND_LIST_API, {
method: 'GET'
});
// return request<{
// items: {
// backend_name: string;
// backend_show_name: string;
// from_config: boolean;
// default_version: string;
// default_backend_param: string[];
// versions: string[];
// }[];
// }>(BACKEND_LIST_API, {
// method: 'GET'
// });
return {
items: [
{
backend_name: 'vllm',
backend_show_name: 'vLLM',
from_config: false,
default_version: '0.10.1.1',
default_backend_param: null,
versions: ['0.10.1.1', '0.10.0', '0.9.2', '0.8.5', '0.8.3']
},
{
backend_name: 'ascend-mindie',
backend_show_name: 'Ascend MindIE',
from_config: false,
default_version: null,
default_backend_param: null,
versions: null
},
{
backend_name: 'custom',
backend_show_name: 'Custom',
from_config: false,
default_version: null,
default_backend_param: null,
versions: null
},
{
backend_name: 'test',
backend_show_name: null,
from_config: true,
default_version: 'v1',
default_backend_param: ['--host=0.0.0.0'],
versions: ['v1']
}
]
};
}
@@ -57,7 +57,7 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
const placement_strategy = Form.useWatch('placement_strategy', form);
const gpuSelectorIds = Form.useWatch(['gpu_selector', 'gpu_ids'], form);
const worker_selector = Form.useWatch('worker_selector', form);
const { onValuesChange, onBackendChange, backendOptions } = useFormContext();
const { onValuesChange } = useFormContext();
const paramsConfig = useMemo(() => {
return _.get(BackendParameters, backend, []);
@@ -119,23 +119,6 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
onValuesChange?.({}, form.getFieldsValue());
};
const handleBackendVersionOnBlur = () => {
onValuesChange?.({}, form.getFieldsValue());
};
const handleScheduleTypeChange = (value: string) => {
if (value === ScheduleValueMap.Auto) {
onValuesChange?.({}, form.getFieldsValue());
}
};
const handleBeforeGpuSelectorChange = (gpuIds: any[]) => {};
const handleGpuSelectorChange = (value: any[]) => {
handleBeforeGpuSelectorChange(value);
onValuesChange?.({}, form.getFieldsValue());
};
const collapseItems = useMemo(() => {
const children = (
<>
+14 -45
View File
@@ -15,6 +15,7 @@ import {
FormData,
SourceType
} from '../config/types';
import { generateGPUIds } from '../config/utils';
import CatalogFrom from '../forms/catalog';
import HuggingFaceForm from '../forms/hugging-face';
import LocalPathForm from '../forms/local-path';
@@ -64,61 +65,29 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
};
// voxbox is not support multi gpu
const handleSetGPUIds = (backend: string) => {
const updateGPUSelector = (backend: string) => {
const gpuids = form.getFieldValue(['gpu_selector', 'gpu_ids']) || [];
if (backend === backendOptionsMap.voxBox && gpuids.length > 0) {
form.setFieldValue(['gpu_selector', 'gpu_ids'], [gpuids[0]]);
}
};
const handleBackendChange = async (val: string) => {
const updates = {
backend_version: ''
};
if (val === backendOptionsMap.llamaBox) {
Object.assign(updates, {
distributed_inference_across_workers: true,
cpu_offloading: true
});
}
form.setFieldsValue({
backend_version: '',
backend_parameters: [],
env: null
});
handleSetGPUIds(val);
props.onBackendChange?.(val);
};
const generateGPUIds = (data: FormData) => {
const gpu_ids = _.get(data, 'gpu_selector.gpu_ids', []);
if (!gpu_ids.length) {
return {
gpu_selector: null
gpu_selector: { gpu_ids: [gpuids[0]] }
};
}
const result = _.reduce(
gpu_ids,
(acc: string[], item: string | string[], index: number) => {
if (Array.isArray(item)) {
acc.push(item[1]);
} else if (index === 1) {
acc.push(item);
}
return acc;
},
[]
);
return {
gpu_selector: {
gpu_ids: result
}
gpu_selector: { gpu_ids: gpuids }
};
};
const handleBackendChange = async (val: string, option: BackendOption) => {
form.setFieldsValue({
env: null,
backend_version: option.default_version || '',
backend_parameters: option.default_backend_param || [],
...updateGPUSelector(val)
});
props.onBackendChange?.(val);
};
// generate the data is available for the backend including the gpu_ids
const handleOk = async (formdata: FormData) => {
let data = _.cloneDeep(formdata);
@@ -18,6 +18,7 @@ import {
import { backendOptionsMap } from '../config/backend-parameters';
import { CatalogFormContext } from '../config/form-context';
import { CatalogSpec, FormData, ListItem, SourceType } from '../config/types';
import { generateGPUIds } from '../config/utils';
import { useCheckCompatibility } from '../hooks';
import useFormInitialValues from '../hooks/use-form-initial-values';
import ColumnWrapper from './column-wrapper';
@@ -96,7 +97,6 @@ const AddModal: React.FC<AddModalProps> = (props) => {
const {
setWarningStatus,
handleDoEvalute,
generateGPUIds,
cancelEvaluate,
submitAnyway,
handleOnValuesChange,
@@ -13,10 +13,10 @@ import { BackendOption, FormData, SourceType } from '../config/types';
import {
MessageStatus,
WarningStausOptions,
checkOnlyAscendNPU,
useCheckCompatibility,
useSelectModel
} from '../hooks';
import useCheckBackend from '../hooks/use-check-backend';
import ColumnWrapper from './column-wrapper';
import CompatibilityAlert from './compatible-alert';
import DataForm from './data-form';
@@ -94,6 +94,7 @@ const AddModal: FC<AddModalProps> = (props) => {
modelSourceMap.modelscope_value
];
const { checkOnlyAscendNPU } = useCheckBackend();
const {
handleShowCompatibleAlert,
setWarningStatus,
@@ -312,11 +313,7 @@ const AddModal: FC<AddModalProps> = (props) => {
};
const handleBackendChange = async (backend: string) => {
if (backend === backendOptionsMap.llamaBox) {
setIsGGUF(true);
} else {
setIsGGUF(false);
}
setIsGGUF(false);
const data = form.current.form.getFieldsValue?.();
const res = handleBackendChangeBefore(data);
@@ -39,7 +39,7 @@ const HFModelItem: React.FC<HFModelItemProps> = (props) => {
: 'icon-modelscope_light'
}
className="m-r-5"
style={{ color: 'var(--ant-color-text-tertiary)' }}
style={{ color: 'var(--ant-color-text-tertiary)', fontSize: 16 }}
/>
{props.title}
</div>
@@ -44,7 +44,12 @@ const Performance: React.FC = () => {
onQuantizationChange?.(val);
};
const handleGpuSelectorChange = (value: any) => {};
const handleBeforeGpuSelectorChange = (gpuIds: any[]) => {};
const handleGpuSelectorChange = (value: any[]) => {
handleBeforeGpuSelectorChange(value);
onValuesChange?.({}, form.getFieldsValue());
};
return (
<>
@@ -12,12 +12,9 @@ import {
queryModelScopeModels
} from '../apis';
import { ModelScopeSortType, ModelSortType, modelSourceMap } from '../config';
import { handleRecognizeAudioModel } from '../config/audio-catalog';
import {
MessageStatus,
WarningStausOptions,
checkCurrentbackend
} from '../hooks';
import { MessageStatus, WarningStausOptions } from '../hooks';
import useCheckBackend from '../hooks/use-check-backend';
import useRecognizeAudio from '../hooks/use-recognize-audio';
import SearchStyle from '../style/search-result.less';
import SearchInput from './search-input';
import SearchResult from './search-result';
@@ -61,6 +58,8 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
displayEvaluateStatus
} = props;
const { recognizeAudioModel } = useRecognizeAudio();
const { checkCurrentbackend } = useCheckBackend();
const [dataSource, setDataSource] = useState<{
dataList: any[];
loading: boolean;
@@ -268,7 +267,7 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
const currentSearchId = getRequestId();
try {
const repoList = list.map((item) => {
const res = handleRecognizeAudioModel(item, modelSource);
const res = recognizeAudioModel(item, modelSource);
let backendObj = {};
const backend = checkCurrentbackend({
@@ -1,10 +1,3 @@
import {
HuggingFaceTaskMap,
ModelscopeTaskMap,
modelSourceMap,
modelTaskMap
} from './index';
export const HuggingFaceModels = [
{
type: 'stt',
@@ -195,60 +188,3 @@ export const ModelScopeModels = [
name: 'faster-whisper-large-v1'
}
];
const checkModelName = (
modelName: string,
item: { type: string; org: string; name: string }
) => {
let sourceName = `${item.org}/${item.name}`;
if (item.name === '*') {
sourceName = `${item.org}`;
}
return (
`${sourceName}`.indexOf(modelName) > -1 ||
modelName?.indexOf(`${sourceName}`) > -1
);
};
export const identifyModelTask = (source: string, modelName: string) => {
let data = null;
if (source === modelSourceMap.huggingface_value) {
data = HuggingFaceModels.find((item) => checkModelName(modelName, item));
}
if (source === modelSourceMap.modelscope_value) {
data = ModelScopeModels.find((item) => checkModelName(modelName, item));
}
if (data) {
return modelTaskMap.audio;
}
return '';
};
export const handleRecognizeAudioModel = (selectModel: any, source: string) => {
const modelTaskType = identifyModelTask(source, selectModel.name);
let isAudio = modelTaskType === modelTaskMap.audio;
// Check if the model is audio type, if not, check if the task is audio
if (!isAudio) {
const modelTask =
HuggingFaceTaskMap.audio.includes(selectModel.task) ||
ModelscopeTaskMap.audio.includes(selectModel.task)
? modelTaskMap.audio
: '';
isAudio = modelTask === modelTaskMap.audio;
}
const modelTaskData = {
value: selectModel.task,
type: isAudio ? modelTaskMap.audio : '',
isAudio: isAudio,
text2speech:
HuggingFaceTaskMap[modelTaskMap.textToSpeech] === selectModel.task ||
ModelscopeTaskMap[modelTaskMap.textToSpeech] === selectModel.task,
speech2text:
HuggingFaceTaskMap[modelTaskMap.speechToText] === selectModel.task ||
ModelscopeTaskMap[modelTaskMap.speechToText] === selectModel.task
};
return modelTaskData;
};
+1 -1
View File
@@ -10,7 +10,7 @@ interface FormContextProps {
gpuOptions?: any[];
backendOptions: BackendOption[];
onValuesChange?: (changedValues: any, allValues: any) => void;
onBackendChange: (backend: string) => void;
onBackendChange: (backend: string, option: any) => void;
}
interface CatalogFormContextProps {
+30
View File
@@ -1,5 +1,6 @@
import _ from 'lodash';
import { backendOptionsMap } from '../config/backend-parameters';
import { FormData } from './types';
export const generateGPUSelector = (data: any, gpuOptions: any[]) => {
const gpu_ids = _.get(data, 'gpu_selector.gpu_ids', []);
@@ -31,3 +32,32 @@ export const generateGPUSelector = (data: any, gpuOptions: any[]) => {
}
};
};
export const generateGPUIds = (data: FormData) => {
const gpu_ids = _.get(data, 'gpu_selector.gpu_ids', []);
console.log('generateGPUIds', gpu_ids);
if (!gpu_ids.length) {
return {
gpu_selector: null
};
}
const result = _.reduce(
gpu_ids,
(acc: string[], item: string | string[], index: number) => {
if (Array.isArray(item)) {
acc.push(item[1]);
} else if (index === 1) {
acc.push(item);
}
return acc;
},
[]
);
return {
gpu_selector: {
gpu_ids: result || []
}
};
};
+2 -1
View File
@@ -9,9 +9,10 @@ import { deployFormKeyMap, localPathTipsList, modelSourceMap } from '../config';
import { backendOptionsMap } from '../config/backend-parameters';
import { useFormContext } from '../config/form-context';
import { FormData } from '../config/types';
import { checkOnlyAscendNPU } from '../hooks';
import useCheckBackend from '../hooks/use-check-backend';
const LocalPathForm: React.FC = () => {
const { checkOnlyAscendNPU } = useCheckBackend();
const form = Form.useFormInstance();
const formCtx = useFormContext();
const source = Form.useWatch('source', form);
+8 -64
View File
@@ -9,9 +9,11 @@ import _ from 'lodash';
import { useEffect, useRef, useState } from 'react';
import { evaluationsModelSpec } from '../apis';
import { modelSourceMap, modelTaskMap } from '../config';
import { handleRecognizeAudioModel } from '../config/audio-catalog';
import { backendOptionsMap } from '../config/backend-parameters';
import { EvaluateResult, FormData } from '../config/types';
import { generateGPUIds } from '../config/utils';
import useCheckBackend from './use-check-backend';
import useRecognizeAudio from './use-recognize-audio';
export type MessageStatus = {
show: boolean;
@@ -102,38 +104,6 @@ export const useGenerateModelFileOptions = () => {
};
};
// handle for ascend npu only
export const checkOnlyAscendNPU = (gpuOptions: any[]) => {
if (!gpuOptions?.length) {
return false;
}
return gpuOptions?.every?.((item) => {
if (!item.children?.length) {
return false;
}
return item.children?.every((child: any) => {
return _.toLower(child.vendor) === 'huawei';
});
});
};
export const checkCurrentbackend = (data: {
isAudio: boolean;
isGGUF: boolean;
gpuOptions: any[];
defaultBackend?: string;
}) => {
const { isAudio, isGGUF, gpuOptions, defaultBackend } = data;
if (isAudio) {
return backendOptionsMap.voxBox;
}
if (checkOnlyAscendNPU(gpuOptions)) {
return backendOptionsMap.ascendMindie;
}
return defaultBackend;
};
export const useCheckCompatibility = () => {
const intl = useIntl();
const cacheFormValuesRef = useRef<any>({});
@@ -379,35 +349,6 @@ export const useCheckCompatibility = () => {
return warningMessage;
};
const generateGPUIds = (data: FormData) => {
const gpu_ids = _.get(data, 'gpu_selector.gpu_ids', []);
console.log('generateGPUIds', gpu_ids);
if (!gpu_ids.length) {
return {
gpu_selector: null
};
}
const result = _.reduce(
gpu_ids,
(acc: string[], item: string | string[], index: number) => {
if (Array.isArray(item)) {
acc.push(item[1]);
} else if (index === 1) {
acc.push(item);
}
return acc;
},
[]
);
return {
gpu_selector: {
gpu_ids: result || []
}
};
};
const handleDoEvalute = async (formData: FormData) => {
const currentRequestId = updateRequestId();
const evalutionData = await handleEvaluate(formData);
@@ -428,6 +369,7 @@ export const useCheckCompatibility = () => {
!allValues.local_path
);
};
const handleOnValuesChange = async (params: {
changedValues: any;
allValues: any;
@@ -487,7 +429,6 @@ export const useCheckCompatibility = () => {
handleShowCompatibleAlert,
handleUpdateWarning,
handleDoEvalute,
generateGPUIds,
handleEvaluate,
setWarningStatus: updateWarningStatus,
unlockWarningStatus,
@@ -503,6 +444,9 @@ export const useCheckCompatibility = () => {
};
export const useSelectModel = (data: { gpuOptions: any[] }) => {
const { checkCurrentbackend } = useCheckBackend();
const { recognizeAudioModel } = useRecognizeAudio();
// just for setting the model name or repo_id, and the backend, Since the model type is fixed.
const { gpuOptions } = data;
@@ -511,7 +455,7 @@ export const useSelectModel = (data: { gpuOptions: any[] }) => {
const reg = /(-gguf)$/i;
name = _.toLower(name).replace(reg, '');
const modelTaskData = handleRecognizeAudioModel(selectModel, source);
const modelTaskData = recognizeAudioModel(selectModel, source);
const backend = checkCurrentbackend({
defaultBackend: backendOptionsMap.vllm,
@@ -0,0 +1,41 @@
import _ from 'lodash';
import { backendOptionsMap } from '../config/backend-parameters';
export default function useCheckBackend() {
// handle for ascend npu only
const checkOnlyAscendNPU = (gpuOptions: any[]) => {
if (!gpuOptions?.length) {
return false;
}
return gpuOptions?.every?.((item) => {
if (!item.children?.length) {
return false;
}
return item.children?.every((child: any) => {
return _.toLower(child.vendor) === 'huawei';
});
});
};
const checkCurrentbackend = (data: {
isAudio: boolean;
isGGUF: boolean;
gpuOptions: any[];
defaultBackend?: string;
}) => {
const { isAudio, gpuOptions, defaultBackend } = data;
if (isAudio) {
return backendOptionsMap.voxBox;
}
if (checkOnlyAscendNPU(gpuOptions)) {
return backendOptionsMap.ascendMindie;
}
return defaultBackend;
};
return {
checkOnlyAscendNPU,
checkCurrentbackend
};
}
@@ -0,0 +1,71 @@
import {
HuggingFaceTaskMap,
ModelscopeTaskMap,
modelSourceMap,
modelTaskMap
} from '../config';
import { HuggingFaceModels, ModelScopeModels } from '../config/audio-catalog';
export default function useRecognizeAudio() {
const checkModelName = (
modelName: string,
item: { type: string; org: string; name: string }
) => {
let sourceName = `${item.org}/${item.name}`;
if (item.name === '*') {
sourceName = `${item.org}`;
}
return (
`${sourceName}`.indexOf(modelName) > -1 ||
modelName?.indexOf(`${sourceName}`) > -1
);
};
const identifyModelTask = (source: string, modelName: string) => {
let data = null;
if (source === modelSourceMap.huggingface_value) {
data = HuggingFaceModels.find((item) => checkModelName(modelName, item));
}
if (source === modelSourceMap.modelscope_value) {
data = ModelScopeModels.find((item) => checkModelName(modelName, item));
}
if (data) {
return modelTaskMap.audio;
}
return '';
};
const recognizeAudioModel = (selectModel: any, source: string) => {
const modelTaskType = identifyModelTask(source, selectModel.name);
let isAudio = modelTaskType === modelTaskMap.audio;
// Check if the model is audio type, if not, check if the task is audio
if (!isAudio) {
const modelTask =
HuggingFaceTaskMap.audio.includes(selectModel.task) ||
ModelscopeTaskMap.audio.includes(selectModel.task)
? modelTaskMap.audio
: '';
isAudio = modelTask === modelTaskMap.audio;
}
const modelTaskData = {
value: selectModel.task,
type: isAudio ? modelTaskMap.audio : '',
isAudio: isAudio,
text2speech:
HuggingFaceTaskMap[modelTaskMap.textToSpeech] === selectModel.task ||
ModelscopeTaskMap[modelTaskMap.textToSpeech] === selectModel.task,
speech2text:
HuggingFaceTaskMap[modelTaskMap.speechToText] === selectModel.task ||
ModelscopeTaskMap[modelTaskMap.speechToText] === selectModel.task
};
return modelTaskData;
};
return {
identifyModelTask,
recognizeAudioModel
};
}
@@ -1 +0,0 @@
export default function useSelectorChange() {}
@@ -8,7 +8,6 @@ import useTableFetch from '@/hooks/use-table-fetch';
import { createModel } from '@/pages/llmodels/apis';
import DeployModal from '@/pages/llmodels/components/deploy-modal';
import { modelSourceMap } from '@/pages/llmodels/config';
import { identifyModelTask } from '@/pages/llmodels/config/audio-catalog';
import { backendOptionsMap } from '@/pages/llmodels/config/backend-parameters';
import {
modalConfig,
@@ -16,8 +15,10 @@ import {
} from '@/pages/llmodels/config/button-actions';
import { SourceType } from '@/pages/llmodels/config/types';
import DownloadModal from '@/pages/llmodels/download';
import useCheckBackend from '@/pages/llmodels/hooks/use-check-backend';
import { useGenerateWorkerOptions } from '@/pages/llmodels/hooks/use-form-initial-values';
import useQueryBackends from '@/pages/llmodels/hooks/use-query-backends';
import useRecognizeAudio from '@/pages/llmodels/hooks/use-recognize-audio';
import { PageContainer } from '@ant-design/pro-components';
import { useIntl, useNavigate } from '@umijs/max';
import { useMemoizedFn } from 'ahooks';
@@ -25,7 +26,6 @@ import { ConfigProvider, Empty, Table, message } from 'antd';
import { useAtom } from 'jotai';
import _ from 'lodash';
import { useEffect, useMemo, useState } from 'react';
import { checkCurrentbackend } from '../../llmodels/hooks';
import {
MODEL_FILES_API,
deleteModelFile,
@@ -40,6 +40,8 @@ import useFilesColumns from '../hooks/use-files-columns';
const filterPattern = /^(.*?)(?:-\d+-of-\d+)?(\.gguf)?$/;
const ModelFiles = () => {
const { identifyModelTask } = useRecognizeAudio();
const { checkCurrentbackend } = useCheckBackend();
const { getWorkerOptionList, workerOptions, clusterList, workersList } =
useGenerateWorkerOptions();
const { saveScrollHeight, restoreScrollHeight } = useBodyScroll();