| @@ -85,7 +85,7 @@ LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(G | |||
| GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(filter-out code.gitea.io/gitea/integrations,$(shell $(GO) list -mod=vendor ./... | grep -v /vendor/))) | |||
| WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f) | |||
| WEBPACK_SOURCES := $(shell find web_src/js web_src/less web_src/vuepages -type f) | |||
| WEBPACK_CONFIGS := webpack.config.js | |||
| WEBPACK_CONFIGS_TMP := webpack_temp.config.js | |||
| WEBPACK_CONFIGS_PRO := webpack_pro.config.js | |||
| @@ -65,7 +65,6 @@ const ( | |||
| ActionCreateImage //36 | |||
| ActionImageRecommend //37 | |||
| ActionChangeUserAvatar //38 | |||
| ) | |||
| // Action represents user operation type and other information to | |||
| @@ -53,8 +53,11 @@ const ( | |||
| JobFailed CloudbrainStatus = "FAILED" | |||
| JobRunning CloudbrainStatus = "RUNNING" | |||
| ModelSafetyTesting CloudbrainStatus = "TESTING" | |||
| JobTypeDebug JobType = "DEBUG" | |||
| JobTypeBenchmark JobType = "BENCHMARK" | |||
| JobTypeModelSafety JobType = "MODELSAFETY" | |||
| JobTypeSnn4imagenet JobType = "SNN4IMAGENET" | |||
| JobTypeBrainScore JobType = "BRAINSCORE" | |||
| JobTypeTrain JobType = "TRAIN" | |||
| @@ -172,26 +175,26 @@ type Cloudbrain struct { | |||
| ImageID string //grampus image_id | |||
| AiCenter string //grampus ai center: center_id+center_name | |||
| TrainUrl string //输出模型的obs路径 | |||
| BranchName string //分支名称 | |||
| Parameters string //传给modelarts的param参数 | |||
| BootFile string //启动文件 | |||
| DataUrl string //数据集的obs路径 | |||
| LogUrl string //日志输出的obs路径 | |||
| PreVersionId int64 //父版本的版本id | |||
| FlavorCode string //modelarts上的规格id | |||
| Description string `xorm:"varchar(256)"` //描述 | |||
| WorkServerNumber int //节点数 | |||
| FlavorName string //规格名称 | |||
| EngineName string //引擎名称 | |||
| TotalVersionCount int //任务的所有版本数量,包括删除的 | |||
| LabelName string //标签名称 | |||
| ModelName string //模型名称 | |||
| ModelVersion string //模型版本 | |||
| CkptName string //权重文件名称 | |||
| PreTrainModelUrl string //预训练模型地址 | |||
| ResultUrl string //推理结果的obs路径 | |||
| TrainUrl string //输出模型的obs路径 | |||
| BranchName string //分支名称 | |||
| Parameters string //传给modelarts的param参数 | |||
| BootFile string //启动文件 | |||
| DataUrl string //数据集的obs路径 | |||
| LogUrl string //日志输出的obs路径 | |||
| PreVersionId int64 //父版本的版本id | |||
| FlavorCode string //modelarts上的规格id | |||
| Description string `xorm:"varchar(256)"` //描述 | |||
| WorkServerNumber int //节点数 | |||
| FlavorName string //规格名称 | |||
| EngineName string //引擎名称 | |||
| TotalVersionCount int //任务的所有版本数量,包括删除的 | |||
| LabelName string //标签名称 | |||
| ModelName string //模型名称 | |||
| ModelVersion string //模型版本 | |||
| CkptName string //权重文件名称 | |||
| PreTrainModelUrl string //预训练模型地址 | |||
| ResultUrl string //推理结果的obs路径 | |||
| ResultJson string `xorm:"varchar(4000)"` | |||
| User *User `xorm:"-"` | |||
| Repo *Repository `xorm:"-"` | |||
| BenchmarkType string `xorm:"-"` //算法评测,模型评测 | |||
| @@ -1490,6 +1493,8 @@ type GrampusTasks struct { | |||
| ReplicaNum int `json:"replicaNum"` | |||
| Datasets []GrampusDataset `json:"datasets"` | |||
| Models []GrampusDataset `json:"models"` | |||
| Code GrampusDataset `json:"code"` | |||
| BootFile string `json:"bootFile"` | |||
| } | |||
| type GrampusDataset struct { | |||
| @@ -2003,6 +2008,13 @@ func GetStoppedJobWithNoStartTimeEndTime() ([]*Cloudbrain, error) { | |||
| return cloudbrains, x.SQL("select * from cloudbrain where status in (?,?,?,?,?,?,?) and (start_time is null or end_time is null) limit 100", ModelArtsTrainJobCompleted, ModelArtsTrainJobFailed, ModelArtsTrainJobKilled, ModelArtsStopped, JobStopped, JobFailed, JobSucceeded).Find(&cloudbrains) | |||
| } | |||
| func GetModelSafetyTestTask() ([]*Cloudbrain, error) { | |||
| cloudbrains := make([]*Cloudbrain, 0) | |||
| sess := x.Where("job_type = ?", string(JobTypeModelSafety)) | |||
| err := sess.Find(&cloudbrains) | |||
| return cloudbrains, err | |||
| } | |||
| func GetCloudbrainCountByUserID(userID int64, jobType string) (int, error) { | |||
| count, err := x.In("status", JobWaiting, JobRunning).And("job_type = ? and user_id = ? and type = ?", jobType, userID, TypeCloudBrainOne).Count(new(Cloudbrain)) | |||
| return int(count), err | |||
| @@ -2017,7 +2029,12 @@ func GetCloudbrainRunCountByRepoID(repoID int64) (int, error) { | |||
| } | |||
| func GetBenchmarkCountByUserID(userID int64) (int, error) { | |||
| count, err := x.In("status", JobWaiting, JobRunning).And("(job_type = ? or job_type = ? or job_type = ?) and user_id = ? and type = ?", string(JobTypeBenchmark), string(JobTypeBrainScore), string(JobTypeSnn4imagenet), userID, TypeCloudBrainOne).Count(new(Cloudbrain)) | |||
| count, err := x.In("status", JobWaiting, JobRunning).And("(job_type = ? or job_type = ? or job_type = ?) and user_id = ? and type = ?", string(JobTypeBenchmark), string(JobTypeModelSafety), string(JobTypeBrainScore), string(JobTypeSnn4imagenet), userID, TypeCloudBrainOne).Count(new(Cloudbrain)) | |||
| return int(count), err | |||
| } | |||
| func GetModelSafetyCountByUserID(userID int64) (int, error) { | |||
| count, err := x.In("status", JobWaiting, JobRunning).And("job_type = ? and user_id = ?", string(JobTypeModelSafety), userID).Count(new(Cloudbrain)) | |||
| return int(count), err | |||
| } | |||
| @@ -0,0 +1,249 @@ | |||
| package aisafety | |||
| import ( | |||
| "crypto/md5" | |||
| "encoding/hex" | |||
| "encoding/json" | |||
| "fmt" | |||
| "net/url" | |||
| "sort" | |||
| "strings" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "github.com/go-resty/resty/v2" | |||
| ) | |||
| var ( | |||
| restyClient *resty.Client | |||
| HOST string | |||
| KEY string | |||
| ) | |||
| type TaskReq struct { | |||
| UnionId string //评测任务ID,唯一标识,由后端生成UUID | |||
| EvalName string //评测任务名称 | |||
| EvalContent string //评测任务描述 | |||
| TLPath string // | |||
| Indicators []string //评测指标,由GetAlgorithmList接口返回的指标列表中的title属性值 | |||
| CDPath string | |||
| CDName string //对抗数据集名称 | |||
| BDPath string | |||
| BDName string //原数据集名称 | |||
| } | |||
| type ReturnMsg struct { | |||
| Code string `json:"code"` | |||
| Msg string `json:"msg"` | |||
| Data ReturnData `json:"data"` | |||
| Times int64 `json:"times"` | |||
| } | |||
| type ReturnData struct { | |||
| ID int `json:"id"` | |||
| No string `json:"no"` | |||
| StandardJson string `json:"standardJson"` | |||
| Code int `json:"code"` | |||
| Msg string `json:"msg"` | |||
| Status int `json:"status"` | |||
| } | |||
| const ( | |||
| APPID = "1" | |||
| LogPageSize = 500 | |||
| LogPageTokenExpired = "5m" | |||
| pageSize = 15 | |||
| Success = "S000" | |||
| ) | |||
| func getRestyClient() *resty.Client { | |||
| if restyClient == nil { | |||
| restyClient = resty.New() | |||
| } | |||
| return restyClient | |||
| } | |||
| func checkSetting() { | |||
| if len(HOST) != 0 && len(KEY) != 0 { | |||
| return | |||
| } | |||
| _ = loginCloudbrain() | |||
| } | |||
| func loginCloudbrain() error { | |||
| HOST = "http://221.122.70.196:8081/atp-api" | |||
| KEY = "1" | |||
| return nil | |||
| } | |||
| func createSign(params map[string]interface{}, signKey string) string { | |||
| var sceneList []string | |||
| for k := range params { | |||
| sceneList = append(sceneList, k) | |||
| } | |||
| sort.Strings(sceneList) | |||
| re := "" | |||
| for _, key := range sceneList { | |||
| if params[key] != nil { | |||
| re += key + "=" + fmt.Sprint(params[key]) + "&" | |||
| } | |||
| } | |||
| re += "key=" + signKey | |||
| log.Info("sign key:" + re) | |||
| h := md5.New() | |||
| h.Write([]byte(re)) | |||
| return strings.ToUpper(hex.EncodeToString(h.Sum(nil))) | |||
| } | |||
| func getParams(req TaskReq) (map[string]interface{}, string) { | |||
| params := make(map[string]interface{}) | |||
| reStr := "" | |||
| params["unionId"] = req.UnionId | |||
| reStr += "unionId=" + req.UnionId | |||
| params["evalName"] = req.EvalName | |||
| reStr += "&evalName=" + req.EvalName | |||
| params["evalContent"] = req.EvalContent | |||
| reStr += "&evalContent=" + url.QueryEscape(req.EvalContent) | |||
| params["TLPath"] = req.TLPath | |||
| reStr += "&TLPath=" + url.QueryEscape(req.TLPath) | |||
| params["CDName"] = req.CDName | |||
| reStr += "&CDName=" + url.QueryEscape(req.CDName) | |||
| params["BDName"] = req.BDName | |||
| reStr += "&BDName=" + url.QueryEscape(req.BDName) | |||
| if req.CDPath != "" { | |||
| params["CDPath"] = req.CDPath | |||
| reStr += "&CDPath=" + url.QueryEscape(req.CDPath) | |||
| } | |||
| if req.BDPath != "" { | |||
| params["BDPath"] = req.BDPath | |||
| reStr += "&BDPath=" + url.QueryEscape(req.BDPath) | |||
| } | |||
| indicators := "" | |||
| if len(req.Indicators) > 0 { | |||
| for _, tmp := range req.Indicators { | |||
| indicators += tmp + "|" | |||
| } | |||
| } | |||
| if len(indicators) > 0 { | |||
| indicators = indicators[0 : len(indicators)-1] | |||
| } | |||
| params["Indicators"] = indicators | |||
| log.Info("indicators=" + indicators) | |||
| reStr += "&Indicators=" + url.QueryEscape(indicators) | |||
| return params, reStr | |||
| } | |||
| func CreateSafetyTask(req TaskReq, jsonstr string) (string, error) { | |||
| checkSetting() | |||
| client := getRestyClient() | |||
| //reqPara, _ := json.Marshal(body) | |||
| //log.Warn("job req:", jsonstr) | |||
| params, urlQuerys := getParams(req) | |||
| bodyMap := make(map[string]interface{}) | |||
| //reJsonMap := make(map[string]interface{}) | |||
| bodyMap["resJson"] = jsonstr | |||
| //bodyMap["externalEvalParam"] = reJsonMap | |||
| //reqPara, _ := json.Marshal(bodyMap) | |||
| //log.Warn("job req json:", string(reqPara)) | |||
| res, err := client.R(). | |||
| SetHeader("Content-Type", "application/json"). | |||
| SetHeader("appId", APPID). | |||
| SetHeader("sign", createSign(params, KEY)). | |||
| //SetAuthToken(TOKEN). | |||
| SetBody(bodyMap). | |||
| Post(HOST + "/v1/external/eval-standard/create?" + urlQuerys) | |||
| log.Info("url=" + HOST + "/v1/external/eval-standard/create?" + urlQuerys) | |||
| responseStr := string(res.Body()) | |||
| log.Info("CreateSafetyTask responseStr=" + responseStr + " res code=" + fmt.Sprint(res.StatusCode())) | |||
| if err != nil { | |||
| return "", fmt.Errorf("resty create job: %s", err) | |||
| } else { | |||
| log.Info("result string=" + " res code=" + fmt.Sprint(res.StatusCode())) | |||
| } | |||
| reMap := make(map[string]interface{}) | |||
| err = json.Unmarshal(res.Body(), &reMap) | |||
| if err == nil && reMap["code"] == "0" { | |||
| dataMap := (reMap["data"]).(map[string]interface{}) | |||
| return fmt.Sprint(dataMap["serialNo"]), nil | |||
| } | |||
| return "", nil | |||
| } | |||
| func GetAlgorithmList() (map[string]interface{}, error) { | |||
| checkSetting() | |||
| client := getRestyClient() | |||
| params := make(map[string]interface{}) | |||
| jsonResult := make(map[string]interface{}) | |||
| sign := createSign(params, KEY) | |||
| res, err := client.R(). | |||
| SetHeader("Content-Type", "application/json"). | |||
| SetHeader("appId", APPID). | |||
| SetHeader("sign", sign). | |||
| Get(HOST + "/v1/external/eval-standard/algorithmList") | |||
| log.Info("url=" + HOST + "/v1/external/eval-standard/algorithmList" + " sign=" + sign + " appId=" + APPID) | |||
| jsonerr := json.Unmarshal(res.Body(), &jsonResult) | |||
| if jsonerr == nil { | |||
| log.Info("jsonResult code=" + fmt.Sprint(jsonResult["msg"])) | |||
| } | |||
| responseStr := string(res.Body()) | |||
| log.Info("GetAlgorithmList responseStr=" + responseStr + " res code=" + fmt.Sprint(res.StatusCode())) | |||
| if err != nil { | |||
| log.Info("error =" + err.Error()) | |||
| return nil, fmt.Errorf("resty GetJob: %v", err) | |||
| } else { | |||
| reMap := make(map[string]interface{}) | |||
| err = json.Unmarshal(res.Body(), &reMap) | |||
| if err == nil && reMap["code"] == "0" { | |||
| return reMap, nil | |||
| } else { | |||
| return nil, fmt.Errorf("get error,code not 0") | |||
| } | |||
| } | |||
| } | |||
| func GetTaskStatus(jobID string) (*ReturnMsg, error) { | |||
| checkSetting() | |||
| client := getRestyClient() | |||
| var reMap ReturnMsg | |||
| params := make(map[string]interface{}) | |||
| params["serialNo"] = jobID | |||
| res, err := client.R(). | |||
| SetHeader("Content-Type", "application/json"). | |||
| SetHeader("appId", APPID). | |||
| SetHeader("sign", createSign(params, KEY)). | |||
| SetResult(&reMap). | |||
| Get(HOST + "/v1/external/eval-standard/query?serialNo=" + jobID) | |||
| log.Info("url=" + HOST + "/v1/external/eval-standard/query?serialNo=" + jobID) | |||
| responseStr := string(res.Body()) | |||
| log.Info("GetTaskStatus responseStr=" + responseStr + " res code=" + fmt.Sprint(res.StatusCode())) | |||
| if err != nil { | |||
| log.Info("error =" + err.Error()) | |||
| return nil, fmt.Errorf("Get task status error: %v", err) | |||
| } else { | |||
| return &reMap, nil | |||
| } | |||
| } | |||
| @@ -20,19 +20,19 @@ import ( | |||
| const ( | |||
| //Command = `pip3 install jupyterlab==2.2.5 -i https://pypi.tuna.tsinghua.edu.cn/simple;service ssh stop;jupyter lab --no-browser --ip=0.0.0.0 --allow-root --notebook-dir="/code" --port=80 --LabApp.token="" --LabApp.allow_origin="self https://cloudbrain.pcl.ac.cn"` | |||
| //CommandBenchmark = `echo "start benchmark";python /code/test.py;echo "end benchmark"` | |||
| CommandBenchmark = `cd /benchmark && bash run_bk.sh >/model/benchmark-log.txt` | |||
| CodeMountPath = "/code" | |||
| DataSetMountPath = "/dataset" | |||
| ModelMountPath = "/model" | |||
| CommandBenchmark = `cd /benchmark && bash run_bk.sh >/model/benchmark-log.txt` | |||
| CodeMountPath = "/code" | |||
| DataSetMountPath = "/dataset" | |||
| ModelMountPath = "/model" | |||
| PretrainModelMountPath = "/pretrainmodel" | |||
| LogFile = "log.txt" | |||
| BenchMarkMountPath = "/benchmark" | |||
| BenchMarkResourceID = 1 | |||
| Snn4imagenetMountPath = "/snn4imagenet" | |||
| BrainScoreMountPath = "/brainscore" | |||
| TaskInfoName = "/taskInfo" | |||
| Snn4imagenetCommand = `/opt/conda/bin/python /snn4imagenet/testSNN_script.py --modelname '%s' --modelpath '/dataset' --modeldescription '%s' >/model/benchmark-log.txt` | |||
| BrainScoreCommand = `bash /brainscore/brainscore_test_par4shSrcipt.sh -b '%s' -n '%s' -p '/dataset' -d '%s' >/model/benchmark-log.txt` | |||
| LogFile = "log.txt" | |||
| BenchMarkMountPath = "/benchmark" | |||
| BenchMarkResourceID = 1 | |||
| Snn4imagenetMountPath = "/snn4imagenet" | |||
| BrainScoreMountPath = "/brainscore" | |||
| TaskInfoName = "/taskInfo" | |||
| Snn4imagenetCommand = `/opt/conda/bin/python /snn4imagenet/testSNN_script.py --modelname '%s' --modelpath '/dataset' --modeldescription '%s' >/model/benchmark-log.txt` | |||
| BrainScoreCommand = `bash /brainscore/brainscore_test_par4shSrcipt.sh -b '%s' -n '%s' -p '/dataset' -d '%s' >/model/benchmark-log.txt` | |||
| SubTaskName = "task1" | |||
| @@ -405,7 +405,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
| } | |||
| func IsBenchmarkJob(jobType string) bool { | |||
| return string(models.JobTypeBenchmark) == jobType || string(models.JobTypeBrainScore) == jobType || string(models.JobTypeSnn4imagenet) == jobType | |||
| return string(models.JobTypeModelSafety) == jobType || string(models.JobTypeBenchmark) == jobType || string(models.JobTypeBrainScore) == jobType || string(models.JobTypeSnn4imagenet) == jobType | |||
| } | |||
| func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTypes ...models.JobType) int64 { | |||
| @@ -5,12 +5,13 @@ | |||
| package cron | |||
| import ( | |||
| "code.gitea.io/gitea/services/reward" | |||
| "code.gitea.io/gitea/services/cloudbrain/resource" | |||
| "code.gitea.io/gitea/modules/modelarts" | |||
| "context" | |||
| "time" | |||
| "code.gitea.io/gitea/modules/modelarts" | |||
| "code.gitea.io/gitea/services/cloudbrain/resource" | |||
| "code.gitea.io/gitea/services/reward" | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/migrations" | |||
| repository_service "code.gitea.io/gitea/modules/repository" | |||
| @@ -122,6 +123,17 @@ func registerHandleUnDecompressAttachment() { | |||
| }) | |||
| } | |||
| func registerHandleModelSafetyTask() { | |||
| RegisterTaskFatal("handle_modelsafety_task", &BaseConfig{ | |||
| Enabled: true, | |||
| RunAtStart: true, | |||
| Schedule: "@every 5m", | |||
| }, func(ctx context.Context, _ *models.User, _ Config) error { | |||
| repo.TimerHandleModelSafetyTestTask() | |||
| return nil | |||
| }) | |||
| } | |||
| func registerHandleBlockChainUnSuccessUsers() { | |||
| RegisterTaskFatal("handle_blockchain_unsuccess_users", &BaseConfig{ | |||
| Enabled: true, | |||
| @@ -279,4 +291,6 @@ func initBasicTasks() { | |||
| //registerRewardPeriodTask() | |||
| registerCloudbrainPointDeductTask() | |||
| registerHandleModelSafetyTask() | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| package grampus | |||
| import ( | |||
| "code.gitea.io/gitea/modules/cloudbrain" | |||
| "encoding/json" | |||
| "strings" | |||
| @@ -73,6 +74,7 @@ type GenerateTrainJobReq struct { | |||
| PreTrainModelPath string | |||
| PreTrainModelUrl string | |||
| Spec *models.Specification | |||
| CodeName string | |||
| } | |||
| func getEndPoint() string { | |||
| @@ -102,6 +104,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| centerID, centerName := getCentersParamter(ctx, req) | |||
| var datasetGrampus, modelGrampus []models.GrampusDataset | |||
| var codeGrampus models.GrampusDataset | |||
| if ProcessorTypeNPU == req.ProcessType { | |||
| datasetGrampus = getDatasetGrampus(req.DatasetInfos) | |||
| if len(req.ModelName) != 0 { | |||
| @@ -114,6 +117,12 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| }, | |||
| } | |||
| } | |||
| codeGrampus = models.GrampusDataset{ | |||
| Name: req.CodeName, | |||
| Bucket: setting.Bucket, | |||
| EndPoint: getEndPoint(), | |||
| ObjectKey: req.CodeObsPath + cloudbrain.DefaultBranchName + ".zip", | |||
| } | |||
| } | |||
| jobResult, err := createJob(models.CreateGrampusJobRequest{ | |||
| @@ -130,6 +139,8 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error | |||
| ReplicaNum: 1, | |||
| Datasets: datasetGrampus, | |||
| Models: modelGrampus, | |||
| Code: codeGrampus, | |||
| BootFile: req.BootFile, | |||
| }, | |||
| }, | |||
| }) | |||
| @@ -1,7 +1,6 @@ | |||
| package modelarts | |||
| import ( | |||
| "code.gitea.io/gitea/modules/modelarts_cd" | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| @@ -9,6 +8,8 @@ import ( | |||
| "strconv" | |||
| "strings" | |||
| "code.gitea.io/gitea/modules/modelarts_cd" | |||
| "code.gitea.io/gitea/models" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "code.gitea.io/gitea/modules/log" | |||
| @@ -70,8 +71,8 @@ const ( | |||
| var ( | |||
| poolInfos *models.PoolInfos | |||
| TrainFlavorInfos *Flavor | |||
| SpecialPools *models.SpecialPools | |||
| MultiNodeConfig *MultiNodes | |||
| SpecialPools *models.SpecialPools | |||
| MultiNodeConfig *MultiNodes | |||
| ) | |||
| type GenerateTrainJobReq struct { | |||
| @@ -141,6 +142,7 @@ type GenerateInferenceJobReq struct { | |||
| ResultUrl string | |||
| Spec *models.Specification | |||
| DatasetName string | |||
| JobType string | |||
| } | |||
| type VersionInfo struct { | |||
| @@ -173,12 +175,12 @@ type ResourcePool struct { | |||
| } `json:"resource_pool"` | |||
| } | |||
| type MultiNodes struct{ | |||
| type MultiNodes struct { | |||
| Info []OrgMultiNode `json:"multinode"` | |||
| } | |||
| type OrgMultiNode struct{ | |||
| type OrgMultiNode struct { | |||
| Org string `json:"org"` | |||
| Node []int `json:"node"` | |||
| Node []int `json:"node"` | |||
| } | |||
| // type Parameter struct { | |||
| @@ -709,7 +711,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| Status: models.TempJobStatus, | |||
| Type: models.TypeCloudBrainTwo, | |||
| JobName: req.JobName, | |||
| JobType: string(models.JobTypeInference), | |||
| JobType: req.JobType, | |||
| }) | |||
| if err != nil { | |||
| log.Error("InsertCloudbrainTemp failed: %v", err.Error()) | |||
| @@ -732,7 +734,7 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| JobID: jobID, | |||
| JobName: req.JobName, | |||
| DisplayJobName: req.DisplayJobName, | |||
| JobType: string(models.JobTypeInference), | |||
| JobType: req.JobType, | |||
| Type: models.TypeCloudBrainTwo, | |||
| VersionID: jobResult.VersionID, | |||
| VersionName: jobResult.VersionName, | |||
| @@ -769,7 +771,15 @@ func GenerateInferenceJob(ctx *context.Context, req *GenerateInferenceJobReq) (e | |||
| log.Error("CreateCloudbrain(%s) failed:%v", req.JobName, err.Error()) | |||
| return err | |||
| } | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.DisplayJobName, models.ActionCreateInferenceTask) | |||
| if req.JobType == string(models.JobTypeModelSafety) { | |||
| task, err := models.GetCloudbrainByJobID(jobID) | |||
| if err == nil { | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, fmt.Sprint(task.ID), req.DisplayJobName, models.ActionCreateBenchMarkTask) | |||
| } | |||
| } else { | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, req.DisplayJobName, models.ActionCreateInferenceTask) | |||
| } | |||
| return nil | |||
| } | |||
| @@ -798,8 +808,8 @@ func InitSpecialPool() { | |||
| } | |||
| } | |||
| func InitMultiNode(){ | |||
| if MultiNodeConfig ==nil && setting.ModelArtsMultiNode!=""{ | |||
| func InitMultiNode() { | |||
| if MultiNodeConfig == nil && setting.ModelArtsMultiNode != "" { | |||
| json.Unmarshal([]byte(setting.ModelArtsMultiNode), &MultiNodeConfig) | |||
| } | |||
| @@ -714,6 +714,22 @@ var ( | |||
| NPU_MINDSPORE_IMAGE_ID int | |||
| NPU_TENSORFLOW_IMAGE_ID int | |||
| }{} | |||
| ModelSafetyTest = struct { | |||
| NPUBaseDataSetName string | |||
| NPUBaseDataSetUUID string | |||
| NPUCombatDataSetName string | |||
| NPUCombatDataSetUUID string | |||
| GPUBaseDataSetName string | |||
| GPUBaseDataSetUUID string | |||
| GPUCombatDataSetName string | |||
| GPUCombatDataSetUUID string | |||
| }{} | |||
| ModelApp = struct { | |||
| DesensitizationUrl string | |||
| }{} | |||
| ) | |||
| // DateLang transforms standard language locale name to corresponding value in datetime plugin. | |||
| @@ -1542,6 +1558,20 @@ func NewContext() { | |||
| getGrampusConfig() | |||
| getModelartsCDConfig() | |||
| getModelConvertConfig() | |||
| getModelSafetyConfig() | |||
| getModelAppConfig() | |||
| } | |||
| func getModelSafetyConfig() { | |||
| sec := Cfg.Section("model_safety_test") | |||
| ModelSafetyTest.GPUBaseDataSetName = sec.Key("GPUBaseDataSetName").MustString("") | |||
| ModelSafetyTest.GPUBaseDataSetUUID = sec.Key("GPUBaseDataSetUUID").MustString("") | |||
| ModelSafetyTest.GPUCombatDataSetName = sec.Key("GPUCombatDataSetName").MustString("") | |||
| ModelSafetyTest.GPUCombatDataSetUUID = sec.Key("GPUCombatDataSetUUID").MustString("") | |||
| ModelSafetyTest.NPUBaseDataSetName = sec.Key("NPUBaseDataSetName").MustString("") | |||
| ModelSafetyTest.NPUBaseDataSetUUID = sec.Key("NPUBaseDataSetUUID").MustString("") | |||
| ModelSafetyTest.NPUCombatDataSetName = sec.Key("NPUCombatDataSetName").MustString("") | |||
| ModelSafetyTest.NPUCombatDataSetUUID = sec.Key("NPUCombatDataSetUUID").MustString("") | |||
| } | |||
| func getModelConvertConfig() { | |||
| @@ -1563,6 +1593,12 @@ func getModelConvertConfig() { | |||
| ModelConvert.NPU_TENSORFLOW_IMAGE_ID = sec.Key("NPU_TENSORFLOW_IMAGE_ID").MustInt(35) | |||
| } | |||
| func getModelAppConfig() { | |||
| sec := Cfg.Section("model_app") | |||
| ModelApp.DesensitizationUrl = sec.Key("desensitization_url").MustString("") | |||
| } | |||
| func getModelartsCDConfig() { | |||
| sec := Cfg.Section("modelarts-cd") | |||
| @@ -1,30 +0,0 @@ | |||
| package timer | |||
| import ( | |||
| "github.com/robfig/cron/v3" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/routers/repo" | |||
| ) | |||
| func LaunchCronJob() { | |||
| log.Trace("Run cron job") | |||
| c := cron.New() | |||
| spec := "*/10 * * * *" | |||
| c.AddFunc(spec, repo.HandleUnDecompressAttachment) | |||
| specCheckBlockChainUserSuccess := "*/10 * * * *" | |||
| c.AddFunc(specCheckBlockChainUserSuccess, repo.HandleBlockChainUnSuccessUsers) | |||
| specCheckRepoBlockChainSuccess := "*/1 * * * *" | |||
| c.AddFunc(specCheckRepoBlockChainSuccess, repo.HandleBlockChainUnSuccessRepos) | |||
| specCheckUnTransformedPRs := "*/1 * * * *" | |||
| c.AddFunc(specCheckUnTransformedPRs, repo.HandleBlockChainMergedPulls) | |||
| specCheckBlockChainCommitSuccess := "*/3 * * * *" | |||
| c.AddFunc(specCheckBlockChainCommitSuccess, repo.HandleBlockChainUnSuccessCommits) | |||
| c.Start() | |||
| } | |||
| @@ -3262,3 +3262,20 @@ hours = Hours | |||
| expected_time = , expected to be available for | |||
| points_acquisition_instructions = Points Acquisition Instructions | |||
| insufficient_points_balance = Insufficient points balance | |||
| [modelsafety] | |||
| model_security_evaluation = Model Security Evaluation | |||
| base_data_set = Base Data Set | |||
| combat_data_set = Combat Data Set | |||
| evaluation_indicators = Evaluation Indicators | |||
| evaluation_result = Evaluation Result | |||
| no_data = No Data | |||
| untargetted = Untargetted | |||
| targetted = targetted | |||
| new_model_security_evaluation_tips = Model Security Evaluation just used for image classification | |||
| [model_app] | |||
| get_file_fail= Can not get the image content, please try again later. | |||
| content_type_unsupported=Allowed image type is jpg, jpeg or png. | |||
| process_image_fail=Fail to process image, please try again later. | |||
| @@ -3282,4 +3282,19 @@ expected_time = ,预计可用 | |||
| points_acquisition_instructions = 积分获取说明 | |||
| insufficient_points_balance = 积分余额不足 | |||
| [modelsafety] | |||
| model_security_evaluation = 模型安全评测 | |||
| base_data_set = 原始数据集 | |||
| combat_data_set = 对抗数据集 | |||
| evaluation_indicators = 评测指标 | |||
| evaluation_result = 评测结果 | |||
| no_data = 无数据 | |||
| untargetted = 非定向 | |||
| targetted = 定向 | |||
| new_model_security_evaluation_tips = 模型安全评测只适用于图像分类 | |||
| [model_app] | |||
| get_file_fail= 获取上传文件失败,请稍后再试。 | |||
| content_type_unsupported=请上传jpg、jpeg或png图片。 | |||
| process_image_fail=图片处理失败,请稍后再试。 | |||
| @@ -81,8 +81,11 @@ var isZh = true; | |||
| if(lang != null && lang.nodeValue =="en-US" ){ | |||
| isZh=false; | |||
| } | |||
| document.onreadystatechange = function () { | |||
| if(document.readyState != "complete"){ | |||
| return; | |||
| } | |||
| console.log("Start to open WebSocket." + document.readyState); | |||
| queryRecommendData(); | |||
| var output = document.getElementById("newmessage"); | |||
| @@ -102,10 +105,9 @@ document.onreadystatechange = function () { | |||
| var html = ""; | |||
| if (data != null){ | |||
| if(messageQueue.length > maxSize){ | |||
| delete messageQueue[0]; | |||
| }else{ | |||
| messageQueue.push(data); | |||
| messageQueue.splice(0,1); | |||
| } | |||
| messageQueue.push(data); | |||
| var currentTime = new Date().getTime(); | |||
| for(var i = 0; i < messageQueue.length; i++){ | |||
| var record = messageQueue[i]; | |||
| @@ -52,7 +52,7 @@ func CloudBrains(ctx *context.Context) { | |||
| var jobTypes []string | |||
| jobTypeNot := false | |||
| if jobType == string(models.JobTypeBenchmark) { | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| } else if jobType != "all" && jobType != "" { | |||
| jobTypes = append(jobTypes, jobType) | |||
| } | |||
| @@ -221,6 +221,7 @@ func GetResourceSceneList(ctx *context.Context) { | |||
| func AddResourceScene(ctx *context.Context, req models.ResourceSceneReq) { | |||
| req.CreatorId = ctx.User.ID | |||
| req.ExclusiveOrg = strings.ReplaceAll(req.ExclusiveOrg, " ", "") | |||
| err := resource.AddResourceScene(req) | |||
| if err != nil { | |||
| log.Error("AddResourceScene error. %v", err) | |||
| @@ -238,6 +239,7 @@ func UpdateResourceScene(ctx *context.Context, req models.ResourceSceneReq) { | |||
| var err error | |||
| switch action { | |||
| case "edit": | |||
| req.ExclusiveOrg = strings.ReplaceAll(req.ExclusiveOrg, " ", "") | |||
| err = resource.UpdateResourceScene(req) | |||
| case "delete": | |||
| err = resource.DeleteResourceScene(id) | |||
| @@ -12,6 +12,7 @@ import ( | |||
| "net/http" | |||
| "os" | |||
| "sort" | |||
| "strconv" | |||
| "strings" | |||
| "time" | |||
| @@ -67,49 +68,62 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||
| log.Error("GetCloudbrainByID failed:", err) | |||
| return | |||
| } | |||
| jobResult, err := cloudbrain.GetJob(job.JobID) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| log.Error("GetJob failed:", err) | |||
| return | |||
| } | |||
| result, _ := models.ConvertToJobResultPayload(jobResult.Payload) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| log.Error("ConvertToJobResultPayload failed:", err) | |||
| return | |||
| } | |||
| oldStatus := job.Status | |||
| job.Status = result.JobStatus.State | |||
| taskRoles := result.TaskRoles | |||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
| if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | |||
| job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | |||
| job.ContainerID = taskRes.TaskStatuses[0].ContainerID | |||
| job.Status = taskRes.TaskStatuses[0].State | |||
| } | |||
| if result.JobStatus.State != string(models.JobWaiting) { | |||
| models.ParseAndSetDurationFromCloudBrainOne(result, job) | |||
| if oldStatus != job.Status { | |||
| notification.NotifyChangeCloudbrainStatus(job, oldStatus) | |||
| if job.JobType == string(models.JobTypeModelSafety) { | |||
| routerRepo.GetAiSafetyTaskByJob(job) | |||
| job, err = models.GetCloudbrainByID(ID) | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "ID": ID, | |||
| "JobName": job.JobName, | |||
| "JobStatus": job.Status, | |||
| "SubState": "", | |||
| "CreatedTime": job.CreatedUnix.Format("2006-01-02 15:04:05"), | |||
| "CompletedTime": job.UpdatedUnix.Format("2006-01-02 15:04:05"), | |||
| "JobDuration": job.TrainJobDuration, | |||
| }) | |||
| } else { | |||
| jobResult, err := cloudbrain.GetJob(job.JobID) | |||
| if err != nil { | |||
| ctx.NotFound(err) | |||
| log.Error("GetJob failed:", err) | |||
| return | |||
| } | |||
| err = models.UpdateJob(job) | |||
| result, _ := models.ConvertToJobResultPayload(jobResult.Payload) | |||
| if err != nil { | |||
| log.Error("UpdateJob failed:", err) | |||
| ctx.NotFound(err) | |||
| log.Error("ConvertToJobResultPayload failed:", err) | |||
| return | |||
| } | |||
| oldStatus := job.Status | |||
| job.Status = result.JobStatus.State | |||
| taskRoles := result.TaskRoles | |||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
| if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | |||
| job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | |||
| job.ContainerID = taskRes.TaskStatuses[0].ContainerID | |||
| job.Status = taskRes.TaskStatuses[0].State | |||
| } | |||
| } | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "ID": ID, | |||
| "JobName": result.Config.JobName, | |||
| "JobStatus": result.JobStatus.State, | |||
| "SubState": result.JobStatus.SubState, | |||
| "CreatedTime": time.Unix(result.JobStatus.CreatedTime/1000, 0).Format("2006-01-02 15:04:05"), | |||
| "CompletedTime": time.Unix(result.JobStatus.CompletedTime/1000, 0).Format("2006-01-02 15:04:05"), | |||
| "JobDuration": job.TrainJobDuration, | |||
| }) | |||
| if result.JobStatus.State != string(models.JobWaiting) { | |||
| models.ParseAndSetDurationFromCloudBrainOne(result, job) | |||
| if oldStatus != job.Status { | |||
| notification.NotifyChangeCloudbrainStatus(job, oldStatus) | |||
| } | |||
| err = models.UpdateJob(job) | |||
| if err != nil { | |||
| log.Error("UpdateJob failed:", err) | |||
| } | |||
| } | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "ID": ID, | |||
| "JobName": result.Config.JobName, | |||
| "JobStatus": result.JobStatus.State, | |||
| "SubState": result.JobStatus.SubState, | |||
| "CreatedTime": time.Unix(result.JobStatus.CreatedTime/1000, 0).Format("2006-01-02 15:04:05"), | |||
| "CompletedTime": time.Unix(result.JobStatus.CompletedTime/1000, 0).Format("2006-01-02 15:04:05"), | |||
| "JobDuration": job.TrainJobDuration, | |||
| }) | |||
| } | |||
| } | |||
| func GetCloudBrainInferenceJob(ctx *context.APIContext) { | |||
| @@ -370,6 +384,96 @@ func CloudbrainForModelConvertGetLog(ctx *context.Context) { | |||
| ctx.JSON(http.StatusOK, result) | |||
| } | |||
| func ModelSafetyGetLog(ctx *context.APIContext) { | |||
| ID := ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"]) | |||
| ctx.ServerError(err.Error(), err) | |||
| return | |||
| } | |||
| if job.JobType == string(models.JobTypeModelSafety) { | |||
| if job.Type == models.TypeCloudBrainTwo { | |||
| //TrainJobForModelConvertGetLog(ctx) | |||
| var baseLine = ctx.Query("base_line") | |||
| var order = ctx.Query("order") | |||
| var lines = ctx.Query("lines") | |||
| lines_int, err := strconv.Atoi(lines) | |||
| if err != nil { | |||
| log.Error("change lines(%d) string to int failed", lines_int) | |||
| } | |||
| if order != modelarts.OrderDesc && order != modelarts.OrderAsc { | |||
| log.Error("order(%s) check failed", order) | |||
| ctx.JSON(http.StatusBadRequest, map[string]interface{}{ | |||
| "err_msg": "order check failed", | |||
| }) | |||
| return | |||
| } | |||
| resultLogFile, err := modelarts.GetTrainJobLogFileNames(job.JobID, strconv.FormatInt(job.VersionID, 10)) | |||
| if err != nil { | |||
| log.Error("GetTrainJobLogFileNames(%s) failed:%v", job.JobID, err.Error()) | |||
| } | |||
| result, err := modelarts.GetTrainJobLog(job.JobID, strconv.FormatInt(job.VersionID, 10), baseLine, resultLogFile.LogFileList[0], order, lines_int) | |||
| if err != nil { | |||
| log.Error("GetTrainJobLog(%s) failed:%v", job.JobID, err.Error()) | |||
| } | |||
| if err != nil { | |||
| log.Error("trainJobGetLog(%s) failed:%v", job.JobID, err.Error()) | |||
| // ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobShow, nil) | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "JobID": job.JobID, | |||
| "LogFileName": "", | |||
| "StartLine": "0", | |||
| "EndLine": "0", | |||
| "Content": "", | |||
| "Lines": 0, | |||
| "CanLogDownload": false, | |||
| }) | |||
| return | |||
| } | |||
| ctx.Data["log_file_name"] = resultLogFile.LogFileList[0] | |||
| ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
| "JobID": job.JobID, | |||
| "LogFileName": resultLogFile.LogFileList[0], | |||
| "StartLine": result.StartLine, | |||
| "EndLine": result.EndLine, | |||
| "Content": result.Content, | |||
| "Lines": result.Lines, | |||
| "CanLogDownload": isCanDownloadLog(ctx, job), | |||
| }) | |||
| } | |||
| } | |||
| //result := "" | |||
| //ctx.JSON(http.StatusOK, result) | |||
| } | |||
| func isCanDownloadLog(ctx *context.APIContext, job *models.Cloudbrain) bool { | |||
| if !ctx.IsSigned { | |||
| return false | |||
| } | |||
| return ctx.IsUserSiteAdmin() || ctx.User.ID == job.UserID | |||
| } | |||
| func ModelSafetyDownloadLogFile(ctx *context.Context) { | |||
| ID := ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"]) | |||
| ctx.ServerError(err.Error(), err) | |||
| return | |||
| } | |||
| if job.JobType == string(models.JobTypeModelSafety) { | |||
| if job.Type == models.TypeCloudBrainOne { | |||
| CloudbrainDownloadLogFile(ctx) | |||
| } else if job.Type == models.TypeCloudBrainTwo { | |||
| ctx.SetParams("jobid", job.JobID) | |||
| ctx.Req.Form.Set("version_name", job.VersionName) | |||
| routerRepo.TrainJobDownloadLogFile(ctx) | |||
| } | |||
| } | |||
| } | |||
| func CloudbrainDownloadLogFile(ctx *context.Context) { | |||
| ID := ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| @@ -378,13 +482,18 @@ func CloudbrainDownloadLogFile(ctx *context.Context) { | |||
| ctx.ServerError(err.Error(), err) | |||
| return | |||
| } | |||
| if job.JobType == string(models.JobTypeModelSafety) { | |||
| if job.Type == models.TypeCloudBrainTwo { | |||
| ModelSafetyDownloadLogFile(ctx) | |||
| return | |||
| } | |||
| } | |||
| logDir := "/model" | |||
| if job.JobType == string(models.JobTypeInference) { | |||
| if job.JobType == string(models.JobTypeInference) || job.JobType == string(models.JobTypeModelSafety) { | |||
| logDir = cloudbrain.ResultPath | |||
| } | |||
| prefix := "/" + setting.CBCodePathPrefix + job.JobName + logDir | |||
| files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | |||
| files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, setting.CBCodePathPrefix+job.JobName+logDir, "") | |||
| if err != nil { | |||
| log.Error("query cloudbrain model failed: %v", err) | |||
| return | |||
| @@ -397,17 +506,22 @@ func CloudbrainDownloadLogFile(ctx *context.Context) { | |||
| } | |||
| } | |||
| if fileName != "" { | |||
| prefix := "/" + setting.CBCodePathPrefix + job.JobName + logDir | |||
| url, err := storage.Attachments.PresignedGetURL(prefix+"/"+fileName, fileName) | |||
| if err != nil { | |||
| log.Error("Get minio get SignedUrl failed: %v", err.Error(), ctx.Data["msgID"]) | |||
| ctx.ServerError("Get minio get SignedUrl failed", err) | |||
| return | |||
| } | |||
| log.Info("fileName=" + fileName) | |||
| http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect) | |||
| } else { | |||
| log.Info("fileName is null.") | |||
| } | |||
| } | |||
| func CloudbrainGetLog(ctx *context.Context) { | |||
| func CloudbrainGetLog(ctx *context.APIContext) { | |||
| ID := ctx.Params(":id") | |||
| job, err := models.GetCloudbrainByID(ID) | |||
| if err != nil { | |||
| @@ -415,12 +529,31 @@ func CloudbrainGetLog(ctx *context.Context) { | |||
| ctx.ServerError(err.Error(), err) | |||
| return | |||
| } | |||
| if job.JobType == string(models.JobTypeModelSafety) { | |||
| if job.Type == models.TypeCloudBrainOne { | |||
| result, err := cloudbrain.GetJob(job.JobID) | |||
| existStr := "" | |||
| if err == nil && result != nil { | |||
| jobRes, _ := models.ConvertToJobResultPayload(result.Payload) | |||
| taskRoles := jobRes.TaskRoles | |||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
| existStr = taskRes.TaskStatuses[0].ExitDiagnostics | |||
| } | |||
| ctx.Data["existStr"] = existStr | |||
| log.Info("existStr=" + existStr) | |||
| } else { | |||
| ModelSafetyGetLog(ctx) | |||
| return | |||
| } | |||
| } | |||
| lines := ctx.QueryInt("lines") | |||
| baseLine := ctx.Query("base_line") | |||
| order := ctx.Query("order") | |||
| var result map[string]interface{} | |||
| resultPath := "/model" | |||
| if job.JobType == string(models.JobTypeInference) { | |||
| if job.JobType == string(models.JobTypeInference) || job.JobType == string(models.JobTypeModelSafety) { | |||
| resultPath = "/result" | |||
| } | |||
| if baseLine == "" && order == "desc" { | |||
| @@ -447,12 +580,19 @@ func CloudbrainGetLog(ctx *context.Context) { | |||
| return | |||
| } | |||
| } | |||
| content := "" | |||
| if result["Content"] != nil { | |||
| content = result["Content"].(string) | |||
| } | |||
| if ctx.Data["existStr"] != nil && result["Lines"].(int) < 50 { | |||
| content = content + ctx.Data["existStr"].(string) | |||
| } | |||
| re := map[string]interface{}{ | |||
| "JobID": ID, | |||
| "LogFileName": result["FileName"], | |||
| "StartLine": result["StartLine"], | |||
| "EndLine": result["EndLine"], | |||
| "Content": result["Content"], | |||
| "Content": content, | |||
| "Lines": result["Lines"], | |||
| "CanLogDownload": result["FileName"] != "", | |||
| } | |||
| @@ -485,7 +625,7 @@ func getAllLineFromFile(path string) int { | |||
| } | |||
| func getLastLogFromModelDir(jobName string, lines int, resultPath string) map[string]interface{} { | |||
| prefix := "/" + setting.CBCodePathPrefix + jobName + resultPath | |||
| prefix := setting.CBCodePathPrefix + jobName + resultPath | |||
| files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | |||
| if err != nil { | |||
| log.Error("query cloudbrain model failed: %v", err) | |||
| @@ -546,7 +686,7 @@ func getLastLogFromModelDir(jobName string, lines int, resultPath string) map[st | |||
| } | |||
| func getLogFromModelDir(jobName string, startLine int, endLine int, resultPath string) map[string]interface{} { | |||
| prefix := "/" + setting.CBCodePathPrefix + jobName + resultPath | |||
| prefix := setting.CBCodePathPrefix + jobName + resultPath | |||
| files, err := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, "") | |||
| if err != nil { | |||
| log.Error("query cloudbrain model failed: %v", err) | |||
| @@ -578,6 +718,11 @@ func getLogFromModelDir(jobName string, startLine int, endLine int, resultPath s | |||
| for i := 0; i < endLine; i++ { | |||
| line, error := r.ReadString('\n') | |||
| if error == io.EOF { | |||
| if i >= startLine { | |||
| fileEndLine = i | |||
| re = re + line | |||
| count++ | |||
| } | |||
| log.Info("read file completed.") | |||
| break | |||
| } | |||
| @@ -626,7 +626,7 @@ func GetAllCloudbrainsPeriodDistribution(ctx *context.Context) { | |||
| } | |||
| jobTypeList := []string{string(models.JobTypeDebug), string(models.JobTypeTrain), string(models.JobTypeInference), string(models.JobTypeBenchmark), | |||
| string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)} | |||
| string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)} | |||
| for _, v := range jobTypeList { | |||
| if _, ok := cloudOneJobTypeRes[v]; !ok { | |||
| cloudOneJobTypeRes[v] = 0 | |||
| @@ -709,7 +709,7 @@ func GetCloudbrainsDetailData(ctx *context.Context) { | |||
| var jobTypes []string | |||
| jobTypeNot := false | |||
| if jobType == string(models.JobTypeBenchmark) { | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| } else if jobType != "all" && jobType != "" { | |||
| jobTypes = append(jobTypes, jobType) | |||
| } | |||
| @@ -0,0 +1,78 @@ | |||
| package modelapp | |||
| import ( | |||
| "bytes" | |||
| "code.gitea.io/gitea/models" | |||
| "crypto/tls" | |||
| "image" | |||
| "image/png" | |||
| "net/http" | |||
| "strconv" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| "code.gitea.io/gitea/modules/base" | |||
| "code.gitea.io/gitea/modules/context" | |||
| "github.com/go-resty/resty/v2" | |||
| ) | |||
| var restyClient *resty.Client | |||
| var tplExploreUpload base.TplName = "model/tuomin/upload" | |||
| var uploadUrl = "/extension/tuomin/upload" | |||
| var allowedContentType = []string{"image/jpeg", "image/jpg", "image/png"} | |||
| func ProcessImageUI(ctx *context.Context) { | |||
| ctx.HTML(200, tplExploreUpload) | |||
| } | |||
| func ProcessImage(ctx *context.Context) { | |||
| file, header, err := ctx.GetFile("file") | |||
| if err != nil { | |||
| ctx.JSON(http.StatusBadRequest,models.BaseErrorMessage(ctx.Tr("model_app.get_file_fail"))) | |||
| return | |||
| } | |||
| defer file.Close() | |||
| contentType := header.Header.Get("Content-Type") | |||
| if !isInAllowedContentType(contentType) { | |||
| ctx.JSON(http.StatusBadRequest,models.BaseErrorMessage(ctx.Tr("model_app.content_type_unsupported"))) | |||
| return | |||
| } | |||
| client := getRestyClient() | |||
| res, err := client.R().SetMultipartField( | |||
| "file", header.Filename, contentType, file).Post(setting.ModelApp.DesensitizationUrl + "?mode=" + strconv.Itoa(ctx.QueryInt("mode"))) | |||
| if err != nil { | |||
| ctx.JSON(http.StatusBadRequest,models.BaseErrorMessage(ctx.Tr("model_app.process_image_fail"))) | |||
| return | |||
| } | |||
| image, _, err := image.Decode(bytes.NewReader(res.Body())) | |||
| if err != nil { | |||
| ctx.JSON(http.StatusBadRequest,models.BaseErrorMessage(ctx.Tr("model_app.process_image_fail"))) | |||
| return | |||
| } | |||
| png.Encode(ctx.Resp, image) | |||
| return | |||
| } | |||
| func isInAllowedContentType(contentType string) bool { | |||
| for _, allowType := range allowedContentType { | |||
| if allowType == contentType { | |||
| return true | |||
| } | |||
| } | |||
| return false | |||
| } | |||
| func getRestyClient() *resty.Client { | |||
| if restyClient == nil { | |||
| restyClient = resty.New() | |||
| restyClient.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) | |||
| } | |||
| return restyClient | |||
| } | |||
| @@ -51,6 +51,9 @@ const ( | |||
| tplCloudBrainBenchmarkNew base.TplName = "repo/cloudbrain/benchmark/new" | |||
| tplCloudBrainBenchmarkShow base.TplName = "repo/cloudbrain/benchmark/show" | |||
| tplCloudBrainModelSafetyNewGpu base.TplName = "repo/modelsafety/newgpu" | |||
| tplCloudBrainModelSafetyNewNpu base.TplName = "repo/modelsafety/newnpu" | |||
| tplCloudBrainImageSubmit base.TplName = "repo/cloudbrain/image/submit" | |||
| tplCloudBrainImageEdit base.TplName = "repo/cloudbrain/image/edit" | |||
| @@ -140,8 +143,11 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
| ctx.Data["is_brainscore_enabled"] = setting.IsBrainScoreEnabled | |||
| ctx.Data["datasetType"] = models.TypeCloudBrainOne | |||
| ctx.Data["benchmarkMode"] = ctx.Query("benchmarkMode") | |||
| defaultMode := ctx.Query("benchmarkMode") | |||
| if defaultMode == "" { | |||
| defaultMode = "alogrithm" | |||
| } | |||
| ctx.Data["benchmarkMode"] = defaultMode | |||
| if ctx.Cloudbrain != nil { | |||
| ctx.Data["branch_name"] = ctx.Cloudbrain.BranchName | |||
| @@ -734,7 +740,10 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
| } else { | |||
| task, err = models.GetCloudbrainByIDWithDeleted(ctx.Params(":id")) | |||
| } | |||
| if task.JobType == string(models.JobTypeModelSafety) { | |||
| GetAiSafetyTaskTmpl(ctx) | |||
| return | |||
| } | |||
| if err != nil { | |||
| log.Info("error:" + err.Error()) | |||
| ctx.NotFound(ctx.Req.URL.RequestURI(), nil) | |||
| @@ -1827,6 +1836,9 @@ func SyncCloudbrainStatus() { | |||
| } | |||
| for _, task := range cloudBrains { | |||
| if task.JobType == string(models.JobTypeModelSafety) { | |||
| continue | |||
| } | |||
| if task.Type == models.TypeCloudBrainOne { | |||
| result, err := cloudbrain.GetJob(task.JobID) | |||
| if err != nil { | |||
| @@ -2112,14 +2124,14 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) { | |||
| } | |||
| var jobTypes []string | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeModelSafety)) | |||
| ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||
| ListOptions: models.ListOptions{ | |||
| Page: page, | |||
| PageSize: setting.UI.IssuePagingNum, | |||
| }, | |||
| RepoID: repo.ID, | |||
| Type: models.TypeCloudBrainOne, | |||
| Type: -1, | |||
| JobTypes: jobTypes, | |||
| }) | |||
| if err != nil { | |||
| @@ -2166,6 +2178,10 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) { | |||
| } | |||
| } | |||
| } | |||
| if task.JobType == string(models.JobTypeModelSafety) { | |||
| ciTasks[i].BenchmarkType = "安全评测" | |||
| ciTasks[i].BenchmarkTypeName = "Image Classification" | |||
| } | |||
| } | |||
| pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5) | |||
| @@ -713,6 +713,7 @@ func grampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain | |||
| DatasetNames: datasetNames, | |||
| DatasetInfos: datasetInfos, | |||
| Spec: spec, | |||
| CodeName: strings.ToLower(repo.Name), | |||
| } | |||
| if form.ModelName != "" { //使用预训练模型训练 | |||
| req.ModelName = form.ModelName | |||
| @@ -977,8 +978,7 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||
| command += "pwd;cd " + workDir + fmt.Sprintf(grampus.CommandPrepareScript, setting.Grampus.SyncScriptProject, setting.Grampus.SyncScriptProject) | |||
| //download code & dataset | |||
| if processorType == grampus.ProcessorTypeNPU { | |||
| commandDownload := "./downloader_for_obs " + setting.Bucket + " " + codeRemotePath + " " + grampus.CodeArchiveName + ";" | |||
| command += commandDownload | |||
| //no need to download code & dataset by internet | |||
| } else if processorType == grampus.ProcessorTypeGPU { | |||
| commandDownload := "./downloader_for_minio " + setting.Grampus.Env + " " + codeRemotePath + " " + grampus.CodeArchiveName + " '" + dataRemotePath + "' '" + datasetName + "'" | |||
| commandDownload = processPretrainModelParameter(pretrainModelPath, pretrainModelFileName, commandDownload) | |||
| @@ -987,8 +987,7 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||
| //unzip code & dataset | |||
| if processorType == grampus.ProcessorTypeNPU { | |||
| commandUnzip := "cd " + workDir + "code;unzip -q master.zip;" | |||
| command += commandUnzip | |||
| //no need to process | |||
| } else if processorType == grampus.ProcessorTypeGPU { | |||
| unZipDatasetCommand := generateDatasetUnzipCommand(datasetName) | |||
| commandUnzip := "cd " + workDir + "code;unzip -q master.zip;echo \"start to unzip dataset\";cd " + workDir + "dataset;" + unZipDatasetCommand | |||
| @@ -1025,7 +1024,7 @@ func generateCommand(repoName, processorType, codeRemotePath, dataRemotePath, bo | |||
| var commandCode string | |||
| if processorType == grampus.ProcessorTypeNPU { | |||
| commandCode = "/bin/bash /home/work/run_train_for_openi.sh " + workDir + "code/" + strings.ToLower(repoName) + "/" + bootFile + " /tmp/log/train.log" + paramCode + ";" | |||
| commandCode = "/bin/bash /home/work/run_train_for_openi.sh /home/work/openi.py /tmp/log/train.log" + paramCode + ";" | |||
| } else if processorType == grampus.ProcessorTypeGPU { | |||
| if pretrainModelFileName != "" { | |||
| paramCode += " --ckpt_url" + "=" + workDir + "pretrainmodel/" + pretrainModelFileName | |||
| @@ -2200,6 +2200,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
| ResultUrl: resultObsPath, | |||
| Spec: spec, | |||
| DatasetName: datasetNames, | |||
| JobType: string(models.JobTypeInference), | |||
| } | |||
| err = modelarts.GenerateInferenceJob(ctx, req) | |||
| @@ -2737,7 +2738,7 @@ func TrainJobDownloadLogFile(ctx *context.Context) { | |||
| return | |||
| } | |||
| ctx.Resp.Header().Set("Cache-Control", "max-age=0") | |||
| http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently) | |||
| http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect) | |||
| } | |||
| func getDatasUrlListByUUIDS(uuidStr string) ([]models.Datasurl, string, string, bool, error) { | |||
| var isMultiDataset bool | |||
| @@ -17,6 +17,8 @@ import ( | |||
| "text/template" | |||
| "time" | |||
| "code.gitea.io/gitea/routers/modelapp" | |||
| "code.gitea.io/gitea/modules/slideimage" | |||
| "code.gitea.io/gitea/routers/image" | |||
| @@ -356,6 +358,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Post("/user/login/kanban", user.SignInPostAPI) | |||
| m.Get("/home/term", routers.HomeTerm) | |||
| m.Get("/home/privacy", routers.HomePrivacy) | |||
| m.Get("/extension/tuomin/upload", modelapp.ProcessImageUI) | |||
| m.Post("/extension/tuomin/upload", reqSignIn, modelapp.ProcessImage) | |||
| m.Group("/explore", func() { | |||
| m.Get("", func(ctx *context.Context) { | |||
| ctx.Redirect(setting.AppSubURL + "/explore/repos") | |||
| @@ -671,6 +675,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Group("/task/config", func() { | |||
| m.Get("/list", task.GetTaskConfigList) | |||
| m.Post("/add/batch", bindIgnErr(models.BatchLimitConfigVO{}), task.BatchAddTaskConfig) | |||
| m.Post("/^:action(new|edit|del)$", bindIgnErr(models.TaskConfigWithLimit{}), task.OperateTaskConfig) | |||
| }) | |||
| @@ -1226,7 +1231,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| }, context.RepoRef()) | |||
| m.Group("/modelmanage", func() { | |||
| m.Post("/create_model", repo.SaveModel) | |||
| m.Post("/create_model_convert", reqRepoModelManageWriter, repo.SaveModelConvert) | |||
| m.Post("/create_model_convert", reqWechatBind, reqRepoModelManageWriter, repo.SaveModelConvert) | |||
| m.Post("/create_new_model", repo.SaveNewNameModel) | |||
| m.Delete("/delete_model", repo.DeleteModel) | |||
| m.Post("/delete_model_convert/:id", repo.DeleteModelConvert) | |||
| @@ -1253,6 +1258,18 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/downloadall", repo.DownloadMultiModelFile) | |||
| }, context.RepoRef()) | |||
| m.Group("/modelsafety", func() { | |||
| m.Group("/:id", func() { | |||
| m.Get("/show", reqRepoCloudBrainWriter, repo.GetAiSafetyTaskTmpl) | |||
| m.Get("", reqRepoCloudBrainWriter, repo.GetAiSafetyTask) | |||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.StopAiSafetyTask) | |||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.DelAiSafetyTask) | |||
| }) | |||
| m.Get("/create_gpu", reqWechatBind, reqRepoCloudBrainWriter, context.PointAccount(), repo.AiSafetyCreateForGetGPU) | |||
| m.Get("/create_npu", reqWechatBind, reqRepoCloudBrainWriter, context.PointAccount(), repo.AiSafetyCreateForGetNPU) | |||
| m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.AiSafetyCreateForPost) | |||
| }, context.RepoRef()) | |||
| m.Group("/debugjob", func() { | |||
| m.Get("", reqRepoCloudBrainReader, repo.DebugJobIndex) | |||
| }, context.RepoRef()) | |||
| @@ -777,7 +777,7 @@ func Cloudbrains(ctx *context.Context) { | |||
| var jobTypes []string | |||
| jobTypeNot := false | |||
| if jobType == string(models.JobTypeBenchmark) { | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| } else if jobType != "all" && jobType != "" { | |||
| jobTypes = append(jobTypes, jobType) | |||
| } | |||
| @@ -110,13 +110,6 @@ | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "MODELSAFETY"}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelsafety/{{$JobID}}/show" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}" | |||
| @@ -131,7 +124,7 @@ | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| {{else if eq .JobType "BENCHMARK" "MODELSAFETY"}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||
| @@ -148,7 +141,7 @@ | |||
| <div class="two wide column text center nowrap" | |||
| style="width: 6% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" | |||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | |||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK" "MODELSAFETY"}}/cloudbrain{{end}}' | |||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | |||
| class="{{.Status}}"></i><span id="{{$JobID}}-text" | |||
| @@ -42,6 +42,7 @@ | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BENCHMARK&listType={{$.ListType}}&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="BENCHMARK">BENCHMARK</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=SNN4IMAGENET&listType={{$.ListType}}&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="SNN4IMAGENET">SNN4IMAGENET</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BRAINSCORE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="BRAINSCORE">BRAINSCORE</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=MODELSAFETY&listType={{$.ListType}}&jobStatus={{$.JobStatus}}&cluster={{$.cluster}}&aiCenter={{$.aiCenter}}" data-value="MODELSAFETY">MODELSAFETY</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| @@ -32,9 +32,15 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a> | |||
| <div class="ui simple dropdown item" > | |||
| {{.i18n.Tr "repo.model_manager"}} | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{AppSubUrl}}/extension/tuomin/upload">模型体验</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui simple dropdown item" id='dropdown_explore'> | |||
| {{.i18n.Tr "explore"}} | |||
| <i class="dropdown icon"></i> | |||
| @@ -68,6 +74,14 @@ | |||
| <a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a> | |||
| <div class="ui simple dropdown item" > | |||
| {{.i18n.Tr "repo.model_manager"}} | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{AppSubUrl}}/extension/tuomin/upload">模型体验</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui simple dropdown item" id='dropdown_PageHome'> | |||
| {{.i18n.Tr "explore"}} | |||
| <i class="dropdown icon"></i> | |||
| @@ -34,6 +34,13 @@ | |||
| </div> | |||
| <a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a> | |||
| <div class="ui simple dropdown item" > | |||
| {{.i18n.Tr "repo.model_manager"}} | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{AppSubUrl}}/extension/tuomin/upload">模型体验</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui dropdown item" id='dropdown_explore'> | |||
| {{.i18n.Tr "explore"}} | |||
| <i class="dropdown icon"></i> | |||
| @@ -66,6 +73,13 @@ | |||
| </div> | |||
| <a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a> | |||
| <div class="ui simple dropdown item" > | |||
| {{.i18n.Tr "repo.model_manager"}} | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{AppSubUrl}}/extension/tuomin/upload">模型体验</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui dropdown item" id='dropdown_PageHome'> | |||
| {{.i18n.Tr "explore"}} | |||
| <i class="dropdown icon"></i> | |||
| @@ -26,6 +26,13 @@ | |||
| </div> | |||
| <a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a> | |||
| <div class="ui simple dropdown item" > | |||
| {{.i18n.Tr "repo.model_manager"}} | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{AppSubUrl}}/extension/tuomin/upload">模型体验</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui dropdown item" id='dropdown_explore'> | |||
| {{.i18n.Tr "explore"}} | |||
| <i class="dropdown icon"></i> | |||
| @@ -59,6 +66,13 @@ | |||
| <a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a> | |||
| <div class="ui simple dropdown item" > | |||
| {{.i18n.Tr "repo.model_manager"}} | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{AppSubUrl}}/extension/tuomin/upload">模型体验</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui dropdown item" id='dropdown_PageHome'> | |||
| {{.i18n.Tr "explore"}} | |||
| <i class="dropdown icon"></i> | |||
| @@ -36,6 +36,13 @@ | |||
| <a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a> | |||
| <div class="ui simple dropdown item" > | |||
| {{.i18n.Tr "repo.model_manager"}} | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{AppSubUrl}}/extension/tuomin/upload">模型体验</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui dropdown item" id='dropdown_explore'> | |||
| {{.i18n.Tr "explore"}} | |||
| <i class="dropdown icon"></i> | |||
| @@ -69,6 +76,13 @@ | |||
| <a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a> | |||
| <a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a> | |||
| <div class="ui simple dropdown item" > | |||
| {{.i18n.Tr "repo.model_manager"}} | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{AppSubUrl}}/extension/tuomin/upload">模型体验</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui dropdown item" id='dropdown_PageHome'> | |||
| {{.i18n.Tr "explore"}} | |||
| <i class="dropdown icon"></i> | |||
| @@ -0,0 +1,13 @@ | |||
| {{template "base/head" .}} | |||
| <link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-model-tuomin.css?v={{MD5 AppVer}}" /> | |||
| <div> | |||
| {{if .Flash}} | |||
| <div class="sixteen wide column"> | |||
| {{template "base/alert" .}} | |||
| </div> | |||
| {{end}} | |||
| <div id="isSignd" data-sign="{{$.IsSigned}}" style="display: none;"></div> | |||
| <div id="__vue-root"></div> | |||
| </div> | |||
| <script src="{{StaticUrlPrefix}}/js/vp-model-tuomin.js?v={{MD5 AppVer}}"></script> | |||
| {{template "base/footer" .}} | |||
| @@ -1,80 +0,0 @@ | |||
| {{template "base/head" .}} | |||
| <div class="organization members"> | |||
| {{template "org/header" .}} | |||
| <div class="ui container"> | |||
| {{template "base/alert" .}} | |||
| {{template "org/navber" .}} | |||
| <div class="ui stackable grid"> | |||
| <div class="ui sixteen wide computer column list"> | |||
| {{ range .Members}} | |||
| <div class="item ui grid"> | |||
| <div class="three wide mobile two wide tablet one wide computer column"> | |||
| <img class="ui avatar" src="{{.SizedRelAvatarLink 48}}"> | |||
| </div> | |||
| <div class="seven wide mobile three wide tablet three wide computer column"> | |||
| <div class="meta"><a href="{{.HomeLink}}">{{.Name}}</a></div> | |||
| <div class="meta">{{.FullName}}</div> | |||
| </div> | |||
| <div class="ui three wide tablet four wide computer column center tablet only computer only"> | |||
| <div class="meta"> | |||
| {{$.i18n.Tr "org.members.membership_visibility"}} | |||
| </div> | |||
| <div class="meta"> | |||
| {{ $isPublic := index $.MembersIsPublicMember .ID}} | |||
| {{if $isPublic}} | |||
| <strong>{{$.i18n.Tr "org.members.public"}}</strong> | |||
| {{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a class="link-action" href data-url="{{$.OrgLink}}/members/action/private?uid={{.ID}}">{{$.i18n.Tr "org.members.public_helper"}}</a>){{end}} | |||
| {{else}} | |||
| <strong>{{$.i18n.Tr "org.members.private"}}</strong> | |||
| {{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}(<a class="link-action" href data-url="{{$.OrgLink}}/members/action/public?uid={{.ID}}">{{$.i18n.Tr "org.members.private_helper"}}</a>){{end}} | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| <div class="five wide mobile three wide tablet three wide computer column"> | |||
| <div class="meta"> | |||
| {{$.i18n.Tr "org.members.member_role"}} | |||
| </div> | |||
| <div class="meta"> | |||
| <strong>{{if index $.MembersIsUserOrgOwner .ID}}{{svg "octicon-shield-lock" 16}} {{$.i18n.Tr "org.members.owner"}}{{else}}{{$.i18n.Tr "org.members.member"}}{{end}}</strong> | |||
| </div> | |||
| </div> | |||
| <div class="ui one wide column center tablet only computer only"> | |||
| <div class="meta"> | |||
| 2FA | |||
| </div> | |||
| <div class="meta"> | |||
| <strong> | |||
| {{if index $.MembersTwoFaStatus .ID}} | |||
| <span class="text green">{{svg "octicon-check" 16}}</span> | |||
| {{else}} | |||
| {{svg "octicon-x" 16}} | |||
| {{end}} | |||
| </strong> | |||
| </div> | |||
| </div> | |||
| <div class="ui three wide column tablet only computer only"> | |||
| <div class="text right"> | |||
| {{if eq $.SignedUser.ID .ID}} | |||
| <form method="post" action="{{$.OrgLink}}/members/action/leave"> | |||
| {{$.CsrfTokenHtml}} | |||
| <button type="submit" class="ui red small button" name="uid" value="{{.ID}}">{{$.i18n.Tr "org.members.leave"}}</button> | |||
| </form> | |||
| {{else if $.IsOrganizationOwner}} | |||
| <form method="post" action="{{$.OrgLink}}/members/action/remove"> | |||
| {{$.CsrfTokenHtml}} | |||
| <button type="submit" class="ui red small button" name="uid" value="{{.ID}}">{{$.i18n.Tr "org.members.remove"}}</button> | |||
| </form> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| {{template "base/paginate" .}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -99,7 +99,6 @@ | |||
| {{range .Tasks}} | |||
| <div class="ui grid stackable item"> | |||
| <div class="row"> | |||
| <!-- 任务名 --> | |||
| <div class="three wide column padding0" style="width: 18% !important;"> | |||
| <a class="title" href="{{$.Link}}/{{.Cloudbrain.ID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| @@ -108,18 +107,24 @@ | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| <span class="job-status" id="{{.Cloudbrain.ID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.Cloudbrain.ID}}" data-version="{{.VersionName}}"> | |||
| <span class="job-status" id="{{.Cloudbrain.ID}}" data-repopath="{{$.RepoRelPath}}{{if or (eq .JobType "MODELSAFETY") (eq .ComputeResource "CPU/GPU")}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.Cloudbrain.ID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| {{.BenchmarkType}} | |||
| {{.BenchmarkType}} | |||
| </div> | |||
| {{if eq .JobType "MODELSAFETY"}} | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| {{.BenchmarkTypeName}} | |||
| </div> | |||
| {{else}} | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| <a style="font-size: 12px;" href="{{.BenchmarkTypeRankLink}}" target="_blank"> | |||
| {{.BenchmarkTypeName}} | |||
| {{.BenchmarkTypeName}} | |||
| </a> | |||
| </div> | |||
| {{end}} | |||
| <!-- 任务创建时间 --> | |||
| <div class="two wide column text center padding0" style="width: 8.5% !important;"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | |||
| @@ -142,9 +147,36 @@ | |||
| </div> | |||
| <div class="three wide column text center padding0" style="width: 20% !important;"> | |||
| <div class="ui compact buttons" > | |||
| <!-- 停止任务 --> | |||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||
| <div class="ui compact buttons" > | |||
| {{if eq .JobType "MODELSAFETY"}} | |||
| <!-- 停止任务 --> | |||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}/modelsafety/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{else}} | |||
| <a class="ui basic disabled button">{{$.i18n.Tr "repo.stop"}}</a> | |||
| {{end}} | |||
| </form> | |||
| <!-- 删除任务 --> | |||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{$.RepoLink}}/modelsafety/{{.Cloudbrain.ID}}/del" method="post"> | |||
| <input type="hidden" name="debugListType" value="all"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-delete-{{.Cloudbrain.ID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "SUCCEEDED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{else}} | |||
| <a class="ui basic button disabled" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| {{else}} | |||
| <!-- 停止任务 --> | |||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | |||
| @@ -162,8 +194,8 @@ | |||
| {{$.i18n.Tr "repo.score"}} | |||
| </a> | |||
| {{end}} | |||
| <!-- 删除任务 --> | |||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | |||
| <!-- 删除任务 --> | |||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | |||
| <input type="hidden" name="debugListType" value="all"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| @@ -175,7 +207,8 @@ | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| </form> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -50,6 +50,8 @@ | |||
| href="{{.Link}}?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a> | |||
| <a class="active item model_benchmark" | |||
| href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
| <a class="item aisafety_benchmark" | |||
| href="{{.RepoLink}}/modelsafety/create_gpu">模型安全评测</a> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| @@ -153,7 +155,7 @@ | |||
| </div> | |||
| </div> | |||
| </form> | |||
| {{else}} | |||
| {{else if eq .benchmarkMode "alogrithm"}} | |||
| <form id="form_id" class="ui form alogrithm_form" action="{{.Link}}?benchmarkMode=alogrithm" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <input type="hidden" name="action" value="update"> | |||
| @@ -165,6 +167,8 @@ | |||
| href="{{.Link}}?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a> | |||
| <a class="item model_benchmark" | |||
| href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
| <a class="item aisafety_benchmark" | |||
| href="{{.RepoLink}}/modelsafety/create_gpu">模型安全评测</a> | |||
| </div> | |||
| </div> | |||
| @@ -281,6 +285,76 @@ | |||
| </div> | |||
| </div> | |||
| </form> | |||
| {{else if eq .benchmarkMode "aisafety"}} | |||
| <form id="form_id" class="ui form alogrithm_form" action="{{.Link}}?benchmarkMode=alogrithm" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <input type="hidden" name="action" value="update"> | |||
| <input type="hidden" name="job_type" value="BENCHMARK"> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| <a class="item alogrithm_benchmark" | |||
| href="{{.Link}}?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a> | |||
| <a class="item model_benchmark" | |||
| href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
| <a class="active item aisafety_benchmark" | |||
| href="{{.RepoLink}}/modelsafety/create_gpu">模型安全评测</a> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | |||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | |||
| tabindex="3" autofocus required maxlength="36"> | |||
| <span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||
| </div> | |||
| <div class="min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;" | |||
| for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="254" | |||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} | |||
| onchange="this.value=this.value.substring(0, 255)" | |||
| onkeydown="this.value=this.value.substring(0, 255)" | |||
| onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
| </div> | |||
| <div id="images-new-cb"> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="__specs__" class="ui search dropdown width48" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}" | |||
| name="spec_id"> | |||
| </select> | |||
| </div> | |||
| <div class="inline min_title field required"> | |||
| <label class="label-fix-width" style="font-weight: normal;">推理程序</label> | |||
| <input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py" | |||
| tabindex="3" autofocus required maxlength="254"> | |||
| <a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" | |||
| target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
| </div> | |||
| <div class="inline unite min_title field"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| <button class="ui create_train_job green button"> | |||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||
| </button> | |||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| @@ -253,7 +253,7 @@ | |||
| <div style="float: right;"> | |||
| {{if and ($.canDownload) (ne .Status "WAITING") ($.Permission.CanWrite $.UnitTypeModelManage) }} | |||
| <a class="ti-action-menu-item" id="{{.VersionName}}-create-model" | |||
| onclick="showcreate({DisplayJobName:{{.DisplayJobName}},JobName:{{.JobName}},JobID:{{.JobID}},VersionName:{{.VersionName}})">{{$.i18n.Tr "repo.modelarts.create_model"}}</a> | |||
| onclick="showcreate({DisplayJobName:{{.DisplayJobName}},JobName:{{.JobName}},JobID:{{.JobID}},VersionName:{{.VersionName}}})">{{$.i18n.Tr "repo.modelarts.create_model"}}</a> | |||
| {{else}} | |||
| <a class="ti-action-menu-item disabled" id="{{.VersionName}}-create-model">{{$.i18n.Tr "repo.modelarts.create_model"}}</a> | |||
| {{end}} | |||
| @@ -207,6 +207,18 @@ | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem; | |||
| } | |||
| .dataset_nowrap_two_line{ | |||
| word-wrap: break-word; | |||
| word-break: break-all; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| display: -webkit-box; | |||
| -webkit-box-orient: vertical; | |||
| line-clamp: 2; | |||
| -webkit-line-clamp: 2; | |||
| text-overflow: -o-ellipsis-lastline; | |||
| max-height: 50px; | |||
| } | |||
| </style> | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| @@ -437,15 +449,14 @@ | |||
| <tbody> | |||
| {{range $.datasetDownload}} | |||
| <tr> | |||
| <td style="word-wrap: break-word;word-break: break-all;"> | |||
| <td class="dataset_nowrap_two_line"> | |||
| {{if eq .IsDelete true}} | |||
| {{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}}) | |||
| {{else}} | |||
| <a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a> | |||
| {{end}} | |||
| </td> | |||
| <td style="word-wrap: break-word;word-break: break-all;">{{.DatasetDownloadLink}}</td> | |||
| <td><div class="dataset_nowrap_two_line">{{.DatasetDownloadLink}}</div></td> | |||
| <td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn-dataset" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{.DatasetDownloadLink}}">{{$.i18n.Tr "dataset.download_copy"}}</a></td> | |||
| </tr> | |||
| {{end}} | |||
| @@ -261,29 +261,25 @@ | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | |||
| <div class="ui labeled input" style="width: 5%;"> | |||
| <input style="border-radius: 0;text-align: center;" type="hidden" name="work_server_number" | |||
| id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" | |||
| readonly> | |||
| <div class="field" id="trainjob_work_server_num_select" name="work_server_number_select"> | |||
| <select class="ui dropdown width" style='width: 100%;' name="work_server_id"> | |||
| {{if .WorkNode}} | |||
| {{range .WorkNode}} | |||
| <select class="ui dropdown width" style='width: 100%;' name="work_server_number"> | |||
| {{if .WorkNode}} | |||
| {{range .WorkNode}} | |||
| {{if $.work_server_number}} | |||
| {{if eq . $.work_server_number }} | |||
| <option name="server_id" selected value="{{.}}">{{.}}</option> | |||
| {{else}} | |||
| <option name="server_id" value="{{.}}">{{.}}</option> | |||
| {{end}} | |||
| {{else}} | |||
| <option name="server_id" value="{{.}}">{{.}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| {{if $.work_server_number}} | |||
| {{if eq . $.work_server_number }} | |||
| <option name="server_id" selected value="{{.}}">{{.}}</option> | |||
| {{else}} | |||
| <option name="server_id" value="{{.}}">{{.}}</option> | |||
| {{end}} | |||
| {{else}} | |||
| <option name="server_id" value="{{.}}">{{.}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| {{else}} | |||
| <option name="server_id" value="1">1</option> | |||
| {{end}} | |||
| {{else}} | |||
| <option name="server_id" value="1">1</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| @@ -892,11 +892,11 @@ | |||
| $('#JobName').val(obj.DisplayJobName).addClass('model_disabled') | |||
| $('input[name="JobId"]').val(obj.JobID) | |||
| $('input[name="VersionName"]').val(obj.VersionName).addClass('model_disabled') | |||
| if(obj.EngineID ==122 || obj.EngineID ==35 || obj.EngineID ==-1){ | |||
| if(obj.EngineID ==122 || obj.EngineID ==35 || obj.EngineID ==-1 || obj.EngineID ==37){ | |||
| $('input[name="Engine_name"]').val("MindSpore").addClass('model_disabled'); | |||
| $('input[name="Engine"]').val(2); | |||
| } | |||
| if(obj.EngineID ==121){ | |||
| if(obj.EngineID ==121 || obj.EngineID ==38){ | |||
| $('input[name="Engine_name"]').val("TensorFlow").addClass('model_disabled'); | |||
| $('input[name="Engine"]').val(1); | |||
| } | |||
| @@ -581,10 +581,10 @@ | |||
| if(versionList[0].Engine == engineOption){ | |||
| return "selected=\"selected\""; | |||
| }else{ | |||
| if(versionList[0].Engine==122 && engineOption==2){ | |||
| if((versionList[0].Engine==122 || versionList[0].Engine==37) && engineOption==2){ | |||
| return "selected=\"selected\""; | |||
| } | |||
| if(versionList[0].Engine==121 && engineOption==1){ | |||
| if((versionList[0].Engine==121 || versionList[0].Engine==38) && engineOption==1){ | |||
| return "selected=\"selected\""; | |||
| } | |||
| } | |||
| @@ -244,9 +244,9 @@ function loadInfo(){ | |||
| function getEngineName(model){ | |||
| if(model.Engine == 0){ | |||
| return "PyTorch"; | |||
| }else if(model.Engine == 1 || model.Engine == 121){ | |||
| }else if(model.Engine == 1 || model.Engine == 121 || model.Engine == 38){ | |||
| return "TensorFlow"; | |||
| }else if(model.Engine == 2 || model.Engine == 122 || model.Engine == 35){ | |||
| }else if(model.Engine == 2 || model.Engine == 122 || model.Engine == 35 || model.Engine == 37){ | |||
| return "MindSpore"; | |||
| }else if(model.Engine == 3){ | |||
| return "Other"; | |||
| @@ -0,0 +1,63 @@ | |||
| <span> | |||
| <i class="question circle icon indicators_descr" style="cursor:pointer;"></i> | |||
| <div class="ui flowing popup bottom left transition hidden" style="inset: 564px auto auto 1px; width: 920px"> | |||
| <table class="ui celled table"> | |||
| <thead> | |||
| <tr> | |||
| <th style="width:80px;">指标</th> | |||
| <th>说明</th> | |||
| </tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr> | |||
| <td data-label="指标">ACC</td> | |||
| <td data-label="说明" indicator="ACC">Accuracy:精确度,计算模型预测准确率,该指标越高,说明评测结果越好。</td> | |||
| </tr> | |||
| <!-- <tr> | |||
| <td data-label="指标">CAV</td> | |||
| <td data-label="说明" indicator="CAV">Classification Accuracy Variance:用于评估深度学习模型性能的最重要指标为准确性。该指标值越高,说明评测结果越好。</td> | |||
| </tr> --> | |||
| <tr> | |||
| <td data-label="指标">ASS</td> | |||
| <td data-label="说明" indicator="ASS">Average Structural Similarity:所有攻击成功对抗样本与其原始样本间的平均相似性。该指标越大,说明评测结果越好。</td> | |||
| </tr> | |||
| <tr> | |||
| <td data-label="指标">ALDp</td> | |||
| <td data-label="说明" indicator="ALDp">Average LpDistortion:为所有攻击成功的对抗样本的平均归一化Lp失真度,ALDp值越小,对抗样本的不可感知性越强。</td> | |||
| </tr> | |||
| <tr> | |||
| <td data-label="指标">ACAC</td> | |||
| <td data-label="说明" indicator="ACAC">Average Confidence of Adversarial Class(ACAC):这个数值越高,攻击算法的攻击能力越强。</td> | |||
| </tr> | |||
| <!-- <tr> | |||
| <td data-label="指标">ACTC</td> | |||
| <td data-label="说明" indicator="ACTC">Average Confidence of True Class(ACTC):这个数值越低,攻击算法的攻击能力越强。</td> | |||
| </tr> --> | |||
| <tr> | |||
| <td data-label="指标">PSD</td> | |||
| <td data-label="说明" indicator="PSD">Perturbation Sensitivity Distance:用于评测人类对扰动的感知能力。该指标值越大,说明评测结果越差。</td> | |||
| </tr> | |||
| <!-- <tr> | |||
| <td data-label="指标">CACC</td> | |||
| <td data-label="说明" indicator="CACC">Clean ACC:该值计算的是原始未被攻击的样本,使用模型和groundtruth相比较的模型的本身的一个。</td> | |||
| </tr> --> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </span> | |||
| <script> | |||
| ;(function() { | |||
| setTimeout(function(){ | |||
| $('.indicators_descr').popup({ | |||
| inline: true, | |||
| hoverable: true, | |||
| position: 'top center', | |||
| delay: { | |||
| show: 300, | |||
| hide: 800 | |||
| } | |||
| }); | |||
| }, 1000); | |||
| })(); | |||
| </script> | |||
| @@ -0,0 +1,469 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .unite { | |||
| font-family: SourceHanSansSC-medium !important; | |||
| color: rgba(16, 16, 16, 100) !important; | |||
| } | |||
| .title { | |||
| font-size: 16px !important; | |||
| padding-left: 3rem !important; | |||
| } | |||
| .min_title{ | |||
| font-size: 14px !important; | |||
| margin-bottom: 2rem !important; | |||
| } | |||
| .width100 { | |||
| width: 100% !important; | |||
| } | |||
| .width81 { | |||
| margin-left: 1.5rem; | |||
| width: 81% !important; | |||
| } | |||
| .width85 { | |||
| width: 85% !important; | |||
| margin-left: 10.5rem !important; | |||
| align-items: center; | |||
| } | |||
| .width48 { | |||
| width: 48.5% !important; | |||
| } | |||
| .nowrapx { | |||
| white-space: nowrap !important; | |||
| } | |||
| .v-middle { | |||
| vertical-align: middle; | |||
| } | |||
| .label-required:after { | |||
| margin: -0.2em 0 0 0.2em; | |||
| content: '*'; | |||
| color: #db2828; | |||
| visibility: visible !important; | |||
| } | |||
| </style> | |||
| {{template "custom/global_mask" .}} | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| {{$Grampus := (or (eq (index (SubJumpablePath .Link) 1) "create_grampus_gpu") (eq (index (SubJumpablePath .Link) 1) "create_grampus_npu"))}} | |||
| <div class="cloudbrain-type" style="display: none;" data-grampus="{{$Grampus}}" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-flag-model="true" data-dataset-uuid="{{.attachment}}" data-dataset-name="{{.dataset_name}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}"></div> | |||
| {{template "base/alert" .}} | |||
| <h4 class="ui top attached header"> | |||
| {{.i18n.Tr "repo.modelarts.evaluate_job.new_job"}} | |||
| </h4> | |||
| <div class="ui attached segment"> | |||
| <input type="hidden" name="benchmarkMode" value="{{.benchmarkMode}}"> | |||
| <form id="form_id" class="ui form alogrithm_form" action="{{.RepoLink}}/modelsafety/create" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <input type="hidden" name="compute_resource" value="{{.compute_resource}}"> | |||
| <input type="hidden" name="type" value="{{.type}}"> | |||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| <a class="item alogrithm_benchmark" | |||
| href="{{.RepoLink}}/cloudbrain/benchmark/create?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a> | |||
| <a class="item model_benchmark" | |||
| href="{{.RepoLink}}/cloudbrain/benchmark/create?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
| <a class="item active model_safe_benchmark" | |||
| href="{{.Link}}">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a> | |||
| </div> | |||
| </div> | |||
| <!-- <div class="required unite min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label> | |||
| <div class="ui blue mini menu compact selectcloudbrain"> | |||
| <a class="item {{if not $Grampus}}active{{end}}" href="{{.RepoLink}}/modelsafety/create_gpu"> | |||
| <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | |||
| {{.i18n.Tr "cloudbrain.resource_cluster_openi"}} | |||
| </a> | |||
| <a class="item {{if $Grampus}}active{{end}}" href="{{.RepoLink}}/modelsafety/create_grampus_gpu"> | |||
| <svg class="svg" sxmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"></path><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-2.29-2.333A17.9 17.9 0 0 1 8.027 13H4.062a8.008 8.008 0 0 0 5.648 6.667zM10.03 13c.151 2.439.848 4.73 1.97 6.752A15.905 15.905 0 0 0 13.97 13h-3.94zm9.908 0h-3.965a17.9 17.9 0 0 1-1.683 6.667A8.008 8.008 0 0 0 19.938 13zM4.062 11h3.965A17.9 17.9 0 0 1 9.71 4.333 8.008 8.008 0 0 0 4.062 11zm5.969 0h3.938A15.905 15.905 0 0 0 12 4.248 15.905 15.905 0 0 0 10.03 11zm4.259-6.667A17.9 17.9 0 0 1 15.973 11h3.965a8.008 8.008 0 0 0-5.648-6.667z"></path></svg> | |||
| {{.i18n.Tr "cloudbrain.resource_cluster_c2net"}}(Beta) | |||
| </a> | |||
| </div> | |||
| </div> --> | |||
| <div class="inline min_title required field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||
| <div class="ui blue mini menu compact selectcloudbrain"> | |||
| <a class="{{if eq .datasetType 0}}active{{end}} item" href="{{.RepoLink}}/modelsafety/create_{{if $Grampus}}grampus_{{end}}gpu"> | |||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||
| height="16"> | |||
| <path fill="none" d="M0 0h24v24H0z" /> | |||
| <path | |||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
| </svg> | |||
| CPU/GPU | |||
| </a> | |||
| <a class="{{if eq .datasetType 1}}active{{end}} item" href="{{.RepoLink}}/modelsafety/create_{{if $Grampus}}grampus_{{end}}npu"> | |||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||
| height="16"> | |||
| <path fill="none" d="M0 0h24v24H0z" /> | |||
| <path | |||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <div class="min_title inline field" style="margin-top:-10px;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| {{template "custom/task_wait_count" .}} | |||
| </div> | |||
| <div class="min_title inline field" style="margin-top:-20px;margin-bottom:12px !important;"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| <div style="display:inline-block;"> | |||
| <div style="display:flex;align-items:center;color:#f2711c;"> | |||
| <i class="ri-error-warning-line" style="margin-right: 0.5rem; font-size: 14px"></i> | |||
| <span style="font-size: 12px">{{.i18n.Tr "modelsafety.new_model_security_evaluation_tips"}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | |||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | |||
| tabindex="3" autofocus required maxlength="36"> | |||
| <span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span> | |||
| </div> | |||
| <div class="min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;" | |||
| for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||
| <textarea style="width: 80%;" id="description" name="description" rows="2" maxlength="254" | |||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} | |||
| onchange="this.value=this.value.substring(0, 255)" | |||
| onkeydown="this.value=this.value.substring(0, 255)" | |||
| onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
| </div> | |||
| <input type="hidden" id="ai_model_version" name="model_version" value="{{$.model_version}}"> | |||
| <div class="required unite inline min_title fields" style="width: 96.8%;"> | |||
| <div class="required eight wide field"> | |||
| <label style="font-size:14px;font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label> | |||
| <div class="ui fluid selection dropdown" id="select_model"> | |||
| <input type="hidden" name="model_name" required value="{{.model_name}}"> | |||
| <div class="text"></div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu" id="model_name"> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <input type="hidden" name="pre_train_model_url" value="{{.train_url}}"> | |||
| <div class="three wide field"> | |||
| <div class="ui fluid selection dropdown" id="select_model_version"> | |||
| <input type="hidden" name="train_url" required value="{{.train_url}}"> | |||
| <div class="text"></div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu" id="model_name_version"></div> | |||
| </div> | |||
| </div> | |||
| <div class="five wide field"> | |||
| <div class="ui fluid selection dropdown" id="select_model_checkpoint"> | |||
| <input type="hidden" name="ckpt_name" required value="{{.ckpt_name}}"> | |||
| <div class="text"></div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu" id="model_checkpoint"> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <span > | |||
| <i class="question circle icon" data-content="{{.i18n.Tr "cloudbrain.model_file_postfix_rule"}}" data-position="top center" data-variation="inverted mini"></i> | |||
| </span> | |||
| </div> | |||
| <div class="required inline min_title field " style="display: none;"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | |||
| <select class="ui dropdown width48" id="trainjob_resource_pool" name="pool_id"> | |||
| {{range .resource_pools}} | |||
| <option value="{{.ID}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| {{if not $Grampus}} | |||
| {{if eq .datasetType 0}} | |||
| <div id="images-new-cb"></div> | |||
| <input type="hidden" id="ai_image_name" value="{{.image}}"> | |||
| {{else}} | |||
| <div class="required inline min_title fields" style="width: 95%;"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}</label> | |||
| <div class="field" style="flex: 1.5;"> | |||
| <select class="ui dropdown width100" id="trainjob_engines"> | |||
| {{range .engines}} | |||
| <option value="{{.Value}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="field" style="flex: 2;" id="engine_name"> | |||
| <select class="ui dropdown width100" id="trainjob_engine_versions" name="engine_id"> | |||
| {{if .engine_id}} | |||
| {{range .engine_versions}} | |||
| {{if eq $.engine_id .ID}} | |||
| <option value="{{.ID}}">{{.Value}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| {{range .engine_versions}} | |||
| {{if ne $.engine_id .ID}} | |||
| <option value="{{.ID}}">{{.Value}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| {{else}} | |||
| {{range .engine_versions}} | |||
| <option value="{{.ID}}">{{.Value}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| {{else}} | |||
| {{if eq .datasetType 0}} | |||
| <div id="images-new-grampus"></div> | |||
| {{else}} | |||
| <div class="required min_title inline field" id="engine_name"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label> | |||
| <select class="ui dropdown width48" id="trainjob_images" name="image_id"> | |||
| {{if .image_id}} | |||
| {{range .images}} | |||
| {{if eq $.image_id .ID}} | |||
| <option value="{{.ID}}">{{.Name}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| {{range .images}} | |||
| {{if ne $.image_id .ID}} | |||
| <option value="{{.ID}}">{{.Name}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| {{else}} | |||
| {{range .images}} | |||
| <option name="image_id" value="{{.ID}}">{{.Name}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| <div class="inline field min_title required"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255"> | |||
| <span> | |||
| <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||
| </span> | |||
| <a href="https://git.openi.org.cn/OpenIOSSG/aisafety" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
| </div> | |||
| <div class="inline field min_title required fields" style="width: 95%;"> | |||
| <label class="label-fix-width label-required" style="font-weight: normal;">{{.i18n.Tr "modelsafety.base_data_set"}}</label> | |||
| <div class="field" style="flex:1.5"> | |||
| <select id="baseDataSet-sel" class="ui dropdown width100" name="src_dataset" ovalue="{{.src_dataset}}"></select> | |||
| </div> | |||
| <div class="field" style="flex:2;display:flex;"> | |||
| <label class="label-fix-width label-required" style="font-weight:normal;display:flex;justify-content:right;align-items: center;">{{.i18n.Tr "modelsafety.combat_data_set"}}</label> | |||
| <div style="flex:1"> | |||
| <select id="combatDataSet-sel" class="ui dropdown width100" name="combat_dataset" ovalue="{{.combat_dataset}}"></select> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="inline min_title field required"> | |||
| <label class="label-fix-width" style="font-weight:normal;">{{.i18n.Tr "modelsafety.evaluation_indicators"}}</label> | |||
| <input type="text" style="display:none;" name="evaluation_index" /> | |||
| <select id="job_indicators" class="ui dropdown width48 v-middle" multiple style='width:385px;' ovalue="{{.evaluationIndex}}"> | |||
| <option value="ACC">ACC</option> | |||
| <!-- <option value="CAV">CAV</option>--> | |||
| <option value="ASS">ASS</option> | |||
| <option value="ALDp">ALDp</option> | |||
| <option value="ACAC">ACAC</option> | |||
| <!-- <option value="ACTC">ACTC</option> --> | |||
| <option value="PSD">PSD</option> | |||
| <!-- <option value="CACC">CACC</option> --> | |||
| </select> | |||
| {{template "repo/modelsafety/indicators_descr".}} | |||
| </div> | |||
| <div class="inline min_title field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||
| <span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"> | |||
| <i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}} | |||
| </span> | |||
| <input id="store_run_para" type="hidden" name="run_para_list"> | |||
| <div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}" data-params-value="{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}" data-params-name="{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}"></div> | |||
| </div> | |||
| <div class="required min_title inline field"> | |||
| <label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="__specs__" class="ui dropdown width48" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}" | |||
| {{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}} | |||
| name="spec_id"> | |||
| </select> | |||
| {{if .CloudBrainPaySwitch}} | |||
| <div class="cloudbrain_resource_spec_blance_tip width48" style="padding:0 5px;margin:6px 0;margin-left:155px;font-size:12px;"> | |||
| <span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span> | |||
| <span style="float:right;"> | |||
| <i class="question circle icon link" data-position="right center" data-variation="mini"></i> | |||
| <a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a> | |||
| </span> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| <div class="inline unite min_title field"> | |||
| <label class="label-fix-width" style="font-weight: normal;"></label> | |||
| <button class="ui create_train_job green button"> | |||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||
| </button> | |||
| <a class="ui button" href="{{.RepoLink}}/cloudbrain/benchmark">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| let form = document.getElementById('form_id'); | |||
| let createFlag = false | |||
| form.onsubmit = function (e) { | |||
| if(createFlag) return false | |||
| createFlag = true | |||
| } | |||
| $('.menu .item').tab(); | |||
| var isValidate = false; | |||
| function validate() { | |||
| $('.ui.form') | |||
| .form({ | |||
| on: 'blur', | |||
| fields: { | |||
| boot_file: { | |||
| identifier: "boot_file", | |||
| rules: [ | |||
| { | |||
| type: "regExp[/.+.py$/g]", | |||
| }, | |||
| ], | |||
| }, | |||
| job_name: { | |||
| identifier: "job_name", | |||
| rules: [ | |||
| { | |||
| type: "regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]", | |||
| }, | |||
| ], | |||
| }, | |||
| display_job_name: { | |||
| identifier: "display_job_name", | |||
| rules: [ | |||
| { | |||
| type: "regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]", | |||
| }, | |||
| ], | |||
| }, | |||
| attachment: { | |||
| identifier: "attachment", | |||
| rules: [ | |||
| { | |||
| type: "empty", | |||
| }, | |||
| ], | |||
| }, | |||
| spec_id: { | |||
| identifier: "spec_id", | |||
| rules: [{ type: "empty" }], | |||
| }, | |||
| evaluation_index:{ | |||
| identifier: 'evaluation_index', | |||
| rules: [{ type: 'empty', } ] | |||
| }, | |||
| model_name:{ | |||
| identifier: 'model_name', | |||
| rules: [{ type: 'empty', } ] | |||
| }, | |||
| train_url:{ | |||
| identifier: 'train_url', | |||
| rules: [{ type: 'empty', }] | |||
| }, | |||
| ckpt_name:{ | |||
| identifier: 'ckpt_name', | |||
| rules: [{ type: 'empty', }] | |||
| }, | |||
| }, | |||
| onSuccess: function () { | |||
| document.getElementById("mask").style.display = "block"; | |||
| isValidate = true; | |||
| }, | |||
| onFailure: function (e) { | |||
| document.getElementById("mask").style.display = "none"; | |||
| isValidate = false; | |||
| createFlag = false; | |||
| return false; | |||
| } | |||
| }) | |||
| } | |||
| validate(); | |||
| $('.ui.create_train_job.green.button').click(function (e) { | |||
| validate(); | |||
| }); | |||
| ;(function() { | |||
| var SPECS = {{ .benchmark_specs }} || {{ .Specs }}; | |||
| var showPoint = {{ .CloudBrainPaySwitch }}; | |||
| window.renderSpecsSelect($('#__specs__'), SPECS, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| })(); | |||
| ;(function() { | |||
| var baseDataSetName = {{.BaseDataSetName}} || ''; | |||
| var baseDataSetUUID = {{.BaseDataSetUUID}} || ''; | |||
| var combatDataSetName = {{.CombatDataSetName}} || ''; | |||
| var combatDataSetUUID = {{.CombatDataSetUUID}} || ''; | |||
| var baseDataSetSel = $('#baseDataSet-sel'); | |||
| var combatDataSetSel = $('#combatDataSet-sel'); | |||
| function initDataSetSelect(names, keys, selectEl) { | |||
| selectEl.empty(); | |||
| var nameList = names.split(','); | |||
| var keyList = keys.split(',') | |||
| for (var i = 0, iLen = nameList.length; i < iLen; i++) { | |||
| selectEl.append(`<option index="${i}" value="${keyList[i]}">${nameList[i]}</option>`); | |||
| } | |||
| var oValue = selectEl.attr('ovalue'); | |||
| oValue && selectEl.val(oValue); | |||
| selectEl.on('change', function() { | |||
| var self = $(this); | |||
| var selectIndex = self.find('option:selected').attr('index'); | |||
| var type = self.attr('id'); | |||
| if (type === 'baseDataSet-sel') { | |||
| var val = combatDataSetSel.find('option[index="'+selectIndex+'"]').attr('value'); | |||
| combatDataSetSel.dropdown('set selected', val); | |||
| } else { | |||
| var val = baseDataSetSel.find('option[index="'+selectIndex+'"]').attr('value'); | |||
| baseDataSetSel.dropdown('set selected', val); | |||
| } | |||
| }).trigger('change'); | |||
| } | |||
| initDataSetSelect(baseDataSetName, baseDataSetUUID, baseDataSetSel); | |||
| initDataSetSelect(combatDataSetName, combatDataSetUUID, combatDataSetSel); | |||
| $('#job_indicators').on('change', function() { | |||
| var value = $(this).val(); | |||
| $('input[name="evaluation_index"]').val(value.join(';')); | |||
| }).trigger('change'); | |||
| var oIndicators = $('#job_indicators').attr('ovalue'); | |||
| if (oIndicators) { | |||
| $('input[name="evaluation_index"]').val(oIndicators); | |||
| $('#job_indicators').dropdown('set exactly', oIndicators.split(';')) | |||
| }; | |||
| })(); | |||
| </script> | |||
| @@ -0,0 +1 @@ | |||
| {{template "repo/modelsafety/new".}} | |||
| @@ -0,0 +1 @@ | |||
| {{template "repo/modelsafety/new".}} | |||
| @@ -0,0 +1,893 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .according-panel-heading { | |||
| box-sizing: border-box; | |||
| padding: 8px 16px; | |||
| color: #252b3a; | |||
| background-color: #f2f5fc; | |||
| line-height: 1.5; | |||
| cursor: pointer; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .accordion-panel-title { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| color: #252b3a; | |||
| } | |||
| .accordion-panel-title-content { | |||
| vertical-align: middle; | |||
| display: inline-block; | |||
| width: calc(100% - 32px); | |||
| cursor: default; | |||
| } | |||
| .acc-margin-bottom { | |||
| margin-bottom: 5px; | |||
| } | |||
| .title_text { | |||
| font-size: 12px; | |||
| } | |||
| .ac-display-inblock { | |||
| display: inline-block; | |||
| } | |||
| .cti-mgRight-sm { | |||
| margin-right: 8px; | |||
| } | |||
| .ac-text-normal { | |||
| font-size: 14px; | |||
| color: #575d6c; | |||
| } | |||
| .uc-accordionTitle-black { | |||
| color: #333; | |||
| } | |||
| .accordion-border { | |||
| border: 1px solid #cce2ff; | |||
| } | |||
| .padding0 { | |||
| padding: 0 !important; | |||
| } | |||
| .content-pad { | |||
| padding: 15px 35px; | |||
| } | |||
| .content-margin { | |||
| margin: 10px 5px; | |||
| } | |||
| .tab_2_content { | |||
| min-height: 600px; | |||
| margin-left: 10px; | |||
| } | |||
| .ac-grid { | |||
| display: block; | |||
| *zoom: 1; | |||
| } | |||
| .ac-grid-col { | |||
| float: left; | |||
| width: 100%; | |||
| } | |||
| .ac-grid-col2 .ac-grid-col { | |||
| width: 50%; | |||
| } | |||
| .ti-form { | |||
| text-align: left; | |||
| max-width: 100%; | |||
| vertical-align: middle; | |||
| } | |||
| .ti-form>tbody { | |||
| font-size: 12px; | |||
| } | |||
| .ti-form>tbody, | |||
| .ti-form>tbody>tr { | |||
| vertical-align: inherit; | |||
| } | |||
| .ti-text-form-label { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| color: #8a8e99; | |||
| font-size: 12px; | |||
| white-space: nowrap !important; | |||
| width: 80px; | |||
| line-height: 30px; | |||
| } | |||
| .ti-text-form-content { | |||
| line-height: 30px; | |||
| padding-bottom: 20px; | |||
| } | |||
| .ti-form>tbody>tr>td { | |||
| vertical-align: top; | |||
| white-space: normal; | |||
| } | |||
| td, | |||
| th { | |||
| padding: 0; | |||
| } | |||
| .ac-grid-col .text-span { | |||
| width: 420px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| } | |||
| .redo-color { | |||
| color: #3291F8; | |||
| } | |||
| .ti-action-menu-item:not(:last-child) { | |||
| margin-right: 10px; | |||
| padding-right: 11px; | |||
| text-decoration: none !important; | |||
| color: #526ecc; | |||
| cursor: pointer; | |||
| display: inline-block; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| position: relative; | |||
| } | |||
| .ti-action-menu-item:not(:last-child):after { | |||
| content: ""; | |||
| display: inline-block; | |||
| position: absolute; | |||
| height: 12px; | |||
| right: 0; | |||
| top: 50%; | |||
| -webkit-transform: translateY(-6px); | |||
| -ms-transform: translateY(-6px); | |||
| -o-transform: translateY(-6px); | |||
| transform: translateY(-6px); | |||
| border-right: 1px solid #dfe1e6; | |||
| } | |||
| .text-width80 { | |||
| width: 100px; | |||
| line-height: 30px; | |||
| } | |||
| .border-according { | |||
| border: 1px solid #dfe1e6; | |||
| } | |||
| .disabled { | |||
| cursor: default; | |||
| pointer-events: none; | |||
| color: rgba(0, 0, 0, .6) !important; | |||
| opacity: .45 !important; | |||
| } | |||
| .pad20 { | |||
| border: 0px !important; | |||
| } | |||
| .model_file_bread { | |||
| margin-bottom: -0.5rem !important; | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem; | |||
| } | |||
| </style> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| <div class="rect1"></div> | |||
| <div class="rect2"></div> | |||
| <div class="rect3"></div> | |||
| <div class="rect4"></div> | |||
| <div class="rect5"></div> | |||
| </div> | |||
| </div> | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <h4 class="ui header" id="vertical-segment"> | |||
| <div class="ui breadcrumb"> | |||
| <a class="section" href="{{.RepoLink}}/debugjob?debugListType=all"> | |||
| {{$.i18n.Tr "repo.cloudbrain"}} | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| <a class="section" href="{{$.RepoLink}}/cloudbrain/benchmark"> | |||
| {{$.i18n.Tr "repo.modelarts.evaluate_job"}} | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| <div class="active section" vfield="DisplayJobName"></div> | |||
| </div> | |||
| </h4> | |||
| <div class="ui accordion border-according" id="accordion" data-repopath="{{$.RepoRelPath}}/cloudbrain" data-jobid="" vdatajobid="ID" data-version=""> | |||
| <input type="hidden" id="jobId_input" name="jobId_input" value="" vvalue="JobID"> | |||
| <div class="active title padding0"> | |||
| <div class="according-panel-heading"> | |||
| <div class="accordion-panel-title"> | |||
| <i class="dropdown icon"></i> | |||
| <span class="accordion-panel-title-content"> | |||
| <span> | |||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | |||
| <span class="cti-mgRight-sm"> | |||
| <span vtime="CreatedUnix"></span> | |||
| </span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||
| <span id="-status-span"> | |||
| <i id="icon" style="vertical-align: middle;" class="{{.Status}}" vclass="Status"></i> | |||
| <span id="text" style="margin-left: 0.4em;font-size: 12px;" vfield="Status"></span> | |||
| </span> | |||
| </span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
| <span class="cti-mgRight-sm uc-accordionTitle-black" id="-duration-span" vfield="TrainJobDuration"></span> | |||
| </div> | |||
| </span> | |||
| </span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="active content"> | |||
| <div class="content-pad"> | |||
| <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
| <a class="active item" data-tab="first0">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
| <a class="item log_bottom" data-tab="second0" data-version="">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
| <a class="item" data-tab="third0" data-version="">{{.i18n.Tr "modelsafety.evaluation_result"}}</a> | |||
| </div> | |||
| <div class="ui tab active" data-tab="first0"> | |||
| <div style="padding-top: 10px;"> | |||
| <div class="tab_2_content"> | |||
| <div class="ac-grid ac-grid-col2"> | |||
| <div class="ac-grid-col"> | |||
| <table class="ti-form"> | |||
| <tbody class="ti-text-form"> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain_task"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="DisplayJobName"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.status"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="-status" vfield="Status"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.createtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| <span style="font-size: 12px;" class="v-field" vtime="CreatedUnix"></span> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.starttime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w v-field" vtime="StartTime" id="-startTime"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.endtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w v-field" vtime="EndTime" id="-EndTime"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="TrainJobDuration" id="-duration"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80" vimagetitle="Image"> | |||
| <span style="display:none;">{{$.i18n.Tr "cloudbrain.mirror"}}</span> | |||
| <span style="display:none;">{{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}}</span> | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="-mirror"> | |||
| <span class="ui poping up clipboard" data-position="top center" id="clipboard-btn" style="cursor:pointer" | |||
| data-clipboard-text="{{.Image}}" | |||
| data-success="{{$.i18n.Tr "repo.copied"}}" | |||
| data-error="{{$.i18n.Tr "repo.copied_error"}}" | |||
| data-content="{{$.i18n.Tr "repo.copy"}}" | |||
| data-variation="inverted tiny" | |||
| vdataclipboardtext="Image" | |||
| > | |||
| <span vtitle="Image" vimage="Image" ></span></span> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="BenchmarkType"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="BenchmarkTypeName"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{.i18n.Tr "modelsafety.base_data_set"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vdataset0="DatasetName"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{.i18n.Tr "modelsafety.combat_data_set"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vdataset1="DatasetName"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vtitle="Parameters" vfield="Parameters"></div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| <div class="ac-grid-col"> | |||
| <table class="ti-form"> | |||
| <tbody class="ti-text-form"> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.code_version"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="BranchName"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vtitle="Description" vfield="Description"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.train_job.resource_type"}}</span> | |||
| </td> | |||
| <td class="ti-text-form-content resorce_type"> | |||
| <div class="text-span text-span-w"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content spec"> | |||
| <div class="text-span text-span-w"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.model_name"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="ModelName"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelconvert.modelversion"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="ModelVersion"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.infer_job_model_file"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="CkptName"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="-mirror" vuser="User.Name"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="BootFile"></div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{.i18n.Tr "modelsafety.evaluation_indicators"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" vfield="LabelName"></div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="ui tab" data-tab="second0"> | |||
| <div> | |||
| <a id="-log-down" | |||
| class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}}' | |||
| href="/api/v1/repos/{{$.RepoRelPath}}/cloudbrain"> | |||
| <i class="ri-download-cloud-2-line"></i> | |||
| <span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span> | |||
| </a> | |||
| </div> | |||
| <div | |||
| style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||
| <span> | |||
| <a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | |||
| class="log_top" data-version=""><i class="icon-to-top"></i></a> | |||
| </span> | |||
| <span class="log-info-"> | |||
| <a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||
| class="log_bottom" data-version=""><i | |||
| class="icon-to-bottom"></i></a> | |||
| </span> | |||
| <div class="ui message message" style="display: none;"> | |||
| <div id="header"></div> | |||
| </div> | |||
| <div class="ui attached log log-scroll" id="log" data-version="" | |||
| style="height: 300px !important; overflow: auto;"> | |||
| <div class="ui inverted active dimmer"> | |||
| <div class="ui loader"></div> | |||
| </div> | |||
| <input type="hidden" name="end_line" value> | |||
| <input type="hidden" name="start_line" value> | |||
| <pre id="log_file"></pre> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="ui tab" data-tab="third0"> | |||
| <style> | |||
| .__res_item { | |||
| margin-bottom: 20px; | |||
| } | |||
| .__res_title { | |||
| height: 50px; | |||
| display: flex; | |||
| align-items: center; | |||
| margin-bottom: 10px; | |||
| } | |||
| .__res_title_icon { | |||
| height: 48px; | |||
| width: 48px; | |||
| margin-right: 8px; | |||
| } | |||
| .bNIWIE.fill:not([stroke]) { | |||
| fill: rgb(105, 192, 255); | |||
| } | |||
| .bNIWIE.fill:not([fill]) { | |||
| fill: rgb(105, 192, 255); | |||
| } | |||
| .__res_title_txt { | |||
| font-family: SourceHanSansSC; | |||
| font-size: 14px; | |||
| font-style: normal; | |||
| line-height: 20px; | |||
| text-decoration: none; | |||
| } | |||
| .__res_title_txt1 { | |||
| font-weight: 700; | |||
| color: rgb(3, 102, 214); | |||
| } | |||
| .__res_title_txt2 { | |||
| font-weight: 300; | |||
| color: rgba(136,136,136,1); | |||
| } | |||
| .__res_table_container { | |||
| overflow-x: auto; | |||
| } | |||
| .__res_table_container table { | |||
| border-bottom-left-radius: 0 !important; | |||
| border-bottom-right-radius: 0 !important; | |||
| } | |||
| .__res_table_container th, .__res_table_container td { | |||
| text-align: center !important; | |||
| } | |||
| .__res_chart_container { | |||
| height:280px; | |||
| border: 1px solid rgba(34,36,38,.1); | |||
| margin-top: -1px; | |||
| border-bottom-left-radius: .28571429rem; | |||
| border-bottom-right-radius: .28571429rem; | |||
| } | |||
| .__res_no_data { | |||
| height: 200px; | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: center; | |||
| } | |||
| </style> | |||
| <div style="display:none;"> | |||
| {{template "repo/modelsafety/indicators_descr".}} | |||
| </div> | |||
| <div class="__res_container"> | |||
| <div class="__res_no_data">{{.i18n.Tr "modelsafety.no_data"}}</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/paginate" .}} | |||
| </div> | |||
| <!-- 确认模态框 --> | |||
| <div id="deletemodel"> | |||
| <div class="ui basic modal"> | |||
| <div class="ui icon header"> | |||
| <i class="trash icon"></i> {{$.i18n.Tr "cloudbrain.delete_task"}} | |||
| </div> | |||
| <div class="content"> | |||
| <p>{{$.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||
| </div> | |||
| <div class="actions"> | |||
| <div class="ui red basic inverted cancel button"> | |||
| <i class="remove icon"></i> {{$.i18n.Tr "cloudbrain.operate_cancel"}} | |||
| </div> | |||
| <div class="ui green basic inverted ok button"> | |||
| <i class="checkmark icon"></i> {{$.i18n.Tr "cloudbrain.operate_confirm"}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script> | |||
| <script> | |||
| ;(function() { | |||
| function paddingZeros(str, len) { | |||
| str = str.toString(); | |||
| if (str.length < len) { | |||
| str = new Array(len - str.length).fill('0').join('') + str; | |||
| } | |||
| return str; | |||
| } | |||
| function timeFormat(date) { | |||
| return `${date.getFullYear()}-${paddingZeros(date.getMonth() + 1, 2)}-${paddingZeros(date.getDate(), 2)} ${paddingZeros(date.getHours(), 2)}:${paddingZeros(date.getMinutes(), 2)}:${paddingZeros(date.getSeconds(), 2)}`; | |||
| } | |||
| function initTable(tableEl, data) { | |||
| tableEl.empty(); | |||
| var lanUntargetted = {{.i18n.Tr "modelsafety.untargetted"}}; | |||
| var lanTargetted = {{.i18n.Tr "modelsafety.targetted"}}; | |||
| if (data.indicator === 'ALDp') { | |||
| tableEl.append(` | |||
| <table class="ui celled table"> | |||
| <thead> | |||
| <tr class="tr-head"><th colspan="2" style="width:100px;">${data.indicator}</th></tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr class="tr-untargetted"><td rowspan="3">${lanUntargetted}</td><td>L_0 norm</td></tr> | |||
| <tr class="tr-untargetted"><td style="border-left: 1px solid rgba(34,36,38,.1);">L_2 norm</td></tr> | |||
| <tr class="tr-untargetted"><td style="border-left: 1px solid rgba(34,36,38,.1);">L_inf norm</td></tr> | |||
| <tr class="tr-targetted"><td rowspan="3">${lanTargetted}</td><td>L_0 norm</td></tr> | |||
| <tr class="tr-targetted"><td style="border-left: 1px solid rgba(34,36,38,.1);">L_2 norm</td></tr> | |||
| <tr class="tr-targetted"><td style="border-left: 1px solid rgba(34,36,38,.1);">L_inf norm</td></tr> | |||
| </tbody> | |||
| </table>`); | |||
| var trHead = tableEl.find('tr.tr-head'); | |||
| var trUntargetted = tableEl.find('tr.tr-untargetted'); | |||
| var trTargetted = tableEl.find('tr.tr-targetted'); | |||
| for (var i = 0, iLen = data.params.length; i < iLen; i++) { | |||
| var params = data.params; | |||
| var untargetted = data.untargetted; | |||
| var targetted = data.targetted; | |||
| trHead.append(`<th>param(${params[i]})</th>`); | |||
| trUntargetted.eq(0).append(`<td>${Number(untargetted[i][0]).toFixed(3)}</td>`); | |||
| trUntargetted.eq(1).append(`<td>${Number(untargetted[i][1]).toFixed(3)}</td>`); | |||
| trUntargetted.eq(2).append(`<td>${Number(untargetted[i][2]).toFixed(3)}</td>`); | |||
| trTargetted.eq(0).append(`<td>${Number(targetted[i][0]).toFixed(3)}</td>`); | |||
| trTargetted.eq(1).append(`<td>${Number(targetted[i][1]).toFixed(3)}</td>`); | |||
| trTargetted.eq(2).append(`<td>${Number(targetted[i][2]).toFixed(3)}</td>`); | |||
| } | |||
| } else { | |||
| tableEl.append(` | |||
| <table class="ui celled table"> | |||
| <thead> | |||
| <tr class="tr-head"><th style="width:100px;">${data.indicator}</th></tr> | |||
| </thead> | |||
| <tbody> | |||
| <tr class="tr-untargetted"><td>{{.i18n.Tr "modelsafety.untargetted"}}</td></tr> | |||
| <tr class="tr-targetted"><td>{{.i18n.Tr "modelsafety.targetted"}}</td></tr> | |||
| </tbody> | |||
| </table>`); | |||
| var trHead = tableEl.find('tr.tr-head'); | |||
| var trUntargetted = tableEl.find('tr.tr-untargetted'); | |||
| var trTargetted = tableEl.find('tr.tr-targetted'); | |||
| for (var i = 0, iLen = data.params.length; i < iLen; i++) { | |||
| var params = data.params; | |||
| var untargetted = data.untargetted; | |||
| var targetted = data.targetted; | |||
| trHead.append(`<th>param(${params[i]})</th>`); | |||
| trUntargetted.append(`<td>${Number(untargetted[i]).toFixed(3)}</td>`); | |||
| trTargetted.append(`<td>${Number(targetted[i]).toFixed(3)}</td>`); | |||
| } | |||
| } | |||
| } | |||
| function initChart(chartEl, data) { | |||
| var chartHandle = chartEl.data('chart'); | |||
| chartHandle && chartHandle.dispose(); | |||
| chartHandle && window.removeEventListener('resize', chartHandle.resize); | |||
| chartHandle = echarts.init(chartEl[0]); | |||
| chartEl.data('chart', chartHandle); | |||
| var lanUntargetted = {{.i18n.Tr "modelsafety.untargetted"}}; | |||
| var lanTargetted = {{.i18n.Tr "modelsafety.targetted"}}; | |||
| var option = { | |||
| tooltip: { | |||
| trigger: 'axis' | |||
| }, | |||
| color: ['rgb(80, 135, 236)', 'rgb(104, 187, 196)'], | |||
| legend: { | |||
| data: [lanUntargetted, lanTargetted], | |||
| top: '15', | |||
| }, | |||
| grid: { | |||
| top: '50', | |||
| left: '20', | |||
| right: '20', | |||
| bottom: '20', | |||
| containLabel: true | |||
| }, | |||
| xAxis: { | |||
| type: 'category', | |||
| data: data.params.map(function(item){ return `param(${item})`}), | |||
| }, | |||
| yAxis: { | |||
| type: 'value' | |||
| }, | |||
| series: [ | |||
| { | |||
| name: lanUntargetted, | |||
| type: 'line', | |||
| data: (data.untargetted || []).map(function(item){ return Number(Number(item).toFixed(3)) }), | |||
| }, | |||
| { | |||
| name: lanTargetted, | |||
| type: 'line', | |||
| data: (data.targetted || []).map(function(item){ return Number(Number(item).toFixed(3)) }), | |||
| } | |||
| ] | |||
| }; | |||
| if (data.indicator === 'ALDp') { | |||
| option.color = ['rgb(80, 135, 236)', 'rgb(247, 238, 209)', 'rgb(231, 230, 238)', 'rgb(104, 187, 196)', 'rgb(211, 183, 136)', 'rgb(159, 131, 179)']; | |||
| option.legend.data = [`${lanUntargetted}(L_0)`, `${lanUntargetted}(L_2)`, `${lanUntargetted}(L_inf)`, | |||
| `${lanTargetted}(L_0)`, `${lanTargetted}(L_2)`, `${lanTargetted}(L_inf)`]; | |||
| option.series = [ | |||
| { | |||
| name: `${lanUntargetted}(L_0)`, | |||
| type: 'line', | |||
| data: (data.untargetted || []).map(function(item){ return Number(item[0].toFixed(3)) }), | |||
| }, | |||
| { | |||
| name: `${lanUntargetted}(L_2)`, | |||
| type: 'line', | |||
| data: (data.untargetted || []).map(function(item){ return Number(item[1].toFixed(3)) }), | |||
| }, | |||
| { | |||
| name: `${lanUntargetted}(L_inf)`, | |||
| type: 'line', | |||
| data: (data.untargetted || []).map(function(item){ return Number(item[2].toFixed(3)) }), | |||
| }, | |||
| { | |||
| name: `${lanTargetted}(L_0)`, | |||
| type: 'line', | |||
| data: (data.targetted || []).map(function(item){ return Number(item[0].toFixed(3)) }), | |||
| }, | |||
| { | |||
| name: `${lanTargetted}(L_2)`, | |||
| type: 'line', | |||
| data: (data.targetted || []).map(function(item){ return Number(item[1].toFixed(3)) }), | |||
| }, | |||
| { | |||
| name: `${lanTargetted}(L_inf)`, | |||
| type: 'line', | |||
| data: (data.targetted || []).map(function(item){ return Number(item[2].toFixed(3)) }), | |||
| } | |||
| ]; | |||
| } | |||
| chartHandle.setOption(option); | |||
| window.addEventListener('resize', chartHandle.resize); | |||
| } | |||
| function initResItems(list) { | |||
| var resContainer = $('.__res_container'); | |||
| resContainer.empty(); | |||
| for (var i = 0, iLen = list.length; i < iLen; i++) { | |||
| var item = list[i], indicator = item.indicator; | |||
| var descr = $(`[indicator="${indicator}"]`).text(); | |||
| var resItemContainer = $(`<div class="__res_item"> | |||
| <div class="__res_title"> | |||
| <div class="__res_title_icon"> | |||
| <svg xmlns="http://www.w3.org/2000/svg" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 bNIWIE svg-icon-path-icon fill" viewBox="0 0 32 32" width="48" height="48"><defs data-reactroot=""></defs><g><path d="M8.155 26.783c-3.342-2.449-5.488-6.36-5.488-10.771 0-0.004 0-0.008 0-0.012v0.001c0-7.364 5.969-13.333 13.333-13.333s13.333 5.969 13.333 13.333c0 0.003 0 0.007 0 0.011 0 4.412-2.146 8.323-5.451 10.745l-0.037 0.026-1.353-2.319c2.549-1.969 4.175-5.026 4.175-8.464 0-5.891-4.776-10.667-10.667-10.667s-10.667 4.776-10.667 10.667c0 3.437 1.626 6.494 4.15 8.445l0.025 0.018-1.353 2.319zM10.867 22.136c-1.758-1.477-2.867-3.677-2.867-6.136 0-4.418 3.582-8 8-8s8 3.582 8 8c0 2.459-1.109 4.658-2.854 6.126l-0.012 0.010-1.373-2.355c0.972-0.966 1.573-2.304 1.573-3.782 0-2.946-2.388-5.333-5.333-5.333s-5.333 2.388-5.333 5.333c0 1.478 0.601 2.816 1.573 3.782l0 0-1.373 2.355zM14.667 17.333h2.667v12h-2.667v-12z"></path></g></svg> | |||
| </div> | |||
| <div class="__res_title_txt"> | |||
| <div class="__res_title_txt1">${indicator}-${item.name}</div> | |||
| <div class="__res_title_txt2">${descr}</div> | |||
| </div> | |||
| </div> | |||
| <div class="__res_table_container"></div> | |||
| <div class="__res_chart_container"></div> | |||
| </div>`); | |||
| resContainer.append(resItemContainer); | |||
| initTable(resItemContainer.find('.__res_table_container'), item); | |||
| initChart(resItemContainer.find('.__res_chart_container'), item); | |||
| } | |||
| }; | |||
| function initResTab(data) { | |||
| var name = data.name; | |||
| var params = data.params; | |||
| var indicators = Object.keys(data.targetted); | |||
| var list = []; | |||
| for (var i = 0, iLen = indicators.length; i < iLen; i++) { | |||
| var indicator = indicators[i]; | |||
| var obj = { | |||
| name: name, | |||
| params: params.flat(), | |||
| indicator: indicator, | |||
| targetted: data.targetted[indicator]['targets'], | |||
| untargetted: data.untargetted[indicator], | |||
| }; | |||
| list.push(obj); | |||
| } | |||
| initResItems(list); | |||
| } | |||
| var resultData; | |||
| function initData() { | |||
| $.ajax({ | |||
| url: window.location.href.replace('cloudbrain/benchmark', 'modelsafety'), | |||
| type: "get", | |||
| data: {}, | |||
| contentType: "application/json; charset=utf-8", | |||
| success(res) { | |||
| for (var key in res) { | |||
| $(`[vfield="${key}"]`).text(res[key]); | |||
| $(`[vclass="${key}"]`).addClass(res[key]); | |||
| $(`[vtime="${key}"]`).text(res[key] ? timeFormat(new Date(res[key] * 1000)) : '--'); | |||
| $(`[vtitle="${key}"]`).attr('title', res[key]); | |||
| $(`[vdataset0="${key}"]`).text(res[key] ? res[key].toString().split(';')[0] : ''); | |||
| $(`[vdataset1="${key}"]`).text(res[key] ? res[key].toString().split(';')[1] : ''); | |||
| $(`[vvalue="${key}"]`).val(res[key]); | |||
| $(`[vdatajobid="${key}"]`).attr('data-jobid', res[key]); | |||
| } | |||
| $(`[vfield="Description"]`).text(res['Description'] || '--'); | |||
| $(`[vfield="Parameters"]`).text(res['Parameters'] || '--'); | |||
| var imageName = res['Image'] || res['EngineName']; | |||
| $(`[vimagetitle="Image"] span`).hide(); | |||
| if (res.Type === 0) { | |||
| imageName = res['Image']; | |||
| $(`[vimagetitle="Image"] span`).eq(0).show(); | |||
| } else { | |||
| imageName = res['EngineName']; | |||
| $(`[vimagetitle="Image"] span`).eq(1).show(); | |||
| } | |||
| $(`[vdataclipboardtext="Image"]`).attr('data-clipboard-text', imageName); | |||
| $(`[vimage="Image"]`).text(imageName); | |||
| $(`[vtitle="Image"]`).attr('title', imageName); | |||
| $(`[vuser="User.Name"]`).text(res['User'] && res['User']['Name']); | |||
| if (res.Spec) { | |||
| var SPEC = res.Spec; | |||
| var showPoint = false; | |||
| var specStr = window.renderSpecStr(SPEC, showPoint, { | |||
| gpu_memory: {{$.i18n.Tr "cloudbrain.gpu_memory"}}, | |||
| free: {{$.i18n.Tr "cloudbrain.free"}}, | |||
| point_hr: {{$.i18n.Tr "cloudbrain.point_hr"}}, | |||
| memory: {{$.i18n.Tr "cloudbrain.memory"}}, | |||
| shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, | |||
| }); | |||
| $('td.ti-text-form-content.spec div').text(specStr); | |||
| SPEC && $('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType)); | |||
| } | |||
| var oLogHref = $('#-log-down').attr('href'); | |||
| $('#-log-down').attr('href', oLogHref + `/${res.ID}/download_log_file`); | |||
| if (res.ResultJson) { | |||
| try { | |||
| resultData = JSON.parse(res.ResultJson); | |||
| } catch(e) { | |||
| resultData = res.ResultJson; | |||
| } | |||
| } | |||
| }, | |||
| error(err) { | |||
| console.log(err); | |||
| }, | |||
| }); | |||
| } | |||
| initData(); | |||
| $(document).ready(function () { | |||
| $('.ui.accordion').accordion({ selector: { trigger: '.icon' } }); | |||
| }); | |||
| $('.pointing.secondary.menu .item').tab({ | |||
| onVisible: function(tabPath) { | |||
| if (tabPath === 'first0') { | |||
| initData(); | |||
| } | |||
| if (tabPath === 'third0') { | |||
| if (resultData) { | |||
| if (typeof resultData === 'object') { | |||
| initResTab(resultData); | |||
| } else if (typeof resultData === 'string') { | |||
| var resContainer = $('.__res_container'); | |||
| resContainer.find('.__res_no_data').text(resultData); | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -85,20 +85,13 @@ | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | |||
| {{else if (eq .JobType "SNN4IMAGENET" "BRAINSCORE")}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "MODELSAFETY"}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelsafety/{{$JobID}}/show" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}" | |||
| @@ -113,7 +106,7 @@ | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| {{else if eq .JobType "BENCHMARK" "MODELSAFETY"}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px"> | |||
| @@ -130,7 +123,7 @@ | |||
| <div class="two wide column text center nowrap" | |||
| style="width: 8% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" | |||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | |||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK" "MODELSAFETY"}}/cloudbrain{{end}}' | |||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | |||
| class="{{.Status}}"></i><span id="{{$JobID}}-text" | |||
| @@ -1011,7 +1011,8 @@ export default { | |||
| if ( | |||
| location.href.indexOf("benchmark") !== -1 || | |||
| location.href.indexOf("train-job") !== -1 || | |||
| location.href.indexOf("inference") !== -1 | |||
| location.href.indexOf("inference") !== -1 || | |||
| location.href.indexOf("modelsafety") !== -1 | |||
| ) { | |||
| this.benchmarkNew = true; | |||
| } | |||
| @@ -242,7 +242,8 @@ export default { | |||
| this.getImageListPublic(); | |||
| if ( | |||
| location.href.indexOf("benchmark") !== -1 || | |||
| location.href.indexOf("train-job") !== -1 | |||
| location.href.indexOf("train-job") !== -1 || | |||
| location.href.indexOf("modelsafety") !== -1 | |||
| ) { | |||
| this.benchmarkNew = true; | |||
| } | |||
| @@ -47,6 +47,7 @@ | |||
| type="text" | |||
| :placeholder="i18n.image_search_placeholder" | |||
| v-model="search" | |||
| @keydown.enter.stop.prevent="searchName" | |||
| /> | |||
| </div> | |||
| <el-tabs v-model="activeName" @tab-click="handleClick"> | |||
| @@ -505,7 +506,8 @@ export default { | |||
| if ( | |||
| location.href.indexOf("train-job") !== -1 || | |||
| location.href.indexOf("inference-job") !== -1 || | |||
| location.href.indexOf("benchmark") !== -1 | |||
| location.href.indexOf("benchmark") !== -1 || | |||
| location.href.indexOf("modelsafety") !== -1 | |||
| ) { | |||
| this.benchmarkNew = true; | |||
| } | |||
| @@ -148,6 +148,10 @@ export default async function initCloudrainSow() { | |||
| $(`#${version_name}-log-down`) | |||
| .removeClass("ti-download-file") | |||
| .addClass("disabled"); | |||
| } else { | |||
| $(`#${version_name}-log-down`) | |||
| .addClass("ti-download-file") | |||
| .removeClass("disabled"); | |||
| } | |||
| $(`#log${version_name} input[name=end_line]`).val(data.EndLine); //如果变动就改变所对应的值 | |||
| $(`#log${version_name} input[name=start_line]`).val(data.StartLine); | |||
| @@ -8,6 +8,7 @@ export default async function initCloudrain() { | |||
| function loadJobStatus() { | |||
| $(".job-status").each((index, job) => { | |||
| const ID = job.dataset.jobid; | |||
| if (!ID) return; | |||
| const repoPath = job.dataset.repopath; | |||
| // const computeResource = job.dataset.resource | |||
| const versionname = job.dataset.version; | |||
| @@ -144,6 +145,7 @@ export default async function initCloudrain() { | |||
| function loadShowJobStatus() { | |||
| $(".ui.accordion.border-according").each((index, job) => { | |||
| const jobID = job.dataset.jobid; | |||
| if (!jobID) return; | |||
| const repoPath = job.dataset.repopath; | |||
| const versionname = job.dataset.version; | |||
| // ['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'] | |||
| @@ -152,7 +154,7 @@ export default async function initCloudrain() { | |||
| // || job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') { | |||
| // return | |||
| // } | |||
| let status = $(`#${versionname}-status-span`).text(); | |||
| let status = $(`#${versionname}-status-span`).text().trim(); | |||
| if ( | |||
| [ | |||
| @@ -65,6 +65,7 @@ const { AppSubUrl, StaticUrlPrefix, csrf } = window.config; | |||
| Object.defineProperty(Vue.prototype, "$echarts", { | |||
| value: echarts, | |||
| }); | |||
| window.echarts = echarts; | |||
| function htmlEncode(text) { | |||
| return jQuery("<div />").text(text).html(); | |||
| @@ -89,7 +89,7 @@ | |||
| identifier: "job_name", | |||
| rules: [ | |||
| { | |||
| type: "regExp[/^[a-zA-Z0-9-_]{1,36}$/]", | |||
| type: "regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]", | |||
| }, | |||
| ], | |||
| }, | |||
| @@ -97,7 +97,7 @@ | |||
| identifier: "display_job_name", | |||
| rules: [ | |||
| { | |||
| type: "regExp[/^[a-zA-Z0-9-_]{1,36}$/]", | |||
| type: "regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]", | |||
| }, | |||
| ], | |||
| }, | |||
| @@ -121,6 +121,7 @@ | |||
| }, | |||
| onFailure: function (e) { | |||
| isValidate = false; | |||
| createFlag = false; | |||
| return false; | |||
| }, | |||
| }); | |||
| @@ -0,0 +1,13 @@ | |||
| import service from "../service"; | |||
| // 数据脱敏接口 | |||
| export const postImgDesensitization = (params, data) => { | |||
| return service({ | |||
| url: "/extension/tuomin/upload", | |||
| headers: { Accept: "image/png" }, | |||
| responseType: "blob", | |||
| method: "POST", | |||
| params: params, | |||
| data: data, | |||
| }); | |||
| }; | |||
| @@ -176,6 +176,22 @@ const en = { | |||
| Activated: 'Activated', | |||
| notActive: 'Not active', | |||
| }, | |||
| tranformImageFailed:'Picture desensitization failed', | |||
| originPicture:'Origin picture', | |||
| desensitizationPicture:'Desensitization picture', | |||
| desensitizationObject:'Desensitization object', | |||
| example:'Example', | |||
| startDesensitization:'Start desensitization', | |||
| all:'All', | |||
| onlyFace:'Only face', | |||
| onlyLicensePlate:'Only license plate', | |||
| dragThePictureHere:'Drag the picture here', | |||
| or:'or', | |||
| clickUpload:'Click upload', | |||
| dataDesensitizationModelExperience:'Data desensitization model experience', | |||
| dataDesensitizationModelDesc:'Use AI technology to desensitize the face and license plate number in the picture. For more information about this model, please visit the project', | |||
| limitFilesUpload:'Only jpg/jpeg/png files can be uploaded', | |||
| limitSizeUpload:'The size of the uploaded file cannot exceed 20M!', | |||
| } | |||
| export default en; | |||
| @@ -176,6 +176,22 @@ const zh = { | |||
| Activated: '已激活', | |||
| notActive: '未激活', | |||
| }, | |||
| tranformImageFailed:'图片脱敏失败', | |||
| originPicture:'原始图片', | |||
| desensitizationPicture:'脱敏图片', | |||
| desensitizationObject:'脱敏对象', | |||
| example:'示例', | |||
| startDesensitization:'开始处理', | |||
| all:'全部', | |||
| onlyFace:'仅人脸', | |||
| onlyLicensePlate:'仅车牌', | |||
| dragThePictureHere:'拖动图片到这里', | |||
| or:'或', | |||
| clickUpload:'点击上传', | |||
| dataDesensitizationModelExperience:'数据脱敏模型体验', | |||
| dataDesensitizationModelDesc:'利用人工智能AI技术,把图片中的人脸、车牌号码进行脱敏处理。该模型更多信息请访问项目', | |||
| limitFilesUpload:'只能上传 jpg/jpeg/png 格式的文件', | |||
| limitSizeUpload:'上传文件大小不能超过 20M !', | |||
| } | |||
| export default zh; | |||
| @@ -0,0 +1,380 @@ | |||
| <template> | |||
| <div class="ui container"> | |||
| <div class="tuomin-title"> | |||
| <h2>{{ $t("dataDesensitizationModelExperience") }}</h2> | |||
| <p> | |||
| {{ $t("dataDesensitizationModelDesc") }} <a | |||
| href="https://git.openi.org.cn/tengxiao/tuomin" | |||
| target="_blank" | |||
| >tengxiao / tuomin</a | |||
| > | |||
| </p> | |||
| </div> | |||
| <el-row :gutter="12" style="margin-top: 33px"> | |||
| <el-col :xs="24" :span="12"> | |||
| <div class="tuomin-content-image"> | |||
| <div class="tuomin-icon"> | |||
| <i | |||
| class="ri-image-line" | |||
| style="font-size: 16px; margin-right: 2px" | |||
| ></i> | |||
| <span style="font-size: 12px">img</span> | |||
| </div> | |||
| <div style="height: 230px; width: 96%; margin: 0 auto"> | |||
| <el-upload | |||
| action="#" | |||
| accept=".jpg,.jpeg,.png,.JPG,.JPEG,.PNG" | |||
| :show-file-list="false" | |||
| :on-change="handleChangePicture" | |||
| list-type="picture-card" | |||
| :file-list="fileList" | |||
| :style="{ display: ImageUrl ? 'none' : 'block' }" | |||
| :auto-upload="false" | |||
| drag | |||
| > | |||
| <div class="el-upload__text"> | |||
| {{ $t("dragThePictureHere") | |||
| }}<span style="color: rgba(136, 136, 136, 0.87)">{{ | |||
| $t("or") | |||
| }}</span | |||
| >{{ $t("clickUpload") }} | |||
| </div> | |||
| </el-upload> | |||
| <img class="preview-image" v-if="ImageUrl" :src="ImageUrl" alt="" /> | |||
| </div> | |||
| <div> | |||
| <div class="tuomin-radio-model"> | |||
| <label class="radio-label" | |||
| >{{ $t("desensitizationObject") }}:</label | |||
| > | |||
| <div> | |||
| <el-radio-group v-model="radio"> | |||
| <el-radio :label="2">{{ $t("all") }}</el-radio> | |||
| <el-radio :label="1">{{ $t("onlyFace") }}</el-radio> | |||
| <el-radio :label="0">{{ $t("onlyLicensePlate") }}</el-radio> | |||
| </el-radio-group> | |||
| </div> | |||
| </div> | |||
| <div class="tuomin-button-model"> | |||
| <el-button @click="cancelUpload">{{ $t("cancel") }}</el-button> | |||
| <el-button | |||
| :disabled="fileList.length < 1" | |||
| @click="startTranform" | |||
| type="primary" | |||
| >{{ $t("startDesensitization") }}</el-button | |||
| > | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </el-col> | |||
| <el-col :xs="24" :span="12"> | |||
| <div class="tuomin-content-image" v-loading="tranformImageLoading"> | |||
| <div class="tuomin-icon"> | |||
| <i | |||
| class="ri-image-line" | |||
| style="font-size: 16px; margin-right: 2px" | |||
| ></i> | |||
| <span style="font-size: 12px">output</span> | |||
| </div> | |||
| <div | |||
| v-if="resultImgSrc" | |||
| class="tuomin-icon-download" | |||
| @click="downImg" | |||
| > | |||
| <i | |||
| class="ri-download-2-line" | |||
| style="font-size: 16px; margin-right: 2px" | |||
| ></i> | |||
| <span style="font-size: 14px">下载</span> | |||
| </div> | |||
| <div style="height: 358px"> | |||
| <el-image | |||
| style="height: 100%; width: 100%" | |||
| :src="resultImgSrc" | |||
| :preview-src-list="[resultImgSrc]" | |||
| > | |||
| <div slot="error" class="image-slot"> | |||
| <i style="font-size: 0" class="el-icon-picture-outline"></i> | |||
| </div> | |||
| </el-image> | |||
| </div> | |||
| </div> | |||
| </el-col> | |||
| </el-row> | |||
| <div style="margin: 39px 0 21px 0"> | |||
| <span>{{ $t("example") }}:</span> | |||
| </div> | |||
| <div class="table-container"> | |||
| <div> | |||
| <el-table border :data="tableData1" style="width: 100%"> | |||
| <el-table-column :label="$t('originPicture')" align="center"> | |||
| <template slot-scope="scope"> | |||
| <div style="width: 100%; height: 200px"> | |||
| <el-image | |||
| style="height: 100%; width: 100%" | |||
| :src="scope.row.imgSrc1" | |||
| :preview-src-list="[scope.row.imgSrc1]" | |||
| > | |||
| <div slot="error" class="image-slot"> | |||
| <i style="font-size: 0" class="el-icon-picture-outline"></i> | |||
| </div> | |||
| </el-image> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column :label="$t('desensitizationPicture')" align="center"> | |||
| <template slot-scope="scope"> | |||
| <div style="width: 100%; height: 200px"> | |||
| <el-image | |||
| style="height: 100%; width: 100%" | |||
| :src="scope.row.imgSrc2" | |||
| :preview-src-list="[scope.row.imgSrc2]" | |||
| > | |||
| <div slot="error" class="image-slot"> | |||
| <i style="font-size: 0" class="el-icon-picture-outline"></i> | |||
| </div> | |||
| </el-image> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="mode" | |||
| :label="$t('desensitizationObject')" | |||
| align="center" | |||
| header-align="center" | |||
| > | |||
| </el-table-column> | |||
| </el-table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { postImgDesensitization } from "~/apis/modules/desensitization"; | |||
| export default { | |||
| data() { | |||
| return { | |||
| ImageUrl: "", | |||
| radio: 2, | |||
| file: "", | |||
| fileList: [], | |||
| resultImgSrc: "", | |||
| tranformImageLoading: false, | |||
| tableData1: [ | |||
| { | |||
| imgSrc1: "/img/origin.png", | |||
| imgSrc2: "/img/tuomin.png", | |||
| mode: this.$t("all"), | |||
| }, | |||
| ], | |||
| startFlag: false, | |||
| }; | |||
| }, | |||
| components: {}, | |||
| methods: { | |||
| // 选择文件、移除文件、上传文件成功/失败后,都会触发 | |||
| handleChangePicture(file, fileList) { | |||
| let acceptList = ["jpg", "jpeg", "png"]; | |||
| // 根据文件名获取文件的后缀名 | |||
| let fileType = file.name.split(".").pop().toLowerCase(); | |||
| // 判断文件格式是否符合要求 | |||
| if (acceptList.indexOf(fileType) === -1) { | |||
| this.$message.error(this.$t("limitFilesUpload")); | |||
| return false; | |||
| } | |||
| // 判断文件大小是否符合要求 | |||
| if (file.size / 1024 / 1024 > 20) { | |||
| this.$message.error(this.$t("limitSizeUpload")); | |||
| return false; | |||
| } | |||
| this.ImageUrl = URL.createObjectURL(file.raw); | |||
| this.file = file; | |||
| this.fileList = fileList; | |||
| }, | |||
| cancelUpload() { | |||
| this.ImageUrl = ""; | |||
| this.file = ""; | |||
| this.fileList = []; | |||
| }, | |||
| downImg() { | |||
| const a = document.createElement("a"); | |||
| a.download = "result.png"; | |||
| a.style.display = "none"; | |||
| a.href = this.resultImgSrc; | |||
| document.body.appendChild(a); | |||
| a.click(); | |||
| document.body.removeChild(a); | |||
| }, | |||
| startTranform() { | |||
| if (!this.startFlag) { | |||
| window.location.href = "/user/login"; | |||
| return; | |||
| } | |||
| if (!this.file) return; | |||
| let fd = new FormData(); | |||
| fd.append("file", this.file.raw); | |||
| this.tranformImageLoading = true; | |||
| postImgDesensitization({ mode: this.radio }, fd) | |||
| .then((res) => { | |||
| const objectURL = URL.createObjectURL(res.data); | |||
| this.resultImgSrc = objectURL; | |||
| this.tranformImageLoading = false; | |||
| }) | |||
| .catch((err) => { | |||
| this.tranformImageLoading = false; | |||
| if (err.response.status === 400) { | |||
| const fr = new FileReader(); | |||
| fr.onload = (e) => { | |||
| try { | |||
| const jsonResult = JSON.parse(e.target.result); | |||
| this.$message({ | |||
| type: "error", | |||
| message: jsonResult.Message, | |||
| }); | |||
| } catch (e) { | |||
| this.$message({ | |||
| type: "error", | |||
| message: this.$t("tranformImageFailed"), | |||
| }); | |||
| } | |||
| }; | |||
| fr.readAsText(err.response.data); | |||
| } else { | |||
| this.$message({ | |||
| type: "error", | |||
| message: this.$t("tranformImageFailed"), | |||
| }); | |||
| } | |||
| }); | |||
| }, | |||
| }, | |||
| mounted() { | |||
| const signEl = document.querySelector("#isSignd"); | |||
| this.startFlag = !!signEl.getAttribute("data-sign"); | |||
| }, | |||
| beforeDestroy() {}, | |||
| }; | |||
| </script> | |||
| <style scoped lang="less"> | |||
| .tuomin-title { | |||
| margin-top: 34px; | |||
| h2 { | |||
| display: flex; | |||
| justify-content: center; | |||
| } | |||
| p { | |||
| display: flex; | |||
| justify-content: center; | |||
| color: rgba(136, 136, 136, 0.87); | |||
| } | |||
| } | |||
| .tuomin-content-image { | |||
| border: 1px solid rgba(0, 0, 0, 0.1); | |||
| border-radius: 5px; | |||
| min-height: 358px; | |||
| position: relative; | |||
| .tuomin-icon { | |||
| z-index: 99; | |||
| display: flex; | |||
| align-items: center; | |||
| position: absolute; | |||
| left: 0; | |||
| top: 0; | |||
| width: 66px; | |||
| height: 22px; | |||
| justify-content: center; | |||
| color: rgba(136, 136, 136, 0.87); | |||
| border-radius: 5px 0px 10px 0px; | |||
| border: 1px solid rgba(0, 0, 0, 0.1); | |||
| } | |||
| .tuomin-icon-download { | |||
| z-index: 99; | |||
| display: flex; | |||
| align-items: center; | |||
| position: absolute; | |||
| right: 10px; | |||
| bottom: 10px; | |||
| width: 66px; | |||
| height: 30px; | |||
| justify-content: center; | |||
| color: rgba(255, 255, 255, 1); | |||
| background-color: rgba(0, 0, 0, 0); | |||
| background: transparent; | |||
| border: 1px solid rgba(136, 136, 136, 0.5); | |||
| border-radius: 4px; | |||
| cursor: pointer; | |||
| } | |||
| .el-upload__text { | |||
| height: 100%; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| } | |||
| .preview-image { | |||
| height: 100%; | |||
| width: 100%; | |||
| } | |||
| .tuomin-radio-model { | |||
| display: flex; | |||
| margin: 25px 12px 0 12px; | |||
| .radio-label { | |||
| font-weight: 600; | |||
| margin-right: 4px; | |||
| color: rgba(16, 16, 16, 1); | |||
| } | |||
| } | |||
| .tuomin-button-model { | |||
| text-align: right; | |||
| margin: 22px 12px 0 12px; | |||
| } | |||
| } | |||
| /deep/ .el-upload--picture-card { | |||
| width: 100%; | |||
| background: #ffff; | |||
| border: none; | |||
| border-bottom: 1px dashed #888; | |||
| border-radius: 0; | |||
| min-height: 230px; | |||
| } | |||
| /deep/ .el-upload-dragger { | |||
| width: 100%; | |||
| background: #ffff; | |||
| border: none; | |||
| border-radius: 0; | |||
| height: 100%; | |||
| } | |||
| .table-container { | |||
| margin-bottom: 16px; | |||
| /deep/ .el-table__header { | |||
| th { | |||
| background: rgb(245, 245, 246); | |||
| font-size: 14px; | |||
| color: rgb(36, 36, 36); | |||
| font-weight: 400; | |||
| } | |||
| } | |||
| /deep/ .el-table__body { | |||
| td { | |||
| font-size: 14px; | |||
| } | |||
| } | |||
| } | |||
| .center { | |||
| display: flex; | |||
| justify-content: center; | |||
| } | |||
| @media screen and (max-width: 768px) { | |||
| body { | |||
| background-color: black; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -0,0 +1,17 @@ | |||
| import Vue from 'vue'; | |||
| import ElementUI from 'element-ui'; | |||
| import 'element-ui/lib/theme-chalk/index.css'; | |||
| import localeEn from 'element-ui/lib/locale/lang/en'; | |||
| import localeZh from 'element-ui/lib/locale/lang/zh-CN'; | |||
| import { i18n, lang } from '~/langs'; | |||
| import App from './index.vue'; | |||
| Vue.use(ElementUI, { | |||
| locale: lang === 'zh-CN' ? localeZh : localeEn, | |||
| size: 'small', | |||
| }); | |||
| new Vue({ | |||
| i18n, | |||
| render: (h) => h(App), | |||
| }).$mount('#__vue-root'); | |||
| @@ -87,6 +87,10 @@ export const getRewardPointRecordInfo = (record) => { | |||
| if (record.SourceType === 'ADMIN_OPERATE') { | |||
| out.remark = record.Remark; | |||
| } else if (record.SourceType === 'ACCOMPLISH_TASK') { | |||
| if (record.Action?.Cloudbrain?.JobType === 'MODELSAFETY') { | |||
| record.Action.Cloudbrain.oJobType = 'MODELSAFETY'; | |||
| record.Action.Cloudbrain.JobType = 'BENCHMARK'; | |||
| } | |||
| switch (record?.Action?.TaskType) { | |||
| case 'CreatePublicRepo': // 创建公开项目 - 创建了项目OpenI/aiforge | |||
| out.remark = `${i18n.t('createdRepository')}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`; | |||