build: output files to dir

This commit is contained in:
jialin
2024-06-17 13:03:41 +08:00
parent 2352c316c0
commit 9fa61b9849
20 changed files with 776 additions and 245 deletions
@@ -161,7 +161,7 @@ const ModelBills: React.FC = () => {
<PageTools
marginBottom={10}
marginTop={0}
left={<span>Bills by model</span>}
left={false}
right={
<Space>
<Select
+50 -11
View File
@@ -1,12 +1,15 @@
import { Card, Col, Row } from 'antd';
import { Card, Col, Row, Space } from 'antd';
import React from 'react';
import { overviewConfigs } from '../config';
import '../styles/index.less';
import styles from './over-view.less';
const CardItem: React.FC<{ label: string; value: number; bgColor: string }> = ({
label,
value,
bgColor
const renderCardItem = (data: {
label: string;
value: React.ReactNode;
bgColor: string;
}) => {
const { label, value, bgColor } = data;
return (
<Card
bordered={false}
@@ -21,16 +24,52 @@ const CardItem: React.FC<{ label: string; value: number; bgColor: string }> = ({
);
};
const Overview: React.FC = (props) => {
const { data = {} } = props;
// const { data = {} } = props;
const data = {
workers: 8,
models: {
healthy: 10,
warning: 2,
error: 1
},
gpus: 30,
allocatedGpus: 12,
instances: {
healthy: 32,
warning: 3,
error: 2
}
};
const renderValue = (
value:
| number
| {
healthy: number;
warning: number;
error: number;
}
) => {
if (typeof value === 'number') {
return value;
}
return (
<Space className="value-box">
<span className={'value-healthy'}>{value.healthy}</span>
<span className={'value-warning'}>{value.warning}</span>
<span className={'value-error'}>{value.error}</span>
</Space>
);
};
return (
<Row gutter={[20, 20]} className={styles.row}>
{overviewConfigs.map((config, index) => (
<Col span={5} key={config.key}>
<CardItem
label={config.label}
value={data[config.key] || 0}
bgColor={config.backgroundColor}
/>
{renderCardItem({
label: config.label,
value: renderValue(data[config.key] || 0),
bgColor: config.backgroundColor
})}
</Col>
))}
</Row>
@@ -1,15 +1,21 @@
import PageTools from '@/components/page-tools';
import { generateRandomArray } from '@/utils';
import { Line } from '@ant-design/plots';
import { DatePicker } from 'antd';
import _ from 'lodash';
const mockData = {
GPU: generateRandomArray(),
CPU: generateRandomArray(),
Memory: generateRandomArray(),
VRAM: generateRandomArray()
};
const UtilizationOvertime: React.FC = () => {
const timeList = [
'01:00:00',
'02:00:00',
'03:00:00',
'04:00:00',
'05:00:00',
// '01:00:00',
// '02:00:00',
// '03:00:00',
// '04:00:00',
// '05:00:00',
'06:00:00',
'07:00:00',
'08:00:00',
@@ -21,7 +27,7 @@ const UtilizationOvertime: React.FC = () => {
'14:00:00',
'15:00:00'
];
const typeList = ['GPU', 'CPU', 'Memory'];
const typeList = ['GPU', 'CPU', 'Memory', 'VRAM'];
const generateData = () => {
const data = [];
for (let i = 0; i < timeList.length; i++) {
@@ -29,7 +35,7 @@ const UtilizationOvertime: React.FC = () => {
data.push({
time: timeList[i],
type: typeList[j],
value: _.round(Math.random(), 3)
value: _.get(mockData, typeList[j])[i]
});
}
}
@@ -41,10 +47,12 @@ const UtilizationOvertime: React.FC = () => {
console.log('dateString============', date);
};
const config = {
// title: 'Resource Utilization',
xField: 'time',
yField: 'value',
color: ['red', 'blue', 'green'],
colorField: 'type',
autoFit: true,
slider: false,
shapeField: 'smooth',
axis: {
@@ -69,21 +77,15 @@ const UtilizationOvertime: React.FC = () => {
tooltip: {
title: 'time',
items: [{ channel: 'y' }]
},
label: {
autoRotate: true
}
// label: {
// autoRotate: true
// }
};
// <DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
return (
<>
<PageTools
marginBottom={10}
marginTop={0}
left={<span>Utilization Over Time</span>}
right={
<DatePicker onChange={handleSelectDate} style={{ width: 300 }} />
}
/>
<PageTools marginBottom={10} marginTop={0} left={false} right={false} />
<Line height={400} data={data} {...config} />
</>
);
+14 -14
View File
@@ -1,13 +1,7 @@
export const overviewConfigs = [
{
key: 'models',
label: 'Models',
backgroundColor:
'linear-gradient(180deg, rgba(0,188,203,.2) 0%, rgba(40,207,181,.2) 100%)'
},
{
key: 'nodes',
label: 'Nodes',
key: 'workers',
label: 'Workers',
backgroundColor:
'linear-gradient(180deg, rgba(0,188,203,.2) 0%, rgba(40,207,181,.2) 100%)'
},
@@ -17,16 +11,22 @@ export const overviewConfigs = [
backgroundColor:
'linear-gradient(180deg, rgba(0,188,203,.2) 0%, rgba(40,207,181,.2) 100%)'
},
{
key: 'idleGpus',
label: 'Idle GPUs',
backgroundColor:
'linear-gradient(180deg, rgba(0,188,203,.2) 0%, rgba(40,207,181,.2) 100%)'
},
{
key: 'allocatedGpus',
label: 'Allocated GPUs',
backgroundColor:
'linear-gradient(180deg, rgba(0,188,203,.2) 0%, rgba(40,207,181,.2) 100%)'
},
{
key: 'models',
label: 'Models',
backgroundColor:
'linear-gradient(180deg, rgba(0,188,203,.2) 0%, rgba(40,207,181,.2) 100%)'
},
{
key: 'instances',
label: 'Instances',
backgroundColor:
'linear-gradient(180deg, rgba(0,188,203,.2) 0%, rgba(40,207,181,.2) 100%)'
}
];
+133 -11
View File
@@ -1,11 +1,94 @@
import BarChart from '@/components/bar-chart';
import HBar from '@/components/bar-chart/h-bar';
import ContentWrapper from '@/components/content-wrapper';
import DividerLine from '@/components/divider-line';
import PageTools from '@/components/page-tools';
import { generateRandomArray } from '@/utils';
import { PageContainer } from '@ant-design/pro-components';
import { Col, Row } from 'antd';
import GPUUtilization from './components/gpu-utilization';
import Overview from './components/over-view';
import UtilizationOvertime from './components/utilization-overtime';
const times = [
'june 1',
'june 2',
'june 3',
'june 4',
'june 5',
'june 6',
'june 7'
];
const users = ['Jim', 'Lucy', 'Lily', 'Tom', 'Jack', 'Rose', 'Jerry'];
const projects = [
'copilot-dev',
'rag-wiki',
'smart-auto-agent',
'office-auto-docs',
'smart-customer-service'
];
const APIRequestData = generateRandomArray({
length: times.length,
max: 100,
min: 0,
offset: 10
});
const TokensData = generateRandomArray({
length: times.length,
max: 2000,
min: 200,
offset: 200
});
const usersData = generateRandomArray({
length: users.length,
max: 100,
min: 0,
offset: 10
});
const projectsData = generateRandomArray({
length: projects.length,
max: 100,
min: 0,
offset: 10
});
const userDataList = usersData
.map((val, i) => {
return {
time: users[i],
value: val
};
})
.sort((a, b) => b.value - a.value);
const projectDataList = projectsData
.map((val, i) => {
return {
time: projects[i],
value: val
};
})
.sort((a, b) => b.value - a.value);
const dataList = APIRequestData.map((val, i) => {
console.log('val', val);
return {
time: times[i],
value: val
};
});
const tokenUsage = TokensData.map((val, i) => {
console.log('val', val);
return {
time: times[i],
value: val
};
});
const Dashboard: React.FC = () => {
return (
<>
@@ -13,6 +96,10 @@ const Dashboard: React.FC = () => {
<Overview></Overview>
</PageContainer>
<DividerLine></DividerLine>
<PageContainer ghost title="System Load">
<UtilizationOvertime></UtilizationOvertime>
</PageContainer>
<DividerLine></DividerLine>
<PageContainer ghost title={false}>
<Row gutter={20} style={{ marginTop: '0px' }}>
<Col span={12}>
@@ -54,18 +141,53 @@ const Dashboard: React.FC = () => {
</Col>
</Row>
</PageContainer>
{/* <DividerLine></DividerLine>
<PageContainer ghost title={false}>
<div style={{ marginTop: '0px' }}>
<ModelBills></ModelBills>
</div>
</PageContainer> */}
<DividerLine></DividerLine>
<PageContainer ghost title={false}>
<div style={{ marginTop: '0px' }}>
<UtilizationOvertime></UtilizationOvertime>
</div>
</PageContainer>
<Row gutter={10}>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>API Request</span>}
>
<BarChart data={dataList} xField="time" yField="value"></BarChart>
</ContentWrapper>
</Col>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>Tokens</span>}
>
<BarChart data={tokenUsage} xField="time" yField="value"></BarChart>
</ContentWrapper>
</Col>
</Row>
<Row gutter={10}>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>Top Users</span>}
>
<HBar
data={userDataList}
xField="time"
yField="value"
height={360}
></HBar>
</ContentWrapper>
</Col>
<Col span={12}>
<ContentWrapper
contentStyle={{ paddingRight: 0 }}
title={<span style={{ lineHeight: '48px' }}>Top Projects</span>}
>
<HBar
data={projectDataList}
xField="time"
yField="value"
height={300}
></HBar>
</ContentWrapper>
</Col>
</Row>
</>
);
};
+17
View File
@@ -0,0 +1,17 @@
.value-box {
display: flex;
justify-content: space-around;
align-items: center;
.value-healthy {
color: var(--ant-green-6);
}
.value-warning {
color: var(--ant-gold-6);
}
.value-danger {
color: var(--ant-red-6);
}
}