From d0675aede372b2a2201618159f8bae84a07b1afd Mon Sep 17 00:00:00 2001 From: "WIN-JHFT4D3SIVT\\caoxiaozhu" Date: Thu, 29 Jan 2026 17:34:59 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E6=88=91=E7=9A=84=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/pages/main.html | 10 +- web/pages/model-compare-create.html | 215 ++++++++---- web/pages/model-inference.html | 522 ++++++++++++++++++++++++++++ 3 files changed, 670 insertions(+), 77 deletions(-) create mode 100644 web/pages/model-inference.html diff --git a/web/pages/main.html b/web/pages/main.html index 8eeb2b1..c59c6f0 100644 --- a/web/pages/main.html +++ b/web/pages/main.html @@ -443,7 +443,7 @@ columns: [ { title: '模型名称', key: 'name' }, { title: '训练方法', key: 'train_methods', render: (val) => val && val[0] ? val[0].name : '-' }, - { title: '模型路径', key: 'path', render: (val) => `${val}` }, + { title: '基座模型', key: 'base_model_path', render: (val) => `${val || '-'}` }, { title: '创建时间', key: 'create_time', render: (val) => val ? new Date(val).toLocaleString('zh-CN') : '-' } ], actions: ['view', 'delete'] @@ -3164,12 +3164,10 @@ document.body.style.overflow = ''; } - // 查看已训练模型详情 + // 查看已训练模型详情 - 跳转到推理页面 window.viewTrainedModel = function(name, method, path) { - const message = '

模型名称:' + name + '

' + - '

训练方法:' + method + '

' + - '

路径:' + path + '

'; - showMessage('模型详情', message, 'info'); + // 跳转到推理测试页面(main.html在pages目录下,所以直接用文件名) + window.location.href = `model-inference.html?model=${encodeURIComponent(name)}&method=${encodeURIComponent(method)}`; }; // 确认弹窗(两个按钮)- 使用 window 确保全局可访问 diff --git a/web/pages/model-compare-create.html b/web/pages/model-compare-create.html index 5cbb478..51fe07f 100644 --- a/web/pages/model-compare-create.html +++ b/web/pages/model-compare-create.html @@ -316,14 +316,46 @@ // 加载模型列表 async function loadModels() { try { - const response = await fetch(`${API_BASE}/model-manage`); - const result = await response.json(); - if (result.code === 0) { - allModels = result.data || []; - renderModels(); - } else { - showMessage('错误', result.message || '加载模型失败', 'error'); + // 并行加载数据库模型和已训练模型 + const [dbResponse, trainedResponse] = await Promise.all([ + fetch(`${API_BASE}/model-manage`), + fetch(`${API_BASE}/model-manage/trained-models`) + ]); + + const dbResult = await dbResponse.json(); + const trainedResult = await trainedResponse.json(); + + let dbModels = []; + let trainedModels = []; + + // 数据库模型 + if (dbResult.code === 0) { + dbModels = dbResult.data || []; } + + // 已训练模型 + if (trainedResult.code === 0) { + const trainedData = trainedResult.data?.models || []; + trainedData.forEach(model => { + if (model.train_methods && model.train_methods.length > 0) { + model.train_methods.forEach(method => { + trainedModels.push({ + id: `trained_${model.name}_${method.name}`.replace(/[^a-zA-Z0-9]/g, '_'), + name: `${model.name} (${method.name})`, + type: 'LLM', + source: 'trained', + model_path: model.path, + train_method: method.name + }); + }); + } + }); + } + + // 合并所有模型 + allModels = [...dbModels, ...trainedModels]; + console.log('[DEBUG] 数据库模型:', dbModels.length, '已训练模型:', trainedModels.length); + renderModels(); } catch (error) { console.error('加载模型失败:', error); document.getElementById('modelList').innerHTML = ` @@ -335,9 +367,14 @@ } } - // 渲染模型列表 + // 渲染模型列表 - 使用分栏显示数据库模型和已训练模型 function renderModels() { const container = document.getElementById('modelList'); + + // 分离数据库模型和已训练模型 + const dbModels = allModels.filter(m => m.source !== 'trained'); + const trainedModels = allModels.filter(m => m.source === 'trained'); + if (allModels.length === 0) { container.innerHTML = `
@@ -348,42 +385,74 @@ return; } - container.innerHTML = allModels.map(model => { - const isSelected = selectedModels.has(model.id); - const isDisabled = !isSelected && selectedModels.size >= 4; - const typeText = { - 'LLM': '大语言模型', - 'CV': '计算机视觉', - 'NLP': '自然语言处理', - 'Embedding': '向量模型', - 'Other': '其他' - }[model.type] || model.type || '其他'; + let html = ''; - return ` -
-
-
-
- ${isSelected ? '' : ''} -
-
-
- ${model.name} - ${typeText} -
-

${model.description || '暂无描述'}

-
+ // 数据库模型区域 + if (dbModels.length > 0) { + html += ` +
+
+ 数据库模型 (${dbModels.length}) +
+
+ `; + html += dbModels.map(model => renderModelCard(model)).join(''); + html += '
'; + } + + // 已训练模型区域 + if (trainedModels.length > 0) { + html += ` +
+
+ 已训练模型 (${trainedModels.length}) +
+
+ `; + html += trainedModels.map(model => renderModelCard(model)).join(''); + html += '
'; + } + + container.innerHTML = html; + updateSelectedCount(); + } + + // 渲染单个模型卡片 + function renderModelCard(model) { + const isSelected = selectedModels.has(model.id); + const isDisabled = !isSelected && selectedModels.size >= 4; + const typeText = { + 'LLM': '大语言模型', + 'CV': '计算机视觉', + 'NLP': '自然语言处理', + 'Embedding': '向量模型', + 'Other': '其他' + }[model.type] || model.type || '其他'; + // 处理字符串类型的ID + const modelId = typeof model.id === 'string' ? `'${model.id.replace(/'/g, "\\'")}'` : model.id; + + return ` +
+
+
+
+ ${isSelected ? '' : ''}
-
- ${model.model_source === 'local' ? '本地模型' : '在线模型'} +
+
+ ${model.name} + ${typeText} +
+

${model.description || '暂无描述'}

+
+ ${model.source === 'trained' || model.model_source === 'local' ? '本地模型' : '在线模型'} +
- `; - }).join(''); - - updateSelectedCount(); +
+ `; } // 切换模型选择 @@ -399,6 +468,11 @@ renderModels(); } + // 暴露到全局作用域供 onclick 调用 + window.toggleModel = toggleModel; + window.goBack = goBack; + window.submitForm = submitForm; + // 筛选模型 function filterModels(keyword) { const filtered = allModels.filter(model => { @@ -411,7 +485,7 @@ renderFilteredModels(filtered); } - // 渲染筛选后的模型列表 + // 渲染筛选后的模型列表 - 使用分栏显示 function renderFilteredModels(models) { const container = document.getElementById('modelList'); if (models.length === 0) { @@ -424,40 +498,39 @@ return; } - container.innerHTML = models.map(model => { - const isSelected = selectedModels.has(model.id); - const isDisabled = !isSelected && selectedModels.size >= 4; - const typeText = { - 'LLM': '大语言模型', - 'CV': '计算机视觉', - 'NLP': '自然语言处理', - 'Embedding': '向量模型', - 'Other': '其他' - }[model.type] || model.type || '其他'; + // 分离数据库模型和已训练模型 + const dbModels = models.filter(m => m.source !== 'trained'); + const trainedModels = models.filter(m => m.source === 'trained'); - return ` -
-
-
-
- ${isSelected ? '' : ''} -
-
-
- ${model.name} - ${typeText} -
-

${model.description || '暂无描述'}

-
-
-
- ${model.model_source === 'local' ? '本地模型' : '在线模型'} -
+ let html = ''; + + // 数据库模型区域 + if (dbModels.length > 0) { + html += ` +
+
+ 数据库模型 (${dbModels.length})
-
+
`; - }).join(''); + html += dbModels.map(model => renderModelCard(model)).join(''); + html += '
'; + } + + // 已训练模型区域 + if (trainedModels.length > 0) { + html += ` +
+
+ 已训练模型 (${trainedModels.length}) +
+
+ `; + html += trainedModels.map(model => renderModelCard(model)).join(''); + html += '
'; + } + + container.innerHTML = html; } // 更新已选数量 diff --git a/web/pages/model-inference.html b/web/pages/model-inference.html new file mode 100644 index 0000000..e5b2072 --- /dev/null +++ b/web/pages/model-inference.html @@ -0,0 +1,522 @@ + + + + + + 模型推理 - 远光软件微调平台 + + + + + + + + + + +
+ +
+
+ +
+
+ + 加载中... +
+
+
+
+ + +
+ +
+
+
+ 训练方法: + - +
+
+ 基座模型: + - +
+
+
+
+ + + 0.7 +
+ +
+
+ + +
+ +
+
+
+
+ +
+
+
AI 助手
+
+ 您好!我是基于该模型训练的AI助手。请在下方输入您的问题,我会尽力为您解答。 +
+
+
+
+
+
+ + +
+
+
+
+ +
+ +
+
+ + 按 Enter 发送,Shift+Enter 换行 +
+
+
+
+
+ + + +