chore: display vllm distributed info

This commit is contained in:
jialin
2025-03-10 15:11:48 +08:00
parent 06d6732ab2
commit 12707793b1
6 changed files with 162 additions and 125 deletions
@@ -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;
+3 -1
View File
@@ -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'
}; };
+6 -3
View File
@@ -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"'
}; };
+3 -1
View File
@@ -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 跨节点'
}; };
+139 -113
View File
@@ -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,38 +273,143 @@ 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,
worker_ip: data?.ip, worker_ip: data?.ip,
port: '', port: '',
ram: convertFileSize(item.computed_resource_claim?.ram, 0), ram: convertFileSize(item.computed_resource_claim?.ram, 0),
gpu_index: displayGPUs(item.computed_resource_claim?.vram || {}) gpu_index: displayGPUs(item.computed_resource_claim?.vram || {})
}; };
}); });
const mainWorker = [ const mainWorker = [
{ {
worker_name: `${instanceData.worker_name} (main)`, worker_name: `${instanceData.worker_name} (main)`,
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 || {}
)
}
];
return (
<div>
<SimpleTabel
columns={distributeCols}
dataSource={[...mainWorker, ...list]}
></SimpleTabel>
</div>
);
},
[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 ( return (
<div> <Tooltip
<SimpleTabel title={
columns={distributeCols} <span className="flex flex-center">
dataSource={[...mainWorker, ...list]} <span>
></SimpleTabel> CPU:{' '}
</div> {_.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>
); );
}, [workerList, instanceData, intl]); }, [
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>
+9 -6
View File
@@ -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;