chore: add worker notes

This commit is contained in:
jialin
2025-11-04 17:19:20 +08:00
parent 23b7936924
commit e5733a7f6e
15 changed files with 318 additions and 137 deletions
@@ -1,4 +1,9 @@
import { BulbOutlined } from '@ant-design/icons';
import AlertInfoBlock from '@/components/alert-info/block';
import {
AddWorkerDockerNotes,
GPUDriverMap
} from '@/pages/resources/config/gpu-driver';
import { BulbOutlined, ExclamationCircleFilled } from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Alert } from 'antd';
import React from 'react';
@@ -9,6 +14,26 @@ import CheckEnvCommand from './check-env-command';
import RegisterClusterInner from './register-cluster-inner';
import SupportedGPUs from './support-gpus';
const StyledTag = styled.span`
display: inline-flex;
align-items: center;
justify-content: center;
margin-right: 8px;
`;
const NotesWrapper = styled.ol`
display: flex;
flex-direction: column;
gap: 8px;
font-weight: 400;
margin: 0 !important;
padding: 0 !important;
line-height: 1.2;
li {
margin-left: 12px !important;
}
`;
const Title = styled.div`
font-size: 16px;
font-weight: 600;
@@ -40,7 +65,6 @@ const Container = styled.div`
.command-info {
margin-top: 24px;
margin-bottom: 8px;
color: var(--ant-color-text-secondary);
}
`;
@@ -63,16 +87,20 @@ const AddWorkerStep: React.FC<AddModalProps> = ({
registrationInfo
}) => {
const intl = useIntl();
const [currentGPU, setCurrentGPU] = React.useState<string>('cuda');
React.useState<string>('cuda');
const [currentGPU, setCurrentGPU] = React.useState<string>(
GPUDriverMap.NVIDIA
);
React.useState<string>(GPUDriverMap.NVIDIA);
const [workerCommand, setWorkerCommand] = React.useState<Record<string, any>>(
{
label: 'NVIDIA',
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#nvidia-cuda'
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#nvidia-cuda',
notes: AddWorkerDockerNotes[GPUDriverMap.NVIDIA]
}
);
const handleSelectProvider = (value: string, item: any) => {
console.log('selected gpu driver:', value, item);
setCurrentGPU(value);
setWorkerCommand(item);
};
@@ -108,22 +136,44 @@ const AddWorkerStep: React.FC<AddModalProps> = ({
</Content>
<div className="command-info">
1. {intl.formatMessage({ id: 'cluster.create.checkEnv.tips' })}
<StyledTag>1.</StyledTag>
{intl.formatMessage({ id: 'cluster.create.checkEnv.tips' })}
</div>
<CheckEnvCommand provider={provider} currentGPU={currentGPU} />
{provider === ProviderValueMap.Kubernetes ? (
<>
<div className="command-info">
2. {intl.formatMessage({ id: 'clusters.create.register.tips' })}
<StyledTag>2.</StyledTag>
{intl.formatMessage({ id: 'clusters.create.register.tips' })}
</div>
<RegisterClusterInner registrationInfo={registrationInfo} />
</>
) : (
<>
<div className="command-info">
2. {intl.formatMessage({ id: 'clusters.create.addCommand.tips' })}
<StyledTag>2.</StyledTag>
{intl.formatMessage({ id: 'clusters.create.addCommand.tips' })}
</div>
<AlertInfoBlock
style={{ marginBottom: 16 }}
type="warning"
icon={<ExclamationCircleFilled />}
message={
workerCommand.notes?.length > 0 ? (
<NotesWrapper>
{workerCommand.notes.map((note: string, index: number) => (
<li
key={index}
dangerouslySetInnerHTML={{
__html: intl.formatMessage({ id: note })
}}
></li>
))}
</NotesWrapper>
) : null
}
></AlertInfoBlock>
<AddWorkerCommand
registrationInfo={registrationInfo}
currentGPU={currentGPU}
@@ -5,10 +5,25 @@ import iluvatarWEBP from '@/assets/logo/Iluvatar.png';
import metaxLogo from '@/assets/logo/metax.png';
import moorePNG from '@/assets/logo/moore _threads.png';
import IconFont from '@/components/icon-font';
import { GPUDriverMap } from '@/pages/resources/config/gpu-driver';
import {
AddWorkerDockerNotes,
GPUDriverMap
} from '@/pages/resources/config/gpu-driver';
import { useIntl } from '@umijs/max';
import styled from 'styled-components';
import ProviderCatalog from './provider-catalog';
const Box = styled.div`
.template-card-wrapper {
.template-card-inner {
line-height: 1;
.template-card-content {
font-size: 13px;
}
}
}
`;
const ProviderImage = ({ src, showBg }: { src: string; showBg?: boolean }) => {
return (
<img
@@ -41,6 +56,7 @@ const SupportedHardware: React.FC<SupportedHardwareProps> = ({
description: '',
key: GPUDriverMap.NVIDIA,
locale: false,
notes: AddWorkerDockerNotes[GPUDriverMap.NVIDIA],
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#nvidia-cuda',
icon: <IconFont type="icon-nvidia2" style={{ fontSize: 32 }} />
},
@@ -50,6 +66,7 @@ const SupportedHardware: React.FC<SupportedHardwareProps> = ({
value: GPUDriverMap.AMD,
key: GPUDriverMap.AMD,
locale: false,
notes: AddWorkerDockerNotes[GPUDriverMap.AMD],
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#amd-rocm',
icon: (
<IconFont
@@ -64,61 +81,72 @@ const SupportedHardware: React.FC<SupportedHardwareProps> = ({
value: GPUDriverMap.ASCEND,
key: GPUDriverMap.ASCEND,
locale: false,
notes: AddWorkerDockerNotes[GPUDriverMap.ASCEND],
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#ascend-cann',
icon: <ProviderImage src={ascendLogo} showBg />
},
{
label: intl.formatMessage({ id: 'vendor.hygon' }),
description: '',
description: 'common.tag.experimental',
value: GPUDriverMap.HYGON,
key: GPUDriverMap.HYGON,
locale: false,
notes: AddWorkerDockerNotes[GPUDriverMap.HYGON],
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#hygon-dtk',
icon: <ProviderImage src={hyponPNG} />
},
{
label: intl.formatMessage({ id: 'vendor.moorthreads' }),
description: '',
description: 'common.tag.experimental',
value: GPUDriverMap.MOORE_THREADS,
key: GPUDriverMap.MOORE_THREADS,
locale: false,
notes: AddWorkerDockerNotes[GPUDriverMap.MOORE_THREADS],
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#moore-threads-musa',
icon: <ProviderImage src={moorePNG} />
},
{
label: intl.formatMessage({ id: 'vendor.iluvatar' }),
description: '',
description: 'common.tag.experimental',
value: GPUDriverMap.ILUVATAR,
key: GPUDriverMap.ILUVATAR,
locale: false,
notes: AddWorkerDockerNotes[GPUDriverMap.ILUVATAR],
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#iluvatar-corex',
icon: <ProviderImage src={iluvatarWEBP} showBg />
},
{
label: intl.formatMessage({ id: 'vendor.cambricon' }),
description: 'common.tag.experimental',
value: GPUDriverMap.CAMBRICON,
key: GPUDriverMap.CAMBRICON,
locale: false,
notes: AddWorkerDockerNotes[GPUDriverMap.CAMBRICON],
link: 'https://docs.gpustack.ai/latest/installation/installation-requirements/#cambricon-mlu',
icon: <ProviderImage src={CambriconPNG} />
},
{
label: intl.formatMessage({ id: 'vendor.metax' }),
description: 'common.tag.experimental',
value: GPUDriverMap.METAX,
key: GPUDriverMap.METAX,
locale: false,
notes: AddWorkerDockerNotes[GPUDriverMap.METAX],
icon: <ProviderImage src={metaxLogo} showBg />
}
];
return (
<ProviderCatalog
onSelect={onSelect}
height={60}
current={current}
dataList={supportedHardPlatforms}
clickable={clickable}
cols={4}
/>
<Box>
<ProviderCatalog
onSelect={onSelect}
height={60}
current={current}
dataList={supportedHardPlatforms}
clickable={clickable}
cols={4}
/>
</Box>
);
};
+7 -2
View File
@@ -64,8 +64,13 @@ const AdvanceConfig = () => {
options={modelCategories}
></SealSelect>
</Form.Item>
{formKey === DeployFormKeyMap.CATALOG && <BackendForm></BackendForm>}
<CustomBackend></CustomBackend>
{formKey === DeployFormKeyMap.CATALOG && (
<>
<BackendForm></BackendForm>
<CustomBackend></CustomBackend>
</>
)}
<BackendParametersList></BackendParametersList>
<Form.Item<FormData> name="env">
<LabelSelector
+8 -1
View File
@@ -12,6 +12,7 @@ import { DeployFormKeyMap, sourceOptions } from '../config';
import { useFormContext } from '../config/form-context';
import { FormData } from '../config/types';
import BackendForm from './backend';
import CustomBackend from './custom-backend';
import LocalPathSource from './local-path-source';
import OnlineSource from './online-source';
@@ -118,7 +119,13 @@ const BasicForm: React.FC<BasicFormProps> = (props) => {
></SealSelect>
}
</Form.Item>
{formKey === DeployFormKeyMap.DEPLOYMENT && <BackendForm></BackendForm>}
{formKey === DeployFormKeyMap.DEPLOYMENT && (
<>
<BackendForm></BackendForm>
<CustomBackend></CustomBackend>
</>
)}
<Form.Item<FormData>
name="replicas"
rules={[
+5 -4
View File
@@ -71,12 +71,13 @@ const ScheduleTypeForm: React.FC = () => {
const scheduleType = Form.useWatch('scheduleType', form);
const workerSelector = Form.useWatch('worker_selector', form);
const handleScheduleTypeChange = (value: string) => {
const handleScheduleTypeChange = async (value: string) => {
if (value === ScheduleValueMap.Auto) {
await new Promise((resolve) => {
setTimeout(resolve, 100);
});
onValuesChange?.({}, form.getFieldsValue());
return;
}
if (value === ScheduleValueMap.Manual) {
} else if (value === ScheduleValueMap.Manual) {
form.setFieldValue(['gpu_selector', 'gpus_per_replica'], null);
}
};
+112 -92
View File
@@ -137,20 +137,20 @@ const registerWorker = (params: {
}) => {
const config = GPUsConfigs[params.gpu];
return `WORKER_NAME="gpustack-worker" \\
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
-volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--runtime ${config.runtime} \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
--volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--runtime ${config.runtime} \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
};
// avaliable for Ascend
@@ -163,21 +163,21 @@ const registerAscendWorker = (params: {
}) => {
const config = GPUsConfigs[params.gpu];
return `WORKER_NAME="gpustack-worker" \\
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
-volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--runtime ${config.runtime} \\
--env "ASCEND_VISIBLE_DEVICES=$(npu-smi info -m | tail -n 1 | awk '{print $1}') \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
--volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--runtime ${config.runtime} \\
--env "ASCEND_VISIBLE_DEVICES=$(npu-smi info -m | tail -n 1 | awk '{print $1}') \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
};
const registerHygonWorker = (params: {
@@ -189,23 +189,23 @@ const registerHygonWorker = (params: {
}) => {
const config = GPUsConfigs[params.gpu];
return `WORKER_NAME="gpustack-worker" \\
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
-volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--runtime ${config.runtime} \\
--volume /opt/hyhal:/opt/hyhal:ro \\
--volume /opt/dtk:/opt/dtk:ro \\
--env ROCM_PATH=/opt/dtk \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
--volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--runtime ${config.runtime} \\
--volume /opt/hyhal:/opt/hyhal:ro \\
--volume /opt/dtk:/opt/dtk:ro \\
--env ROCM_PATH=/opt/dtk \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
};
const registerIluvatarWorker = (params: {
@@ -217,22 +217,22 @@ const registerIluvatarWorker = (params: {
}) => {
const config = GPUsConfigs[params.gpu];
return `WORKER_NAME="gpustack-worker" \\
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
-volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--volume /lib/modules:/lib/modules:ro \\
--volume /usr/local/corex:/usr/local/corex:ro \\
--volume /usr/bin/ixsmi:/usr/bin/ixsmi \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
--volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--volume /lib/modules:/lib/modules:ro \\
--volume /usr/local/corex:/usr/local/corex:ro \\
--volume /usr/bin/ixsmi:/usr/bin/ixsmi \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
};
const registerMetaXWorker = (params: {
@@ -244,21 +244,21 @@ const registerMetaXWorker = (params: {
}) => {
const config = GPUsConfigs[params.gpu];
return `WORKER_NAME="gpustack-worker" \\
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
-volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--volume /opt/mxdriver:/opt/mxdriver:ro \\
--volume /opt/maca:/opt/maca:ro \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
--volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--volume /opt/mxdriver:/opt/mxdriver:ro \\
--volume /opt/maca:/opt/maca:ro \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
};
const registerCambriconWorker = (params: {
@@ -270,21 +270,21 @@ const registerCambriconWorker = (params: {
}) => {
const config = GPUsConfigs[params.gpu];
return `WORKER_NAME="gpustack-worker" \\
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
-volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--volume /usr/local/neuware:/usr/local/neuware:ro \\
--volume /usr/bin/cnmon:/usr/bin/cnmon \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
WORKER_IP="" \\
docker run -d --name \${WORKER_NAME} \\
--restart=unless-stopped \\
--privileged \\
--net=host \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_DEPLOYMENT=true" \\
--env "GPUSTACK_RUNTIME_DEPLOY_MIRRORED_NAME=\${WORKER_NAME}" \\
--volume /var/run/docker.sock:/var/run/docker.sock \\
--volume gpustack-data:/var/lib/gpustack \\
--volume /usr/local/neuware:/usr/local/neuware:ro \\
--volume /usr/bin/cnmon:/usr/bin/cnmon \\
${params.image} \\
--server-url ${params.server} \\
--token ${params.token} \\
--worker-ip \${WORKER_IP}`;
};
export const registerAddWokerCommandMap = {
@@ -297,3 +297,23 @@ export const registerAddWokerCommandMap = {
[GPUDriverMap.METAX]: registerMetaXWorker,
[GPUDriverMap.MOORE_THREADS]: registerWorker
};
export const AddWorkerDockerNotes: Record<string, string[]> = {
[GPUDriverMap.NVIDIA]: [
'clusters.addworker.nvidiaNotes-01',
'clusters.addworker.nvidiaNotes-02'
],
[GPUDriverMap.AMD]: [
'clusters.addworker.nvidiaNotes-01',
'clusters.addworker.nvidiaNotes-02'
],
[GPUDriverMap.MOORE_THREADS]: [
'clusters.addworker.nvidiaNotes-01',
'clusters.addworker.nvidiaNotes-02'
],
[GPUDriverMap.ASCEND]: [],
[GPUDriverMap.HYGON]: ['clusters.addworker.hygonNotes'],
[GPUDriverMap.ILUVATAR]: ['clusters.addworker.corexNotes'],
[GPUDriverMap.CAMBRICON]: ['clusters.addworker.cambriconNotes'],
[GPUDriverMap.METAX]: ['clusters.addworker.metaxNotes']
};