first-update
This commit is contained in:
212
easy-dataset-main/components/distill/AutoDistillProgress.js
Normal file
212
easy-dataset-main/components/distill/AutoDistillProgress.js
Normal file
@@ -0,0 +1,212 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Dialog,
|
||||
DialogTitle,
|
||||
DialogContent,
|
||||
Box,
|
||||
Typography,
|
||||
LinearProgress,
|
||||
Paper,
|
||||
Divider,
|
||||
IconButton,
|
||||
Button
|
||||
} from '@mui/material';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
|
||||
/**
|
||||
* 全自动蒸馏进度组件
|
||||
* @param {Object} props
|
||||
* @param {boolean} props.open - 对话框是否打开
|
||||
* @param {Function} props.onClose - 关闭对话框的回调
|
||||
* @param {Object} props.progress - 进度信息
|
||||
*/
|
||||
export default function AutoDistillProgress({ open, onClose, progress = {} }) {
|
||||
const { t } = useTranslation();
|
||||
const logContainerRef = useRef(null);
|
||||
|
||||
// 自动滚动到底部
|
||||
useEffect(() => {
|
||||
if (logContainerRef.current) {
|
||||
logContainerRef.current.scrollTop = logContainerRef.current.scrollHeight;
|
||||
}
|
||||
}, [progress.logs]);
|
||||
|
||||
const getStageText = () => {
|
||||
const { stage } = progress;
|
||||
switch (stage) {
|
||||
case 'level1':
|
||||
return t('distill.stageBuildingLevel1');
|
||||
case 'level2':
|
||||
return t('distill.stageBuildingLevel2');
|
||||
case 'level3':
|
||||
return t('distill.stageBuildingLevel3');
|
||||
case 'level4':
|
||||
return t('distill.stageBuildingLevel4');
|
||||
case 'level5':
|
||||
return t('distill.stageBuildingLevel5');
|
||||
case 'questions':
|
||||
return t('distill.stageBuildingQuestions');
|
||||
case 'datasets':
|
||||
return t('distill.stageBuildingDatasets');
|
||||
case 'multi-turn-datasets':
|
||||
return t('distill.stageBuildingMultiTurnDatasets', { defaultValue: '生成多轮对话数据集中...' });
|
||||
case 'completed':
|
||||
return t('distill.stageCompleted');
|
||||
default:
|
||||
return t('distill.stageInitializing');
|
||||
}
|
||||
};
|
||||
|
||||
const getOverallProgress = () => {
|
||||
const { tagsBuilt, tagsTotal, questionsBuilt, questionsTotal, datasetsBuilt, datasetsTotal } = progress;
|
||||
|
||||
// 整体进度按比例计算:标签构建占30%,问题生成占35%,数据集生成占35%
|
||||
let tagProgress = tagsTotal ? (tagsBuilt / tagsTotal) * 30 : 0;
|
||||
let questionProgress = questionsTotal ? (questionsBuilt / questionsTotal) * 35 : 0;
|
||||
let datasetProgress = datasetsTotal ? (datasetsBuilt / datasetsTotal) * 35 : 0;
|
||||
|
||||
return Math.min(100, Math.round(tagProgress + questionProgress + datasetProgress));
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={progress.stage === 'completed' || !progress.stage ? onClose : null}
|
||||
maxWidth="md"
|
||||
fullWidth
|
||||
>
|
||||
<DialogTitle>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
{t('distill.autoDistillProgress')}
|
||||
{(progress.stage === 'completed' || !progress.stage) && (
|
||||
<IconButton onClick={onClose} aria-label="close">
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
</Box>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<Box sx={{ py: 1 }}>
|
||||
{/* 整体进度 */}
|
||||
<Box sx={{ mb: 4 }}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
{t('distill.overallProgress')}
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<LinearProgress variant="determinate" value={getOverallProgress()} sx={{ height: 10, borderRadius: 5 }} />
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mt: 0.5 }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{getOverallProgress()}%
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: progress.multiTurnDatasetsTotal > 0 ? 'repeat(4, 1fr)' : 'repeat(3, 1fr)',
|
||||
gap: 2
|
||||
}}
|
||||
>
|
||||
<Paper variant="outlined" sx={{ p: 2 }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{t('distill.tagsProgress')}
|
||||
</Typography>
|
||||
<Typography variant="h6">
|
||||
{progress.tagsBuilt || 0} / {progress.tagsTotal || 0}
|
||||
</Typography>
|
||||
</Paper>
|
||||
|
||||
<Paper variant="outlined" sx={{ p: 2 }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{t('distill.questionsProgress')}
|
||||
</Typography>
|
||||
<Typography variant="h6">
|
||||
{progress.questionsBuilt || 0} / {progress.questionsTotal || 0}
|
||||
</Typography>
|
||||
</Paper>
|
||||
|
||||
<Paper variant="outlined" sx={{ p: 2 }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{t('distill.datasetsProgress')}
|
||||
</Typography>
|
||||
<Typography variant="h6">
|
||||
{progress.datasetsBuilt || 0} / {progress.datasetsTotal || 0}
|
||||
</Typography>
|
||||
</Paper>
|
||||
|
||||
{progress.multiTurnDatasetsTotal > 0 && (
|
||||
<Paper variant="outlined" sx={{ p: 2 }}>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{t('distill.multiTurnDatasetsProgress', { defaultValue: '多轮对话进度' })}
|
||||
</Typography>
|
||||
<Typography variant="h6">
|
||||
{progress.multiTurnDatasetsBuilt || 0} / {progress.multiTurnDatasetsTotal || 0}
|
||||
</Typography>
|
||||
</Paper>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{/* 当前阶段 */}
|
||||
<Box sx={{ mb: 4 }}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
{t('distill.currentStage')}
|
||||
</Typography>
|
||||
|
||||
<Paper variant="outlined" sx={{ p: 2, bgcolor: 'primary.light', color: 'primary.contrastText' }}>
|
||||
<Typography variant="h6">{getStageText()}</Typography>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
{/* 实时日志 */}
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
{t('distill.realTimeLogs')}
|
||||
</Typography>
|
||||
|
||||
<Paper
|
||||
variant="outlined"
|
||||
sx={{
|
||||
p: 2,
|
||||
maxHeight: 250,
|
||||
overflow: 'auto',
|
||||
bgcolor: 'grey.900',
|
||||
color: 'grey.100',
|
||||
fontFamily: 'monospace',
|
||||
fontSize: '0.875rem'
|
||||
}}
|
||||
ref={logContainerRef}
|
||||
>
|
||||
{progress.logs?.length > 0 ? (
|
||||
progress.logs.map((log, index) => {
|
||||
// 检测成功日志,显示为绿色 Successfully
|
||||
let color = 'inherit';
|
||||
if (log.includes('成功') || log.includes('完成') || log.includes('Successfully')) {
|
||||
color = '#4caf50';
|
||||
}
|
||||
if (log.includes('失败') || log.toLowerCase().includes('error')) {
|
||||
color = '#f44336';
|
||||
}
|
||||
return (
|
||||
<Box key={index} sx={{ mb: 0.5, color: color }}>
|
||||
{log}
|
||||
</Box>
|
||||
);
|
||||
})
|
||||
) : (
|
||||
<Typography variant="body2" color="grey.500">
|
||||
{t('distill.waitingForLogs')}
|
||||
</Typography>
|
||||
)}
|
||||
</Paper>
|
||||
</Box>
|
||||
</Box>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user