fix: benchmark tooltip issues

This commit is contained in:
jialin
2026-02-06 18:34:20 +08:00
parent 4a582ec8b1
commit 096227e3da
14 changed files with 119 additions and 69 deletions
+1 -1
View File
@@ -157,7 +157,7 @@ export const FilterBar: React.FC<FilterBarProps> = (props) => {
actionType === 'dropdown' ? (
<DropDownActions
styles={{
root: { minWidth: '125px' }
root: { minWidth: '140px' }
}}
menu={{
items: actionItems,
+1 -1
View File
@@ -43,6 +43,6 @@ export default {
'backend.recommendModels': 'Recommended Models',
'backend.filter.source': 'Filter by source',
'backend.add.custom': 'Custom',
'backend.add.community': 'Community Backends',
'backend.add.community': 'Community',
'backend.community.title': 'Community Backend Marketplace'
};
+3 -1
View File
@@ -83,5 +83,7 @@ export default {
'benchmark.env.cpuCounts': 'CPU Cores',
'benchmark.table.export.results': 'Export Results',
'benchmark.form.nonLlmModel.tips':
'Benchmarking currently only supports LLM models'
'Benchmarking currently only supports LLM models',
'benchmark.detail.result.duration': 'Duration',
'benchmark.detail.result.basic': 'Basic'
};
+1 -1
View File
@@ -43,6 +43,6 @@ export default {
'backend.recommendModels': 'Recommended Models',
'backend.filter.source': 'Filter by source',
'backend.add.custom': 'Custom',
'backend.add.community': 'Community Backends',
'backend.add.community': 'Community',
'backend.community.title': 'Community Backend Marketplace'
};
+3 -1
View File
@@ -83,5 +83,7 @@ export default {
'benchmark.env.cpuCounts': 'CPU Cores',
'benchmark.table.export.results': 'Export Results',
'benchmark.form.nonLlmModel.tips':
'Benchmarking currently only supports LLM models'
'Benchmarking currently only supports LLM models',
'benchmark.detail.result.duration': 'Duration',
'benchmark.detail.result.basic': 'Basic'
};
+2 -2
View File
@@ -43,7 +43,7 @@ export default {
'backend.recommendModels': 'Recommended Models',
'backend.filter.source': 'Filter by source',
'backend.add.custom': 'Custom',
'backend.add.community': 'Community Backends',
'backend.add.community': 'Community',
'backend.community.title': 'Community Backend Marketplace'
};
@@ -52,6 +52,6 @@ export default {
// 2. 'backend.recommendModels': 'Recommended Models',
// 3. 'backend.filter.source': 'Filter by source',
// 4. 'backend.add.custom': 'Custom',
// 5. 'backend.add.community': 'Community Backends',
// 5. 'backend.add.community': 'Community',
// 6. 'backend.community.title': 'Community Backend Marketplace'
// ========== End of To-Do List ==========
+3 -1
View File
@@ -83,5 +83,7 @@ export default {
'benchmark.env.cpuCounts': 'CPU Cores',
'benchmark.table.export.results': 'Export Results',
'benchmark.form.nonLlmModel.tips':
'Benchmarking currently only supports LLM models'
'Benchmarking currently only supports LLM models',
'benchmark.detail.result.duration': 'Duration',
'benchmark.detail.result.basic': 'Basic'
};
+1 -1
View File
@@ -40,6 +40,6 @@ export default {
'backend.recommendModels': '推荐模型',
'backend.filter.source': '按来源过滤',
'backend.add.custom': '自定义',
'backend.add.community': '社区后端',
'backend.add.community': '社区',
'backend.community.title': '社区后端市场'
};
+3 -1
View File
@@ -82,5 +82,7 @@ export default {
'benchmark.env.driverVersion': '驱动版本',
'benchmark.env.cpuCounts': 'CPU 核心数',
'benchmark.table.export.results': '导出结果',
'benchmark.form.nonLlmModel.tips': '基准测试目前仅支持 LLM 模型'
'benchmark.form.nonLlmModel.tips': '基准测试目前仅支持 LLM 模型',
'benchmark.detail.result.duration': '耗时',
'benchmark.detail.result.basic': '基础信息'
};
+1 -1
View File
@@ -215,7 +215,7 @@ const ColumnSettings: React.FC<{
{intl.formatMessage({ id: 'common.checkbox.all' })}
</Button>
<Button size="middle" type="primary" onClick={handleConfirm}>
{intl.formatMessage({ id: 'common.button.confirm' })}
{intl.formatMessage({ id: 'common.button.save' })}
</Button>
</div>
</div>
@@ -108,46 +108,21 @@ const requestColumns = [
0,
precision: 0,
unit: ''
},
{
title: 'benchmark.detail.result.duration',
key: 'duration',
dataIndex: 'duration',
path: ['raw_metrics', 'benchmarks', '0', 'duration'],
precision: 0,
render: (value: number) => (value ? `${round(value, 2)} (s)` : 0),
unit: ''
}
];
const PERCENTILES = [
{ key: 'metrics', label: 'Metrics', title: 'N/A' }
] as const;
const PercentileResult: React.FC = () => {
const { detailData } = useDetailContext();
const intl = useIntl();
const metrics = detailData?.raw_metrics?.benchmarks?.[0]?.metrics || {};
const buildPercentileTable = (metrics: any) => {
return PERCENTILES.map(({ key, title }) => {
const row: any = { metrics: title };
[...throughputColumns, ...latencyColumns].forEach(
({ dataIndex, path }) => {
row[dataIndex] = _.get(detailData, path) ?? 0;
}
);
return row;
});
};
const items = [...throughputColumns, ...latencyColumns].map(
({ title, dataIndex, path, render, unit }) => ({
key: dataIndex,
label: title,
children: unit ? (
<span className="flex-center">
{render(_.get(detailData, path) ?? 0)}{' '}
<span className="m-l-4">({unit})</span>
</span>
) : (
render(_.get(detailData, path) ?? 0)
)
})
);
const throughputItems = throughputColumns.map(
({ title, dataIndex, path, render, unit }) => ({
@@ -215,8 +190,8 @@ const PercentileResult: React.FC = () => {
<Box>
<Descriptions
styles={descriptionStyles}
title={intl.formatMessage({ id: 'benchmark.detail.summary.latency' })}
items={latencyItems}
title={intl.formatMessage({ id: 'benchmark.detail.result.basic' })}
items={requestItems}
colon={false}
column={1}
></Descriptions>
@@ -231,8 +206,8 @@ const PercentileResult: React.FC = () => {
></Descriptions>
<Descriptions
styles={descriptionStyles}
title={intl.formatMessage({ id: 'benchmark.detail.summary.request' })}
items={requestItems}
title={intl.formatMessage({ id: 'benchmark.detail.summary.latency' })}
items={latencyItems}
colon={false}
column={1}
></Descriptions>
@@ -38,14 +38,11 @@ const useBenchmarkColumns = (params: {
...columns,
{
title: (
<AutoTooltip ghost minWidth={20}>
<Typography.Text ellipsis={{ tooltip: true }}>
{intl.formatMessage({ id: 'common.table.operation' })}
</AutoTooltip>
</Typography.Text>
),
dataIndex: 'operations',
ellipsis: {
showTitle: false
},
render: (value: string, record: ListItem) => (
<RowActions record={record} handleSelect={handleSelect}></RowActions>
)
@@ -1,8 +1,10 @@
import AutoTooltip from '@/components/auto-tooltip';
import InfoColumn from '@/components/simple-table/info-column';
import StatusTag from '@/components/status-tag';
import { tableSorter } from '@/config/settings';
import ColumnSettings from '@/pages/_components/column-settings';
import { useIntl } from '@umijs/max';
import { Typography } from 'antd';
import dayjs from 'dayjs';
import _, { round } from 'lodash';
import React from 'react';
@@ -120,6 +122,21 @@ const useColumnSettings = (options: {
);
};
const fieldList = [
{
label: 'benchmark.detail.throughput.inputToken',
key: 'input_tokens_per_second_mean',
locale: true,
render: (val: any) => round(val, 2)
},
{
label: 'benchmark.detail.throughput.outputToken',
key: 'output_tokens_per_second_mean',
locale: true,
render: (val: any) => round(val, 2)
}
];
const resultColumns = [
{
title: renderTitle(
@@ -144,7 +161,7 @@ const useColumnSettings = (options: {
unit: 'ms',
render: (text: number) => (
<AutoTooltip ghost minWidth={20}>
{_.round(text, 2)}
{_.round(text, 2) || '-'}
</AutoTooltip>
)
},
@@ -158,7 +175,7 @@ const useColumnSettings = (options: {
unit: 'ms',
render: (text: number) => (
<AutoTooltip ghost minWidth={20}>
{_.round(text, 2)}
{_.round(text, 2) || '-'}
</AutoTooltip>
)
},
@@ -170,7 +187,7 @@ const useColumnSettings = (options: {
dataIndex: 'inter_token_latency_mean',
path: 'inter_token_latency_mean',
unit: 'ms',
render: (value: number) => round(value, 2)
render: (value: number) => round(value, 2) || '-'
},
{
title: 'RPS',
@@ -178,7 +195,7 @@ const useColumnSettings = (options: {
sorter: tableSorter(1),
render: (text: string) => (
<AutoTooltip ghost minWidth={20}>
{_.round(text, 2)}
{_.round(text, 2) || '-'}
</AutoTooltip>
)
},
@@ -193,9 +210,14 @@ const useColumnSettings = (options: {
path: 'tokens_per_second_mean',
unit: 'Tokens/s',
sorter: tableSorter(1),
render: (text: number) => (
<AutoTooltip ghost minWidth={20}>
{_.round(text, 2)}
render: (text: number, record: any) => (
<AutoTooltip
ghost
minWidth={20}
showTitle
title={<InfoColumn fieldList={fieldList} data={record}></InfoColumn>}
>
{_.round(text, 2) || '-'}
</AutoTooltip>
)
},
@@ -213,7 +235,7 @@ const useColumnSettings = (options: {
unit: 'Tokens/s',
render: (value: number) => (
<AutoTooltip ghost minWidth={20}>
{round(value, 2)}
{round(value, 2) || 0}
</AutoTooltip>
)
},
@@ -231,7 +253,7 @@ const useColumnSettings = (options: {
unit: 'Tokens/s',
render: (value: number) => (
<AutoTooltip ghost minWidth={20}>
{round(value, 2)}
{round(value, 2) || 0}
</AutoTooltip>
)
},
@@ -249,14 +271,53 @@ const useColumnSettings = (options: {
),
unit: ''
}
// {
// title: renderTitle(
// intl.formatMessage({ id: 'benchmark.detail.requests.success' })
// ),
// dataIndex: 'successful_requests',
// path: ['raw_metrics', 'benchmarks', '0'],
// render: (value: number) =>
// round(_.get(value, ['metrics', 'request_totals', 'successful']), 0) ||
// 0,
// precision: 0,
// color: 'var(--ant-color-success)',
// unit: ''
// },
// {
// title: renderTitle(
// intl.formatMessage({ id: 'benchmark.detail.requests.failed' })
// ),
// dataIndex: 'failed_requests',
// path: ['raw_metrics', 'benchmarks', '0'],
// render: (value: number) =>
// round(_.get(value, ['metrics', 'request_totals', 'errored']), 0) || 0,
// precision: 0,
// color: 'var(--ant-color-error)',
// unit: ''
// },
// {
// title: renderTitle(
// intl.formatMessage({
// id: 'benchmark.detail.requests.concurrency'
// })
// ),
// dataIndex: 'request_concurrency',
// path: ['raw_metrics', 'benchmarks', '0'],
// render: (value: number) =>
// round(_.get(value, 'metrics.request_concurrency.successful.mean'), 0) ||
// 0,
// precision: 0,
// unit: ''
// }
];
const metadataColumns = [
{
title: (
<AutoTooltip ghost minWidth={20}>
<Typography.Text ellipsis={{ tooltip: true }}>
{intl.formatMessage({ id: 'clusters.title' })}
</AutoTooltip>
</Typography.Text>
),
dataIndex: 'cluster_id',
render: (text: number) => (
@@ -266,8 +327,10 @@ const useColumnSettings = (options: {
)
},
{
title: renderTitle(
intl.formatMessage({ id: 'benchmark.detail.modelName' })
title: (
<Typography.Text ellipsis={{ tooltip: true }}>
{intl.formatMessage({ id: 'benchmark.detail.modelName' })}
</Typography.Text>
),
dataIndex: 'model_name',
sorter: tableSorter(1),
@@ -287,7 +350,11 @@ const useColumnSettings = (options: {
)
},
{
title: renderTitle(intl.formatMessage({ id: 'benchmark.form.profile' })),
title: (
<Typography.Text ellipsis={{ tooltip: true }}>
{intl.formatMessage({ id: 'benchmark.form.profile' })}
</Typography.Text>
),
dataIndex: 'profile',
render: (text: string) => (
<AutoTooltip ghost minWidth={20}>
@@ -8,7 +8,8 @@ import React, { forwardRef, useImperativeHandle } from 'react';
import APIKeys from './api-keys';
import ProxyConfig from './proxy-config';
const referLink = `https://higress.cn/docs/latest/plugins/ai/api-provider/ai-proxy/?spm=36971b57.3562eb7c.0.0.31764f5f7uLs2F#%E6%8F%90%E4%BE%9B%E5%95%86%E7%89%B9%E6%9C%89%E9%85%8D%E7%BD%AE`;
const referLinkZh = `https://higress.cn/docs/latest/plugins/ai/api-provider/ai-proxy/?spm=36971b57.3562eb7c.0.0.31764f5f7uLs2F#%E6%8F%90%E4%BE%9B%E5%95%86%E7%89%B9%E6%9C%89%E9%85%8D%E7%BD%AE`;
const referLinkEn = `https://higress.cn/en/docs/latest/plugins/ai/api-provider/ai-proxy/?spm=36971b57.4a688c53.0.0.64ac436ewz1xGA`;
const AdvanceConfig: React.FC<{
action: PageActionType;
@@ -19,6 +20,8 @@ const AdvanceConfig: React.FC<{
const editorRef = React.useRef<any>(null);
const [fileContent, setFileContent] = React.useState<string>('');
const referLink = intl.locale === 'zh-CN' ? referLinkZh : referLinkEn;
useImperativeHandle(ref, () => ({
getYamlValue: () => {
return editorRef.current?.getValue();