From 646d235c657292c13f98312bdf234ba6e5d71a17 Mon Sep 17 00:00:00 2001 From: jialin Date: Tue, 28 Oct 2025 17:20:01 +0800 Subject: [PATCH] fix: adjust gpus_per_replicas ux --- .../components/deploy-builtin-modal.tsx | 2 + .../llmodels/components/deploy-modal.tsx | 7 +- src/pages/llmodels/config/form-context.ts | 1 + src/pages/llmodels/config/index.ts | 8 +- src/pages/llmodels/config/types.ts | 1 - src/pages/llmodels/config/utils.ts | 14 +-- src/pages/llmodels/forms/index.tsx | 17 ++-- src/pages/llmodels/forms/kv-cache.tsx | 7 +- src/pages/llmodels/forms/schedule-type.tsx | 95 ++++++++++--------- src/pages/llmodels/hooks/index.ts | 6 +- .../llmodels/hooks/use-form-initial-values.ts | 7 +- 11 files changed, 80 insertions(+), 85 deletions(-) diff --git a/src/pages/llmodels/components/deploy-builtin-modal.tsx b/src/pages/llmodels/components/deploy-builtin-modal.tsx index 3b5909bf..f209956a 100644 --- a/src/pages/llmodels/components/deploy-builtin-modal.tsx +++ b/src/pages/llmodels/components/deploy-builtin-modal.tsx @@ -98,6 +98,7 @@ const AddModal: React.FC = (props) => { setWarningStatus, handleDoEvalute, cancelEvaluate, + clearCacheFormValues, submitAnyway, handleOnValuesChange, warningStatus @@ -609,6 +610,7 @@ const AddModal: React.FC = (props) => { onBackendChange={handleBackendChange} onSourceChange={handleSourceChange} onValuesChange={onValuesChange} + clearCacheFormValues={clearCacheFormValues} > diff --git a/src/pages/llmodels/components/deploy-modal.tsx b/src/pages/llmodels/components/deploy-modal.tsx index b7d2a158..2f1f2151 100644 --- a/src/pages/llmodels/components/deploy-modal.tsx +++ b/src/pages/llmodels/components/deploy-modal.tsx @@ -116,7 +116,7 @@ const AddModal: FC = (props) => { cancelEvaluate, unlockWarningStatus, handleOnValuesChange: handleOnValuesChangeBefore, - clearCahceFormValues, + clearCacheFormValues, warningStatus, submitAnyway } = useCheckCompatibility(); @@ -314,7 +314,7 @@ const AddModal: FC = (props) => { } console.log('handleOnSelectModel:', item, selectedModel); setIsGGUF(item.isGGUF); - clearCahceFormValues(); + clearCacheFormValues(); unlockWarningStatus(); setEvaluteState({ state: EvaluateProccess.model, @@ -511,7 +511,7 @@ const AddModal: FC = (props) => { handleOnOpen(); } else { cancelEvaluate(); - clearCahceFormValues(); + clearCacheFormValues(); } return () => { setSelectedModel({}); @@ -645,6 +645,7 @@ const AddModal: FC = (props) => { isGGUF={isGGUF} onBackendChange={handleBackendChange} onValuesChange={onValuesChange} + clearCacheFormValues={clearCacheFormValues} > diff --git a/src/pages/llmodels/config/form-context.ts b/src/pages/llmodels/config/form-context.ts index b7cecb58..ea8325ae 100644 --- a/src/pages/llmodels/config/form-context.ts +++ b/src/pages/llmodels/config/form-context.ts @@ -22,6 +22,7 @@ interface FormContextProps { workerLabelOptions: CascaderOption[]; backendOptions: BackendOption[]; initialValues?: FormData; // for editing model + clearCacheFormValues?: () => void; onValuesChange?: (changedValues: any, allValues: any) => void; onBackendChange: (backend: string, option: any) => void; } diff --git a/src/pages/llmodels/config/index.ts b/src/pages/llmodels/config/index.ts index 322eef41..9894dbaa 100644 --- a/src/pages/llmodels/config/index.ts +++ b/src/pages/llmodels/config/index.ts @@ -212,11 +212,6 @@ export const ScheduleValueMap = { SpecificGPUType: 'specific_gpu_type' }; -export const gpusCountTypeMap = { - Auto: 'auto', - Custom: 'custom' -}; - export const scheduleList = [ { label: 'models.form.scheduletype.auto', @@ -347,10 +342,9 @@ export const excludeFields = [ 'backend_version', 'ollama_library_model_name', 'scheduleType', - 'gpusCountType', 'placement_strategy', 'backend', - 'gpu_selector', + 'gpu_selector.gpu_ids', 'run_command', 'image_name', 'extended_kv_cache.enabled' diff --git a/src/pages/llmodels/config/types.ts b/src/pages/llmodels/config/types.ts index fc137981..bdb479d8 100644 --- a/src/pages/llmodels/config/types.ts +++ b/src/pages/llmodels/config/types.ts @@ -70,7 +70,6 @@ export interface FormData { cpu_offloading?: boolean; worker_selector?: object; scheduleType?: string; - gpusCountType?: string; name: string; replicas: number; description: string; diff --git a/src/pages/llmodels/config/utils.ts b/src/pages/llmodels/config/utils.ts index f99f2e5e..e7fd3fa7 100644 --- a/src/pages/llmodels/config/utils.ts +++ b/src/pages/llmodels/config/utils.ts @@ -1,5 +1,4 @@ import _ from 'lodash'; -import { gpusCountTypeMap } from '.'; import { backendOptionsMap } from '../config/backend-parameters'; import { FormData } from './types'; @@ -60,17 +59,14 @@ export const generateGPUIds = (data: FormData) => { }, [] ); - if (gpusCountTypeMap.Auto === data.gpusCountType) { - return { - gpu_selector: { - gpu_ids: result || [] - } - }; - } + return { gpu_selector: { gpu_ids: result || [], - gpus_per_replica: data.gpu_selector?.gpus_per_replica || null + gpus_per_replica: + data.gpu_selector?.gpus_per_replica === -1 + ? null + : data.gpu_selector?.gpus_per_replica } }; }; diff --git a/src/pages/llmodels/forms/index.tsx b/src/pages/llmodels/forms/index.tsx index 0e155dbe..3f4cc9c3 100644 --- a/src/pages/llmodels/forms/index.tsx +++ b/src/pages/llmodels/forms/index.tsx @@ -9,7 +9,6 @@ import styled from 'styled-components'; import { deployFormKeyMap, excludeFields, - gpusCountTypeMap, modelSourceMap, ScheduleValueMap } from '../config'; @@ -65,6 +64,7 @@ interface DataFormProps { sourceList?: Global.BaseOption[]; clusterList: Global.BaseOption[]; fields?: string[]; + clearCacheFormValues?: () => void; onValuesChange?: (changedValues: any, allValues: any) => void; onSourceChange?: (value: string) => void; onOk: (values: FormData) => void; @@ -82,6 +82,7 @@ const DataForm: React.FC = forwardRef((props, ref) => { sourceList, clusterList = [], fields = ['source'], + clearCacheFormValues, onBackendChange, onSourceChange, onValuesChange, @@ -154,9 +155,9 @@ const DataForm: React.FC = forwardRef((props, ref) => { if (backend === backendOptionsMap.voxBox && gpuids.length > 0) { return { - gpusCountType: gpusCountTypeMap.Auto, gpu_selector: { - gpu_ids: [gpuids[0]] + gpu_ids: [gpuids[0]], + gpus_per_replica: -1 } }; } @@ -217,7 +218,7 @@ const DataForm: React.FC = forwardRef((props, ref) => { data.categories = data.categories ? [data.categories] : []; const gpuSelector = generateGPUIds(data); const allValues = { - ..._.omit(data, ['scheduleType', 'gpusCountType']), + ..._.omit(data, ['scheduleType']), ...gpuSelector }; @@ -235,7 +236,9 @@ const DataForm: React.FC = forwardRef((props, ref) => { const getFieldPaths = (obj: Record, prefix = ''): string => { const result = Object.entries(obj).flatMap(([key, value]) => { const path = prefix ? `${prefix}.${key}` : key; - return typeof value === 'object' && value !== null + return typeof value === 'object' && + value !== null && + !Array.isArray(value) ? getFieldPaths(value, path) : [path]; }); @@ -328,6 +331,7 @@ const DataForm: React.FC = forwardRef((props, ref) => { backendOptions: backendOptions, workerLabelOptions: workerLabelOptions, initialValues: initialValues, + clearCacheFormValues: clearCacheFormValues, onValuesChange: onValuesChange, onBackendChange: handleBackendChange }} @@ -344,7 +348,7 @@ const DataForm: React.FC = forwardRef((props, ref) => { name="deployModel" form={form} onFinish={handleOk} - preserve={false} + preserve={true} clearOnDestroy={true} onValuesChange={handleOnValuesChange} onFinishFailed={handleOnFinishFailed} @@ -355,7 +359,6 @@ const DataForm: React.FC = forwardRef((props, ref) => { placement_strategy: 'spread', cpu_offloading: true, scheduleType: ScheduleValueMap.Auto, - gpusCountType: gpusCountTypeMap.Auto, categories: null, restart_on_error: true, distributed_inference_across_workers: true, diff --git a/src/pages/llmodels/forms/kv-cache.tsx b/src/pages/llmodels/forms/kv-cache.tsx index 0f79d6ac..41aff1f0 100644 --- a/src/pages/llmodels/forms/kv-cache.tsx +++ b/src/pages/llmodels/forms/kv-cache.tsx @@ -16,13 +16,14 @@ const KVCacheForm = () => { const backend = Form.useWatch('backend', form); const handleOnChange = async (e: any) => { + const extendedKVCache = form.getFieldValue('extended_kv_cache'); if (e.target.checked) { form.setFieldsValue({ extended_kv_cache: { enabled: true, - chunk_size: 256, - max_local_cpu_size: 10, - remote_url: '' + chunk_size: extendedKVCache?.chunk_size || 256, + max_local_cpu_size: extendedKVCache?.max_local_cpu_size || 10, + remote_url: extendedKVCache?.remote_url || '' } }); } diff --git a/src/pages/llmodels/forms/schedule-type.tsx b/src/pages/llmodels/forms/schedule-type.tsx index 2a30413e..1e80af01 100644 --- a/src/pages/llmodels/forms/schedule-type.tsx +++ b/src/pages/llmodels/forms/schedule-type.tsx @@ -1,18 +1,16 @@ import LabelSelector from '@/components/label-selector'; import { LabelSelectorContext } from '@/components/label-selector/context'; -import SealInputNumber from '@/components/seal-form/input-number'; import SealCascader from '@/components/seal-form/seal-cascader'; import SealSelect from '@/components/seal-form/seal-select'; import TooltipList from '@/components/tooltip-list'; -import { PageAction } from '@/config'; import useAppUtils from '@/hooks/use-app-utils'; import { useIntl } from '@umijs/max'; -import { Form } from 'antd'; +import { Form, InputNumber } from 'antd'; import _ from 'lodash'; import React from 'react'; +import styled from 'styled-components'; import GPUCard from '../components/gpu-card'; import { - gpusCountTypeMap, placementStrategyOptions, scheduleList, ScheduleValueMap @@ -21,6 +19,10 @@ import { backendOptionsMap } from '../config/backend-parameters'; import { useFormContext } from '../config/form-context'; import { FormData } from '../config/types'; +const InputWrapper = styled.div` + padding: 8px 4px; +`; + const placementStrategyTips = [ { title: 'Spread', @@ -73,24 +75,30 @@ const ScheduleTypeForm: React.FC = () => { action, gpuOptions, workerLabelOptions, + clearCacheFormValues, initialValues } = useFormContext(); const { getRuleMessage } = useAppUtils(); const form = Form.useFormInstance(); const scheduleType = Form.useWatch('scheduleType', form); - const gpusCountType = Form.useWatch('gpusCountType', form); - const wokerSelector = Form.useWatch('worker_selector', form); + const workerSelector = Form.useWatch('worker_selector', form); + const GPUsPerReplicas = Form.useWatch( + ['gpu_selector', 'gpus_per_replica'], + form + ); const handleScheduleTypeChange = (value: string) => { if (value === ScheduleValueMap.Auto) { onValuesChange?.({}, form.getFieldsValue()); + return; + } + if (value === ScheduleValueMap.Manual) { + form.setFieldValue(['gpu_selector', 'gpus_per_replica'], -1); } }; - const handleGpusCountTypeChange = (val: string) => { - if (val === gpusCountTypeMap.Custom) { - form.setFieldValue(['gpu_selector', 'gpus_per_replica'], 1); - } + const handleGpusPerReplicasChange = (val: string | number | null) => { + form.setFieldValue(['gpu_selector', 'gpus_per_replica'], val); onValuesChange?.({}, form.getFieldsValue()); }; @@ -98,6 +106,8 @@ const ScheduleTypeForm: React.FC = () => { const handleGpuSelectorChange = (value: any[]) => { if (value.length > 0) { onValuesChange?.({}, form.getFieldsValue()); + } else { + clearCacheFormValues?.(); } }; @@ -221,50 +231,41 @@ const ScheduleTypeForm: React.FC = () => { onChange={handleGpuSelectorChange} > -