164 lines
4.2 KiB
Vue
164 lines
4.2 KiB
Vue
<script setup lang="ts">
|
|
import { ref, watch } from 'vue'
|
|
import type { FormInstance, FormRules } from 'element-plus'
|
|
import type { DatasetItem, GpuInfo, TrainedModel } from '@/types'
|
|
|
|
export interface EvalTaskSetupDraft {
|
|
eval_task_name: string
|
|
model_id: string | number
|
|
gpu_id: string | number
|
|
data_source: 'dataset' | 'inference'
|
|
dataset_id: string | number
|
|
leaderboard: boolean
|
|
}
|
|
|
|
defineProps<{
|
|
trainedModels: TrainedModel[]
|
|
evalDatasets: DatasetItem[]
|
|
gpus: GpuInfo[]
|
|
loading?: boolean
|
|
disabled?: boolean
|
|
}>()
|
|
|
|
const form = defineModel<EvalTaskSetupDraft>({ required: true })
|
|
const formRef = ref<FormInstance>()
|
|
|
|
const rules: FormRules<EvalTaskSetupDraft> = {
|
|
eval_task_name: [
|
|
{ required: true, message: '请输入任务名称', trigger: 'blur' },
|
|
{ max: 50, message: '任务名称不超过 50 个字符', trigger: 'blur' },
|
|
],
|
|
model_id: [{ required: true, message: '请选择评测模型', trigger: 'change' }],
|
|
gpu_id: [{ required: true, message: '请选择 GPU', trigger: 'change' }],
|
|
dataset_id: [
|
|
{
|
|
validator: (_rule, value, callback) => {
|
|
if (form.value.data_source === 'dataset' && (value === '' || value === null || value === undefined)) {
|
|
callback(new Error('请选择评测数据集'))
|
|
return
|
|
}
|
|
callback()
|
|
},
|
|
trigger: 'change',
|
|
},
|
|
],
|
|
}
|
|
|
|
watch(
|
|
() => form.value.data_source,
|
|
(source) => {
|
|
if (source !== 'dataset') {
|
|
form.value.dataset_id = ''
|
|
formRef.value?.clearValidate('dataset_id')
|
|
}
|
|
},
|
|
)
|
|
|
|
async function validate() {
|
|
if (!formRef.value) return false
|
|
try {
|
|
const valid = await formRef.value.validate()
|
|
return !!valid
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
defineExpose({ validate })
|
|
</script>
|
|
|
|
<template>
|
|
<el-form
|
|
ref="formRef"
|
|
:model="form"
|
|
:rules="rules"
|
|
label-width="120px"
|
|
class="step-form"
|
|
:disabled="disabled"
|
|
scroll-to-error
|
|
>
|
|
<el-form-item label="任务名称" prop="eval_task_name">
|
|
<el-input v-model="form.eval_task_name" placeholder="请输入任务名称" maxlength="50" show-word-limit />
|
|
</el-form-item>
|
|
|
|
<el-form-item label="评测模型" prop="model_id">
|
|
<el-select
|
|
v-model="form.model_id"
|
|
placeholder="请选择已训练且已合并的模型"
|
|
filterable
|
|
style="width: 100%"
|
|
:loading="loading"
|
|
>
|
|
<el-option
|
|
v-for="model in trainedModels"
|
|
:key="model.id"
|
|
:label="model.name"
|
|
:value="model.id"
|
|
:disabled="!model.merged"
|
|
/>
|
|
</el-select>
|
|
<div class="field-tip">未完成合并的模型不可用于评测。</div>
|
|
</el-form-item>
|
|
|
|
<el-form-item label="选择 GPU" prop="gpu_id">
|
|
<el-select v-model="form.gpu_id" placeholder="请选择 GPU" style="width: 100%" :loading="loading">
|
|
<el-option
|
|
v-for="(gpu, index) in gpus"
|
|
:key="index"
|
|
:label="`${gpu.name} (GPU ${index})`"
|
|
:value="index"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item label="数据来源">
|
|
<el-radio-group v-model="form.data_source">
|
|
<el-radio value="dataset">评测数据集</el-radio>
|
|
<el-radio value="inference">推理结果集</el-radio>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
|
|
<el-form-item v-if="form.data_source === 'dataset'" label="评测数据集" prop="dataset_id">
|
|
<el-select
|
|
v-model="form.dataset_id"
|
|
placeholder="请选择评测数据集"
|
|
filterable
|
|
style="width: 100%"
|
|
:loading="loading"
|
|
>
|
|
<el-option v-for="dataset in evalDatasets" :key="dataset.id" :label="dataset.name" :value="dataset.id" />
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-alert
|
|
v-else
|
|
title="将使用该模型最近一次可用的推理结果集。"
|
|
type="info"
|
|
:closable="false"
|
|
show-icon
|
|
class="source-alert"
|
|
/>
|
|
|
|
<el-form-item label="加入排行榜">
|
|
<el-switch v-model="form.leaderboard" />
|
|
</el-form-item>
|
|
</el-form>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.step-form {
|
|
max-width: 760px;
|
|
}
|
|
|
|
.field-tip {
|
|
color: #909399;
|
|
font-size: 12px;
|
|
line-height: 20px;
|
|
}
|
|
|
|
.source-alert {
|
|
margin: -4px 0 20px 120px;
|
|
max-width: 640px;
|
|
}
|
|
</style>
|