fix: 推理/评测结果同步、数据集统计与算力节点管理增强

后端:
- 抽取 fetch_eval_result_content 复用函数,model_eval_detail 直接应用评测任务结果
- health 接口移除数据库依赖,返回静态指标
- 数据集: count_dataset_records JSON 感知计数; 文件统计改为从 dataset_files 聚合重算; 在线编辑记录 size/record_count/version_no; 上传同步批处理
- 算力节点: 调度支持 requested GPU 子集校验与容量计算; 新增 delete_compute_node(含活动任务保护)及 DELETE 接口; 连接池 connect_timeout
- 评测任务落库 basic_metrics/score/completed_time, failed/stopped 记录 error

评测引擎:
- _load_dataset 支持 JSON/JSONL 文件
- 新增 exact match 与文本相似度指标, 余弦相似度去掉 2 样本限制

前端:
- 算力节点列表「维护」改为「删除」(带确认弹窗), compute.ts 新增 deleteComputeNode
- 数据集上传超时调整为 120s; FineTuneTask 增加 compute_node_id; GpuInfo 状态增加 reserved
This commit is contained in:
wuyongtao
2026-08-03 15:49:21 +08:00
parent cc08b164d0
commit 5cc306eb0a
15 changed files with 402 additions and 112 deletions

View File

@@ -1,9 +1,10 @@
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import PageCard from '@/components/PageCard.vue'
import ModelStatusTag from '@/components/ModelStatusTag.vue'
import { getEvalDetail } from '@/api/modules/eval'
import { usePolling } from '@/composables/usePolling'
import type { EvalSampleResult, EvalTaskDetail } from '@/types'
const route = useRoute()
@@ -16,6 +17,7 @@ const keyword = ref('')
const judgementFilter = ref('')
const currentPage = ref(1)
const pageSize = ref(10)
const ACTIVE_STATUSES = new Set(['pending', 'queued', 'running'])
const filteredSamples = computed(() => {
const normalizedKeyword = keyword.value.trim().toLowerCase()
@@ -74,8 +76,8 @@ function resetPage() {
currentPage.value = 1
}
async function loadDetail() {
loading.value = true
async function loadDetail(options: { silent?: boolean } = {}) {
if (!options.silent) loading.value = true
loadError.value = ''
try {
detail.value = await getEvalDetail(taskId)
@@ -83,11 +85,29 @@ async function loadDetail() {
detail.value = null
loadError.value = '评测详情加载失败,请稍后重试。'
} finally {
loading.value = false
if (!options.silent) loading.value = false
}
}
onMounted(loadDetail)
const { start: startPolling, stop: stopPolling } = usePolling(
async () => {
await loadDetail({ silent: true })
if (!ACTIVE_STATUSES.has(String(detail.value?.status || ''))) {
stopPolling()
}
},
5000,
{ immediate: false },
)
onMounted(async () => {
await loadDetail()
if (ACTIVE_STATUSES.has(String(detail.value?.status || ''))) {
startPolling()
}
})
onUnmounted(stopPolling)
</script>
<template>
@@ -113,7 +133,7 @@ onMounted(loadDetail)
<i class="fa fa-exclamation-circle" aria-hidden="true" />
<h2>无法加载评测详情</h2>
<p>{{ loadError }}</p>
<el-button type="primary" @click="loadDetail">重新加载</el-button>
<el-button type="primary" @click="() => loadDetail()">重新加载</el-button>
</div>
<template v-else-if="detail">