模型开始训练界面以及查看日志功能完善
This commit is contained in:
@@ -219,6 +219,9 @@
|
||||
<button onclick="switchTab('evaluation')" id="tab-evaluation" class="tab-btn" style="display: inline-flex; align-items: center; justify-content: center;">
|
||||
评测模型
|
||||
</button>
|
||||
<button onclick="switchTab('trained')" id="tab-trained" class="tab-btn" style="display: inline-flex; align-items: center; justify-content: center;">
|
||||
已训练模型
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -235,7 +238,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 模型表格 -->
|
||||
<div class="bg-white rounded-lg shadow-sm">
|
||||
<div id="modelsTableContainer" class="bg-white rounded-lg shadow-sm">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead class="bg-gray-50">
|
||||
@@ -260,6 +263,33 @@
|
||||
<p class="text-gray-500">暂无模型数据</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已训练模型表格 -->
|
||||
<div id="trainedModelsContainer" class="hidden bg-white rounded-lg shadow-sm">
|
||||
<div class="p-4 border-b border-gray-200">
|
||||
<p class="text-sm text-gray-500">已训练模型存储在 /app/base/saves 目录下</p>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">基座模型</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">训练方法</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">模型路径</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="trainedModelsBody" class="bg-white divide-y divide-gray-200">
|
||||
<!-- 动态加载 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- 空状态 -->
|
||||
<div id="trainedEmptyState" class="hidden px-6 py-12 text-center">
|
||||
<i class="fa fa-inbox text-4xl text-gray-300 mb-3"></i>
|
||||
<p class="text-gray-500">暂无已训练模型</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -272,6 +302,7 @@
|
||||
const API_BASE = getApiBase();
|
||||
|
||||
let allModels = [];
|
||||
let trainedModels = [];
|
||||
let currentTab = 'all';
|
||||
|
||||
// Tab 切换
|
||||
@@ -284,7 +315,25 @@
|
||||
const activeTab = document.getElementById(`tab-${tab}`);
|
||||
activeTab.classList.add('tab-active');
|
||||
|
||||
renderModels();
|
||||
// 显示/隐藏搜索框和添加按钮
|
||||
const toolbar = document.querySelector('div[style*="justify-content: space-between"]');
|
||||
if (toolbar) {
|
||||
toolbar.style.display = tab === 'trained' ? 'none' : 'flex';
|
||||
}
|
||||
|
||||
// 显示/隐藏表格容器
|
||||
const modelsTable = document.getElementById('modelsTableContainer');
|
||||
const trainedModelsContainer = document.getElementById('trainedModelsContainer');
|
||||
|
||||
if (tab === 'trained') {
|
||||
modelsTable.classList.add('hidden');
|
||||
trainedModelsContainer.classList.remove('hidden');
|
||||
loadTrainedModels();
|
||||
} else {
|
||||
modelsTable.classList.remove('hidden');
|
||||
trainedModelsContainer.classList.add('hidden');
|
||||
renderModels();
|
||||
}
|
||||
}
|
||||
|
||||
// 加载模型数据
|
||||
@@ -302,6 +351,23 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 加载已训练模型数据
|
||||
async function loadTrainedModels() {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/model-manage/trained-models`);
|
||||
const result = await response.json();
|
||||
|
||||
console.log('[DEBUG] 已训练模型:', result);
|
||||
|
||||
if (result.code === 0) {
|
||||
trainedModels = result.data?.models || [];
|
||||
renderTrainedModels();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载已训练模型失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 筛选模型
|
||||
function filterModels() {
|
||||
renderModels();
|
||||
@@ -396,6 +462,70 @@
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// 渲染已训练模型列表
|
||||
function renderTrainedModels() {
|
||||
const tbody = document.getElementById('trainedModelsBody');
|
||||
const emptyState = document.getElementById('trainedEmptyState');
|
||||
|
||||
// 收集所有训练方法
|
||||
let allTrainMethods = [];
|
||||
trainedModels.forEach(model => {
|
||||
if (model.train_methods && model.train_methods.length > 0) {
|
||||
model.train_methods.forEach(method => {
|
||||
allTrainMethods.push({
|
||||
baseModel: model.name,
|
||||
trainMethod: method.name,
|
||||
path: method.path
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (allTrainMethods.length === 0) {
|
||||
tbody.innerHTML = '';
|
||||
emptyState.classList.remove('hidden');
|
||||
return;
|
||||
}
|
||||
|
||||
emptyState.classList.add('hidden');
|
||||
|
||||
tbody.innerHTML = allTrainMethods.map(item => {
|
||||
// 训练方法显示
|
||||
const methodMap = {
|
||||
'lora': 'LoRA',
|
||||
'qlora': 'QLoRA',
|
||||
'full': '全量微调',
|
||||
'prefix': 'Prefix Tuning',
|
||||
'adapter': 'Adapter'
|
||||
};
|
||||
const methodDisplay = methodMap[item.trainMethod] || item.trainMethod;
|
||||
|
||||
return `
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm font-medium text-gray-900">${item.baseModel}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<span class="px-2 py-1 text-xs font-medium rounded bg-green-100 text-green-700">${methodDisplay}</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<div class="text-sm text-gray-500 max-w-xs truncate" title="${item.path}">${item.path}</div>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<button onclick="viewTrainedModel('${item.path.replace(/\\/g, '\\\\')}')" class="text-primary hover:text-primary/80 mr-3">
|
||||
<i class="fa fa-folder-open"></i> 查看
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// 查看已训练模型
|
||||
function viewTrainedModel(path) {
|
||||
alert(`模型路径: ${path}\n\n您可以从此路径加载模型进行推理或评测。`);
|
||||
}
|
||||
|
||||
// 编辑模型
|
||||
function editModel(id) {
|
||||
window.location.href = `model-manage-create.html?id=${id}`;
|
||||
|
||||
Reference in New Issue
Block a user