Files
YG_FT_Platform/web/js/services/training.js
WIN-JHFT4D3SIVT\caoxiaozhu 513e96082c 重构了main.html的主函数
重构了大量的页面的sidebar
优化了代码结构
2026-02-02 09:22:52 +08:00

202 lines
8.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 训练服务模块
* 处理训练任务相关的操作和进度跟踪
*/
// 训练进度缓存
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 `
<div class="flex flex-col">
<span class="text-sm font-medium text-primary">${progressData.progress}%</span>
<span class="text-xs text-gray-500">${progressData.step || ''} ${progressData.speed || ''}</span>
<span class="text-xs text-gray-400">ETA: ${progressData.eta || '--:--'}</span>
</div>
`;
}
}
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 = `<span class="px-2 py-1 rounded text-xs ${actualStatus === 'running' ? 'bg-green-100 text-green-700' : actualStatus === 'failed' ? 'bg-red-100 text-red-700' : 'bg-blue-100 text-blue-700'}">${actualStatus}</span>`;
}
}
}
}
} 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 = `<span class="px-2 py-1 rounded text-xs ${statusClass}">${actualStatus}</span>`;
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
};