chore: benchmark detail locales

This commit is contained in:
jialin
2026-02-01 20:22:25 +08:00
parent 7b4d60b576
commit 043218937f
23 changed files with 450 additions and 242 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ import { createFromIconfontCN } from '@ant-design/icons';
// import './iconfont/iconfont.js';
const IconFont = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/c/font_4613488_mis8x88kojd.js'
scriptUrl: '//at.alicdn.com/t/c/font_4613488_pxk0gz02dig.js'
});
export default IconFont;
+54 -1
View File
@@ -1,6 +1,7 @@
export default {
'benchmark.title': 'Benchmarks',
'benchmark.button.add': 'Add Benchmark',
'benchmark.button.edit': 'Edit Benchmark',
'benchmark.button.compare': 'Compare',
'benchmark.table.model': 'Model',
'benchmark.table.instance': 'Model Instance',
@@ -26,5 +27,57 @@ export default {
'benchmark.detail.summary.title': 'Summary',
'benchmark.detail.configure.title': 'Configure',
'benchmark.detail.environment.title': 'Environment',
'benchmark.detail.logs.title': 'Logs'
'benchmark.detail.logs.title': 'Logs',
'benchmark.form.totalRequests.tips': 'Total Requests',
'benchmark.form.profile.latency.tips':
'Single-request latency benchmark focusing on TTFT and tail latency. Suitable for API serving and chat scenarios.',
'benchmark.form.profile.throughput.tips':
'Max throughput with realistic prompt length. The most commonly used baseline for GPU and model comparison.',
'benchmark.form.profile.longContext.tips':
'Stress test for long-context handling. Evaluates KV cache behavior, memory usage, and backend stability.',
'benchmark.form.profile.heavy.tips':
'Decode-heavy generation benchmark. Measures sustained decoding speed and output token throughput.',
'benchmark.table.filter.bygpu': 'Filter by GPU',
'benchmark.table.filter.bymodel': 'Filter by Model',
'benchmark.table.filter.bydataset': 'Filter by Dataset',
'benchmark.table.avg': 'Average',
'benchmark.table.columnSettings': 'Column Settings',
'benchmark.detail.summary.results': 'Test Results',
'benchmark.detail.summary.metrics': 'Test Metrics',
'benchmark.detail.summary.latency': 'Latency',
'benchmark.detail.summary.throughput': 'Throughput',
'benchmark.detail.summary.request': 'Requests',
'benchmark.detail.avg.reqLatency': 'Average Request Latency',
'benchmark.detail.avg.ttft': 'Average TTFT',
'benchmark.detail.avg.tpot': 'Average TPOT',
'benchmark.detail.avg.itl': 'Average ITL',
'benchmark.detail.throughput.totalToken': 'Total Token Throughput',
'benchmark.detail.throughput.inputToken': 'Input Token Throughput',
'benchmark.detail.throughput.outputToken': 'Output Token Throughput',
'benchmark.detail.requests.total': 'Total Requests',
'benchmark.detail.requests.success': 'Successful Requests',
'benchmark.detail.requests.failed': 'Failed Requests',
'benchmark.detail.requests.concurrency': 'Concurrency',
'benchmark.detail.percentile.latency': 'Latency',
'benchmark.detail.percentile.inputTokens': 'Input Tokens',
'benchmark.detail.percentile.outputTokens': 'Output Tokens',
'benchmark.detail.percentile.input': 'Input',
'benchmark.detail.percentile.output': 'Output',
'benchmark.detail.percentile.total': 'Total',
'benchmark.detail.configure.tokenLength': 'Token Length (Input/Output)',
'benchmark.detail.percentile.title': 'Percentile',
'benchmark.detail.modelName': 'Model Name',
'benchmark.detail.instanceName': 'Instance Name',
'benchmark.detail.configure': 'Configuration',
'benchmark.detail.modelFile': 'Model File',
'benchmark.detail.kvCache': 'Extended KV Cache',
'benchmark.detail.speculativeDecoding': 'Speculative Decoding',
'benchmark.detail.inputOutputTokenLength': 'Token Length (Input/Output)',
'benchmark.env.gpuName': 'GPU Name',
'benchmark.env.workerName': 'Worker Name',
'benchmark.env.index': 'Index',
'benchmark.env.system': 'System',
'benchmark.env.runtimeVersion': 'Runtime Version',
'benchmark.env.driverVersion': 'Driver Version',
'benchmark.env.cpuCounts': 'CPU Counts'
};
+1 -1
View File
@@ -30,7 +30,7 @@ export default {
'resources.table.vram': 'VRAM',
'resources.table.index': 'Index',
'resources.table.workername': 'Worker Name',
'resources.table.vender': 'Vendor',
'resources.table.vendor': 'Vendor',
'resources.table.temperature': 'Temperature',
'resources.table.core': 'Cores',
'resources.table.utilization': 'Utilization',
+54 -1
View File
@@ -1,6 +1,7 @@
export default {
'benchmark.title': 'Benchmarks',
'benchmark.button.add': 'Add Benchmark',
'benchmark.button.edit': 'Edit Benchmark',
'benchmark.button.compare': 'Compare',
'benchmark.table.model': 'Model',
'benchmark.table.instance': 'Model Instance',
@@ -26,5 +27,57 @@ export default {
'benchmark.detail.summary.title': 'Summary',
'benchmark.detail.configure.title': 'Configure',
'benchmark.detail.environment.title': 'Environment',
'benchmark.detail.logs.title': 'Logs'
'benchmark.detail.logs.title': 'Logs',
'benchmark.form.totalRequests.tips': 'Total Requests',
'benchmark.form.profile.latency.tips':
'Single-request latency benchmark focusing on TTFT and tail latency. Suitable for API serving and chat scenarios.',
'benchmark.form.profile.throughput.tips':
'Max throughput with realistic prompt length. The most commonly used baseline for GPU and model comparison.',
'benchmark.form.profile.longContext.tips':
'Stress test for long-context handling. Evaluates KV cache behavior, memory usage, and backend stability.',
'benchmark.form.profile.heavy.tips':
'Decode-heavy generation benchmark. Measures sustained decoding speed and output token throughput.',
'benchmark.table.filter.bygpu': 'Filter by GPU',
'benchmark.table.filter.bymodel': 'Filter by Model',
'benchmark.table.filter.bydataset': 'Filter by Dataset',
'benchmark.table.avg': 'Average',
'benchmark.table.columnSettings': 'Column Settings',
'benchmark.detail.summary.results': 'Test Results',
'benchmark.detail.summary.metrics': 'Test Metrics',
'benchmark.detail.summary.latency': 'Latency',
'benchmark.detail.summary.throughput': 'Throughput',
'benchmark.detail.summary.request': 'Requests',
'benchmark.detail.avg.reqLatency': 'Average Request Latency',
'benchmark.detail.avg.ttft': 'Average TTFT',
'benchmark.detail.avg.tpot': 'Average TPOT',
'benchmark.detail.avg.itl': 'Average ITL',
'benchmark.detail.throughput.totalToken': 'Total Token Throughput',
'benchmark.detail.throughput.inputToken': 'Input Token Throughput',
'benchmark.detail.throughput.outputToken': 'Output Token Throughput',
'benchmark.detail.requests.total': 'Total Requests',
'benchmark.detail.requests.success': 'Successful Requests',
'benchmark.detail.requests.failed': 'Failed Requests',
'benchmark.detail.requests.concurrency': 'Concurrency',
'benchmark.detail.percentile.latency': 'Latency',
'benchmark.detail.percentile.inputTokens': 'Input Tokens',
'benchmark.detail.percentile.outputTokens': 'Output Tokens',
'benchmark.detail.percentile.input': 'Input',
'benchmark.detail.percentile.output': 'Output',
'benchmark.detail.percentile.total': 'Total',
'benchmark.detail.configure.tokenLength': 'Token Length (Input/Output)',
'benchmark.detail.percentile.title': 'Percentile',
'benchmark.detail.modelName': 'Model Name',
'benchmark.detail.instanceName': 'Instance Name',
'benchmark.detail.configure': 'Configuration',
'benchmark.detail.modelFile': 'Model File',
'benchmark.detail.kvCache': 'Extended KV Cache',
'benchmark.detail.speculativeDecoding': 'Speculative Decoding',
'benchmark.detail.inputOutputTokenLength': 'Token Length (Input/Output)',
'benchmark.env.gpuName': 'GPU Name',
'benchmark.env.workerName': 'Worker Name',
'benchmark.env.index': 'Index',
'benchmark.env.system': 'System',
'benchmark.env.runtimeVersion': 'Runtime Version',
'benchmark.env.driverVersion': 'Driver Version',
'benchmark.env.cpuCounts': 'CPU Counts'
};
+1 -1
View File
@@ -29,7 +29,7 @@ export default {
'resources.table.vram': 'VRAM',
'resources.table.index': 'インデックス',
'resources.table.workername': 'ワーカー名',
'resources.table.vender': 'ベンダー',
'resources.table.vendor': 'ベンダー',
'resources.table.temperature': '温度',
'resources.table.core': 'コア数',
'resources.table.utilization': '利用率',
+54 -1
View File
@@ -1,6 +1,7 @@
export default {
'benchmark.title': 'Benchmarks',
'benchmark.button.add': 'Add Benchmark',
'benchmark.button.edit': 'Edit Benchmark',
'benchmark.button.compare': 'Compare',
'benchmark.table.model': 'Model',
'benchmark.table.instance': 'Model Instance',
@@ -26,5 +27,57 @@ export default {
'benchmark.detail.summary.title': 'Summary',
'benchmark.detail.configure.title': 'Configure',
'benchmark.detail.environment.title': 'Environment',
'benchmark.detail.logs.title': 'Logs'
'benchmark.detail.logs.title': 'Logs',
'benchmark.form.totalRequests.tips': 'Total Requests',
'benchmark.form.profile.latency.tips':
'Single-request latency benchmark focusing on TTFT and tail latency. Suitable for API serving and chat scenarios.',
'benchmark.form.profile.throughput.tips':
'Max throughput with realistic prompt length. The most commonly used baseline for GPU and model comparison.',
'benchmark.form.profile.longContext.tips':
'Stress test for long-context handling. Evaluates KV cache behavior, memory usage, and backend stability.',
'benchmark.form.profile.heavy.tips':
'Decode-heavy generation benchmark. Measures sustained decoding speed and output token throughput.',
'benchmark.table.filter.bygpu': 'Filter by GPU',
'benchmark.table.filter.bymodel': 'Filter by Model',
'benchmark.table.filter.bydataset': 'Filter by Dataset',
'benchmark.table.avg': 'Average',
'benchmark.table.columnSettings': 'Column Settings',
'benchmark.detail.summary.results': 'Test Results',
'benchmark.detail.summary.metrics': 'Test Metrics',
'benchmark.detail.summary.latency': 'Latency',
'benchmark.detail.summary.throughput': 'Throughput',
'benchmark.detail.summary.request': 'Requests',
'benchmark.detail.avg.reqLatency': 'Average Request Latency',
'benchmark.detail.avg.ttft': 'Average TTFT',
'benchmark.detail.avg.tpot': 'Average TPOT',
'benchmark.detail.avg.itl': 'Average ITL',
'benchmark.detail.throughput.totalToken': 'Total Token Throughput',
'benchmark.detail.throughput.inputToken': 'Input Token Throughput',
'benchmark.detail.throughput.outputToken': 'Output Token Throughput',
'benchmark.detail.requests.total': 'Total Requests',
'benchmark.detail.requests.success': 'Successful Requests',
'benchmark.detail.requests.failed': 'Failed Requests',
'benchmark.detail.requests.concurrency': 'Concurrency',
'benchmark.detail.percentile.latency': 'Latency',
'benchmark.detail.percentile.inputTokens': 'Input Tokens',
'benchmark.detail.percentile.outputTokens': 'Output Tokens',
'benchmark.detail.percentile.input': 'Input',
'benchmark.detail.percentile.output': 'Output',
'benchmark.detail.percentile.total': 'Total',
'benchmark.detail.configure.tokenLength': 'Token Length (Input/Output)',
'benchmark.detail.percentile.title': 'Percentile',
'benchmark.detail.modelName': 'Model Name',
'benchmark.detail.instanceName': 'Instance Name',
'benchmark.detail.configure': 'Configuration',
'benchmark.detail.modelFile': 'Model File',
'benchmark.detail.kvCache': 'Extended KV Cache',
'benchmark.detail.speculativeDecoding': 'Speculative Decoding',
'benchmark.detail.inputOutputTokenLength': 'Token Length (Input/Output)',
'benchmark.env.gpuName': 'GPU Name',
'benchmark.env.workerName': 'Worker Name',
'benchmark.env.index': 'Index',
'benchmark.env.system': 'System',
'benchmark.env.runtimeVersion': 'Runtime Version',
'benchmark.env.driverVersion': 'Driver Version',
'benchmark.env.cpuCounts': 'CPU Counts'
};
+1 -1
View File
@@ -29,7 +29,7 @@ export default {
'resources.table.vram': 'VRAM',
'resources.table.index': 'Индекс',
'resources.table.workername': 'Имя воркера',
'resources.table.vender': 'Производитель',
'resources.table.vendor': 'Производитель',
'resources.table.temperature': 'Температура',
'resources.table.core': 'Ядра',
'resources.table.utilization': 'Использование',
+54 -1
View File
@@ -1,6 +1,7 @@
export default {
'benchmark.title': '基准测试',
'benchmark.button.add': '添加基准测试',
'benchmark.button.edit': '编辑基准测试',
'benchmark.button.compare': '对比',
'benchmark.table.model': '模型',
'benchmark.table.instance': '模型实例',
@@ -16,6 +17,7 @@ export default {
'benchmark.table.outputLen': '输出长度',
'benchmark.form.profile': '模式',
'benchmark.form.totalRequests': '总请求数',
'benchmark.form.totalRequests.tips': '总请求数',
'benchmark.form.profile.latency': '延迟',
'benchmark.form.profile.throughput': '吞吐',
'benchmark.form.profile.longContext': '长上下文',
@@ -26,5 +28,56 @@ export default {
'benchmark.detail.summary.title': '摘要',
'benchmark.detail.configure.title': '配置',
'benchmark.detail.environment.title': '环境',
'benchmark.detail.logs.title': '日志'
'benchmark.detail.logs.title': '日志',
'benchmark.form.profile.latency.tips':
'单请求延迟测试,关注 TTFT 与尾延迟。适用于 API 服务和聊天场景。',
'benchmark.form.profile.throughput.tips':
'在真实提示长度下测试最大吞吐量。常用于 GPU 与模型性能对比的基准。',
'benchmark.form.profile.longContext.tips':
'长上下文压力测试。评估 KV Cache 行为、内存占用及后端稳定性。',
'benchmark.form.profile.heavy.tips':
'以解码为主的生成测试。衡量持续解码速度与输出 Token 吞吐能力。',
'benchmark.table.filter.bygpu': '按 GPU 过滤',
'benchmark.table.filter.bymodel': '按模型过滤',
'benchmark.table.filter.bydataset': '按数据集过滤',
'benchmark.table.avg': '均值',
'benchmark.table.columnSettings': '列设置',
'benchmark.detail.summary.results': '测试结果',
'benchmark.detail.summary.metrics': '测试指标',
'benchmark.detail.summary.latency': '延迟',
'benchmark.detail.summary.throughput': '吞吐',
'benchmark.detail.summary.request': '请求数',
'benchmark.detail.avg.reqLatency': '平均请求延迟',
'benchmark.detail.avg.ttft': '平均 TTFT',
'benchmark.detail.avg.tpot': '平均 TPOT',
'benchmark.detail.avg.itl': '平均 ITL',
'benchmark.detail.throughput.totalToken': '总 Token 吞吐量',
'benchmark.detail.throughput.inputToken': '输入 Token 吞吐量',
'benchmark.detail.throughput.outputToken': '输出 Token 吞吐量',
'benchmark.detail.requests.total': '请求总数',
'benchmark.detail.requests.success': '请求成功数',
'benchmark.detail.requests.failed': '请求失败数',
'benchmark.detail.requests.concurrency': '请求并发数',
'benchmark.detail.percentile.latency': '延迟',
'benchmark.detail.percentile.inputTokens': '输入 Token',
'benchmark.detail.percentile.outputTokens': '输出 Token',
'benchmark.detail.percentile.input': '输入',
'benchmark.detail.percentile.output': '输出',
'benchmark.detail.percentile.total': '总量',
'benchmark.detail.configure.tokenLength': 'Token 长度 (输入/输出)',
'benchmark.detail.percentile.title': '百分位数',
'benchmark.detail.modelName': '模型名称',
'benchmark.detail.instanceName': '实例名称',
'benchmark.detail.configure': '测试配置',
'benchmark.detail.modelFile': '模型文件',
'benchmark.detail.kvCache': '扩展 KV 缓存',
'benchmark.detail.speculativeDecoding': '推测解码',
'benchmark.detail.inputOutputTokenLength': 'Token 长度 (输入/输出)',
'benchmark.env.gpuName': 'GPU 名称',
'benchmark.env.workerName': '节点名称',
'benchmark.env.index': '序号',
'benchmark.env.system': '系统',
'benchmark.env.runtimeVersion': '运行时版本',
'benchmark.env.driverVersion': '驱动版本',
'benchmark.env.cpuCounts': 'CPU 核心数'
};
+1 -1
View File
@@ -30,7 +30,7 @@ export default {
'resources.table.vram': '显存',
'resources.table.index': '序号',
'resources.table.workername': '节点名称',
'resources.table.vender': '厂商',
'resources.table.vendor': '厂商',
'resources.table.temperature': '温度',
'resources.table.core': '核数',
'resources.table.gpuutilization': 'GPU 利用率',
@@ -3,6 +3,7 @@ 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 { useIntl } from '@umijs/max';
import useMemoizedFn from 'ahooks/lib/useMemoizedFn';
import { Col, Row, Tag } from 'antd';
import _ from 'lodash';
@@ -17,6 +18,7 @@ const Container = styled.div`
`;
const Environment: React.FC = () => {
const intl = useIntl();
const { detailData } = useDetailContext();
const { snapshot } = detailData;
@@ -57,9 +59,16 @@ const Environment: React.FC = () => {
});
}, [snapshot, mainWorker]);
const GPUColumns = [
const GPUColumns: {
title: string;
dataIndex: string;
key: string;
span: number;
colStyle?: React.CSSProperties;
render?: (value: any, record: any) => React.ReactNode;
}[] = [
{
title: 'GPU Name',
title: intl.formatMessage({ id: 'benchmark.env.gpuName' }),
dataIndex: 'name',
key: 'name',
span: 6,
@@ -69,32 +78,30 @@ const Environment: React.FC = () => {
)
},
{
title: 'Index',
title: intl.formatMessage({ id: 'benchmark.env.index' }),
dataIndex: 'index',
key: 'index',
span: 4,
colStyle: { paddingLeft: 48 }
},
{
title: 'Vendor',
title: intl.formatMessage({ id: 'resources.table.vendor' }),
dataIndex: 'vendor',
key: 'vendor',
span: 6,
colStyle: { paddingLeft: 110 }
},
{
title: 'VRAM',
title: intl.formatMessage({ id: 'resources.table.vram' }),
dataIndex: 'memory_total',
key: 'memory_total',
label: 'VRAM',
span: 4,
render: (value: number, record: any) => convertFileSize(value)
},
{
title: 'Cores',
title: intl.formatMessage({ id: 'resources.table.core' }),
dataIndex: 'core_total',
key: 'core_total',
label: 'Cores',
span: 4,
colStyle: { paddingLeft: 36 }
}
@@ -102,7 +109,7 @@ const Environment: React.FC = () => {
const columns = [
{
title: 'Worker Name',
title: intl.formatMessage({ id: 'benchmark.env.workerName' }),
dataIndex: 'name',
key: 'name',
span: 6,
@@ -120,7 +127,7 @@ const Environment: React.FC = () => {
}
},
{
title: 'System',
title: intl.formatMessage({ id: 'benchmark.env.system' }),
dataIndex: 'os',
key: 'system',
span: 5,
@@ -133,7 +140,7 @@ const Environment: React.FC = () => {
}
},
{
title: 'Runtime Version',
title: intl.formatMessage({ id: 'benchmark.env.runtimeVersion' }),
dataIndex: 'runtime_version',
key: 'runtime_version',
span: 3,
@@ -142,7 +149,7 @@ const Environment: React.FC = () => {
}
},
{
title: 'Driver Version',
title: intl.formatMessage({ id: 'benchmark.env.driverVersion' }),
dataIndex: 'driver_version',
key: 'driver_version',
span: 3,
@@ -151,13 +158,13 @@ const Environment: React.FC = () => {
}
},
{
title: 'CPU Count',
title: intl.formatMessage({ id: 'benchmark.env.cpuCounts' }),
dataIndex: 'cpu_total',
key: 'cpu_total',
span: 3
},
{
title: 'Memory',
title: intl.formatMessage({ id: 'resources.table.memory' }),
dataIndex: 'memory_total',
key: 'memory_total',
span: 4,
@@ -218,8 +225,8 @@ const Environment: React.FC = () => {
}}
>
{col.render
? col.render((gpu as any)[col.dataIndex], gpu)
: (gpu as any)[col.dataIndex]}
? col.render(gpu[col.dataIndex], gpu)
: gpu[col.dataIndex]}
</span>
</Col>
))}
@@ -52,14 +52,16 @@ const RightActions: React.FC<RightActionsProps> = ({
style={{ color: 'var(--ant-color-text-placeholder)' }}
></SearchOutlined>
}
placeholder="Filter by GPU"
placeholder={intl.formatMessage({ id: 'benchmark.table.filter.bygpu' })}
style={{ width: 180 }}
allowClear
onChange={handleGPUChange}
></Input>
<BaseSelect
allowClear
placeholder="Filter by model"
placeholder={intl.formatMessage({
id: 'benchmark.table.filter.bymodel'
})}
style={{ width: 200 }}
options={modelList}
onChange={(value, option) =>
@@ -71,7 +73,9 @@ const RightActions: React.FC<RightActionsProps> = ({
></BaseSelect>
<BaseSelect
allowClear
placeholder="Filter by dataset"
placeholder={intl.formatMessage({
id: 'benchmark.table.filter.bydataset'
})}
style={{ width: 200 }}
options={datasetList?.map((item) => ({
...item,
@@ -4,14 +4,12 @@ import {
DownloadOutlined,
PlusOutlined
} from '@ant-design/icons';
import { useIntl } from '@umijs/max';
import { Button, Space } from 'antd';
import React from 'react';
export interface RightActionsProps {
handleDeleteByBatch: () => void;
handleClickPrimary?: () => void;
handleSettingFields?: () => void;
handleExport?: () => void;
settingButton?: React.ReactNode;
buttonText?: string;
@@ -23,13 +21,11 @@ export interface RightActionsProps {
const RightActions: React.FC<RightActionsProps> = ({
handleDeleteByBatch,
handleClickPrimary,
handleSettingFields,
handleExport,
settingButton,
buttonText,
rowSelection
}) => {
const intl = useIntl();
const ButtonList = [
{
label: 'common.button.export',
@@ -56,13 +52,7 @@ const RightActions: React.FC<RightActionsProps> = ({
return (
<Space size={16}>
{/* <Tooltip title="Column Settings">
<Button
onClick={handleSettingFields}
icon={<SettingOutlined />}
></Button>
</Tooltip> */}
{/* {settingButton} */}
{settingButton}
<Button
icon={<PlusOutlined></PlusOutlined>}
type="primary"
@@ -70,19 +60,6 @@ const RightActions: React.FC<RightActionsProps> = ({
>
{buttonText}
</Button>
{/* <Button
icon={<DeleteOutlined />}
danger
onClick={handleDeleteByBatch}
disabled={!rowSelection?.selectedRowKeys?.length}
>
<span>
{intl?.formatMessage?.({ id: 'common.button.delete' })}
{rowSelection?.selectedRowKeys?.length > 0 && (
<span>({rowSelection?.selectedRowKeys?.length})</span>
)}
</span>
</Button> */}
<DropdownButtons
items={ButtonList}
extra={
@@ -1,24 +1,28 @@
import { useIntl } from '@umijs/max';
import { Descriptions, DescriptionsProps } from 'antd';
import React from 'react';
import { useDetailContext } from '../../config/detail-context';
const Benchmark: React.FC = () => {
const intl = useIntl();
const { detailData } = useDetailContext();
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'Profile',
label: intl.formatMessage({ id: 'benchmark.form.profile' }),
children: detailData?.profile || '-'
},
{
key: '2',
label: 'Dataset',
label: intl.formatMessage({ id: 'benchmark.table.dataset' }),
children: detailData?.dataset_name || '-'
},
{
key: '3',
label: 'Token Length (Input/Output)',
label: intl.formatMessage({
id: 'benchmark.detail.inputOutputTokenLength'
}),
children: (
<span>
{detailData?.dataset_input_tokens || '-'} /{' '}
@@ -28,24 +32,23 @@ const Benchmark: React.FC = () => {
},
{
key: '7',
label: 'Total Requests',
label: intl.formatMessage({ id: 'benchmark.form.totalRequests' }),
children: detailData?.total_requests || '-'
},
{
key: '6',
label: 'Request Rate',
label: intl.formatMessage({ id: 'benchmark.table.requestRate' }),
children: detailData?.request_rate || '-'
},
{
key: '5',
label: 'Seed',
label: intl.formatMessage({ id: 'playground.image.params.seed' }),
children: detailData?.seed || '-'
}
];
return (
<div>
<span>Parameters</span>
<Descriptions
items={items}
colon={false}
@@ -1,3 +1,4 @@
import { useIntl } from '@umijs/max';
import { Divider } from 'antd';
import React from 'react';
import styled from 'styled-components';
@@ -14,14 +15,18 @@ const Container = styled.div`
`;
const Summary: React.FC = () => {
const intl = useIntl();
return (
<Container>
<Section title="Results" minHeight={450}>
<Section
title={intl.formatMessage({ id: 'benchmark.detail.summary.results' })}
minHeight={450}
>
<MetricsResult />
<Divider />
<PercentileResult />
</Section>
<Section title="Benchmark Details">
<Section title={intl.formatMessage({ id: 'benchmark.detail.configure' })}>
<Instance />
<Divider />
<BenchMark />
@@ -1,4 +1,5 @@
import AutoTooltip from '@/components/auto-tooltip';
import { useIntl } from '@umijs/max';
import { Descriptions, Flex, Tag } from 'antd';
import _ from 'lodash';
import React, { useMemo } from 'react';
@@ -9,6 +10,7 @@ const calcTotalVram = (vram: Record<string, number>) => {
};
const Instance: React.FC = () => {
const intl = useIntl();
const { detailData } = useDetailContext();
const [, instanceData] =
Object.entries(detailData?.snapshot?.instances || {})[0] || [];
@@ -20,14 +22,14 @@ const Instance: React.FC = () => {
return [
{
key: '1',
label: 'Model Name',
label: intl.formatMessage({ id: 'benchmark.detail.modelName' }),
children: (
<AutoTooltip ghost>{detailData?.model_name || '-'}</AutoTooltip>
)
},
{
key: '2',
label: 'Instance Name',
label: intl.formatMessage({ id: 'benchmark.detail.instanceName' }),
children: (
<AutoTooltip ghost>
{detailData?.model_instance_name || '-'}
@@ -37,7 +39,7 @@ const Instance: React.FC = () => {
{
key: '5',
label: 'Backend',
label: intl.formatMessage({ id: 'models.form.backend' }),
children: `${instanceData?.backend || '-'} ${
instanceData?.backend_version
? `(${instanceData?.backend_version})`
@@ -46,7 +48,7 @@ const Instance: React.FC = () => {
},
{
key: '6',
label: 'Model File',
label: intl.formatMessage({ id: 'benchmark.detail.modelFile' }),
children: (
<AutoTooltip ghost>{instanceData?.resolved_path || '-'}</AutoTooltip>
)
@@ -61,7 +63,7 @@ const Instance: React.FC = () => {
return [
{
key: '1',
label: 'Backend Parameters',
label: intl.formatMessage({ id: 'models.form.backend_parameters' }),
children: (
<Flex
gap={8}
@@ -84,21 +86,27 @@ const Instance: React.FC = () => {
},
{
key: '3',
label: 'Extended KV Cache',
label: intl.formatMessage({ id: 'benchmark.detail.kvCache' }),
children: (
<Flex gap={8} wrap="wrap">
{instanceData?.extended_kv_cache?.enabled ? (
<>
<span className="flex-center">
<span>RAM-to-VRAM Ratio:</span>
<span>
{intl.formatMessage({ id: 'models.form.ramRatio' })}:
</span>
<span>{instanceData?.extended_kv_cache?.ram_ratio}</span>
</span>
<span className="flex-center">
<span>Maximum RAM Size (GiB):</span>
<span>
{intl.formatMessage({ id: 'models.form.ramSize' })}:
</span>
<span>{instanceData?.extended_kv_cache?.ram_size}</span>
</span>
<span className="flex-center">
<span>Size of Cache Chunks:</span>
<span>
{intl.formatMessage({ id: 'models.form.chunkSize' })}:
</span>
<span>{instanceData?.extended_kv_cache?.chunk_size}</span>
</span>
</>
@@ -110,21 +118,29 @@ const Instance: React.FC = () => {
},
{
key: '4',
label: 'Speculative Decoding',
label: intl.formatMessage({
id: 'benchmark.detail.speculativeDecoding'
}),
children: (
<Flex gap={8} wrap="wrap">
{instanceData?.speculative_config?.enabled ? (
<>
<span className="flex-center">
<span>Algorithm:</span>
<span>
{intl.formatMessage({ id: 'models.form.algorithm' })}:
</span>
<span>{instanceData?.speculative_config?.algorithm}</span>
</span>
<span className="flex-center">
<span>Draft Model:</span>
<span>
{intl.formatMessage({ id: 'models.form.draftModel' })}:
</span>
<span>{instanceData?.speculative_config?.draft_model}</span>
</span>
<span className="flex-center">
<span>Number of Draft Tokens:</span>
<span>
{intl.formatMessage({ id: 'models.form.numDraftTokens' })}:
</span>
<span>
{instanceData?.speculative_config?.num_draft_tokens}
</span>
@@ -138,7 +154,7 @@ const Instance: React.FC = () => {
},
{
key: '2',
label: 'Environment Variables',
label: intl.formatMessage({ id: 'models.form.env' }),
children: (
<Flex gap={8} wrap="wrap">
{instanceData?.env
@@ -158,7 +174,6 @@ const Instance: React.FC = () => {
return (
<div>
<span>Instance</span>
<Descriptions
items={items}
colon={false}
@@ -1,75 +1,33 @@
import { useIntl } from '@umijs/max';
import { Descriptions } from 'antd';
import _, { round } from 'lodash';
import React from 'react';
import styled from 'styled-components';
import { useDetailContext } from '../../config/detail-context';
const Card = styled.div`
height: 78px;
padding: 12px 16px;
border: 1px solid var(--ant-color-border);
border-radius: var(--ant-border-radius);
background-color: var(--ant-color-bg-container);
`;
const Box = styled.div`
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 16px;
`;
const DescWrapper = styled.div`
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 24px;
`;
const columns = [
// {
// title: 'Duration',
// dataIndex: 'duration',
// path: ['raw_metrics', 'benchmarks', '0', 'duration'],
// unit: 's',
// render: (value: number) => round(value, 2)
// },
// {
// title: 'Total Requests',
// dataIndex: 'total_requests',
// path: 'total_requests',
// unit: '',
// render: (value: number) => round(value, 0)
// },
const throughputColumns = [
{
title: 'Total token throughput',
title: 'benchmark.detail.throughput.totalToken',
dataIndex: 'tokens_per_second_mean',
path: 'tokens_per_second_mean',
unit: 'Tokens/s',
render: (value: number) => round(value, 2)
},
{
title: 'Input token throughput ',
title: 'benchmark.detail.throughput.inputToken',
dataIndex: 'input_tokens_per_second_mean',
path: 'input_tokens_per_second_mean',
unit: 'Tokens/s',
render: (value: number) => round(value, 2)
},
// {
// title: 'Success Requests',
// dataIndex: 'successful_requests',
// path: ['raw_metrics', 'benchmarks', '0'],
// unit: '',
// render: (value: number) => {
// return (
// <span style={{ color: 'var(--ant-color-success)' }}>
// {_.get(value, 'metrics.request_totals.successful')}
// </span>
// );
// }
// },
{
title: 'Output token throughput',
title: 'benchmark.detail.throughput.outputToken',
dataIndex: 'output_tokens_per_second_mean',
path: 'output_tokens_per_second_mean',
unit: 'Tokens/s',
@@ -77,56 +35,30 @@ const columns = [
}
];
const columnsSub = [
// {
// title: 'Failed Requests',
// dataIndex: 'failed_requests',
// path: ['raw_metrics', 'benchmarks', '0'],
// unit: '',
// render: (value: number) => {
// return (
// <span style={{ color: 'var(--ant-color-error)' }}>
// {_.get(value, 'metrics.request_totals.errored')}
// </span>
// );
// }
// },
// {
// title: 'Concurrency',
// dataIndex: 'request_concurrency',
// path: ['raw_metrics', 'benchmarks', '0'],
// unit: '',
// render: (value: number) => {
// return round(
// _.get(value, 'metrics.request_concurrency.successful.mean'),
// 0
// );
// }
// },
const latencyColumns = [
{
title: 'Average Request Latency',
title: 'benchmark.detail.avg.reqLatency',
dataIndex: 'request_latency_mean',
path: 'request_latency_mean',
unit: 'ms',
render: (value: number) => round(value, 2)
},
{
title: 'Average Time To First Token',
title: 'benchmark.detail.avg.ttft',
dataIndex: 'time_to_first_token_mean',
path: 'time_to_first_token_mean',
unit: 'ms',
render: (value: number) => round(value, 2)
},
{
title: 'Average Time Per Output Token',
title: 'benchmark.detail.avg.tpot',
dataIndex: 'time_per_output_token_mean',
path: 'time_per_output_token_mean',
unit: 'ms',
render: (value: number) => round(value, 2)
},
{
title: 'Average Inter Token Latency',
title: 'benchmark.detail.avg.itl',
dataIndex: 'inter_token_latency_mean',
path: 'inter_token_latency_mean',
unit: 'ms',
@@ -134,9 +66,9 @@ const columnsSub = [
}
];
const requestFields = [
const requestColumns = [
{
label: 'Total Requests',
label: 'benchmark.detail.requests.total',
key: 'total_requests',
dataIndex: 'total_requests',
path: 'total_requests',
@@ -145,7 +77,7 @@ const requestFields = [
unit: ''
},
{
label: 'Success Requests',
label: 'benchmark.detail.requests.success',
key: 'total_requests',
dataIndex: 'successful_requests',
path: ['raw_metrics', 'benchmarks', '0'],
@@ -156,7 +88,7 @@ const requestFields = [
unit: ''
},
{
label: 'Failed Requests',
label: 'benchmark.detail.requests.failed',
key: 'total_requests',
dataIndex: 'failed_requests',
path: ['raw_metrics', 'benchmarks', '0'],
@@ -167,7 +99,7 @@ const requestFields = [
unit: ''
},
{
label: 'Concurrency',
label: 'benchmark.detail.requests.concurrency',
key: 'request_concurrency',
dataIndex: 'request_concurrency',
path: ['raw_metrics', 'benchmarks', '0'],
@@ -185,21 +117,24 @@ const PERCENTILES = [
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 };
[...columns, ...columnsSub].forEach(({ dataIndex, path }) => {
row[dataIndex] = _.get(detailData, path) ?? 0;
});
[...throughputColumns, ...latencyColumns].forEach(
({ dataIndex, path }) => {
row[dataIndex] = _.get(detailData, path) ?? 0;
}
);
return row;
});
};
const items = [...columns, ...columnsSub].map(
const items = [...throughputColumns, ...latencyColumns].map(
({ title, dataIndex, path, render, unit }) => ({
key: dataIndex,
label: title,
@@ -214,10 +149,10 @@ const PercentileResult: React.FC = () => {
})
);
const throughputItems = columns.map(
const throughputItems = throughputColumns.map(
({ title, dataIndex, path, render, unit }) => ({
key: dataIndex,
label: title,
label: intl.formatMessage({ id: title }),
children: unit ? (
<span className="flex-center">
{render(_.get(detailData, path) ?? 0)}{' '}
@@ -229,10 +164,10 @@ const PercentileResult: React.FC = () => {
})
);
const latencyItems = columnsSub.map(
const latencyItems = latencyColumns.map(
({ title, dataIndex, path, render, unit }) => ({
key: dataIndex,
label: title,
label: intl.formatMessage({ id: title }),
children: unit ? (
<span className="flex-center">
{render(_.get(detailData, path) ?? 0)}{' '}
@@ -244,10 +179,10 @@ const PercentileResult: React.FC = () => {
})
);
const requestItems = requestFields.map(
const requestItems = requestColumns.map(
({ label, dataIndex, path, render, unit, color }) => ({
key: dataIndex,
label: label,
label: intl.formatMessage({ id: label }),
children: unit ? (
<span className="flex-center" style={{ color: color }}>
{render(_.get(detailData, path) ?? 0)}{' '}
@@ -277,25 +212,26 @@ const PercentileResult: React.FC = () => {
return (
<div>
<span>Metrics</span>
<Box>
<Descriptions
styles={descriptionStyles}
title="Latency"
title={intl.formatMessage({ id: 'benchmark.detail.summary.latency' })}
items={latencyItems}
colon={false}
column={1}
></Descriptions>
<Descriptions
styles={descriptionStyles}
title="Throughput"
title={intl.formatMessage({
id: 'benchmark.detail.summary.throughput'
})}
items={throughputItems}
colon={false}
column={1}
></Descriptions>
<Descriptions
styles={descriptionStyles}
title="Requests"
title={intl.formatMessage({ id: 'benchmark.detail.summary.request' })}
items={requestItems}
colon={false}
column={1}
@@ -1,56 +1,9 @@
import { useIntl } from '@umijs/max';
import { Table } from 'antd';
import { round } from 'lodash';
import React from 'react';
import { useDetailContext } from '../../config/detail-context';
const columns = [
{
title: 'TTFT (ms)',
dataIndex: 'time_to_first_token_ms',
render: (value: number) => round(value, 2)
},
{
title: 'ITL (ms)',
dataIndex: 'inter_token_latency_ms',
render: (value: number) => round(value, 2)
},
{
title: 'TPOT (ms)',
dataIndex: 'time_per_output_token_ms',
render: (value: number) => round(value, 2)
},
{
title: 'Latency (s)',
dataIndex: 'request_latency',
render: (value: number) => round(value, 2)
},
{
title: 'Input tokens',
dataIndex: 'prompt_token_count',
render: (value: number) => round(value, 0)
},
{
title: 'Output tokens',
dataIndex: 'output_token_count',
render: (value: number) => round(value, 0)
},
{
title: 'Input (Tokens/s)',
dataIndex: 'prompt_tokens_per_second',
render: (value: number) => round(value, 2)
},
{
title: 'Output (Tokens/s)',
dataIndex: 'output_tokens_per_second',
render: (value: number) => round(value, 2)
},
{
title: 'Total (Tokens/s)',
dataIndex: 'tokens_per_second',
render: (value: number) => round(value, 2)
}
];
const PERCENTILES = [
{ key: 'p50', label: '50%' },
{ key: 'p90', label: '90%' },
@@ -58,9 +11,62 @@ const PERCENTILES = [
] as const;
const PercentileResult: React.FC = () => {
const intl = useIntl();
const { detailData } = useDetailContext();
const metrics = detailData?.raw_metrics?.benchmarks?.[0]?.metrics || {};
const columns = [
{
title: 'TTFT (ms)',
dataIndex: 'time_to_first_token_ms',
render: (value: number) => round(value, 2)
},
{
title: 'ITL (ms)',
dataIndex: 'inter_token_latency_ms',
render: (value: number) => round(value, 2)
},
{
title: 'TPOT (ms)',
dataIndex: 'time_per_output_token_ms',
render: (value: number) => round(value, 2)
},
{
title: `${intl.formatMessage({ id: 'benchmark.detail.percentile.latency' })} (s)`,
dataIndex: 'request_latency',
render: (value: number) => round(value, 2)
},
{
title: intl.formatMessage({
id: 'benchmark.detail.percentile.inputTokens'
}),
dataIndex: 'prompt_token_count',
render: (value: number) => round(value, 0)
},
{
title: intl.formatMessage({
id: 'benchmark.detail.percentile.outputTokens'
}),
dataIndex: 'output_token_count',
render: (value: number) => round(value, 0)
},
{
title: `${intl.formatMessage({ id: 'benchmark.detail.percentile.input' })} (Tokens/s)`,
dataIndex: 'prompt_tokens_per_second',
render: (value: number) => round(value, 2)
},
{
title: `${intl.formatMessage({ id: 'benchmark.detail.percentile.output' })} (Tokens/s)`,
dataIndex: 'output_tokens_per_second',
render: (value: number) => round(value, 2)
},
{
title: `${intl.formatMessage({ id: 'benchmark.detail.percentile.total' })} (Tokens/s)`,
dataIndex: 'tokens_per_second',
render: (value: number) => round(value, 2)
}
];
const buildPercentileTable = (metrics: any) => {
return PERCENTILES.map(({ key, label }) => {
const row: any = { percentile: label };
@@ -76,12 +82,17 @@ const PercentileResult: React.FC = () => {
return (
<div>
<span>Percentile</span>
<Table
size="small"
columns={[
{
title: <span style={{ fontWeight: 500 }}>Percentile</span>,
title: (
<span style={{ fontWeight: 500 }}>
{intl.formatMessage({
id: 'benchmark.detail.percentile.title'
})}
</span>
),
dataIndex: 'percentile',
render: (value: string) => (
<span style={{ fontWeight: 500 }}>{value}</span>
+8 -9
View File
@@ -32,10 +32,10 @@ export const BenchmarkStatus: Record<string, StatusType> = {
};
export const ProfileValueMap = {
LatencyShort: 'latency_short',
ThroughputMedium: 'throughput_medium',
LongContextStress: 'long_context_stress',
GenerationHeavy: 'generation_heavy',
LatencyShort: 'Latency',
ThroughputMedium: 'Throughput',
LongContextStress: 'Long Context',
GenerationHeavy: 'Generation Heavy',
Custom: 'Custom'
};
@@ -50,28 +50,27 @@ export const ProfileLabelMap = {
export const profileOptions = [
{
label: 'benchmark.form.profile.latency',
tips: 'benchmark.form.profile.latency.tips',
value: ProfileValueMap.LatencyShort,
locale: true
},
{
label: 'benchmark.form.profile.throughput',
tips: 'benchmark.form.profile.throughput.tips',
value: ProfileValueMap.ThroughputMedium,
locale: true
},
{
label: 'benchmark.form.profile.longContext',
tips: 'benchmark.form.profile.longContext.tips',
value: ProfileValueMap.LongContextStress,
locale: true
},
{
label: 'benchmark.form.profile.heavy',
tips: 'benchmark.form.profile.heavy.tips',
value: ProfileValueMap.GenerationHeavy,
locale: true
},
{
label: 'benchmark.form.profile.custom',
value: ProfileValueMap.Custom,
locale: true
}
];
+19 -3
View File
@@ -1,8 +1,9 @@
import AutoTooltip from '@/components/auto-tooltip';
import SealSelect from '@/components/seal-form/seal-select';
import { PageAction } from '@/config';
import useAppUtils from '@/hooks/use-app-utils';
import { useIntl } from '@umijs/max';
import { Form } from 'antd';
import { Form, Select } from 'antd';
import _ from 'lodash';
import React, { useEffect } from 'react';
import { ProfileValueMap } from '../config';
@@ -68,10 +69,25 @@ const DatasetForm: React.FC = () => {
<SealSelect
disabled={action === PageAction.EDIT}
onChange={handleProfileChange}
options={profilesOptions}
label={intl.formatMessage({ id: 'benchmark.form.profile' })}
required
></SealSelect>
>
{profilesOptions?.map((item: any) => (
<Select.Option key={item.value} value={item.value}>
<AutoTooltip
ghost
showTitle={!!item.tips}
title={
item?.tips
? intl.formatMessage({ id: item?.tips || '' })
: false
}
>
{intl.formatMessage({ id: item?.label || '' })}
</AutoTooltip>
</Select.Option>
))}
</SealSelect>
</Form.Item>
<RandomSettingsForm
+9 -2
View File
@@ -77,7 +77,10 @@ const Benchmark: React.FC = () => {
}, []);
const handleAddBenchmark = () => {
openBenchmarkModal(PageAction.CREATE, 'Add Benchmark');
openBenchmarkModal(
PageAction.CREATE,
intl.formatMessage({ id: 'benchmark.button.add' })
);
};
const handleModalOk = async (data: FormData) => {
@@ -108,7 +111,11 @@ const Benchmark: React.FC = () => {
};
const handleEditUser = (row: ListItem) => {
openBenchmarkModal(PageAction.EDIT, 'Edit Benchmark', row);
openBenchmarkModal(
PageAction.EDIT,
intl.formatMessage({ id: 'benchmark.button.edit' }),
row
);
};
const handleSelect = useMemoizedFn((val: any, row: ListItem) => {
@@ -3,6 +3,7 @@ import { useIntl } from '@umijs/max';
import _ from 'lodash';
import { useState } from 'react';
import { queryProfiles } from '../apis';
import { profileOptions } from '../config';
import { ProfileOption } from '../config/types';
export default function useQueryProfiles() {
@@ -23,10 +24,16 @@ export default function useQueryProfiles() {
const fetchProfilesData = async () => {
const res = await fetchData({});
const profileMap = profileOptions.reduce((map, obj) => {
map.set(obj.value, obj);
return map;
}, new Map<string, any>());
const list =
res?.profiles?.map((item) => {
return {
label: item.name,
label: profileMap.get(item.name)?.label || item.name,
tips: profileMap.get(item.name)?.tips || '',
value: item.name,
config: {
..._.omit(item, 'name')
@@ -38,6 +45,7 @@ export default function useQueryProfiles() {
...list,
{
label: intl.formatMessage({ id: 'backend.custom' }),
tips: '',
value: 'Custom',
config: {
dataset_name: '',
+11 -3
View File
@@ -81,8 +81,10 @@ const CatalogItem: React.FC<CatalogItemProps> = (props) => {
>
<IconFont
type="icon-new_release_outlined"
className="m-r-5"
style={{ color: 'var(--ant-color-text-secondary)' }}
style={{
color: 'var(--ant-color-text-tertiary)',
marginRight: 5
}}
></IconFont>
{data.release_date}
</span>
@@ -90,7 +92,13 @@ const CatalogItem: React.FC<CatalogItemProps> = (props) => {
{_.map(data.licenses, (license: string, index: number) => {
return (
<span key={license} className="flex-center m-r-8">
<IconFont type="icon-justice1" className="m-r-5"></IconFont>
<IconFont
type="icon-license"
style={{
color: 'var(--ant-color-text-tertiary)',
marginRight: 5
}}
></IconFont>
<span>{license}</span>
</span>
);
@@ -84,7 +84,7 @@ const useGPUColumns = (props: {
)
},
{
title: intl.formatMessage({ id: 'resources.table.vender' }),
title: intl.formatMessage({ id: 'resources.table.vendor' }),
dataIndex: 'vendor',
sorter: tableSorter(5)
},