diff --git a/src/locales/en-US/models.ts b/src/locales/en-US/models.ts
index a458ed62..35133761 100644
--- a/src/locales/en-US/models.ts
+++ b/src/locales/en-US/models.ts
@@ -212,5 +212,6 @@ export default {
'models.form.kvCache.tips':
'Available only with built-in backends (vLLM / SGLang) — switch backend in Advanced to enable.',
'models.form.kvCache.tips2':
- 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).'
+ 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).',
+ 'models.form.scheduling': 'Scheduling'
};
diff --git a/src/locales/ja-JP/models.ts b/src/locales/ja-JP/models.ts
index 4dfca12e..429aca80 100644
--- a/src/locales/ja-JP/models.ts
+++ b/src/locales/ja-JP/models.ts
@@ -209,7 +209,8 @@ export default {
'models.form.kvCache.tips':
'Available only with built-in backends (vLLM / SGLang) — switch backend in Advanced to enable.',
'models.form.kvCache.tips2':
- 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).'
+ 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).',
+ 'models.form.scheduling': 'Scheduling'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -255,5 +256,6 @@ export default {
// 42. 'models.mymodels.status.active': 'Active'
// 43. 'models.form.remoteURL.tips': 'Refer to the configuration documentation for details.',
// 44. 'models.form.kvCache.tips': 'Available only with built-in backends (vLLM / SGLang) — switch backend in Advanced to enable.'
-// 45. 'models.form.kvCache.tips2': 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).'
+// 45. 'models.form.kvCache.tips2': 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).',
+// 46. 'models.form.scheduling': 'Scheduling'
// ========== End of To-Do List ==========
diff --git a/src/locales/ru-RU/models.ts b/src/locales/ru-RU/models.ts
index 19e67e9d..5f1d73f9 100644
--- a/src/locales/ru-RU/models.ts
+++ b/src/locales/ru-RU/models.ts
@@ -212,7 +212,8 @@ export default {
'models.form.kvCache.tips':
'Available only with built-in backends (vLLM / SGLang) — switch backend in Advanced to enable.',
'models.form.kvCache.tips2':
- 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).'
+ 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).',
+ 'models.form.scheduling': 'Scheduling'
};
// ========== To-Do: Translate Keys (Remove After Translation) ==========
@@ -222,4 +223,5 @@ export default {
// 5. 'models.form.remoteURL.tips': 'Refer to the configuration documentation for details.',
// 6. 'models.form.kvCache.tips': 'Available only with built-in backends (vLLM / SGLang) — switch backend in Advanced to enable.'
// 7. 'models.form.kvCache.tips2': 'KV cache is only supported when using built-in inference backends (vLLM or SGLang).';
+// 8. 'models.form.scheduling': 'Scheduling'
// ========== End of To-Do List ==========
diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts
index 736ce4f7..a7c2383d 100644
--- a/src/locales/zh-CN/models.ts
+++ b/src/locales/zh-CN/models.ts
@@ -200,5 +200,6 @@ export default {
'models.form.kvCache.tips':
'仅在内置后端(vLLM / SGLang)可用 —— 请在高级配置中切换后端以启用。',
'models.form.kvCache.tips2':
- '仅在使用内置推理后端(vLLM 或 SGLang)时支持 KV 缓存。'
+ '仅在使用内置推理后端(vLLM 或 SGLang)时支持 KV 缓存。',
+ 'models.form.scheduling': '调度'
};
diff --git a/src/pages/llmodels/forms/advance-config.tsx b/src/pages/llmodels/forms/advance-config.tsx
index aad9e1d5..681e03e5 100644
--- a/src/pages/llmodels/forms/advance-config.tsx
+++ b/src/pages/llmodels/forms/advance-config.tsx
@@ -1,50 +1,25 @@
import LabelSelector from '@/components/label-selector';
-import { LabelSelectorContext } from '@/components/label-selector/context';
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 { modelCategories, 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';
-import ScheduleTypeForm from '../forms/schedule-type';
-
-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, workerLabelOptions } = useFormContext();
+ const { onValuesChange } = useFormContext();
- const handleWorkerLabelsChange = useCallback(
- (labels: Record) => {
- form.setFieldValue('worker_selector', labels);
- },
- []
- );
const handleEnviromentVarsChange = useCallback(
(labels: Record) => {
form.setFieldValue('env', labels);
@@ -63,14 +38,6 @@ const AdvanceConfig = () => {
}
};
- const handleSelectorOnBlur = () => {
- onSelectorChange('worker_selector');
- };
-
- const handleDeleteWorkerSelector = (index: number) => {
- onValuesChange?.({}, form.getFieldsValue());
- };
-
const handleEnvSelectorOnBlur = () => {
onSelectorChange('env', true);
};
@@ -96,75 +63,7 @@ const AdvanceConfig = () => {
options={modelCategories}
>
-
- {scheduleType === ScheduleValueMap.Auto && (
- <>
- name="placement_strategy">
-
- }
- >
-
-
-
- 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();
- }
- })
- ]}
- >
-
- {intl.formatMessage({
- id: 'resources.form.workerSelector.description'
- })}
-
- }
- >
-
-
- >
- )}
-
name="env">
= forwardRef((props, ref) => {
label: intl.formatMessage({ id: 'common.title.basicInfo' }),
field: 'name'
},
+ {
+ value: 'scheduling',
+ label: intl.formatMessage({ id: 'models.form.scheduling' }),
+ field: 'scheduleType'
+ },
{
value: 'performance',
label: intl.formatMessage({ id: 'models.form.performance' }),
@@ -378,18 +384,22 @@ const DataForm: React.FC = forwardRef((props, ref) => {
accordion={false}
onChange={handleOnCollapseChange}
items={[
+ {
+ key: 'scheduling',
+ label: intl.formatMessage({ id: 'models.form.scheduling' }),
+ forceRender: true,
+ children:
+ },
{
key: 'performance',
label: intl.formatMessage({ id: 'models.form.performance' }),
forceRender: true,
- extra: ,
children:
},
{
key: 'advanced',
label: intl.formatMessage({ id: 'resources.form.advanced' }),
forceRender: true,
- extra: ,
children:
}
]}
diff --git a/src/pages/llmodels/forms/schedule-type.tsx b/src/pages/llmodels/forms/schedule-type.tsx
index ce48eb95..8c7841dd 100644
--- a/src/pages/llmodels/forms/schedule-type.tsx
+++ b/src/pages/llmodels/forms/schedule-type.tsx
@@ -1,3 +1,5 @@
+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';
@@ -5,11 +7,29 @@ import TooltipList from '@/components/tooltip-list';
import useAppUtils from '@/hooks/use-app-utils';
import { useIntl } from '@umijs/max';
import { Form } from 'antd';
+import _ from 'lodash';
import React from 'react';
import GPUCard from '../components/gpu-card';
-import { gpusCountTypeMap, scheduleList, ScheduleValueMap } from '../config';
+import {
+ gpusCountTypeMap,
+ placementStrategyOptions,
+ scheduleList,
+ ScheduleValueMap
+} from '../config';
import { backendOptionsMap } from '../config/backend-parameters';
import { useFormContext } from '../config/form-context';
+import { FormData } from '../config/types';
+
+const placementStrategyTips = [
+ {
+ title: 'Spread',
+ tips: 'resources.form.spread.tips'
+ },
+ {
+ title: 'Binpack',
+ tips: 'resources.form.binpack.tips'
+ }
+];
const scheduleTypeTips = [
{
@@ -47,11 +67,12 @@ const gpuAllocateTypeTips = [
const ScheduleTypeForm: React.FC = () => {
const intl = useIntl();
- const { onValuesChange, gpuOptions } = useFormContext();
+ const { onValuesChange, gpuOptions, workerLabelOptions } = 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 handleScheduleTypeChange = (value: string) => {
if (value === ScheduleValueMap.Auto) {
@@ -105,9 +126,32 @@ const ScheduleTypeForm: React.FC = () => {
}
};
+ 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 handleWorkerLabelsChange = (labels: Record) => {
+ form.setFieldValue('worker_selector', labels);
+ };
+
+ const handleSelectorOnBlur = () => {
+ onSelectorChange('worker_selector');
+ };
+
+ const handleDeleteWorkerSelector = (index: number) => {
+ onValuesChange?.({}, form.getFieldsValue());
+ };
+
return (
<>
-
+
{
)}
>
)}
+ {scheduleType === ScheduleValueMap.Auto && (
+ <>
+ name="placement_strategy">
+
+ }
+ >
+
+
+
+ name="worker_selector"
+ rules={[
+ ({ getFieldValue }) => ({
+ validator(rule, value) {
+ if (
+ 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();
+ }
+ })
+ ]}
+ >
+
+ {intl.formatMessage({
+ id: 'resources.form.workerSelector.description'
+ })}
+
+ }
+ >
+
+
+ >
+ )}
>
);
};