refactor: env detail
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
import { Tag } from 'antd';
|
||||
import AutoTooltip from '@/components/auto-tooltip';
|
||||
import RowChildren from '@/components/seal-table/components/row-children';
|
||||
import SealTable from '@/components/seal-table/index';
|
||||
import useExpandedRowKeys from '@/hooks/use-expanded-row-keys';
|
||||
import { convertFileSize } from '@/utils';
|
||||
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
|
||||
import { Col, Row } from 'antd';
|
||||
import React, { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { useDetailContext } from '../../config/detail-context';
|
||||
import WorkerData from './worker-data';
|
||||
|
||||
const Container = styled.div`
|
||||
display: flex;
|
||||
@@ -14,74 +19,209 @@ const Environment: React.FC = () => {
|
||||
const { detailData } = useDetailContext();
|
||||
const { snapshot } = detailData;
|
||||
|
||||
const { handleExpandChange, handleExpandAll, expandedRowKeys } =
|
||||
useExpandedRowKeys();
|
||||
|
||||
const mainWorker = useMemo(() => {
|
||||
// get workers data
|
||||
|
||||
const [[workerName, workerInfo]] = Object.entries(snapshot.workers);
|
||||
const gpuData = Object.values(snapshot.gpus).filter(
|
||||
(gpu) => gpu.worker_name === workerName
|
||||
);
|
||||
|
||||
return {
|
||||
workerData: workerInfo,
|
||||
gpuData: [...gpuData, ...gpuData]
|
||||
...workerInfo,
|
||||
isMain: true,
|
||||
children: gpuData
|
||||
};
|
||||
}, [snapshot]);
|
||||
|
||||
const subWorkers = useMemo(() => {
|
||||
const [[mainWorkerName, mainWorkerInfo]] = Object.entries(snapshot.workers);
|
||||
// const subWorkers = useMemo(() => {
|
||||
// const [[mainWorkerName, mainWorkerInfo]] = Object.entries(snapshot.workers);
|
||||
|
||||
const subOrdinaryWorkers = Object.values(snapshot.instances).filter(
|
||||
(instance) => instance.worker_name === mainWorkerName
|
||||
// const subOrdinaryWorkers = Object.values(snapshot.instances).filter(
|
||||
// (instance) => instance.worker_name === mainWorkerName
|
||||
// );
|
||||
|
||||
// return subOrdinaryWorkers.map((worker) => {
|
||||
// const gpuData = Object.values(snapshot.gpus).filter(
|
||||
// (gpu) => gpu.worker_name === worker.worker_name
|
||||
// );
|
||||
|
||||
// return {
|
||||
// ...worker,
|
||||
// isMain: false,
|
||||
// children: gpuData
|
||||
// };
|
||||
// });
|
||||
// }, [snapshot, mainWorker]);
|
||||
|
||||
const GPUColumns = [
|
||||
{
|
||||
title: 'GPU Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
span: 6,
|
||||
colStyle: { paddingLeft: 16 },
|
||||
render: (value: string, record: any) => (
|
||||
<AutoTooltip ghost>{value}</AutoTooltip>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Vendor',
|
||||
dataIndex: 'vendor',
|
||||
key: 'vendor',
|
||||
span: 4,
|
||||
colStyle: { paddingLeft: 46 }
|
||||
},
|
||||
{
|
||||
title: 'VRAM',
|
||||
dataIndex: 'memory_total',
|
||||
key: 'memory_total',
|
||||
label: 'VRAM',
|
||||
span: 3,
|
||||
render: (value: number, record: any) => convertFileSize(value)
|
||||
},
|
||||
{
|
||||
title: 'Cores',
|
||||
dataIndex: 'core_total',
|
||||
key: 'core_total',
|
||||
label: 'Cores',
|
||||
span: 3
|
||||
},
|
||||
{
|
||||
title: 'Runtime Version',
|
||||
dataIndex: 'runtime_version',
|
||||
key: 'runtime_version',
|
||||
span: 4
|
||||
},
|
||||
{
|
||||
title: 'Driver Version',
|
||||
dataIndex: 'driver_version',
|
||||
key: 'driver_version',
|
||||
span: 4,
|
||||
colStyle: { paddingLeft: 35 }
|
||||
}
|
||||
];
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'Worker Name',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
span: 6
|
||||
},
|
||||
{
|
||||
title: 'System',
|
||||
dataIndex: 'os',
|
||||
key: 'system',
|
||||
span: 4,
|
||||
render: (os: { name: string; version: string }, record: any) => {
|
||||
return `${record.os.name}`;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Version',
|
||||
dataIndex: 'version',
|
||||
key: 'version',
|
||||
span: 6,
|
||||
render: (val: any, record: any) => {
|
||||
return <AutoTooltip ghost>{record.os.version}</AutoTooltip>;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'CPU Count',
|
||||
dataIndex: 'cpu_total',
|
||||
key: 'cpu_total',
|
||||
span: 4
|
||||
},
|
||||
{
|
||||
title: 'Memory',
|
||||
dataIndex: 'memory_total',
|
||||
key: 'memory_total',
|
||||
span: 4,
|
||||
render: (value: number) => convertFileSize(value)
|
||||
}
|
||||
];
|
||||
|
||||
const dataList = useMemo(() => {
|
||||
return [mainWorker];
|
||||
}, [mainWorker]);
|
||||
|
||||
const handleToggleExpandAll = useMemoizedFn((expanded: boolean) => {
|
||||
const keys = dataList?.map((item) => item.id);
|
||||
handleExpandAll(expanded, keys);
|
||||
});
|
||||
|
||||
const loadChildren = useMemoizedFn(async (record: any) => {
|
||||
return record.children || [];
|
||||
});
|
||||
|
||||
const renderChildren = useMemoizedFn((list: any[]) => {
|
||||
return (
|
||||
<div style={{ borderRadius: 'var(--ant-table-header-border-radius)' }}>
|
||||
<RowChildren>
|
||||
{list.map((gpu) => (
|
||||
<Row key={gpu.id} style={{ width: '100%' }} align="middle">
|
||||
{GPUColumns.map((col) => (
|
||||
<Col key={col.key} span={col.span} style={{ ...col.colStyle }}>
|
||||
<span
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
gap: 4,
|
||||
flexDirection: 'column'
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
color: 'var(--ant-color-text-tertiary)',
|
||||
fontSize: 12
|
||||
}}
|
||||
>
|
||||
{col.title}
|
||||
</span>
|
||||
{col.render
|
||||
? col.render((gpu as any)[col.dataIndex], gpu)
|
||||
: (gpu as any)[col.dataIndex]}
|
||||
</span>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
))}
|
||||
</RowChildren>
|
||||
</div>
|
||||
);
|
||||
|
||||
return subOrdinaryWorkers.map((worker) => {
|
||||
const gpuData = Object.values(snapshot.gpus).filter(
|
||||
(gpu) => gpu.worker_name === worker.worker_name
|
||||
);
|
||||
|
||||
return {
|
||||
workerData: worker,
|
||||
gpuData: gpuData
|
||||
};
|
||||
});
|
||||
}, [snapshot, mainWorker]);
|
||||
});
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<WorkerData
|
||||
{/* <WorkerData
|
||||
workerData={mainWorker.workerData}
|
||||
gpuData={mainWorker.gpuData}
|
||||
gpuData={mainWorker.children}
|
||||
title={
|
||||
<div className="flex-center gap-8">
|
||||
<Tag color="geekblue">Main</Tag>
|
||||
<span>{mainWorker?.workerData?.name}</span>
|
||||
</div>
|
||||
}
|
||||
></WorkerData>
|
||||
<WorkerData
|
||||
workerData={mainWorker.workerData}
|
||||
gpuData={mainWorker.gpuData}
|
||||
title={
|
||||
<div className="flex-center gap-8">
|
||||
<Tag
|
||||
style={{
|
||||
backgroundColor: 'var(--ant-color-fill-secondary)',
|
||||
color: 'var(--ant-color-text-tertiary)'
|
||||
}}
|
||||
>
|
||||
Sub
|
||||
</Tag>
|
||||
<span>{mainWorker?.workerData?.name}</span>
|
||||
</div>
|
||||
}
|
||||
></WorkerData>
|
||||
{/* {subWorkers?.map?.((worker, index) => (
|
||||
<WorkerData
|
||||
key={index}
|
||||
workerData={worker.workerData}
|
||||
gpuData={worker.gpuData}
|
||||
></WorkerData>
|
||||
))} */}
|
||||
></WorkerData> */}
|
||||
<SealTable
|
||||
rowKey="id"
|
||||
loadChildren={loadChildren}
|
||||
expandedRowKeys={expandedRowKeys}
|
||||
onExpand={handleExpandChange}
|
||||
onExpandAll={handleToggleExpandAll}
|
||||
renderChildren={renderChildren}
|
||||
showSorterTooltip={false}
|
||||
dataSource={dataList}
|
||||
loading={false}
|
||||
loadend={true}
|
||||
columns={columns}
|
||||
childParentKey="id"
|
||||
expandable={true}
|
||||
></SealTable>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ const Benchmark: React.FC = () => {
|
||||
];
|
||||
|
||||
return (
|
||||
<Section title="Benchmark Parameters">
|
||||
<Section title="Benchmark Parameters" minHeight={132}>
|
||||
<Descriptions
|
||||
items={items}
|
||||
colon={false}
|
||||
|
||||
@@ -144,7 +144,7 @@ const Instance: React.FC = () => {
|
||||
}, [detailData]);
|
||||
|
||||
return (
|
||||
<Section title="Model Instance">
|
||||
<Section title="Model Instance" minHeight={220}>
|
||||
<Descriptions
|
||||
items={items}
|
||||
colon={false}
|
||||
|
||||
@@ -12,18 +12,7 @@ const columns = [
|
||||
unit: 's',
|
||||
render: (value: number) => round(value, 2)
|
||||
},
|
||||
{
|
||||
title: 'Concurrency',
|
||||
dataIndex: 'request_concurrency',
|
||||
path: ['raw_metrics', 'benchmarks', '0'],
|
||||
unit: '',
|
||||
render: (value: number) => {
|
||||
return round(
|
||||
_.get(value, 'metrics.request_concurrency.successful.mean'),
|
||||
0
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Total Requests',
|
||||
dataIndex: 'total_requests',
|
||||
@@ -31,6 +20,13 @@ const columns = [
|
||||
unit: '',
|
||||
render: (value: number) => round(value, 0)
|
||||
},
|
||||
{
|
||||
title: 'Total token throughput',
|
||||
dataIndex: 'tokens_per_second_mean',
|
||||
path: 'tokens_per_second_mean',
|
||||
unit: 'Tokens/s',
|
||||
render: (value: number) => round(value, 2)
|
||||
},
|
||||
{
|
||||
title: 'Success Requests',
|
||||
dataIndex: 'successful_requests',
|
||||
@@ -44,6 +40,17 @@ const columns = [
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: 'Output token throughput',
|
||||
dataIndex: 'output_tokens_per_second_mean',
|
||||
path: 'output_tokens_per_second_mean',
|
||||
unit: 'Tokens/s',
|
||||
render: (value: number) => round(value, 2)
|
||||
}
|
||||
];
|
||||
|
||||
const columnsSub = [
|
||||
{
|
||||
title: 'Failed Requests',
|
||||
dataIndex: 'failed_requests',
|
||||
@@ -58,27 +65,22 @@ const columns = [
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Output token throughput (t/s)',
|
||||
dataIndex: 'output_tokens_per_second_mean',
|
||||
path: 'output_tokens_per_second_mean',
|
||||
unit: 't/s',
|
||||
render: (value: number) => round(value, 2)
|
||||
}
|
||||
];
|
||||
|
||||
const columnsSub = [
|
||||
{
|
||||
title: 'Total token throughput (t/s)',
|
||||
dataIndex: 'tokens_per_second_mean',
|
||||
path: 'tokens_per_second_mean',
|
||||
unit: 't/s',
|
||||
render: (value: number) => round(value, 2)
|
||||
title: 'Concurrency',
|
||||
dataIndex: 'request_concurrency',
|
||||
path: ['raw_metrics', 'benchmarks', '0'],
|
||||
unit: '',
|
||||
render: (value: number) => {
|
||||
return round(
|
||||
_.get(value, 'metrics.request_concurrency.successful.mean'),
|
||||
0
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Request token throughput (t/s)',
|
||||
title: 'Request token throughput ',
|
||||
dataIndex: 'prompt_tokens_per_second_mean',
|
||||
path: 'prompt_tokens_per_second_mean',
|
||||
unit: 't/s',
|
||||
unit: 'Tokens/s',
|
||||
render: (value: number) => round(value, 2)
|
||||
},
|
||||
{
|
||||
@@ -135,14 +137,19 @@ const PercentileResult: React.FC = () => {
|
||||
({ title, dataIndex, path, render, unit }) => ({
|
||||
key: dataIndex,
|
||||
label: title,
|
||||
children: unit
|
||||
? render(_.get(detailData, path) ?? 0) + ` (${unit})`
|
||||
: render(_.get(detailData, path) ?? 0)
|
||||
children: unit ? (
|
||||
<span className="flex-center">
|
||||
{render(_.get(detailData, path) ?? 0)}{' '}
|
||||
<span className="m-l-4">({unit})</span>
|
||||
</span>
|
||||
) : (
|
||||
render(_.get(detailData, path) ?? 0)
|
||||
)
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<Section title="Metrics Result" minHeight={200}>
|
||||
<Section title="Metrics Result" minHeight={210}>
|
||||
{/* <Table
|
||||
size="small"
|
||||
columns={[
|
||||
|
||||
@@ -76,7 +76,7 @@ const PercentileResult: React.FC = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Section title="Percentiles Result">
|
||||
<Section title="Percentiles Result" minHeight={240}>
|
||||
<Table
|
||||
size="small"
|
||||
columns={[
|
||||
@@ -90,6 +90,17 @@ const PercentileResult: React.FC = () => {
|
||||
rowKey="percentile"
|
||||
pagination={false}
|
||||
styles={{
|
||||
// header: {
|
||||
// row: {
|
||||
// background: 'none',
|
||||
// borderBottom: '1px solid var(--ant-color-split)'
|
||||
// },
|
||||
// cell: {
|
||||
// background: 'none',
|
||||
// paddingBottom: 0,
|
||||
// borderBottom: '1px solid var(--ant-color-split)'
|
||||
// }
|
||||
// },
|
||||
body: {
|
||||
cell: {
|
||||
height: 54
|
||||
|
||||
Reference in New Issue
Block a user