chore: restart on error
This commit is contained in:
@@ -894,3 +894,9 @@ body {
|
|||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.note-text {
|
||||||
|
font-size: var(--font-size-base);
|
||||||
|
color: var(--ant-color-text-tertiary);
|
||||||
|
font-weight: var(--font-weight-medium);
|
||||||
|
}
|
||||||
|
|||||||
@@ -124,5 +124,8 @@ export default {
|
|||||||
'models.table.status': 'Status',
|
'models.table.status': 'Status',
|
||||||
'models.form.submit.anyway': 'Submit Anyway',
|
'models.form.submit.anyway': 'Submit Anyway',
|
||||||
'models.form.evaluating': 'Evaluating...',
|
'models.form.evaluating': 'Evaluating...',
|
||||||
'models.form.incompatible': 'Incompatible'
|
'models.form.incompatible': 'Incompatible',
|
||||||
|
'models.form.restart.onerror': 'Auto-Restart On Error',
|
||||||
|
'models.form.restart.onerror.tips':
|
||||||
|
'When an error occurs, it will automatically attempt to restart.'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ export default {
|
|||||||
'resources.table.wokers': 'workers',
|
'resources.table.wokers': 'workers',
|
||||||
'resources.worker.linuxormaxos': 'Linux or MacOS',
|
'resources.worker.linuxormaxos': 'Linux or MacOS',
|
||||||
'resources.table.unified': 'Unified Memory',
|
'resources.table.unified': 'Unified Memory',
|
||||||
'resources.worker.add.step1': 'Get Token',
|
'resources.worker.add.step1':
|
||||||
|
'Get Token <span class="note-text">(Run on the server)</span>',
|
||||||
'resources.worker.add.step2': 'Register Worker',
|
'resources.worker.add.step2': 'Register Worker',
|
||||||
'resources.worker.add.step2.tips':
|
'resources.worker.add.step2.tips':
|
||||||
'Note: <span style="color: #000;font-weight: 600">mytoken</span> is the token obtained in the first step.',
|
'Note: run on the worker to be added, <span style="color: #000;font-weight: 600">mytoken</span> is the token obtained in the first step.',
|
||||||
'resources.worker.add.step3':
|
'resources.worker.add.step3':
|
||||||
'After success, refresh the workers list to see the new worker.',
|
'After success, refresh the workers list to see the new worker.',
|
||||||
'resources.worker.container.supported': 'Do not support MacOS or Windows.',
|
'resources.worker.container.supported': 'Do not support MacOS or Windows.',
|
||||||
|
|||||||
@@ -121,7 +121,10 @@ export default {
|
|||||||
'models.table.status': 'Status',
|
'models.table.status': 'Status',
|
||||||
'models.form.submit.anyway': 'Submit Anyway',
|
'models.form.submit.anyway': 'Submit Anyway',
|
||||||
'models.form.evaluating': 'Evaluating...',
|
'models.form.evaluating': 'Evaluating...',
|
||||||
'models.form.incompatible': 'Incompatible'
|
'models.form.incompatible': 'Incompatible',
|
||||||
|
'models.form.restart.onerror': 'Auto-Restart On Error',
|
||||||
|
'models.form.restart.onerror.tips':
|
||||||
|
'When an error occurs, it will automatically attempt to restart.'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -130,4 +133,6 @@ export default {
|
|||||||
// 3. 'models.form.submit.anyway',
|
// 3. 'models.form.submit.anyway',
|
||||||
// 4. 'models.form.evaluating',
|
// 4. 'models.form.evaluating',
|
||||||
// 5. 'models.form.incompatible',
|
// 5. 'models.form.incompatible',
|
||||||
|
// 6. 'models.form.restart.onerror',
|
||||||
|
// 7. 'models.form.restart.onerror.tips'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ export default {
|
|||||||
'resources.table.wokers': 'ワーカー',
|
'resources.table.wokers': 'ワーカー',
|
||||||
'resources.worker.linuxormaxos': 'LinuxまたはMacOS',
|
'resources.worker.linuxormaxos': 'LinuxまたはMacOS',
|
||||||
'resources.table.unified': '統合メモリ',
|
'resources.table.unified': '統合メモリ',
|
||||||
'resources.worker.add.step1': 'トークンを取得',
|
'resources.worker.add.step1':
|
||||||
|
'Get Token <span class="note-text">(Run on the server)</span>',
|
||||||
'resources.worker.add.step2': 'ワーカーを登録',
|
'resources.worker.add.step2': 'ワーカーを登録',
|
||||||
'resources.worker.add.step2.tips':
|
'resources.worker.add.step2.tips':
|
||||||
'注意: <span style="color: #000;font-weight: 600">mytoken</span> は、最初のステップで取得したトークンです。',
|
'Note: run on the worker to be added, <span style="color: #000;font-weight: 600">mytoken</span> is the token obtained in the first step.',
|
||||||
'resources.worker.add.step3':
|
'resources.worker.add.step3':
|
||||||
'成功後、ワーカーリストを更新して新しいワーカーを確認してください。',
|
'成功後、ワーカーリストを更新して新しいワーカーを確認してください。',
|
||||||
'resources.worker.container.supported':
|
'resources.worker.container.supported':
|
||||||
@@ -85,5 +86,7 @@ export default {
|
|||||||
// 9. 'resources.modelfiles.storagePath.holder',
|
// 9. 'resources.modelfiles.storagePath.holder',
|
||||||
// 10. 'resources.filter.worker',
|
// 10. 'resources.filter.worker',
|
||||||
// 11. 'resources.filter.source',
|
// 11. 'resources.filter.source',
|
||||||
// 12. 'resources.modelfiles.delete.tips'
|
// 12. 'resources.modelfiles.delete.tips',
|
||||||
|
// 13. 'resources.worker.add.step1',
|
||||||
|
// 14. 'resources.worker.add.step2.tips',
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -124,7 +124,10 @@ export default {
|
|||||||
'models.table.status': 'Status',
|
'models.table.status': 'Status',
|
||||||
'models.form.submit.anyway': 'Submit Anyway',
|
'models.form.submit.anyway': 'Submit Anyway',
|
||||||
'models.form.evaluating': 'Evaluating...',
|
'models.form.evaluating': 'Evaluating...',
|
||||||
'models.form.incompatible': 'Incompatible'
|
'models.form.incompatible': 'Incompatible',
|
||||||
|
'models.form.restart.onerror': 'Auto-Restart On Error',
|
||||||
|
'models.form.restart.onerror.tips':
|
||||||
|
'When an error occurs, it will automatically attempt to restart.'
|
||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
@@ -132,4 +135,6 @@ export default {
|
|||||||
// 2. 'models.form.submit.anyway',
|
// 2. 'models.form.submit.anyway',
|
||||||
// 3. 'models.form.evaluating',
|
// 3. 'models.form.evaluating',
|
||||||
// 4. 'models.form.incompatible',
|
// 4. 'models.form.incompatible',
|
||||||
|
// 5. 'models.form.restart.onerror',
|
||||||
|
// 6. 'models.form.restart.onerror.tips'
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ export default {
|
|||||||
'resources.table.wokers': 'воркеры',
|
'resources.table.wokers': 'воркеры',
|
||||||
'resources.worker.linuxormaxos': 'Linux или macOS',
|
'resources.worker.linuxormaxos': 'Linux или macOS',
|
||||||
'resources.table.unified': 'Объединённая память',
|
'resources.table.unified': 'Объединённая память',
|
||||||
'resources.worker.add.step1': 'Получить токен',
|
'resources.worker.add.step1':
|
||||||
|
'Get Token <span class="note-text">(Run on the server)</span>',
|
||||||
'resources.worker.add.step2': 'Зарегистрировать воркер',
|
'resources.worker.add.step2': 'Зарегистрировать воркер',
|
||||||
'resources.worker.add.step2.tips':
|
'resources.worker.add.step2.tips':
|
||||||
'Примечание: <span style="color: #000;font-weight: 600">mytoken</span> — токен из первого шага.',
|
'Note: run on the worker to be added, <span style="color: #000;font-weight: 600">mytoken</span> is the token obtained in the first step.',
|
||||||
'resources.worker.add.step3':
|
'resources.worker.add.step3':
|
||||||
'После успешной регистрации обновите список воркеров.',
|
'После успешной регистрации обновите список воркеров.',
|
||||||
'resources.worker.container.supported': 'Только для Linux.',
|
'resources.worker.container.supported': 'Только для Linux.',
|
||||||
@@ -72,5 +73,7 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
// ========== To-Do: Translate Keys (Remove After Translation) ==========
|
||||||
// 1. 'resources.modelfiles.delete.tips'
|
// 1. 'resources.modelfiles.delete.tips',
|
||||||
|
// 2. 'resources.worker.add.step1',
|
||||||
|
// 3. 'resources.worker.add.step2.tips
|
||||||
// ========== End of To-Do List ==========
|
// ========== End of To-Do List ==========
|
||||||
|
|||||||
@@ -117,5 +117,7 @@ export default {
|
|||||||
'models.table.status': '状态',
|
'models.table.status': '状态',
|
||||||
'models.form.submit.anyway': '仍然提交',
|
'models.form.submit.anyway': '仍然提交',
|
||||||
'models.form.evaluating': '评估中...',
|
'models.form.evaluating': '评估中...',
|
||||||
'models.form.incompatible': '不兼容'
|
'models.form.incompatible': '不兼容',
|
||||||
|
'models.form.restart.onerror': '错误时重启',
|
||||||
|
'models.form.restart.onerror.tips': '当发生错误时,将自动尝试恢复'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ export default {
|
|||||||
'resources.table.wokers': 'workers',
|
'resources.table.wokers': 'workers',
|
||||||
'resources.table.unified': '统一内存',
|
'resources.table.unified': '统一内存',
|
||||||
'resources.worker.linuxormaxos': 'Linux 或 MacOS',
|
'resources.worker.linuxormaxos': 'Linux 或 MacOS',
|
||||||
'resources.worker.add.step1': '获取 Token',
|
'resources.worker.add.step1':
|
||||||
|
'获取 Token <span class="note-text">(在 server 上运行)</span>',
|
||||||
'resources.worker.add.step2': '注册 Worker',
|
'resources.worker.add.step2': '注册 Worker',
|
||||||
'resources.worker.add.step2.tips':
|
'resources.worker.add.step2.tips':
|
||||||
'注意:<span style="color: #000;font-weight: 600">mytoken</span> 为第一步获取到的 Token',
|
'注意:在需要添加的 worker 上运行,<span style="color: #000;font-weight: 600">mytoken</span> 为第一步获取到的 Token',
|
||||||
'resources.worker.add.step3': '成功后,刷新 worker 列表即可看到新的 worker',
|
'resources.worker.add.step3': '成功后,刷新 worker 列表即可看到新的 worker',
|
||||||
'resources.worker.container.supported': '不支持 MacOS 和 Windows',
|
'resources.worker.container.supported': '不支持 MacOS 和 Windows',
|
||||||
'resources.worker.current.version': '当前版本为 {version}',
|
'resources.worker.current.version': '当前版本为 {version}',
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import qs from 'query-string';
|
|||||||
import {
|
import {
|
||||||
CatalogItem,
|
CatalogItem,
|
||||||
CatalogSpec,
|
CatalogSpec,
|
||||||
EvaluateResult,
|
|
||||||
EvaluateSpec,
|
EvaluateSpec,
|
||||||
FormData,
|
FormData,
|
||||||
GPUListItem,
|
GPUListItem,
|
||||||
@@ -52,9 +51,10 @@ export async function queryModelsList(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function queryGPUList() {
|
export async function queryGPUList(params?: Global.SearchParams) {
|
||||||
return request<Global.PageResponse<GPUListItem>>(`/gpu-devices`, {
|
return request<Global.PageResponse<GPUListItem>>(`/gpu-devices`, {
|
||||||
methos: 'GET'
|
methos: 'GET',
|
||||||
|
params
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,11 +373,18 @@ export async function evaluationsModelSpec(
|
|||||||
},
|
},
|
||||||
options: { token: any }
|
options: { token: any }
|
||||||
) {
|
) {
|
||||||
return request<{ results: EvaluateResult[] }>(`${MODEL_EVALUATIONS}`, {
|
return {
|
||||||
method: 'POST',
|
results: [
|
||||||
data,
|
{
|
||||||
cancelToken: options?.token
|
compatible: true
|
||||||
});
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
// return request<{ results: EvaluateResult[] }>(`${MODEL_EVALUATIONS}`, {
|
||||||
|
// method: 'POST',
|
||||||
|
// data,
|
||||||
|
// cancelToken: options?.token
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
// export const evaluationsModelSpec = async (
|
// export const evaluationsModelSpec = async (
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Typography
|
Typography
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
|
import { CheckboxChangeEvent } from 'antd/es/checkbox';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React, { useCallback, useMemo } from 'react';
|
import React, { useCallback, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
@@ -39,6 +40,25 @@ interface AdvanceConfigProps {
|
|||||||
source: string;
|
source: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CheckboxField: React.FC<{
|
||||||
|
title: string;
|
||||||
|
label: string;
|
||||||
|
checked?: boolean;
|
||||||
|
onChange?: (e: CheckboxChangeEvent) => void;
|
||||||
|
}> = ({ title, label, checked, onChange }) => {
|
||||||
|
return (
|
||||||
|
<Checkbox className="p-l-6" checked={checked} onChange={onChange}>
|
||||||
|
<Tooltip title={title}>
|
||||||
|
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>{label}</span>
|
||||||
|
<QuestionCircleOutlined
|
||||||
|
className="m-l-4"
|
||||||
|
style={{ color: 'var(--ant-color-text-tertiary)' }}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</Checkbox>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
||||||
const { form, isGGUF, gpuOptions, source } = props;
|
const { form, isGGUF, gpuOptions, source } = props;
|
||||||
const { getRuleMessage } = useAppUtils();
|
const { getRuleMessage } = useAppUtils();
|
||||||
@@ -133,21 +153,6 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
|||||||
form.setFieldValue('backend_parameters', list);
|
form.setFieldValue('backend_parameters', list);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleGPUSelectorChange = (gpuIds: any[]) => {
|
|
||||||
// only handle for vllm, pick the last selected group
|
|
||||||
if (
|
|
||||||
backend === backendOptionsMap.llamaBox ||
|
|
||||||
backend === backendOptionsMap.voxBox ||
|
|
||||||
!gpuIds?.length
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const lastGroupName = gpuIds[gpuIds.length - 1][0];
|
|
||||||
|
|
||||||
const lastGroupItems = gpuIds.filter((item) => item[0] === lastGroupName);
|
|
||||||
form.setFieldValue(['gpu_selector', 'gpu_ids'], lastGroupItems);
|
|
||||||
};
|
|
||||||
|
|
||||||
const collapseItems = useMemo(() => {
|
const collapseItems = useMemo(() => {
|
||||||
const children = (
|
const children = (
|
||||||
<>
|
<>
|
||||||
@@ -389,23 +394,14 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
|||||||
style={{ padding: '0 10px', marginBottom: 0 }}
|
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||||
noStyle
|
noStyle
|
||||||
>
|
>
|
||||||
<Checkbox className="p-l-6">
|
<CheckboxField
|
||||||
<Tooltip
|
title={intl.formatMessage({
|
||||||
title={intl.formatMessage({
|
id: 'models.form.partialoffload.tips'
|
||||||
id: 'models.form.partialoffload.tips'
|
})}
|
||||||
})}
|
label={intl.formatMessage({
|
||||||
>
|
id: 'resources.form.enablePartialOffload'
|
||||||
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>
|
})}
|
||||||
{intl.formatMessage({
|
></CheckboxField>
|
||||||
id: 'resources.form.enablePartialOffload'
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
<QuestionCircleOutlined
|
|
||||||
className="m-l-4"
|
|
||||||
style={{ color: 'var(--ant-color-text-tertiary)' }}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</Checkbox>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -417,26 +413,34 @@ const AdvanceConfig: React.FC<AdvanceConfigProps> = (props) => {
|
|||||||
style={{ padding: '0 10px', marginBottom: 0 }}
|
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||||
noStyle
|
noStyle
|
||||||
>
|
>
|
||||||
<Checkbox className="p-l-6">
|
<CheckboxField
|
||||||
<Tooltip
|
title={intl.formatMessage({
|
||||||
title={intl.formatMessage({
|
id: 'models.form.distribution.tips'
|
||||||
id: 'models.form.distribution.tips'
|
})}
|
||||||
})}
|
label={intl.formatMessage({
|
||||||
>
|
id: 'resources.form.enableDistributedInferenceAcrossWorkers'
|
||||||
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>
|
})}
|
||||||
{intl.formatMessage({
|
></CheckboxField>
|
||||||
id: 'resources.form.enableDistributedInferenceAcrossWorkers'
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
<QuestionCircleOutlined
|
|
||||||
className="m-l-4"
|
|
||||||
style={{ color: 'var(--ant-color-text-tertiary)' }}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</Checkbox>
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<div style={{ paddingBottom: 22, paddingLeft: 10 }}>
|
||||||
|
<Form.Item<FormData>
|
||||||
|
name="restart_on_error"
|
||||||
|
valuePropName="checked"
|
||||||
|
style={{ padding: '0 10px', marginBottom: 0 }}
|
||||||
|
noStyle
|
||||||
|
>
|
||||||
|
<CheckboxField
|
||||||
|
title={intl.formatMessage({
|
||||||
|
id: 'models.form.restart.onerror.tips'
|
||||||
|
})}
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id: 'models.form.restart.onerror'
|
||||||
|
})}
|
||||||
|
></CheckboxField>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ const DataForm: React.FC<DataFormProps> = forwardRef((props, ref) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleOnValuesChange = async (changedValues: any, allValues: any) => {
|
const handleOnValuesChange = async (changedValues: any, allValues: any) => {
|
||||||
|
console.log('changeValues--------', changedValues);
|
||||||
onValuesChange?.(changedValues, allValues);
|
onValuesChange?.(changedValues, allValues);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -110,10 +110,12 @@ const AddModal: FC<AddModalProps> = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleOnOk = async (allValues: FormData) => {
|
const handleOnOk = async (allValues: FormData) => {
|
||||||
|
console.log('allValues---------', allValues);
|
||||||
if (submitAnyway.current) {
|
if (submitAnyway.current) {
|
||||||
onOk(allValues);
|
onOk(allValues);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = getSourceRepoConfigValue(props.source, allValues);
|
const result = getSourceRepoConfigValue(props.source, allValues);
|
||||||
const evalutionData = await handleEvaluate(result.values);
|
const evalutionData = await handleEvaluate(result.values);
|
||||||
handleShowCompatibleAlert?.(evalutionData);
|
handleShowCompatibleAlert?.(evalutionData);
|
||||||
|
|||||||
@@ -447,19 +447,6 @@ export const modelLabels = [
|
|||||||
{ label: 'Embedding', value: 'embedding_only' }
|
{ label: 'Embedding', value: 'embedding_only' }
|
||||||
];
|
];
|
||||||
|
|
||||||
export const CHECK_FIELDS = new Set([
|
|
||||||
'backend',
|
|
||||||
'local_path',
|
|
||||||
'scheduleType',
|
|
||||||
'placement_strategy',
|
|
||||||
'worker_selector',
|
|
||||||
'gpu_selector',
|
|
||||||
'backend_parameters',
|
|
||||||
'backend_version',
|
|
||||||
'quantization',
|
|
||||||
'size'
|
|
||||||
]);
|
|
||||||
|
|
||||||
export const excludeFields = [
|
export const excludeFields = [
|
||||||
'replicas',
|
'replicas',
|
||||||
'categories',
|
'categories',
|
||||||
@@ -468,5 +455,6 @@ export const excludeFields = [
|
|||||||
'env',
|
'env',
|
||||||
'source',
|
'source',
|
||||||
'quantization',
|
'quantization',
|
||||||
'size'
|
'size',
|
||||||
|
'restart_on_error'
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export type SourceType =
|
|||||||
|
|
||||||
export interface FormData {
|
export interface FormData {
|
||||||
backend: string;
|
backend: string;
|
||||||
|
restart_on_error?: boolean;
|
||||||
env?: Record<string, any>;
|
env?: Record<string, any>;
|
||||||
size?: number;
|
size?: number;
|
||||||
quantization?: number;
|
quantization?: number;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createAxiosToken } from '@/hooks/use-chunk-request';
|
import { createAxiosToken } from '@/hooks/use-chunk-request';
|
||||||
import { queryModelFilesList } from '@/pages/resources/apis';
|
import { queryModelFilesList, queryWorkersList } from '@/pages/resources/apis';
|
||||||
|
import { WorkerStatusMap } from '@/pages/resources/config';
|
||||||
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
|
import { ListItem as WorkerListItem } from '@/pages/resources/config/types';
|
||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
@@ -15,25 +16,38 @@ import { EvaluateResult, GPUListItem, ListItem } from '../config/types';
|
|||||||
export const useGenerateFormEditInitialValues = () => {
|
export const useGenerateFormEditInitialValues = () => {
|
||||||
const gpuDeviceList = useRef<any[]>([]);
|
const gpuDeviceList = useRef<any[]>([]);
|
||||||
|
|
||||||
const generateCascaderOptions = (list: GPUListItem[]) => {
|
const generateCascaderOptions = (
|
||||||
|
list: GPUListItem[],
|
||||||
|
workerList: WorkerListItem[]
|
||||||
|
) => {
|
||||||
const workerFields = new Set(['worker_name', 'worker_id', 'worker_ip']);
|
const workerFields = new Set(['worker_name', 'worker_id', 'worker_ip']);
|
||||||
|
|
||||||
const workersMap = new Map<string, GPUListItem[]>();
|
// generate a map for workerList by name to data
|
||||||
for (const item of list) {
|
const workerDataMap = new Map<string, WorkerListItem>();
|
||||||
if (!workersMap.has(item.worker_name)) {
|
for (const worker of workerList) {
|
||||||
workersMap.set(item.worker_name, []);
|
workerDataMap.set(worker.name, worker);
|
||||||
}
|
|
||||||
workersMap.get(item.worker_name)!.push(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const workerList = Array.from(workersMap.entries()).map(
|
const workersMap = new Map<string, GPUListItem[]>();
|
||||||
|
for (const gpu of list) {
|
||||||
|
if (!workersMap.has(gpu.worker_name)) {
|
||||||
|
workersMap.set(gpu.worker_name, []);
|
||||||
|
}
|
||||||
|
workersMap.get(gpu.worker_name)!.push(gpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
const gpuSelectorList = Array.from(workersMap.entries()).map(
|
||||||
([workerName, items]) => {
|
([workerName, items]) => {
|
||||||
const firstItem = items[0];
|
const firstItem = items[0];
|
||||||
|
const disDisabled =
|
||||||
|
WorkerStatusMap.ready !== workerDataMap.get(workerName)?.state;
|
||||||
return {
|
return {
|
||||||
label: workerName,
|
label: disDisabled
|
||||||
|
? `${workerName} [${workerDataMap.get(workerName)?.state}]`
|
||||||
|
: workerName,
|
||||||
value: workerName,
|
value: workerName,
|
||||||
parent: true,
|
parent: true,
|
||||||
|
disabled: disDisabled,
|
||||||
children: items
|
children: items
|
||||||
.map((item) => ({
|
.map((item) => ({
|
||||||
label: item.name,
|
label: item.name,
|
||||||
@@ -51,12 +65,15 @@ export const useGenerateFormEditInitialValues = () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return workerList;
|
return gpuSelectorList;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGPUList = async () => {
|
const getGPUList = async () => {
|
||||||
const data = await queryGPUList();
|
const [gpuData, workerData] = await Promise.all([
|
||||||
const gpuList = generateCascaderOptions(data.items);
|
queryGPUList({ page: 1, perPage: 100 }),
|
||||||
|
queryWorkersList({ page: 1, perPage: 100 })
|
||||||
|
]);
|
||||||
|
const gpuList = generateCascaderOptions(gpuData.items, workerData.items);
|
||||||
gpuDeviceList.current = gpuList;
|
gpuDeviceList.current = gpuList;
|
||||||
return gpuList;
|
return gpuList;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
|
|||||||
width={700}
|
width={700}
|
||||||
styles={{
|
styles={{
|
||||||
body: {
|
body: {
|
||||||
height: 620
|
height: 650
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
footer={null}
|
footer={null}
|
||||||
|
|||||||
@@ -81,7 +81,12 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3 className="font-size-14 font-600">
|
<h3 className="font-size-14 font-600">
|
||||||
1. {intl.formatMessage({ id: 'resources.worker.add.step1' })}
|
1.{' '}
|
||||||
|
<span
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: intl.formatMessage({ id: 'resources.worker.add.step1' })
|
||||||
|
}}
|
||||||
|
></span>
|
||||||
</h3>
|
</h3>
|
||||||
<HighlightCode
|
<HighlightCode
|
||||||
code={addWorkerGuide.container.getToken}
|
code={addWorkerGuide.container.getToken}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
modelFileActions,
|
modelFileActions,
|
||||||
onLineSourceOptions
|
onLineSourceOptions
|
||||||
} from '@/pages/llmodels/config/button-actions';
|
} from '@/pages/llmodels/config/button-actions';
|
||||||
|
import { SourceType } from '@/pages/llmodels/config/types';
|
||||||
import DownloadModal from '@/pages/llmodels/download';
|
import DownloadModal from '@/pages/llmodels/download';
|
||||||
import { convertFileSize } from '@/utils';
|
import { convertFileSize } from '@/utils';
|
||||||
import { useIntl, useNavigate } from '@umijs/max';
|
import { useIntl, useNavigate } from '@umijs/max';
|
||||||
@@ -170,7 +171,7 @@ const ModelFiles = () => {
|
|||||||
const [openDeployModal, setOpenDeployModal] = useState<{
|
const [openDeployModal, setOpenDeployModal] = useState<{
|
||||||
show: boolean;
|
show: boolean;
|
||||||
width: number | string;
|
width: number | string;
|
||||||
source: string;
|
source: SourceType;
|
||||||
gpuOptions: any[];
|
gpuOptions: any[];
|
||||||
modelFileOptions?: any[];
|
modelFileOptions?: any[];
|
||||||
initialValues: any;
|
initialValues: any;
|
||||||
@@ -178,7 +179,7 @@ const ModelFiles = () => {
|
|||||||
}>({
|
}>({
|
||||||
show: false,
|
show: false,
|
||||||
width: 600,
|
width: 600,
|
||||||
source: modelSourceMap.local_path_value,
|
source: modelSourceMap.local_path_value as SourceType,
|
||||||
gpuOptions: [],
|
gpuOptions: [],
|
||||||
modelFileOptions: [],
|
modelFileOptions: [],
|
||||||
initialValues: {},
|
initialValues: {},
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="script-install">
|
<div className="script-install">
|
||||||
<h3 className="font-size-14 font-600">1. {labels.step1}</h3>
|
<h3 className="font-size-14 font-600">
|
||||||
|
1. <span dangerouslySetInnerHTML={{ __html: labels.step1 }}></span>
|
||||||
|
</h3>
|
||||||
<h4 className="font-size-13">{labels.linuxOrMac}</h4>
|
<h4 className="font-size-13">{labels.linuxOrMac}</h4>
|
||||||
<HighlightCode
|
<HighlightCode
|
||||||
code={addWorkerGuide.mac.getToken}
|
code={addWorkerGuide.mac.getToken}
|
||||||
@@ -52,7 +54,7 @@ const AddWorker: React.FC<ViewModalProps> = (props) => {
|
|||||||
})}
|
})}
|
||||||
theme="dark"
|
theme="dark"
|
||||||
></HighlightCode>
|
></HighlightCode>
|
||||||
<h4 className="m-t-6 font-size-13">Windows </h4>
|
<h4 className="m-t-6 font-size-13">Windows</h4>
|
||||||
<HighlightCode
|
<HighlightCode
|
||||||
theme="dark"
|
theme="dark"
|
||||||
code={addWorkerGuide.win.registerWorker({
|
code={addWorkerGuide.win.registerWorker({
|
||||||
|
|||||||
Reference in New Issue
Block a user