chore: benchmark detail locales
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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'
|
||||
};
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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'
|
||||
};
|
||||
|
||||
@@ -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': '利用率',
|
||||
|
||||
@@ -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'
|
||||
};
|
||||
|
||||
@@ -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': 'Использование',
|
||||
|
||||
@@ -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 核心数'
|
||||
};
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: '',
|
||||
|
||||
@@ -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)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user