/**
* 训练服务模块
* 处理训练任务相关的操作和进度跟踪
*/
// 训练进度缓存
window.trainingProgressCache = window.trainingProgressCache || {};
// 使用 window 避免重复声明
if (typeof window._progressRefreshTimer === 'undefined') {
window._progressRefreshTimer = null;
}
// 渲染训练进度
function renderTrainingProgress(val, row) {
const progressData = window.trainingProgressCache[row.id];
if (progressData && progressData.status === 'running') {
if (progressData.progress > 0) {
return `
${progressData.progress}%
${progressData.step || ''} ${progressData.speed || ''}
ETA: ${progressData.eta || '--:--'}
`;
}
}
return `${val || 0}%`;
}
// 刷新训练进度
async function refreshTrainingProgress() {
if (typeof window.currentPage !== 'string' || window.currentPage !== 'fine-tune') return;
try {
const response = await fetch(`${window.API_BASE}/fine-tune`);
const result = await response.json();
if (result.code === 0 && result.data) {
// 刷新运行中或已完成的任务(有进度信息)
const activeTasks = result.data.filter(task =>
task.status === 'running' || task.status === 'pending'
);
for (const task of activeTasks) {
try {
// 并行获取进度和PID状态
const [progressResponse, statusResponse] = await Promise.all([
fetch(`${window.API_BASE}/fine-tune/progress/${task.id}`),
fetch(`${window.API_BASE}/fine-tune/${task.id}`)
]);
const progressResult = await progressResponse.json();
const statusResult = await statusResponse.json();
if (progressResult.code === 0 && progressResult.data) {
window.trainingProgressCache[task.id] = progressResult.data;
}
// 如果状态已改变(PID已结束),更新表格中的状态显示
if (statusResult.code === 0 && statusResult.data) {
const actualStatus = statusResult.data.status;
if (task.status !== actualStatus) {
// 找到对应的行并更新状态
const row = document.querySelector(`tr[data-id="${task.id}"]`);
if (row) {
const statusCell = row.querySelector('td:nth-child(3)');
if (statusCell) {
statusCell.innerHTML = `${actualStatus}`;
}
}
}
}
} catch (e) {
console.warn(`获取任务 ${task.id} 信息失败:`, e);
}
}
}
} catch (error) {
console.warn('刷新训练进度失败:', error);
}
}
// 检查并更新任务状态(用于 fine-tune 页面)
async function checkAndUpdateTaskStatus() {
if (typeof window.currentPage !== 'string' || window.currentPage !== 'fine-tune') return;
try {
const response = await fetch(`${window.API_BASE}/fine-tune`);
const result = await response.json();
if (result.code === 0 && result.data) {
// 获取所有 running 状态的任务
const runningTasks = result.data.filter(task => task.status === 'running');
for (const task of runningTasks) {
try {
// 调用 status API 获取实际状态(会检查 PID)
const statusResponse = await fetch(`${window.API_BASE}/fine-tune/${task.id}`);
const statusResult = await statusResponse.json();
if (statusResult.code === 0 && statusResult.data) {
const actualStatus = statusResult.data.status;
// 如果实际状态不是 running,更新表格显示
if (actualStatus !== 'running') {
const row = document.querySelector(`tr[data-id="${task.id}"]`);
if (row) {
const statusCell = row.querySelector('td:nth-child(3)');
if (statusCell) {
const statusClass = actualStatus === 'failed'
? 'bg-red-100 text-red-700'
: 'bg-blue-100 text-blue-700';
statusCell.innerHTML = `${actualStatus}`;
console.log(`[Status] 任务 ${task.id} 状态已更新: running -> ${actualStatus}`);
}
}
}
}
} catch (e) {
console.warn(`检查任务 ${task.id} 状态失败:`, e);
}
}
}
} catch (error) {
console.warn('检查任务状态失败:', error);
}
}
// 启动训练进度自动刷新
function startProgressRefresh() {
stopProgressRefresh();
window._progressRefreshTimer = setInterval(() => {
refreshTrainingProgress();
checkAndUpdateTaskStatus();
}, 5000);
}
// 停止训练进度刷新
function stopProgressRefresh() {
if (window._progressRefreshTimer) {
clearInterval(window._progressRefreshTimer);
window._progressRefreshTimer = null;
}
}
// 停止训练任务
async function stopItem(taskId) {
window.showConfirm('确认停止', '确定要停止这个训练任务吗?进程将被终止。', async () => {
try {
const response = await fetch(`${window.API_BASE}/fine-tune/stop/${taskId}`, {
method: 'POST'
});
const result = await response.json();
if (result.code === 0) {
window.showMessage('成功', '训练任务已停止', 'success');
// 刷新当前页面
const activeLink = document.querySelector('.nav-link.sidebar-item-active');
if (activeLink && typeof window.loadPage === 'function') {
window.loadPage(activeLink.dataset.page);
}
} else {
window.showMessage('错误', result.message || '停止失败', 'error');
}
} catch (error) {
window.showMessage('错误', '停止失败: ' + error.message, 'error');
}
});
}
// 查看训练日志 - 跳转到日志页面
async function viewTrainingLog(taskId, taskName) {
window.loadPage('logs');
}
// 查看调优任务日志 - 跳转到training-log.html页面
function viewFineTuneLogs(taskId, taskName) {
// 保存 taskId 到 sessionStorage
sessionStorage.setItem('trainingLogTaskId', taskId.toString());
sessionStorage.setItem('trainingLogTaskName', taskName);
// 跳转到日志页面
window.navigateToPage('training-log');
}
// 跳转到训练日志二级页面
function navigateToTrainingLog(taskId) {
// 传递 taskId 到 sessionStorage
sessionStorage.setItem('trainingLogTaskId', taskId.toString());
// 跳转到日志页面
window.navigateToPage('training-log');
}
// 导出训练服务
window.TrainingService = {
renderTrainingProgress,
refreshTrainingProgress,
checkAndUpdateTaskStatus,
startProgressRefresh,
stopProgressRefresh,
stopItem,
viewTrainingLog,
viewFineTuneLogs,
navigateToTrainingLog
};