refactor: advance collapse
This commit is contained in:
@@ -0,0 +1,211 @@
|
||||
import LabelSelector from '@/components/label-selector';
|
||||
import CheckboxField from '@/components/seal-form/checkbox-field';
|
||||
import SealSelect from '@/components/seal-form/seal-select';
|
||||
import TooltipList from '@/components/tooltip-list';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import { useCallback } from 'react';
|
||||
import {
|
||||
modelCategories,
|
||||
placementStrategyOptions,
|
||||
ScheduleValueMap
|
||||
} from '../config';
|
||||
import { backendOptionsMap } from '../config/backend-parameters';
|
||||
import { useFormContext } from '../config/form-context';
|
||||
import { FormData } from '../config/types';
|
||||
import Backend from '../forms/backend';
|
||||
import BackendParametersList from '../forms/backend-parameters-list';
|
||||
|
||||
const placementStrategyTips = [
|
||||
{
|
||||
title: 'Spread',
|
||||
tips: 'resources.form.spread.tips'
|
||||
},
|
||||
{
|
||||
title: 'Binpack',
|
||||
tips: 'resources.form.binpack.tips'
|
||||
}
|
||||
];
|
||||
|
||||
const AdvanceConfig = () => {
|
||||
const intl = useIntl();
|
||||
const form = Form.useFormInstance();
|
||||
const wokerSelector = Form.useWatch('worker_selector', form);
|
||||
const EnviromentVars = Form.useWatch('env', form);
|
||||
const scheduleType = Form.useWatch('scheduleType', form);
|
||||
const backend = Form.useWatch('backend', form);
|
||||
const { onValuesChange } = useFormContext();
|
||||
|
||||
const handleWorkerLabelsChange = useCallback(
|
||||
(labels: Record<string, any>) => {
|
||||
form.setFieldValue('worker_selector', labels);
|
||||
},
|
||||
[]
|
||||
);
|
||||
const handleEnviromentVarsChange = useCallback(
|
||||
(labels: Record<string, any>) => {
|
||||
form.setFieldValue('env', labels);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const onSelectorChange = (field: string, allowEmpty?: boolean) => {
|
||||
const workerSelector = form.getFieldValue(field);
|
||||
// check if all keys have values
|
||||
const hasEmptyValue = _.some(_.keys(workerSelector), (k: string) => {
|
||||
return !workerSelector[k];
|
||||
});
|
||||
if (!hasEmptyValue || allowEmpty) {
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectorOnBlur = () => {
|
||||
onSelectorChange('worker_selector');
|
||||
};
|
||||
|
||||
const handleDeleteWorkerSelector = (index: number) => {
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
};
|
||||
|
||||
const handleEnvSelectorOnBlur = () => {
|
||||
onSelectorChange('env', true);
|
||||
};
|
||||
|
||||
const handleDeleteEnvSelector = (index: number) => {
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item<FormData> name="categories">
|
||||
<SealSelect
|
||||
allowNull
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.categories'
|
||||
})}
|
||||
options={modelCategories}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
<Backend></Backend>
|
||||
{scheduleType === ScheduleValueMap.Auto && (
|
||||
<>
|
||||
<Form.Item<FormData> name="placement_strategy">
|
||||
<SealSelect
|
||||
label={intl.formatMessage({
|
||||
id: 'resources.form.placementStrategy'
|
||||
})}
|
||||
options={placementStrategyOptions}
|
||||
description={
|
||||
<TooltipList list={placementStrategyTips}></TooltipList>
|
||||
}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
<Form.Item<FormData>
|
||||
name="worker_selector"
|
||||
rules={[
|
||||
({ getFieldValue }) => ({
|
||||
validator(rule, value) {
|
||||
if (
|
||||
getFieldValue('scheduleType') === ScheduleValueMap.Auto &&
|
||||
_.keys(value).length > 0
|
||||
) {
|
||||
if (_.some(_.keys(value), (k: string) => !value[k])) {
|
||||
return Promise.reject(
|
||||
intl.formatMessage(
|
||||
{
|
||||
id: 'common.validate.value'
|
||||
},
|
||||
{
|
||||
name: intl.formatMessage({
|
||||
id: 'models.form.selector'
|
||||
})
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
})
|
||||
]}
|
||||
>
|
||||
<LabelSelector
|
||||
label={intl.formatMessage({
|
||||
id: 'resources.form.workerSelector'
|
||||
})}
|
||||
labels={wokerSelector}
|
||||
onChange={handleWorkerLabelsChange}
|
||||
onBlur={handleSelectorOnBlur}
|
||||
onDelete={handleDeleteWorkerSelector}
|
||||
description={
|
||||
<span>
|
||||
{intl.formatMessage({
|
||||
id: 'resources.form.workerSelector.description'
|
||||
})}
|
||||
</span>
|
||||
}
|
||||
></LabelSelector>
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
|
||||
<BackendParametersList></BackendParametersList>
|
||||
<Form.Item<FormData> name="env">
|
||||
<LabelSelector
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.env'
|
||||
})}
|
||||
labels={EnviromentVars}
|
||||
btnText={intl.formatMessage({ id: 'common.button.vars' })}
|
||||
onBlur={handleEnvSelectorOnBlur}
|
||||
onDelete={handleDeleteEnvSelector}
|
||||
onChange={handleEnviromentVarsChange}
|
||||
></LabelSelector>
|
||||
</Form.Item>
|
||||
|
||||
{scheduleType === ScheduleValueMap.Auto &&
|
||||
[backendOptionsMap.vllm, backendOptionsMap.ascendMindie].includes(
|
||||
backend
|
||||
) && (
|
||||
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
||||
<Form.Item<FormData>
|
||||
name="distributed_inference_across_workers"
|
||||
valuePropName="checked"
|
||||
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||
noStyle
|
||||
>
|
||||
<CheckboxField
|
||||
description={intl.formatMessage({
|
||||
id: 'models.form.distribution.tips'
|
||||
})}
|
||||
label={intl.formatMessage({
|
||||
id: 'resources.form.enableDistributedInferenceAcrossWorkers'
|
||||
})}
|
||||
></CheckboxField>
|
||||
</Form.Item>
|
||||
</div>
|
||||
)}
|
||||
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
||||
<Form.Item<FormData>
|
||||
name="restart_on_error"
|
||||
valuePropName="checked"
|
||||
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||
noStyle
|
||||
>
|
||||
<CheckboxField
|
||||
description={intl.formatMessage({
|
||||
id: 'models.form.restart.onerror.tips'
|
||||
})}
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.restart.onerror'
|
||||
})}
|
||||
></CheckboxField>
|
||||
</Form.Item>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AdvanceConfig;
|
||||
@@ -0,0 +1,93 @@
|
||||
import IconFont from '@/components/icon-font';
|
||||
import ListInput from '@/components/list-input';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form, Typography } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import { useMemo } from 'react';
|
||||
import { backendParamsHolderTips, getBackendParamsTips } from '../config';
|
||||
import BackendParameters, {
|
||||
backendOptionsMap
|
||||
} from '../config/backend-parameters';
|
||||
import { useFormContext } from '../config/form-context';
|
||||
import { FormData } from '../config/types';
|
||||
|
||||
const BackendParametersList: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const { onValuesChange } = useFormContext();
|
||||
const form = Form.useFormInstance();
|
||||
const backend = Form.useWatch('backend', form);
|
||||
|
||||
const backendParamsTips = useMemo(() => {
|
||||
return getBackendParamsTips(backend);
|
||||
}, [backend]);
|
||||
|
||||
const paramsConfig = useMemo(() => {
|
||||
return _.get(BackendParameters, backend, []);
|
||||
}, [backend]);
|
||||
|
||||
const handleBackendParametersChange = (list: string[]) => {
|
||||
form.setFieldValue('backend_parameters', list);
|
||||
};
|
||||
|
||||
const handleBackendParametersOnBlur = () => {
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
};
|
||||
|
||||
const handleDeleteBackendParameters = (index: number) => {
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
};
|
||||
|
||||
return (
|
||||
<Form.Item<FormData> name="backend_parameters">
|
||||
<ListInput
|
||||
placeholder={
|
||||
backendParamsHolderTips[backend]
|
||||
? intl.formatMessage({
|
||||
id: backendParamsHolderTips[backend].holder
|
||||
})
|
||||
: ''
|
||||
}
|
||||
btnText={intl.formatMessage({ id: 'common.button.addParams' })}
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.backend_parameters'
|
||||
})}
|
||||
dataList={form.getFieldValue('backend_parameters') || []}
|
||||
onChange={handleBackendParametersChange}
|
||||
onBlur={handleBackendParametersOnBlur}
|
||||
onDelete={handleDeleteBackendParameters}
|
||||
options={paramsConfig}
|
||||
description={
|
||||
backendParamsTips.link && (
|
||||
<span>
|
||||
{backend === backendOptionsMap.ascendMindie && (
|
||||
<span>
|
||||
{intl.formatMessage({ id: 'models.backend.mindie.310p' })}
|
||||
</span>
|
||||
)}
|
||||
<span style={{ marginLeft: 5 }}>
|
||||
{intl.formatMessage(
|
||||
{ id: 'models.form.backend_parameters.vllm.tips' },
|
||||
{ backend: backendParamsTips.backend || '' }
|
||||
)}{' '}
|
||||
<Typography.Link
|
||||
style={{ display: 'inline' }}
|
||||
className="flex-center"
|
||||
href={backendParamsTips.link}
|
||||
target="_blank"
|
||||
>
|
||||
<span>{intl.formatMessage({ id: 'common.text.here' })}</span>
|
||||
<IconFont
|
||||
type="icon-external-link"
|
||||
className="font-size-14 m-l-4"
|
||||
></IconFont>
|
||||
</Typography.Link>
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
></ListInput>
|
||||
</Form.Item>
|
||||
);
|
||||
};
|
||||
|
||||
export default BackendParametersList;
|
||||
+9
-3
@@ -14,9 +14,14 @@ 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);
|
||||
const { formKey, gpuOptions, onValuesChange, onBackendChange } = formCtx;
|
||||
const {
|
||||
formKey,
|
||||
gpuOptions,
|
||||
backendOptions,
|
||||
onValuesChange,
|
||||
onBackendChange
|
||||
} = useFormContext();
|
||||
const { getRuleMessage } = useAppUtils();
|
||||
const intl = useIntl();
|
||||
const localPathCache = useRef<string>(form.getFieldValue('local_path') || '');
|
||||
@@ -58,7 +63,8 @@ const LocalPathForm: React.FC = () => {
|
||||
});
|
||||
|
||||
if (oldBackend !== backend) {
|
||||
onBackendChange?.(backend);
|
||||
const option = backendOptions.find((item) => item.value === backend);
|
||||
onBackendChange?.(backend, option);
|
||||
} else {
|
||||
onValuesChange?.({ local_path: value }, form.getFieldsValue());
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
import SealCascader from '@/components/seal-form/seal-cascader';
|
||||
import SealSelect from '@/components/seal-form/seal-select';
|
||||
import TooltipList from '@/components/tooltip-list';
|
||||
import useAppUtils from '@/hooks/use-app-utils';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form } from 'antd';
|
||||
import React from 'react';
|
||||
import GPUCard from '../components/gpu-card';
|
||||
import { scheduleList, ScheduleValueMap } from '../config';
|
||||
import { backendOptionsMap } from '../config/backend-parameters';
|
||||
import { useCatalogFormContext, useFormContext } from '../config/form-context';
|
||||
|
||||
const scheduleTypeTips = [
|
||||
{
|
||||
title: {
|
||||
text: 'models.form.scheduletype.auto',
|
||||
locale: true
|
||||
},
|
||||
tips: 'models.form.scheduletype.auto.tips'
|
||||
},
|
||||
{
|
||||
title: {
|
||||
text: 'models.form.scheduletype.manual',
|
||||
locale: true
|
||||
},
|
||||
tips: 'models.form.scheduletype.manual.tips'
|
||||
}
|
||||
];
|
||||
|
||||
const Performance: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const { onValuesChange, gpuOptions } = useFormContext();
|
||||
const { onQuantizationChange } = useCatalogFormContext();
|
||||
const { getRuleMessage } = useAppUtils();
|
||||
const form = Form.useFormInstance();
|
||||
|
||||
const handleScheduleTypeChange = (value: string) => {
|
||||
if (value === ScheduleValueMap.Auto) {
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
}
|
||||
};
|
||||
|
||||
const handleOnQuantizationChange = (val: any) => {
|
||||
onQuantizationChange?.(val);
|
||||
};
|
||||
|
||||
const handleBeforeGpuSelectorChange = (gpuIds: any[]) => {};
|
||||
|
||||
const handleGpuSelectorChange = (value: any[]) => {
|
||||
handleBeforeGpuSelectorChange(value);
|
||||
onValuesChange?.({}, form.getFieldsValue());
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form.Item name="scheduleType">
|
||||
<SealSelect
|
||||
onChange={handleScheduleTypeChange}
|
||||
label={intl.formatMessage({ id: 'models.form.scheduletype' })}
|
||||
description={<TooltipList list={scheduleTypeTips}></TooltipList>}
|
||||
options={scheduleList}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
{form.getFieldValue('scheduleType') ===
|
||||
ScheduleValueMap.SpecificGPUType && (
|
||||
<>
|
||||
<Form.Item name={['gpu_selector', 'gpu_type']}>
|
||||
<SealSelect
|
||||
label={intl.formatMessage({ id: 'models.form.gpuType' })}
|
||||
options={[]}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
<Form.Item name={['gpu_selector', 'gpu_count']}>
|
||||
<SealSelect
|
||||
label={intl.formatMessage({ id: 'models.form.gpuCount' })}
|
||||
options={[
|
||||
{
|
||||
label: 'Auto',
|
||||
value: 'auto'
|
||||
},
|
||||
{
|
||||
label: '1',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: '2',
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
label: '4',
|
||||
value: 4
|
||||
}
|
||||
]}
|
||||
></SealSelect>
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
{form.getFieldValue('scheduleType') === ScheduleValueMap.Manual &&
|
||||
!form.getFieldValue('fix_gpu_type') && (
|
||||
<>
|
||||
<Form.Item
|
||||
name={['gpu_selector', 'gpu_ids']}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: getRuleMessage('select', 'models.form.gpuselector')
|
||||
}
|
||||
]}
|
||||
>
|
||||
<SealCascader
|
||||
required
|
||||
showSearch
|
||||
expandTrigger="hover"
|
||||
multiple={
|
||||
form.getFieldValue('backend') !== backendOptionsMap.voxBox
|
||||
}
|
||||
classNames={{
|
||||
popup: {
|
||||
root: 'cascader-popup-wrapper gpu-selector'
|
||||
}
|
||||
}}
|
||||
maxTagCount={1}
|
||||
label={intl.formatMessage({ id: 'models.form.gpuselector' })}
|
||||
options={gpuOptions}
|
||||
showCheckedStrategy="SHOW_CHILD"
|
||||
value={form.getFieldValue(['gpu_selector', 'gpu_ids'])}
|
||||
optionNode={GPUCard}
|
||||
getPopupContainer={(triggerNode) => triggerNode.parentNode}
|
||||
onChange={handleGpuSelectorChange}
|
||||
></SealCascader>
|
||||
</Form.Item>
|
||||
</>
|
||||
)}
|
||||
{/* <div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
||||
<Form.Item<FormData>
|
||||
name="optimize_long_prompt"
|
||||
valuePropName="checked"
|
||||
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||
noStyle
|
||||
>
|
||||
<CheckboxField
|
||||
label={intl.formatMessage({ id: 'models.form.optimizeLongPrompt' })}
|
||||
></CheckboxField>
|
||||
</Form.Item>
|
||||
</div>
|
||||
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
||||
<Form.Item<FormData>
|
||||
name="enable_speculative_decoding"
|
||||
valuePropName="checked"
|
||||
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||
noStyle
|
||||
>
|
||||
<CheckboxField
|
||||
label={intl.formatMessage({
|
||||
id: 'models.form.enableSpeculativeDecoding'
|
||||
})}
|
||||
></CheckboxField>
|
||||
</Form.Item>
|
||||
</div> */}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Performance;
|
||||
Reference in New Issue
Block a user