fix: gpu selector issues
This commit is contained in:
@@ -60,8 +60,7 @@ const OptionNodes = (props: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
let width: any = {
|
let width: any = {
|
||||||
maxWidth: 140,
|
maxWidth: 140
|
||||||
minWidth: 140
|
|
||||||
};
|
};
|
||||||
if (!data.parent) {
|
if (!data.parent) {
|
||||||
width = undefined;
|
width = undefined;
|
||||||
|
|||||||
@@ -21,6 +21,12 @@ const Header = styled.div`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const ItemInfo = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
white-space: break-spaces;
|
||||||
|
`;
|
||||||
|
|
||||||
const Description = styled.div`
|
const Description = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -60,7 +66,7 @@ const GPUCard: React.FC<{
|
|||||||
description={
|
description={
|
||||||
info || (
|
info || (
|
||||||
<>
|
<>
|
||||||
<span>
|
<ItemInfo>
|
||||||
{intl.formatMessage({ id: 'resources.table.vram' })}(
|
{intl.formatMessage({ id: 'resources.table.vram' })}(
|
||||||
{intl.formatMessage({ id: 'resources.table.used' })}/
|
{intl.formatMessage({ id: 'resources.table.used' })}/
|
||||||
{intl.formatMessage({ id: 'resources.table.total' })}):{' '}
|
{intl.formatMessage({ id: 'resources.table.total' })}):{' '}
|
||||||
@@ -70,8 +76,8 @@ const GPUCard: React.FC<{
|
|||||||
)}{' '}
|
)}{' '}
|
||||||
/ {convertFileSize(data?.memory?.total || 0)}
|
/ {convertFileSize(data?.memory?.total || 0)}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</ItemInfo>
|
||||||
<span>
|
<ItemInfo>
|
||||||
<span>
|
<span>
|
||||||
{intl.formatMessage({ id: 'resources.table.gpuutilization' })}
|
{intl.formatMessage({ id: 'resources.table.gpuutilization' })}
|
||||||
:{' '}
|
:{' '}
|
||||||
@@ -80,7 +86,7 @@ const GPUCard: React.FC<{
|
|||||||
? _.round(data?.memory?.utilization_rate || 0, 2)
|
? _.round(data?.memory?.utilization_rate || 0, 2)
|
||||||
: _.round(data.memory?.allocated / data.memory?.total, 2) * 100}
|
: _.round(data.memory?.allocated / data.memory?.total, 2) * 100}
|
||||||
%
|
%
|
||||||
</span>
|
</ItemInfo>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { PageActionType } from '@/config/types';
|
import { PageActionType } from '@/config/types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { BackendOption, DeployFormKey } from './types';
|
import { BackendOption, DeployFormKey, FormData } from './types';
|
||||||
|
|
||||||
type EmptyObject = Record<never, never>;
|
type EmptyObject = Record<never, never>;
|
||||||
|
|
||||||
@@ -17,10 +17,11 @@ interface FormContextProps {
|
|||||||
isGGUF?: boolean;
|
isGGUF?: boolean;
|
||||||
formKey: DeployFormKey;
|
formKey: DeployFormKey;
|
||||||
source: string;
|
source: string;
|
||||||
pageAction: PageActionType;
|
action: PageActionType;
|
||||||
gpuOptions: CascaderOption[];
|
gpuOptions: CascaderOption[];
|
||||||
workerLabelOptions: CascaderOption[];
|
workerLabelOptions: CascaderOption[];
|
||||||
backendOptions: BackendOption[];
|
backendOptions: BackendOption[];
|
||||||
|
initialValues?: FormData; // for editing model
|
||||||
onValuesChange?: (changedValues: any, allValues: any) => void;
|
onValuesChange?: (changedValues: any, allValues: any) => void;
|
||||||
onBackendChange: (backend: string, option: any) => void;
|
onBackendChange: (backend: string, option: any) => void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const BackendFields: React.FC = () => {
|
|||||||
const {
|
const {
|
||||||
isGGUF,
|
isGGUF,
|
||||||
formKey,
|
formKey,
|
||||||
pageAction: action,
|
action,
|
||||||
source,
|
source,
|
||||||
gpuOptions,
|
gpuOptions,
|
||||||
onValuesChange,
|
onValuesChange,
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const SegmentedHeader = styled.div<{ $top?: number }>`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
interface DataFormProps {
|
interface DataFormProps {
|
||||||
initialValues?: any;
|
initialValues?: FormData;
|
||||||
ref?: any;
|
ref?: any;
|
||||||
source: SourceType;
|
source: SourceType;
|
||||||
action: PageActionType;
|
action: PageActionType;
|
||||||
@@ -323,10 +323,11 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
|||||||
isGGUF: isGGUF,
|
isGGUF: isGGUF,
|
||||||
formKey: formKey,
|
formKey: formKey,
|
||||||
source: props.source,
|
source: props.source,
|
||||||
pageAction: action,
|
action: action,
|
||||||
gpuOptions: gpuOptions,
|
gpuOptions: gpuOptions,
|
||||||
backendOptions: backendOptions,
|
backendOptions: backendOptions,
|
||||||
workerLabelOptions: workerLabelOptions,
|
workerLabelOptions: workerLabelOptions,
|
||||||
|
initialValues: initialValues,
|
||||||
onValuesChange: onValuesChange,
|
onValuesChange: onValuesChange,
|
||||||
onBackendChange: handleBackendChange
|
onBackendChange: handleBackendChange
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const HuggingFaceForm: React.FC = () => {
|
|||||||
const formInstance = Form.useFormInstance();
|
const formInstance = Form.useFormInstance();
|
||||||
const formCtx = useFormContext();
|
const formCtx = useFormContext();
|
||||||
const { getRuleMessage } = useAppUtils();
|
const { getRuleMessage } = useAppUtils();
|
||||||
const { formKey, pageAction, isGGUF, onValuesChange } = formCtx;
|
const { formKey, action, isGGUF, onValuesChange } = formCtx;
|
||||||
const source = Form.useWatch('source');
|
const source = Form.useWatch('source');
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -47,7 +47,7 @@ const HuggingFaceForm: React.FC = () => {
|
|||||||
<SealInput.Input
|
<SealInput.Input
|
||||||
label={intl.formatMessage({ id: 'models.form.repoid' })}
|
label={intl.formatMessage({ id: 'models.form.repoid' })}
|
||||||
required
|
required
|
||||||
disabled={pageAction === PageAction.CREATE}
|
disabled={action === PageAction.CREATE}
|
||||||
onBlur={handleOnBlur}
|
onBlur={handleOnBlur}
|
||||||
></SealInput.Input>
|
></SealInput.Input>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -58,7 +58,7 @@ const HuggingFaceForm: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<SealInput.Input
|
<SealInput.Input
|
||||||
label={intl.formatMessage({ id: 'models.form.filename' })}
|
label={intl.formatMessage({ id: 'models.form.filename' })}
|
||||||
disabled={pageAction === PageAction.CREATE}
|
disabled={action === PageAction.CREATE}
|
||||||
></SealInput.Input>
|
></SealInput.Input>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
@@ -78,7 +78,7 @@ const HuggingFaceForm: React.FC = () => {
|
|||||||
<SealInput.Input
|
<SealInput.Input
|
||||||
required
|
required
|
||||||
label={intl.formatMessage({ id: 'models.form.repoid' })}
|
label={intl.formatMessage({ id: 'models.form.repoid' })}
|
||||||
disabled={pageAction === PageAction.CREATE}
|
disabled={action === PageAction.CREATE}
|
||||||
onBlur={handleOnBlur}
|
onBlur={handleOnBlur}
|
||||||
></SealInput.Input>
|
></SealInput.Input>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
@@ -89,7 +89,7 @@ const HuggingFaceForm: React.FC = () => {
|
|||||||
>
|
>
|
||||||
<SealInput.Input
|
<SealInput.Input
|
||||||
label={intl.formatMessage({ id: 'models.form.filename' })}
|
label={intl.formatMessage({ id: 'models.form.filename' })}
|
||||||
disabled={pageAction === PageAction.CREATE}
|
disabled={action === PageAction.CREATE}
|
||||||
></SealInput.Input>
|
></SealInput.Input>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import SealInputNumber from '@/components/seal-form/input-number';
|
|||||||
import SealCascader from '@/components/seal-form/seal-cascader';
|
import SealCascader from '@/components/seal-form/seal-cascader';
|
||||||
import SealSelect from '@/components/seal-form/seal-select';
|
import SealSelect from '@/components/seal-form/seal-select';
|
||||||
import TooltipList from '@/components/tooltip-list';
|
import TooltipList from '@/components/tooltip-list';
|
||||||
|
import { PageAction } from '@/config';
|
||||||
import useAppUtils from '@/hooks/use-app-utils';
|
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';
|
||||||
@@ -67,7 +68,13 @@ const gpuAllocateTypeTips = [
|
|||||||
|
|
||||||
const ScheduleTypeForm: React.FC = () => {
|
const ScheduleTypeForm: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { onValuesChange, gpuOptions, workerLabelOptions } = useFormContext();
|
const {
|
||||||
|
onValuesChange,
|
||||||
|
action,
|
||||||
|
gpuOptions,
|
||||||
|
workerLabelOptions,
|
||||||
|
initialValues
|
||||||
|
} = useFormContext();
|
||||||
const { getRuleMessage } = useAppUtils();
|
const { getRuleMessage } = useAppUtils();
|
||||||
const form = Form.useFormInstance();
|
const form = Form.useFormInstance();
|
||||||
const scheduleType = Form.useWatch('scheduleType', form);
|
const scheduleType = Form.useWatch('scheduleType', form);
|
||||||
@@ -88,39 +95,41 @@ const ScheduleTypeForm: React.FC = () => {
|
|||||||
onValuesChange?.({}, form.getFieldsValue());
|
onValuesChange?.({}, form.getFieldsValue());
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBeforeGpuSelectorChange = (gpuIds: any[]) => {};
|
|
||||||
|
|
||||||
const handleGpuSelectorChange = (value: any[]) => {
|
const handleGpuSelectorChange = (value: any[]) => {
|
||||||
handleBeforeGpuSelectorChange(value);
|
if (value.length > 0) {
|
||||||
onValuesChange?.({}, form.getFieldsValue());
|
onValuesChange?.({}, form.getFieldsValue());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnStepReplicaStep = (
|
const handleOnStepReplicaStep = (
|
||||||
value: number,
|
value: number | string | null,
|
||||||
info: { offset: number; type: 'up' | 'down' }
|
info: { offset: number | string | null; type: 'up' | 'down' }
|
||||||
) => {
|
) => {
|
||||||
let newValue = value;
|
let newValue = value;
|
||||||
const isPowerOfTwo = (n: number) => (n & (n - 1)) === 0 && n !== 0; // check power of two
|
const isPowerOfTwo = (n: number) => (n & (n - 1)) === 0 && n !== 0; // check power of two
|
||||||
if (!isPowerOfTwo(value)) {
|
if (!isPowerOfTwo(value as number)) {
|
||||||
if (info.type === 'up') {
|
if (info.type === 'up') {
|
||||||
newValue = Math.pow(2, Math.ceil(Math.log2(value)));
|
newValue = Math.pow(2, Math.ceil(Math.log2(value as number)));
|
||||||
} else {
|
} else {
|
||||||
newValue = Math.pow(2, Math.floor(Math.log2(value)));
|
newValue = Math.pow(2, Math.floor(Math.log2(value as number)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], newValue);
|
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], newValue);
|
||||||
onValuesChange?.({}, form.getFieldsValue());
|
onValuesChange?.({}, form.getFieldsValue());
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnStepReplica = (value: number | null) => {
|
const handleOnStepReplica = async (value: number | string | null) => {
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, 200);
|
||||||
|
});
|
||||||
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], 1);
|
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isPowerOfTwo = (n: number) => (n & (n - 1)) === 0 && n !== 0; // check power of two
|
const isPowerOfTwo = (n: number) => (n & (n - 1)) === 0 && n !== 0; // check power of two
|
||||||
if (!isPowerOfTwo(value)) {
|
if (!isPowerOfTwo(value as number)) {
|
||||||
const newValue = Math.pow(2, Math.round(Math.log2(value)));
|
const newValue = Math.pow(2, Math.round(Math.log2(value as number)));
|
||||||
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], newValue);
|
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], newValue);
|
||||||
onValuesChange?.({}, form.getFieldsValue());
|
onValuesChange?.({}, form.getFieldsValue());
|
||||||
}
|
}
|
||||||
@@ -212,7 +221,13 @@ const ScheduleTypeForm: React.FC = () => {
|
|||||||
onChange={handleGpuSelectorChange}
|
onChange={handleGpuSelectorChange}
|
||||||
></SealCascader>
|
></SealCascader>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name="gpusCountType">
|
<Form.Item
|
||||||
|
name="gpusCountType"
|
||||||
|
hidden={
|
||||||
|
action === PageAction.EDIT &&
|
||||||
|
!!initialValues?.gpu_selector?.gpus_per_replica
|
||||||
|
}
|
||||||
|
>
|
||||||
<SealSelect
|
<SealSelect
|
||||||
onChange={handleGpusCountTypeChange}
|
onChange={handleGpusCountTypeChange}
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
|
|||||||
Reference in New Issue
Block a user