fix: benchmark issues
This commit is contained in:
@@ -171,6 +171,7 @@ export default {
|
|||||||
'playground.params.refAudio': 'Reference Audio',
|
'playground.params.refAudio': 'Reference Audio',
|
||||||
'playground.params.refAudio.tips':
|
'playground.params.refAudio.tips':
|
||||||
'Enter a reference audio URL, or upload an audio file.',
|
'Enter a reference audio URL, or upload an audio file.',
|
||||||
'playground.params.refAudio.text': 'Transcript of Reference Audio (no ICL)',
|
'playground.params.refAudio.text':
|
||||||
|
'Transcript of Reference Audio (for ICL mode)',
|
||||||
'playground.params.refAudio.vectorMode': 'Use Speaker Embedding Only (no ICL)'
|
'playground.params.refAudio.vectorMode': 'Use Speaker Embedding Only (no ICL)'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -174,7 +174,8 @@ export default {
|
|||||||
'playground.params.refAudio': 'Reference Audio',
|
'playground.params.refAudio': 'Reference Audio',
|
||||||
'playground.params.refAudio.tips':
|
'playground.params.refAudio.tips':
|
||||||
'Enter a reference audio URL, or upload an audio file.',
|
'Enter a reference audio URL, or upload an audio file.',
|
||||||
'playground.params.refAudio.text': 'Transcript of Reference Audio (no ICL)',
|
'playground.params.refAudio.text':
|
||||||
|
'Transcript of Reference Audio (for ICL mode)',
|
||||||
'playground.params.refAudio.vectorMode': 'Use Speaker Embedding Only (no ICL)'
|
'playground.params.refAudio.vectorMode': 'Use Speaker Embedding Only (no ICL)'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,8 @@ export default {
|
|||||||
'playground.params.refAudio': 'Reference Audio',
|
'playground.params.refAudio': 'Reference Audio',
|
||||||
'playground.params.refAudio.tips':
|
'playground.params.refAudio.tips':
|
||||||
'Enter a reference audio URL, or upload an audio file.',
|
'Enter a reference audio URL, or upload an audio file.',
|
||||||
'playground.params.refAudio.text': 'Transcript of Reference Audio (no ICL)',
|
'playground.params.refAudio.text':
|
||||||
|
'Transcript of Reference Audio (for ICL mode)',
|
||||||
'playground.params.refAudio.vectorMode': 'Use Speaker Embedding Only (no ICL)'
|
'playground.params.refAudio.vectorMode': 'Use Speaker Embedding Only (no ICL)'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ type AddModalProps = {
|
|||||||
open: boolean;
|
open: boolean;
|
||||||
currentData?: ListItem; // Used when action is EDIT
|
currentData?: ListItem; // Used when action is EDIT
|
||||||
clusterList?: Global.BaseOption<number>[];
|
clusterList?: Global.BaseOption<number>[];
|
||||||
|
profilesOptions?: Global.BaseOption<string>[];
|
||||||
|
datasetList?: Global.BaseOption<number | string>[];
|
||||||
onOk: (values: FormData) => void;
|
onOk: (values: FormData) => void;
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
};
|
};
|
||||||
@@ -20,6 +22,8 @@ const AddBenchmark: React.FC<AddModalProps> = ({
|
|||||||
open,
|
open,
|
||||||
currentData,
|
currentData,
|
||||||
clusterList,
|
clusterList,
|
||||||
|
profilesOptions,
|
||||||
|
datasetList,
|
||||||
onOk,
|
onOk,
|
||||||
onCancel
|
onCancel
|
||||||
}) => {
|
}) => {
|
||||||
@@ -54,6 +58,8 @@ const AddBenchmark: React.FC<AddModalProps> = ({
|
|||||||
open={open}
|
open={open}
|
||||||
currentData={currentData}
|
currentData={currentData}
|
||||||
clusterList={clusterList}
|
clusterList={clusterList}
|
||||||
|
profilesOptions={profilesOptions}
|
||||||
|
datasetList={datasetList}
|
||||||
onFinish={handleOk}
|
onFinish={handleOk}
|
||||||
/>
|
/>
|
||||||
</FormDrawer>
|
</FormDrawer>
|
||||||
|
|||||||
@@ -1,245 +0,0 @@
|
|||||||
import AutoTooltip from '@/components/auto-tooltip';
|
|
||||||
import { useIntl } from '@umijs/max';
|
|
||||||
import { Col, Descriptions, DescriptionsProps, Row, Statistic } from 'antd';
|
|
||||||
import dayjs from 'dayjs';
|
|
||||||
import _, { round } from 'lodash';
|
|
||||||
import React from 'react';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import { useDetailContext } from '../../config/detail-context';
|
|
||||||
import Section from './section';
|
|
||||||
|
|
||||||
const Container = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 16px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
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;
|
|
||||||
gap: 16px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Summary: React.FC = () => {
|
|
||||||
const { detailData, clusterList } = useDetailContext();
|
|
||||||
const intl = useIntl();
|
|
||||||
const rawMetrics = _.get(detailData, ['raw_metrics', 'benchmarks', '0'], {});
|
|
||||||
|
|
||||||
const items: DescriptionsProps['items'] = [
|
|
||||||
{
|
|
||||||
key: '1',
|
|
||||||
label: 'Model',
|
|
||||||
children: <AutoTooltip ghost>{detailData.model_name}</AutoTooltip>
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '2',
|
|
||||||
label: 'Cluster',
|
|
||||||
children: (
|
|
||||||
<AutoTooltip ghost>
|
|
||||||
{clusterList?.find((item) => item.value === detailData.cluster_id)
|
|
||||||
?.label || detailData.cluster_id}
|
|
||||||
</AutoTooltip>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '4',
|
|
||||||
label: 'Dataset',
|
|
||||||
children: detailData.dataset_name
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '5',
|
|
||||||
label: 'Duration (s)',
|
|
||||||
children: round(rawMetrics.duration || 0, 2)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '3',
|
|
||||||
label: 'Update Time',
|
|
||||||
children: dayjs(detailData.updated_at).format('YYYY-MM-DD HH:mm:ss')
|
|
||||||
}
|
|
||||||
];
|
|
||||||
const cardFields = [
|
|
||||||
{
|
|
||||||
label: 'Total Requests',
|
|
||||||
key: 'total_requests',
|
|
||||||
value: detailData.total_requests,
|
|
||||||
precision: 0,
|
|
||||||
unit: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Success Rate',
|
|
||||||
key: 'success_rate',
|
|
||||||
value: round(
|
|
||||||
(_.get(rawMetrics, 'metrics.request_totals.successful') /
|
|
||||||
_.get(rawMetrics, 'metrics.request_totals.total')) *
|
|
||||||
100 || 0,
|
|
||||||
1
|
|
||||||
),
|
|
||||||
color: 'var(--ant-color-success)',
|
|
||||||
precision: 0,
|
|
||||||
unit: '%'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Incomplete Count',
|
|
||||||
key: 'incomplete_count',
|
|
||||||
value: _.get(rawMetrics, 'metrics.request_totals.incomplete'),
|
|
||||||
color: 'var(--ant-color-warning)',
|
|
||||||
unit: ''
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// label: 'Error Count',
|
|
||||||
// key: 'error_count',
|
|
||||||
// value: _.get(rawMetrics, 'metrics.request_totals.error'),
|
|
||||||
// color: 'var(--ant-color-error)',
|
|
||||||
// unit: ''
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
label: 'Concurrency',
|
|
||||||
key: 'concurrency',
|
|
||||||
value: _.get(rawMetrics, 'metrics.request_concurrency.successful.mean'),
|
|
||||||
precision: 2,
|
|
||||||
unit: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'RPS',
|
|
||||||
key: 'rps',
|
|
||||||
value: detailData.requests_per_second_mean,
|
|
||||||
precision: 2,
|
|
||||||
unit: 'req/s'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'ITL',
|
|
||||||
key: 'itl',
|
|
||||||
value: detailData.inter_token_latency_mean,
|
|
||||||
unit: 'ms'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'TPOT',
|
|
||||||
key: 'time_per_output_token_mean',
|
|
||||||
value: detailData.time_per_output_token_mean,
|
|
||||||
precision: 2,
|
|
||||||
unit: 'ms'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'TTFT',
|
|
||||||
key: 'time_to_first_token_mean',
|
|
||||||
value: detailData.time_to_first_token_mean,
|
|
||||||
precision: 2,
|
|
||||||
unit: 'ms'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const throughputFields = [
|
|
||||||
{
|
|
||||||
key: '3',
|
|
||||||
label: 'Total token throughput',
|
|
||||||
children: `${round(detailData.tokens_per_second_mean || 0, 2)} Tokens/s`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '1',
|
|
||||||
label: 'Request token throughput',
|
|
||||||
children: `${round(detailData.input_tokens_per_second_mean || 0, 2)} Tokens/s`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '2',
|
|
||||||
label: 'Output token throughput',
|
|
||||||
children: `${round(detailData.output_tokens_per_second_mean || 0, 2)} Tokens/s`
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const latencyFields = [
|
|
||||||
{
|
|
||||||
key: '1',
|
|
||||||
label: 'Avg Request Latency',
|
|
||||||
children: `${round(detailData.request_latency_mean, 2)} ms`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '2',
|
|
||||||
label: 'Avg Time to First Token',
|
|
||||||
children: `${round(detailData.time_to_first_token_mean, 2)} ms`
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '3',
|
|
||||||
label: 'Avg Time Per Output Token',
|
|
||||||
children: `${round(detailData.time_per_output_token_mean, 2)} ms`
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<Row gutter={16}>
|
|
||||||
{cardFields.map((field) => (
|
|
||||||
<Col span={6} key={field.key} style={{ padding: '8px' }}>
|
|
||||||
<Card>
|
|
||||||
<Statistic
|
|
||||||
title={field.label}
|
|
||||||
value={field.value}
|
|
||||||
precision={field.precision}
|
|
||||||
styles={{
|
|
||||||
content: {
|
|
||||||
color: field.color,
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: 500
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
paddingBottom: 4
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
suffix={field.unit}
|
|
||||||
/>
|
|
||||||
</Card>
|
|
||||||
</Col>
|
|
||||||
))}
|
|
||||||
</Row>
|
|
||||||
<Section title="Metadata">
|
|
||||||
<Descriptions
|
|
||||||
items={items}
|
|
||||||
colon={false}
|
|
||||||
column={3}
|
|
||||||
layout="vertical"
|
|
||||||
styles={{
|
|
||||||
content: {
|
|
||||||
justifyContent: 'flex-start'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
></Descriptions>
|
|
||||||
</Section>
|
|
||||||
|
|
||||||
<Box>
|
|
||||||
<Section title="Throughput">
|
|
||||||
<Descriptions
|
|
||||||
items={throughputFields}
|
|
||||||
colon={true}
|
|
||||||
column={1}
|
|
||||||
styles={{
|
|
||||||
content: {
|
|
||||||
justifyContent: 'flex-end'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
></Descriptions>
|
|
||||||
</Section>
|
|
||||||
<Section title="Latency">
|
|
||||||
<Descriptions
|
|
||||||
items={latencyFields}
|
|
||||||
colon={true}
|
|
||||||
column={1}
|
|
||||||
styles={{
|
|
||||||
content: {
|
|
||||||
justifyContent: 'flex-end'
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
></Descriptions>
|
|
||||||
</Section>
|
|
||||||
</Box>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Summary;
|
|
||||||
@@ -5,13 +5,17 @@ import { useDetailContext } from '../../config/detail-context';
|
|||||||
|
|
||||||
const Benchmark: React.FC = () => {
|
const Benchmark: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { detailData } = useDetailContext();
|
const { detailData, profilesOptions } = useDetailContext();
|
||||||
|
|
||||||
const items: DescriptionsProps['items'] = [
|
const items: DescriptionsProps['items'] = [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
label: intl.formatMessage({ id: 'benchmark.form.profile' }),
|
label: intl.formatMessage({ id: 'benchmark.form.profile' }),
|
||||||
children: detailData?.profile || '-'
|
children:
|
||||||
|
profilesOptions.find((option) => option.value === detailData?.profile)
|
||||||
|
?.label ||
|
||||||
|
detailData?.profile ||
|
||||||
|
'-'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '2',
|
key: '2',
|
||||||
@@ -43,7 +47,7 @@ const Benchmark: React.FC = () => {
|
|||||||
{
|
{
|
||||||
key: '5',
|
key: '5',
|
||||||
label: intl.formatMessage({ id: 'playground.image.params.seed' }),
|
label: intl.formatMessage({ id: 'playground.image.params.seed' }),
|
||||||
children: detailData?.seed || '-'
|
children: detailData?.dataset_seed || '-'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -59,25 +59,29 @@ const Instance: React.FC = () => {
|
|||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
label: intl.formatMessage({ id: 'models.form.backend_parameters' }),
|
label: intl.formatMessage({ id: 'models.form.backend_parameters' }),
|
||||||
children: (
|
children:
|
||||||
<Flex
|
instanceData?.backend_parameters &&
|
||||||
gap={8}
|
instanceData?.backend_parameters.length > 0 ? (
|
||||||
wrap="wrap"
|
<Flex
|
||||||
style={{
|
gap={8}
|
||||||
backgroundColor: 'var(--ant-color-fill-quaternary)',
|
wrap="wrap"
|
||||||
padding: '4px',
|
style={{
|
||||||
borderRadius: '2px'
|
backgroundColor: 'var(--ant-color-fill-quaternary)',
|
||||||
}}
|
padding: '4px',
|
||||||
>
|
borderRadius: '2px'
|
||||||
{instanceData?.backend_parameters?.map(
|
}}
|
||||||
(param: string, index: number) => (
|
>
|
||||||
<span key={index} style={{ margin: 0 }}>
|
{instanceData?.backend_parameters?.map(
|
||||||
{param}
|
(param: string, index: number) => (
|
||||||
</span>
|
<span key={index} style={{ margin: 0 }}>
|
||||||
)
|
{param}
|
||||||
)}
|
</span>
|
||||||
</Flex>
|
)
|
||||||
)
|
)}
|
||||||
|
</Flex>
|
||||||
|
) : (
|
||||||
|
'-'
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: '3',
|
key: '3',
|
||||||
@@ -86,24 +90,32 @@ const Instance: React.FC = () => {
|
|||||||
<Flex gap={8} wrap="wrap">
|
<Flex gap={8} wrap="wrap">
|
||||||
{instanceData?.extended_kv_cache?.enabled ? (
|
{instanceData?.extended_kv_cache?.enabled ? (
|
||||||
<>
|
<>
|
||||||
<span className="flex-center">
|
{instanceData?.extended_kv_cache?.ram_ratio && (
|
||||||
<span>
|
<span className="flex-center">
|
||||||
{intl.formatMessage({ id: 'models.form.ramRatio' })}:
|
<span>
|
||||||
|
{intl.formatMessage({ id: 'models.form.ramRatio' })}:
|
||||||
|
</span>
|
||||||
|
<span>{instanceData?.extended_kv_cache?.ram_ratio}</span>
|
||||||
</span>
|
</span>
|
||||||
<span>{instanceData?.extended_kv_cache?.ram_ratio}</span>
|
)}
|
||||||
</span>
|
|
||||||
<span className="flex-center">
|
{instanceData?.extended_kv_cache?.ram_size && (
|
||||||
<span>
|
<span className="flex-center">
|
||||||
{intl.formatMessage({ id: 'models.form.ramSize' })}:
|
<span>
|
||||||
|
{intl.formatMessage({ id: 'models.form.ramSize' })}:
|
||||||
|
</span>
|
||||||
|
<span>{instanceData?.extended_kv_cache?.ram_size}</span>
|
||||||
</span>
|
</span>
|
||||||
<span>{instanceData?.extended_kv_cache?.ram_size}</span>
|
)}
|
||||||
</span>
|
|
||||||
<span className="flex-center">
|
{instanceData?.extended_kv_cache?.chunk_size && (
|
||||||
<span>
|
<span className="flex-center">
|
||||||
{intl.formatMessage({ id: 'models.form.chunkSize' })}:
|
<span>
|
||||||
|
{intl.formatMessage({ id: 'models.form.chunkSize' })}:
|
||||||
|
</span>
|
||||||
|
<span>{instanceData?.extended_kv_cache?.chunk_size}</span>
|
||||||
</span>
|
</span>
|
||||||
<span>{instanceData?.extended_kv_cache?.chunk_size}</span>
|
)}
|
||||||
</span>
|
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
'-'
|
'-'
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const PercentileResult: React.FC = () => {
|
|||||||
render: (value: number) => round(value, 2)
|
render: (value: number) => round(value, 2)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: `${intl.formatMessage({ id: 'benchmark.detail.percentile.latency' })} (s)`,
|
title: `${intl.formatMessage({ id: 'benchmark.detail.percentile.latency' })} (ms)`,
|
||||||
dataIndex: 'request_latency',
|
dataIndex: 'request_latency',
|
||||||
render: (value: number) => round(value, 2)
|
render: (value: number) => round(value, 2)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ interface DetailContextProps {
|
|||||||
clusterList?: Global.BaseOption<number>[];
|
clusterList?: Global.BaseOption<number>[];
|
||||||
id: number;
|
id: number;
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
|
profilesOptions: Global.BaseOption<string>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DetailContext = createContext<DetailContextProps>(
|
const DetailContext = createContext<DetailContextProps>(
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export interface GPUData {
|
|||||||
|
|
||||||
export interface BenchmarkDetail {
|
export interface BenchmarkDetail {
|
||||||
profile: string;
|
profile: string;
|
||||||
seed: number;
|
dataset_seed: number;
|
||||||
raw_metrics: {
|
raw_metrics: {
|
||||||
benchmarks: Array<{
|
benchmarks: Array<{
|
||||||
metrics: Record<string, any>;
|
metrics: Record<string, any>;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ interface FormContextProps {
|
|||||||
open?: boolean;
|
open?: boolean;
|
||||||
clusterList?: Global.BaseOption<number>[];
|
clusterList?: Global.BaseOption<number>[];
|
||||||
modelList?: Global.BaseOption<number>[];
|
modelList?: Global.BaseOption<number>[];
|
||||||
|
profilesOptions: Global.BaseOption<string>[];
|
||||||
|
datasetList: Global.BaseOption<number | string>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const FormContext = createContext<FormContextProps>({} as FormContextProps);
|
const FormContext = createContext<FormContextProps>({} as FormContextProps);
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export const profileOptions = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const DatasetValueMap = {
|
export const DatasetValueMap = {
|
||||||
ShareGPT: 'ShareGPT',
|
ShareGPT: 'ShareGPT',
|
||||||
Random: 'Random'
|
Random: 'Random'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import useViewLogs from './hooks/use-view-logs';
|
|||||||
import { useExportBenchmark } from './services/use-export-benchmark';
|
import { useExportBenchmark } from './services/use-export-benchmark';
|
||||||
import useQueryBenchmarkList from './services/use-query-benchmarks';
|
import useQueryBenchmarkList from './services/use-query-benchmarks';
|
||||||
import useQueryDetail from './services/use-query-detail';
|
import useQueryDetail from './services/use-query-detail';
|
||||||
|
import useQueryProfiles from './services/use-query-profiles';
|
||||||
import useStopBenchmark from './services/use-stop-benchmark';
|
import useStopBenchmark from './services/use-stop-benchmark';
|
||||||
|
|
||||||
const Details: React.FC = () => {
|
const Details: React.FC = () => {
|
||||||
@@ -27,6 +28,11 @@ const Details: React.FC = () => {
|
|||||||
fetchData: fetchBenchmarkList,
|
fetchData: fetchBenchmarkList,
|
||||||
cancelRequest: cancelBenchmarkRequest
|
cancelRequest: cancelBenchmarkRequest
|
||||||
} = useQueryBenchmarkList();
|
} = useQueryBenchmarkList();
|
||||||
|
const {
|
||||||
|
profilesOptions,
|
||||||
|
fetchProfilesData,
|
||||||
|
cancelRequest: cancelProfilesRequest
|
||||||
|
} = useQueryProfiles();
|
||||||
const { loading, detailData, cancelRequest, fetchData } = useQueryDetail();
|
const { loading, detailData, cancelRequest, fetchData } = useQueryDetail();
|
||||||
const { openViewLogsModal, closeViewLogsModal, openViewLogsModalStatus } =
|
const { openViewLogsModal, closeViewLogsModal, openViewLogsModalStatus } =
|
||||||
useViewLogs();
|
useViewLogs();
|
||||||
@@ -92,7 +98,7 @@ const Details: React.FC = () => {
|
|||||||
} else if (val === 'stop') {
|
} else if (val === 'stop') {
|
||||||
handleStopBenchmark(row.id);
|
handleStopBenchmark(row.id);
|
||||||
} else if (val === 'export') {
|
} else if (val === 'export') {
|
||||||
exportData([row.id]);
|
exportData([row.id], row.name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -102,8 +108,10 @@ const Details: React.FC = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchBenchmarkList({ page: -1 });
|
fetchBenchmarkList({ page: -1 });
|
||||||
|
fetchProfilesData();
|
||||||
return () => {
|
return () => {
|
||||||
cancelBenchmarkRequest();
|
cancelBenchmarkRequest();
|
||||||
|
cancelProfilesRequest();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -126,7 +134,8 @@ const Details: React.FC = () => {
|
|||||||
detailData: detailData || {},
|
detailData: detailData || {},
|
||||||
clusterList: [],
|
clusterList: [],
|
||||||
loading: loading,
|
loading: loading,
|
||||||
id: Number(id)
|
id: Number(id),
|
||||||
|
profilesOptions: profilesOptions
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DetailContent
|
<DetailContent
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import SealInput from '@/components/seal-form/seal-input';
|
import SealInput from '@/components/seal-form/seal-input';
|
||||||
import SealSelect from '@/components/seal-form/seal-select';
|
import SealSelect from '@/components/seal-form/seal-select';
|
||||||
import { PageAction } from '@/config';
|
import { modelNameReg, PageAction } from '@/config';
|
||||||
import useAppUtils from '@/hooks/use-app-utils';
|
import useAppUtils from '@/hooks/use-app-utils';
|
||||||
import { ClusterStatusValueMap } from '@/pages/cluster-management/config';
|
import { ClusterStatusValueMap } from '@/pages/cluster-management/config';
|
||||||
import { useBenchmarkTargetInstance } from '@/pages/llmodels/hooks/use-run-benchmark';
|
import { useBenchmarkTargetInstance } from '@/pages/llmodels/hooks/use-run-benchmark';
|
||||||
@@ -53,6 +53,10 @@ const BasicForm: React.FC = () => {
|
|||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: getRuleMessage('input', 'common.table.name')
|
message: getRuleMessage('input', 'common.table.name')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: modelNameReg,
|
||||||
|
message: intl.formatMessage({ id: 'models.form.rules.name' })
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -9,26 +9,13 @@ import React, { useEffect } from 'react';
|
|||||||
import { ProfileValueMap } from '../config';
|
import { ProfileValueMap } from '../config';
|
||||||
import { useFormContext } from '../config/form-context';
|
import { useFormContext } from '../config/form-context';
|
||||||
import { FormData } from '../config/types';
|
import { FormData } from '../config/types';
|
||||||
import useQueryDataset from '../services/use-query-dataset';
|
|
||||||
import useQueryProfiles from '../services/use-query-profiles';
|
|
||||||
import RandomSettingsForm from './random-settings';
|
import RandomSettingsForm from './random-settings';
|
||||||
|
|
||||||
const DatasetForm: React.FC = () => {
|
const DatasetForm: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const form = Form.useFormInstance();
|
const form = Form.useFormInstance();
|
||||||
const { getRuleMessage } = useAppUtils();
|
const { getRuleMessage } = useAppUtils();
|
||||||
const { action, open } = useFormContext();
|
const { action, open, profilesOptions, datasetList } = useFormContext();
|
||||||
const {
|
|
||||||
datasetList,
|
|
||||||
loading: datasetLoading,
|
|
||||||
fetchDatasetData,
|
|
||||||
cancelRequest: cancelDatasetRequest
|
|
||||||
} = useQueryDataset();
|
|
||||||
const {
|
|
||||||
profilesOptions,
|
|
||||||
fetchProfilesData,
|
|
||||||
cancelRequest: cancelProfilesRequest
|
|
||||||
} = useQueryProfiles();
|
|
||||||
|
|
||||||
const handleProfileChange = (value: string, option: any) => {
|
const handleProfileChange = (value: string, option: any) => {
|
||||||
if (value !== ProfileValueMap.Custom) {
|
if (value !== ProfileValueMap.Custom) {
|
||||||
@@ -43,6 +30,8 @@ const DatasetForm: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const labelRender = (label: string) => {};
|
||||||
|
|
||||||
// Initialize profile when open form
|
// Initialize profile when open form
|
||||||
const initProfile = (
|
const initProfile = (
|
||||||
value: string,
|
value: string,
|
||||||
@@ -63,28 +52,28 @@ const DatasetForm: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) {
|
|
||||||
cancelDatasetRequest();
|
|
||||||
cancelProfilesRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
const profiles = await fetchProfilesData();
|
if (
|
||||||
const datasets = await fetchDatasetData();
|
profilesOptions &&
|
||||||
// set default profile
|
profilesOptions.length > 0 &&
|
||||||
if (profiles?.length > 0) {
|
action === PageAction.CREATE
|
||||||
const throughputProfile = profiles.find(
|
) {
|
||||||
|
const throughputProfile = profilesOptions.find(
|
||||||
(item) => item.value === ProfileValueMap.ThroughputMedium
|
(item) => item.value === ProfileValueMap.ThroughputMedium
|
||||||
);
|
);
|
||||||
if (throughputProfile) {
|
if (throughputProfile) {
|
||||||
initProfile(throughputProfile.value, throughputProfile, datasets);
|
initProfile(
|
||||||
|
throughputProfile.value,
|
||||||
|
throughputProfile,
|
||||||
|
datasetList
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
}, [open]);
|
}, [open, action, profilesOptions, datasetList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -127,10 +116,7 @@ const DatasetForm: React.FC = () => {
|
|||||||
</SealSelect>
|
</SealSelect>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<RandomSettingsForm
|
<RandomSettingsForm datasetList={datasetList}></RandomSettingsForm>
|
||||||
datasetList={datasetList}
|
|
||||||
datasetLoading={datasetLoading}
|
|
||||||
></RandomSettingsForm>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ interface ProviderFormProps {
|
|||||||
currentData?: ListItem; // Used when action is EDIT
|
currentData?: ListItem; // Used when action is EDIT
|
||||||
open?: boolean;
|
open?: boolean;
|
||||||
clusterList?: Global.BaseOption<number>[];
|
clusterList?: Global.BaseOption<number>[];
|
||||||
|
datasetList: Global.BaseOption<number | string>[];
|
||||||
|
profilesOptions: Global.BaseOption<string>[];
|
||||||
onFinish: (values: FormData) => Promise<void>;
|
onFinish: (values: FormData) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +36,15 @@ const TABKeysMap = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ProviderForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
const ProviderForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
||||||
const { action, currentData, onFinish, open, clusterList } = props;
|
const {
|
||||||
|
action,
|
||||||
|
currentData,
|
||||||
|
onFinish,
|
||||||
|
open,
|
||||||
|
clusterList,
|
||||||
|
profilesOptions,
|
||||||
|
datasetList
|
||||||
|
} = props;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const { getScrollElementScrollableHeight } = useWrapperContext();
|
const { getScrollElementScrollableHeight } = useWrapperContext();
|
||||||
@@ -102,7 +112,9 @@ const ProviderForm: React.FC<ProviderFormProps> = forwardRef((props, ref) => {
|
|||||||
value={{
|
value={{
|
||||||
action,
|
action,
|
||||||
open,
|
open,
|
||||||
clusterList: clusterList
|
clusterList: clusterList,
|
||||||
|
profilesOptions: profilesOptions,
|
||||||
|
datasetList: datasetList
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Form
|
<Form
|
||||||
|
|||||||
@@ -5,18 +5,19 @@ import useAppUtils from '@/hooks/use-app-utils';
|
|||||||
import { useIntl } from '@umijs/max';
|
import { useIntl } from '@umijs/max';
|
||||||
import { Form } from 'antd';
|
import { Form } from 'antd';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
|
import { DatasetValueMap } from '../config';
|
||||||
import { useFormContext } from '../config/form-context';
|
import { useFormContext } from '../config/form-context';
|
||||||
import { FormData } from '../config/types';
|
import { FormData } from '../config/types';
|
||||||
|
|
||||||
const RandomSettingsForm: React.FC<{
|
const RandomSettingsForm: React.FC<{
|
||||||
datasetList: Global.BaseOption<number | string>[];
|
datasetList: Global.BaseOption<number | string>[];
|
||||||
datasetLoading: boolean;
|
|
||||||
}> = (props) => {
|
}> = (props) => {
|
||||||
const { datasetList, datasetLoading } = props;
|
const { datasetList } = props;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { action, open } = useFormContext();
|
const { action, open } = useFormContext();
|
||||||
const form = Form.useFormInstance();
|
const form = Form.useFormInstance();
|
||||||
const profile = Form.useWatch('profile', form);
|
const profile = Form.useWatch('profile', form);
|
||||||
|
const datasetName = Form.useWatch('dataset_name', form);
|
||||||
const { getRuleMessage } = useAppUtils();
|
const { getRuleMessage } = useAppUtils();
|
||||||
|
|
||||||
const disabled = useMemo(() => {
|
const disabled = useMemo(() => {
|
||||||
@@ -43,58 +44,66 @@ const RandomSettingsForm: React.FC<{
|
|||||||
label: item.label,
|
label: item.label,
|
||||||
value: item.label
|
value: item.label
|
||||||
}))}
|
}))}
|
||||||
loading={datasetLoading}
|
|
||||||
label={intl.formatMessage({ id: 'benchmark.table.dataset' })}
|
label={intl.formatMessage({ id: 'benchmark.table.dataset' })}
|
||||||
required
|
required
|
||||||
></SealSelect>
|
></SealSelect>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item<FormData>
|
{datasetName === DatasetValueMap.Random && (
|
||||||
name="dataset_input_tokens"
|
<>
|
||||||
rules={[
|
<Form.Item<FormData>
|
||||||
{
|
name="dataset_input_tokens"
|
||||||
required: true,
|
rules={[
|
||||||
message: getRuleMessage('input', 'benchmark.table.inputTokenLength')
|
{
|
||||||
}
|
required: true,
|
||||||
]}
|
message: getRuleMessage(
|
||||||
>
|
'input',
|
||||||
<SealInputNumber
|
'benchmark.table.inputTokenLength'
|
||||||
min={0}
|
)
|
||||||
disabled={disabled}
|
}
|
||||||
label={intl.formatMessage({ id: 'benchmark.table.inputTokenLength' })}
|
]}
|
||||||
required
|
>
|
||||||
></SealInputNumber>
|
<SealInputNumber
|
||||||
</Form.Item>
|
min={0}
|
||||||
<Form.Item<FormData>
|
disabled={disabled}
|
||||||
name="dataset_output_tokens"
|
label={intl.formatMessage({
|
||||||
rules={[
|
id: 'benchmark.table.inputTokenLength'
|
||||||
{
|
})}
|
||||||
required: true,
|
required
|
||||||
message: getRuleMessage(
|
></SealInputNumber>
|
||||||
'input',
|
</Form.Item>
|
||||||
'benchmark.table.outputTokenLength'
|
<Form.Item<FormData>
|
||||||
)
|
name="dataset_output_tokens"
|
||||||
}
|
rules={[
|
||||||
]}
|
{
|
||||||
>
|
required: true,
|
||||||
<SealInputNumber
|
message: getRuleMessage(
|
||||||
min={0}
|
'input',
|
||||||
disabled={disabled}
|
'benchmark.table.outputTokenLength'
|
||||||
label={intl.formatMessage({
|
)
|
||||||
id: 'benchmark.table.outputTokenLength'
|
}
|
||||||
})}
|
]}
|
||||||
required
|
>
|
||||||
></SealInputNumber>
|
<SealInputNumber
|
||||||
</Form.Item>
|
min={0}
|
||||||
<Form.Item<FormData>
|
disabled={disabled}
|
||||||
name="dataset_seed"
|
label={intl.formatMessage({
|
||||||
getValueProps={(value) => ({ value: value || null })}
|
id: 'benchmark.table.outputTokenLength'
|
||||||
>
|
})}
|
||||||
<SealInputNumber
|
required
|
||||||
min={0}
|
></SealInputNumber>
|
||||||
disabled={disabled}
|
</Form.Item>
|
||||||
label={intl.formatMessage({ id: 'playground.image.params.seed' })}
|
<Form.Item<FormData>
|
||||||
></SealInputNumber>
|
name="dataset_seed"
|
||||||
</Form.Item>
|
getValueProps={(value) => ({ value: value || null })}
|
||||||
|
>
|
||||||
|
<SealInputNumber
|
||||||
|
min={0}
|
||||||
|
disabled={disabled}
|
||||||
|
label={intl.formatMessage({ id: 'playground.image.params.seed' })}
|
||||||
|
></SealInputNumber>
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Form.Item<FormData>
|
<Form.Item<FormData>
|
||||||
name="request_rate"
|
name="request_rate"
|
||||||
getValueProps={(value) => ({ value: value < 0 ? 'Infinity' : value })}
|
getValueProps={(value) => ({ value: value < 0 ? 'Infinity' : value })}
|
||||||
|
|||||||
@@ -92,10 +92,11 @@ const BenchmarkStateTag = (props: { data: ListItem }) => {
|
|||||||
|
|
||||||
const useColumnSettings = (options: {
|
const useColumnSettings = (options: {
|
||||||
contentHeight: number;
|
contentHeight: number;
|
||||||
|
profileOptions: Global.BaseOption<string>[];
|
||||||
clusterList: Global.BaseOption<number>[];
|
clusterList: Global.BaseOption<number>[];
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const { contentHeight, clusterList } = options;
|
const { contentHeight, clusterList, profileOptions } = options;
|
||||||
const [selectedColumns, setSelectedColumns] =
|
const [selectedColumns, setSelectedColumns] =
|
||||||
React.useState<string[]>(defaultColumns);
|
React.useState<string[]>(defaultColumns);
|
||||||
|
|
||||||
@@ -111,10 +112,10 @@ const useColumnSettings = (options: {
|
|||||||
title={`${title} ${options?.subTitle || ''}`}
|
title={`${title} ${options?.subTitle || ''}`}
|
||||||
>
|
>
|
||||||
{title}
|
{title}
|
||||||
|
{options?.subTitle && (
|
||||||
|
<div className="sub-title">{options.subTitle}</div>
|
||||||
|
)}
|
||||||
</AutoTooltip>
|
</AutoTooltip>
|
||||||
{options?.subTitle && (
|
|
||||||
<SubTitleWrapper>{options.subTitle}</SubTitleWrapper>
|
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -247,45 +248,6 @@ const useColumnSettings = (options: {
|
|||||||
</AutoTooltip>
|
</AutoTooltip>
|
||||||
),
|
),
|
||||||
unit: ''
|
unit: ''
|
||||||
},
|
|
||||||
{
|
|
||||||
title: renderTitle(
|
|
||||||
intl.formatMessage({ id: 'benchmark.detail.requests.success' })
|
|
||||||
),
|
|
||||||
dataIndex: 'successful_requests',
|
|
||||||
path: ['raw_metrics', 'benchmarks', '0'],
|
|
||||||
render: (value: number) =>
|
|
||||||
round(_.get(value, ['metrics', 'request_totals', 'successful']), 0) ||
|
|
||||||
0,
|
|
||||||
precision: 0,
|
|
||||||
color: 'var(--ant-color-success)',
|
|
||||||
unit: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: renderTitle(
|
|
||||||
intl.formatMessage({ id: 'benchmark.detail.requests.failed' })
|
|
||||||
),
|
|
||||||
dataIndex: 'failed_requests',
|
|
||||||
path: ['raw_metrics', 'benchmarks', '0'],
|
|
||||||
render: (value: number) =>
|
|
||||||
round(_.get(value, ['metrics', 'request_totals', 'errored']), 0) || 0,
|
|
||||||
precision: 0,
|
|
||||||
color: 'var(--ant-color-error)',
|
|
||||||
unit: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: renderTitle(
|
|
||||||
intl.formatMessage({
|
|
||||||
id: 'benchmark.detail.requests.concurrency'
|
|
||||||
})
|
|
||||||
),
|
|
||||||
dataIndex: 'request_concurrency',
|
|
||||||
path: ['raw_metrics', 'benchmarks', '0'],
|
|
||||||
render: (value: number) =>
|
|
||||||
round(_.get(value, 'metrics.request_concurrency.successful.mean'), 0) ||
|
|
||||||
0,
|
|
||||||
precision: 0,
|
|
||||||
unit: ''
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -326,7 +288,8 @@ const useColumnSettings = (options: {
|
|||||||
dataIndex: 'profile',
|
dataIndex: 'profile',
|
||||||
render: (text: string) => (
|
render: (text: string) => (
|
||||||
<AutoTooltip ghost minWidth={20}>
|
<AutoTooltip ghost minWidth={20}>
|
||||||
{text}
|
{profileOptions.find((option) => option.value === text)?.label ||
|
||||||
|
text}
|
||||||
</AutoTooltip>
|
</AutoTooltip>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import useCreateBenchmark from './hooks/use-create-benchmark';
|
|||||||
import useViewLogs from './hooks/use-view-logs';
|
import useViewLogs from './hooks/use-view-logs';
|
||||||
import { useExportBenchmark } from './services/use-export-benchmark';
|
import { useExportBenchmark } from './services/use-export-benchmark';
|
||||||
import useQueryDataset from './services/use-query-dataset';
|
import useQueryDataset from './services/use-query-dataset';
|
||||||
|
import useQueryProfiles from './services/use-query-profiles';
|
||||||
import useStopBenchmark from './services/use-stop-benchmark';
|
import useStopBenchmark from './services/use-stop-benchmark';
|
||||||
|
|
||||||
const Benchmark: React.FC = () => {
|
const Benchmark: React.FC = () => {
|
||||||
@@ -73,15 +74,22 @@ const Benchmark: React.FC = () => {
|
|||||||
cancelRequest: cancelClusterRequest,
|
cancelRequest: cancelClusterRequest,
|
||||||
clusterList
|
clusterList
|
||||||
} = useQueryClusterList();
|
} = useQueryClusterList();
|
||||||
|
const { benchmarkTargetInstance } = useBenchmarkTargetInstance();
|
||||||
|
const {
|
||||||
|
profilesOptions,
|
||||||
|
fetchProfilesData,
|
||||||
|
cancelRequest: cancelProfilesRequest
|
||||||
|
} = useQueryProfiles();
|
||||||
const { SettingsButton, columns: selectedColumns } = useColumnSettings({
|
const { SettingsButton, columns: selectedColumns } = useColumnSettings({
|
||||||
contentHeight: 320,
|
contentHeight: 320,
|
||||||
clusterList
|
clusterList,
|
||||||
|
profileOptions: profilesOptions
|
||||||
});
|
});
|
||||||
const { benchmarkTargetInstance } = useBenchmarkTargetInstance();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchModelList({ page: -1 });
|
fetchModelList({ page: -1 });
|
||||||
fetchDatasetData();
|
fetchDatasetData();
|
||||||
|
fetchProfilesData();
|
||||||
fetchClusterList({ page: -1 }).then(() => {
|
fetchClusterList({ page: -1 }).then(() => {
|
||||||
if (benchmarkTargetInstance.model_name) {
|
if (benchmarkTargetInstance.model_name) {
|
||||||
openBenchmarkModal(
|
openBenchmarkModal(
|
||||||
@@ -92,6 +100,7 @@ const Benchmark: React.FC = () => {
|
|||||||
});
|
});
|
||||||
return () => {
|
return () => {
|
||||||
cancelClusterRequest();
|
cancelClusterRequest();
|
||||||
|
cancelProfilesRequest();
|
||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -261,6 +270,8 @@ const Benchmark: React.FC = () => {
|
|||||||
action={openBenchmarkModalStatus.action}
|
action={openBenchmarkModalStatus.action}
|
||||||
title={openBenchmarkModalStatus.title}
|
title={openBenchmarkModalStatus.title}
|
||||||
currentData={openBenchmarkModalStatus.currentData}
|
currentData={openBenchmarkModalStatus.currentData}
|
||||||
|
profilesOptions={profilesOptions}
|
||||||
|
datasetList={datasetList}
|
||||||
onCancel={handleModalCancel}
|
onCancel={handleModalCancel}
|
||||||
onOk={handleModalOk}
|
onOk={handleModalOk}
|
||||||
></AddBenchmarkModal>
|
></AddBenchmarkModal>
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export default function useQueryProfiles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
console.log('options===', options);
|
||||||
setProfilesOptions(options);
|
setProfilesOptions(options);
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user