chore: display vllm distributed info
This commit is contained in:
@@ -2,7 +2,8 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 54px;
|
min-height: 54px;
|
||||||
|
padding-block: 5px;
|
||||||
border-radius: var(--border-radius-mdium);
|
border-radius: var(--border-radius-mdium);
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
|||||||
@@ -106,5 +106,7 @@ export default {
|
|||||||
'Multiple replicas enable load balancing for { api } inference requests.',
|
'Multiple replicas enable load balancing for { api } inference requests.',
|
||||||
'models.table.list.empty': 'No Models yet!',
|
'models.table.list.empty': 'No Models yet!',
|
||||||
'models.table.list.getStart':
|
'models.table.list.getStart':
|
||||||
'<span style="margin-right: 5px;font-size: 13px;">Get started with</span> <span style="font-size: 14px;font-weight: 700">DeepSeek-R1-Distill-Qwen-1.5B</span>'
|
'<span style="margin-right: 5px;font-size: 13px;">Get started with</span> <span style="font-size: 14px;font-weight: 700">DeepSeek-R1-Distill-Qwen-1.5B</span>',
|
||||||
|
'models.table.llamaAcrossworker': 'Llama-box Across Workers',
|
||||||
|
'models.table.vllmAcrossworker': 'vLLM Across Workers'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -85,8 +85,7 @@ export default {
|
|||||||
'models.form.gpuselector': 'Селектор GPU',
|
'models.form.gpuselector': 'Селектор GPU',
|
||||||
'models.form.backend.llamabox':
|
'models.form.backend.llamabox':
|
||||||
'Для моделей формата GGUF. Поддержка Linux, macOS и Windows.',
|
'Для моделей формата GGUF. Поддержка Linux, macOS и Windows.',
|
||||||
'models.form.backend.vllm':
|
'models.form.backend.vllm': 'Для моделей не-GGUF формата. Только x86 Linux.',
|
||||||
'Для моделей не-GGUF формата. Только x86 Linux.',
|
|
||||||
'models.form.backend.voxbox': 'Для аудиомоделей не-GGUF формата.',
|
'models.form.backend.voxbox': 'Для аудиомоделей не-GGUF формата.',
|
||||||
'models.form.search.gguftips':
|
'models.form.search.gguftips':
|
||||||
'Для воркеров на macOS/Windows отметьте GGUF (для аудиомоделей снимите).',
|
'Для воркеров на macOS/Windows отметьте GGUF (для аудиомоделей снимите).',
|
||||||
@@ -106,5 +105,9 @@ export default {
|
|||||||
'Несколько реплик обеспечивают балансировку нагрузки для { api } запросов.',
|
'Несколько реплик обеспечивают балансировку нагрузки для { api } запросов.',
|
||||||
'models.table.list.empty': 'Модели отсутствуют!',
|
'models.table.list.empty': 'Модели отсутствуют!',
|
||||||
'models.table.list.getStart':
|
'models.table.list.getStart':
|
||||||
'<span style="margin-right: 5px;font-size: 13px;">Начните работу с</span> <span style="font-size: 14px;font-weight: 700">DeepSeek-R1-Distill-Qwen-1.5B</span>'
|
'<span style="margin-right: 5px;font-size: 13px;">Начните работу с</span> <span style="font-size: 14px;font-weight: 700">DeepSeek-R1-Distill-Qwen-1.5B</span>',
|
||||||
|
'models.table.llamaAcrossworker':
|
||||||
|
'TODO: Translate key "models.table.llamaAcrossworker"',
|
||||||
|
'models.table.vllmAcrossworker':
|
||||||
|
'TODO: Translate key "models.table.vllmAcrossworker"'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -102,5 +102,7 @@ export default {
|
|||||||
'models.form.replicas.tips': '多副本数实现 { api } 接口推理请求的负载均衡',
|
'models.form.replicas.tips': '多副本数实现 { api } 接口推理请求的负载均衡',
|
||||||
'models.table.list.empty': '暂无已部署模型',
|
'models.table.list.empty': '暂无已部署模型',
|
||||||
'models.table.list.getStart':
|
'models.table.list.getStart':
|
||||||
'<span style="margin-right: 5px;font-size: 13px;">一键部署</span><span style="font-size: 14px;font-weight: 700">DeepSeek-R1-Distill-Qwen-1.5B</span><span style="margin-left: 5px;font-size: 13px;">立即使用!</span>'
|
'<span style="margin-right: 5px;font-size: 13px;">一键部署</span><span style="font-size: 14px;font-weight: 700">DeepSeek-R1-Distill-Qwen-1.5B</span><span style="margin-left: 5px;font-size: 13px;">立即使用!</span>',
|
||||||
|
'models.table.llamaAcrossworker': 'Llama-box 跨节点',
|
||||||
|
'models.table.vllmAcrossworker': 'vLLM 跨节点'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -88,11 +88,6 @@ const distributeCols = [
|
|||||||
return row.port ? `${row.worker_ip}:${row.port}` : row.worker_ip;
|
return row.port ? `${row.worker_ip}:${row.port}` : row.worker_ip;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: 'models.form.backend',
|
|
||||||
locale: true,
|
|
||||||
key: 'backend'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'models.table.gpuindex',
|
title: 'models.table.gpuindex',
|
||||||
locale: true,
|
locale: true,
|
||||||
@@ -278,9 +273,9 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
);
|
);
|
||||||
}, [modelData, instanceData, intl]);
|
}, [modelData, instanceData, intl]);
|
||||||
|
|
||||||
const renderDistributionInfo = useMemo(() => {
|
const renderDistributedServer = useCallback(
|
||||||
const rpcServerList = instanceData.distributed_servers?.rpc_servers || [];
|
(severList: any[]) => {
|
||||||
const list = _.map(rpcServerList, (item: any) => {
|
const list = _.map(severList, (item: any) => {
|
||||||
const data = _.find(workerList, { id: item.worker_id });
|
const data = _.find(workerList, { id: item.worker_id });
|
||||||
return {
|
return {
|
||||||
worker_name: data?.name,
|
worker_name: data?.name,
|
||||||
@@ -297,7 +292,9 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
worker_ip: `${instanceData.worker_ip}`,
|
worker_ip: `${instanceData.worker_ip}`,
|
||||||
port: '',
|
port: '',
|
||||||
ram: convertFileSize(instanceData.computed_resource_claim?.ram, 0),
|
ram: convertFileSize(instanceData.computed_resource_claim?.ram, 0),
|
||||||
gpu_index: displayGPUs(instanceData.computed_resource_claim?.vram || {})
|
gpu_index: displayGPUs(
|
||||||
|
instanceData.computed_resource_claim?.vram || {}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -309,7 +306,110 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
></SimpleTabel>
|
></SimpleTabel>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}, [workerList, instanceData, intl]);
|
},
|
||||||
|
[workerList, instanceData, intl]
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderDistributionInfo = useCallback(
|
||||||
|
(severList: any[], label: string) => {
|
||||||
|
if (!severList.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
overlayInnerStyle={{
|
||||||
|
width: 'max-content',
|
||||||
|
maxWidth: '500px',
|
||||||
|
minWidth: '400px'
|
||||||
|
}}
|
||||||
|
title={renderDistributedServer(severList)}
|
||||||
|
>
|
||||||
|
<Tag
|
||||||
|
color="processing"
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
maxWidth: '100%',
|
||||||
|
minWidth: 50,
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
overflow: 'hidden',
|
||||||
|
opacity: 0.75,
|
||||||
|
borderRadius: 12
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<InfoCircleOutlined className="m-r-5" />
|
||||||
|
{intl.formatMessage({
|
||||||
|
id: label
|
||||||
|
})}
|
||||||
|
</Tag>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[renderDistributedServer]
|
||||||
|
);
|
||||||
|
|
||||||
|
const renderOffloadInfo = useMemo(() => {
|
||||||
|
const total_layers = instanceData.computed_resource_claim?.total_layers;
|
||||||
|
const offload_layers = instanceData.computed_resource_claim?.offload_layers;
|
||||||
|
if (total_layers === offload_layers || !offload_layers || !total_layers) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
title={
|
||||||
|
<span className="flex flex-center">
|
||||||
|
<span>
|
||||||
|
CPU:{' '}
|
||||||
|
{_.subtract(
|
||||||
|
instanceData.computed_resource_claim?.total_layers,
|
||||||
|
instanceData.computed_resource_claim?.offload_layers
|
||||||
|
) || 0}{' '}
|
||||||
|
{intl.formatMessage({
|
||||||
|
id: 'models.table.layers'
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
<Divider
|
||||||
|
type="vertical"
|
||||||
|
style={{
|
||||||
|
borderColor: '#fff',
|
||||||
|
opacity: 0.5
|
||||||
|
}}
|
||||||
|
></Divider>
|
||||||
|
<span>
|
||||||
|
GPU: {instanceData.computed_resource_claim?.offload_layers}{' '}
|
||||||
|
{intl.formatMessage({
|
||||||
|
id: 'models.table.layers'
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Tag
|
||||||
|
color="cyan"
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
maxWidth: '100%',
|
||||||
|
minWidth: 50,
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
overflow: 'hidden',
|
||||||
|
opacity: 0.75,
|
||||||
|
borderRadius: 12
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<InfoCircleOutlined className="m-r-5" />
|
||||||
|
{intl.formatMessage({
|
||||||
|
id: 'models.table.cpuoffload'
|
||||||
|
})}
|
||||||
|
</Tag>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}, [
|
||||||
|
instanceData.computed_resource_claim?.total_layers,
|
||||||
|
instanceData.computed_resource_claim?.offload_layers
|
||||||
|
]);
|
||||||
|
|
||||||
const handleOnSelect = useCallback(
|
const handleOnSelect = useCallback(
|
||||||
(val: string) => {
|
(val: string) => {
|
||||||
@@ -366,88 +466,14 @@ const InstanceItem: React.FC<InstanceItemProps> = ({
|
|||||||
}}
|
}}
|
||||||
className="flex align-center"
|
className="flex align-center"
|
||||||
>
|
>
|
||||||
{instanceData.computed_resource_claim?.total_layers !==
|
{renderOffloadInfo}
|
||||||
instanceData.computed_resource_claim?.offload_layers && (
|
{renderDistributionInfo(
|
||||||
<Tooltip
|
instanceData.distributed_servers?.rpc_servers || [],
|
||||||
title={
|
'models.table.llamaAcrossworker'
|
||||||
<span className="flex flex-center">
|
|
||||||
<span>
|
|
||||||
CPU:{' '}
|
|
||||||
{_.subtract(
|
|
||||||
instanceData.computed_resource_claim?.total_layers,
|
|
||||||
instanceData.computed_resource_claim?.offload_layers
|
|
||||||
) || 0}{' '}
|
|
||||||
{intl.formatMessage({
|
|
||||||
id: 'models.table.layers'
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
<Divider
|
|
||||||
type="vertical"
|
|
||||||
style={{
|
|
||||||
borderColor: '#fff',
|
|
||||||
opacity: 0.5
|
|
||||||
}}
|
|
||||||
></Divider>
|
|
||||||
<span>
|
|
||||||
GPU:{' '}
|
|
||||||
{instanceData.computed_resource_claim?.offload_layers}{' '}
|
|
||||||
{intl.formatMessage({
|
|
||||||
id: 'models.table.layers'
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Tag
|
|
||||||
color="cyan"
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
maxWidth: '100%',
|
|
||||||
minWidth: 50,
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
overflow: 'hidden',
|
|
||||||
opacity: 0.75,
|
|
||||||
borderRadius: 12
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<InfoCircleOutlined className="m-r-5" />
|
|
||||||
{intl.formatMessage({
|
|
||||||
id: 'models.table.cpuoffload'
|
|
||||||
})}
|
|
||||||
</Tag>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
)}
|
||||||
{instanceData?.distributed_servers?.rpc_servers?.length && (
|
{renderDistributionInfo(
|
||||||
<Tooltip
|
instanceData.distributed_servers?.ray_actors || [],
|
||||||
overlayInnerStyle={{
|
'models.table.vllmAcrossworker'
|
||||||
width: 'max-content',
|
|
||||||
maxWidth: '500px',
|
|
||||||
minWidth: '400px'
|
|
||||||
}}
|
|
||||||
title={renderDistributionInfo}
|
|
||||||
>
|
|
||||||
<Tag
|
|
||||||
color="processing"
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
maxWidth: '100%',
|
|
||||||
minWidth: 50,
|
|
||||||
textOverflow: 'ellipsis',
|
|
||||||
whiteSpace: 'nowrap',
|
|
||||||
overflow: 'hidden',
|
|
||||||
opacity: 0.75,
|
|
||||||
borderRadius: 12
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<InfoCircleOutlined className="m-r-5" />
|
|
||||||
{intl.formatMessage({
|
|
||||||
id: 'models.table.acrossworker'
|
|
||||||
})}
|
|
||||||
</Tag>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ interface ComputedResourceClaim {
|
|||||||
ram: number;
|
ram: number;
|
||||||
vram: Record<string, number>;
|
vram: Record<string, number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DistributedServerItem {
|
||||||
|
pid: number;
|
||||||
|
port: number;
|
||||||
|
worker_id: string;
|
||||||
|
computed_resource_claim: ComputedResourceClaim;
|
||||||
|
}
|
||||||
export interface ModelInstanceListItem {
|
export interface ModelInstanceListItem {
|
||||||
backend?: string;
|
backend?: string;
|
||||||
backend_version?: string;
|
backend_version?: string;
|
||||||
@@ -74,12 +81,8 @@ export interface ModelInstanceListItem {
|
|||||||
huggingface_filename: string;
|
huggingface_filename: string;
|
||||||
ollama_library_model_name: string;
|
ollama_library_model_name: string;
|
||||||
distributed_servers?: {
|
distributed_servers?: {
|
||||||
rpc_servers: {
|
rpc_servers: DistributedServerItem[];
|
||||||
pid: number;
|
ray_actors: DistributedServerItem[];
|
||||||
port: number;
|
|
||||||
worker_id: string;
|
|
||||||
computed_resource_claim: ComputedResourceClaim;
|
|
||||||
}[];
|
|
||||||
};
|
};
|
||||||
computed_resource_claim?: ComputedResourceClaim;
|
computed_resource_claim?: ComputedResourceClaim;
|
||||||
s3_address: string;
|
s3_address: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user