#5097 V20240109

Merged
ychao_1983 merged 167 commits from V20240109 into develop 4 months ago
  1. +2
    -2
      README.md
  2. +0
    -0
      docs/持续集成操作指南.md
  3. +1
    -0
      entity/container.go
  4. +6
    -0
      manager/client/grampus/grampus.go
  5. +31
    -27
      models/action.go
  6. +14
    -0
      models/ai_model_manage.go
  7. +5
    -4
      models/cloudbrain.go
  8. +1
    -0
      models/models.go
  9. +4
    -1
      models/resource_scene.go
  10. +3
    -1
      models/task_config.go
  11. +6
    -8
      models/user_business_analysis.go
  12. +32
    -0
      models/user_other_info.go
  13. +1
    -1
      models/user_year_summary.go
  14. +1
    -1
      modules/base/tool.go
  15. +1
    -1
      modules/context/context.go
  16. +24
    -14
      modules/git/repo_stats_custom.go
  17. +3
    -0
      modules/notebook/contentManager.go
  18. +10
    -4
      modules/setting/setting.go
  19. +2
    -2
      modules/templates/helper.go
  20. +12
    -3
      options/locale/locale_en-US.ini
  21. +10
    -1
      options/locale/locale_zh-CN.ini
  22. +18
    -4
      public/home/home.js
  23. +2
    -0
      public/home/search.js
  24. +1
    -1
      routers/api/v1/api.go
  25. +3
    -225
      routers/api/v1/repo/cloudbrain.go
  26. +264
    -0
      routers/api/v1/repo/modelmanage.go
  27. +5
    -6
      routers/card_request/card_request.go
  28. +348
    -78
      routers/repo/ai_model_convert.go
  29. +10
    -12
      routers/repo/cloudbrain.go
  30. +16
    -2
      routers/repo/grampus.go
  31. +2
    -138
      routers/repo/modelarts.go
  32. +2
    -2
      routers/repo/repo_statistic.go
  33. +6
    -6
      routers/repo/user_data_analysis.go
  34. +97
    -1
      routers/repo/util.go
  35. +1
    -0
      routers/repo/view.go
  36. +10
    -2
      routers/routes/routes.go
  37. +48
    -5
      routers/user/auth.go
  38. +3
    -1
      services/ai_task_service/cluster/c2net.go
  39. +5
    -0
      services/ai_task_service/cluster/cloudbrain_two.go
  40. +12
    -2
      services/ai_task_service/container_builder/code_builder.go
  41. +3
    -1
      services/ai_task_service/container_builder/output_path_builder.go
  42. +1
    -0
      services/ai_task_service/container_builder/pre_model_builder.go
  43. +139
    -0
      services/ai_task_service/task/cloudbrain_two_inference_task.go
  44. +144
    -0
      services/ai_task_service/task/grampus_inference_task.go
  45. +20
    -0
      services/ai_task_service/task/grampus_notebook_task.go
  46. +1
    -1
      services/ai_task_service/task/opt_handler.go
  47. +1
    -1
      services/ai_task_service/task/task_creation_info.go
  48. +9
    -8
      services/ai_task_service/task/task_service.go
  49. +13
    -12
      services/cloudbrain/clear.go
  50. +20
    -13
      services/cloudbrain/cloudbrainTask/notebook.go
  51. +1
    -1
      services/socketwrap/clientManager.go
  52. +4
    -4
      templates/admin/cloudbrain/list.tmpl
  53. +5
    -1
      templates/base/footer.tmpl
  54. +2
    -2
      templates/repo/cloudbrain/benchmark/index.tmpl
  55. +2
    -10
      templates/repo/cloudbrain/benchmark/new.tmpl
  56. +1
    -553
      templates/repo/cloudbrain/inference/new.tmpl
  57. +1
    -446
      templates/repo/cloudbrain/inference/show.tmpl
  58. +1
    -0
      templates/repo/grampus/inference/new.tmpl
  59. +1
    -0
      templates/repo/grampus/inference/show.tmpl
  60. +1
    -1
      templates/repo/home.tmpl
  61. +4
    -306
      templates/repo/modelarts/inferencejob/index.tmpl
  62. +1
    -577
      templates/repo/modelarts/inferencejob/new.tmpl
  63. +1
    -435
      templates/repo/modelarts/inferencejob/show.tmpl
  64. +10
    -25
      templates/repo/modelmanage/convertshowinfo.tmpl
  65. +2
    -27
      templates/repo/modelsafety/new.tmpl
  66. +1
    -1
      templates/terms.tmpl
  67. +16
    -0
      templates/user/auth/network_security.tmpl
  68. +2
    -2
      templates/user/auth/signin_navbar.tmpl
  69. +4
    -4
      templates/user/dashboard/cloudbrains.tmpl
  70. +21
    -1
      templates/user/dashboard/feeds.tmpl
  71. +4
    -4
      web_src/js/components/dataset/selectDataset.vue
  72. +2
    -0
      web_src/js/features/i18nVue.js
  73. +54
    -0
      web_src/js/index.js
  74. +3
    -0
      web_src/less/openi.less
  75. +1
    -1
      web_src/vuepages/components/cloudbrain/DatasetSelect.vue
  76. +1
    -1
      web_src/vuepages/const/index.js
  77. +13
    -7
      web_src/vuepages/langs/config/en-US.js
  78. +6
    -0
      web_src/vuepages/langs/config/zh-CN.js
  79. +201
    -52
      web_src/vuepages/pages/cloudbrain/configs.js
  80. +16
    -2
      web_src/vuepages/pages/cloudbrain/list/index.vue
  81. +9
    -0
      web_src/vuepages/pages/cloudbrain/tools.js
  82. +6
    -4
      web_src/vuepages/pages/computingpower/components/DemandForm.vue
  83. +9
    -5
      web_src/vuepages/pages/computingpower/demand/index.vue
  84. +1
    -0
      web_src/vuepages/pages/dataset/square/constant.js
  85. +3
    -3
      web_src/vuepages/pages/modelbase/components/cloudbrain/DatasetSelect.vue
  86. +3
    -1
      web_src/vuepages/pages/modelmanage/fileupload/index.vue
  87. +7
    -1
      web_src/vuepages/pages/reward/point/utils.js

+ 2
- 2
README.md View File

@@ -71,7 +71,7 @@
```
docker pull swr.cn-north-4.myhuaweicloud.com/openi/aiforge-postgres:v1
docker pull swr.cn-north-4.myhuaweicloud.com/openi/aiforge-dev:v1
docker pull swr.cn-north-4.myhuaweicloud.com/openi/aiforge-dev:v2
```

2. 启动镜像:
@@ -92,7 +92,7 @@
-p 8787:3000 \
-p 2222:22 \
-v /home/openi/data:/data \
-d swr.cn-north-4.myhuaweicloud.com/openi/aiforge-dev:v1
-d swr.cn-north-4.myhuaweicloud.com/openi/aiforge-dev:v2
```

3. 进入开发容器并下载代码:


+ 0
- 0
docs/持续集成操作指南.md View File


+ 1
- 0
entity/container.go View File

@@ -19,6 +19,7 @@ type ContainerData struct {
GetBackEndpoint string `json:"getBackEndpoint"`
S3DownloadUrl string `json:"s3DownloadUrl"`
Size int64 `json:"size"`
IsOverwrite bool `json:"isOverwrite"`
StorageType StorageType
}



+ 6
- 0
manager/client/grampus/grampus.go View File

@@ -33,6 +33,7 @@ const (

errorIllegalToken = 1005
errorCannotStopCreatingJob = 5008
MAX_MATRICS_SIZE = 1000
)

type GetTokenParams struct {
@@ -370,6 +371,11 @@ func GetGrampusMetrics(jobID string, startTime int64, endTime int64, nodeId ...i

size := int64(math.Ceil(float64(endTime-startTime)/float64(step))) + 1

if size > MAX_MATRICS_SIZE {
step = int64(math.Ceil(float64(size*step) / float64(MAX_MATRICS_SIZE)))
size = MAX_MATRICS_SIZE
}

url = url + "?startTime=" + strconv.FormatInt(startTime, 10) + "&step=" + strconv.FormatInt(step, 10) + "&size=" + strconv.FormatInt(size, 10)
}
res, err := client.R().


+ 31
- 27
models/action.go View File

@@ -50,32 +50,34 @@ const (
ActionRejectPullRequest // 22
ActionCommentPull // 23

ActionUploadAttachment //24
ActionCreateDebugGPUTask //25
ActionCreateDebugNPUTask //26
ActionCreateTrainTask //27
ActionCreateInferenceTask // 28
ActionCreateBenchMarkTask //29
ActionCreateNewModelTask //30
ActionCreateGPUTrainTask //31
ActionCreateGrampusNPUTrainTask //32
ActionCreateGrampusGPUTrainTask //33
ActionBindWechat //34
ActionDatasetRecommended //35
ActionCreateImage //36
ActionImageRecommend //37
ActionChangeUserAvatar //38
ActionCreateGrampusNPUDebugTask //39
ActionCreateGrampusGPUDebugTask //40
ActionCreateGrampusGCUDebugTask //41
ActionCreateGrampusGCUTrainTask //42
ActionCreateGrampusMLUDebugTask //43
ActionCreateGrampusMLUTrainTask //44
ActionCreateGrampusGPUOnlineInferTask //45
ActionCreateGrampusDCUDebugTask //46
ActionCreateSuperComputeTask //47
ActionCreateGrampusILUVATARDebugTask //48
ActionCreateGrampusMETAXDebugTask //49
ActionUploadAttachment //24
ActionCreateDebugGPUTask //25
ActionCreateDebugNPUTask //26
ActionCreateTrainTask //27
ActionCreateInferenceTask // 28
ActionCreateBenchMarkTask //29
ActionCreateNewModelTask //30
ActionCreateGPUTrainTask //31
ActionCreateGrampusNPUTrainTask //32
ActionCreateGrampusGPUTrainTask //33
ActionBindWechat //34
ActionDatasetRecommended //35
ActionCreateImage //36
ActionImageRecommend //37
ActionChangeUserAvatar //38
ActionCreateGrampusNPUDebugTask //39
ActionCreateGrampusGPUDebugTask //40
ActionCreateGrampusGCUDebugTask //41
ActionCreateGrampusGCUTrainTask //42
ActionCreateGrampusMLUDebugTask //43
ActionCreateGrampusMLUTrainTask //44
ActionCreateGrampusGPUOnlineInferTask //45
ActionCreateGrampusDCUDebugTask //46
ActionCreateSuperComputeTask //47
ActionCreateGrampusILUVATARDebugTask //48
ActionCreateGrampusMETAXDebugTask //49
ActionCreateGrampusGPUInferenceTask //50
ActionCreateGrampusILUVATARInferenceTask //51
)

// Action represents user operation type and other information to
@@ -431,7 +433,9 @@ func (a *Action) IsCloudbrainAction() bool {
ActionCreateGrampusMLUDebugTask,
ActionCreateGrampusILUVATARDebugTask,
ActionCreateGrampusMETAXDebugTask,
ActionCreateSuperComputeTask:
ActionCreateSuperComputeTask,
ActionCreateGrampusILUVATARInferenceTask,
ActionCreateGrampusGPUInferenceTask:
return true
}
return false


+ 14
- 0
models/ai_model_manage.go View File

@@ -227,6 +227,20 @@ func UpdateModelConvertCBTI(id string, CloudBrainTaskId string) error {
return nil
}

func UpdateResultMigrateFlag(id string, resultMigrateFlag string) error {
var sess *xorm.Session
sess = x.ID(id)
defer sess.Close()
re, err := sess.Cols("status_result").Update(&AiModelConvert{
StatusResult: resultMigrateFlag,
})
if err != nil {
return err
}
log.Info("success to update resultMigrateFlag from db.re=" + fmt.Sprint((re)))
return nil
}

func UpdateModelConvert(job *AiModelConvert) error {
return updateModelConvert(x, job)
}


+ 5
- 4
models/cloudbrain.go View File

@@ -2080,6 +2080,7 @@ type GrampusDataset struct {
ReadOnly bool `json:"readOnly"`
GetBackEndpoint string `json:"getBackEndpoint"`
Size int64 `json:"size"`
IsOverwrite bool `json:"isOverwrite"`
}

type CreateGrampusJobRequest struct {
@@ -2749,7 +2750,7 @@ func GetGPUStoppedNotDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error)
JobStopped, JobSucceeded, JobFailed, ModelArtsCreateFailed, ModelArtsStartFailed, ModelArtsUnavailable, ModelArtsResizFailed, ModelArtsDeleted,
ModelArtsStopped, ModelArtsTrainJobCanceled, ModelArtsTrainJobCheckFailed, ModelArtsTrainJobCompleted, ModelArtsTrainJobDeleteFailed, ModelArtsTrainJobDeployServiceFailed,
ModelArtsTrainJobFailed, ModelArtsTrainJobImageFailed, ModelArtsTrainJobKilled, ModelArtsTrainJobLost, ModelArtsTrainJobSubmitFailed, ModelArtsTrainJobSubmitModelFailed).
Where("(((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and cleared=false and job_type != 'DEBUG' and (type=0 or (type =2 and compute_resource='CPU/GPU'))", missEndTimeBefore, endTimeBefore).
Where("(((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and cleared=false and job_type != 'DEBUG' and (type=0 or type=2)", missEndTimeBefore, endTimeBefore).
Limit(limit).
Find(&cloudbrains)
}
@@ -2763,7 +2764,7 @@ func GetNPUStoppedNotDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error)
JobStopped, JobSucceeded, JobFailed, ModelArtsCreateFailed, ModelArtsStartFailed, ModelArtsUnavailable, ModelArtsResizFailed, ModelArtsDeleted,
ModelArtsStopped, ModelArtsTrainJobCanceled, ModelArtsTrainJobCheckFailed, ModelArtsTrainJobCompleted, ModelArtsTrainJobDeleteFailed, ModelArtsTrainJobDeployServiceFailed,
ModelArtsTrainJobFailed, ModelArtsTrainJobImageFailed, ModelArtsTrainJobKilled, ModelArtsTrainJobLost, ModelArtsTrainJobSubmitFailed, ModelArtsTrainJobSubmitModelFailed).
Where("updated_unix<? and updated_unix != 0 and cleared=false and job_type != 'DEBUG' and (type=1 or (type =2 and compute_resource='NPU'))", endTimeBefore).
Where("updated_unix<? and updated_unix != 0 and cleared=false and job_type != 'DEBUG' and type=1", endTimeBefore).
Limit(limit).
Find(&cloudbrains)
}
@@ -2782,7 +2783,7 @@ func GetGPUStoppedDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error) {
FROM cloudbrain
where job_type='DEBUG'
ORDER BY job_name, updated_unix DESC) a
where status in ('STOPPED','SUCCEEDED','FAILED') and (((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and (type=0 or (type =2 and compute_resource='CPU/GPU')) and cleared=false`
where status in ('STOPPED','SUCCEEDED','FAILED') and (((end_time is null or end_time=0) and updated_unix<? and updated_unix != 0 ) or (end_time<? and end_time != 0)) and (type=0 or type =2 ) and cleared=false`
//
return cloudbrains, x.Unscoped().SQL(sql, missEndTimeBefore, endTimeBefore).Limit(limit).Find(&cloudbrains)

@@ -2796,7 +2797,7 @@ func GetNPUStoppedDebugJobDaysAgo(days int, limit int) ([]*Cloudbrain, error) {
FROM cloudbrain
where job_type='DEBUG'
ORDER BY job_name, updated_unix DESC) a
where status in ('STOPPED','SUCCEEDED','FAILED') and updated_unix<? and updated_unix != 0 and (type=1 or (type =2 and compute_resource='NPU')) and cleared=false`
where status in ('STOPPED','SUCCEEDED','FAILED') and updated_unix<? and updated_unix != 0 and type=1 and cleared=false`
//(type=0 or (type =2 and compute_resource='CPU/GPU')) and
return cloudbrains, x.Unscoped().SQL(sql, endTimeBefore).Limit(limit).Find(&cloudbrains)



+ 1
- 0
models/models.go View File

@@ -195,6 +195,7 @@ func init() {
new(UserBusinessAnalysisYesterday),
new(UserBusinessAnalysisLastWeek),
new(UserLoginLog),
new(UserOtherInfo),
new(UserMetrics),
new(UserAnalysisPara),
new(Invitation),


+ 4
- 1
models/resource_scene.go View File

@@ -27,6 +27,7 @@ type ResourceScene struct {
JobType string
Cluster string
ComputeResource string
IsExclusive bool
IsSpecExclusive string
SceneType string //共享或者独占场景
ExclusiveOrg string
@@ -176,6 +177,7 @@ func InsertResourceScene(r ResourceSceneReq) error {
rs := ResourceScene{
SceneName: r.SceneName,
JobType: r.JobType,
IsExclusive: r.IsSpecExclusive == "exclusive",
IsSpecExclusive: r.IsSpecExclusive,
SceneType: r.SceneType,
Cluster: r.Cluster,
@@ -273,11 +275,12 @@ func UpdateResourceScene(r ResourceSceneReq) error {
//update scene
rs := ResourceScene{
SceneName: r.SceneName,
IsExclusive: r.IsSpecExclusive == "exclusive",
IsSpecExclusive: r.IsSpecExclusive,
ExclusiveOrg: r.ExclusiveOrg,
SceneType: r.SceneType,
}
if _, err = sess.ID(r.ID).UseBool("is_spec_exclusive").Update(&rs); err != nil {
if _, err = sess.ID(r.ID).UseBool("is_spec_exclusive", "is_exclusive").Update(&rs); err != nil {
return err
}



+ 3
- 1
models/task_config.go View File

@@ -80,7 +80,9 @@ func GetTaskTypeFromAction(a ActionType) TaskType {
ActionCreateGrampusMETAXDebugTask,
ActionCreateSuperComputeTask,
ActionCreateGrampusGPUOnlineInferTask,
ActionCreateGrampusGPUTrainTask:
ActionCreateGrampusGPUTrainTask,
ActionCreateGrampusGPUInferenceTask,
ActionCreateGrampusILUVATARInferenceTask:
return TaskCreateCloudbrainTask
case ActionCreateRepo:
return TaskCreatePublicRepo


+ 6
- 8
models/user_business_analysis.go View File

@@ -580,17 +580,18 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS
var err error
var existCommitCodeSize map[int64]int
if tableName == "user_business_analysis_all" || tableName == "user_business_analysis_current_year" {

oneDayStartTime := pageEndTime.AddDate(0, 0, -1)
oneDayStartTime = time.Date(oneDayStartTime.Year(), oneDayStartTime.Month(), oneDayStartTime.Day(), 0, 0, 0, 1, oneDayStartTime.Location())
if oneDayStartTime.Format("2006-01-02") == pageStartTime.Format("2006-01-02") {
existCommitCodeSize = make(map[int64]int, 0)
} else {
existCommitCodeSize = queryCommitCodeSizeFromDb("public." + tableName)
}
oneDayEndTime := time.Date(oneDayStartTime.Year(), oneDayStartTime.Month(), oneDayStartTime.Day(), 23, 59, 59, 1, oneDayStartTime.Location())
log.Info("GetAllUserKPIStats oneDayStartTime=" + oneDayStartTime.Format("2006-01-02 15:04:05"))
log.Info("GetAllUserKPIStats pageEndTime=" + pageEndTime.Format("2006-01-02 15:04:05"))
log.Info("GetAllUserKPIStats pageEndTime=" + oneDayEndTime.Format("2006-01-02 15:04:05"))
log.Info("existCommitCodeSize len=" + fmt.Sprint(len(existCommitCodeSize)))
CommitCodeSizeMap, err = GetAllUserKPIStats(oneDayStartTime, pageEndTime)
CommitCodeSizeMap, err = GetAllUserKPIStats(oneDayStartTime, oneDayEndTime)
if err != nil {
log.Info("query commit code errr.")
} else {
@@ -2286,7 +2287,7 @@ func queryUserModelConvert(start_unix int64, end_unix int64) map[int64]int {
}

func isBenchMark(JobType string) bool {
if JobType == "BENCHMARK" || JobType == "MODELSAFETY" || JobType == "SNN4IMAGENET" || JobType == "BRAINSCORE" || JobType == "SNN4ECOSET" {
if JobType == "BENCHMARK" || JobType == "MODELSAFETY" || JobType == "SNN4IMAGENET" || JobType == "BRAINSCORE" || JobType == "SNN4ECOSET" || JobType == "SIM2BRAIN_SNN" {
return true
}
return false
@@ -2322,12 +2323,9 @@ func queryCloudBrainTask(start_unix int64, end_unix int64) (map[int64]int, map[s
if _, ok := resourceItemMap[cloudTaskRecord.UserID]; !ok {
resourceItemMap[cloudTaskRecord.UserID] = make(map[string]int)
}

if cloudTaskRecord.Duration < 100000000 && cloudTaskRecord.Duration > 0 {
setMapKey("CloudBrainRunTime", cloudTaskRecord.UserID, int(cloudTaskRecord.Duration), resultItemMap)
resourceItemMap[cloudTaskRecord.UserID][cloudTaskRecord.ComputeResource] = resourceItemMap[cloudTaskRecord.UserID][cloudTaskRecord.ComputeResource] + int(cloudTaskRecord.Duration)
} else {
resourceItemMap[cloudTaskRecord.UserID][cloudTaskRecord.ComputeResource] = 0
}
if cloudTaskRecord.Type == 1 { //npu
setMapKey("CloudBrainTwo", cloudTaskRecord.UserID, 1, resultItemMap)
@@ -2359,7 +2357,7 @@ func queryCloudBrainTask(start_unix int64, end_unix int64) (map[int64]int, map[s
} else {
setMapKey("NpuDebugJob", cloudTaskRecord.UserID, 1, resultItemMap)
}
} else if cloudTaskRecord.ComputeResource == GPUResource {
} else {
if cloudTaskRecord.JobType == "TRAIN" {
setMapKey("GpuTrainJob", cloudTaskRecord.UserID, 1, resultItemMap)
} else if cloudTaskRecord.JobType == "ONLINEINFERENCE" {


+ 32
- 0
models/user_other_info.go View File

@@ -0,0 +1,32 @@
package models

import (
"code.gitea.io/gitea/modules/timeutil"
)

type UserOtherInfo struct {
ID int64 `xorm:"pk autoincr"`
UId int64 `xorm:"NOT NULL"`
IsNewAgree bool
CreatedUnix timeutil.TimeStamp `xorm:"created"`
}

func GetNewAgreeByUID(uid int64) bool {
userOtherInfo := new(UserOtherInfo)
has, err := xStatistic.Where("u_id=?", uid).Desc("id").Limit(1).Get(userOtherInfo)
if err != nil || !has {
return false
}
return userOtherInfo.IsNewAgree
}

func SaveUserOtherInfoToDb(uid int64) {
statictisSess := xStatistic.NewSession()
defer statictisSess.Close()

userOtherInfo := &UserOtherInfo{
UId: uid,
IsNewAgree: true,
}
statictisSess.Insert(userOtherInfo)
}

+ 1
- 1
models/user_year_summary.go View File

@@ -342,7 +342,7 @@ func queryUserYearModel(start_unix int64, end_unix int64) map[int64]map[string]i
var indexTotal int64
indexTotal = 0
for {
sess.Select("id,user_id,download_count,reference_count").Table("ai_model_manage").Where(cond).OrderBy("id asc").Limit(PAGE_SIZE, int(indexTotal))
sess.Select("id,name,user_id,download_count,reference_count").Table("ai_model_manage").Where(cond).OrderBy("id asc").Limit(PAGE_SIZE, int(indexTotal))
aiModelList := make([]*AiModelManage, 0)
sess.Find(&aiModelList)
log.Info("query user year AiModelManage size=" + fmt.Sprint(len(aiModelList)))


+ 1
- 1
modules/base/tool.go View File

@@ -224,7 +224,7 @@ func SizedAvatarLinkWithDomain(email string, size int) string {

// FileSize calculates the file size and generate user-friendly string.
func FileSize(s int64) string {
return humanize.Bytes(uint64(s))
return humanize.IBytes(uint64(s))
}

// PrettyNumber produces a string form of the given number in base 10 with


+ 1
- 1
modules/context/context.go View File

@@ -302,7 +302,6 @@ func Contexter() macaron.Handler {
})))
return
}

// Get user from session if logged in.
ctx.User, ctx.IsBasicAuth = auth.SignedInUser(ctx.Context, ctx.Session)

@@ -314,6 +313,7 @@ func Contexter() macaron.Handler {
ctx.Data["SignedUserName"] = ctx.User.Name
ctx.Data["IsAdmin"] = ctx.User.IsAdmin
ctx.Data["IsOperator"] = ctx.User.IsOperator
ctx.Data["IsNewAgree"] = models.GetNewAgreeByUID(ctx.User.ID)
c.Data["SignedUserName"] = ctx.User.Name
} else {
ctx.Data["SignedUserID"] = int64(0)


+ 24
- 14
modules/git/repo_stats_custom.go View File

@@ -100,21 +100,25 @@ func GetUserKPIStats(repoPath string, startTime time.Time, endTime time.Time) (m
CommitLines: 0,
}
}

usersKPIStatses[email].Commits++
default: // Changed file
//Log.Info("code commit file=" + l)
if parts := strings.Fields(l); len(parts) >= 3 {
if parts[0] != "-" {
if c, err := strconv.ParseInt(strings.TrimSpace(parts[0]), 10, 64); err == nil {
usersKPIStatses[email].CommitLines += c
if isCodeFile(parts[2]) {
if parts[0] != "-" {
if c, err := strconv.ParseInt(strings.TrimSpace(parts[0]), 10, 64); err == nil {
usersKPIStatses[email].CommitLines += c
}
}
}
if parts[1] != "-" {
if c, err := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64); err == nil {
usersKPIStatses[email].CommitLines += c
if parts[1] != "-" {
if c, err := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64); err == nil {
usersKPIStatses[email].CommitLines += c
}
}
if usersKPIStatses[email].CommitLines > 100000 {
Log.Info("count code more than 100000, email=" + email + " lines=" + fmt.Sprint(usersKPIStatses[email].CommitLines) + " repo=" + repoPath)
}
}

}
}
}
@@ -123,12 +127,18 @@ func GetUserKPIStats(repoPath string, startTime time.Time, endTime time.Time) (m

}

//获取一天内的用户贡献指标
func getUserKPIStats(repoPath string) (map[string]*UserKPIStats, error) {
timeUntil := time.Now()
oneDayAgo := timeUntil.AddDate(0, 0, -1)
var (
codePostfix []string = []string{".py", ".go", ".js", ".html", ".css", ".c", ".cpp", ".h", ".hpp", ".java", ".sql", ".php", ".rb", ".vue", ".yml", ".swift", ".kt", ".sh", ".pl", ".rs", ".lua", ".ts", ".m"}
)

return GetUserKPIStats(repoPath, oneDayAgo, oneDayAgo)
func isCodeFile(name string) bool {
lowerName := strings.ToLower(name)
for _, v := range codePostfix {
if strings.HasSuffix(lowerName, v) {
return true
}
}
return false
}

func SetRepoKPIStats(repoPath string, fromTime time.Time, stats *RepoKPIStats, newContributers map[string]struct{}) error {


+ 3
- 0
modules/notebook/contentManager.go View File

@@ -185,6 +185,9 @@ func getJupyterBaseUrl(url string) string {
if strings.HasSuffix(url, "lab") {
baseUrl = url[0 : jupyterUrlLength-len(path.Base(url))]
}
if !strings.HasSuffix(baseUrl, "/") {
baseUrl = baseUrl + "/"
}

return baseUrl
}


+ 10
- 4
modules/setting/setting.go View File

@@ -838,7 +838,10 @@ var (
TensorFlowNpuBootFile string
TensorFlowGpuBootFile string
ConvertRepoPath string
GPU_Resource_Specs_ID int
GPU_Resource_Specs_ID string
GPU_AiCenter_Code string
GPU_Spec_ID int64
GPU_Spec_AccCardType string
NPU_FlavorCode string
NPU_PoolID string
NPU_MINDSPORE_IMAGE_ID int
@@ -1842,7 +1845,7 @@ func getModelSafetyConfig() {

func getModelConvertConfig() {
sec := Cfg.Section("model_convert")
ModelConvert.GPU_PYTORCH_IMAGE = sec.Key("GPU_PYTORCH_IMAGE").MustString("dockerhub.pcl.ac.cn:5000/user-images/openi:tensorRT_7_zouap")
ModelConvert.GPU_PYTORCH_IMAGE = sec.Key("GPU_PYTORCH_IMAGE").MustString("192.168.204.28:5000/default-workspace/99280a9940ae44ca8f5892134386fddb/image:tensorrt_8.0_for_c2net_1")
ModelConvert.GpuQueue = sec.Key("GpuQueue").MustString("openidgx")
ModelConvert.GPU_TENSORFLOW_IMAGE = sec.Key("GPU_TENSORFLOW_IMAGE").MustString("dockerhub.pcl.ac.cn:5000/user-images/openi:tf2onnx")
ModelConvert.NPU_MINDSPORE_16_IMAGE = sec.Key("NPU_MINDSPORE_16_IMAGE").MustString("swr.cn-south-222.ai.pcl.cn/openi/mindspore1.8.1_train_openi_new:v1")
@@ -1852,13 +1855,16 @@ func getModelConvertConfig() {
ModelConvert.TensorFlowNpuBootFile = sec.Key("TensorFlowNpuBootFile").MustString("convert_tensorflow.py")
ModelConvert.TensorFlowGpuBootFile = sec.Key("TensorFlowGpuBootFile").MustString("convert_tensorflow_gpu.py")
ModelConvert.ConvertRepoPath = sec.Key("ConvertRepoPath").MustString("https://openi.pcl.ac.cn/zouap/npu_test")
ModelConvert.GPU_Resource_Specs_ID = sec.Key("GPU_Resource_Specs_ID").MustInt(1)
ModelConvert.GPU_Resource_Specs_ID = sec.Key("GPU_Resource_Specs_ID").MustString("e677036134cd11ed9c2a06e51cc0c06b")
ModelConvert.GPU_AiCenter_Code = sec.Key("GPU_AiCenter_Code").MustString("cloudbrain1")
ModelConvert.GPU_Spec_ID = sec.Key("GPU_Spec_ID").MustInt64(183)
ModelConvert.GPU_Spec_AccCardType = sec.Key("GPU_Spec_AccCardType").MustString("A100")
ModelConvert.NPU_FlavorCode = sec.Key("NPU_FlavorCode").MustString("modelarts.bm.910.arm.public.1")
ModelConvert.NPU_PoolID = sec.Key("NPU_PoolID").MustString("pool7908321a")
ModelConvert.NPU_MINDSPORE_IMAGE_ID = sec.Key("NPU_MINDSPORE_IMAGE_ID").MustInt(37)
ModelConvert.NPU_TENSORFLOW_IMAGE_ID = sec.Key("NPU_TENSORFLOW_IMAGE_ID").MustInt(38)
ModelConvert.GPU_PADDLE_IMAGE = sec.Key("GPU_PADDLE_IMAGE").MustString("dockerhub.pcl.ac.cn:5000/user-images/openi:paddle2.3.0_gpu_cuda11.2_cudnn8")
ModelConvert.GPU_MXNET_IMAGE = sec.Key("GPU_MXNET_IMAGE").MustString("dockerhub.pcl.ac.cn:5000/user-images/openi:mxnet191cu_cuda102_py37")
ModelConvert.GPU_MXNET_IMAGE = sec.Key("GPU_MXNET_IMAGE").MustString("192.168.204.22:5000/default-workspace/99280a9940ae44ca8f5892134386fddb/image:mxnet191cu_cuda102_py37_c2net")
ModelConvert.PaddleOnnxBootFile = sec.Key("PaddleOnnxBootFile").MustString("convert_paddle.py")
ModelConvert.MXnetOnnxBootFile = sec.Key("MXnetOnnxBootFile").MustString("convert_mxnet.py")
}


+ 2
- 2
modules/templates/helper.go View File

@@ -105,7 +105,7 @@ func NewFuncMap() []template.FuncMap {
return setting.UI.Reactions
},
"DebugAttachSize": func() int {
return setting.DebugAttachSize * 1000 * 1000 * 1000
return setting.DebugAttachSize * 1024 * 1024 * 1024
},
"LlmCommonKB": func() string {
return setting.LLM_CHAT_API.COMMON_KB
@@ -796,7 +796,7 @@ func buildSubjectBodyTemplate(stpl *texttmpl.Template, btpl *template.Template,

// Dataset categories
func categories() []string {
return []string{"computer_vision", "natural_language_processing", "speech_processing", "computer_vision_natural_language_processing"}
return []string{"computer_vision", "natural_language_processing", "speech_processing", "computer_vision_natural_language_processing", "medical_imaging"}
}

func licenses() []string {


+ 12
- 3
options/locale/locale_en-US.ini View File

@@ -416,7 +416,13 @@ change_email = Change email
change_email_address = Change email address
new_email_address = New email address
openi_community_really_awesome = OpenI, Really Awesome!

protocol_header=Please read the following content carefully:
protocol_title=Dear OpenI User
protocol_context=Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you check and agree, you can continue to use our services. Thank you for your cooperation and understanding.
protocol_context_sub=For more agreement content, please refer to the<u><font color="# 3291f8"><a href="/home/term" target="_blank">《Openl Qizhi Community AI Collaboration Platform Usage Agreement》</a></font></u>
protocol_confirm=Agree and continue
protocol_cancel=Disagree, exit
protocol_update=Reading protocol updates
[phone]
format_err=The format of phone number is wrong.
query_err=Fail to query phone number, please try again later.
@@ -955,6 +961,7 @@ category.computer_vision= computer vision
category.natural_language_processing= natural language processing
category.speech_processing= speech processing
category.computer_vision_natural_language_processing= computer vision and natural language processing
category.medical_imaging = medical imaging
attachment.delete= Delete this version of dataset
attachment.delete_desc= Are you sure you will delete this version of dataset, once deleted can not be recovery
public= public
@@ -1300,7 +1307,7 @@ cloudbrain.morethanonejob2=You can view all your Cloud Brain tasks in <a href="/
modelarts.online_infer = Online Inference
modelarts.infer_job_model = Model
modelarts.infer_job_model_file = Model File
modelarts.infer_job = Inference Job
modelarts.infer_job = Inference Task
modelarts.infer_job.model_version = Model/Version
modelarts.infer_job.select_model = Select Model
modelarts.infer_job.boot_file_helper=The startup file is the entry file for your program execution and must end in.py.Such as inference.py, main.py, example/inference.py, case/main.py.
@@ -1324,7 +1331,7 @@ successfully_deleted = Successfully deleted

debug_task_not_created = Debug task has not been created
train_task_not_created = Train task has not been created
inference_job_not_created = Inference job has not been created
inference_job_not_created = Inference task has not been created
model_Evaluation_not_created = Model evaluation has not been created
repo_not_initialized = Code version: You have not initialized the code repository, please <a href="%s"> initialized </a> first ;
debug_task_running_limit =Running time: no more than 4 hours, it will automatically stop if it exceeds 4 hours;
@@ -3228,6 +3235,8 @@ task_c2ent_onlineinferjob=`created GPU type online inference task <a href="%s/gr
task_c2net_cpusupercomputejob=`created CPU type HPC task <a href="%s/supercompute/job/%s">%s</a>`
task_nputrainjob=`created NPU training task <a href="%s/modelarts/train-job/%s">%s</a>`
task_inferencejob=`created reasoning task <a href="%s/modelarts/inference-job/%s">%s</a>`
task_c2net_gpu_inferencejob=`created GPU type inference task <a href="%s/grampus/inference-job/%s">%s</a>`
task_c2net_gpgpu_iluvatar_inferencejob=`created ILUVATAR-GPGPU type inference task <a href="%s/grampus/inference-job/%s">%s</a>`
task_benchmark=`created profiling task <a href="%s/cloudbrain/benchmark/%s">%s</a>`
task_createmodel=`created new model <a href="%s/modelmanage/model_readme_tmpl?name=%s">%s</a>`
task_gputrainjob=`created CPU/GPU training task <a href="%s/cloudbrain/train-job/%s">%s</a>`


+ 10
- 1
options/locale/locale_zh-CN.ini View File

@@ -419,7 +419,13 @@ change_email=修改邮箱
change_email_address=修改邮箱地址
new_email_address=新邮箱地址
openi_community_really_awesome=启智社区 确实给力

protocol_header=请仔细阅读下方内容:
protocol_title=尊敬的启智用户
protocol_context=感谢您一直以来对Openl启智社区AI协作平台的支持。为了保障您的使用权益和确保网络安全,我们于2024年1月份更新了《Openl启智社区AI协作平台使用协议》。更新后的协议明确了用户<font color="#ff2525">禁止使用内网穿透工具</font>的条例。在您勾选同意后,便可以继续使用我们的服务。感谢您的合作与理解。
protocol_context_sub=更多协议内容,请参考<u><font color="#3291f8"><a href="/home/term" target="_blank">《Openl启智社区AI协作平台使用协议》</a></font></u>
protocol_confirm=同意并继续
protocol_cancel=不同意,退出
protocol_update=阅读协议更新
[phone]
format_err=手机号格式错误。
query_err=查询手机号失败,请稍后再试。
@@ -959,6 +965,7 @@ category.computer_vision=计算机视觉
category.natural_language_processing=自然语言处理
category.speech_processing=语音处理
category.computer_vision_natural_language_processing=计算机视觉、自然语言处理
category.medical_imaging = 医学影像
attachment.delete= 删除该版本的数据集
attachment.delete_desc= 你确定要删除该版本的数据集么?一旦删除不能恢复。
public=公有
@@ -3247,6 +3254,8 @@ task_c2ent_onlineinferjob=`创建了GPU类型在线推理任务 <a href="%s/gram
task_c2net_cpusupercomputejob=`创建了CPU类型超算任务 <a href="%s/supercompute/job/%s">%s</a>`
task_nputrainjob=`创建了NPU类型训练任务 <a href="%s/modelarts/train-job/%s">%s</a>`
task_inferencejob=`创建了推理任务 <a href="%s/modelarts/inference-job/%s">%s</a>`
task_c2net_gpu_inferencejob=`创建了GPU类型推理任务 <a href="%s/grampus/inference-job/%s">%s</a>`
task_c2net_gpgpu_iluvatar_inferencejob=`创建了ILUVATAR-GPGPU类型推理任务 <a href="%s/grampus/inference-job/%s">%s</a>`
task_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>`
task_createmodel=`导入了新模型 <a href="%s/modelmanage/model_readme_tmpl?name=%s">%s</a>`
task_gputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/cloudbrain/train-job/%s">%s</a>`


+ 18
- 4
public/home/home.js View File

@@ -243,8 +243,8 @@ document.onreadystatechange = function () {
html += recordPrefix + actionName;
html += " <a href=\"" + getRepoLink(record) + "\" rel=\"nofollow\">" + getRepotext(record) + "</a>"
}
else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "30"
|| record.OpType == "31" || record.OpType == "32" || record.OpType == "33" || record.OpType == "42" || record.OpType == "44"){
else if(record.OpType == "24" || record.OpType == "26" || record.OpType == "27" || record.OpType == "28" || record.OpType == "50" || record.OpType == "51"
|| record.OpType == "30" || record.OpType == "31" || record.OpType == "32" || record.OpType == "33" || record.OpType == "42" || record.OpType == "44"){
html += recordPrefix + actionName;
const taskLink = getTaskLink(record);
if (taskLink) {
@@ -311,7 +311,17 @@ function getTaskLink(record){
re = '';
}
}else if(record.OpType == 28){
re = re + "/modelarts/inference-job/" + record.Content;
if (record.Cloudbrain) {
re = re + "/modelarts/inference-job/" + record.Cloudbrain.ID;
} else {
re = '';
}
}else if(record.OpType == 50 || record.OpType == 51){
if (record.Cloudbrain) {
re = re + "/grampus/inference-job/" + record.Cloudbrain.ID;
} else {
re = '';
}
}else if(record.OpType == 29){
re = re + "/cloudbrain/benchmark/" + record.Content;
}else if(record.OpType == 30){
@@ -487,6 +497,8 @@ var actionNameZH={
"26":"创建了NPU类型调试任务",
"27":"创建了NPU类型训练任务",
"28":"创建了推理任务",
"50":"创建了GPU类型推理任务",
"51":"创建了ILUVATAR-GPGPU类型推理任务",
"29":"创建了评测任务",
"30":"导入了新模型",
"31":"创建了CPU/GPU类型训练任务",
@@ -528,7 +540,9 @@ var actionNameEN={
"25":" created CPU/GPU type debugging task ",
"26":" created NPU type debugging task ",
"27":" created NPU type training task",
"28":" created reasoning task",
"28":" created inference task",
"50":" created GPU type inference task",
"51":" created ILUVATAR-GPGPU type inference task",
"29":" created profiling task",
"30":" created new model",
"31":" created CPU/GPU type training task",


+ 2
- 0
public/home/search.js View File

@@ -346,6 +346,7 @@ var categoryDesc = {
natural_language_processing: "自然语言处理",
speech_processing: "语音处理",
computer_vision_natural_language_processing: "计算机视觉、自然语言处理",
medical_imaging: "医学影像",
};

var categoryENDesc = {
@@ -354,6 +355,7 @@ var categoryENDesc = {
speech_processing: "speech processing",
computer_vision_natural_language_processing:
"computer vision and natural language processing",
medical_imaging: "medical imaging",
};

var taskDesc = {


+ 1
- 1
routers/api/v1/api.go View File

@@ -1321,7 +1321,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/download_model_convert_resultfile", repo.DownloadModeConvertResultFile)

m.Get("/:id", repo.GetCloudbrainModelConvertTask)
m.Get("/:id/log", repo.CloudbrainForModelConvertGetLog)
m.Get("/:id/log", repo.GrampusForModelConvertGetLog)
m.Get("/:id/modelartlog", repo.TrainJobForModelConvertGetLog)
m.Get("/:id/model_list", repo.CloudBrainModelConvertList)
}, reqRepoReader(models.UnitTypeModelManage))


+ 3
- 225
routers/api/v1/repo/cloudbrain.go View File

@@ -166,7 +166,7 @@ func CreateFileNotebookTask(ctx *context.Context, option api.CreateFileNotebookJ
imageUrl := setting.FileNoteBook.ImageGPU
imageId := ""
imageName := imageUrl
cluster := entity.OpenICloudbrainOne
cluster := entity.C2Net

if option.Type == 0 {
specId = setting.FileNoteBook.SpecIdCPU
@@ -283,13 +283,12 @@ func GetFileNoteBookInfo(ctx *context.APIContext) {
}

var specCPU, specGpu, specNPU, specNPUCD *api.SpecificationShow
var specGpuQueueCode string
for _, spec := range specs {
if spec.ID == setting.FileNoteBook.SpecIdCPU {
specCPU = convert.ToSpecification(spec)
} else if spec.ID == setting.FileNoteBook.SpecIdGPU {
specGpu = convert.ToSpecification(spec)
specGpuQueueCode = spec.QueueCode
} else if spec.ID == setting.FileNoteBook.SpecIdNPU {
specNPU = convert.ToSpecification(spec)
} else if spec.ID == setting.FileNoteBook.SpecIdNPUCD {
@@ -299,14 +298,7 @@ func GetFileNoteBookInfo(ctx *context.APIContext) {

waitCountNpu := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "")

queuesMap, err := cloudbrain.GetQueuesDetail()
var waitCountGPU int
if err != nil {
log.Error("Fail to query gpu queues waiting count", err)
waitCountGPU = 0
} else {
waitCountGPU = (*queuesMap)[specGpuQueueCode]
}
waitCountGPU := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.GPUResource, models.JobTypeDebug)

var a *models.PointAccount
if ctx.User != nil {
@@ -659,145 +651,6 @@ func InferencJobResultList(ctx *context.APIContext) {

}

func GetCloudbrainModelConvertTask(ctx *context.APIContext) {
var (
err error
)
ID := ctx.Params(":id")
job, err := models.QueryModelConvertById(ID)
if err != nil {
ctx.NotFound(err)
log.Error("GetCloudbrainByID failed:", err)
return
}
if job.IsGpuTrainTask() {
jobResult, err := cloudbrain.GetJob(job.CloudBrainTaskId)
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
}

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.ModelComputeAndSetDuration(job, result)
err = models.UpdateModelConvert(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"),
})
} else {

result, err := modelarts.GetTrainJob(job.CloudBrainTaskId, job.ModelArtsVersionId)
if err != nil {
log.Error("get modelart job failed:", err)
ctx.NotFound(err)
return
}

job.Status = modelarts.TransTrainJobStatus(result.IntStatus)
job.RunTime = result.Duration / 1000
job.TrainJobDuration = models.ConvertDurationToStr(job.RunTime)
err = models.UpdateModelConvert(job)
if err != nil {
log.Error("UpdateJob failed:", err)
}

ctx.JSON(http.StatusOK, map[string]interface{}{
"ID": ID,
"JobStatus": job.Status,
})

}

}

func CloudbrainGetLogByJobId(jobId string, jobName string) map[string]interface{} {
var hits []models.Hits
result, err := cloudbrain.GetJobLog(jobId)
if err != nil {
log.Error("GetJobLog failed: %v", err)
return nil
}
hits = result.Hits.Hits

//if the size equal page_size, then take the scroll_id to get all log and delete the scroll_id(the num of scroll_id is limited)
if len(result.Hits.Hits) >= cloudbrain.LogPageSize {
for {
resultNext, err := cloudbrain.GetJobAllLog(result.ScrollID)
if err != nil {
log.Error("GetJobAllLog failed: %v", err)
} else {
for _, hit := range resultNext.Hits.Hits {
hits = append(hits, hit)
}
}

if len(resultNext.Hits.Hits) < cloudbrain.LogPageSize {
log.Info("get all log already")
break
}
}
}

cloudbrain.DeleteJobLogToken(result.ScrollID)

sort.Slice(hits, func(i, j int) bool {
return hits[i].Sort[0] < hits[j].Sort[0]
})

var content string
for _, log := range hits {
content += log.Source.Message + "\n"
}

return map[string]interface{}{
"JobName": jobName,
"Content": content,
}

}

func CloudbrainForModelConvertGetLog(ctx *context.Context) {
ID := ctx.Params(":id")
job, err := models.QueryModelConvertById(ID)
if err != nil {
log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"])
ctx.ServerError(err.Error(), err)
return
}

result := CloudbrainGetLogByJobId(job.CloudBrainTaskId, job.Name)
if result == nil {
log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"])
ctx.ServerError(err.Error(), err)
return
}
ctx.JSON(http.StatusOK, result)
}

func ModelSafetyGetLog(ctx *context.APIContext) {
ID := ctx.Params(":id")
job, err := models.GetCloudbrainByID(ID)
@@ -1248,81 +1101,6 @@ func getLogFromModelDir(jobName string, startLine int, endLine int, resultPath s
}
}

func CloudBrainModelConvertList(ctx *context.APIContext) {
ID := ctx.Params(":id")
parentDir := ctx.Query("parentDir")
dirArray := strings.Split(parentDir, "/")
var versionName = "V0001"

job, err := models.QueryModelConvertById(ID)
if err != nil {
log.Error("GetCloudbrainByJobID(%s) failed:%v", job.Name, err.Error())
ctx.ServerError("GetModelDirs failed:", err)
return
}
result, err := QueryModelConvertResultFileList(ctx, ID)
if err == nil {
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobID": job.ID,
"VersionName": versionName,
"StatusOK": 0,
"Path": dirArray,
"Dirs": result,
"task": job,
"PageIsCloudBrain": true,
})
} else {
log.Error("GetCloudbrainByJobID failed:%v", err.Error())
ctx.ServerError("GetModelDirs failed:", err)
return
}
}

func QueryModelConvertResultFileList(ctx *context.APIContext, id string) ([]storage.FileInfo, error) {
ID := id
parentDir := ctx.Query("parentDir")
job, err := models.QueryModelConvertById(ID)
if err != nil {
log.Error("GetCloudbrainByJobID(%s) failed:%v", job.Name, err.Error())
return nil, err
}
if job.IsGpuTrainTask() {
//get dirs
dirs, err := routerRepo.GetModelDirs(job.ID, parentDir)
if err != nil {
log.Error("GetModelDirs failed:%v", err.Error(), ctx.Data["msgID"])
return nil, err
}

var fileInfos []storage.FileInfo
err = json.Unmarshal([]byte(dirs), &fileInfos)
if err != nil {
log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"])
return nil, err
}

for i, fileInfo := range fileInfos {
temp, _ := time.Parse("2006-01-02 15:04:05", fileInfo.ModTime)
fileInfos[i].ModTime = temp.Local().Format("2006-01-02 15:04:05")
}

sort.Slice(fileInfos, func(i, j int) bool {
return fileInfos[i].ModTime > fileInfos[j].ModTime
})

return fileInfos, nil
} else {
var versionName = "V0001"
models, err := storage.GetObsListObject(job.ID, "output/", parentDir, versionName)
if err != nil {
log.Info("get TrainJobListModel failed:", err)
return nil, err
}
return models, nil
}

}

func CloudBrainModelList(ctx *context.APIContext) {
var jobID = ctx.Params(":jobid")
var versionName = ctx.Query("version_name")


+ 264
- 0
routers/api/v1/repo/modelmanage.go View File

@@ -1,14 +1,27 @@
package repo

import (
"encoding/json"
"fmt"
"net/http"
"sort"
"strings"
"time"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/convert"
"code.gitea.io/gitea/modules/grampus"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/redis/redis_key"
"code.gitea.io/gitea/modules/redis/redis_lock"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
routerRepo "code.gitea.io/gitea/routers/repo"
"code.gitea.io/gitea/services/ai_task_service/schedule"
)

type FileInfo struct {
@@ -204,3 +217,254 @@ func DeleteModelFile(ctx *context.APIContext) {
log.Info("DeleteModelFile by api.")
routerRepo.DeleteModelFile(ctx.Context)
}

func GetCloudbrainModelConvertTask(ctx *context.APIContext) {
var (
err error
)
ID := ctx.Params(":id")
job, err := models.QueryModelConvertById(ID)
if err != nil {
ctx.NotFound(err)
log.Error("GetCloudbrainByID failed:", err)
return
}
if job.IsGpuTrainTask() {
jobResult, err := grampus.GetJob(job.CloudBrainTaskId)
if err != nil {
ctx.NotFound(err)
log.Error("GetJob failed:", err)
return
}
jobResultJson, _ := json.Marshal(jobResult)
log.Info("grampus jobResultJson=" + string(jobResultJson))

if jobResult.JobInfo.Status == models.GrampusStatusPending || jobResult.JobInfo.Status == "" {
job.Status = models.GrampusStatusWaiting
} else {
job.Status = strings.ToUpper(jobResult.JobInfo.Status)
}
if jobResult.JobInfo.CompletedAt > 0 {
job.EndTime = timeutil.TimeStamp(jobResult.JobInfo.CompletedAt)
}
if strings.ToUpper(jobResult.JobInfo.Status) != models.GrampusStatusWaiting && jobResult.JobInfo.Status != models.GrampusStatusPending {
models.ModelConvertSetDuration(job)
err = models.UpdateModelConvert(job)
if err != nil {
log.Error("UpdateJob failed:", err)
}
}
doGrampusModelConvertMigrate(jobResult.JobInfo.Status, job)
ctx.JSON(http.StatusOK, map[string]interface{}{
"ID": ID,
"JobName": jobResult.JobInfo.Name,
"JobStatus": job.Status,
"SubState": "",
"CreatedTime": time.Unix(jobResult.JobInfo.CreatedAt, 0).Format("2006-01-02 15:04:05"),
"CompletedTime": time.Unix(jobResult.JobInfo.CompletedAt, 0).Format("2006-01-02 15:04:05"),
})
} else {

result, err := modelarts.GetTrainJob(job.CloudBrainTaskId, job.ModelArtsVersionId)
if err != nil {
log.Error("get modelart job failed:", err)
ctx.NotFound(err)
return
}

job.Status = modelarts.TransTrainJobStatus(result.IntStatus)
job.RunTime = result.Duration / 1000
job.TrainJobDuration = models.ConvertDurationToStr(job.RunTime)
err = models.UpdateModelConvert(job)
if err != nil {
log.Error("UpdateJob failed:", err)
}

ctx.JSON(http.StatusOK, map[string]interface{}{
"ID": ID,
"JobStatus": job.Status,
})

}

}

func GrampusTaskGetLogByJobId(jobId string, jobName string) map[string]interface{} {
var content string
result, err := grampus.GetTrainJobLog(jobId)
if err != nil {
log.Error("GetJobLog failed: %v", err)
content = ""
} else {
content = result
}
return map[string]interface{}{
"JobName": jobName,
"Content": content,
}
}

func GrampusForModelConvertGetLog(ctx *context.Context) {
ID := ctx.Params(":id")
job, err := models.QueryModelConvertById(ID)
if err != nil {
log.Error("GetCloudbrainByJobName failed: %v", err, ctx.Data["MsgID"])
ctx.ServerError(err.Error(), err)
return
}

result := GrampusTaskGetLogByJobId(job.CloudBrainTaskId, job.Name)
if result == nil {
log.Error("GetJobLog failed: %v", err, ctx.Data["MsgID"])
ctx.ServerError(err.Error(), err)
return
}
ctx.JSON(http.StatusOK, result)
}

func CloudBrainModelConvertList(ctx *context.APIContext) {
ID := ctx.Params(":id")
parentDir := ctx.Query("parentDir")
dirArray := strings.Split(parentDir, "/")
var versionName = "V0001"

job, err := models.QueryModelConvertById(ID)
if err != nil {
log.Error("GetCloudbrainByJobID(%s) failed:%v", job.Name, err.Error())
ctx.ServerError("GetModelDirs failed:", err)
return
}
result, err := QueryModelConvertResultFileList(ctx, ID)
if err == nil {
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobID": job.ID,
"VersionName": versionName,
"StatusOK": 0,
"Path": dirArray,
"Dirs": result,
"task": job,
"PageIsCloudBrain": true,
})
} else {
log.Error("GetCloudbrainByJobID failed:%v", err.Error())
ctx.ServerError("GetModelDirs failed:", err)
return
}
}

func QueryModelConvertResultFileList(ctx *context.APIContext, id string) ([]storage.FileInfo, error) {
ID := id
parentDir := ctx.Query("parentDir")
job, err := models.QueryModelConvertById(ID)
if err != nil {
log.Error("GetCloudbrainByJobID(%s) failed:%v", job.Name, err.Error())
return nil, err
}
if job.IsGpuTrainTask() {
//get dirs
dirs, err := routerRepo.GetModelDirs(job.ID, parentDir)
if err != nil {
log.Error("GetModelDirs failed:%v", err.Error(), ctx.Data["msgID"])
return nil, err
}

var fileInfos []storage.FileInfo
err = json.Unmarshal([]byte(dirs), &fileInfos)
if err != nil {
log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"])
return nil, err
}

for i, fileInfo := range fileInfos {
temp, _ := time.Parse("2006-01-02 15:04:05", fileInfo.ModTime)
fileInfos[i].ModTime = temp.Local().Format("2006-01-02 15:04:05")
}

sort.Slice(fileInfos, func(i, j int) bool {
return fileInfos[i].ModTime > fileInfos[j].ModTime
})

return fileInfos, nil
} else {
var versionName = "V0001"
models, err := storage.GetObsListObject(job.ID, "output/", parentDir, versionName)
if err != nil {
log.Info("get TrainJobListModel failed:", err)
return nil, err
}
return models, nil
}

}

func doGrampusModelConvertMigrate(status string, job *models.AiModelConvert) error {
if strings.ToUpper(status) == models.GrampusStatusSucceeded {
if job.StatusResult != "MIGRATE_SUCCEED" {
lock := redis_lock.NewDistributeLock(redis_key.RecordHandleLock(job.CloudBrainTaskId))
success, err := lock.Lock(60 * time.Second)
if err != nil {
log.Error("HandleUnfinishedMigrateRecord lock err.ID=%d %v", job.CloudBrainTaskId, err)
return err
}
if !success {
log.Error("HandleUnfinishedMigrateRecord lock failed.ID=%d ", job.CloudBrainTaskId)
return nil
}
//todo migrate
grampus.PostModelMigrate(job.CloudBrainTaskId)
go dealModelConvertModelMigrate(job)
}
}

return nil
}

func dealModelConvertModelMigrate(job *models.AiModelConvert) {
count := 0
for {
if count > 20 {
break
}
log.Info("deal count= " + fmt.Sprint(count))
if updateModelMigrateStatus(job) {
count++
time.Sleep(3 * time.Second)
} else {
break
}
}
}

func updateModelMigrateStatus(job *models.AiModelConvert) bool {
res, err := grampus.ModelMigrateInfo(job.CloudBrainTaskId)
if err != nil {
log.Error("ModelMigrateInfo err. r.ID=%d %v", job.CloudBrainTaskId, err)
return true
}
log.Info("model migrate status=" + fmt.Sprint(res.Status))
status := models.GrampusMigrateResponse(res.Status).ConvertToModelMigrateStep()
if status == models.GrampusMigrateSuccess {
log.Info("start to move grampus bucket to minio")
//to move bucket
if err := schedule.MoveBucketInOpenIMinio(res.DestObjectKey, grampus.GetGPUModelObjectKey(job.ID), res.DestBucket, setting.Attachment.Minio.Bucket); err != nil {
log.Error("MoveBucketInOpenIMinio err.%v", err)
} else {
models.UpdateResultMigrateFlag(job.ID, "MIGRATE_SUCCEED")
}
return false
}
if status == models.GrampusMigrateFailed || status == models.GrampusMigrateNoNeed {
return false
}
return true
}

func getModelMigrateStatusFromGrampus(jobId string) models.ModelMigrateStep {
res, err := grampus.ModelMigrateInfo(jobId)
if err != nil {
log.Error("ModelMigrateInfo err. r.ID=%d %v", jobId, err)
return -1
}
log.Info("model convert ModelMigrateInfo r.ID=%d res=%+v", jobId, res)
return models.GrampusMigrateResponse(res.Status).ConvertToModelMigrateStep()
}

+ 5
- 6
routers/card_request/card_request.go View File

@@ -14,7 +14,6 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
cardrequestservice "code.gitea.io/gitea/services/card_request"
"golang.org/x/exp/slices"
)

func GetCreationInfo(ctx *context.Context) {
@@ -111,7 +110,7 @@ func GetAdminCardRequestList(ctx *context.Context) {
}

func CreateCardRequest(ctx *context.Context, cardReq api.CardReq) {
data, err := cardrequestservice.GetCreationInfo()
/**data, err := cardrequestservice.GetCreationInfo()
if err != nil {
log.Error("can not get creation info", err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
@@ -126,14 +125,14 @@ func CreateCardRequest(ctx *context.Context, cardReq api.CardReq) {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.parameter_is_wrong")))
return
}
}
}*/

if cardReq.ResourceType != models.RESOURCE_TYPE_SHARE && cardReq.ResourceType != models.RESOURCE_TYPE_EXCLUSIVE {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.parameter_is_wrong")))
return
}

err = cardrequestservice.CreateCardRequest(cardReq, ctx.User.ID)
err := cardrequestservice.CreateCardRequest(cardReq, ctx.User.ID)
if err != nil {
log.Error("can not create card request", err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("card_request.create_fail")))
@@ -182,7 +181,7 @@ func UpdateCardRequest(ctx *context.Context, cardReq api.CardReq) {
return
}

data, err := cardrequestservice.GetCreationInfo()
/**data, err := cardrequestservice.GetCreationInfo()
if err != nil {
log.Error("can not get creation info", err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(err.Error()))
@@ -197,7 +196,7 @@ func UpdateCardRequest(ctx *context.Context, cardReq api.CardReq) {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.parameter_is_wrong")))
return
}
}
}*/

if cardReq.ResourceType != models.RESOURCE_TYPE_SHARE && cardReq.ResourceType != models.RESOURCE_TYPE_EXCLUSIVE {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.parameter_is_wrong")))


+ 348
- 78
routers/repo/ai_model_convert.go View File

@@ -12,6 +12,8 @@ import (
"path"
"strings"

"code.gitea.io/gitea/entity"
"code.gitea.io/gitea/manager/client/grampus"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/context"
@@ -21,6 +23,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/services/ai_task_service/storage_helper"
uuid "github.com/satori/go.uuid"
)

@@ -34,7 +37,7 @@ const (
MXNET_ENGINE = 6
ModelMountPath = "/model"
CodeMountPath = "/code"
DataSetMountPath = "/dataset"
DataSetMountPath = "/tmp/dataset"
LogFile = "log.txt"
DefaultBranchName = "master"
SubTaskName = "task1"
@@ -205,7 +208,6 @@ func createNpuTrainJob(modelConvert *models.AiModelConvert, ctx *context.Context
return err
}
deleteLocalDir(codeLocalPath)

intputshape := strings.Split(modelConvert.InputShape, ",")
n := "256"
c := "1"
@@ -416,12 +418,22 @@ func createGpuTrainJob(modelConvert *models.AiModelConvert, ctx *context.Context
}

log.Info("command=" + command)

codePath := setting.JobPath + modelConvert.ID + CodeMountPath
downloadConvertCode(setting.ModelConvert.ConvertRepoPath, codePath, DefaultBranchName)
codeTmpPath := setting.JobPath + modelConvert.ID + CodeMountPath + "tmp"
uploader := storage_helper.SelectUploaderFromStorageType(entity.MINIO)
codeRemoteDir := path.Join(uploader.GetJobDefaultObjectKeyPrefix(modelConvert.ID), "code")
log.Info("codePath=" + codePath)
log.Info("codeTmpPath=" + codeTmpPath)
log.Info("codeRemoteDir=" + codeRemoteDir)

downloadConvertCode(setting.ModelConvert.ConvertRepoPath, codeTmpPath, DefaultBranchName)

Zip(codePath+"/master.zip", codeTmpPath)

uploadCodeToMinio(codePath+"/", modelConvert.ID, CodeMountPath+"/")

deleteLocalDir(codePath)
deleteLocalDir(codeTmpPath)

minioCodePath := setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + modelConvert.ID + "/code"
log.Info("minio codePath=" + minioCodePath)
@@ -436,73 +448,330 @@ func createGpuTrainJob(modelConvert *models.AiModelConvert, ctx *context.Context
minioModelPath := setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + modelConvert.ID + "/model"
log.Info("minio model path=" + minioModelPath)

if TrainResourceSpecs == nil {
json.Unmarshal([]byte(setting.TrainResourceSpecs), &TrainResourceSpecs)
}
resourceSpec := TrainResourceSpecs.ResourceSpec[setting.ModelConvert.GPU_Resource_Specs_ID]
jobResult, err := cloudbrain.CreateJob(modelConvert.ID, models.CreateJobParams{
JobName: modelConvert.ID,
RetryCount: 1,
GpuType: setting.ModelConvert.GpuQueue,
Image: IMAGE_URL,
TaskRoles: []models.TaskRole{
{
Name: SubTaskName,
TaskNumber: 1,
MinSucceededTaskCount: 1,
MinFailedTaskCount: 1,
CPUNumber: resourceSpec.CpuNum,
GPUNumber: resourceSpec.GpuNum,
MemoryMB: resourceSpec.MemMiB,
ShmMB: resourceSpec.ShareMemMiB,
Command: command,
NeedIBDevice: false,
IsMainRole: false,
UseNNI: false,
},
},
Volumes: []models.Volume{
{
HostPath: models.StHostPath{
Path: minioCodePath,
MountPath: CodeMountPath,
ReadOnly: false,
datasetRemoteDir := path.Join(uploader.GetJobDefaultObjectKeyPrefix(modelConvert.ID), "dataset")

outputRemoteDir := path.Join(uploader.GetJobDefaultObjectKeyPrefix(modelConvert.ID), "model")

datasetDirectoryObjectKey := datasetRemoteDir
if !strings.HasSuffix(datasetRemoteDir, "/") {
datasetDirectoryObjectKey = datasetRemoteDir + "/"
}
codeObjectKey := codeRemoteDir + "/master.zip"
log.Info("codeObjectKey=" + codeObjectKey)
log.Info("uploader.GetRealPath(codeObjectKey)=" + uploader.GetRealPath(codeObjectKey))

req := entity.CreateTrainTaskRequest{
Name: modelConvert.ID,
DisplayJobName: modelConvert.Name,
Description: "",
TaskConfig: getGrampusTrainTaskConfig(),
Tasks: []entity.TrainTask{{
Command: command,
Name: modelConvert.ID,
ResourceSpecId: setting.ModelConvert.GPU_Resource_Specs_ID, //toDO
ImageId: "", //form.ImageID,
ImageUrl: IMAGE_URL,
Datasets: []entity.ContainerData{
entity.ContainerData{
ContainerPath: DataSetMountPath,
Name: "dataset",
ReadOnly: false,
ObjectKey: datasetDirectoryObjectKey,
RealPath: uploader.GetRealPath(datasetRemoteDir),
Bucket: uploader.GetBucket(),
EndPoint: uploader.GetEndpoint(),
GetBackEndpoint: uploader.GetEndpoint(),
IsDir: true,
StorageType: entity.MINIO,
},
},
{
HostPath: models.StHostPath{
Path: dataActualPath,
MountPath: DataSetMountPath,
ReadOnly: true,
Code: []entity.ContainerData{
entity.ContainerData{
Name: strings.ToLower(ctx.Repo.Repository.Name),
Bucket: uploader.GetBucket(),
EndPoint: uploader.GetEndpoint(),
ObjectKey: codeObjectKey,
ReadOnly: true,
ContainerPath: "/tmp/code/master.zip",
RealPath: uploader.GetRealPath(codeObjectKey),
IsDir: true,
S3DownloadUrl: uploader.GetS3DownloadUrl(codeObjectKey),
StorageType: entity.MINIO,
},
},
{
HostPath: models.StHostPath{
Path: minioModelPath,
MountPath: ModelMountPath,
ReadOnly: false,
Queues: []models.ResourceQueue{
models.ResourceQueue{
AiCenterCode: setting.ModelConvert.GPU_AiCenter_Code,
},
},
},
})
PreTrainModel: nil,
BootFile: "",
OutPut: []entity.ContainerData{{
ContainerPath: "/tmp/output",
ReadOnly: false,
ObjectKey: outputRemoteDir,
RealPath: uploader.GetRealPath(outputRemoteDir),
Bucket: uploader.GetBucket(),
EndPoint: uploader.GetEndpoint(),
GetBackEndpoint: uploader.GetEndpoint(),
IsDir: true,
StorageType: entity.MINIO,
}},
Params: models.Parameters{},
Spec: &models.Specification{
ID: setting.ModelConvert.GPU_Spec_ID,
SourceSpecId: setting.ModelConvert.GPU_Resource_Specs_ID,
AccCardsNum: 1,
AccCardType: setting.ModelConvert.GPU_Spec_AccCardType,
ComputeResource: "GPU",
AiCenterCode: setting.ModelConvert.GPU_AiCenter_Code,
},
RepoName: ctx.Repo.Repository.Name,
WorkServerNumber: 1,
}},
}

reqJson, _ := json.Marshal(req)
log.Info("reqJson=" + string(reqJson))

jobResult, err := createGrampusTrainJob(req, command)

if err != nil {
log.Error("CreateJob failed:", err.Error(), ctx.Data["MsgID"])
models.UpdateModelConvertFailed(modelConvert.ID, "FAILED", err.Error())
return err
}
if jobResult.Code != Success {
log.Error("CreateJob(%s) failed:%s", modelConvert.ID, jobResult.Msg, ctx.Data["MsgID"])
models.UpdateModelConvertFailed(modelConvert.ID, "FAILED", err.Error())
return errors.New(jobResult.Msg)
jobResultJson, _ := json.Marshal(jobResult)
log.Info("jobResultJson=" + string(jobResultJson))

if jobResult.ErrorCode != 0 {
log.Error("CreateJob(%s) failed:%s", modelConvert.ID, jobResult.ErrorMsg, ctx.Data["MsgID"])
models.UpdateModelConvertFailed(modelConvert.ID, "FAILED", jobResult.ErrorMsg)
return errors.New(jobResult.ErrorMsg)
}

var jobID = jobResult.Payload["jobId"].(string)
var jobID = jobResult.JobInfo.JobID
log.Info("jobId=" + jobID)
models.UpdateModelConvertCBTI(modelConvert.ID, jobID)

return nil
}

func getGrampusTrainTaskConfig() *entity.AITaskBaseConfig {
codePath := "/tmp/code"
datasetPath := "/tmp/dataset"
pretrainModelPath := "/tmp/pretrainmodel"
outputPath := "/tmp/output"
var config = &entity.AITaskBaseConfig{
ContainerSteps: map[entity.ContainerDataType]*entity.ContainerBuildOpts{
entity.ContainerCode: {
ContainerPath: codePath,
StorageRelativePath: cloudbrain.CodeMountPath,
ReadOnly: false,
AcceptStorageType: []entity.StorageType{entity.MINIO, entity.OBS},
},
entity.ContainerDataset: {
ContainerPath: datasetPath,
ReadOnly: true,
AcceptStorageType: []entity.StorageType{entity.MINIO, entity.OBS},
},
entity.ContainerPreTrainModel: {
ContainerPath: pretrainModelPath,
ReadOnly: true,
AcceptStorageType: []entity.StorageType{entity.MINIO, entity.OBS},
},
entity.ContainerOutPutPath: {
ContainerPath: outputPath,
StorageRelativePath: cloudbrain.ModelMountPath,
ReadOnly: false,
AcceptStorageType: []entity.StorageType{entity.MINIO},
MKDIR: false,
},
},
}
config.ActionType = models.ActionCreateGrampusGPUTrainTask
config.IsActionUseJobId = true
return config
}

func createGrampusTrainJob(req entity.CreateTrainTaskRequest, exeCommand string) (*models.CreateGrampusJobResponse, error) {
jobResult, err := grampus.CreateJob(convertTrainReq2Grampus(req, exeCommand))
if err != nil {
log.Error("CreateNoteBook failed: %v", err.Error())
return nil, err
}
return jobResult, nil
}

func convertTrainReq2Grampus(req entity.CreateTrainTaskRequest, exeCommand string) models.CreateGrampusJobRequest {
command := generateGrampusTrainCommand(req, exeCommand)

tasks := make([]models.GrampusTasks, len(req.Tasks))
for i := 0; i < len(req.Tasks); i++ {
t := req.Tasks[i]
tasks[i] = convertTrainTask2Grampus(t, command)
}

return models.CreateGrampusJobRequest{Name: req.Name, Tasks: tasks}
}

func convertTrainTask2Grampus(t entity.TrainTask, command string) models.GrampusTasks {
return models.GrampusTasks{
Name: t.Name,
ResourceSpecId: t.ResourceSpecId,
ImageId: t.ImageId,
ImageUrl: t.ImageUrl,
Datasets: convertContainerArray2GrampusArray(t.Datasets),
Code: convertContainerArray2Grampus(t.Code),
Command: command,
CenterID: []string{t.Queues[0].AiCenterCode},
ReplicaNum: 1,
Models: convertContainerArray2GrampusArray(t.PreTrainModel),
BootFile: t.BootFile,
OutPut: convertContainerArray2Grampus(t.OutPut),
WorkServerNumber: t.WorkServerNumber,
}
}

func convertContainerArray2GrampusArray(containerDatas []entity.ContainerData) []models.GrampusDataset {
res := make([]models.GrampusDataset, len(containerDatas))
for i := 0; i < len(containerDatas); i++ {
d := containerDatas[i]
res[i] = convertContainer2Grampus(d)
}
return res
}

func convertContainerArray2Grampus(containerDatas []entity.ContainerData) models.GrampusDataset {
res := models.GrampusDataset{}
if containerDatas != nil && len(containerDatas) > 0 {
res = convertContainer2Grampus(containerDatas[0])
}
return res
}

func convertContainer2Grampus(d entity.ContainerData) models.GrampusDataset {
return models.GrampusDataset{
Name: d.Name,
Bucket: d.Bucket,
EndPoint: d.EndPoint,
ObjectKey: d.ObjectKey,
ContainerPath: d.ContainerPath,
ReadOnly: d.ReadOnly,
GetBackEndpoint: d.GetBackEndpoint,
Size: d.Size,
}
}

func generateGrampusTrainCommand(req entity.CreateTrainTaskRequest, exeCommand string) string {
t := req.Tasks[0]
containerConfig := req.TaskConfig
computeResource := t.Spec.ComputeResource
var codePath = containerConfig.GetContainerPath(entity.ContainerCode)
var modelPath = containerConfig.GetContainerPath(entity.ContainerPreTrainModel)
var datasetPath = containerConfig.GetContainerPath(entity.ContainerDataset)
var outputPath = containerConfig.GetContainerPath(entity.ContainerOutPutPath)

builder := &entity.CommandBuilder{}
builder.
//mkdir dirs
Add(buildMkdirCommand(codePath, modelPath, datasetPath, outputPath)).
//unzip code
Add(buildUnzipCodeCommand(codePath, t.Code[0].ContainerPath, computeResource)).
//unzip dataset
Add(buildUnzipDatasetCommand(t.Datasets, datasetPath, computeResource)).
//export
Add(buildExportCommand(req.Name, computeResource)).
//exec code
Add(buildExeCommand(exeCommand))

return builder.ToString()
}
func buildExeCommand(exeCommand ...string) *entity.CommandBuilder {
builder := &entity.CommandBuilder{}
for _, dir := range exeCommand {
builder.Next(entity.NewCommand(dir))
}
return builder
}

func buildMkdirCommand(dirs ...string) *entity.CommandBuilder {
builder := &entity.CommandBuilder{}
for _, dir := range dirs {
builder.Next(entity.NewCommand("mkdir", "-p", dir))
}
return builder
}

func buildUnzipCodeCommand(codeConfigPath, codeFilePath, computeSource string) *entity.CommandBuilder {
builder := &entity.CommandBuilder{}
if computeSource == models.NPU {
return builder
}
builder.
Next(entity.NewCommand("echo", "'start to unzip code'")).
Next(entity.NewCommand("cd", codeConfigPath)).
Next(entity.NewCommand("unzip", "-q", codeFilePath)).
Next(entity.NewCommand("echo", "'unzip code finished'")).
Next(entity.NewCommand("ls", "-l")).
Next(entity.NewCommand("ls", "-l", "mnist_pytorchexample_gpu"))
return builder
}
func buildUnzipDatasetCommand(datasets []entity.ContainerData, datasetPath, computeSource string) *entity.CommandBuilder {
builder := &entity.CommandBuilder{}
if computeSource == models.NPU {
return builder
}
if len(datasets) == 0 {
return nil
}
builder.Next(entity.NewCommand("cd", datasetPath)).
Next(entity.NewCommand("echo", "'start to unzip datasets'"))

fileDatasets := make([]entity.ContainerData, 0)
for _, dataset := range datasets {
if !dataset.IsDir {
fileDatasets = append(fileDatasets, dataset)
}
}
//单数据集
if len(fileDatasets) == 1 {
if strings.HasSuffix(fileDatasets[0].Name, ".tar.gz") {
builder.Next(entity.NewCommand("tar", "--strip-components=1", "-zxvf", "'"+fileDatasets[0].Name+"'"))
} else {
builder.Next(entity.NewCommand("unzip", "-q", "'"+fileDatasets[0].Name+"'"))
}
builder.Next(entity.NewCommand("ls", "-l"))
builder.Next(entity.NewCommand("echo", "'unzip datasets finished'"))
return builder
}
//多数据集
for i := 0; i < len(fileDatasets); i++ {
name := fileDatasets[i].Name
if strings.HasSuffix(name, ".tar.gz") {
builder.Next(entity.NewCommand("tar", "-zxvf", name))
} else {
builder.Next(entity.NewCommand("unzip", "-q", "'"+name+"'", "-d", "'./"+strings.TrimSuffix(name, ".zip")+"'"))
}
}
builder.Next(entity.NewCommand("ls", "-l"))
builder.Next(entity.NewCommand("echo", "'unzip datasets finished'"))
return builder
}

func buildExportCommand(jobName, computeResource string) *entity.CommandBuilder {
builder := &entity.CommandBuilder{}

if computeResource == models.NPU {
outputRemotePath := setting.CodePathPrefix + jobName + modelarts.OutputPath
builder.Next(entity.NewCommand("export", "bucket="+setting.Grampus.Env, "&&", "export", "remote_path="+outputRemotePath))
} else {
outputRemotePath := setting.CBCodePathPrefix + jobName + cloudbrain.ModelMountPath + "/"
builder.Next(entity.NewCommand("export", "env="+setting.Grampus.Env, "&&", "export", "remote_path="+outputRemotePath))
}
return builder
}

func deleteLocalDir(dirpath string) {
//TODO delete
_err := os.RemoveAll(dirpath)
@@ -527,15 +796,13 @@ func getGpuModelConvertCommand(name string, modelFile string, modelConvert *mode
h = inputshape[2]
w = inputshape[3]
}
command += "python3 /code/" + bootfile + " --model " + modelFile + " --n " + n + " --c " + c + " --h " + h + " --w " + w
command += "list -all /tmp/code;list -all /tmp/dataset;python3 /tmp/code/" + bootfile + " --model " + modelFile + " --n " + n + " --c " + c + " --h " + h + " --w " + w
if modelConvert.DestFormat == CONVERT_FORMAT_TRT {
if modelConvert.NetOutputFormat == NetOutputFormat_FP16 {
command += " --fp16 True"
} else {
command += " --fp16 False"
}
}
command += " > " + ModelMountPath + "/" + name + "-" + LogFile
command += " > /tmp/output/" + name + "-" + LogFile
return command
}

@@ -557,9 +824,13 @@ func DeleteModelConvert(ctx *context.Context) {

func deleteCloudBrainTask(task *models.AiModelConvert) {
if task.IsGpuTrainTask() {
log.Info("delete cloudbrain one resource.")
log.Info("delete grampus model convert task.")
_, err := grampus.DeleteJob(task.CloudBrainTaskId)
if err != nil {
log.Error("Delete grampus job failed:%v", err)
}
dirPath := setting.CBCodePathPrefix + task.ID + "/"
err := storage.Attachments.DeleteDir(dirPath)
err = storage.Attachments.DeleteDir(dirPath)
if err != nil {
log.Error("DeleteDir(%s) failed:%v", dirPath, err)
}
@@ -579,7 +850,7 @@ func stopModelConvert(id string) error {
return err
}
if job.IsGpuTrainTask() {
err = cloudbrain.StopJob(job.CloudBrainTaskId)
_, err = grampus.StopJob(job.CloudBrainTaskId)
if err != nil {
log.Error("Stop cloudbrain Job(%s) failed:%v", job.CloudBrainTaskId, err)
}
@@ -662,34 +933,33 @@ func ShowModelConvertInfo(ctx *context.Context) {
ctx.HTML(200, tplModelConvertInfo)
return
}
result, err := cloudbrain.GetJob(job.CloudBrainTaskId)
jobResult, err := grampus.GetJob(job.CloudBrainTaskId)
if err != nil {
log.Info("error:" + err.Error())
ctx.Data["error"] = err.Error()
ctx.HTML(200, tplModelConvertInfo)
return
}
if result != nil {
jobRes, _ := models.ConvertToJobResultPayload(result.Payload)
ctx.Data["result"] = jobRes
taskRoles := jobRes.TaskRoles
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
ctx.Data["taskRes"] = taskRes
ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics
ctx.Data["AppExitDiagnostics"] = jobRes.JobStatus.AppExitDiagnostics

job.Status = jobRes.JobStatus.State

if jobRes.JobStatus.State != string(models.JobWaiting) && jobRes.JobStatus.State != string(models.JobFailed) {
job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP
job.ContainerID = taskRes.TaskStatuses[0].ContainerID
job.Status = taskRes.TaskStatuses[0].State
jobEvent, err := grampus.GetTrainJobEvents(job.CloudBrainTaskId)
jobEventJson, _ := json.Marshal(jobEvent)
log.Info("jobEventJson=" + string(jobEventJson))
if jobEvent != nil {
ctx.Data["AppExitDiagnostics"] = string(jobEventJson)
}
if jobResult != nil {
ctx.Data["ExitDiagnostics"] = jobResult.ExitDiagnostics
if jobResult.JobInfo.Status == models.GrampusStatusPending {
job.Status = models.GrampusStatusWaiting
} else {
job.Status = strings.ToUpper(jobResult.JobInfo.Status)
}
if jobRes.JobStatus.State != string(models.JobWaiting) {
models.ModelComputeAndSetDuration(job, jobRes)
job.StartTime = timeutil.TimeStamp(jobResult.JobInfo.StartedAt)
job.EndTime = timeutil.TimeStamp(jobResult.JobInfo.CompletedAt)
if strings.ToUpper(jobResult.JobInfo.Status) != models.GrampusStatusWaiting && jobResult.JobInfo.Status != models.GrampusStatusPending {
models.ModelConvertSetDuration(job)
err = models.UpdateModelConvert(job)
if err != nil {
log.Error("UpdateModelConvert failed:", err)
log.Error("UpdateJob failed:", err)
}
}
}


+ 10
- 12
routers/repo/cloudbrain.go View File

@@ -114,10 +114,10 @@ func cloudBrainNewDataPrepare(ctx *context.Context, jobType string) error {
ctx.Data["benchmark_categories"] = categories.Category

ctx.Data["benchmark_types"] = GetBenchmarkTypes(ctx).BenchmarkType
queuesDetail, _ := cloudbrain.GetQueuesDetail()
if queuesDetail != nil {
ctx.Data["QueuesDetail"] = queuesDetail
}
// queuesDetail, _ := cloudbrain.GetQueuesDetail()
// if queuesDetail != nil {
// ctx.Data["QueuesDetail"] = queuesDetail
// }

prepareCloudbrainOneSpecs(ctx)

@@ -325,7 +325,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
for _, infos := range datasetInfos {
attachSize += infos.Size
}
if attachSize > int64(setting.DebugAttachSize*1000*1000*1000) {
if attachSize > int64(setting.DebugAttachSize*1024*1024*1024) {
log.Error("The DatasetSize exceeds the limit (%dGB)", setting.DebugAttachSize) // GB
cloudBrainNewDataPrepare(ctx, jobType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.debug_datasetsize", setting.DebugAttachSize), tpl, &form)
@@ -2438,7 +2438,8 @@ func CloudBrainBenchmarkNew(ctx *context.Context) {
ctx.ServerError("get new cloudbrain info failed", err)
return
}
ctx.HTML(200, tplCloudBrainBenchmarkNew)
//ctx.HTML(200, tplCloudBrainBenchmarkNew)
ctx.HTML(200, tplCloudBrainModelSafetyNewNpu)
}

func getBenchmarkAttachment(benchmarkTypeID, benchmarkChildTypeID int, ctx *context.Context) (*models.BenchmarkDataset, error) {
@@ -3008,16 +3009,13 @@ func cloudBrainTrainJobCreate(ctx *context.Context) {
}

func InferenceCloudBrainJobNew(ctx *context.Context) {
err := cloudBrainNewDataPrepare(ctx, string(models.JobTypeInference))
if err != nil {
ctx.ServerError("get new train-job info failed", err)
return
}
ctx.Data["PageIsCloudBrain"] = true
ctx.HTML(http.StatusOK, tplCloudBrainInferenceJobNew)
}

func InferenceCloudBrainJobShow(ctx *context.Context) {
cloudBrainShow(ctx, tplCloudBrainInferenceJobShow, models.JobTypeInference)
ctx.Data["PageIsCloudBrain"] = true
ctx.HTML(http.StatusOK, tplCloudBrainInferenceJobShow)
}

func DownloadGPUInferenceResultFile(ctx *context.Context) {


+ 16
- 2
routers/repo/grampus.go View File

@@ -67,9 +67,23 @@ const (
tplGrampusTrainJobMLUNew base.TplName = "repo/grampus/trainjob/mlu/new"

//C2NET notebook
tplGrampusNotebookNew base.TplName = "repo/grampus/notebook/new"
tplGrampusNotebookNew base.TplName = "repo/grampus/notebook/new"

// Inference job
tplGrampusInferenceNew base.TplName = "repo/grampus/inference/new"
tplGrampusInferenceShow base.TplName = "repo/grampus/inference/show"
)

func GrampusInferenceNew(ctx *context.Context) {
ctx.Data["PageIsCloudBrain"] = true
ctx.HTML(http.StatusOK, tplGrampusInferenceNew)
}

func GrampusInferenceShow(ctx *context.Context) {
ctx.Data["PageIsCloudBrain"] = true
ctx.HTML(http.StatusOK, tplGrampusInferenceShow)
}

func GrampusNotebookNew(ctx *context.Context) {
ctx.Data["PageIsCloudBrain"] = true
ctx.HTML(http.StatusOK, tplGrampusNotebookNew)
@@ -256,7 +270,7 @@ func GrampusNotebookCreate(ctx *context.Context, form auth.CreateGrampusNotebook
for _, infos := range datasetInfos {
attachSize += infos.Size
}
if attachSize > int64(setting.DebugAttachSize*1000*1000*1000) {
if attachSize > int64(setting.DebugAttachSize*1024*1024*1024) {
log.Error("The DatasetSize exceeds the limit (%dGB)", setting.DebugAttachSize) // GB
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.debug_datasetsize", setting.DebugAttachSize), tpl, &form)


+ 2
- 138
routers/repo/modelarts.go View File

@@ -254,7 +254,7 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm
for _, infos := range datasetInfos {
attachSize += infos.Size
}
if attachSize > int64(setting.DebugAttachSize*1000*1000*1000) {
if attachSize > int64(setting.DebugAttachSize*1024*1024*1024) {
log.Error("The DatasetSize exceeds the limit (%dGB)", setting.DebugAttachSize) //GB
notebookNewDataPrepare(ctx)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.debug_datasetsize", setting.DebugAttachSize), tplModelArtsNotebookNew, &form)
@@ -2544,91 +2544,11 @@ func checkModelArtsSpecialPool(ctx *context.Context, flavorCode string, jobType
return ""
}
func InferenceJobIndex(ctx *context.Context) {
MustEnableModelArts(ctx)

repo := ctx.Repo.Repository
page := ctx.QueryInt("page")
if page <= 0 {
page = 1
}

listType := ctx.Query("listType")
ctx.Data["ListType"] = listType

if listType == models.AllResource {
listType = ""
}

var jobTypes []string
jobTypes = append(jobTypes, string(models.JobTypeInference))
tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{
ListOptions: models.ListOptions{
Page: page,
PageSize: setting.UI.IssuePagingNum,
},
RepoID: repo.ID,
ComputeResource: listType,
JobTypes: jobTypes,
Type: models.TypeCloudBrainAll,
})
if err != nil {
ctx.ServerError("Cloudbrain", err)
return
}

for i, task := range tasks {
tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain)
tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain)
if tasks[i].ComputeResource == "" {
tasks[i].ComputeResource = models.NPUResource
}
if tasks[i].ModelId != "" {
model, err := models.QueryModelById(tasks[i].ModelId)
if err == nil && model != nil {
if model.RepoId != tasks[i].RepoID {
repo, err := models.GetRepositoryByID(model.RepoId)
if err == nil && repo != nil {
tasks[i].ModelRepoName = repo.Name
tasks[i].ModelRepoOwnerName = repo.OwnerName
}
}
}
}
}
isQueryPrivate := isQueryPrivateModel(ctx)
repoId := ctx.Repo.Repository.ID
Type := -1
_, model_count, _ := models.QueryModel(&models.AiModelQueryOptions{
ListOptions: models.ListOptions{
Page: 1,
PageSize: 2,
},
RepoID: repoId,
Type: Type,
New: MODEL_LATEST,
IsOnlyThisRepo: true,
Status: 0,
IsQueryPrivate: isQueryPrivate,
})
ctx.Data["MODEL_COUNT"] = model_count

pager := context.NewPagination(int(count), setting.UI.IssuePagingNum, page, 5)
pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager

ctx.Data["PageIsCloudBrain"] = true
ctx.Data["Tasks"] = tasks
ctx.Data["CanCreate"] = cloudbrain.CanCreateOrDebugJob(ctx)
ctx.Data["RepoIsEmpty"] = repo.IsEmpty
ctx.HTML(200, tplModelArtsInferenceJobIndex)
}
func InferenceJobNew(ctx *context.Context) {
err := inferenceJobNewDataPrepare(ctx)
if err != nil {
ctx.ServerError("get new inference-job info failed", err)
return
}

ctx.Data["PageIsCloudBrain"] = true
ctx.HTML(200, tplModelArtsInferenceJobNew)
}
func inferenceJobNewDataPrepare(ctx *context.Context) error {
@@ -2783,62 +2703,6 @@ func inferenceJobErrorNewDataPrepare(ctx *context.Context, form auth.CreateModel
}
func InferenceJobShow(ctx *context.Context) {
ctx.Data["PageIsCloudBrain"] = true
var jobID = ctx.Params(":jobid")

page := ctx.QueryInt("page")
if page <= 0 {
page = 1
}
task, err := models.GetCloudbrainByJobID(jobID)

if err != nil {
log.Error("GetInferenceTask(%s) failed:%v", jobID, err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}
//设置权限
canNewJob, err := canUserCreateTrainJobVersion(ctx, task.UserID)
if err != nil {
ctx.ServerError("canNewJob failed", err)
return
}
ctx.Data["canNewJob"] = canNewJob

//将运行参数转化为epoch_size = 3, device_target = Ascend的格式
var parameters models.Parameters
err = json.Unmarshal([]byte(task.Parameters), &parameters)
if err != nil {
log.Error("Failed to Unmarshal Parameters: %s (%v)", task.Parameters, err)
trainJobNewDataPrepare(ctx)
return
}

if len(parameters.Parameter) > 0 {
paramTemp := ""
for _, Parameter := range parameters.Parameter {
param := Parameter.Label + " = " + Parameter.Value + "; "
paramTemp = paramTemp + param
}
task.Parameters = paramTemp[:len(paramTemp)-2]
} else {
task.Parameters = ""
}
prepareSpec4Show(ctx, task)
LabelName := strings.Fields(task.LabelName)
ctx.Data["labelName"] = LabelName
ctx.Data["jobID"] = jobID
ctx.Data["jobName"] = task.JobName
ctx.Data["displayJobName"] = task.DisplayJobName
ctx.Data["task"] = task
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task)
ctx.Data["datasetDownload"] = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false)
tempUids := []int64{}
tempUids = append(tempUids, task.UserID)
JobCreater, err := models.GetUserNamesByIDs(tempUids)
if err != nil {
log.Error("GetUserNamesByIDs (WhitelistUserIDs): %v", err)
}
ctx.Data["userName"] = JobCreater[0]
ctx.HTML(http.StatusOK, tplModelArtsInferenceJobShow)
}



+ 2
- 2
routers/repo/repo_statistic.go View File

@@ -15,8 +15,8 @@ import (
)

func StatisticAuto() {
RepoStatisticAuto()
TimingCountData()
go RepoStatisticAuto()
go TimingCountData()
}

//auto daily


+ 6
- 6
routers/repo/user_data_analysis.go View File

@@ -724,12 +724,6 @@ func TimingCountDataByDateAndReCount(date string, isReCount bool) {
startYear := time.Date(USER_YEAR, 1, 1, 0, 0, 0, 1, t.Location())
endYear := startYear.AddDate(1, 0, 0)

if time.Now().Year() == 2024 {
log.Info("the day is 2024,so not update.")
return
}
models.RefreshUserYearTable(startYear, endYear)

//query wiki data
log.Info("start to time count data")
wikiMap, err := queryWikiCountMap(startTime, endTime)
@@ -740,6 +734,12 @@ func TimingCountDataByDateAndReCount(date string, isReCount bool) {
mailer.SendWarnNotifyMail(setting.Warn_Notify_Mails, warnEmailMessage)
}

if time.Now().Year() == 2024 {
log.Info("the day is 2024,so not update.")
return
}
models.RefreshUserYearTable(startYear, endYear)

log.Info("end to count all user info data")
}



+ 97
- 1
routers/repo/util.go View File

@@ -1,7 +1,103 @@
package repo

import "regexp"
import (
"archive/zip"
"io"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"regexp"
)

var NamePattern = regexp.MustCompile(`^[A-Za-z0-9-_\\.]{1,100}$`)

var GrampusNamePattern = regexp.MustCompile(`^[A-Za-z][\w|\-|\\.]{0,49}$`)

// Zip compresses the specified files or dirs to zip archive.
// If a path is a dir don't need to specify the trailing path separator.
// For example calling Zip("archive.zip", "dir", "csv/baz.csv") will get archive.zip and the content of which is
// baz.csv
// dir
// ├── bar.txt
// └── foo.txt
// Note that if a file is a symbolic link it will be skipped.
func Zip(zipPath string, paths string) error {
// Create zip file and it's parent dir.
if err := os.MkdirAll(filepath.Dir(zipPath), os.ModePerm); err != nil {
return err
}
archive, err := os.Create(zipPath)
if err != nil {
return err
}
defer archive.Close()

// New zip writer.
zipWriter := zip.NewWriter(archive)
defer zipWriter.Close()

files, err := ioutil.ReadDir(paths)
if err != nil {
return err
}
// Traverse the file or directory.
for _, file := range files {
// Remove the trailing path separator if path is a directory.
rootPath := filepath.Join(paths, file.Name())

// Visit all the files or directories in the tree.
err = filepath.Walk(rootPath, walkFunc(rootPath, zipWriter))
if err != nil {
return err
}
}
return nil
}

func walkFunc(rootPath string, zipWriter *zip.Writer) filepath.WalkFunc {
return func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}

// If a file is a symbolic link it will be skipped.
if info.Mode()&os.ModeSymlink != 0 {
return nil
}

// Create a local file header.
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}

// Set compression method.
header.Method = zip.Deflate

// Set relative path of a file as the header name.
header.Name, err = filepath.Rel(filepath.Dir(rootPath), path)
if err != nil {
return err
}
if info.IsDir() {
header.Name += string(os.PathSeparator)
}

// Create writer for the file header and save content of the file.
headerWriter, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
if info.IsDir() {
return nil
}
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(headerWriter, f)
return err
}
}

+ 1
- 0
routers/repo/view.go View File

@@ -783,6 +783,7 @@ func renderCode(ctx *context.Context) {
}
ctx.Data["Title"] = title
ctx.Data["RequireHighlightJS"] = true
ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror

branchLink := ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
treeLink := branchLink


+ 10
- 2
routers/routes/routes.go View File

@@ -370,6 +370,8 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/home/notice", routers.HomeNoticeTmpl)
m.Get("/home/privacy", routers.HomePrivacy)

m.Post("/user/saveOtherInfo", user.SaveUserOtherInfo, reqSignIn)

m.Group("/modelsquare", func() {
m.Get("/main", repo.ModelSquareTmpl)
m.Get("/main_query_data", repo.ModelSquareData)
@@ -404,7 +406,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/demand", routers.ComputingPowerDemand)
m.Get("/domestic", routers.ComputingPowerDomestic)
}, ignSignIn)
operationReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, OperationRequired: true})
m.Group("/explore", func() {
m.Get("", func(ctx *context.Context) {
@@ -474,7 +476,6 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/login/cloud_brain", user.SignInCloudBrain)
m.Post("/login/cloud_brain", bindIgnErr(auth.SignInForm{}), user.SignInCloudBrainPost)
m.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost)

m.Get("/login/phone", user.SignInPhone)
m.Post("/login/phone", bindIgnErr(auth.PhoneNumberCodeForm{}), user.SignInPhonePost)
m.Group("", func() {
@@ -1388,6 +1389,13 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateGrampusTrainJobForm{}), context.PointAccount(), repo.GrampusTrainJobGcuCreate)
})
})

m.Group("/inference-job", func() {
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, context.PointAccount(), repo.GrampusInferenceNew)
m.Group("/:id", func() {
m.Get("", reqRepoCloudBrainReader, repo.GrampusInferenceShow)
})
})
}, context.RepoRef())
m.Group("/modelmanage", func() {
m.Get("/create_local_model", repo.CreateLocalModel)


+ 48
- 5
routers/user/auth.go View File

@@ -76,12 +76,10 @@ func AutoSignIn(ctx *context.Context) (bool, error) {
if !models.HasEngine {
return false, nil
}

uname := ctx.GetCookie(setting.CookieUserName)
if len(uname) == 0 {
return false, nil
}

isSucceed := false
defer func() {
if !isSucceed {
@@ -98,12 +96,10 @@ func AutoSignIn(ctx *context.Context) (bool, error) {
}
return false, nil
}

if val, ok := ctx.GetSuperSecureCookie(
base.EncodeMD5(u.Rands+u.Passwd), setting.CookieRememberName); !ok || val != u.Name {
return false, nil
}

isSucceed = true

// Set session IDs
@@ -116,7 +112,8 @@ func AutoSignIn(ctx *context.Context) (bool, error) {
if err := ctx.Session.Release(); err != nil {
return false, err
}

log.Info("Auto login succeed.")
models.SaveLoginInfoToDb(ctx.Req.Request, u)
ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true)
return true, nil
}
@@ -195,6 +192,51 @@ func setRSAContext(ctx *context.Context) {
}
}

func GetUserOtherInfo(ctx *context.Context) {
userName := ctx.Query("userName")
phone := ctx.Query("phone")
var err error
var user *models.User
if userName != "" {
user, err = models.GetUserByName(userName)
}
if phone != "" {
user, err = models.GetUserByPhoneNumber(phone)
}
re := make(map[string]interface{}, 0)
if err != nil || user == nil {
re["result_code"] = "-1"
ctx.JSON(200, re)
} else {
re["result_code"] = "0"
re["agree"] = models.GetNewAgreeByUID(user.ID)
ctx.JSON(200, re)
}
}

func SaveUserOtherInfo(ctx *context.Context) {
userName := ctx.Query("userName")
phone := ctx.Query("phone")
var err error
var user *models.User
if userName != "" {
user, err = models.GetUserByName(userName)
}
if phone != "" {
user, err = models.GetUserByPhoneNumber(phone)
}
re := make(map[string]interface{}, 0)
if err != nil || user == nil {
re["result_code"] = "-1"
ctx.JSON(200, re)
} else {
re["result_code"] = "0"
models.SaveUserOtherInfoToDb(user.ID)
ctx.Data["IsNewAgree"] = true
ctx.JSON(200, re)
}
}

// SignInCloudBrain render sign in page
func SignInCloudBrain(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")
@@ -254,6 +296,7 @@ func SignInPhonePost(ctx *context.Context, form auth.PhoneNumberCodeForm) {
}
return
}

models.SaveLoginInfoToDb(ctx.Req.Request, u)

handleSignIn(ctx, u, form.Remember)


+ 3
- 1
services/ai_task_service/cluster/c2net.go View File

@@ -36,6 +36,7 @@ func (c C2NetClusterAdapter) CreateNoteBook(req entity.CreateNoteBookTaskRequest
newReq, err := convertNoteBookReq2Grampus(req)
if err != nil {
log.Error("CreateNoteBook err.req=%+v err=%v", req, err)
return nil, err
}
jobResult, err := grampus.CreateNotebookJob(newReq)
if err != nil {
@@ -316,6 +317,7 @@ func convertContainer2Grampus(d entity.ContainerData) models.GrampusDataset {
ReadOnly: d.ReadOnly,
GetBackEndpoint: d.GetBackEndpoint,
Size: d.Size,
IsOverwrite: d.IsOverwrite,
}
}

@@ -777,7 +779,7 @@ func (c C2NetClusterAdapter) DeleteTrainJob(opts entity.JobIdAndVersionId) error
}

func (c C2NetClusterAdapter) StopTrainJob(opts entity.JobIdAndVersionId) error {
_, err := grampus.StopJob(opts.JobID, string(models.JobTypeDebug))
_, err := grampus.StopJob(opts.JobID)
if err != nil {
log.Error("StopNoteBook(%s) failed:%v", opts, err)
return err


+ 5
- 0
services/ai_task_service/cluster/cloudbrain_two.go View File

@@ -482,6 +482,11 @@ func handleCloudbrainTwoParameter(req entity.CreateTrainTaskRequest) models.Para
})
}

param.Parameter = append(param.Parameter, models.Parameter{
Label: modelarts.ResultUrl,
Value: t.OutPut[0].S3DownloadUrl,
})

existDeviceTarget := false
for _, parameter := range t.Params.Parameter {
if parameter.Label == modelarts.DeviceTarget {


+ 12
- 2
services/ai_task_service/container_builder/code_builder.go View File

@@ -1,6 +1,11 @@
package container_builder

import (
"path"
"strings"

"code.gitea.io/gitea/models"

"code.gitea.io/gitea/entity"
"code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/log"
@@ -8,8 +13,6 @@ import (
"code.gitea.io/gitea/routers/response"
"code.gitea.io/gitea/services/ai_task_service/context"
"code.gitea.io/gitea/services/ai_task_service/storage_helper"
"path"
"strings"
)

type CodeBuilder struct {
@@ -57,6 +60,13 @@ func (b *CodeBuilder) Build(ctx *context.CreationContext) ([]entity.ContainerDat
return nil, response.LOAD_CODE_FAILED
}
}
if ctx.Request.IsFileNoteBookRequest && ctx.Request.Cluster == entity.C2Net && ctx.Request.ComputeSource.Name == models.GPU {
err := uploader.MKDIR(remoteDir)
if err != nil {
log.Error("MKDIR err.displayJobName = %s err=%v", ctx.Request.DisplayJobName, err)
return nil, response.LOAD_CODE_FAILED
}
}

var codeArchiveName, objectKey string
if !b.Opts.Uncompressed && !b.Opts.VolumeFolder {


+ 3
- 1
services/ai_task_service/container_builder/output_path_builder.go View File

@@ -1,13 +1,14 @@
package container_builder

import (
"path"

"code.gitea.io/gitea/entity"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/routers/response"
"code.gitea.io/gitea/services/ai_task_service/context"
"code.gitea.io/gitea/services/ai_task_service/storage_helper"
"path"
)

type OutputPathBuilder struct {
@@ -67,6 +68,7 @@ func (b *OutputPathBuilder) Build(ctx *context.CreationContext) ([]entity.Contai
GetBackEndpoint: uploader.GetEndpoint(),
IsDir: true,
StorageType: storageTypes[0],
S3DownloadUrl: uploader.GetS3DownloadUrl(remoteDir),
}}, nil
}



+ 1
- 0
services/ai_task_service/container_builder/pre_model_builder.go View File

@@ -104,6 +104,7 @@ func (b *PretrainModelBuilder) Build(ctx *context.CreationContext) ([]entity.Con
S3DownloadUrl: uploader.GetS3DownloadUrl(preTrainModelPath),
IsDir: false,
Size: size,
IsOverwrite: true,
}
preTrainModelEntity = append(preTrainModelEntity, modelData)
}


+ 139
- 0
services/ai_task_service/task/cloudbrain_two_inference_task.go View File

@@ -0,0 +1,139 @@
package task

import (
"strings"

"code.gitea.io/gitea/entity"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/routers/response"
"code.gitea.io/gitea/services/ai_task_service/context"
)

type CloudbrainTwoInferenceTaskTemplate struct {
DefaultAITaskTemplate
}

func init() {
t := &CloudbrainTwoInferenceTaskTemplate{
DefaultAITaskTemplate: DefaultAITaskTemplate{
ClusterType: entity.OpenICloudbrainTwo,
JobType: models.JobTypeInference,
Config: GetCloudbrainTwoInferenceConfig,
},
}
RegisterTask(models.JobTypeInference, entity.OpenICloudbrainTwo, t)
}

func GetCloudbrainTwoInferenceConfig(opts entity.AITaskConfigKey) *entity.AITaskBaseConfig {
var config = &entity.AITaskBaseConfig{
ActionType: models.ActionCreateInferenceTask,
IsActionUseJobId: true,
ContainerSteps: map[entity.ContainerDataType]*entity.ContainerBuildOpts{
entity.ContainerCode: {
ContainerPath: "/code",
ReadOnly: false,
AcceptStorageType: []entity.StorageType{entity.OBS},
Uncompressed: true,
},
entity.ContainerDataset: {
ContainerPath: "/dataset",
ReadOnly: true,
Uncompressed: true,
AcceptStorageType: []entity.StorageType{entity.OBS},
},
entity.ContainerPreTrainModel: {
ContainerPath: "/pretrainmodel",
ReadOnly: true,
AcceptStorageType: []entity.StorageType{entity.OBS},
},
entity.ContainerOutPutPath: {
ContainerPath: "/output",
StorageRelativePath: "/output" + models.CloudbrainTwoDefaultVersion,
ReadOnly: false,
AcceptStorageType: []entity.StorageType{entity.OBS},
MKDIR: true,
},
entity.ContainerLogPath: {
ContainerPath: "/log",
StorageRelativePath: "/log" + models.CloudbrainTwoDefaultVersion,
ReadOnly: false,
AcceptStorageType: []entity.StorageType{entity.OBS},
MKDIR: true,
},
},
}
return config
}

func (t CloudbrainTwoInferenceTaskTemplate) Create(ctx *context.CreationContext) (*entity.CreateTaskRes, *response.BizError) {
c := &CreateOperator{}
err := c.Next(t.CheckParamFormat).
Next(t.HandleReqParameters).
Next(t.CheckPrivilege4Continue).
Next(t.CheckSourceTaskIsCleared).
Next(t.CheckWorkerNum).
Next(t.CheckMultiRequest).
Next(t.CheckBranchExists).
Next(t.CheckBootFile).
Next(t.CheckDisplayJobName).
Next(t.LoadSpec).
Next(t.CheckPointBalance).
Next(t.CheckDatasets).
Next(t.CheckModel).
Next(t.InsertCloudbrainRecord4Async).
AsyncNextWithErrFun(t.BuildContainerData, t.GetAvailableQueues, t.CallCreationAPI, t.AfterCallCreationAPI4Async, t.NotifyCreation, t.HandleErr4Async).
Operate(ctx)
if err != nil {
log.Error("create GrampusInferenceTask err.%v", err)
return nil, err
}
return &entity.CreateTaskRes{ID: ctx.NewCloudbrain.ID}, nil
}

func (g CloudbrainTwoInferenceTaskTemplate) CallCreationAPI(ctx *context.CreationContext) *response.BizError {
c := g.GetMyCluster()
if c == nil {
return response.SYSTEM_ERROR
}
form := ctx.Request
req := entity.CreateTrainTaskRequest{
Name: form.JobName,
DisplayJobName: form.DisplayJobName,
Description: form.Description,
Tasks: []entity.TrainTask{
{
Name: form.JobName,
ResourceSpecId: ctx.Spec.SourceSpecId,
ImageId: form.ImageID,
ImageUrl: strings.TrimSpace(form.ImageUrl),
Datasets: ctx.GetContainerDataArray(entity.ContainerDataset),
Code: ctx.GetContainerDataArray(entity.ContainerCode),
LogPath: ctx.GetContainerDataArray(entity.ContainerLogPath),
Queues: ctx.Queues,
PreTrainModel: ctx.GetContainerDataArray(entity.ContainerPreTrainModel),
BootFile: form.BootFile,
OutPut: ctx.GetContainerDataArray(entity.ContainerOutPutPath),
Params: form.ParamArray,
Spec: ctx.Spec,
PoolId: ctx.Spec.QueueCode,
WorkServerNumber: form.WorkServerNumber,
},
},
}
createTime := timeutil.TimeStampNow()
res, err := c.CreateTrainJob(req)
if err != nil {
log.Error("CloudbrainTwo InfereceTask Create err.req=%+v err=%v", req, err)
return response.NewBizError(err)
}
ctx.Response = &entity.CreationResponse{
JobID: res.JobID,
Status: res.Status,
CreateTime: createTime,
VersionID: res.VersionID,
VersionName: res.VersionName,
}
return nil
}

+ 144
- 0
services/ai_task_service/task/grampus_inference_task.go View File

@@ -0,0 +1,144 @@
package task

import (
"strings"

"code.gitea.io/gitea/entity"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/routers/response"
"code.gitea.io/gitea/services/ai_task_service/context"
)

type GrampusInferenceTaskTemplate struct {
DefaultAITaskTemplate
}

func init() {
t := &GrampusInferenceTaskTemplate{
DefaultAITaskTemplate: DefaultAITaskTemplate{
ClusterType: entity.C2Net,
JobType: models.JobTypeInference,
Config: GetGrampusInferenceTaskConfig,
},
}
RegisterTask(models.JobTypeInference, entity.C2Net, t)
}

func GetGrampusInferenceTaskConfig(opts entity.AITaskConfigKey) *entity.AITaskBaseConfig {
codePath := "/code"
datasetPath := "/dataset"
pretrainModelPath := "/pretrainmodel"
outputPath := "/output"
var config = &entity.AITaskBaseConfig{
ContainerSteps: map[entity.ContainerDataType]*entity.ContainerBuildOpts{
entity.ContainerCode: {
ContainerPath: "/tmp" + codePath,
StorageRelativePath: codePath,
ReadOnly: false,
AcceptStorageType: []entity.StorageType{entity.MINIO, entity.OBS},
},
entity.ContainerDataset: {
ContainerPath: "/tmp" + datasetPath,
ReadOnly: true,
AcceptStorageType: []entity.StorageType{entity.MINIO, entity.OBS},
},
entity.ContainerPreTrainModel: {
ContainerPath: "/tmp" + pretrainModelPath,
ReadOnly: true,
AcceptStorageType: []entity.StorageType{entity.MINIO, entity.OBS},
},
entity.ContainerOutPutPath: {
ContainerPath: "/tmp" + outputPath,
StorageRelativePath: cloudbrain.ModelMountPath,
ReadOnly: false,
AcceptStorageType: []entity.StorageType{entity.MINIO},
MKDIR: false,
},
},
}

switch opts.ComputeSource {
case models.GPU:
config.ActionType = models.ActionCreateGrampusGPUInferenceTask
case models.ILUVATAR:
config.ActionType = models.ActionCreateGrampusILUVATARInferenceTask
}

config.IsActionUseJobId = true
return config
}

func (t GrampusInferenceTaskTemplate) Create(ctx *context.CreationContext) (*entity.CreateTaskRes, *response.BizError) {
c := &CreateOperator{}
err := c.Next(t.CheckParamFormat).
Next(t.HandleReqParameters).
Next(t.CheckPrivilege4Continue).
Next(t.CheckSourceTaskIsCleared).
Next(t.CheckBranchExists).
Next(t.CheckBootFile).
Next(t.CheckWorkerNum).
Next(t.CheckMultiRequest).
Next(t.CheckDisplayJobName).
Next(t.LoadSpec).
Next(t.CheckPointBalance).
Next(t.CheckDatasets).
Next(t.CheckModel).
Next(t.InsertCloudbrainRecord4Async).
AsyncNextWithErrFun(t.BuildContainerData, t.GetAvailableQueues, t.CallCreationAPI, t.AfterCallCreationAPI4Async, t.NotifyCreation, t.HandleErr4Async).
Operate(ctx)
if err != nil {
log.Error("create GrampusTrainTaskTemplate err.%v", err)
return nil, err
}
return &entity.CreateTaskRes{ID: ctx.NewCloudbrain.ID}, nil
}

func (g GrampusInferenceTaskTemplate) CallCreationAPI(ctx *context.CreationContext) *response.BizError {
c := g.GetMyCluster()
if c == nil {
return response.SYSTEM_ERROR
}
form := ctx.Request
imageUrl := strings.TrimSpace(form.ImageUrl)
if form.ImageID != "" {
imageUrl = ""
}
req := entity.CreateTrainTaskRequest{
Name: form.JobName,
DisplayJobName: form.DisplayJobName,
Tasks: []entity.TrainTask{
{
Name: form.JobName,
ResourceSpecId: ctx.Spec.SourceSpecId,
ImageId: form.ImageID,
ImageUrl: imageUrl,
Datasets: ctx.GetContainerDataArray(entity.ContainerDataset),
Code: ctx.GetContainerDataArray(entity.ContainerCode),
Queues: ctx.Queues,
PreTrainModel: ctx.GetContainerDataArray(entity.ContainerPreTrainModel),
BootFile: form.BootFile,
OutPut: ctx.GetContainerDataArray(entity.ContainerOutPutPath),
Params: form.ParamArray,
Spec: ctx.Spec,
RepoName: ctx.Repository.Name,
WorkServerNumber: ctx.Request.WorkServerNumber,
},
},
TaskConfig: ctx.Config,
}
createTime := timeutil.TimeStampNow()
res, err := c.CreateTrainJob(req)
if err != nil {
log.Error("GrampusTrainTaskTemplate CreateTrainJob err.req=%+v err=%v", req, err)
return response.NewBizError(err)
}
ctx.Response = &entity.CreationResponse{
JobID: res.JobID,
Status: res.Status,
CreateTime: createTime,
}
return nil
}

+ 20
- 0
services/ai_task_service/task/grampus_notebook_task.go View File

@@ -118,6 +118,26 @@ func GetGrampusNoteBookConfig(opts entity.AITaskConfigKey) *entity.AITaskBaseCon
},
}
}
//在线运行notebook配置
if opts.IsFileNoteBookRequest {
config = &entity.AITaskBaseConfig{
ContainerSteps: map[entity.ContainerDataType]*entity.ContainerBuildOpts{
entity.ContainerFileNoteBookCode: {},
entity.ContainerCode: {
ContainerPath: codePath,
ReadOnly: false,
AcceptStorageType: []entity.StorageType{entity.MINIO},
Uncompressed: true,
},
entity.ContainerDataset: {
ContainerPath: datasetPath,
ReadOnly: true,
AcceptStorageType: []entity.StorageType{entity.MINIO, entity.OBS},
},
},
}

}

switch opts.ComputeSource {
case models.NPU:


+ 1
- 1
services/ai_task_service/task/opt_handler.go View File

@@ -144,7 +144,7 @@ func (g DefaultCreationHandler) CheckDatasets(ctx *context.CreationContext) *res
attachSize += infos.Size
}
limitSizeGB := ctx.Config.DatasetsLimitSizeGB
if limitSizeGB > 0 && attachSize > int64(limitSizeGB*1000*1000*1000) {
if limitSizeGB > 0 && attachSize > int64(limitSizeGB*1024*1024*1024) {
log.Error("The DatasetSize exceeds the limit (%dGB)", limitSizeGB) // GB
return response.DATASET_SIZE_OVER_LIMIT.WithParams(limitSizeGB)
}


+ 1
- 1
services/ai_task_service/task/task_creation_info.go View File

@@ -87,7 +87,7 @@ func GetAITaskCreationInfo(req entity.GetAITaskCreationInfoReq) (*entity.Creatio
}

result.Config = entity.AITaskCreationConfig{
DatasetMaxSize: setting.DebugAttachSize * 1000 * 1000 * 1000,
DatasetMaxSize: setting.DebugAttachSize * 1024 * 1024 * 1024,
}
//查询可用节点数
if workerNums, err := t.GetAllowedWorkerNum(req.User.ID, req.ComputeSource); err == nil {


+ 9
- 8
services/ai_task_service/task/task_service.go View File

@@ -299,14 +299,14 @@ func UpdateByQueryResponse(res *entity.QueryTaskResponse, task *models.Cloudbrai
var noteBookOKMap = make(map[string]int, 20)
var noteBookFailMap = make(map[string]int, 20)

//if a task notebook url can get successfulCount times, the notebook can browser.
// if a task notebook url can get successfulCount times, the notebook can browser.
const successfulCount = 3
const maxSuccessfulCount = 10

//云脑一存在状态为RUNNING但实际不可用的情况,且存在访问调试链接成功后又失败的情况,因此需要一段时间内多次成功才认为调试可用
//下列代码来源于services/cloudbrain/cloudbrainTask/sync_status.go:118
//func isNoteBookReady(task *models.Cloudbrain) bool
//为了解决循环引用copy了一份到此类,稍有改编
// 云脑一存在状态为RUNNING但实际不可用的情况,且存在访问调试链接成功后又失败的情况,因此需要一段时间内多次成功才认为调试可用
// 下列代码来源于services/cloudbrain/cloudbrainTask/sync_status.go:118
// func isNoteBookReady(task *models.Cloudbrain) bool
// 为了解决循环引用copy了一份到此类,稍有改编
func isCloudbrainOneNotebookReady(jobId string) bool {
url, err := new(cluster.CloudbrainOneClusterAdapter).GetNoteBookUrl(jobId)
if err != nil {
@@ -393,7 +393,7 @@ func StopTask(id int64, stopRemote StopFunc) error {
return nil
}

//jobId string, baseLine int64, lines int64, order int64
// jobId string, baseLine int64, lines int64, order int64
func QueryTaskLog(opts entity.QueryLogOpts, getLogRemote GetLogFunc) (*entity.ClusterLog, error) {
cloudbrain, err := models.GetCloudbrainByCloudbrainID(opts.CloudbrainId)
if err != nil {
@@ -650,7 +650,8 @@ func CreateAITask(form entity.CreateReq, gitRepo *git.Repository, repo *models.R
GitRepo: gitRepo,
Repository: repo,
User: user,
Config: t.GetConfig(entity.AITaskConfigKey{ComputeSource: form.ComputeSourceStr}),
Config: t.GetConfig(entity.AITaskConfigKey{ComputeSource: form.ComputeSourceStr,
IsFileNoteBookRequest: form.IsFileNoteBookRequest}),
})
}

@@ -706,7 +707,7 @@ func GetOperationProfile(id int64, getOperationProfile GetOperationProfileFunc)
return s, err
}

//SyncAITaskStatus 定时更新云脑状态和运行时长
// SyncAITaskStatus 定时更新云脑状态和运行时长
func SyncAITaskStatus() {
defer func() {
if err := recover(); err != nil {


+ 13
- 12
services/cloudbrain/clear.go View File

@@ -53,16 +53,23 @@ func ClearCloudbrainResultSpace() {
var ids []int64
for _, task := range tasks {
//(type=0 or (type =2 and compute_resource='CPU/GPU')) and
if task.ComputeResource == "CPU/GPU" || task.ComputeResource == "GCU" {
if task.Type == models.TypeCloudBrainOne {
log.Info("clear cloud brain one,name=" + task.JobName)
err := DeleteCloudbrainOneJobStorage(task.JobName)
if err == nil {
log.Info("clear job in cloudbrain table:" + task.JobName)
ids = append(ids, task.ID)
}
if task.Type == models.TypeC2Net {
deleteC2NetTask(task)
} else if task.Type == models.TypeC2Net {
DeleteCloudbrainOneJobStorage(task.JobName)
deleteC2NetTask(task)
if task.ComputeResource == "NPU" {
deleteModelArtsStorage(task.JobName, task.VersionName)
}
log.Info("clear TypeC2Net,name=" + task.JobName)
ids = append(ids, task.ID)
} else {
log.Info("clear npu,name=" + task.JobName)
id := DeleteNPUJobStorage(task)
if id > 0 {
ids = append(ids, id)
@@ -77,7 +84,6 @@ func ClearCloudbrainResultSpace() {
if len(tasks) < setting.ClearStrategy.BatchSize+setting.ClearStrategy.DebugJobSize {
clearLocalHistoryTrashFile()
clearMinioHistoryTrashFile()

}
log.Info("clear cloudbrain one result space end.")

@@ -182,7 +188,8 @@ func deleteC2NetTask(taskInfo *models.Cloudbrain) {

func DeleteNPUJobStorage(taskInfo *models.Cloudbrain) int64 {
if taskInfo.Type == models.TypeCloudBrainTwo {
if taskInfo.JobType == string(models.JobTypeTrain) || taskInfo.JobType == string(models.JobTypeInference) {
if taskInfo.JobType == string(models.JobTypeTrain) || taskInfo.JobType == string(models.JobTypeInference) ||
taskInfo.JobType == string(models.JobTypeModelSafety) {
modelarts.DelTrainJobVersion(taskInfo.JobID, strconv.FormatInt(taskInfo.VersionID, 10))
}
if taskInfo.JobType == string(models.JobTypeDebug) {
@@ -201,13 +208,7 @@ func DeleteNPUJobStorage(taskInfo *models.Cloudbrain) int64 {
}
return taskInfo.ID
}
if taskInfo.Type == models.TypeC2Net {
deleteC2NetTask(taskInfo)
if taskInfo.ComputeResource == "NPU" {
deleteModelArtsStorage(taskInfo.JobName, taskInfo.VersionName)
return taskInfo.ID
}
}

return 0
}



+ 20
- 13
services/cloudbrain/cloudbrainTask/notebook.go View File

@@ -10,6 +10,8 @@ import (
"strconv"
"strings"

"code.gitea.io/gitea/entity"

"code.gitea.io/gitea/modules/storage"

"code.gitea.io/gitea/modules/grampus"
@@ -168,7 +170,7 @@ func GrampusNotebookCreate(ctx *context.Context, option api.CreateNotebookOption
for _, infos := range datasetInfos {
attachSize += infos.Size
}
if attachSize > int64(setting.DebugAttachSize*1000*1000*1000) {
if attachSize > int64(setting.DebugAttachSize*1024*1024*1024) {
log.Error("The DatasetSize exceeds the limit (%dGB)", setting.DebugAttachSize) // GB
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.error.debug_datasetsize", setting.DebugAttachSize)))
return
@@ -294,15 +296,6 @@ func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOp
return
}

//var imageIdNpu string
//
//if option.Type == NPUType {
// imageIdNpu, err = getNpuImageId(option)
// if err != nil {
// ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.parameter_is_wrong")))
// return
// }
//}
var err error
isNotebookFileExist, _ := isNoteBookFileExist(ctx, option)
if !isNotebookFileExist {
@@ -476,8 +469,22 @@ func FileNotebookStatus(ctx *context.Context, option api.CreateFileNotebookJobOp
func getBaseUrlAndToken(task *models.Cloudbrain) (string, string, error) {
var debugBaseUrl string
var token string
if task.Type == models.TypeCloudBrainOne {
debugBaseUrl = setting.DebugServerHost + "jpylab_" + task.JobID + "_" + task.SubTaskName + "/lab"
if task.Type == models.TypeC2Net {
log.Info("get grampus debug url begin: ", task.JobID)
result, err := grampus.GetNotebookJob(task.JobID)
if err != nil {
return "", "", err
}
if result == nil {
return "", "", fmt.Errorf("can not get job response.")
}
convertRes := entity.ConvertGrampusNotebookResponse(result.JobInfo)
debugBaseUrl = convertRes.Url
token = convertRes.Token
if debugBaseUrl == "" {
log.Error("notebook job not found:"+task.JobID, err)
return "", "", fmt.Errorf("can not get job or job is invalid.")
}

} else {
var result *models.GetNotebook2Result
@@ -695,7 +702,7 @@ func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNot

func getCloudbrainType(optionType int) int {
if optionType <= GPUType {
return models.TypeCloudBrainOne
return models.TypeC2Net
}
if setting.ModelartsCD.Enabled {
return models.TypeCDCenter


+ 1
- 1
services/socketwrap/clientManager.go View File

@@ -10,7 +10,7 @@ import (
"github.com/elliotchance/orderedmap"
)

var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49}
var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51}

type ClientsManager struct {
Clients *orderedmap.OrderedMap


+ 4
- 4
templates/admin/cloudbrain/list.tmpl View File

@@ -89,7 +89,7 @@
<div class="row">
<!-- 任务名 -->
{{$JobID := '0'}}
{{if eq .JobType "DEBUG" "TRAIN" "HPC" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK" "MODELSAFETY" "SNN4ECOSET" "SIM2BRAIN_SNN" "ONLINEINFERENCE"}}
{{if eq .JobType "DEBUG" "TRAIN" "INFERENCE" "HPC" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK" "MODELSAFETY" "SNN4ECOSET" "SIM2BRAIN_SNN" "ONLINEINFERENCE"}}
{{$JobID = .Cloudbrain.ID}}
{{else}}
{{$JobID = .JobID}}
@@ -119,7 +119,7 @@
</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}}"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 2}}grampus{{else if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}"
title="{{.DisplayJobName}}" style="font-size: 14px;">
<span class="fitted"
style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
@@ -155,7 +155,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" "ONLINEINFERENCE" "HPC"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{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-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG" "ONLINEINFERENCE" "HPC"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/train-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK" "MODELSAFETY"}}/cloudbrain{{end}}'
data-jobid="{{$JobID}}" data-version="{{.VersionName}}"
data-cloudbrainid="{{.Cloudbrain.ID}}" data-datamigrate='{{$.i18n.Tr "repo.migratingData"}}' data-centerpend='{{$.i18n.Tr "repo.centerPending"}}'>
<span>
@@ -351,7 +351,7 @@
</form>
{{else}}
<form class="ui compact buttons" id="delForm-{{$JobID}}"
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE") (eq .JobType "SNN4ECOSET") (eq .JobType "SIM2BRAIN_SNN")}}/cloudbrain{{else if eq .JobType "DEBUG" "ONLINEINFERENCE" "HPC"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?isadminpage=true'
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE") (eq .JobType "SNN4ECOSET") (eq .JobType "SIM2BRAIN_SNN")}}/cloudbrain{{else if eq .JobType "DEBUG" "ONLINEINFERENCE" "HPC"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{end}}/{{$JobID}}/del?isadminpage=true'
method="post">
{{$.CsrfTokenHtml}}
<input type="hidden" value="{{.Cloudbrain.ID}}" style="display:none" name="id" />


+ 5
- 1
templates/base/footer.tmpl View File

@@ -9,7 +9,9 @@
</div>

{{template "custom/body_outer_post" .}}

{{if not .IsNewAgree}}
{{template "user/auth/network_security" .}}
{{end}}
{{template "base/footer_content" .}}

<script src="{{StaticUrlPrefix}}/js/jquery.js?v={{MD5 AppVer}}"></script>
@@ -46,6 +48,8 @@
<script src="{{StaticUrlPrefix}}/fomantic/semantic.min.js?v={{MD5 AppVer}}"></script>
<script src="{{StaticUrlPrefix}}/js/index.js?v={{MD5 AppVer}}"></script>
{{template "custom/footer" .}}

{{if .PageIsHome}}

<!--script src="https://www.jq22.com/jquery/jquery-1.10.2.js?v={{MD5 AppVer}}"></script-->


+ 2
- 2
templates/repo/cloudbrain/benchmark/index.tmpl View File

@@ -45,9 +45,9 @@
</div>
</div>
<div class="column right aligned">
<a class="ui compact orange basic icon button" href="https://openi.org.cn/projects/Benchmark/#algType" style="box-shadow: none;" target="_blank"><i class="large ri-trophy-fill middle aligned icon"></i>{{$.i18n.Tr "repo.benchmark_leaderboards"}}</a>
{{if .Permission.CanWrite $.UnitTypeCloudBrain}}
<a class="ui green button" href="{{.RepoLink}}/cloudbrain/benchmark/create">{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a>
<a class="ui green button" href="{{.RepoLink}}/modelsafety/create_npu">{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a>
{{else}}
<a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}</a>
{{end}}


+ 2
- 10
templates/repo/cloudbrain/benchmark/new.tmpl View File

@@ -21,12 +21,8 @@
<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="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">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
href="{{.RepoLink}}/modelsafety/create_npu">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
</div>
</div>
<div>
@@ -133,12 +129,8 @@
<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="active 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="item aisafety_benchmark"
href="{{.RepoLink}}/modelsafety/create_gpu">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
href="{{.RepoLink}}/modelsafety/create_npu">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
</div>
</div>



+ 1
- 553
templates/repo/cloudbrain/inference/new.tmpl View File

@@ -1,553 +1 @@
{{template "base/head" .}}
<style>

.title{
font-size: 16px !important;
padding-left: 3rem !important;
}
.min_title{
font-size: 14px !important;
margin-bottom: 2rem !important;
}
.width{
width:100% !important;
}
.width80{
width: 80.7% !important;
}

.width85 {
width: 85% !important;
margin-left: 10.5rem !important;
align-items: center;
}
.width35{
width: 35.5% !important;
}

.width48{
width: 48.5% !important;
}
.nowrapx {
white-space: nowrap !important;
}
</style>
{{template "custom/global_mask" .}}
<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
{{template "custom/alert_cb" .}}
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new_infer"}}
</h4>
<div class="ui attached segment">
<!-- equal width -->
<form id="form_id" class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_image_name" value="{{.image}}">

<input type="hidden" id="failed_train_url" value="{{$.train_url}}">
<input type="hidden" id="failed_model_name" value="{{$.model_name}}">
<input type="hidden" id="failed_model_version" value="{{$.model_version}}">
<input type="hidden" id="failed_ckpt_name" value="{{$.ckpt_name}}">
<input type="hidden" id="failed_train_url" value="{{$.train_url}}">
<input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}">
<input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}">
<h4 class="title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required min_title inline 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="active item" href="{{.RepoLink}}/cloudbrain/inference-job/create">
<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="item" href="{{.RepoLink}}/modelarts/inference-job/create">
<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 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 style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;">
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.new_infer_gpu_tooltips" "/dataset" "/model" "/result" | Safe}}</span>
</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: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="36">
<span class="tooltips" style="margin-left:11.5rem;display: block;">{{.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>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" 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)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>

<h4 class="title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<!-- 模型相关配置 -->
<!--
<div class="required inline min_title fields" style="width: 94%;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>
<div class="six wide field">
<div class="ui fluid search selection dropdown loading " id="select_model">
<input type="hidden" name="model_name" required>
<div class="text"></div>
<i class="dropdown icon"></i>
<div class="menu" id="model_name">
</div>
</div>
</div>
<div class="three wide field">
<div class="ui fluid search selection dropdown" id="select_model_version">
<input type="hidden" name="train_url" required>
<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 search selection dropdown" id="select_model_checkpoint">
<input type="hidden" name="ckpt_name" required>
<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>
<div class="select-multi-model" data-required="true" data-model-id="{{.model_id}}" data-model-name="{{.model_name}}" data-model-version="{{.model_version}}"
data-pre-train-model-url="{{.pre_train_model_url}}" data-ckpt-name="{{.ckpt_name}}"></div>
<div id="select-multi-model"></div>
</div>
<!-- AI引擎 -->
<div id="images-new-cb"></div>
<!-- 代码分支 -->
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width48" id="code_version" name="branch_name">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branch_name }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{else}}
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branchName }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{end}}
</select>
</div>
<!-- GPU 卡的类型 -->
<!--<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label>
<select id="cloudbrain_gpu_type" class="ui search width48 dropdown gpu-type" placeholder="选择GPU类型"
style='width:385px' name="gpu_type">
{{if .gpu_type}}
{{range .inference_gpu_types}}
{{if eq $.gpu_type .Queue}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
{{range .inference_gpu_types}}
{{if ne $.gpu_type .Queue}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
{{else}}
{{range .inference_gpu_types}}
<option value="{{.Queue}}">{{.Value}}</option>
{{end}}
{{end}}
</select>
</div>-->
<!-- 数据集-->
<div id="select-multi-dataset">

</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span>
<div class="inline min_title field required">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
{{if .boot_file}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" >
{{else}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" >
{{end}}
<span >
<i class="question circle icon" data-content={{.i18n.Tr "repo.modelarts.infer_job.boot_file_helper"}} data-position="top center" data-variation="inverted mini"></i>
</span>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/inference.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</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="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}}">

</div>
</div>

<div class="required field " style="display: none;">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label>
<select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id">
{{range .resource_pools}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
</select>
</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="cloudbrain_resource_spec" class="ui search dropdown width80" placeholder="选择资源规格" name="resource_spec_id">
{{if .resource_spec_id}}
{{range .inference_resource_specs}}
{{if eq $.resource_spec_id .Id}}
<option value="{{.Id}}">{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
{{range .inference_resource_specs}}
{{if ne $.resource_spec_id .Id}}
<option value="{{.Id}}">{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
{{else}}
{{range .inference_resource_specs}}
<option name="resource_spec_id" value="{{.Id}}">
{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option>
{{end}}
{{end}}
</select>
</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"}}" ovalue="{{.spec_id}}" name="spec_id" {{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}>
</select>
<span><i class="question circle icon link" data-content="{{.i18n.Tr "repo.modelarts.train_job.resource_helper"}}" data-position="right center" data-variation="mini"></i></span>
<a href="https://openi.pcl.ac.cn/docs/index.html#/quickstart/resources" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{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" ></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
{{end}}
</div>
<!-- 表单操作 -->
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;"></label>
<button class="ui create_train_job green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button" href="{{.RepoLink}}/modelarts/inference-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
<!-- 模态框 -->
</form>
</div>
</div>
</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.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
}
const RepoLink = {{.RepoLink}}
let nameMap,nameList
// 获取模型列表和模型名称对应的模型版本
$(document).ready(function(){
return; // 用模型选择组件了
modelVersion()
modelCkpt()
$.get(`${RepoLink}/modelmanage/query_model_for_predict?type=0`, (data) => {
nameMap = data.nameMap
nameList = data.nameList
let faildModelName = document.getElementById('failed_model_name').value
let html = ''
nameList.forEach(element => {
html += `<div class="item" data-value="${element}">${element}</div>`
});
if(nameList.length!==0){
$('#model_name').append(html)
if(faildModelName){
$("#select_model").dropdown('set text',faildModelName)
$("#select_model").dropdown('set value',faildModelName)
}else{
$("#select_model").dropdown('set text',nameList[0])
$("#select_model").dropdown('set value',nameList[0],nameList[0])
}
}
$('#select_model').removeClass("loading")
})
})

// 根据选中的模型名称获取相应的模型版本
function modelVersion(){
let faildModelVersion = $('#failed_model_version').val()
let faildTrainUrl = $('#failed_train_url').val()
$('#select_model').dropdown({
onChange: function(value, text, $selectedItem) {
$("#select_model_version").addClass("loading")
$('#model_name_version').empty()
let html = ''
nameMap[value].forEach(element => {
html += `<div class="item" data-label="${element.label}" data-id="${element.id}" data-value="${element.path}">${element.version}</div>`
});
$('#model_name_version').append(html)
$("#select_model_version").removeClass("loading")
const initVersionText = $('#model_name_version div.item:first-child').text()
const initVersionValue = $('#model_name_version div.item:first-child').data('value')

if(faildModelVersion&&faildTrainUrl){
$("#select_model_version").dropdown('set text',faildModelVersion)
$("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child'))
}else{
$("#select_model_version").dropdown('set text',initVersionText)
$("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
}
}
})
}
// 根据选中的模型版本获取相应的模型权重文件
function modelCkpt(){
let faildCkptName = $('#failed_ckpt_name').val()
$('#select_model_version').dropdown({
onChange: function(value, text, $selectedItem) {
const dataID = $selectedItem[0].getAttribute("data-id")
const label = $selectedItem[0].getAttribute("data-label")
$("#select_model_checkpoint").addClass("loading")
$("#model_checkpoint").empty()
let html = ''
loadCheckpointList(dataID).then((res)=>{
res.forEach(element => {
const ckptSuffix = element.FileName.split(".")
const loadCheckpointFile = ['ckpt','pb','h5','json','pkl','pth','t7','pdparams','onnx','pbtxt','keras','mlmodel','cfg','pt']
if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){
html += `<div class="item" data-value="${element.FileName}">${element.FileName}</div>`
}
})
$('#model_checkpoint').append(html)
$("#select_model_checkpoint").removeClass("loading")
const initVersionText = $('#model_checkpoint div.item:first-child').text()
const initVersionValue = $('#model_checkpoint div.item:first-child').data('value')
if(faildCkptName){
$("#select_model_checkpoint").dropdown('set text',faildCkptName)
$("#select_model_checkpoint").dropdown('set value',faildCkptName,faildCkptName,$('#model_name_version div.item:first-child'))
}else{
$("#select_model_checkpoint").dropdown('set text',initVersionText)
$("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
}
})
$("input#ai_model_version").val(text)
$("input#ai_model_label").val(label)
}
})
}
function loadCheckpointList(value){
return new Promise((resolve,reject)=>{
$.get(`${RepoLink}/modelmanage/query_modelfile_for_predict`,{id:value}, (data) => {
resolve(data)
})
})
}

$('.question.circle.icon').hover(function(){
$(this).popup('show')
});

$(document).ready(function(){
let params = $('.dynamic.field').data('params')
params&&params.parameter.forEach((item,index)=>{
Add_parameter(index,flag=true,item)
})

})
// 参数增加、删除、修改、保存
function Add_parameter(i,flag=false,paramsObject={}) {
let value = ''
value += `<div class="two fields width85" id= "para${i}">`
value += '<div class="field">'
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}'
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}'
if(flag){
value +=`<input type="text" class="shipping_first-name" value="${paramsObject.label}">`
}else{
value +='<input type="text" class="shipping_first-name" required placeholder="' + placeholder_name+ '">'
}
value += '</div>'
value += '<div class="field">'
if(flag){
value +=`<input type="text" class="shipping_last-name" value="${paramsObject.value}">`
}else{
value +='<input type="text" class="shipping_last-name" required placeholder="' + placeholder_value+ '">'
}
value += '</div>'
value += '<span><i class="trash icon"></i></span>'
value += '</div>'
$(".dynamic.field").append(value)

}

$('#add_run_para').click(function () {
var len = $(".dynamic.field .two.fields").length
Add_parameter(len)
});

$(".dynamic.field").on("click", ".trash.icon", function () {
var index = $(this).parent().parent().index()
$(this).parent().parent().remove()
var len = $(".dynamic.field .two.fields").length
$(".dynamic.field .two.fields").each(function () {
var cur_index = $(this).index()
$(this).attr('id', 'para' + cur_index)
})
});

function send_run_para() {
var run_parameters = []
var msg = {}
$(".dynamic.field .two.fields").each(function () {
var para_name = $(this).find('input.shipping_first-name').val()
var para_value = $(this).find('input.shipping_last-name').val()
run_parameters.push({ "label": para_name, "value": para_value })
})
msg["parameter"] = run_parameters
msg = JSON.stringify(msg)
$('#store_run_para').val(msg)
}

var isValidate = false;
function validate(){
$('.ui.form')
.form({
on: 'blur',
fields: {
boot_file: {
identifier : 'boot_file',
rules: [
{
type: 'regExp[/.+\.py$/g]',
}
]
},
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',
}
]

},
model_name:{
identifier : 'model_name',
rules: [
{
type: 'empty',
}
]
},
train_url:{
identifier : 'train_url',
rules: [
{
type: 'empty',
}
]
},
ckpt_name:{
identifier : 'ckpt_name',
rules: [
{
type: 'empty',
}
]
},
spec_id: {
identifier: 'spec_id',
rules: [{ type: 'empty' }]
}
},
onSuccess: function(){
document.getElementById("mask").style.display = "block"
isValidate = true;
},
onFailure: function(e){
isValidate = false;
return false;
}
})
}
document.onreadystatechange = function() {
if (document.readyState === "complete") {
document.getElementById("mask").style.display = "none"
}
}
validate();
$('.ui.create_train_job.green.button').click(function(e) {
send_run_para();
validate();
})
;(function() {
var SPECS = {{ .inference_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"}},
no_use_resource:{{$.i18n.Tr "cloudbrain.no_use_resource"}},
});
})();
</script>
{{ template "repo/cloudbrain/cloudbraincreate" .}}

+ 1
- 446
templates/repo/cloudbrain/inference/show.tmpl View File

@@ -1,446 +1 @@
{{template "base/head" .}}
<style>
.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}}/modelarts/inference-job">
{{$.i18n.Tr "repo.modelarts.infer_job"}}
</a>
<div class="divider"> / </div>
<div class="active section">{{.displayJobName}}</div>
</div>
</h4>
{{with .task}}
<div class="ui accordion border-according" id="accordion{{.VersionName}}"
data-repopath="{{$.RepoRelPath}}/cloudbrain" data-jobid="{{.ID}}" data-version="{{.VersionName}}">
<input type="hidden" id="jobId_input" name="jobId_input" value="{{.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">{{TimeSinceUnix1 .CreatedUnix}}</span>

<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}:
<span id="{{.VersionName}}-status-span"><i id="icon"
style="vertical-align: middle;" class="{{.Status}}"></i><span id="text"
style="margin-left: 0.4em;font-size: 12px;">{{.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="{{.VersionName}}-duration-span">{{$.duration}}</span>
<span class="refresh-status" data-tooltip="刷新" style="cursor: pointer;" data-inverted="" data-version="{{.VersionName}}"><i
class="redo icon redo-color"></i></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="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a>
<a class="item detail-log-tab" data-tab="third"
data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a>
<a class="item load-model-file" data-tab="four"
data-gpu-flag="true" data-download-flag="{{$.canDownload}}" data-path="{{$.RepoLink}}/cloudbrain/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a>
</div>
<div class="ui tab active" data-tab="first">
<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">
{{.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="{{.VersionName}}-status">
{{.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.run_version"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.VersionName}}
</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_time"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
<span style="font-size: 12px;" id="{{.VersionName}}-startTime">
{{if not (eq .StartTime 0)}}
{{TimeSinceUnix1 .StartTime}}
{{else}}
--
{{end}}
</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.modelarts.train_job.dura_time"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-duration">
{{.TrainJobDuration}}
</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.resource_type"}}
</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.model.manage.description"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-desc" style="width: 380px;">
{{if .Description}}
<span title="{{.Description}}">{{.Description}}</span>
{{else}}
<span>--</span>
{{end}}
</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="{{.VersionName}}-creator">
{{.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 "cloudbrain.mirror"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-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.copy_link_success"}}"
data-error="{{$.i18n.Tr "repo.copy_link_error"}}"
data-content="{{$.i18n.Tr "repo.copy_link"}}"
data-variation="inverted tiny"
>
<span title="{{.Image}}">{{.Image}}</span>
</span>
</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.infer_job_model"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
<span>{{.ModelName}}</span>&nbsp;&nbsp;
<span style="color: #8a8e99">{{$.i18n.Tr "repo.modelarts.version"}}:</span><span>{{.ModelVersion}}</span>&nbsp;&nbsp;

</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">
{{.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.modelarts.model_label"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-labels">
{{if .LabelName}}
{{range $.LabelName}}
<a class="ui label" title="{{.}}">{{.}}</a>
{{end}}
{{else}}
<span>--</span>
{{end}}
</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.code_version"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.BranchName}}
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</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.modelarts.train_job.start_file"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.BootFile}}
</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" title="{{.Parameters}}">
{{if .Parameters}}
<span>{{.Parameters}}</span>
{{else}}
<span>--</span>
{{end}}
</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>
</tbody>
</table>
</div>
</div>
<div style="clear:both">
<table style="border:none" class="ui fixed small stackable table">
<thead>
<tr><th style="color: #8a8e99;font-size:12px" class="three wide left aligned">{{$.i18n.Tr "dataset.file"}}</th>
</tr></thead>
<tbody>
{{range $m ,$n := $.datasetDownload}}
<tr>
<td style="word-wrap: break-word;word-break: break-all;">
{{if eq .IsDelete true}}
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}})
{{else}}
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a>
{{end}}
</td>
</tr>
{{end}}

</tbody>
</table>
</div>
</div>

</div>
</div>
<div class="ui tab" data-tab="third">
<!--
<div class="file-info">
<a id="{{.VersionName}}-log-down"
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}} file-info'
href="/api/v1/repos/{{$.RepoRelPath}}/cloudbrain/{{.ID}}/download_log_file">
<i class="ri-download-cloud-2-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span>
</a>
<div class="file-info full-log-dialog" data-version="{{.VersionName}}" data-log="{{$.i18n.Tr "repo.modelarts.log_file"}}"
data-exit="{{$.i18n.Tr "repo.modelarts.exit_full_screen"}}" style="margin-left: 1rem;color:#0366d6;cursor: pointer;"
data-log-down="{{$.i18n.Tr "repo.modelarts.download_log"}}" data-href="/api/v1/repos/{{$.RepoRelPath}}/cloudbrain/{{.ID}}/download_log_file"
data-scroll-top="{{$.i18n.Tr "repo.log_scroll_start"}}" data-scroll-bottom="{{$.i18n.Tr "repo.log_scroll_end"}}">
<i class="ri-aspect-ratio-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.fullscreen_log_file"}}</span>
</div>
</div>
<div
style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;">
<span>
<a title="{{$.i18n.Tr "repo.log_scroll_start"}}" style="position: absolute; right: -32px;cursor: pointer;"
class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a>
</span>
<span class="log-info-{{.VersionName}}">
<a title="{{$.i18n.Tr "repo.log_scroll_end"}}" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;"
class="log_bottom" data-version="{{.VersionName}}"><i
class="icon-to-bottom"></i></a>
</span>
<div class="ui message message{{.VersionName}}" style="display: none;">
<div id="header"></div>
</div>
<div class="ui attached log log-scroll" id="log{{.VersionName}}" data-version="{{.VersionName}}"
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="end_line-max" value>
<input type="hidden" name="start_line-max" value>
<input type="hidden" name="start_line-max-copy" value>
<input type="hidden" name="start_line" value>
<input type="hidden" name="init_log" value>
<pre id="log_file{{.VersionName}}"></pre>
</div>
</div>
-->
<div class="detail-log-content detail-log-content-{{.VersionName}}"
data-multiplenode=""
data-logapiurl="{{$.RepoLink}}/cloudbrain/{{.ID}}/log"
data-logdownloadurl="/api/v1/repos{{$.RepoLink}}/cloudbrain/{{.ID}}/download_log_file"
data-workservernumber="{{.WorkServerNumber}}"
data-version="{{.VersionName}}">
{{template "custom/task_log" Dict "$" $ "i18n" $.i18n }}
</div>
<div class="ui modal full-log-dlg-{{.VersionName}} container" style="height:90%;margin:3rem auto;">
<div id="log-file-title" style="font-size: 16px;font-weight:600;padding:20px 30px 16px;">{{$.i18n.Tr "repo.modelarts.log_file"}}</div>
<div style="padding:0 50px 10px 30px;height:100%">
<div class="detail-log-fullscreen-content detail-log-fullscreen-content-{{.VersionName}}" style="height:100%;"
data-multiplenode=""
data-logapiurl="{{$.RepoLink}}/cloudbrain/{{.ID}}/log"
data-logdownloadurl="/api/v1/repos{{$.RepoLink}}/cloudbrain/{{.ID}}/download_log_file"
data-workservernumber="{{.WorkServerNumber}}"
data-version="{{.VersionName}}">
{{template "custom/task_log" Dict "$" $ "i18n" $.i18n "Full" true }}
</div>
</div>
</div>
</div>

<div class="ui tab" data-tab="four">
<input type="hidden" name="model{{.VersionName}}" value="-1">
<input type="hidden" name="modelback{{.VersionName}}" value="-1">
<div style="display: flex;justify-content: space-between;">
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'>
<div class="active section">{{.VersionName}}</div>
<div class="divider"> / </div>
</div>
<a id="{{.VersionName}}-result-down" style="padding-right: 1%;display: none;"
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}} file-info'
href="{{$.RepoLink}}/cloudbrain/inference-job/{{.JobID}}/downloadall?version_name={{.VersionName}}">
<i class="ri-download-cloud-2-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.all_result_download"}}</span>
</a>
</div>
<div id="dir_list{{.VersionName}}">

</div>
</div>

</div>
</div>
</div>
<!-- {{template "custom/max_log" .}} -->
{{end}}
</div>

</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>

<script>
$('.menu .item').tab()

$(document).ready(function () {
$('.ui.accordion').accordion({ selector: { trigger: '.icon' } });
});
$(document).ready(function () {
$('.secondary.menu .item').tab();
});
;(function() {
var SPEC = {{ .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"}},
no_use_resource:{{$.i18n.Tr "cloudbrain.no_use_resource"}},
});
$('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));
})();
</script>
{{ template "repo/cloudbrain/cloudbraindetail" .}}

+ 1
- 0
templates/repo/grampus/inference/new.tmpl View File

@@ -0,0 +1 @@
{{ template "repo/cloudbrain/cloudbraincreate" .}}

+ 1
- 0
templates/repo/grampus/inference/show.tmpl View File

@@ -0,0 +1 @@
{{ template "repo/cloudbrain/cloudbraindetail" .}}

+ 1
- 1
templates/repo/home.tmpl View File

@@ -245,7 +245,7 @@
<!-- Only show clone panel in repository home page -->
{{if eq $n 0}}
<div class="ui action tiny input" id="clone-panel">
<div class="ui basic floating button" style="margin-right:10px;padding:0 10px; font-size:13px;{{if eq .IsRepositoryOwner true }} {{else if eq .IsRepositoryAdmin true}} {{else if eq .CanEditFile true}}{{else}} display:none; {{end}}">
<div class="ui basic floating button" style="margin-right:10px;padding:0 10px; font-size:13px;{{if eq .IsMirror true}}display:none; {{else if eq .IsRepositoryOwner true }} {{else if eq .IsRepositoryAdmin true}} {{else if eq .CanEditFile true}}{{else}} display:none; {{end}}">
<a href="/ide/project?type=ide&owner={{.Owner.Name}}&project={{.Repository.Name}}&git={{.CloneLink.HTTPS}}&branch={{.VisitBranchName}}" target="_blank"><div class="text">WEB IDE</div></a>
</div>
{{if not $.DisableHTTP}}


+ 4
- 306
templates/repo/modelarts/inferencejob/index.tmpl View File

@@ -1,311 +1,9 @@
<!-- 头部导航栏 -->
{{template "base/head" .}}

<style>
.fontsize14{
font-size: 14px;
}
.padding0{
padding: 0 !important;
}
</style>


<!-- 提示框 -->
<div class="alert"></div>

<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-cloudbrain-list.css?v={{MD5 AppVer}}" />
<script>const Tasks = {{.Tasks}}; </script>
<div class="repository release dataset-list view">
{{template "repo/header" .}}
<!-- 列表容器 -->
<div class="ui container">
{{template "base/alert" .}}
<div class="ui two column stackable grid ">
<div class="column">
<div class="ui blue small menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/debugjob?debugListType=all">{{$.i18n.Tr "repo.modelarts.notebook"}}</a>
<a class="item" href="{{.RepoLink}}/modelarts/train-job?listType=all">{{$.i18n.Tr "repo.modelarts.train_job"}}</a>
<a class="active item" href="{{.RepoLink}}/modelarts/inference-job">{{$.i18n.Tr "repo.modelarts.infer_job"}}</a>
<a class="item" href="{{.RepoLink}}/cloudbrain/benchmark">{{$.i18n.Tr "repo.modelarts.evaluate_job"}}</a>
<a class="item" href="{{.RepoLink}}/grampus/onlineinfer">{{$.i18n.Tr "repo.modelarts.online_infer"}}</a>
{{if MLOPS}}
<a class="item" href="{{MlopsHost}}/AIStudio/mlops/deploy-online/edge-inference?reponame={{.Repository.Name}}&repoId={{.Repository.ID}}" target="_blank">
在线推理1
</a>
<a class="item" href="{{MlopsHost}}/AIStudio/mlops/pipeline/list?reponame={{.Repository.Name}}&repoId={{.Repository.ID}}" target="_blank">
流水线
</a>
{{end}}
</div>
</div>
<div class="column right aligned">
<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;">
{{svg "octicon-server" 16}}
<div class="default text" style="color: rgba(0,0,0,.87);"></div>
<i class="dropdown icon"></i>
<div class="menu">
<div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div>
<div class="item" data-value="CPU/GPU">CPU/GPU</div>
<div class="item" data-value="NPU">NPU</div>
</div>
</div>
{{if .Permission.CanWrite $.UnitTypeCloudBrain}}
<a class="ui green button" href="{{.RepoLink}}/cloudbrain/inference-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a>
{{else}}
<a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a>
{{end}}
</div>
</div>
{{if eq 0 (len .Tasks)}}
<div class="ui placeholder segment bgtask-none">
<div class="ui icon header bgtask-header-pic"></div>
<div class="bgtask-content-header">{{$.i18n.Tr "repo.inference_job_not_created"}}</div>
<div class="bgtask-content">
{{if $.RepoIsEmpty}}
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.repo_not_initialized" .RepoLink | Safe}}</div>
{{end}}
{{if eq 0 $.MODEL_COUNT}}
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.model_not_exist" .RepoLink .RepoLink | Safe}}</div>
{{end}}
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.dataset_desc"}}</div>
<div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions" "https://openi.pcl.ac.cn/docs/index.html#/cloudbrain/infer/inference-job" | Safe}}</div>
</div>
</div>
{{else}}
<!-- 中下列表展示区 -->
<div class="ui grid">
<div class="row">
<div class="ui sixteen wide column">
<!-- 任务展示 -->
<div class="dataset list">

<!-- 表头 -->
<div class="ui grid stackable" style="background: #f0f0f0;;">
<div class="row">
<div class="three wide column padding0" style="width: 17% !important;">
<span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span>
</div>
<div class="three wide column text center padding0" style="width: 17% !important;">
<span style="margin:0 6px">{{$.i18n.Tr "repo.modelarts.infer_job.model_version"}}</span>
</div>
<div class="two wide column text center padding0" style="width: 10.5% !important;">
<span>{{$.i18n.Tr "repo.modelarts.status"}}</span>
</div>
<div class="two wide column text center padding0" style="width: 10.5% !important;">
<span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span>
</div>
<div class="two wide column text center padding0" style="width: 10.5% !important;">
<span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span>
</div>
<div class="two wide column text center padding0" style="width: 10.5% !important;">
<span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span>
</div>
<div class="one wide column text center padding0" style="width: 6% !important;">
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
</div>
<div class="three wide column text center padding0" style="width: 18% !important;">
<span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span>
</div>
</div>
</div>

{{range .Tasks}}
<div class="ui grid stackable item">
<div class="row">

<!-- 任务名 -->
<div class="three wide column padding0" style="width: 17% !important;">
<a class="title" href="/{{$.RepoRelPath}}/{{if eq .Cloudbrain.Type 0 }}cloudbrain{{else}}modelarts{{end}}/inference-job/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;">

<span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
</a>
</div>
<!-- 模型版本 -->
<!-- href="{{$.RepoLink}}/modelmanage/model_readme_tmpl?name={{.ModelName}}" -->
<div class="three wide column text center padding0" style="display: flex;width: 17% !important;">
<a id="{{.JobName}}" class="goto_modelmanage nowrap" title="{{.ModelName}}" href="javascript:void(0);"
data-variation="inverted"
data-position="top center"
data-content="{{$.i18n.Tr "repo.modelarts.infer_job.model_cant_see"}}"
data-jobname="{{.JobName}}"
data-modelid="{{.ModelId}}"
data-modelname="{{.ModelName}}"
data-version="{{.ModelVersion}}"
data-repopath="{{$.RepoLink}}"
data-modelrepoownername="{{.ModelRepoOwnerName}}"
data-modelreponame="{{.ModelRepoName}}"
>
{{.ModelName}}&nbsp;</a>&nbsp;<span style="font-size: 12px;">{{.ModelVersion}}</span>
</div>
<!-- 任务状态 -->
<div class="two wide column text center padding0" style="width: 10.5% !important;">
<span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}/{{if eq .Cloudbrain.Type 0 }}cloudbrain{{else}}modelarts{{end}}/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}">
<span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-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;">
<span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span>
</div>
<!-- 任务运行时间 -->
<div class="two wide column text center padding0" style="width: 10.5% !important;">
<span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span>
</div>
<!-- 计算资源 -->
<div class="two wide column text center padding0" style="width: 10.5% !important;">
<span style="font-size: 12px;">{{.ComputeResource}}</span>
</div>
<!-- 创建者 -->
<div class="one wide column text center padding0" style="width: 6% !important;">
{{if .User.Name}}
<a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a>
{{else}}
<a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a>
{{end}}
</div>

<div class="three wide column text center padding0" style="width: 18% !important;">
<!-- 停止任务 -->
{{if eq .Cloudbrain.Type 0 }}
<div class="ui compact buttons">
<form id="stopForm-{{.JobID}}" style="margin-left:-1px;">
{{$.CsrfTokenHtml}}
{{if .CanDel}}
<a id="ai-stop-{{.JobID}}"
class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button'
data-repopath="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/stop"
data-jobid="{{.JobID}}">
{{$.i18n.Tr "repo.stop"}}
</a>
{{else}}
<a class="ui basic disabled button">
{{$.i18n.Tr "repo.stop"}}
</a>
{{end}}
</form>
</div>
{{else}}
<div class="ui compact buttons">
{{$.CsrfTokenHtml}}
{{if .CanDel}}
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}} blue {{end}}button" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}">
{{$.i18n.Tr "repo.stop"}}
</a>
{{else}}
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{.JobID}}" class="ui basic disabled button">
{{$.i18n.Tr "repo.stop"}}
</a>
{{end}}

</div>
{{end}}
<!-- 下载 -->
<div class="ui compact buttons">
{{$.CsrfTokenHtml}}
{{if .CanModify}}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-download-{{.JobID}}" href="{{$.RepoLink}}/{{if eq .Cloudbrain.Type 0 }}cloudbrain{{else}}modelarts{{end}}/inference-job/{{.JobID}}/downloadall?version_name={{.VersionName}}" class="ui basic blue button" style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.model_download"}}
</a>
{{else}}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" class="ui basic button disabled" style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.model_download"}}
</a>
{{end}}
</div>
<!-- 删除任务 -->
<div class="ui compact buttons">
{{$.CsrfTokenHtml}}
{{if .CanDel}}
{{if eq .Cloudbrain.Type 0 }}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" data-repopath="{{$.RepoRelPath}}/cloudbrain/inference-job/{{.JobID}}/del" data-version="V0001" style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
</a>
{{else}}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job/{{.JobID}}/del_version" data-version="{{.VersionName}}" style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
</a>
{{end}}
{{else}}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" class="ui basic button disabled" style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
</a>
{{end}}
</div>
</div>
</div>
</div>
{{end}}
<div id="app" style="margin-top: 2rem;">
<div class="center">
<el-pagination
background
@current-change="handleCurrentChange"
:current-page="page"
:page-sizes="[10]"
:page-size="10"
layout="total, sizes, prev, pager, next, jumper"
:total="{{.Page.Paginater.Total}}">
</el-pagination>
</div>
</div>
</div>
{{template "custom/save_most_time" .}}
</div>
</div>
</div>
{{end}}

</div>

</div>
</div>

</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 id="__vue-root"></div>
</div>
<script src="{{StaticUrlPrefix}}/js/vp-cloudbrain-list.js?v={{MD5 AppVer}}"></script>
{{template "base/footer" .}}

<script>
let url = {{$.RepoLink}};
let all = {{$.i18n.Tr "repo.gpu_type_all"}}
$(document).ready(function(){
const params = new URLSearchParams(location.search)
if(!location.search){
$('.default.text').text(all)
}else{
if(!params.has('listType') || params.get('listType')=='all'){
$('.default.text').text(all)
}
else{
$('.default.text').text(params.get('listType'))
}
}
$('.ui.selection.dropdown').dropdown({
onChange:function(value){
location.href = `${url}/modelarts/inference-job?listType=${value}`
}
})
})
</script>


+ 1
- 577
templates/repo/modelarts/inferencejob/new.tmpl View File

@@ -1,577 +1 @@
{{template "base/head" .}}
<style>
.title{
font-size: 16px !important;
padding-left: 3rem !important;
}
.min_title{
font-size: 14px !important;
margin-bottom: 2rem !important;
}
.width80{
width: 80.7% !important;
}
.width{
width:100% !important;
}
.width85 {
width: 85% !important;
margin-left: 10.5rem !important;
align-items: center;
}
.width35{
width: 35.5% !important;
}

.width48{
width: 48.5% !important;
}
.nowrapx {
white-space: nowrap !important;
}
</style>
{{template "custom/global_mask" .}}
<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
{{template "custom/alert_cb" .}}
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="1" data-repo-link="{{.RepoLink}}"></div>
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new_infer"}}
</h4>
<div class="ui attached segment">
<!-- equal width -->
<form id="form_id" class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_engine_name" name="engine_names" value="">
<input type="hidden" id="ai_flaver_name" name="flaver_names" value="">

<input type="hidden" id="failed_train_url" value="{{$.train_url}}">
<input type="hidden" id="failed_model_name" value="{{$.model_name}}">
<input type="hidden" id="failed_model_version" value="{{$.model_version}}">
<input type="hidden" id="failed_ckpt_name" value="{{$.ckpt_name}}">
<input type="hidden" id="failed_train_url" value="{{$.train_url}}">
<input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}">
<input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}">

<h4 class="title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required min_title inline 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="item" href="{{.RepoLink}}/cloudbrain/inference-job/create">
<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="active item" href="{{.RepoLink}}/modelarts/inference-job/create">
<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 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 style="display: flex;align-items: center;margin-left: 156px;margin-top: 0.5rem;">
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.infer_dataset_path_rule" | Safe}}</span>
</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: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="36">
<span class="tooltips" style="margin-left:11.5rem;display: block;">{{.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>
{{if .description}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}}>{{.description}}</textarea>
{{else}}
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="255" 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)"></textarea>
{{end}}
</div>
<div class="ui divider"></div>
<h4 class="title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<!-- 模型相关配置 -->
<!--
<div class="required inline min_title fields" style="width: 94%;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>
<div class="six wide field">
<div class="ui fluid search selection dropdown loading " id="select_model">
<input type="hidden" name="model_name" required>
<div class="text"></div>
<i class="dropdown icon"></i>
<div class="menu" id="model_name">
</div>
</div>
</div>
<div class="three wide field">
<div class="ui fluid search selection dropdown" id="select_model_version">
<input type="hidden" name="train_url" required>
<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 search selection dropdown" id="select_model_checkpoint">
<input type="hidden" name="ckpt_name" required>
<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_path_rule"}} {{.i18n.Tr "cloudbrain.model_file_postfix_rule"}}" data-position="top center" data-variation="inverted mini"></i>
</span>
</div>
-->
<div>
<div class="select-multi-model" data-required="true" data-model-id="{{.model_id}}" data-model-name="{{.model_name}}" data-model-version="{{.model_version}}" data-multiple="true"
data-pre-train-model-url="{{.pre_train_model_url}}" data-ckpt-name="{{.ckpt_name}}"></div>
<div id="select-multi-model"></div>
</div>
<!-- AI引擎 -->
<div class="required inline min_title fields" style="width: 92.5%;">
<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 width" 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 width" 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>
<!-- 代码分支 -->
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width48" id="code_version" name="branch_name">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branch_name }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{else}}
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option>
{{range $k, $v :=.Branches}}
{{ if ne $v $.branchName }}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
{{end}}
</select>
</div>

<!-- 数据集 -->
<div id="select-multi-dataset">

</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span>
<div class="inline min_title field required">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
{{if .bootFile}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" >
{{else}}
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" >
{{end}}
<span >
<i class="question circle icon" data-content={{.i18n.Tr "repo.modelarts.infer_job.boot_file_helper"}} data-position="top center" data-variation="inverted mini"></i>
</span>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</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="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;">
{{if ne 0 (len .params)}}
{{range $k ,$v := .params}}
<div class="two fields width85" id="para{{$k}}">
<div class="field">
<input type="text" name="shipping_first-name" value={{$v.Label}} required>
</div>
<div class="field">
<input type="text" name="shipping_last-name" value={{$v.Value}} required>
</div>
<span>
<i class="trash icon"></i>
</span>

</div>
{{end}}
{{end}}
</div>
</div>

<div class="required field " style="display: none;">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label>
<select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id">
{{range .resource_pools}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
</select>
</div>
<!-- 规格 -->
<!--<div class="required min_title inline field" id="flaver_name">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<select class="ui dropdown width80" id="trainjob-flavor" name="flavor">
{{if .flavor}}
{{range .flavor_infos}}
{{if eq $.flavor .Code}}
<option value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
{{range .flavor_infos}}
{{if ne $.flavor .Code}}
<option value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
{{else}}
{{range .flavor_infos}}
<option name="flavor" value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
</select>
</div>-->
<div class="required min_title inline field" id="flaver_name">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<select class="ui dropdown width48" id="__specs__" name="spec_id" ovalue="{{.spec_id}}" {{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}></select>
<span><i class="question circle icon link" data-content="{{.i18n.Tr "repo.modelarts.train_job.resource_helper"}}" data-position="right center" data-variation="mini"></i></span>
<a href="https://openi.pcl.ac.cn/docs/index.html#/quickstart/resources" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{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"></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
{{end}}
</div>
<!-- 计算节点 -->
<div class="inline required min_title field">
<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;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly>
</div>
</div>
<!-- 表单操作 -->
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;"></label>
<button class="ui create_train_job green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
<!-- 模态框 -->
</form>
</div>
</div>
</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.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
}
const RepoLink = {{.RepoLink}}
const url_href = window.location.pathname.split('create')[0]
let nameMap,nameList
$(".ui.button").attr('href',url_href)
// 获取模型列表和模型名称对应的模型版本

$(document).ready(function(){
return; // 用模型选择组件了
modelVersion()
modelCkpt()
$.get(`${RepoLink}/modelmanage/query_model_for_predict?type=1`, (data) => {
nameMap = data.nameMap
nameList = data.nameList
let faildModelName = document.getElementById('failed_model_name').value
let html = ''
nameList.forEach(element => {
html += `<div class="item" data-value="${element}">${element}</div>`
});
if(nameList.length!==0){
$('#model_name').append(html)
if(faildModelName){
$("#select_model").dropdown('set text',faildModelName)
$("#select_model").dropdown('set value',faildModelName)
}else{
$("#select_model").dropdown('set text',nameList[0])
$("#select_model").dropdown('set value',nameList[0],nameList[0])
}
}
$('#select_model').removeClass("loading")
})
})

// 根据选中的模型名称获取相应的模型版本
function modelVersion(){
let faildModelVersion = $('#failed_model_version').val()
let faildTrainUrl = $('#failed_train_url').val()
$('#select_model').dropdown({
onChange: function(value, text, $selectedItem) {
$("#select_model_version").addClass("loading")
$('#model_name_version').empty()
let html = ''
nameMap[value].forEach(element => {
html += `<div class="item" data-label="${element.label}" data-id="${element.id}" data-value="${element.path}">${element.version}</div>`
});
$('#model_name_version').append(html)
$("#select_model_version").removeClass("loading")
const initVersionText = $('#model_name_version div.item:first-child').text()
const initVersionValue = $('#model_name_version div.item:first-child').data('value')

if(faildModelVersion&&faildTrainUrl){
$("#select_model_version").dropdown('set text',faildModelVersion)
$("#select_model_version").dropdown('set value',faildTrainUrl,faildModelVersion,$('#model_name_version div.item:first-child'))
}else{
$("#select_model_version").dropdown('set text',initVersionText)
$("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
}
}
})
}
// 根据选中的模型版本获取相应的模型权重文件
function modelCkpt(){
let faildCkptName = $('#failed_ckpt_name').val()
$('#select_model_version').dropdown({
onChange: function(value, text, $selectedItem) {
const dataID = $selectedItem[0].getAttribute("data-id")
const label = $selectedItem[0].getAttribute("data-label")
$("#select_model_checkpoint").addClass("loading")
$("#model_checkpoint").empty()
let html = ''
loadCheckpointList(dataID).then((res)=>{
res.forEach(element => {
const ckptSuffix = element.FileName.split(".")
const loadCheckpointFile = ['ckpt','pb','h5','json','pkl','pth','t7','pdparams','onnx','pbtxt','keras','mlmodel','cfg','pt']
if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){
html += `<div class="item" data-value="${element.FileName}">${element.FileName}</div>`
}
})
$('#model_checkpoint').append(html)
$("#select_model_checkpoint").removeClass("loading")
const initVersionText = $('#model_checkpoint div.item:first-child').text()
const initVersionValue = $('#model_checkpoint div.item:first-child').data('value')
if(faildCkptName){
$("#select_model_checkpoint").dropdown('set text',faildCkptName)
$("#select_model_checkpoint").dropdown('set value',faildCkptName,faildCkptName,$('#model_name_version div.item:first-child'))
}else{
$("#select_model_checkpoint").dropdown('set text',initVersionText)
$("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child'))
}
})
$("input#ai_model_version").val(text)
$("input#ai_model_label").val(label)
}
})
}
function loadCheckpointList(value){
return new Promise((resolve,reject)=>{
$.get(`${RepoLink}/modelmanage/query_modelfile_for_predict`,{id:value}, (data) => {
resolve(data)
})
})
}

$('.question.circle.icon').hover(function(){
$(this).popup('show')
});

// 参数增加、删除、修改、保存
function Add_parameter(i){
let placeholder_value='{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}'
let placeholder_name='{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}'
value = '<div class="two fields width85" id= "para'+ i +'">' +
'<div class="field">' +
'<input type="text" name="shipping_first-name" required placeholder="' + placeholder_name+ '">' +
'</div> ' +
'<div class="field"> ' +
'<input type="text" name="shipping_last-name" required placeholder="' + placeholder_value + '">' +
'</div>'+
'<span>' +
'<i class="trash icon">' +
'</i>' +
'</span>' +
'</div>'
$(".dynamic.field").append(value)
}

$('#add_run_para').click(function(){
var len = $(".dynamic.field .two.fields").length
Add_parameter(len)
});

$(".dynamic.field").on("click",".trash.icon", function() {
var index = $(this).parent().parent().index()
$(this).parent().parent().remove()
var len = $(".dynamic.field .two.fields").length
$(".dynamic.field .two.fields").each(function(){
var cur_index = $(this).index()
$(this).attr('id', 'para' + cur_index)
})
});
function send_run_para(){
var run_parameters = []
var msg = {}
$(".dynamic.field .two.fields").each(function(){
var para_name = $(this).find('input[name=shipping_first-name]').val()
var para_value = $(this).find('input[name=shipping_last-name]').val()
run_parameters.push({"label": para_name, "value": para_value})
})
msg["parameter"] = run_parameters
msg = JSON.stringify(msg)
$('#store_run_para').val(msg)
}
function get_name(){
let name1=$("#engine_name .text").text()
let name2=$("#flaver_name .text").text()
$("input#ai_engine_name").val(name1)
$("input#ai_flaver_name").val(name2)
}

var isValidate = false;
function validate(){
$('.ui.form')
.form({
on: 'blur',
fields: {
boot_file: {
identifier : 'boot_file',
rules: [
{
type: 'regExp[/.+\.py$/g]',
}
]
},
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',
}
]

},
model_name:{
identifier : 'model_name',
rules: [
{
type: 'empty',
}
]
},
train_url:{
identifier : 'train_url',
rules: [
{
type: 'empty',
}
]
},
ckpt_name:{
identifier : 'ckpt_name',
rules: [
{
type: 'empty',
}
]
},
spec_id: {
identifier: 'spec_id',
rules: [{ type: 'empty' }]
}
},
onSuccess: function(){
document.getElementById("mask").style.display = "block"
isValidate = true;
},
onFailure: function(e){
isValidate = false;
return false;
}
})
}
document.onreadystatechange = function() {
if (document.readyState === "complete") {
document.getElementById("mask").style.display = "none"
}
}
validate();
$('.ui.create_train_job.green.button').click(function(e) {
send_run_para()
get_name()
validate();
})

;(function() {
var 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"}},
no_use_resource:{{$.i18n.Tr "cloudbrain.no_use_resource"}},
});
})();
</script>
{{ template "repo/cloudbrain/cloudbraincreate" .}}

+ 1
- 435
templates/repo/modelarts/inferencejob/show.tmpl View File

@@ -1,435 +1 @@
{{template "base/head" .}}
<style>
.model_file_bread{
margin-bottom: -0.5rem !important;
padding-left: 1rem;
padding-top: 0.5rem ;
}
</style>
<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}}/modelarts/inference-job">
{{$.i18n.Tr "repo.modelarts.infer_job"}}
</a>
<div class="divider"> / </div>
<div class="active section">{{.displayJobName}}</div>
</div>
</h4>
{{with .task}}
<div class="ui accordion border-according" id="accordion{{.VersionName}}"
data-repopath="{{$.RepoRelPath}}/modelarts/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}">
<input type="hidden" id="jobId_input" name="jobId_input" value="{{.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">{{TimeSinceUnix1 .CreatedUnix}}</span>

<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}:
<span id="{{.VersionName}}-status-span"><i id="icon"
style="vertical-align: middle;" class="{{.Status}}"></i><span id="text"
style="margin-left: 0.4em;font-size: 12px;">{{.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="{{.VersionName}}-duration-span">{{.TrainJobDuration}}</span>
<span class="refresh-status" data-tooltip="刷新" style="cursor: pointer;" data-inverted="" data-version="{{.VersionName}}"><i
class="redo icon redo-color"></i></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="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a>
<a class="item detail-log-tab" data-tab="second" data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a>
<a class="item load-model-file" data-tab="third" data-download-flag="{{$.canDownload}}" data-path="{{$.RepoLink}}/modelarts/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a>
</div>

<div class="ui tab active" data-tab="first">
<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">
{{.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="{{.VersionName}}-status">
{{.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.run_version"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.VersionName}}
</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_time"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
<span style="font-size: 12px;" id="{{.VersionName}}-startTime">
{{if not (eq .StartTime 0)}}
{{TimeSinceUnix1 .StartTime}}
{{else}}
--
{{end}}
</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.modelarts.train_job.dura_time"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-duration">
{{.TrainJobDuration}}
</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.AI_driver"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.EngineName}}
</div>
</td>

</tr>

<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.model.manage.description"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-desc" style="width: 380px;">
{{if .Description}}
<span title="{{.Description}}">{{.Description}}</span>
{{else}}
<span>--</span>
{{end}}
</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="{{.VersionName}}-creator">
{{$.userName}}
</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.compute_node"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.WorkServerNumber}}
</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.infer_job_model"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
<span>{{.ModelName}}</span>&nbsp;&nbsp;
<span style="color: #8a8e99">{{$.i18n.Tr "repo.modelarts.version"}}:</span><span>{{.ModelVersion}}</span>&nbsp;&nbsp;

</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">
{{.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.modelarts.model_label"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-labels">

{{if .LabelName}}
{{range $.labelName}}
<a class="ui label" title="{{.}}">{{.}}</a>
{{end}}
{{else}}
<span>--</span>
{{end}}
</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.code_version"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.BranchName}}
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</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.modelarts.train_job.start_file"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.BootFile}}
</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" title="{{.Parameters}}">
{{if .Parameters}}
<span>{{.Parameters}}</span>
{{else}}
<span>--</span>
{{end}}
</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>
</tbody>
</table>
</div>
</div>
<div style="clear:both">
<table style="border:none" class="ui fixed small stackable table">
<thead>
<tr><th style="color: #8a8e99;font-size:12px" class="three wide left aligned">{{$.i18n.Tr "dataset.file"}}</th>
</tr></thead>
<tbody>
{{range $m ,$n := $.datasetDownload}}
<tr>
<td style="word-wrap: break-word;word-break: break-all;">
{{if eq .IsDelete true}}
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}})
{{else}}
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a>
{{end}}
</td>
</tr>
{{end}}

</tbody>
</table>
</div>
</div>

</div>
</div>

<div class="ui tab" data-tab="second">
<!--
<div class="file-info">
<a id="{{.VersionName}}-log-down"
class='{{if and ($.canDownload) (eq .Status "KILLED" "FAILED" "START_FAILED" "STOPPED" "COMPLETED") }}ti-download-file{{else}}disabled{{end}} file-info'
href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/download_log_file?version_name={{.VersionName}}">
<i class="ri-download-cloud-2-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span>
</a>
<div class="file-info full-log-dialog" data-version="{{.VersionName}}" data-log="{{$.i18n.Tr "repo.modelarts.log_file"}}"
data-exit="{{$.i18n.Tr "repo.modelarts.exit_full_screen"}}" style="margin-left: 1rem;color:#0366d6;cursor: pointer;"
data-log-down="{{$.i18n.Tr "repo.modelarts.download_log"}}" data-href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/download_log_file?version_name={{.VersionName}}"
data-scroll-top="{{$.i18n.Tr "repo.log_scroll_start"}}" data-scroll-bottom="{{$.i18n.Tr "repo.log_scroll_end"}}">
<i class="ri-aspect-ratio-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.fullscreen_log_file"}}</span>
</div>
</div>
<div style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;">
<span>
<a title="{{$.i18n.Tr "repo.log_scroll_start"}}" style="position: absolute; right: -32px;cursor: pointer;"
class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a>
</span>
<span class="log-info-{{.VersionName}}">
<a title="{{$.i18n.Tr "repo.log_scroll_end"}}" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;"
class="log_bottom" data-version="{{.VersionName}}"><i
class="icon-to-bottom"></i></a>
</span>
<div class="ui message message{{.VersionName}}" style="display: none;">
<div id="header"></div>
</div>
<div class="ui attached log log-scroll" data-version="{{.VersionName}}" id="log{{.VersionName}}" 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="end_line-max" value>
<input type="hidden" name="start_line-max" value>
<input type="hidden" name="start_line-max-copy" value>
<input type="hidden" name="start_line" value>
<input type="hidden" name="init_log" value>
<pre id="log_file{{.VersionName}}"></pre>
</div>

</div>
-->
<div class="detail-log-content detail-log-content-{{.VersionName}}"
data-multiplenode=""
data-logapiurl="{{$.RepoLink}}/modelarts/inference-job/{{.JobID}}/log"
data-logdownloadurl="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/download_log_file"
data-workservernumber="{{.WorkServerNumber}}"
data-version="{{.VersionName}}">
{{template "custom/task_log" Dict "$" $ "i18n" $.i18n }}
</div>
<div class="ui modal full-log-dlg-{{.VersionName}} container" style="height:90%;margin:3rem auto;">
<div id="log-file-title" style="font-size: 16px;font-weight:600;padding:20px 30px 16px;">{{$.i18n.Tr "repo.modelarts.log_file"}}</div>
<div style="padding:0 50px 10px 30px;height:100%">
<div class="detail-log-fullscreen-content detail-log-fullscreen-content-{{.VersionName}}" style="height:100%;"
data-multiplenode=""
data-logapiurl="{{$.RepoLink}}/modelarts/inference-job/{{.JobID}}/log"
data-logdownloadurl="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/download_log_file"
data-workservernumber="{{.WorkServerNumber}}"
data-version="{{.VersionName}}">
{{template "custom/task_log" Dict "$" $ "i18n" $.i18n "Full" true }}
</div>
</div>
</div>
</div>
<div class="ui tab" data-tab="third">
<input type="hidden" name="model{{.VersionName}}" value="-1">
<input type="hidden" name="modelback{{.VersionName}}" value="-1">
<div style="display: flex;justify-content: space-between;">
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'>
<div class="active section">result</div>
<div class="divider"> / </div>
</div>
<a id="{{.VersionName}}-result-down" style="padding-right: 1%;display: none;"
class='{{if $.canDownload}}ti-download-file{{else}}disabled{{end}} file-info'
href="{{$.RepoLink}}/modelarts/inference-job/{{.JobID}}/downloadall?version_name={{.VersionName}}">
<i class="ri-download-cloud-2-line"></i>
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.all_result_download"}}</span>
</a>
</div>
<div id="dir_list{{.VersionName}}">

</div>
</div>

</div>
</div>
</div>
<!-- {{template "custom/max_log" .}} -->
{{end}}
</div>
<!-- 确认模态框 -->
</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
console.log('{{$.canDownload}}')
$(document).ready(function(){
$('.secondary.menu .item').tab();
});
let userName
let repoPath
let jobID
let downlaodFlag = {{$.canDownload }}
$(document).ready(function(){
let url = window.location.href;
let urlArr = url.split('/')
userName = urlArr.slice(-5)[0]
repoPath = urlArr.slice(-4)[0]
jobID = urlArr.slice(-1)[0]
})
;(function() {
var SPEC = {{ .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"}},
no_use_resource:{{$.i18n.Tr "cloudbrain.no_use_resource"}},
});
$('td.ti-text-form-content.spec div').text(specStr);
})();
</script>
{{ template "repo/cloudbrain/cloudbraindetail" .}}

+ 10
- 25
templates/repo/modelmanage/convertshowinfo.tmpl View File

@@ -273,7 +273,9 @@ td, th {
<td class="ti-text-form-content">
<div class="text-span text-span-w">
<span style="font-size: 12px;" class="">{{TimeSinceUnix1 .CreatedUnix}}</span>
<span style="font-size: 12px;" class="">
{{if eq .StartTime 0}}--{{else}}{{TimeSinceUnix1 .StartTime}} {{end}}
</span>
</div>
</td>
</tr>
@@ -686,33 +688,17 @@ td, th {
function parseInfo(){
let jsonValue = document.getElementById("json_value").value;
let jsonObj = JSON.parse(jsonValue);
let podRoleName = jsonObj["podRoleName"];
let jobEvents = jsonObj["jobEvents"];
let html = "";
if (podRoleName != null){
let task0 = podRoleName["task1-0"];
let podEvents = jsonObj["podEvents"];
let podEventArray = podEvents[task0];
if(podEventArray != null){
for(var i=0; i < podEventArray.length;i++){
if (podEventArray[i]["reason"]!="") {
html +="<p><b>[" +podEventArray[i]["reason"] + "]</b></p>";
html +="<p>" +podEventArray[i]["message"] + "</p>";
html +="<p>" +podEventArray[i]["action"] + "</p>";
if (jobEvents != null){
for(var i=0; i < jobEvents.length;i++){
if (jobEvents[i]["reason"]!="") {
let time = jobEvents[i]["timestamp"] && new Date(jobEvents[i]["timestamp"])
html +="<p><b>[" +jobEvents[i]["reason"] + "]</b> <span>"+time.toLocaleString()+"</span></p>";
html +="<p>" +jobEvents[i]["message"] + "</p>";
}
}
}
let extras= jsonObj["extras"];
if(extras != null){
for(var i=0; i < extras.length;i++){
if (extras[i]["reason"]!="") {
html +="<p><b>[" +extras[i]["reason"] + "]</b></p>";
html +="<p>" +extras[i]["message"] + "</p>";
html +="<p>" +extras[i]["action"] + "</p>";
}
}
}
}

let string = document.getElementById("ExitDiagnostics").value;
string = string.replace(/\r\n/g,"<br>")
string = string.replace(/\n/g,"<br>");
@@ -722,7 +708,6 @@ td, th {
html +="<p><b>[ExitDiagnostics]</b></p>";
html +="<p>" +string + "</p>";
}
document.getElementById("info_display").innerHTML=html;
}


+ 2
- 27
templates/repo/modelsafety/new.tmpl View File

@@ -68,39 +68,14 @@
<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"
<a class="item active model_safe_benchmark"
href="{{.Link}}">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
</div>
</div>
<!-- <div class="required 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">


+ 1
- 1
templates/terms.tmpl View File

@@ -21,7 +21,7 @@
您充分理解并同意,您在使用平台服务时,应当遵守所有中华人民共和国的法律、法规、规章制度、规范、政策、行政命令、强制标准及行业标准等(统称为“法律法规”)。除非法律法规允许且启智社区事先书面许可,您不得从事以下活动,也不得同意、授权或指示任何第三人从事包括但不限于以下内容的活动:
<br>
(1) 对平台服务进行挖矿、逆向工程、反编辑等恶意行为损坏平台服务相关内容与数据,或不正当手段获取原始数据和其他数据等;<br>
(2) 对平台服务或者平台服务运行过程中释放出的任何数据或其他数据及平台服务运行过程中的交互数据进行复制、更改、修改等操作,包括但不限于使用插件、外挂或非经授权的第三方工具或服务接入平台服务和相关系统;
(2) 对平台服务或者平台服务运行过程中释放出的任何数据或其他数据及平台服务运行过程中的交互数据进行复制、更改、修改等操作,包括但不限于使用插件、外挂或非经授权的第三方工具(如内网穿透工具)或服务接入平台服务和相关系统;
<br>
(3) 宣扬或提供关于非法行为的说明信息、宣扬针对任何团体或个人的人身伤害或传播任何病毒、蠕虫、缺陷、特洛伊木马或其他具有破坏性的内容等;<br>
(4) 删除本平台服务中包含的任何版权声明、商标声明或其他所有权声明;包括但不限于任何有损本平台一切相关知识产权的行为;<br>


+ 16
- 0
templates/user/auth/network_security.tmpl View File

@@ -0,0 +1,16 @@
<div class="ui tiny modal network-security" data-update='{{.i18n.Tr "auth.protocol_update"}}' data-confirm='{{.i18n.Tr "auth.protocol_confirm"}}'>
<div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);font-size: 1rem;">{{.i18n.Tr "auth.protocol_header"}}</div>
<div class="content">
<p>{{.i18n.Tr "auth.protocol_title"}}</p>
<p style="text-indent: 2rem;">
{{.i18n.Tr "auth.protocol_context" | Safe}}
</p>
<p></p>
<p>{{.i18n.Tr "auth.protocol_context_sub" | Safe}}</p>
</div>
<div class="actions" style="border: none;text-align: center;padding: 0 1rem 2rem 1rem;background-color: #fff;">
<div class="ui green approve button">{{.i18n.Tr "auth.protocol_confirm"}}</div>
<div class="ui blank cancel button">{{.i18n.Tr "auth.protocol_cancel"}}</div>
</div>
</div>
</div>

+ 2
- 2
templates/user/auth/signin_navbar.tmpl View File

@@ -8,9 +8,9 @@
<a class="{{if .PageIsLogin}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login">
{{.i18n.Tr "phone.account_password_login"}}
</a>
<a class="{{if .PageIsCloudBrainLogin}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/cloud_brain">
<!--<a class="{{if .PageIsCloudBrainLogin}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/cloud_brain">
{{.i18n.Tr "phone.cloud_brain_user_login"}}
</a>
</a>-->
{{if .EnableOpenIDSignIn}}
<a class="{{if .PageIsLoginOpenID}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/openid">
<i class="fa fa-openid"></i>


+ 4
- 4
templates/user/dashboard/cloudbrains.tmpl View File

@@ -72,7 +72,7 @@
<div class="row">
<!-- 任务名 -->
{{$JobID := '0'}}
{{if eq .JobType "DEBUG" "TRAIN" "HPC" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK" "MODELSAFETY" "SNN4ECOSET" "SIM2BRAIN_SNN" "ONLINEINFERENCE"}}
{{if eq .JobType "DEBUG" "TRAIN" "INFERENCE" "HPC" "SNN4IMAGENET" "BRAINSCORE" "BENCHMARK" "MODELSAFETY" "SNN4ECOSET" "SIM2BRAIN_SNN" "ONLINEINFERENCE"}}
{{$JobID = .Cloudbrain.ID}}
{{else}}
{{$JobID = .JobID}}
@@ -102,7 +102,7 @@
</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}}"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 2}}grampus{{else if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}"
title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px">
<span class="fitted"
style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
@@ -321,7 +321,7 @@
</form>
{{else}}
<form class="ui compact buttons" id="delForm-{{$JobID}}"
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE") (eq .JobType "SNN4ECOSET") (eq .JobType "SIM2BRAIN_SNN")}}/cloudbrain{{else if eq .JobType "DEBUG" "ONLINEINFERENCE" "HPC"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true'
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE") (eq .JobType "SNN4ECOSET") (eq .JobType "SIM2BRAIN_SNN")}}/cloudbrain{{else if eq .JobType "DEBUG" "ONLINEINFERENCE" "HPC"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true'
method="post">
{{$.CsrfTokenHtml}}
<input type="hidden" value="{{.Cloudbrain.ID}}" style="display:none" name="id" />
@@ -380,7 +380,7 @@
<div class="two wide column text center nowrap"
style="padding-left: 2.2rem !important; width: 8% !important;">
<span class="job-status" id="{{$JobID}}"
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG" "ONLINEINFERENCE" "HPC"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{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-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG" "ONLINEINFERENCE" "HPC"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/train-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK" "MODELSAFETY"}}/cloudbrain{{end}}'
data-jobid="{{$JobID}}" data-version="{{.VersionName}}"
data-cloudbrainid="{{.Cloudbrain.ID}}" data-datamigrate='{{$.i18n.Tr "repo.migratingData"}}' data-centerpend='{{$.i18n.Tr "repo.centerPending"}}'>
<span>


+ 21
- 1
templates/user/dashboard/feeds.tmpl View File

@@ -91,7 +91,23 @@
{{$.i18n.Tr "action.task_nputrainjob" "" "" "" | Str2html}}<span style="">{{.RefName}}{{$.i18n.Tr "repo.issues.deleted_milestone"}}</span>
{{end}}
{{else if eq .GetOpType 28}}
{{$.i18n.Tr "action.task_inferencejob" .GetRepoLink .Content .RefName | Str2html}}
{{if .Cloudbrain}}
{{$.i18n.Tr "action.task_inferencejob" .GetRepoLink (Printf "%d" .Cloudbrain.ID) .RefName | Str2html}}
{{else}}
{{$.i18n.Tr "action.task_inferencejob" "" "" "" | Str2html}}<span style="">{{.RefName}}{{$.i18n.Tr "repo.issues.deleted_milestone"}}</span>
{{end}}
{{else if eq .GetOpType 50}}
{{if .Cloudbrain}}
{{$.i18n.Tr "action.task_c2net_gpu_inferencejob" .GetRepoLink (Printf "%d" .Cloudbrain.ID) .RefName | Str2html}}
{{else}}
{{$.i18n.Tr "action.task_c2net_gpu_inferencejob" "" "" "" | Str2html}}<span style="">{{.RefName}}{{$.i18n.Tr "repo.issues.deleted_milestone"}}</span>
{{end}}
{{else if eq .GetOpType 51}}
{{if .Cloudbrain}}
{{$.i18n.Tr "action.task_c2net_gpgpu_iluvatar_inferencejob" .GetRepoLink (Printf "%d" .Cloudbrain.ID) .RefName | Str2html}}
{{else}}
{{$.i18n.Tr "action.task_c2net_gpgpu_iluvatar_inferencejob" "" "" "" | Str2html}}<span style="">{{.RefName}}{{$.i18n.Tr "repo.issues.deleted_milestone"}}</span>
{{end}}
{{else if eq .GetOpType 29}}
{{$.i18n.Tr "action.task_benchmark" .GetRepoLink .Content .RefName | Str2html}}
{{else if eq .GetOpType 30}}
@@ -241,6 +257,10 @@
<span class="text grey"><i class="ri-character-recognition-line icon big"></i></span>
{{else if eq .GetOpType 28}}
<span class="text grey"><i class="ri-haze-2-line icon big"></i></span>
{{else if eq .GetOpType 50}}
<span class="text grey"><i class="ri-haze-2-line icon big"></i></span>
{{else if eq .GetOpType 51}}
<span class="text grey"><i class="ri-haze-2-line icon big"></i></span>
{{else if eq .GetOpType 29}}
<span class="text grey"><i class="ri-vip-crown-line icon big"></i></span>
{{else if eq .GetOpType 30}}


+ 4
- 4
web_src/js/components/dataset/selectDataset.vue View File

@@ -180,7 +180,7 @@
class="unzip-failed"
v-if="data.Size > exceedSize"
>
{{ i18n.dataset_exceeds_failed }}{{exceedSize/(1000*1000*1000)}}G
{{ i18n.dataset_exceeds_failed }}{{exceedSize/(1024*1024*1024)}}G
</span>
</span>
</span>
@@ -292,7 +292,7 @@
class="unzip-failed"
v-if="data.Size > exceedSize"
>
{{ i18n.dataset_exceeds_failed }}{{exceedSize/(1000*1000*1000)}}G
{{ i18n.dataset_exceeds_failed }}{{exceedSize/(1024*1024*1024)}}G
</span>
</span>
</span>
@@ -404,7 +404,7 @@
class="unzip-failed"
v-if="data.Size > exceedSize"
>
{{ i18n.dataset_exceeds_failed }}{{exceedSize/(1000*1000*1000)}}G
{{ i18n.dataset_exceeds_failed }}{{exceedSize/(1024*1024*1024)}}G
</span>
</span>
</span>
@@ -516,7 +516,7 @@
class="unzip-failed"
v-if="data.Size > exceedSize"
>
{{ i18n.dataset_exceeds_failed }}{{exceedSize/(1000*1000*1000)}}G
{{ i18n.dataset_exceeds_failed }}{{exceedSize/(1024*1024*1024)}}G
</span>
</span>
</span>


+ 2
- 0
web_src/js/features/i18nVue.js View File

@@ -5,6 +5,7 @@ export const i18nVue = {
speech_processing: "语音处理",
computer_vision_natural_language_processing: "计算机视觉、自然语言处理",
machine_translation: "机器翻译",
medical_imaging: "医学影像",
question_answering_system: "问答系统",
information_retrieval: "信息检索",
knowledge_graph: "知识图谱",
@@ -226,6 +227,7 @@ export const i18nVue = {
computer_vision_natural_language_processing:
"computer vision and natural language processing",
machine_translation: "machine translation",
medical_imaging: "medical imaging",
question_answering_system: "question answering system",
information_retrieval: "information retrieval",
knowledge_graph: "knowledge graph",


+ 54
- 0
web_src/js/index.js View File

@@ -1179,6 +1179,7 @@ async function initRepository() {
headers: { "X-Csrf-Token": csrf },
maxFiles: $dropzone.data("max-file"),
maxFilesize: $dropzone.data("max-size"),
filesizeBase: 1024,
acceptedFiles:
$dropzone.data("accepts") === "*/*"
? null
@@ -2828,6 +2829,7 @@ $(document).ready(async () => {
headers: { "X-Csrf-Token": csrf },
maxFiles: $dropzone.data("max-file"),
maxFilesize: $dropzone.data("max-size"),
filesizeBase: 1024,
acceptedFiles:
$dropzone.data("accepts") === "*/*" ? null : $dropzone.data("accepts"),
addRemoveLinks: true,
@@ -5392,3 +5394,55 @@ initTopToHome();
$(".question.circle.icon").hover(function () {
$(this).popup("show");
});


function initAddUsageAgreement() {
function showLoginProtocolDialog(userName) {
let cutDown = 5
let updateTips = $('.ui.modal.network-security').data('update')
let confirmTips = $('.ui.modal.network-security').data('confirm')
$('.ui.modal.network-security')
.modal({
centered: false,
onShow: function () {
$('.ui.dimmer').css({ "background-color": "rgb(136, 136, 136,0.7)" })
$('.network-security .approve').addClass('disabled').text(`${updateTips} (${cutDown}s)`)
var timer = setInterval(function () {
cutDown--
$('.network-security .approve').addClass('disabled').text(`${updateTips} (${cutDown}s)`)
if (cutDown <= 0) {
$('.network-security .approve').removeClass('disabled').text(confirmTips)
clearInterval(timer);
}
}, 1000);
},
onHide:function(){
},
onApprove: async function ($element) {
try {
const res = await postSaveProtocolInfo(userName)
if (res?.data?.result_code === "0") {
return true
} else {
return false
}
} catch (err) {
console.log(err)
}
},
onDeny: function () {
$(".link-action").trigger("click");
},
})
.modal('setting', 'closable', false)
.modal('show')
}
async function postSaveProtocolInfo(userName) {
let params = {userName:userName}
return axios.post(`${AppSubUrl}/user/saveOtherInfo`,qs.stringify(params))
}
if ($('meta[name="_uid"]').length) {
showLoginProtocolDialog($('meta[name="_uid"]').attr('content-ext'))
}
}
initAddUsageAgreement()

+ 3
- 0
web_src/less/openi.less View File

@@ -1616,4 +1616,7 @@ i.SUCCEEDED {
.ui.secondary.menu #navbar .right.menu .ui.item.simple {
padding: 0.78571429em 0.42857143em;
margin: 0 0.15714286em;
}
.ui.tiny.modal.network-security{
top:20vh !important;
}

+ 1
- 1
web_src/vuepages/components/cloudbrain/DatasetSelect.vue View File

@@ -78,7 +78,7 @@
{{ $t('datasetObj.dataset_unzip_failed') }}
</span>
<span class="unzip-failed" v-if="useExceedSize && exceedSize && data.Size > exceedSize">
{{ $t('datasetObj.dataset_exceeds_failed') }}{{ exceedSize / (1000 * 1000 * 1000) }}G
{{ $t('datasetObj.dataset_exceeds_failed') }}{{ exceedSize / (1024 * 1024 * 1024) }}G
</span>
</span>
</span>


+ 1
- 1
web_src/vuepages/const/index.js View File

@@ -12,7 +12,7 @@ export const JOB_TYPE = [{ k: 'DEBUG', v: i18n.t('debugTask') }, { k: 'TRAIN', v
export const CLUSTERS = [{ k: 'OpenI', v: i18n.t('resourcesManagement.OpenI') }, { k: 'C2Net', v: i18n.t('resourcesManagement.C2Net') }];
export const AI_CENTER = [{ k: 'OpenIOne', v: i18n.t('resourcesManagement.OpenIOne') }, { k: 'OpenITwo', v: i18n.t('resourcesManagement.OpenITwo') }, { k: 'OpenIChengdu', v: i18n.t('resourcesManagement.OpenIChengdu') }, { k: 'pclcci', v: i18n.t('resourcesManagement.pclcci') }, { k: 'hefei', v: i18n.t('resourcesManagement.hefeiCenter') }, { k: 'xuchang', v: i18n.t('resourcesManagement.xuchangCenter') }];
export const COMPUTER_RESOURCES = [{ k: 'CPU', v: 'CPU' }, { k: 'GPU', v: 'GPU' }, { k: 'NPU', v: 'NPU' }, { k: 'GCU', v: 'GCU' }, { k: 'MLU', v: 'MLU' }, { k: 'DCU', v: 'DCU' }, { k: 'ILUVATAR-GPGPU', v: 'ILUVATAR-GPGPU' }, { k: 'METAX-GPGPU', v: 'METAX-GPGPU' }];
export const ACC_CARD_TYPE = [{ k: 'T4', v: 'T4' }, { k: 'A100', v: 'A100' }, { k: 'V100', v: 'V100' }, { k: 'ASCEND910', v: 'Ascend 910' }, { k: 'MLU270', v: 'MLU270' }, { k: 'MLU290', v: 'MLU290' }, { k: 'RTX3080', v: 'RTX3080' }, { k: 'ENFLAME-T20', v: 'ENFLAME-T20' }, { k: 'DCU', v: 'DCU' }, { k: 'BI-V100', v: 'BI-V100' }, { k: 'MR-V100', v: 'MR-V100' }, { k: 'N100', v: 'N100' }];
export const ACC_CARD_TYPE = [{ k: 'T4', v: 'T4' }, { k: 'A100', v: 'A100' }, { k: 'V100', v: 'V100' }, { k: 'ASCEND910', v: 'Ascend 910' }, { k: 'ASCEND-D910B', v: 'Ascend-D910B' }, { k: 'MLU270', v: 'MLU270' }, { k: 'MLU290', v: 'MLU290' }, { k: 'RTX3080', v: 'RTX3080' }, { k: 'ENFLAME-T20', v: 'ENFLAME-T20' }, { k: 'DCU', v: 'DCU' }, { k: 'BI-V100', v: 'BI-V100' }, { k: 'MR-V100', v: 'MR-V100' }, { k: 'N100', v: 'N100' }];
export const SPECIFICATION_STATUS = [{ k: '1', v: i18n.t('resourcesManagement.willOnShelf') }, { k: '2', v: i18n.t('resourcesManagement.onShelf') }, { k: '3', v: i18n.t('resourcesManagement.offShelf') }];
export const NETWORK_TYPE = [{ k: 1, v: `${i18n.t('cloudbrainObj.networkType')}(${i18n.t('cloudbrainObj.noInternet')})` }, { k: 2, v: `${i18n.t('cloudbrainObj.networkType')}(${i18n.t('cloudbrainObj.hasInternet')})` }];
export const NETWORK_TYPE_VALUE = [{ k: 1, v: i18n.t('cloudbrainObj.noInternet') }, { k: 2, v: i18n.t('cloudbrainObj.hasInternet') }];


+ 13
- 7
web_src/vuepages/langs/config/en-US.js View File

@@ -476,6 +476,7 @@ const en = {
computer_vision_natural_language_processing:
"computer vision and natural language processing",
machine_translation: "machine translation",
medical_imaging: "medical imaging",
question_answering_system: "question answering system",
information_retrieval: "information retrieval",
knowledge_graph: "knowledge graph",
@@ -538,14 +539,16 @@ const en = {
computeResource: 'Computing resources',
sameTaskTips1: 'You have created an <span>equivalent task</span> that is waiting or running, please wait for the task to finish before creating it.',
sameTaskTips2: 'You can view all your Cloud Brain tasks in <a href="/cloudbrains" target="_blank"> Home &gt; Cloudbrain Task </a>.',
pathTips1: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the dataset is storaged in <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online',
pathTips11: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the dataset is storaged in <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online',
pathTips2: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the dataset is storaged in <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online',
pathTips1: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the dataset is storaged in <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online.',
pathTips11: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the dataset is storaged in <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online.',
pathTips2: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the dataset is storaged in <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online.',
pathTips3: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the dataset is storaged in <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the <strong style="color:#010101">{model}</strong>.',
pathTips4: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online',
pathTips4: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online.',
pathTips5: 'The dataset is stored in <strong style="color:#010101">{dataset}</strong>, the model file is stored in <strong style="color:#010101">{model}</strong>, please store the inference output in <strong style="color:#010101">{output}</strong> for subsequent downloads.',
pathTips6: 'The dataset location is stored in the run parameter <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">{model}</strong>, and the output path is stored in the run parameter <strong style="color:#010101">{output}</strong>.',
pathTips66: 'The dataset location is stored in the run parameter <strong style="color:#010101">{dataset}</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">{model}</strong>, and please put your model into <strong style="color:#010101">{output}</strong> then you can download it online.',
pathTips7: 'The dataset location is stored in the run parameter <strong style="color:#010101">{dataset}</strong>, the model file is stored in the run parameter <strong style="color:#010101">{model}</strong>, and the inference output path is stored in the run parameter <strong style="color:#010101">{output}</strong>.',
pathTips71: 'The code is storaged in <strong style="color:#010101">{code}</strong>, the dataset is storaged in <strong style="color:#010101">{dataset}</strong>, the model file is storaged in the <strong style="color:#010101">{model}</strong>, and please put your inference output into <strong style="color:#010101">{output}</strong> then you can download it online.',
basicInfo: 'Basic Info',
paramsSetting: 'Parameter setting',
taskPrepareTips: 'The task is currently being prepared. Drink a glass of water and come back to take a look~',
@@ -631,18 +634,21 @@ const en = {
debugTaskEmptyTitle: 'Debug task has not been created',
debugTaskEmptyTip0: 'Code version: You have not initialized the code repository, please <a href="{url}">initialized</a> first;',
debugTaskEmptyTip1: 'Running time: no more than 4 hours, it will automatically stop if it exceeds 4 hours;',
debugTaskEmptyTip2: 'Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU.And dataset also needs to be uploaded to the corresponding environment;',
debugTaskEmptyTip2: 'Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU. And dataset also needs to be uploaded to the corresponding environment;',
debugTaskEmptyTip3: 'Instructions for use: You can refer to the OpenI AI collaboration platform<a href="{url}"> Help Center </a>.',
onlineInferTaskEmptyTitle: 'Online Inference task has not been created',
onlineInferEmptyTip2: 'Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU.And dataset also needs to be uploaded to the corresponding environment;',
onlineInferEmptyTip2: 'Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU. And dataset also needs to be uploaded to the corresponding environment;',
superTaskEmptyTitle: 'HPC task has not been created',
deleteConfirmTips: 'Are you sure you want to delete this task? Once this task is deleted, it cannot be recovered.',
deletingTips: 'Task deletion in progress, please wait',
tabTitDebug: 'Debug Task',
tabTitTrain: 'Train Task',
tabTitInference: 'Inference Job',
tabTitInference: 'Inference Task',
tabTitBenchmark: 'Model Evaluation',
trainTaskEmptyTitle: 'Train task has not been created',
trainTaskEmptyTip2: 'Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU. And dataset also needs to be uploaded to the corresponding environment;',
inferenceTaskEmptyTitle: 'Inference task has not been created',
inferenceTaskEmptyTip2: 'Dataset: Cloud Brain 1 provides CPU/GPU,Cloud Brain 2 provides Ascend NPU. And dataset also needs to be uploaded to the corresponding environment;',
bootFileTips: 'The startup file is the entry file that your program executes, and it must be a file ending in .py',
viewSample: 'View sample',
tabTitOnlineInference: 'Online Inference',


+ 6
- 0
web_src/vuepages/langs/config/zh-CN.js View File

@@ -491,6 +491,7 @@ const zh = {
speech_processing: "语音处理",
computer_vision_natural_language_processing: "计算机视觉、自然语言处理",
machine_translation: "机器翻译",
medical_imaging: "医学影像",
question_answering_system: "问答系统",
information_retrieval: "信息检索",
knowledge_graph: "知识图谱",
@@ -562,6 +563,8 @@ const zh = {
pathTips5: '数据集存储在 <strong style="color:#010101">{dataset}</strong> 中,模型文件存储在 <strong style="color:#010101">{model}</strong> 中,推理输出请存储在 <strong style="color:#010101">{output}</strong> 中以供后续下载。',
pathTips6: '数据集位置存储在运行参数 <strong style="color:#010101">{dataset}</strong> 中,预训练模型存放在运行参数 <strong style="color:#010101">{model}</strong> 中,训练输出路径存储在运行参数 <strong style="color:#010101">{output}</strong> 中。',
pathTips66: '数据集位置存储在运行参数 <strong style="color:#010101">{dataset}</strong> 中,预训练模型存放在运行参数 <strong style="color:#010101">{model}</strong> 中,训练输出请存储在 <strong style="color:#010101">{output}</strong> 中以供后续下载。',
pathTips7: '数据集位置存储在运行参数 <strong style="color:#010101">{dataset}</strong> 中,模型存放在运行参数 <strong style="color:#010101">{model}</strong> 中,推理输出路径存储在运行参数 <strong style="color:#010101">{output}</strong> 中。',
pathTips71: '推理脚本存储在 <strong style="color:#010101">{code}</strong> 中,数据集存储在 <strong style="color:#010101">{dataset}</strong> 中,模型存储在 <strong style="color:#010101">{model}</strong> 中,推理输出请存储在 <strong style="color:#010101">{output}</strong> 中以供后续下载。',
basicInfo: '基本信息',
paramsSetting: '参数设置',
taskPrepareTips: '任务正在准备中,喝杯水回来再看看~',
@@ -659,6 +662,9 @@ const zh = {
tabTitInference: '推理任务',
tabTitBenchmark: '评测任务',
trainTaskEmptyTitle: '未创建过训练任务',
trainTaskEmptyTip2: '数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,训练使用的数据集也需要上传到对应的环境;',
inferenceTaskEmptyTitle: '未创建过推理任务',
inferenceTaskEmptyTip2: '数据集:云脑1提供 CPU / GPU 资源,云脑2提供 Ascend NPU 资源,推理使用的数据集也需要上传到对应的环境;',
bootFileTips: '启动文件是您程序执行的入口文件,必须是以.py结尾的文件。比如train.py、main.py、example/train.py、case/main.py。',
viewSample: '查看样例',
tabTitOnlineInference: '在线推理',


+ 201
- 52
web_src/vuepages/pages/cloudbrain/configs.js View File

@@ -34,8 +34,8 @@ export const CreatePageConfigs = {
url: 'debugjob?debugListType=all',
clusters: ['OpenI', 'C2Net'],
'OpenI': [{
url: 'cloudbrain/create',
computerResouces: ['GPU', 'NPU'],
url: 'modelarts/notebook/create',
computerResouces: ['NPU'],
'GPU': [{
url: 'cloudbrain/create',
clusterType: 'OpenICloudbrainOne',
@@ -93,8 +93,8 @@ export const CreatePageConfigs = {
model: '/pretrainmodel',
}),
form: {
taskName: { reuqired: true, },
taskDescr: { reuqired: false, },
taskName: { required: true, },
taskDescr: { required: false, },
taskType: {},
branchName: {},
model: { required: false, multiple: true },
@@ -132,7 +132,7 @@ export const CreatePageConfigs = {
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: false, multiple: true },
imagev2: { required: true },
imagev2: { required: true, relatedSpec: true },
dataset: { required: false, useExceedSize: true },
networkType: { required: true },
spec: { required: true },
@@ -151,7 +151,7 @@ export const CreatePageConfigs = {
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: false, multiple: true },
imagev2: { required: true },
imagev2: { required: true, relatedSpec: true },
dataset: { required: false, useExceedSize: true },
networkType: { required: true },
spec: { required: true },
@@ -170,7 +170,7 @@ export const CreatePageConfigs = {
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: false, multiple: true },
imagev2: { required: true },
imagev2: { required: true, relatedSpec: true },
dataset: { required: false, useExceedSize: true },
networkType: { required: true },
spec: { required: true },
@@ -189,7 +189,7 @@ export const CreatePageConfigs = {
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: false, multiple: true },
imagev2: { required: true },
imagev2: { required: true, relatedSpec: true },
dataset: { required: false, useExceedSize: true },
networkType: { required: true },
spec: { required: true },
@@ -208,7 +208,7 @@ export const CreatePageConfigs = {
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: false, multiple: true },
imagev2: { required: true },
imagev2: { required: true, relatedSpec: true },
dataset: { required: false, useExceedSize: true },
networkType: { required: true },
spec: { required: true },
@@ -221,8 +221,8 @@ export const CreatePageConfigs = {
url: 'modelarts/train-job?listType=all',
clusters: ['OpenI', 'C2Net'],
'OpenI': [{
url: 'cloudbrain/train-job/create',
computerResouces: ['GPU', 'NPU'],
url: 'modelarts/train-job/create',
computerResouces: ['NPU'],
'GPU': [{
url: 'cloudbrain/train-job/create',
clusterType: 'OpenICloudbrainOne',
@@ -271,7 +271,7 @@ export const CreatePageConfigs = {
branchName: { required: true, },
model: { required: false, multiple: false },
imagev2: { required: true },
bootFile: { required: true, sampleUrl: 'https://openi.pcl.ac.cn/OpenIOSSG/MINIST_Example' },
bootFile: { required: true, sampleUrl: 'https://openi.pcl.ac.cn/OpenIOSSG/MNIST_Example' },
dataset: { required: true, type: 1 },
runParameters: { required: false },
networkType: { required: true },
@@ -297,8 +297,8 @@ export const CreatePageConfigs = {
output: '/tmp/output',
}),
form: {
taskName: { reuqired: true, },
taskDescr: { reuqired: false, },
taskName: { required: true, },
taskDescr: { required: false, },
taskType: {},
branchName: {},
model: { multiple: false },
@@ -348,7 +348,7 @@ export const CreatePageConfigs = {
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: false, multiple: false },
imagev2: { required: true },
imagev2: { required: true, relatedSpec: true },
bootFile: { required: true, sampleUrl: 'https://openi.pcl.ac.cn/OpenIOSSG/MNIST_PytorchExample_GCU/src/branch/master/train_for_c2net.py' },
dataset: { required: true },
runParameters: { required: false },
@@ -371,7 +371,7 @@ export const CreatePageConfigs = {
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: false, multiple: false },
imagev2: { required: true },
imagev2: { required: true, relatedSpec: true },
bootFile: { required: true, sampleUrl: '' },
dataset: { required: true },
runParameters: { required: false },
@@ -385,23 +385,80 @@ export const CreatePageConfigs = {
// 推理任务
'INFERENCE': [{
url: 'modelarts/inference-job',
clusters: ['OpenI'],
clusters: ['OpenI', 'C2Net'],
'OpenI': [{
url: 'cloudbrain/inference-job/create',
computerResouces: ['GPU', 'NPU'],
'GPU': [{
url: 'cloudbrain/inference-job/create',
tips2: '',
// hideTips2: true,
hideCluster: true,
form: {},
}],
url: 'modelarts/inference-job/create',
computerResouces: ['NPU'],
'NPU': [{
url: 'modelarts/inference-job/create',
tips2: '',
// hideTips2: true,
hideCluster: true,
form: {},
clusterType: 'OpenICloudbrainTwo',
tips2: i18n.t('cloudbrainObj.pathTips7', {
dataset: 'multi_data_url',
model: 'pretrain_url',
output: 'result_url',
}),
form: {
taskName: { required: true, },
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: true, multiple: false },
imagev2: { required: true },
bootFile: { required: true, sampleUrl: 'https://openi.pcl.ac.cn/OpenIOSSG/MNIST_Example/src/branch/master/inference.py' },
dataset: { required: true, type: 1 },
runParameters: { required: false },
networkType: { required: true },
spec: { required: true },
workServerNum: { required: true },
},
}],
}],
'C2Net': [{
url: 'grampus/inference-job/create',
computerResouces: ['GPU', 'ILUVATAR-GPGPU'],
'GPU': [{
url: 'grampus/inference-job/create',
clusterType: 'C2Net',
tips2: i18n.t('cloudbrainObj.pathTips71', {
code: '/tmp/code',
dataset: '/tmp/dataset',
model: '/tmp/pretrainmodel',
output: '/tmp/output',
}),
form: {
taskName: { required: true, },
taskDescr: { required: false, },
taskType: {},
branchName: {},
model: { required: true, multiple: false },
imagev1: { required: true, type: 2 },
bootFile: { required: true, sampleUrl: 'https://openi.pcl.ac.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/inference_for_c2net.py' },
dataset: { required: true, type: 0 },
runParameters: { required: false },
networkType: { required: true },
spec: {},
},
}],
'ILUVATAR-GPGPU': [{
url: 'modelarts/inference-job/create?type=1',
clusterType: 'C2Net',
tips2: i18n.t('cloudbrainObj.pathTips71', {
code: '/tmp/code',
dataset: '/tmp/dataset',
model: '/tmp/pretrainmodel',
output: '/tmp/output',
}),
form: {
taskName: { required: true, },
taskDescr: { required: false, },
branchName: { required: true, },
model: { required: true, multiple: false },
imagev2: { required: true, relatedSpec: true },
bootFile: { required: true, sampleUrl: 'https://openi.pcl.ac.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/inference_for_c2net.py' },
dataset: { required: true, type: 0 },
runParameters: { required: false },
networkType: { required: true },
spec: { required: true },
}
}],
}],
}],
@@ -488,8 +545,8 @@ export const CreatePageConfigs = {
model: '/pretrainmodel',
}),
form: {
taskName: { reuqired: true, },
taskDescr: { reuqired: false, },
taskName: { required: true, },
taskDescr: { required: false, },
taskType: {},
branchName: {},
bootFile: { required: true, sampleUrl: 'https://openi.pcl.ac.cn/OpenIOSSG/Online-Inference_Example' },
@@ -535,14 +592,20 @@ export const ListPageConfigs = {
operations: ['stop', 'modify', 'delete'],
emptyTitle: i18n.t('cloudbrainObj.trainTaskEmptyTitle'),
emptyTip0: true,
emptyTip1: i18n.t('cloudbrainObj.debugTaskEmptyTip2'),
emptyTip1: i18n.t('cloudbrainObj.trainTaskEmptyTip2'),
emptyTip2: i18n.t('cloudbrainObj.debugTaskEmptyTip3'),
}, {
jobType: 'INFERENCE',
sortList: getSortList(['', 'GPU', 'NPU', 'ILUVATAR-GPGPU']),
jobTypeName: getListValueWithKey(JOB_TYPE, 'INFERENCE'),
url: 'modelarts/inference-job',
createUrl: 'cloudbrain/inference-job/create',

createUrl: 'modelarts/inference-job/create',
columns: ['taskName', 'status', 'createTime', 'runDuration', 'clusterAndComputeResource', 'creator'],
operations: ['stop', 'delete'],
emptyTitle: i18n.t('cloudbrainObj.inferenceTaskEmptyTitle'),
emptyTip0: true,
emptyTip1: i18n.t('cloudbrainObj.inferenceTaskEmptyTip2'),
emptyTip2: i18n.t('cloudbrainObj.debugTaskEmptyTip3'),
}, {
jobType: 'BENCHMARK',
jobTypeName: getListValueWithKey(JOB_TYPE, 'BENCHMARK'),
@@ -1010,30 +1073,116 @@ export const DetailPageConfigs = {
}],
}]
}],
/*
// 推理任务
'INFERENCE': [{
listUrl: 'modelarts/inference-job',
clusters: ['OpenI'],
clusters: ['OpenI', 'C2Net'],
'OpenI': [{
url: 'cloudbrain/inference-job/create',
computerResouces: ['GPU', 'NPU'],
'GPU': [{
url: 'cloudbrain/inference-job/create',
tips2: '',
// hideTips2: true,
hideCluster: true,
form: {},
}],
'NPU': [{
url: 'modelarts/inference-job/create',
tips2: '',
// hideTips2: true,
hideCluster: true,
form: {},
detailUrl: 'modelarts/inference-job/',
summary: [],
operations: [],
tabs: [{
name: 'configInfo',
fields: [
'taskName', 'imagev2',
'status', 'spec',
'creator', 'hasInternet',
'branch', 'modelName',
'computerRes', 'modelVersion',
'runVersion', 'modelFiles',
'createTime', 'bootFile',
'startTime', 'runParameters',
'endTime', 'workServerNum',
'duration', '',
'descr', '',
'failedReason',
'dataset',
'modelList',
]
}, {
name: 'logs',
multiNodes: true,
}, {
name: 'resourceUseage',
multiNodes: true,
}, {
name: 'resultDownload'
}],
}],
}],
'C2Net': [{
'GPU': [{
detailUrl: 'grampus/inference-job/',
summary: [],
operations: [],
tabs: [{
name: 'configInfo',
fields: [
'taskName', 'imagev1',
'status', 'spec',
'creator', 'aiCenter',
'branch', 'hasInternet',
'computerRes', 'modelName',
'createTime', 'modelVersion',
'startTime', 'modelFiles',
'endTime', 'bootFile',
'duration', 'runParameters',
'descr', 'workServerNum',
'failedReason', '',
'dataset',
'modelList',
]
}, {
name: 'operationProfile'
}, {
name: 'logs',
noScroll: true,
multiNodes: true,
}, {
name: 'resourceUseage',
multiNodes: true,
}, {
name: 'resultDownload'
}],
}],
'ILUVATAR-GPGPU': [{
detailUrl: 'grampus/inference-job/',
summary: [],
operations: [],
tabs: [{
name: 'configInfo',
fields: [
'taskName', 'imagev2',
'status', 'spec',
'creator', 'aiCenter',
'branch', 'hasInternet',
'computerRes', 'modelName',
'createTime', 'modelVersion',
'startTime', 'modelFiles',
'endTime', 'bootFile',
'duration', 'runParameters',
'descr', '',
'failedReason',
'dataset',
'modelList',
]
}, {
name: 'operationProfile'
}, {
name: 'logs',
noScroll: true,
multiNodes: true,
}, {
name: 'resourceUseage',
multiNodes: true,
}, {
name: 'resultDownload'
}],
}],
}]
}],
/*
// 评测任务
'BENCHMARK': [{ // 评测任务-算法
listUrl: 'cloudbrain/benchmark',
@@ -1127,7 +1276,7 @@ export const DetailPageConfigs = {
}, {
name: 'logs',
noScroll: true,
},{
}, {
name: 'resultDownload'
}],
}],


+ 16
- 2
web_src/vuepages/pages/cloudbrain/list/index.vue View File

@@ -37,14 +37,22 @@
<span>{{ scope.row.task.versionCount }}</span>
</template>
</el-table-column>
<el-table-column v-if="pageCfg.page.columns.indexOf('modelInfo') >= 0" :label="$t('repos.model')" align="left"
header-align="left" width="100">
<template slot-scope="scope">
<span>{{ scope.row.task.model }}</span>
</template>
</el-table-column>
<el-table-column v-if="pageCfg.page.columns.indexOf('status') >= 0" prop="Status" :label="$t('status')"
align="left" header-align="left" min-width="120">
<template slot-scope="scope">
<div class="status-wrap">
<i :class="scope.row.task.status"></i>
<span>{{ scope.row.task.status }}</span>
<i v-if="scope.row.task.detailed_status==='dataMigrating' && scope.row.task.status==='WAITING'" :class="scope.row.task.detailed_status" :title="$t('cloudbrainObj.migratingData')"></i>
<i v-if="scope.row.task.detailed_status==='centerPending' && scope.row.task.status==='WAITING'" :class="scope.row.task.detailed_status" :title="$t('cloudbrainObj.centerPending')"></i>
<i v-if="scope.row.task.detailed_status === 'dataMigrating' && scope.row.task.status === 'WAITING'"
:class="scope.row.task.detailed_status" :title="$t('cloudbrainObj.migratingData')"></i>
<i v-if="scope.row.task.detailed_status === 'centerPending' && scope.row.task.status === 'WAITING'"
:class="scope.row.task.detailed_status" :title="$t('cloudbrainObj.centerPending')"></i>
</div>
</template>
</el-table-column>
@@ -105,6 +113,11 @@
:class="scope.row.can_modify && scope.row.task.canModify ? '' : 'disabled'">{{
$t('cloudbrainObj.modify')
}}</a>
<a href="javascript:;" v-if="pageCfg.page.operations.indexOf('download') >= 0"
@click="opDownload(scope.row)"
:class="scope.row.can_delete && scope.row.task.canDelete ? '' : 'disabled'">{{
$t('cloudbrainObj.modelDownload')
}}</a>
<a href="javascript:;" v-if="pageCfg.page.operations.indexOf('delete') >= 0"
@click="opDelete(scope.row)"
:class="scope.row.can_delete && scope.row.task.canDelete ? '' : 'disabled'">{{
@@ -387,6 +400,7 @@ export default {
});
});
},
opDownload(row) { },
},
beforeMount() {
const urlParams = getUrlSearchParams();


+ 9
- 0
web_src/vuepages/pages/cloudbrain/tools.js View File

@@ -162,6 +162,15 @@ export class CloudBrainTools {
}
break;
case 'INFERENCE':
if (taskInfo.cluster == 'OpenI') {
if (taskInfo.compute_source == 'GPU') {
link += `cloudbrain/inference-job/${taskInfo.id}`;
} else if (taskInfo.compute_source == 'NPU') {
link += `modelarts/inference-job/${taskInfo.id}`;
}
} else if (taskInfo.cluster == 'C2Net') {
link += `grampus/inference-job/${taskInfo.id}`;
}
break;
case 'BENCHMARK':
break;


+ 6
- 4
web_src/vuepages/pages/computingpower/components/DemandForm.vue View File

@@ -1,6 +1,6 @@
<template>
<div>
<div class="title" v-if="type == 'add'">请在下方填写您的算力使用需求</div>
<div class="title" v-if="type == 'add'">请在下方填写您的算力使用需求,部分大额或独占资源使用涉及付费,平台运营人员会与您联系沟通详情。</div>
<div class="form-c">
<el-form ref="formRef" size="default" :model="form" :rules="formRules" label-width="110px">
<el-form-item label="计算资源" prop="compute_resource">
@@ -166,7 +166,9 @@ export default {
],
},
computeResourceList: [],
computeResourceCardTypeMap: {},
computeResourceCardTypeMap: {
'GPU': ['A100', 'V100', 'T4'],
},
cardTypeList: [],
resourceTypeList: [
{ k: 1, v: '共享' },
@@ -292,8 +294,8 @@ export default {
res = res.data;
if (res.code == 0) {
const data = res.data;
this.computeResourceCardTypeMap = data;
this.computeResourceList = Object.keys(data).map(itm => ({ k: itm, v: itm }));
Object.assign(this.computeResourceCardTypeMap, { ...data });
this.computeResourceList = Object.keys(this.computeResourceCardTypeMap).map(itm => ({ k: itm, v: itm }));
this.cardTypeList = [];
this.form.card_type = '';
}


+ 9
- 5
web_src/vuepages/pages/computingpower/demand/index.vue View File

@@ -40,10 +40,10 @@
<div class="demand-item-right">
<span class="status pending" v-if="item.status == 1"><i
class="el-icon-stopwatch"></i><span>待处理</span></span>
<span class="status accepted" v-if="item.status == 2"><i
class="el-icon-circle-check"></i><span>已接纳</span></span>
<span class="status refuse " v-if="item.status == 2"><i
class="el-icon-circle-check"></i><span>已处理</span></span>
<span class="status refuse" v-if="item.status == 3"><i
class="el-icon-circle-close"></i><span>未接纳</span></span>
class="el-icon-circle-check"></i><span>已处理</span></span>
</div>
</div>
</div>
@@ -90,8 +90,12 @@
class="el-icon-stopwatch"></i><span>待处理</span></span>
<span class="status accepted" v-if="item.status == 2"><i
class="el-icon-circle-check"></i><span>已接纳</span></span>
<span class="status refuse" v-if="item.status == 3"><i
class="el-icon-circle-close"></i><span>未接纳</span></span>
<span class="status refuse" v-if="item.status == 3">
<i class="el-icon-circle-close"></i><span>未接纳</span>
<el-tooltip v-if="false" class="item" effect="dark" :content="item.review" placement="top">
<i class="el-icon-info" style="margin-left:5px;cursor:pointer"></i>
</el-tooltip>
</span>
</div>
</div>
</div>


+ 1
- 0
web_src/vuepages/pages/dataset/square/constant.js View File

@@ -4,6 +4,7 @@ export const Category = [
{ name: "speech_processing", active: false },
{ name: "computer_vision_natural_language_processing", active: false },
{ name: "machine_translation", active: false },
{ name: "medical_imaging", active: false },
]
export const Task = [
{ name: "machine_translation", active: false },


+ 3
- 3
web_src/vuepages/pages/modelbase/components/cloudbrain/DatasetSelect.vue View File

@@ -3,7 +3,7 @@
<div class="title" v-if="showTitle"><span :class="required ? 'required' : ''">{{ selfTitle }}</span></div>
<div class="content">
<div class="dataset-list-c" :class="errStatus ? 'error' : ''">
<div class="dataset-item" v-for="(item, index) in selectList" :key="item.id">
<div class="dataset-item" v-for="(item) in selectList" :key="item.id">
{{ item.name }};
</div>
<div v-if="selectList.length == 0" class="dataset-item-placeholder">
@@ -75,7 +75,7 @@
{{ $t('datasetObj.dataset_unzip_failed') }}
</span>
<span class="unzip-failed" v-if="exceedSize && data.Size > exceedSize">
{{ $t('datasetObj.dataset_exceeds_failed') }}{{ exceedSize / (1000 * 1000 * 1000) }}G
{{ $t('datasetObj.dataset_exceeds_failed') }}{{ exceedSize / (1024 * 1024 * 1024) }}G
</span>
</span>
</span>
@@ -90,7 +90,7 @@
<div class="right-title"><span>{{ $t('datasetObj.dataset_selected') }}</span></div>
<div class="right-selected-list">
<el-checkbox-group v-model="dlgSelectedDataset">
<el-checkbox v-for="(item, index) in dlgSelectedDatasetList" :key="item.id" :label="item.id"
<el-checkbox v-for="(item) in dlgSelectedDatasetList" :key="item.id" :label="item.id"
:true-label="item.id" :title="item.label" @change="(checked) => dlgChangeSelect(checked, item)">
{{ item.label }}
</el-checkbox>


+ 3
- 1
web_src/vuepages/pages/modelmanage/fileupload/index.vue View File

@@ -4,7 +4,8 @@
<NotFound></NotFound>
</div>
<div v-else>
<ModelHeader :tab="'files'" :repoOwnerName="repoOwnerName" :repoName="repoName" :modelName="modelName" :model="modelData" v-if="JSON.stringify(modelData)!=='{}'">
<ModelHeader :tab="'files'" :repoOwnerName="repoOwnerName" :repoName="repoName" :modelName="modelName"
:model="modelData" v-if="JSON.stringify(modelData) !== '{}'">
</ModelHeader>
<div class="ui container">
<div class="header">
@@ -181,6 +182,7 @@ export default {
maxFiles: 10,
parallelUploads: 20,
uploadMultiple: true,
filesizeBase: 1024,
maxFilesize: maxModelFilesSize,
timeout: 0,
addRemoveLinks: true,


+ 7
- 1
web_src/vuepages/pages/reward/point/utils.js View File

@@ -49,7 +49,13 @@ const getJobTypeLink = (record, type) => {
}
break;
case 'INFERENCE':
link += `/modelarts/inference-job/${cloudbrain.JobID}`;
if (cloudbrain.Type === 1) {
link += `/modelarts/inference-job/${cloudbrain.ID}`;
} else if (cloudbrain.Type === 0) {
link += `/cloudbrain/inference-job/${cloudbrain.ID}`;
} else if (cloudbrain.Type === 2) {
link += `/grampus/inference-job/${cloudbrain.ID}`;
}
break;
case 'BENCHMARK':
link += `/cloudbrain/benchmark/${cloudbrain.ID}`;


Loading…
Cancel
Save