feat: add extended_kv_cache
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import IconFont from '@/components/icon-font';
|
||||||
import { isNotEmptyValue } from '@/utils/index';
|
import { isNotEmptyValue } from '@/utils/index';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import type { CascaderAutoProps } from 'antd';
|
import type { CascaderAutoProps } from 'antd';
|
||||||
@@ -33,10 +34,11 @@ const renderTag = (props: any) => {
|
|||||||
|
|
||||||
const OptionNodes = (props: {
|
const OptionNodes = (props: {
|
||||||
data: any;
|
data: any;
|
||||||
|
notFoundContent?: React.ReactNode;
|
||||||
optionNode: React.FC<{ data: any }>;
|
optionNode: React.FC<{ data: any }>;
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { data, optionNode: OptionNode } = props;
|
const { data, optionNode: OptionNode, notFoundContent } = props;
|
||||||
if (data.value === '__EMPTY__') {
|
if (data.value === '__EMPTY__') {
|
||||||
return (
|
return (
|
||||||
<Empty
|
<Empty
|
||||||
@@ -48,9 +50,12 @@ const OptionNodes = (props: {
|
|||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
}}
|
}}
|
||||||
description={intl.formatMessage({
|
description={
|
||||||
id: 'common.search.empty'
|
notFoundContent ||
|
||||||
})}
|
intl.formatMessage({
|
||||||
|
id: 'common.search.empty'
|
||||||
|
})
|
||||||
|
}
|
||||||
></Empty>
|
></Empty>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -85,6 +90,7 @@ const SealCascader: React.FC<
|
|||||||
allowNull,
|
allowNull,
|
||||||
isInFormItems = true,
|
isInFormItems = true,
|
||||||
optionNode,
|
optionNode,
|
||||||
|
notFoundContent,
|
||||||
tagRender,
|
tagRender,
|
||||||
...rest
|
...rest
|
||||||
} = props;
|
} = props;
|
||||||
@@ -168,11 +174,13 @@ const SealCascader: React.FC<
|
|||||||
>
|
>
|
||||||
<Cascader
|
<Cascader
|
||||||
{...rest}
|
{...rest}
|
||||||
|
suffixIcon={<IconFont type="icon-down"></IconFont>}
|
||||||
optionRender={
|
optionRender={
|
||||||
optionNode
|
optionNode
|
||||||
? (data) => (
|
? (data) => (
|
||||||
<OptionNodes
|
<OptionNodes
|
||||||
data={data}
|
data={data}
|
||||||
|
notFoundContent={notFoundContent}
|
||||||
optionNode={optionNode}
|
optionNode={optionNode}
|
||||||
></OptionNodes>
|
></OptionNodes>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ const Inner = styled.div.attrs({
|
|||||||
className: '__inner__'
|
className: '__inner__'
|
||||||
})`
|
})`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Extra = styled.div`
|
const Extra = styled.div`
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ const SliderWrapper = styled.div`
|
|||||||
.borderless {
|
.borderless {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
.ant-slider {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
padding-block: 0;
|
padding-block: 0;
|
||||||
padding-inline: 2px;
|
padding-inline: 2px;
|
||||||
input.ant-input-number-input {
|
input.ant-input-number-input {
|
||||||
|
|||||||
@@ -182,5 +182,10 @@ export default {
|
|||||||
'models.table.users.all': 'All Users',
|
'models.table.users.all': 'All Users',
|
||||||
'models.table.users.selected': 'Selected Users',
|
'models.table.users.selected': 'Selected Users',
|
||||||
'models.table.nouserFound': 'No users found',
|
'models.table.nouserFound': 'No users found',
|
||||||
'models.form.performance': 'Performance'
|
'models.form.performance': 'Performance',
|
||||||
|
'models.form.gpus.notfound': 'No GPUs found',
|
||||||
|
'models.form.extendedkvcache': 'Enable Extended KV Cache',
|
||||||
|
'models.form.chunkSize': 'Size Of Cache Chunks',
|
||||||
|
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
|
||||||
|
'models.form.remoteURL': 'Remote Storage URL'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -179,7 +179,12 @@ export default {
|
|||||||
'models.table.users.all': 'All Users',
|
'models.table.users.all': 'All Users',
|
||||||
'models.table.users.selected': 'Selected Users',
|
'models.table.users.selected': 'Selected Users',
|
||||||
'models.table.nouserFound': 'No users found',
|
'models.table.nouserFound': 'No users found',
|
||||||
'models.form.performance': 'Performance'
|
'models.form.performance': 'Performance',
|
||||||
|
'models.form.gpus.notfound': 'No GPUs found',
|
||||||
|
'models.form.extendedkvcache': 'Enable Extended KV Cache',
|
||||||
|
'models.form.chunkSize': 'Size Of Cache Chunks',
|
||||||
|
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
|
||||||
|
'models.form.remoteURL': 'Remote Storage URL'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -202,5 +207,11 @@ export default {
|
|||||||
// 17. 'models.table.users.all': 'All Users',
|
// 17. 'models.table.users.all': 'All Users',
|
||||||
// 18. 'models.table.users.selected': 'Selected Users',
|
// 18. 'models.table.users.selected': 'Selected Users',
|
||||||
// 19. 'models.table.nouserFound': 'No users found',
|
// 19. 'models.table.nouserFound': 'No users found',
|
||||||
// 20. 'models.form.performance': 'Performance'
|
// 20. 'models.form.performance': 'Performance',
|
||||||
|
// 21. 'models.form.gpus.notfound': 'No GPUs found',
|
||||||
|
// 22. 'models.form.extendedkvcache': 'Enable Extended KV Cache',
|
||||||
|
// 23. 'models.form.chunkSize': 'Size Of Cache Chunks',
|
||||||
|
// 24. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
|
||||||
|
// 25. 'models.form.remoteURL': 'Remote Storage URL'
|
||||||
|
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -182,7 +182,12 @@ export default {
|
|||||||
'models.table.users.all': 'All users',
|
'models.table.users.all': 'All users',
|
||||||
'models.table.users.selected': 'Selected users',
|
'models.table.users.selected': 'Selected users',
|
||||||
'models.table.nouserFound': 'No users found',
|
'models.table.nouserFound': 'No users found',
|
||||||
'models.form.performance': 'Performance'
|
'models.form.performance': 'Performance',
|
||||||
|
'models.form.gpus.notfound': 'No GPUs found',
|
||||||
|
'models.form.extendedkvcache': 'Enable Extended KV Cache',
|
||||||
|
'models.form.chunkSize': 'Size Of Cache Chunks',
|
||||||
|
'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
|
||||||
|
'models.form.remoteURL': 'Remote Storage URL'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -197,5 +202,10 @@ export default {
|
|||||||
// 9. 'models.table.users.all': 'All users',
|
// 9. 'models.table.users.all': 'All users',
|
||||||
// 10. 'models.table.users.selected': 'Selected users',
|
// 10. 'models.table.users.selected': 'Selected users',
|
||||||
// 11. 'models.table.nouserFound': 'No users found',
|
// 11. 'models.table.nouserFound': 'No users found',
|
||||||
// 12. 'models.form.performance': 'Performance'
|
// 12. 'models.form.performance': 'Performance',
|
||||||
|
// 13. 'models.form.gpus.notfound': 'No GPUs found',
|
||||||
|
// 14. 'models.form.extendedkvcache': 'Enable Extended KV Cache',
|
||||||
|
// 15. 'models.form.chunkSize': 'Size Of Cache Chunks',
|
||||||
|
// 16. 'models.form.maxCPUSize': 'Maximum CPU Cache Size (GiB)',
|
||||||
|
// 17. 'models.form.remoteURL': 'Remote Storage URL'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -172,5 +172,10 @@ export default {
|
|||||||
'models.table.users.all': '所有用户',
|
'models.table.users.all': '所有用户',
|
||||||
'models.table.users.selected': '已选用户',
|
'models.table.users.selected': '已选用户',
|
||||||
'models.table.nouserFound': '未找到用户',
|
'models.table.nouserFound': '未找到用户',
|
||||||
'models.form.performance': '性能'
|
'models.form.performance': '性能',
|
||||||
|
'models.form.gpus.notfound': '未找到 GPU',
|
||||||
|
'models.form.extendedkvcache': '启用扩展 KV 缓存',
|
||||||
|
'models.form.chunkSize': '缓存分块大小',
|
||||||
|
'models.form.maxCPUSize': 'CPU 缓存最大占用 (GiB)',
|
||||||
|
'models.form.remoteURL': '远程存储地址'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -76,6 +76,12 @@ export interface FormData {
|
|||||||
optimize_long_prompt: boolean;
|
optimize_long_prompt: boolean;
|
||||||
enable_speculative_decoding: boolean;
|
enable_speculative_decoding: boolean;
|
||||||
cluster_id: number;
|
cluster_id: number;
|
||||||
|
extended_kv_cache: {
|
||||||
|
enabled: boolean;
|
||||||
|
chunk_size: number;
|
||||||
|
max_local_cpu_size: number;
|
||||||
|
remote_url: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ComputedResourceClaim {
|
interface ComputedResourceClaim {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { useFormContext } from '../config/form-context';
|
|||||||
import { FormData } from '../config/types';
|
import { FormData } from '../config/types';
|
||||||
import Backend from '../forms/backend';
|
import Backend from '../forms/backend';
|
||||||
import BackendParametersList from '../forms/backend-parameters-list';
|
import BackendParametersList from '../forms/backend-parameters-list';
|
||||||
|
import ScheduleTypeForm from '../forms/schedule-type';
|
||||||
|
|
||||||
const placementStrategyTips = [
|
const placementStrategyTips = [
|
||||||
{
|
{
|
||||||
@@ -88,6 +89,7 @@ const AdvanceConfig = () => {
|
|||||||
options={modelCategories}
|
options={modelCategories}
|
||||||
></SealSelect>
|
></SealSelect>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<ScheduleTypeForm></ScheduleTypeForm>
|
||||||
<Backend></Backend>
|
<Backend></Backend>
|
||||||
{scheduleType === ScheduleValueMap.Auto && (
|
{scheduleType === ScheduleValueMap.Auto && (
|
||||||
<>
|
<>
|
||||||
@@ -169,7 +171,7 @@ const AdvanceConfig = () => {
|
|||||||
[backendOptionsMap.vllm, backendOptionsMap.ascendMindie].includes(
|
[backendOptionsMap.vllm, backendOptionsMap.ascendMindie].includes(
|
||||||
backend
|
backend
|
||||||
) && (
|
) && (
|
||||||
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
<div style={{ paddingBottom: 22 }}>
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
name="distributed_inference_across_workers"
|
name="distributed_inference_across_workers"
|
||||||
valuePropName="checked"
|
valuePropName="checked"
|
||||||
@@ -187,7 +189,7 @@ const AdvanceConfig = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
<div style={{ paddingBottom: 22 }}>
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
name="restart_on_error"
|
name="restart_on_error"
|
||||||
valuePropName="checked"
|
valuePropName="checked"
|
||||||
|
|||||||
@@ -191,6 +191,12 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
|||||||
categories: null,
|
categories: null,
|
||||||
restart_on_error: true,
|
restart_on_error: true,
|
||||||
distributed_inference_across_workers: true,
|
distributed_inference_across_workers: true,
|
||||||
|
extended_kv_cache: {
|
||||||
|
enabled: false,
|
||||||
|
chunk_size: 256,
|
||||||
|
max_local_cpu_size: 10,
|
||||||
|
remote_url: ''
|
||||||
|
},
|
||||||
...initialValues
|
...initialValues
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -254,6 +260,28 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
|||||||
></SealSelect>
|
></SealSelect>
|
||||||
}
|
}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item<FormData>
|
||||||
|
name="replicas"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: getRuleMessage('input', 'models.form.replicas')
|
||||||
|
}
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<SealInput.Number
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'models.form.replicas'
|
||||||
|
})}
|
||||||
|
required
|
||||||
|
description={intl.formatMessage(
|
||||||
|
{ id: 'models.form.replicas.tips' },
|
||||||
|
{ api: `${window.location.origin}/v1` }
|
||||||
|
)}
|
||||||
|
min={0}
|
||||||
|
></SealInput.Number>
|
||||||
|
</Form.Item>
|
||||||
<CatalogFrom></CatalogFrom>
|
<CatalogFrom></CatalogFrom>
|
||||||
<Form.Item<FormData> name="description">
|
<Form.Item<FormData> name="description">
|
||||||
<SealInput.TextArea
|
<SealInput.TextArea
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import CheckboxField from '@/components/seal-form/checkbox-field';
|
||||||
|
import SealInputNumber from '@/components/seal-form/input-number';
|
||||||
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
|
import { useIntl } from '@umijs/max';
|
||||||
|
import { Form } from 'antd';
|
||||||
|
import { FormData } from '../config/types';
|
||||||
|
|
||||||
|
const KVCacheForm = () => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const form = Form.useFormInstance();
|
||||||
|
const kvCacheEnabled = Form.useWatch(['extended_kv_cache', 'enabled'], form);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div style={{ paddingBottom: 22 }}>
|
||||||
|
<Form.Item<FormData>
|
||||||
|
name={['extended_kv_cache', 'enabled']}
|
||||||
|
valuePropName="checked"
|
||||||
|
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||||
|
noStyle
|
||||||
|
>
|
||||||
|
<CheckboxField
|
||||||
|
label={intl.formatMessage({ id: 'models.form.extendedkvcache' })}
|
||||||
|
></CheckboxField>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
{kvCacheEnabled && (
|
||||||
|
<>
|
||||||
|
<Form.Item<FormData>
|
||||||
|
name={['extended_kv_cache', 'max_local_cpu_size']}
|
||||||
|
>
|
||||||
|
<SealInputNumber
|
||||||
|
label={intl.formatMessage({ id: 'models.form.maxCPUSize' })}
|
||||||
|
min={0}
|
||||||
|
step={1}
|
||||||
|
precision={0}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item<FormData> name={['extended_kv_cache', 'chunk_size']}>
|
||||||
|
<SealInputNumber
|
||||||
|
label={intl.formatMessage({ id: 'models.form.chunkSize' })}
|
||||||
|
min={0}
|
||||||
|
step={1}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item<FormData> name={['extended_kv_cache', 'remote_url']}>
|
||||||
|
<SealInput.Input
|
||||||
|
label={intl.formatMessage({ id: 'models.form.remoteURL' })}
|
||||||
|
min={0}
|
||||||
|
step={1}
|
||||||
|
placeholder="protocol://host:port"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default KVCacheForm;
|
||||||
@@ -1,143 +1,15 @@
|
|||||||
import SealCascader from '@/components/seal-form/seal-cascader';
|
|
||||||
import SealInput from '@/components/seal-form/seal-input';
|
|
||||||
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 { useIntl } from '@umijs/max';
|
||||||
import { Form } from 'antd';
|
import { Form } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import GPUCard from '../components/gpu-card';
|
import KVCacheForm from './kv-cache';
|
||||||
import { scheduleList, ScheduleValueMap } from '../config';
|
|
||||||
import { backendOptionsMap } from '../config/backend-parameters';
|
|
||||||
import { useCatalogFormContext, useFormContext } from '../config/form-context';
|
|
||||||
import { FormData } from '../config/types';
|
|
||||||
|
|
||||||
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 Performance: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { onValuesChange, gpuOptions } = useFormContext();
|
|
||||||
const { onQuantizationChange } = useCatalogFormContext();
|
|
||||||
const { getRuleMessage } = useAppUtils();
|
|
||||||
const form = Form.useFormInstance();
|
const form = Form.useFormInstance();
|
||||||
const scheduleType = Form.useWatch('scheduleType', form);
|
|
||||||
|
|
||||||
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<Form.Item<FormData>
|
<KVCacheForm></KVCacheForm>
|
||||||
name="replicas"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: getRuleMessage('input', 'models.form.replicas')
|
|
||||||
}
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<SealInput.Number
|
|
||||||
style={{ width: '100%' }}
|
|
||||||
label={intl.formatMessage({
|
|
||||||
id: 'models.form.replicas'
|
|
||||||
})}
|
|
||||||
required
|
|
||||||
description={intl.formatMessage(
|
|
||||||
{ id: 'models.form.replicas.tips' },
|
|
||||||
{ api: `${window.location.origin}/v1` }
|
|
||||||
)}
|
|
||||||
min={0}
|
|
||||||
></SealInput.Number>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item name="scheduleType">
|
|
||||||
<SealSelect
|
|
||||||
onChange={handleScheduleTypeChange}
|
|
||||||
label={intl.formatMessage({ id: 'models.form.scheduletype' })}
|
|
||||||
description={<TooltipList list={scheduleTypeTips}></TooltipList>}
|
|
||||||
options={scheduleList}
|
|
||||||
></SealSelect>
|
|
||||||
</Form.Item>
|
|
||||||
{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={[]}
|
|
||||||
></SealSelect>
|
|
||||||
</Form.Item>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{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 }}>
|
{/* <div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
name="optimize_long_prompt"
|
name="optimize_long_prompt"
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
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 ScheduleTypeForm: React.FC = () => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const { onValuesChange, gpuOptions } = useFormContext();
|
||||||
|
const { onQuantizationChange } = useCatalogFormContext();
|
||||||
|
const { getRuleMessage } = useAppUtils();
|
||||||
|
const form = Form.useFormInstance();
|
||||||
|
const scheduleType = Form.useWatch('scheduleType', form);
|
||||||
|
|
||||||
|
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>
|
||||||
|
{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={[]}
|
||||||
|
></SealSelect>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{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}
|
||||||
|
notFoundContent={intl.formatMessage({
|
||||||
|
id: 'models.form.gpus.notfound'
|
||||||
|
})}
|
||||||
|
onChange={handleGpuSelectorChange}
|
||||||
|
></SealCascader>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ScheduleTypeForm;
|
||||||
Reference in New Issue
Block a user