feat: add extended_kv_cache

This commit is contained in:
jialin
2025-10-14 20:09:43 +08:00
parent 620c113fae
commit 83403a1a1a
13 changed files with 277 additions and 142 deletions
+4 -2
View File
@@ -16,6 +16,7 @@ import { useFormContext } from '../config/form-context';
import { FormData } from '../config/types';
import Backend from '../forms/backend';
import BackendParametersList from '../forms/backend-parameters-list';
import ScheduleTypeForm from '../forms/schedule-type';
const placementStrategyTips = [
{
@@ -88,6 +89,7 @@ const AdvanceConfig = () => {
options={modelCategories}
></SealSelect>
</Form.Item>
<ScheduleTypeForm></ScheduleTypeForm>
<Backend></Backend>
{scheduleType === ScheduleValueMap.Auto && (
<>
@@ -169,7 +171,7 @@ const AdvanceConfig = () => {
[backendOptionsMap.vllm, backendOptionsMap.ascendMindie].includes(
backend
) && (
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
<div style={{ paddingBottom: 22 }}>
<Form.Item<FormData>
name="distributed_inference_across_workers"
valuePropName="checked"
@@ -187,7 +189,7 @@ const AdvanceConfig = () => {
</Form.Item>
</div>
)}
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
<div style={{ paddingBottom: 22 }}>
<Form.Item<FormData>
name="restart_on_error"
valuePropName="checked"
+28
View File
@@ -191,6 +191,12 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
categories: null,
restart_on_error: true,
distributed_inference_across_workers: true,
extended_kv_cache: {
enabled: false,
chunk_size: 256,
max_local_cpu_size: 10,
remote_url: ''
},
...initialValues
}}
>
@@ -254,6 +260,28 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
></SealSelect>
}
</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>
<Form.Item<FormData> name="description">
<SealInput.TextArea
+60
View File
@@ -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;
+2 -130
View File
@@ -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 { 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';
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'
}
];
import KVCacheForm from './kv-cache';
const Performance: 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<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>
<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>
</>
)}
<KVCacheForm></KVCacheForm>
{/* <div style={{ paddingBottom: 22, paddingLeft: 10 }}>
<Form.Item<FormData>
name="optimize_long_prompt"
+124
View File
@@ -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;