fix: adjust gpus_per_replicas ux

This commit is contained in:
jialin
2025-10-28 17:21:22 +08:00
parent a86bed294e
commit 646d235c65
11 changed files with 80 additions and 85 deletions
@@ -98,6 +98,7 @@ const AddModal: React.FC<AddModalProps> = (props) => {
setWarningStatus,
handleDoEvalute,
cancelEvaluate,
clearCacheFormValues,
submitAnyway,
handleOnValuesChange,
warningStatus
@@ -609,6 +610,7 @@ const AddModal: React.FC<AddModalProps> = (props) => {
onBackendChange={handleBackendChange}
onSourceChange={handleSourceChange}
onValuesChange={onValuesChange}
clearCacheFormValues={clearCacheFormValues}
></DataForm>
</>
</ColumnWrapper>
@@ -116,7 +116,7 @@ const AddModal: FC<AddModalProps> = (props) => {
cancelEvaluate,
unlockWarningStatus,
handleOnValuesChange: handleOnValuesChangeBefore,
clearCahceFormValues,
clearCacheFormValues,
warningStatus,
submitAnyway
} = useCheckCompatibility();
@@ -314,7 +314,7 @@ const AddModal: FC<AddModalProps> = (props) => {
}
console.log('handleOnSelectModel:', item, selectedModel);
setIsGGUF(item.isGGUF);
clearCahceFormValues();
clearCacheFormValues();
unlockWarningStatus();
setEvaluteState({
state: EvaluateProccess.model,
@@ -511,7 +511,7 @@ const AddModal: FC<AddModalProps> = (props) => {
handleOnOpen();
} else {
cancelEvaluate();
clearCahceFormValues();
clearCacheFormValues();
}
return () => {
setSelectedModel({});
@@ -645,6 +645,7 @@ const AddModal: FC<AddModalProps> = (props) => {
isGGUF={isGGUF}
onBackendChange={handleBackendChange}
onValuesChange={onValuesChange}
clearCacheFormValues={clearCacheFormValues}
></DataForm>
</>
</ColumnWrapper>
@@ -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;
}
+1 -7
View File
@@ -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'
-1
View File
@@ -70,7 +70,6 @@ export interface FormData {
cpu_offloading?: boolean;
worker_selector?: object;
scheduleType?: string;
gpusCountType?: string;
name: string;
replicas: number;
description: string;
+5 -9
View File
@@ -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
}
};
};
+10 -7
View File
@@ -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<string>[];
clusterList: Global.BaseOption<number>[];
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<DataFormProps> = forwardRef((props, ref) => {
sourceList,
clusterList = [],
fields = ['source'],
clearCacheFormValues,
onBackendChange,
onSourceChange,
onValuesChange,
@@ -154,9 +155,9 @@ const DataForm: React.FC<DataFormProps> = 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<DataFormProps> = 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<DataFormProps> = forwardRef((props, ref) => {
const getFieldPaths = (obj: Record<string, any>, 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<DataFormProps> = forwardRef((props, ref) => {
backendOptions: backendOptions,
workerLabelOptions: workerLabelOptions,
initialValues: initialValues,
clearCacheFormValues: clearCacheFormValues,
onValuesChange: onValuesChange,
onBackendChange: handleBackendChange
}}
@@ -344,7 +348,7 @@ const DataForm: React.FC<DataFormProps> = 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<DataFormProps> = 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,
+4 -3
View File
@@ -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 || ''
}
});
}
+48 -47
View File
@@ -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}
></SealCascader>
</Form.Item>
<Form.Item
name="gpusCountType"
hidden={
action === PageAction.EDIT &&
!!initialValues?.gpu_selector?.gpus_per_replica
}
>
<Form.Item name={['gpu_selector', 'gpus_per_replica']}>
<SealSelect
onChange={handleGpusCountTypeChange}
label={intl.formatMessage({
id: 'models.form.gpusAllocationType'
id: 'models.form.gpusperreplica'
})}
description={
<TooltipList list={gpuAllocateTypeTips}></TooltipList>
}
options={[
{
label: intl.formatMessage({
id: 'models.form.gpusAllocationType.auto'
}),
value: gpusCountTypeMap.Auto
label: intl.formatMessage({ id: 'common.options.auto' }),
value: -1
},
{
label: intl.formatMessage({
id: 'models.form.gpusAllocationType.custom'
}),
value: gpusCountTypeMap.Custom
}
{ label: '1', value: 1 },
{ label: '2', value: 2 },
{ label: '4', value: 4 },
{ label: '8', value: 8 }
]}
></SealSelect>
popupRender={(originNode) => (
<div>
{originNode}
<InputWrapper>
<InputNumber
step={1}
style={{ width: '100%' }}
defaultValue={
GPUsPerReplicas === null ? -1 : GPUsPerReplicas
}
value={GPUsPerReplicas === -1 ? null : GPUsPerReplicas}
onChange={handleGpusPerReplicasChange}
onStep={handleOnStepReplicaStep}
/>
</InputWrapper>
</div>
)}
onChange={handleOnStepReplica}
/>
</Form.Item>
{gpusCountType === gpusCountTypeMap.Custom && (
<Form.Item name={['gpu_selector', 'gpus_per_replica']}>
<SealInputNumber
label={intl.formatMessage({
id: 'models.form.gpusperreplica'
})}
min={1}
step={1}
onChange={handleOnStepReplica}
onStep={handleOnStepReplicaStep}
/>
</Form.Item>
)}
</>
)}
{scheduleType === ScheduleValueMap.Auto && (
@@ -317,7 +318,7 @@ const ScheduleTypeForm: React.FC = () => {
label={intl.formatMessage({
id: 'resources.form.workerSelector'
})}
labels={wokerSelector}
labels={workerSelector}
onChange={handleWorkerLabelsChange}
onBlur={handleSelectorOnBlur}
onDelete={handleDeleteWorkerSelector}
+3 -3
View File
@@ -375,7 +375,7 @@ export const useCheckCompatibility = () => {
return null;
};
const clearCahceFormValues = () => {
const clearCacheFormValues = () => {
cacheFormValuesRef.current = {};
};
@@ -437,7 +437,7 @@ export const useCheckCompatibility = () => {
useEffect(() => {
return () => {
cancelEvaluate();
clearCahceFormValues();
clearCacheFormValues();
};
}, []);
@@ -452,7 +452,7 @@ export const useCheckCompatibility = () => {
handleBackendChangeBefore,
handleOnValuesChange: handleOnValuesChange,
handleEvaluateOnChange: handleOnValuesChange,
clearCahceFormValues,
clearCacheFormValues,
warningStatus,
checkTokenRef,
submitAnyway
@@ -10,7 +10,7 @@ import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
import { useAtom } from 'jotai';
import { useState } from 'react';
import { queryGPUList } from '../apis';
import { gpusCountTypeMap, ScheduleValueMap } from '../config';
import { ScheduleValueMap } from '../config';
import { GPUListItem, ListItem } from '../config/types';
type EmptyObject = Record<never, never>;
@@ -276,10 +276,7 @@ export default function useFormInitialValues() {
categories: data?.categories?.length ? data.categories[0] : null,
scheduleType: data?.gpu_selector
? ScheduleValueMap.Manual
: ScheduleValueMap.Auto,
gpusCountType: data?.gpu_selector?.gpus_per_replica
? gpusCountTypeMap.Custom
: gpusCountTypeMap.Auto
: ScheduleValueMap.Auto
};
return formData;
};