import SealAutoComplete from '@/components/seal-form/auto-complete'; import SealInput from '@/components/seal-form/seal-input'; import SealSelect from '@/components/seal-form/seal-select'; import { PageAction } from '@/config'; import { PageActionType } from '@/config/types'; import { useIntl } from '@umijs/max'; import { Form } from 'antd'; import _ from 'lodash'; import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from 'react'; import { queryGPUList } from '../apis'; import { backendOptionsMap, modelSourceMap, ollamaModelOptions } from '../config'; import { FormData, GPUListItem } from '../config/types'; import AdvanceConfig from './advance-config'; interface DataFormProps { ref?: any; source: string; action: PageActionType; selectedModel: any; isGGUF: boolean; onOk: (values: FormData) => void; } const sourceOptions = [ { label: 'Hugging Face', value: modelSourceMap.huggingface_value, key: 'huggingface' }, { label: 'Ollama Library', value: modelSourceMap.ollama_library_value, key: 'ollama_library' }, { label: 'ModelScope', value: modelSourceMap.modelscope_value, key: 'model_scope' } ]; const SEARCH_SOURCE = [ modelSourceMap.huggingface_value, modelSourceMap.modelscope_value ]; const DataForm: React.FC = forwardRef((props, ref) => { const { action, isGGUF, onOk } = props; const [form] = Form.useForm(); const intl = useIntl(); const [gpuOptions, setGpuOptions] = useState< Array >([]); const getGPUList = async () => { const data = await queryGPUList(); const list = _.map(data.items, (item: GPUListItem) => { return { ...item, label: item.name, value: `${item.worker_name}-${item.name}-${item.index}` }; }); setGpuOptions(list); }; useEffect(() => { getGPUList(); }, []); const handleSumit = () => { form.submit(); }; useImperativeHandle( ref, () => { return { submit: handleSumit, setFieldsValue: (values: FormData) => { form.setFieldsValue(values); }, setFieldValue: (name: string, value: any) => { form.setFieldValue(name, value); }, getFieldValue: (name: string) => { return form.getFieldValue(name); } }; }, [] ); const handleOnSelectModel = () => { let name = _.split(props.selectedModel.name, '/').slice(-1)[0]; const reg = /(-gguf)$/i; name = _.toLower(name).replace(reg, ''); if (SEARCH_SOURCE.includes(props.source)) { form.setFieldsValue({ repo_id: props.selectedModel.name, name: name }); } else { form.setFieldsValue({ ollama_library_model_name: props.selectedModel.name, name: name }); } }; const renderHuggingfaceFields = () => { return ( <> name="repo_id" key="repo_id" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.repoid' }) } ) } ]} > {isGGUF && ( name="file_name" key="file_name" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.filename' }) } ) } ]} > )} ); }; const renderS3Fields = () => { return ( <> name="s3_address" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.s3address' }) } ) } ]} > ); }; const renderOllamaModelFields = () => { return ( <> name="ollama_library_model_name" key="ollama_library_model_name" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.table.name' }) } ) } ]} > ); }; const renderFieldsBySource = useMemo(() => { if (SEARCH_SOURCE.includes(props.source)) { return renderHuggingfaceFields(); } if (props.source === modelSourceMap.ollama_library_value) { return renderOllamaModelFields(); } if (props.source === modelSourceMap.s3_value) { return renderS3Fields(); } return null; }, [props.source, isGGUF]); const handleOk = (formdata: FormData) => { const gpu = _.find(gpuOptions, (item: any) => { return item.value === formdata.gpu_selector; }); if (gpu) { onOk({ ..._.omit(formdata, ['scheduleType']), gpu_selector: { gpu_name: gpu.name, gpu_index: gpu.index, worker_name: gpu.worker_name } }); } else { onOk({ ..._.omit(formdata, ['scheduleType']) }); } }; useEffect(() => { if (action === PageAction.CREATE) { form.setFieldValue( 'backend', isGGUF ? backendOptionsMap.llamaBox : backendOptionsMap.vllm ); } }, [isGGUF]); useEffect(() => { handleOnSelectModel(); }, [props.selectedModel.name]); return (
name="name" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'common.table.name' }) } ) } ]} > name="source" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.select' }, { name: intl.formatMessage({ id: 'models.form.source' }) } ) } ]} > { } {renderFieldsBySource} name="replicas" rules={[ { required: true, message: intl.formatMessage( { id: 'common.form.rule.input' }, { name: intl.formatMessage({ id: 'models.form.replicas' }) } ) } ]} > name="description"> ); }); export default React.memo(DataForm);