Browse Source

合并最新的代码。

Signed-off-by: zouap <zouap@pcl.ac.cn>
pull/3432/head
zouap 2 years ago
parent
commit
d4e5061626
74 changed files with 3402 additions and 3083 deletions
  1. +4
    -0
      models/action.go
  2. +18
    -0
      models/ai_model_manage.go
  3. +72
    -6
      models/cloudbrain.go
  4. +64
    -1
      models/cloudbrain_static.go
  5. +10
    -1
      models/repo_statistic.go
  6. +2
    -0
      models/task_config.go
  7. +1
    -2
      models/user_business_struct.go
  8. +21
    -0
      modules/auth/grampus.go
  9. +12
    -7
      modules/auth/modelarts.go
  10. +61
    -12
      modules/cloudbrain/cloudbrain.go
  11. +3
    -2
      modules/cron/tasks_basic.go
  12. +178
    -9
      modules/grampus/grampus.go
  13. +112
    -4
      modules/grampus/resty.go
  14. +34
    -130
      modules/modelarts/modelarts.go
  15. +34
    -27
      modules/modelarts_cd/modelarts.go
  16. +18
    -17
      modules/setting/setting.go
  17. +9
    -0
      modules/templates/helper.go
  18. +16
    -1
      options/locale/locale_en-US.ini
  19. +18
    -1
      options/locale/locale_zh-CN.ini
  20. +10
    -3
      public/home/home.js
  21. +3
    -0
      routers/api/v1/api.go
  22. +56
    -9
      routers/api/v1/repo/cloudbrain.go
  23. +36
    -60
      routers/api/v1/repo/cloudbrain_dashboard.go
  24. +1
    -1
      routers/api/v1/repo/images.go
  25. +1
    -1
      routers/api/v1/repo/modelarts.go
  26. +8
    -6
      routers/api/v1/repo/repo_dashbord.go
  27. +17
    -11
      routers/repo/ai_model_manage.go
  28. +120
    -57
      routers/repo/cloudbrain.go
  29. +74
    -120
      routers/repo/cloudbrain_statistic.go
  30. +662
    -80
      routers/repo/grampus.go
  31. +104
    -33
      routers/repo/modelarts.go
  32. +9
    -2
      routers/repo/repo_statistic.go
  33. +14
    -11
      routers/routes/routes.go
  34. +10
    -0
      services/cloudbrain/cloudbrainTask/count.go
  35. +14
    -3
      services/cloudbrain/cloudbrainTask/notebook.go
  36. +78
    -0
      services/cloudbrain/cloudbrainTask/sync_status.go
  37. +1
    -1
      services/socketwrap/clientManager.go
  38. +19
    -19
      templates/admin/cloudbrain/list.tmpl
  39. +2
    -2
      templates/custom/select_model.tmpl
  40. +1
    -197
      templates/repo/cloudbrain/benchmark/show.tmpl
  41. +6
    -10
      templates/repo/cloudbrain/inference/new.tmpl
  42. +0
    -195
      templates/repo/cloudbrain/inference/show.tmpl
  43. +141
    -191
      templates/repo/cloudbrain/new.tmpl
  44. +71
    -255
      templates/repo/cloudbrain/show.tmpl
  45. +1
    -15
      templates/repo/cloudbrain/trainjob/new.tmpl
  46. +2
    -195
      templates/repo/cloudbrain/trainjob/show.tmpl
  47. +20
    -16
      templates/repo/debugjob/index.tmpl
  48. +163
    -0
      templates/repo/grampus/notebook/gpu/new.tmpl
  49. +151
    -0
      templates/repo/grampus/notebook/npu/new.tmpl
  50. +439
    -0
      templates/repo/grampus/notebook/show.tmpl
  51. +2
    -8
      templates/repo/grampus/trainjob/gpu/new.tmpl
  52. +2
    -15
      templates/repo/grampus/trainjob/npu/new.tmpl
  53. +0
    -189
      templates/repo/grampus/trainjob/show.tmpl
  54. +6
    -11
      templates/repo/modelarts/inferencejob/new.tmpl
  55. +0
    -155
      templates/repo/modelarts/inferencejob/show.tmpl
  56. +104
    -188
      templates/repo/modelarts/notebook/new.tmpl
  57. +69
    -239
      templates/repo/modelarts/notebook/show.tmpl
  58. +1
    -15
      templates/repo/modelarts/trainjob/new.tmpl
  59. +0
    -195
      templates/repo/modelarts/trainjob/show.tmpl
  60. +38
    -69
      templates/repo/modelarts/trainjob/version_new.tmpl
  61. +15
    -5
      templates/repo/modelmanage/convertshowinfo.tmpl
  62. +9
    -14
      templates/repo/modelsafety/new.tmpl
  63. +1
    -197
      templates/repo/modelsafety/show.tmpl
  64. +10
    -11
      templates/user/dashboard/cloudbrains.tmpl
  65. +4
    -0
      templates/user/dashboard/feeds.tmpl
  66. +3
    -26
      web_src/js/components/dataset/selectDataset.vue
  67. +1
    -22
      web_src/js/components/images/selectImages.vue
  68. +5
    -1
      web_src/js/features/cloudbrainShow.js
  69. +13
    -2
      web_src/js/features/cloudrbanin.js
  70. +3
    -0
      web_src/js/index.js
  71. +12
    -5
      web_src/js/standalone/cloudbrainNew.js
  72. +170
    -2
      web_src/less/openi.less
  73. +8
    -0
      web_src/vuepages/pages/notebook/debug/index.vue
  74. +5
    -1
      web_src/vuepages/pages/reward/point/utils.js

+ 4
- 0
models/action.go View File

@@ -65,6 +65,8 @@ const (
ActionCreateImage //36
ActionImageRecommend //37
ActionChangeUserAvatar //38
ActionCreateGrampusNPUDebugTask //39
ActionCreateGrampusGPUDebugTask //40
)

// Action represents user operation type and other information to
@@ -375,6 +377,8 @@ func (a *Action) IsCloudbrainAction() bool {
ActionCreateInferenceTask,
ActionCreateBenchMarkTask,
ActionCreateGPUTrainTask,
ActionCreateGrampusGPUDebugTask,
ActionCreateGrampusNPUDebugTask,
ActionCreateGrampusNPUTrainTask,
ActionCreateGrampusGPUTrainTask:
return true


+ 18
- 0
models/ai_model_manage.go View File

@@ -403,6 +403,18 @@ func QueryModelByName(name string, repoId int64) []*AiModelManage {
return aiModelManageList
}

func QueryModelByPath(path string) (*AiModelManage, error) {
modelManage := new(AiModelManage)
has, err := x.Where("path=?", path).Get(modelManage)
if err != nil {
return nil, err
}
if !has {
return nil, ErrNotExist{}
}
return modelManage, nil
}

func QueryModel(opts *AiModelQueryOptions) ([]*AiModelManage, int64, error) {
sess := x.NewSession()
defer sess.Close()
@@ -473,6 +485,12 @@ func QueryModel(opts *AiModelQueryOptions) ([]*AiModelManage, int64, error) {
return aiModelManages, count, nil
}

func QueryModelConvertCountByRepoID(repoId int64) int64 {
convert := new(AiModelConvert)
total, _ := x.Where("repo_id =?", repoId).Count(convert)
return total
}

func QueryModelConvertByRepoID(repoId int64) ([]*AiModelConvert, error) {
sess := x.NewSession()
defer sess.Close()


+ 72
- 6
models/cloudbrain.go View File

@@ -114,6 +114,7 @@ const (
GrampusStatusFailed = "FAILED"
GrampusStatusSucceeded = "SUCCEEDED"
GrampusStatusStopped = "STOPPED"
GrampusStatusStopping = "STOPPING"
GrampusStatusUnknown = "UNKNOWN"
GrampusStatusWaiting = "WAITING"

@@ -181,7 +182,7 @@ type Cloudbrain struct {
BranchName string //分支名称
Parameters string //传给modelarts的param参数
BootFile string //启动文件
DataUrl string //数据集的obs路径
DataUrl string `xorm:"varchar(3500)"` //数据集的obs路径
LogUrl string //日志输出的obs路径
PreVersionId int64 //父版本的版本id
FlavorCode string //modelarts上的规格id
@@ -298,6 +299,12 @@ func (task *Cloudbrain) IsUserHasRight(user *User) bool {
}
return user.IsAdmin || user.ID == task.UserID
}
func (task *Cloudbrain) IsGPUTask() bool {
return task.ComputeResource == GPUResource
}
func (task *Cloudbrain) IsNPUTask() bool {
return task.ComputeResource == NPUResource
}

func ConvertDurationToStr(duration int64) string {
if duration <= 0 {
@@ -1215,6 +1222,13 @@ type DatasetDownload struct {
IsDelete bool `json:"is_delete"`
}

type ModelDownload struct {
Name string `json:"name"`
DownloadLink string `json:"download_link"`
RepositoryLink string `json:"repository_link"`
IsDelete bool `json:"is_delete"`
}

type DataSource struct {
DatasetID string `json:"dataset_id"`
DatasetVersion string `json:"dataset_version"`
@@ -1458,6 +1472,20 @@ type GrampusJobInfo struct {
UserID string `json:"userId"`
Tasks []GrampusTasks `json:"tasks"`
}

type GrampusNotebookInfo struct {
StartedAt int64 `json:"startedAt"`
RunSec int64 `json:"runSec"`
CompletedAt int64 `json:"completedAt"`
CreatedAt int64 `json:"createdAt"`
UpdatedAt int64 `json:"updatedAt"`
Desc string `json:"desc"`
JobID string `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
UserID string `json:"userId"`
Tasks []GrampusNotebookTask `json:"tasks"`
}
type Center struct {
ID string `json:"id"`
Name string `json:"name"`
@@ -1534,9 +1562,22 @@ type GetGrampusJobResponse struct {
JobInfo GrampusJobInfo `json:"otJob"`
}

type GrampusNotebookResponse struct {
GrampusResult
JobInfo GrampusNotebookInfo `json:"otJob"`
}

type GrampusNotebookRestartResponse struct {
GrampusResult
NewId string `json:"newId"`
Status string `json:"status"`
}

type GrampusStopJobResponse struct {
GrampusResult
StoppedAt int64 `json:"stoppedAt"`
StoppedAt int64 `json:"stoppedAt"`
ID string `json:"id"`
Status string `json:"status"`
}

type GrampusTasks struct {
@@ -1553,12 +1594,32 @@ type GrampusTasks struct {
Code GrampusDataset `json:"code"`
BootFile string `json:"bootFile"`
}
type GrampusNotebookTask struct {
AutoStopDuration int `json:"autoStopDuration"`
Name string `json:"name"`
Capacity int `json:"capacity"`
CenterID []string `json:"centerID"`
CenterName []string `json:"centerName"`
Code GrampusDataset `json:"code"`
Datasets []GrampusDataset `json:"datasets"`
CodeUrl string `json:"codeUrl"`
DataUrl string `json:"dataUrl"`
ImageId string `json:"imageId"`
ImageUrl string `json:"imageUrl"`
ResourceSpecId string `json:"resourceSpecId"`
Token string `json:"token"`
Url string `json:"url"`
Status string `json:"status"`
Command string `json:"command"`
}

type GrampusDataset struct {
Name string `json:"name"`
Bucket string `json:"bucket"`
EndPoint string `json:"endPoint"`
ObjectKey string `json:"objectKey"`
Name string `json:"name"`
Bucket string `json:"bucket"`
EndPoint string `json:"endPoint"`
ObjectKey string `json:"objectKey"`
ContainerPath string `json:"containerPath"`
ReadOnly bool `json:"readOnly"`
}

type CreateGrampusJobRequest struct {
@@ -1566,6 +1627,11 @@ type CreateGrampusJobRequest struct {
Tasks []GrampusTasks `json:"tasks"`
}

type CreateGrampusNotebookRequest struct {
Name string `json:"name"`
Tasks []GrampusNotebookTask `json:"tasks"`
}

type GetTrainJobMetricStatisticResult struct {
TrainJobResult
Interval int `json:"interval"` //查询的时间间隔,单位为分钟


+ 64
- 1
models/cloudbrain_static.go View File

@@ -92,6 +92,17 @@ type HourTimeStatistic struct {
HourTimeTotalDuration map[string]int `json:"hourTimeTotalDuration"`
HourTimeUsageRate map[string]float64 `json:"hourTimeUsageRate"`
}
type CloudbrainTypeDuration []struct {
Type int `xorm:"type"`
DurationSum int `xorm:"durationSum"`
CardDurationSum int `xorm:"cardDurationSum"`
Count int `xorm:"count"`
}
type CloudbrainAllDuration struct {
DurationSum int `xorm:"durationSum"`
CardDurationSum int `xorm:"cardDurationSum"`
Count int `xorm:"count"`
}

func GetTodayCreatorCount(beginTime time.Time, endTime time.Time) (int64, error) {
countSql := "SELECT count(distinct user_id) FROM " +
@@ -303,7 +314,7 @@ func GetCloudbrainByTime(beginTime int64, endTime int64) ([]*CloudbrainInfo, err
builder.And(builder.Gte{"cloudbrain.start_time": beginTime}, builder.Lte{"cloudbrain.start_time": endTime}, builder.Gt{"cloudbrain.start_time": 0}),
)
cond = cond.Or(
builder.And(builder.Eq{"cloudbrain.status": string(JobRunning)}),
builder.And(builder.Eq{"cloudbrain.status": string(JobRunning)}, builder.Lte{"cloudbrain.start_time": beginTime}),
)
sess.OrderBy("cloudbrain.id ASC")
cloudbrains := make([]*CloudbrainInfo, 0, 10)
@@ -425,3 +436,55 @@ func DeleteCloudbrainDurationStatistic(beginTime timeutil.TimeStamp, endTime tim
}
return nil
}

func GetCloudbrainTypeCardDuration() (CloudbrainTypeDuration, error) {
query := `
SELECT
cloudbrain.type,
SUM(cloudbrain.duration) as durationSum,
SUM(
COALESCE(cloudbrain.duration *
CASE
WHEN cloudbrain.work_server_number = 0 THEN 1
ELSE COALESCE(cloudbrain.work_server_number, 1)
END *
COALESCE(cloudbrain_spec.acc_cards_num, 1), 0)
) as cardDurationSum,
COUNT(*) as count
FROM cloudbrain
LEFT JOIN cloudbrain_spec
ON cloudbrain.id = cloudbrain_spec.cloudbrain_id
GROUP BY cloudbrain.type
`
// 执行查询
var results CloudbrainTypeDuration
if err := x.SQL(query).Find(&results); err != nil {
panic(err)
}
return results, nil
}

func GetCloudbrainAllCardDuration() (CloudbrainAllDuration, error) {
query := `
SELECT
SUM(cloudbrain.duration) as durationSum,
SUM(
COALESCE(cloudbrain.duration *
CASE
WHEN cloudbrain.work_server_number = 0 THEN 1
ELSE COALESCE(cloudbrain.work_server_number, 1)
END *
COALESCE(cloudbrain_spec.acc_cards_num, 1), 0)
) as cardDurationSum,
COUNT(*) as count
FROM cloudbrain
LEFT JOIN cloudbrain_spec
ON cloudbrain.id = cloudbrain_spec.cloudbrain_id
`
// 执行查询
var result CloudbrainAllDuration
if _, err := x.SQL(query).Get(&result); err != nil {
panic(err)
}
return result, nil
}

+ 10
- 1
models/repo_statistic.go View File

@@ -36,7 +36,7 @@ type RepoStatistic struct {
NumDevMonths int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
RepoSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
DatasetSize int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumModels int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumModels int64 `xorm:"NOT NULL DEFAULT 0" json:"model"`
NumWikiViews int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumCommits int64 `xorm:"NOT NULL DEFAULT 0" json:"commit"`
NumCommitsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
@@ -55,6 +55,15 @@ type RepoStatistic struct {
NumIssuesGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumCommentsGrowth int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`

NumDatasetFile int64 `xorm:"NOT NULL DEFAULT 0" json:"datasetFiles"`
NumCloudbrain int64 `xorm:"NOT NULL DEFAULT 0" json:"cloudbrains"`
NumModelConvert int64 `xorm:"NOT NULL DEFAULT 0" json:"modelConverts"`

NumDatasetFileAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumCloudbrainAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"-"`
NumModelConvertAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"- "`
NumModelsAdded int64 `xorm:"NOT NULL DEFAULT 0" json:"- "`

Impact float64 `xorm:"NOT NULL DEFAULT 0" json:"impact"`
Completeness float64 `xorm:"NOT NULL DEFAULT 0" json:"completeness"`
Liveness float64 `xorm:"NOT NULL DEFAULT 0" json:"liveness"`


+ 2
- 0
models/task_config.go View File

@@ -36,6 +36,8 @@ func GetTaskTypeFromAction(a ActionType) TaskType {
ActionCreateInferenceTask,
ActionCreateBenchMarkTask,
ActionCreateGPUTrainTask,
ActionCreateGrampusGPUDebugTask,
ActionCreateGrampusNPUDebugTask,
ActionCreateGrampusNPUTrainTask,
ActionCreateGrampusGPUTrainTask:
return TaskCreateCloudbrainTask


+ 1
- 2
models/user_business_struct.go View File

@@ -623,8 +623,7 @@ type UserBusinessAnalysisAll struct {

Phone string `xorm:"NULL"`
InvitationUserNum int `xorm:"NOT NULL DEFAULT 0"`

ModelConvertCount int `xorm:"NOT NULL DEFAULT 0"`
ModelConvertCount int `xorm:"NOT NULL DEFAULT 0"`
}

type UserBusinessAnalysis struct {


+ 21
- 0
modules/auth/grampus.go View File

@@ -29,3 +29,24 @@ type CreateGrampusTrainJobForm struct {
func (f *CreateGrampusTrainJobForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}

type CreateGrampusNotebookForm struct {
Type int `form:"type"`
DisplayJobName string `form:"display_job_name" binding:"Required"`
Attachment string `form:"attachment"`
ImageID string `form:"image_id" binding:"Required"`
Description string `form:"description"`
BranchName string `form:"branch_name" binding:"Required"`
Image string `form:"image" binding:"Required"`
DatasetName string `form:"dataset_name"`
ModelName string `form:"model_name"`
ModelVersion string `form:"model_version"`
CkptName string `form:"ckpt_name"`
LabelName string `form:"label_names"`
PreTrainModelUrl string `form:"pre_train_model_url"`
SpecId int64 `form:"spec_id" binding:"Required"`
}

func (f *CreateGrampusNotebookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
return validate(errs, ctx.Data, f, ctx.Locale)
}

+ 12
- 7
modules/auth/modelarts.go View File

@@ -16,13 +16,18 @@ func (f *CreateModelArtsForm) Validate(ctx *macaron.Context, errs binding.Errors
}

type CreateModelArtsNotebookForm struct {
DisplayJobName string `form:"display_job_name" binding:"Required"`
JobName string `form:"job_name" binding:"Required"`
Attachment string `form:"attachment"`
Description string `form:"description"`
Flavor string `form:"flavor" binding:"Required"`
ImageId string `form:"image_id" binding:"Required"`
SpecId int64 `form:"spec_id" binding:"Required"`
DisplayJobName string `form:"display_job_name" binding:"Required"`
JobName string `form:"job_name" binding:"Required"`
Attachment string `form:"attachment"`
Description string `form:"description"`
Flavor string `form:"flavor" binding:"Required"`
ImageId string `form:"image_id" binding:"Required"`
ModelName string `form:"model_name"`
ModelVersion string `form:"model_version"`
CkptName string `form:"ckpt_name"`
LabelName string `form:"label_names"`
PreTrainModelUrl string `form:"pre_train_model_url"`
SpecId int64 `form:"spec_id" binding:"Required"`
}

func (f *CreateModelArtsNotebookForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {


+ 61
- 12
modules/cloudbrain/cloudbrain.go View File

@@ -5,6 +5,7 @@ import (
"errors"
"os"
"strconv"
"strings"

"code.gitea.io/gitea/modules/timeutil"

@@ -145,7 +146,7 @@ func isAdminOrImageCreater(ctx *context.Context, image *models.Image, err error)
func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) {

var id = ctx.Params(":id")
job, err := GetCloudBrainByIdOrJobId(id)
job, err := GetCloudBrainByIdOrJobId(id, "id")
if err != nil {
log.Error("GetCloudbrainByID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -161,7 +162,7 @@ func AdminOrOwnerOrJobCreaterRight(ctx *context.Context) {
func AdminOrJobCreaterRight(ctx *context.Context) {

var id = ctx.Params(":id")
job, err := GetCloudBrainByIdOrJobId(id)
job, err := GetCloudBrainByIdOrJobId(id, "id")
if err != nil {
log.Error("GetCloudbrainByID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -177,7 +178,7 @@ func AdminOrJobCreaterRight(ctx *context.Context) {
func AdminOrOwnerOrJobCreaterRightForTrain(ctx *context.Context) {

var jobID = ctx.Params(":jobid")
job, err := GetCloudBrainByIdOrJobId(jobID)
job, err := GetCloudBrainByIdOrJobId(jobID, "jobid")
if err != nil {
log.Error("GetCloudbrainByJobID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -193,7 +194,7 @@ func AdminOrOwnerOrJobCreaterRightForTrain(ctx *context.Context) {
func AdminOrJobCreaterRightForTrain(ctx *context.Context) {

var jobID = ctx.Params(":jobid")
job, err := GetCloudBrainByIdOrJobId(jobID)
job, err := GetCloudBrainByIdOrJobId(jobID, "jobid")
if err != nil {
log.Error("GetCloudbrainByJobID failed:%v", err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
@@ -490,6 +491,21 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e
}
}

if task.PreTrainModelUrl != "" { //预训练
_, err := models.QueryModelByPath(task.PreTrainModelUrl)
if err != nil {
log.Warn("The model may be deleted", err)
} else {
volumes = append(volumes, models.Volume{
HostPath: models.StHostPath{
Path: setting.Attachment.Minio.RealPath + task.PreTrainModelUrl,
MountPath: PretrainModelMountPath,
ReadOnly: true,
},
})
}
}

createTime := timeutil.TimeStampNow()
jobResult, err := CreateJob(jobName, models.CreateJobParams{
JobName: jobName,
@@ -540,10 +556,16 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e
GpuQueue: task.GpuQueue,
ResourceSpecId: task.ResourceSpecId,
ComputeResource: task.ComputeResource,
CreatedUnix: createTime,
UpdatedUnix: createTime,
BranchName: task.BranchName,
Spec: spec,

CreatedUnix: createTime,
UpdatedUnix: createTime,
BranchName: task.BranchName,
Spec: spec,
ModelName: task.ModelName,
ModelVersion: task.ModelVersion,
LabelName: task.LabelName,
PreTrainModelUrl: task.PreTrainModelUrl,
CkptName: task.CkptName,
}

err = models.RestartCloudbrain(task, newTask)
@@ -653,18 +675,45 @@ func IsElementExist(s []string, str string) bool {
return false
}

func GetCloudBrainByIdOrJobId(id string) (*models.Cloudbrain,error) {
func GetCloudBrainByIdOrJobId(id string, initialQuery string) (*models.Cloudbrain, error) {
_, err := strconv.ParseInt(id, 10, 64)
var job *models.Cloudbrain
if err != nil {

job, err = models.GetCloudbrainByJobID(id)
} else {
job, err = models.GetCloudbrainByID(id)
if err!=nil{

if strings.EqualFold(initialQuery, "id") {
job, err = models.GetCloudbrainByID(id)
if err != nil {
job, err = models.GetCloudbrainByJobID(id)
}
} else {
job, err = models.GetCloudbrainByJobID(id)
if err != nil {
job, err = models.GetCloudbrainByID(id)
}
}

}
return job,err
return job, err
}

type GenerateModelArtsNotebookReq struct {
JobName string
DisplayJobName string
Uuid string
Description string

BootFile string

ImageId string
AutoStopDurationMs int64

Spec *models.Specification
ModelName string
LabelName string
CkptName string
ModelVersion string
PreTrainModelUrl string
}

+ 3
- 2
modules/cron/tasks_basic.go View File

@@ -5,10 +5,11 @@
package cron

import (
"code.gitea.io/gitea/modules/setting"
"context"
"time"

"code.gitea.io/gitea/modules/setting"

"code.gitea.io/gitea/modules/urfs_client/urchin"
cloudbrainService "code.gitea.io/gitea/services/cloudbrain"

@@ -296,7 +297,7 @@ func registerHandleCloudbrainDurationStatistic() {
RegisterTaskFatal("handle_cloudbrain_duration_statistic", &BaseConfig{
Enabled: true,
RunAtStart: false,
Schedule: "1 0 * * * ?",
Schedule: "1 1 * * * ?",
}, func(ctx context.Context, _ *models.User, _ Config) error {
repo.CloudbrainDurationStatisticHour()
return nil


+ 178
- 9
modules/grampus/grampus.go View File

@@ -1,7 +1,8 @@
package grampus

import (
"encoding/json"
"fmt"
"strconv"
"strings"

"code.gitea.io/gitea/models"
@@ -26,8 +27,10 @@ const (

CodeArchiveName = "master.zip"

BucketRemote = "grampus"
RemoteModelPath = "/output/" + models.ModelSuffix
BucketRemote = "grampus"
RemoteModelPath = "/output/" + models.ModelSuffix
autoStopDurationMs = 4 * 60 * 60 * 1000
CommandGpuDebug = "mkdir -p /dataset;%s! [ -x \"$(command -v jupyter)\" ] && pip install jupyterlab==3 -i https://pypi.tuna.tsinghua.edu.cn/simple;jupyter lab --ServerApp.shutdown_no_activity_timeout=%s --TerminalManager.cull_inactive_timeout=%s --TerminalManager.cull_interval=%s --MappingKernelManager.cull_idle_timeout=%s --MappingKernelManager.cull_interval=%s --MappingKernelManager.cull_connected=True --MappingKernelManager.cull_busy=True --no-browser --ip=0.0.0.0 --allow-root --notebook-dir='/code' --port=$OCTOPUS_NOTEBOOK_PORT --LabApp.token='' --LabApp.allow_origin='*' --LabApp.base_url=$OCTOPUS_NOTEBOOK_BASE_URL;"
)

var (
@@ -37,7 +40,7 @@ var (

SpecialPools *models.SpecialPools

CommandPrepareScriptGpu = ";mkdir -p output;mkdir -p code;mkdir -p dataset;mkdir -p pretrainmodel;echo \"start loading script\";wget -q https://openi.pcl.ac.cn/OpenIOSSG/%s/archive/master.zip;" +
CommandPrepareScriptGpu = ";mkdir -p output;mkdir -p code;mkdir -p dataset;mkdir -p pretrainmodel;echo \"start loading script\";wget -q https://git.openi.org.cn/OpenIOSSG/%s/archive/master.zip;" +
"echo \"finish loading script\";unzip -q master.zip;cd %s;chmod 777 downloader_for_obs uploader_for_npu downloader_for_minio uploader_for_gpu;"
)

@@ -81,6 +84,32 @@ type GenerateTrainJobReq struct {
CodeName string
}

type GenerateNotebookJobReq struct {
JobName string
Command string
ImageUrl string
ImageId string
DisplayJobName string
Uuid string
Description string
CodeStoragePath string
CommitID string
BranchName string
ComputeResource string
ProcessType string
DatasetNames string
DatasetInfos map[string]models.DatasetInfo
ModelName string
LabelName string
CkptName string
ModelVersion string
PreTrainModelPath string
PreTrainModelUrl string
Spec *models.Specification
CodeName string
ModelPath string //参考启智GPU调试, 挂载/model目录用户的模型可以输出到这个目录
}

func getEndPoint() string {
index := strings.Index(setting.Endpoint, "//")
endpoint := setting.Endpoint[index+2:]
@@ -101,6 +130,151 @@ func getDatasetGrampus(datasetInfos map[string]models.DatasetInfo) []models.Gram
}
return datasetGrampus
}
func getDatasetGPUGrampus(datasetInfos map[string]models.DatasetInfo) ([]models.GrampusDataset, string) {
var datasetGrampus []models.GrampusDataset
var command = ""
for uuid, datasetInfo := range datasetInfos {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: datasetInfo.FullName,
Bucket: setting.Attachment.Minio.Bucket,
EndPoint: setting.Attachment.Minio.Endpoint,
ObjectKey: datasetInfo.DataLocalPath,
ReadOnly: true,
ContainerPath: "/dataset1/" + datasetInfo.Name,
})

command += "cp /dataset1/'" + datasetInfo.Name + "'/" + uuid + " /dataset/'" + datasetInfo.FullName + "';"

}
return datasetGrampus, command
}

func GenerateNotebookJob(ctx *context.Context, req *GenerateNotebookJobReq) (jobId string, err error) {
createTime := timeutil.TimeStampNow()

var datasetGrampus []models.GrampusDataset
var codeGrampus models.GrampusDataset
var cpCommand string
imageUrl := req.ImageUrl
if ProcessorTypeNPU == req.ProcessType {
datasetGrampus = getDatasetGrampus(req.DatasetInfos)
if len(req.ModelName) != 0 {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: req.ModelName,
Bucket: setting.Bucket,
EndPoint: getEndPoint(),
ReadOnly: true,
ObjectKey: req.PreTrainModelPath,
})
}

codeGrampus = models.GrampusDataset{
Name: req.CodeName,
Bucket: setting.Bucket,
EndPoint: getEndPoint(),
ObjectKey: req.CodeStoragePath + cloudbrain.DefaultBranchName + ".zip",
ReadOnly: false,
}
imageUrl = ""
req.Command = ""
} else {
datasetGrampus, cpCommand = getDatasetGPUGrampus(req.DatasetInfos)
if len(req.ModelName) != 0 {
datasetGrampus = append(datasetGrampus, models.GrampusDataset{
Name: req.ModelName,
Bucket: setting.Attachment.Minio.Bucket,
EndPoint: setting.Attachment.Minio.Endpoint,
ObjectKey: req.PreTrainModelPath,
ReadOnly: true,
ContainerPath: cloudbrain.PretrainModelMountPath,
})
}
codeGrampus = models.GrampusDataset{
Name: req.CodeName,
Bucket: setting.Attachment.Minio.Bucket,
EndPoint: setting.Attachment.Minio.Endpoint,
ObjectKey: req.CodeStoragePath + cloudbrain.DefaultBranchName + ".zip",
ReadOnly: false,
ContainerPath: cloudbrain.CodeMountPath,
}
req.Command = fmt.Sprintf(CommandGpuDebug, cpCommand, setting.CullIdleTimeout, setting.CullIdleTimeout, setting.CullInterval, setting.CullIdleTimeout, setting.CullInterval)
log.Info("debug command:" + req.Command)

}

jobResult, err := createNotebookJob(models.CreateGrampusNotebookRequest{
Name: req.JobName,
Tasks: []models.GrampusNotebookTask{
{
Name: req.JobName,
ResourceSpecId: req.Spec.SourceSpecId,
ImageId: req.ImageId,
ImageUrl: imageUrl,
Datasets: datasetGrampus,
Code: codeGrampus,
AutoStopDuration: autoStopDurationMs,
Capacity: setting.Capacity,
Command: req.Command,
},
},
})
if err != nil {
log.Error("createNotebookJob failed: %v", err.Error())
return "", err
}

jobID := jobResult.JobInfo.JobID
err = models.CreateCloudbrain(&models.Cloudbrain{
Status: TransTrainJobStatus(jobResult.JobInfo.Status),
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
JobID: jobID,
JobName: req.JobName,
DisplayJobName: req.DisplayJobName,
JobType: string(models.JobTypeDebug),
Type: models.TypeC2Net,
Uuid: req.Uuid,
DatasetName: req.DatasetNames,
CommitID: req.CommitID,
IsLatestVersion: "1",
ComputeResource: req.ComputeResource,
ImageID: req.ImageId,
BranchName: req.BranchName,
Description: req.Description,
WorkServerNumber: 1,
EngineName: req.ImageUrl,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: req.Spec,
ModelName: req.ModelName,
ModelVersion: req.ModelVersion,
LabelName: req.LabelName,
PreTrainModelUrl: req.PreTrainModelUrl,
CkptName: req.CkptName,
})

if err != nil {
log.Error("CreateCloudbrain(%s) failed:%v", req.DisplayJobName, err.Error())
return "", err
}

var actionType models.ActionType
if req.ComputeResource == models.NPUResource {
actionType = models.ActionCreateGrampusNPUDebugTask
} else if req.ComputeResource == models.GPUResource {
actionType = models.ActionCreateGrampusGPUDebugTask
}
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
log.Error("GetCloudbrainByJobID failed: %v", err.Error())
return "", err
}

stringId := strconv.FormatInt(task.ID, 10)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, req.DisplayJobName, actionType)

return jobID, nil
}

func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (jobId string, err error) {
createTime := timeutil.TimeStampNow()
@@ -269,11 +443,6 @@ func TransTrainJobStatus(status string) string {

return strings.ToUpper(status)
}
func InitSpecialPool() {
if SpecialPools == nil && setting.Grampus.SpecialPools != "" {
json.Unmarshal([]byte(setting.Grampus.SpecialPools), &SpecialPools)
}
}

func GetNpuModelRemoteObsUrl(jobName string) string {
return "s3:///" + BucketRemote + "/" + GetNpuModelObjectKey(jobName)


+ 112
- 4
modules/grampus/resty.go View File

@@ -26,6 +26,7 @@ const (
urlGetResourceSpecs = urlOpenApiV1 + "resourcespec"
urlGetAiCenter = urlOpenApiV1 + "sharescreen/aicenter"
urlGetImages = urlOpenApiV1 + "image"
urlNotebookJob = urlOpenApiV1 + "notebook"

errorIllegalToken = 1005
)
@@ -87,6 +88,39 @@ func getToken() error {
return nil
}

func createNotebookJob(req models.CreateGrampusNotebookRequest) (*models.GrampusNotebookResponse, error) {
checkSetting()
client := getRestyClient()
var result models.GrampusNotebookResponse

retry := 0

sendjob:
_, err := client.R().
SetHeader("Content-Type", "application/json").
SetAuthToken(TOKEN).
SetBody(req).
SetResult(&result).
Post(HOST + urlNotebookJob)

if err != nil {
return nil, fmt.Errorf("resty CreateNotebookJob: %s", err)
}

if result.ErrorCode == errorIllegalToken && retry < 1 {
retry++
_ = getToken()
goto sendjob
}

if result.ErrorCode != 0 {
log.Error("CreateNotebookJob failed(%d): %s", result.ErrorCode, result.ErrorMsg)
return &result, fmt.Errorf("CreateNotebookJob failed(%d): %s", result.ErrorCode, result.ErrorMsg)
}

return &result, nil
}

func createJob(req models.CreateGrampusJobRequest) (*models.CreateGrampusJobResponse, error) {
checkSetting()
client := getRestyClient()
@@ -120,6 +154,38 @@ sendjob:
return &result, nil
}

func GetNotebookJob(jobID string) (*models.GrampusNotebookResponse, error) {
checkSetting()
client := getRestyClient()
var result models.GrampusNotebookResponse

retry := 0

sendjob:
_, err := client.R().
SetAuthToken(TOKEN).
SetResult(&result).
Get(HOST + urlNotebookJob + "/" + jobID)

if err != nil {
return nil, fmt.Errorf("resty GetNotebookJob: %v", err)
}

if result.ErrorCode == errorIllegalToken && retry < 1 {
retry++
log.Info("retry get token")
_ = getToken()
goto sendjob
}

if result.ErrorCode != 0 {
log.Error("GetNotebookJob failed(%d): %s", result.ErrorCode, result.ErrorMsg)
return nil, fmt.Errorf("GetNotebookJob failed(%d): %s", result.ErrorCode, result.ErrorMsg)
}

return &result, nil
}

func GetJob(jobID string) (*models.GetGrampusJobResponse, error) {
checkSetting()
client := getRestyClient()
@@ -184,18 +250,23 @@ sendjob:
return &result, nil
}

func GetImages(processorType string) (*models.GetGrampusImagesResult, error) {
func GetImages(processorType string, jobType string) (*models.GetGrampusImagesResult, error) {
checkSetting()
client := getRestyClient()
var result models.GetGrampusImagesResult

retry := 0

queryType := "TrainJob"
if jobType == string(models.JobTypeDebug) {
queryType = "Notebook"
}

sendjob:
_, err := client.R().
SetAuthToken(TOKEN).
SetResult(&result).
Get(HOST + urlGetImages + "?processorType=" + processorType)
Get(HOST + urlGetImages + "?processorType=" + processorType + "&trainType=" + queryType)

if err != nil {
return nil, fmt.Errorf("resty GetImages: %v", err)
@@ -271,19 +342,26 @@ func GetGrampusMetrics(jobID string) (models.GetTrainJobMetricStatisticResult, e
return result, nil
}

func StopJob(jobID string) (*models.GrampusStopJobResponse, error) {
func StopJob(jobID string, jobType ...string) (*models.GrampusStopJobResponse, error) {
checkSetting()
client := getRestyClient()
var result models.GrampusStopJobResponse

retry := 0

url := urlTrainJob
if len(jobType) > 0 {
if jobType[0] == string(models.JobTypeDebug) {
url = urlNotebookJob
}
}

sendjob:
_, err := client.R().
//SetHeader("Content-Type", "application/json").
SetAuthToken(TOKEN).
SetResult(&result).
Post(HOST + urlTrainJob + "/" + jobID + "/stop")
Post(HOST + url + "/" + jobID + "/stop")

if err != nil {
return &result, fmt.Errorf("resty StopTrainJob: %v", err)
@@ -335,3 +413,33 @@ sendjob:

return &result, nil
}

func RestartNotebookJob(jobID string) (*models.GrampusNotebookRestartResponse, error) {
checkSetting()
client := getRestyClient()
var restartResponse *models.GrampusNotebookRestartResponse
retry := 0

sendjob:
res, err := client.R().
SetAuthToken(TOKEN).
SetResult(&restartResponse).
Post(HOST + urlNotebookJob + "/" + jobID + "/start")

if err != nil {
return nil, fmt.Errorf("resty grampus restart note book job: %v", err)
}
if restartResponse.ErrorCode == errorIllegalToken && retry < 1 {
retry++
log.Info("retry get token")
_ = getToken()
goto sendjob
}

if res.StatusCode() != http.StatusOK {
log.Error("resty grampus restart note book job failed(%s): %v", res.String(), err.Error())
return nil, fmt.Errorf("resty grampus restart note book job failed: %v", err)
}

return restartResponse, nil
}

+ 34
- 130
modules/modelarts/modelarts.go View File

@@ -20,34 +20,16 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/timeutil"
)

const (
//notebook

storageTypeOBS = "obs"
autoStopDuration = 4 * 60 * 60
AutoStopDurationMs = 4 * 60 * 60 * 1000
MORDELART_USER_IMAGE_ENGINE_ID = -1
DataSetMountPath = "/home/ma-user/work"
NotebookEnv = "Python3"
NotebookType = "Ascend"
FlavorInfo = "Ascend: 1*Ascend 910 CPU: 24 核 96GiB (modelarts.kat1.xlarge)"

//train-job
// ResourcePools = "{\"resource_pool\":[{\"id\":\"pool1328035d\", \"value\":\"专属资源池\"}]}"
// Engines = "{\"engine\":[{\"id\":1, \"value\":\"Ascend-Powered-Engine\"}]}"
// EngineVersions = "{\"version\":[{\"id\":118,\"value\":\"MindSpore-1.0.0-c75-python3.7-euleros2.8-aarch64\"}," +
// "{\"id\":119,\"value\":\"MindSpore-1.1.1-c76-python3.7-euleros2.8-aarch64\"}," +
// "{\"id\":120,\"value\":\"MindSpore-1.1.1-c76-tr5-python3.7-euleros2.8-aarch64\"}," +
// "{\"id\":117,\"value\":\"TF-1.15-c75-python3.7-euleros2.8-aarch64\"}" +
// "]}"
// TrainJobFlavorInfo = "{\"flavor\":[{\"code\":\"modelarts.bm.910.arm.public.2\",\"value\":\"Ascend : 2 * Ascend 910 CPU:48 核 512GiB\"}," +
// "{\"code\":\"modelarts.bm.910.arm.public.8\",\"value\":\"Ascend : 8 * Ascend 910 CPU:192 核 2048GiB\"}," +
// "{\"code\":\"modelarts.bm.910.arm.public.4\",\"value\":\"Ascend : 4 * Ascend 910 CPU:96 核 1024GiB\"}," +
// "{\"code\":\"modelarts.bm.910.arm.public.1\",\"value\":\"Ascend : 1 * Ascend 910 CPU:24 核 256GiB\"}" +
// "]}"

CodePath = "/code/"
OutputPath = "/output/"
ResultPath = "/result/"
@@ -190,14 +172,6 @@ type OrgMultiNode struct {
Node []int `json:"node"`
}

// type Parameter struct {
// Label string `json:"label"`
// Value string `json:"value"`
// }

// type Parameters struct {
// Parameter []Parameter `json:"parameter"`
// }

type Parameters struct {
Parameter []struct {
@@ -206,98 +180,23 @@ type Parameters struct {
} `json:"parameter"`
}

func GenerateTask(ctx *context.Context, jobName, uuid, description, flavor string) error {
var dataActualPath string
if uuid != "" {
dataActualPath = setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + "/"
} else {
userPath := setting.UserBasePath + ctx.User.Name + "/"
isExist, err := storage.ObsHasObject(userPath)
if err != nil {
log.Error("ObsHasObject failed:%v", err.Error(), ctx.Data["MsgID"])
return err
}

if !isExist {
if err = storage.ObsCreateObject(userPath); err != nil {
log.Error("ObsCreateObject failed:%v", err.Error(), ctx.Data["MsgID"])
return err
}
}

dataActualPath = setting.Bucket + "/" + userPath
}

if poolInfos == nil {
json.Unmarshal([]byte(setting.PoolInfos), &poolInfos)
}
createTime := timeutil.TimeStampNow()
jobResult, err := CreateJob(models.CreateNotebookParams{
JobName: jobName,
Description: description,
ProfileID: setting.ProfileID,
Flavor: flavor,
Pool: models.Pool{
ID: poolInfos.PoolInfo[0].PoolId,
Name: poolInfos.PoolInfo[0].PoolName,
Type: poolInfos.PoolInfo[0].PoolType,
},
Spec: models.Spec{
Storage: models.Storage{
Type: storageTypeOBS,
Location: models.Location{
Path: dataActualPath,
},
},
AutoStop: models.AutoStop{
Enable: true,
Duration: autoStopDuration,
},
},
})
if err != nil {
log.Error("CreateJob failed: %v", err.Error())
return err
}
err = models.CreateCloudbrain(&models.Cloudbrain{

Status: string(models.JobWaiting),
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
JobID: jobResult.ID,
JobName: jobName,
JobType: string(models.JobTypeDebug),
Type: models.TypeCloudBrainTwo,
Uuid: uuid,
ComputeResource: models.NPUResource,
CreatedUnix: createTime,
UpdatedUnix: createTime,
})

if err != nil {
return err
}
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobResult.ID, jobName, models.ActionCreateDebugNPUTask)
return nil
}

func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification, bootFile string, autoStopDurationInMs int64) (string, error) {
func GenerateNotebook2(ctx *context.Context, req cloudbrain.GenerateModelArtsNotebookReq) (string, error) {
if poolInfos == nil {
json.Unmarshal([]byte(setting.PoolInfos), &poolInfos)
}

imageName, err := GetNotebookImageName(imageId)
imageName, err := GetNotebookImageName(req.ImageId)
if err != nil {
log.Error("GetNotebookImageName failed: %v", err.Error())
return "", err
}
createTime := timeutil.TimeStampNow()
jobResult, err := createNotebook2(models.CreateNotebook2Params{
JobName: jobName,
Description: description,
Flavor: spec.SourceSpecId,
Duration: autoStopDurationInMs,
ImageID: imageId,
JobName: req.JobName,
Description: req.Description,
Flavor: req.Spec.SourceSpecId,
Duration: req.AutoStopDurationMs,
ImageID: req.ImageId,
PoolID: poolInfos.PoolInfo[0].PoolId,
Feature: models.NotebookFeature,
Volume: models.VolumeReq{
@@ -310,13 +209,13 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
if err != nil {
log.Error("createNotebook2 failed: %v", err.Error())
if strings.HasPrefix(err.Error(), UnknownErrorPrefix) {
log.Info("(%s)unknown error, set temp status", displayJobName)
log.Info("(%s)unknown error, set temp status", req.DisplayJobName)
errTemp := models.InsertCloudbrainTemp(&models.CloudbrainTemp{
JobID: models.TempJobId,
VersionID: models.TempVersionId,
Status: models.TempJobStatus,
Type: models.TypeCloudBrainTwo,
JobName: jobName,
JobName: req.JobName,
JobType: string(models.JobTypeDebug),
})
if errTemp != nil {
@@ -327,23 +226,28 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
return "", err
}
task := &models.Cloudbrain{
Status: jobResult.Status,
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
JobID: jobResult.ID,
JobName: jobName,
FlavorCode: spec.SourceSpecId,
DisplayJobName: displayJobName,
JobType: string(models.JobTypeDebug),
Type: models.TypeCloudBrainTwo,
Uuid: uuid,
ComputeResource: models.NPUResource,
Image: imageName,
BootFile: bootFile,
Description: description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: spec,
Status: jobResult.Status,
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
JobID: jobResult.ID,
JobName: req.JobName,
FlavorCode: req.Spec.SourceSpecId,
DisplayJobName: req.DisplayJobName,
JobType: string(models.JobTypeDebug),
Type: models.TypeCloudBrainTwo,
Uuid: req.Uuid,
ComputeResource: models.NPUResource,
Image: imageName,
BootFile: req.BootFile,
Description: req.Description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: req.Spec,
ModelName: req.ModelName,
ModelVersion: req.ModelVersion,
LabelName: req.LabelName,
PreTrainModelUrl: req.PreTrainModelUrl,
CkptName: req.CkptName,
}

err = models.CreateCloudbrain(task)
@@ -352,7 +256,7 @@ func GenerateNotebook2(ctx *context.Context, displayJobName, jobName, uuid, desc
}

stringId := strconv.FormatInt(task.ID, 10)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, req.DisplayJobName, models.ActionCreateDebugNPUTask)
return jobResult.ID, nil
}



+ 34
- 27
modules/modelarts_cd/modelarts.go View File

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

"code.gitea.io/gitea/modules/cloudbrain"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
@@ -88,19 +90,19 @@ type Parameters struct {
} `json:"parameter"`
}

func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, description, imageId string, spec *models.Specification, bootFile string,autoStopDurationInMs int64) (string, error) {
imageName, err := GetNotebookImageName(imageId)
func GenerateNotebook(ctx *context.Context, req cloudbrain.GenerateModelArtsNotebookReq) (string, error) {
imageName, err := GetNotebookImageName(req.ImageId)
if err != nil {
log.Error("GetNotebookImageName failed: %v", err.Error())
return "", err
}
createTime := timeutil.TimeStampNow()
jobResult, err := createNotebook(models.CreateNotebookWithoutPoolParams{
JobName: jobName,
Description: description,
Flavor: spec.SourceSpecId,
Duration: autoStopDurationInMs,
ImageID: imageId,
JobName: req.JobName,
Description: req.Description,
Flavor: req.Spec.SourceSpecId,
Duration: req.AutoStopDurationMs,
ImageID: req.ImageId,
Feature: models.NotebookFeature,
Volume: models.VolumeReq{
Capacity: setting.Capacity,
@@ -112,13 +114,13 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr
if err != nil {
log.Error("createNotebook failed: %v", err.Error())
if strings.HasPrefix(err.Error(), UnknownErrorPrefix) {
log.Info("(%s)unknown error, set temp status", displayJobName)
log.Info("(%s)unknown error, set temp status", req.DisplayJobName)
errTemp := models.InsertCloudbrainTemp(&models.CloudbrainTemp{
JobID: models.TempJobId,
VersionID: models.TempVersionId,
Status: models.TempJobStatus,
Type: models.TypeCDCenter,
JobName: jobName,
JobName: req.JobName,
JobType: string(models.JobTypeDebug),
})
if errTemp != nil {
@@ -129,23 +131,28 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr
return "", err
}
task := &models.Cloudbrain{
Status: jobResult.Status,
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
JobID: jobResult.ID,
JobName: jobName,
FlavorCode: spec.SourceSpecId,
DisplayJobName: displayJobName,
JobType: string(models.JobTypeDebug),
Type: models.TypeCDCenter,
Uuid: uuid,
ComputeResource: models.NPUResource,
Image: imageName,
Description: description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: spec,
BootFile: bootFile,
Status: jobResult.Status,
UserID: ctx.User.ID,
RepoID: ctx.Repo.Repository.ID,
JobID: jobResult.ID,
JobName: req.JobName,
FlavorCode: req.Spec.SourceSpecId,
DisplayJobName: req.DisplayJobName,
JobType: string(models.JobTypeDebug),
Type: models.TypeCDCenter,
Uuid: req.Uuid,
ComputeResource: models.NPUResource,
Image: imageName,
Description: req.Description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: req.Spec,
BootFile: req.BootFile,
ModelName: req.ModelName,
ModelVersion: req.ModelVersion,
LabelName: req.LabelName,
PreTrainModelUrl: req.PreTrainModelUrl,
CkptName: req.CkptName,
}

err = models.CreateCloudbrain(task)
@@ -154,7 +161,7 @@ func GenerateNotebook(ctx *context.Context, displayJobName, jobName, uuid, descr
}

stringId := strconv.FormatInt(task.ID, 10)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateDebugNPUTask)
notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, req.DisplayJobName, models.ActionCreateDebugNPUTask)
return jobResult.ID, nil
}



+ 18
- 17
modules/setting/setting.go View File

@@ -519,7 +519,6 @@ var (
CullIdleTimeout string
CullInterval string


//benchmark config
IsBenchmarkEnabled bool
BenchmarkOwner string
@@ -617,14 +616,14 @@ var (
UsageRateBeginTime string
}{}

ClearStrategy= struct {
Enabled bool
ResultSaveDays int
BatchSize int
DebugJobSize int
TrashSaveDays int
Cron string
RunAtStart bool
ClearStrategy = struct {
Enabled bool
ResultSaveDays int
BatchSize int
DebugJobSize int
TrashSaveDays int
Cron string
RunAtStart bool
}{}

C2NetInfos *C2NetSqInfos
@@ -711,6 +710,7 @@ var (

ProjectHealth float64
ProjectHealthIssueCompleteRatio float64
ProjectHealth0IssueCloseRatio float64

TeamHealth float64
TeamHealthContributors float64
@@ -1705,16 +1705,16 @@ func getModelartsCDConfig() {
getNotebookFlavorInfos()
}

func getClearStrategy(){
func getClearStrategy() {

sec := Cfg.Section("clear_strategy")
ClearStrategy.Enabled=sec.Key("ENABLED").MustBool(false)
ClearStrategy.ResultSaveDays=sec.Key("RESULT_SAVE_DAYS").MustInt(30)
ClearStrategy.BatchSize=sec.Key("BATCH_SIZE").MustInt(500)
ClearStrategy.DebugJobSize=sec.Key("DEBUG_BATCH_SIZE").MustInt(100)
ClearStrategy.TrashSaveDays=sec.Key("TRASH_SAVE_DAYS").MustInt(90)
ClearStrategy.Cron=sec.Key("CRON").MustString("* 0,30 2-8 * * ?")
ClearStrategy.RunAtStart=sec.Key("RUN_AT_START").MustBool(false)
ClearStrategy.Enabled = sec.Key("ENABLED").MustBool(false)
ClearStrategy.ResultSaveDays = sec.Key("RESULT_SAVE_DAYS").MustInt(30)
ClearStrategy.BatchSize = sec.Key("BATCH_SIZE").MustInt(500)
ClearStrategy.DebugJobSize = sec.Key("DEBUG_BATCH_SIZE").MustInt(100)
ClearStrategy.TrashSaveDays = sec.Key("TRASH_SAVE_DAYS").MustInt(90)
ClearStrategy.Cron = sec.Key("CRON").MustString("* 0,30 2-8 * * ?")
ClearStrategy.RunAtStart = sec.Key("RUN_AT_START").MustBool(false)
}

func getGrampusConfig() {
@@ -1781,6 +1781,7 @@ func SetRadarMapConfig() {
RadarMap.LivenessRelease = sec.Key("liveness_release").MustFloat64(0.4)
RadarMap.ProjectHealth = sec.Key("project_health").MustFloat64(0.1)
RadarMap.ProjectHealthIssueCompleteRatio = sec.Key("project_health_issue_complete_ratio").MustFloat64(100)
RadarMap.ProjectHealth0IssueCloseRatio = sec.Key("project_health_0_issue_close_ratio").MustFloat64(0.0)
RadarMap.TeamHealth = sec.Key("team_health").MustFloat64(0.1)
RadarMap.TeamHealthContributors = sec.Key("team_health_contributors").MustFloat64(0.2)
RadarMap.TeamHealthKeyContributors = sec.Key("team_health_key_contributors").MustFloat64(0.6)


+ 9
- 0
modules/templates/helper.go View File

@@ -47,6 +47,7 @@ const (
REF_TYPE_BRANCH = "branch"
REF_TYPE_TAG = "tag"
REF_TYPE_PATTERN = "(refs/heads/|refs/tags/)"
DURATION_STR_ZERO = "00:00:00"
)

// Used from static.go && dynamic.go
@@ -109,6 +110,7 @@ func NewFuncMap() []template.FuncMap {
"AttachmentStatus": dataset.GetStatusText,
"IsShowDataSetOfCurrentRepo": dataset.IsShowDataSetOfCurrentRepo,
"TimeSinceUnixShort": timeutil.TimeSinceUnixShort,
"ConvertDurationToStr": ConvertDurationToStr,
"RawTimeSince": timeutil.RawTimeSince,
"FileSize": base.FileSize,
"PrettyNumber": base.PrettyNumber,
@@ -365,6 +367,7 @@ func NewTextFuncMap() []texttmpl.FuncMap {
"TimeSinceUnix": timeutil.TimeSinceUnix,
"TimeSinceUnix1": timeutil.TimeSinceUnix1,
"TimeSinceUnixShort": timeutil.TimeSinceUnixShort,
"ConvertDurationToStr": ConvertDurationToStr,
"RawTimeSince": timeutil.RawTimeSince,
"AttachmentResourceType": dataset.GetResourceType,
"AttachmentStatus": dataset.GetStatusText,
@@ -804,3 +807,9 @@ func MB2GB(size int) string {
}
return s
}
func ConvertDurationToStr(duration int64) string {
if duration <= 0 {
return DURATION_STR_ZERO
}
return util.AddZero(duration/3600) + ":" + util.AddZero(duration%3600/60) + ":" + util.AddZero(duration%60)
}

+ 16
- 1
options/locale/locale_en-US.ini View File

@@ -853,6 +853,7 @@ description = Description
description_format_err=Description's length can be up to %s characters long.
create_dataset = Create Dataset
download_url=Download Url
download_model_url=Download Url
download_oper=Operation
download_copy=Copy URL
create_dataset_fail=Failed to create dataset.
@@ -1061,6 +1062,7 @@ model_rename=Duplicate model name, please modify model name.
notebook_file_not_exist=Notebook file does not exist.
notebook_select_wrong=Please select a Notebook(.ipynb) file first.
notebook_file_no_right=You have no right to access the Notebook(.ipynb) file.
debug_again_fail=Fail to restart debug task, please try again later.

date=Date
repo_add=Project Increment
@@ -1343,9 +1345,12 @@ modelconvert.inputshapeerror=Format input error, please input such as: 1,1,32,32

modelconvert.manage.create_error1=A model transformation task with the same name already exists.
modelconvert.manage.create_error2=Only one running model transformation task can be created.
modelconvert.manage.model_not_exist=The model does not exist.
modelconvert.manage.model_not_exist=The model in the task does not exist or has been deleted.
modelconvert.manage.no_operate_right=You have no right to do the operation.

debug.manage.model_not_exist=The model in the task does not exist or has been deleted, please create a new debug job.
debug.manage.dataset_not_exist=The part of datasets in the task does not exist or has been deleted, please create a new debug job.

grampus.train_job.ai_center = AI Center
grampus.dataset_path_rule = The code is storaged in /cache/code;the dataset is storaged in /cache/dataset;and please put your model into /cache/output, then you can download it online。
grampus.gpu_dataset_path_rule = The code is storaged in /tmp/code;the dataset is storaged in /tmp/dataset;and please put your model into /tmp/output, then you can download it online。
@@ -2751,6 +2756,10 @@ repos.pr=PR
repos.commit=Commit
repos.closedIssues=Closed Issue
repos.contributor=Contributor
repos.numDataset=Dataset File
repos.numCloudbrain=Cloudbrain Task
repos.numModel=Model
repos.numModelConvert=Model Convert Task
repos.yes=Yes
repos.no=No

@@ -3121,6 +3130,8 @@ reject_pull_request = `suggested changes for <a href="%s/pulls/%s">%s#%[2]s</a>`
upload_dataset=`upload dataset <a href="%s/datasets">%s</a>`
task_gpudebugjob=`created CPU/GPU type debugging task <a href="%s/cloudbrain/%s">%s</a>`
task_npudebugjob=`created NPU type debugging task <a href="%s/modelarts/notebook/%s">%s</a>`
task_c2net_gpudebugjob=`created CPU/GPU type debugging task <a href="%s/grampus/notebook/%s">%s</a>`
task_c2net_npudebugjob=`created NPU type debugging task <a href="%s/grampus/notebook/%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_benchmark=`created profiling task <a href="%s/cloudbrain/benchmark/%s">%s</a>`
@@ -3240,6 +3251,7 @@ dataset = Dataset
resource_specification = Resource specification
dataset_storage_path = Dataset storage path
model_storage_path = Model storage path
output_storage_path = Output storage path
code_storage_path = Code storage path
benchmark_path = Benchmark script path
snn4imagenet_path = Snn4imagenet script path
@@ -3295,8 +3307,11 @@ load_code_failed=Fail to load code, please check if the right branch is selected

error.dataset_select = dataset select error:the count exceed the limit or has same name
new_train_gpu_tooltips = The code is storaged in <strong style="color:#010101">%s</strong>, the dataset is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">%s</strong>, and please put your model into <strong style="color:#010101">%s</strong> then you can download it online
new_debug_gpu_tooltips = The code is storaged in <strong style="color:#010101">%s</strong>, the dataset is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the <strong style="color:#010101">%s</strong>, and please put your model into <strong style="color:#010101">%s</strong> then you can download it online
new_debug_gpu_tooltips1 = The code is storaged in <strong style="color:#010101">%s</strong>, the dataset is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the <strong style="color:#010101">%s</strong>.
new_train_npu_tooltips = The code is storaged in <strong style="color:#010101">%s</strong>, the pre-trained model is storaged in the run parameter <strong style="color:#010101">%s</strong>, and please put your model into <strong style="color:#010101">%s</strong> then you can download it online
new_infer_gpu_tooltips = The dataset is stored in <strong style="color:#010101">%s</strong>, the model file is stored in <strong style="color:#010101">%s</strong>, please store the inference output in <strong style="color:#010101">%s</strong> for subsequent downloads.
code_obs_address = Code OBS address

[points]
points = points


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

@@ -864,6 +864,7 @@ reference_dataset_fail=关联数据集失败,请稍后再试。
cancel_reference_dataset_fail=取消关联数据集失败,请稍后再试。

download_url=数据集下载地址
download_model_url=模型文件下载地址
download_copy=复制链接
download_oper=操作
show_dataset=数据集
@@ -1060,6 +1061,7 @@ model_rename=模型名称重复,请修改模型名称
notebook_file_not_exist=Notebook文件不存在。
notebook_select_wrong=请先选择Notebook(.ipynb)文件。
notebook_file_no_right=您没有这个Notebook文件的读权限。
debug_again_fail=再次调试失败,请稍后再试。

date=日期
repo_add=新增项目
@@ -1357,9 +1359,13 @@ modelconvert.modelfileempty=请选择模型文件。

modelconvert.manage.create_error1=相同的名称模型转换任务已经存在。
modelconvert.manage.create_error2=只能创建一个正在运行的模型转换任务。
modelconvert.manage.model_not_exist=选择的模型不存在。
modelconvert.manage.model_not_exist=任务中选择的模型不存在或者已被删除
modelconvert.manage.no_operate_right=您没有操作权限。


debug.manage.model_not_exist=任务中选择的模型不存在或者已被删除,请新建调试任务。
debug.manage.dataset_not_exist=任务中选择的部分数据集不存在或者已被删除,请新建调试任务。

grampus.train_job.ai_center=智算中心
grampus.dataset_path_rule = 训练脚本存储在/cache/code中,数据集存储在/cache/dataset中,训练输出请存储在/cache/output中以供后续下载。
grampus.gpu_dataset_path_rule = 训练脚本存储在/tmp/code中,数据集存储在/tmp/dataset中,训练输出请存储在/tmp/output中以供后续下载。
@@ -2768,6 +2774,11 @@ repos.pr=PR数
repos.commit=Commit数
repos.closedIssues=已解决任务数
repos.contributor=贡献者数
repos.numDataset=数据集文件数
repos.numCloudbrain=云脑任务数
repos.numModel=模型数
repos.numModelConvert=转换任务数

repos.yes=是
repos.no=否

@@ -3138,6 +3149,8 @@ reject_pull_request=`建议变更 <a href="%s/pulls/%s">%s#%[2]s</a>`
upload_dataset=`上传了数据集文件 <a href="%s/datasets">%s</a>`
task_gpudebugjob=`创建了CPU/GPU类型调试任务 <a href="%s/cloudbrain/%s">%s</a>`
task_npudebugjob=`创建了NPU类型调试任务 <a href="%s/modelarts/notebook/%s">%s</a>`
task_c2net_gpudebugjob=`创建了CPU/GPU类型调试任务 <a href="%s/grampus/notebook/%s">%s</a>`
task_c2net_npudebugjob=`创建了NPU类型调试任务 <a href="%s/grampus/notebook/%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_benchmark=`创建了评测任务 <a href="%s/cloudbrain/benchmark/%s">%s</a>`
@@ -3258,6 +3271,7 @@ resource_specification = 资源规格
dataset_storage_path = 数据集存放路径
model_storage_path = 模型存放路径
code_storage_path = 代码存放路径
output_storage_path = 输出存放路径
benchmark_path = benchmark脚本存放路径
snn4imagenet_path = snn4imagenet脚本存放路径
brainscore_path = brainscore脚本存放路径
@@ -3315,8 +3329,11 @@ load_code_failed=代码加载失败,请确认选择了正确的分支。

error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集
new_train_gpu_tooltips = 训练脚本存储在 <strong style="color:#010101">%s</strong> 中,数据集存储在 <strong style="color:#010101">%s</strong> 中,预训练模型存放在运行参数 <strong style="color:#010101">%s</strong> 中,训练输出请存储在 <strong style="color:#010101">%s</strong> 中以供后续下载。
new_debug_gpu_tooltips = 项目代码存储在 <strong style="color:#010101">%s</strong> 中,数据集存储在 <strong style="color:#010101">%s</strong> 中,选择的模型存储在 <strong style="color:#010101">%s</strong> 中,调试输出请存储在 <strong style="color:#010101">%s</strong> 中以供后续下载。
new_debug_gpu_tooltips1 = 项目代码存储在 <strong style="color:#010101">%s</strong> 中,数据集存储在 <strong style="color:#010101">%s</strong> 中,选择的模型存储在 <strong style="color:#010101">%s</strong> 中。
new_train_npu_tooltips = 训练脚本存储在 <strong style="color:#010101">%s</strong> 中,预训练模型存放在运行参数 <strong style="color:#010101">%s</strong> 中,训练输出请存储在 <strong style="color:#010101">%s</strong> 中以供后续下载。
new_infer_gpu_tooltips = 数据集存储在 <strong style="color:#010101">%s</strong> 中,模型文件存储在 <strong style="color:#010101">%s</strong> 中,推理输出请存储在 <strong style="color:#010101">%s</strong> 中以供后续下载。
code_obs_address = 代码obs地址

[points]
points = 积分


+ 10
- 3
public/home/home.js View File

@@ -247,7 +247,7 @@ document.onreadystatechange = function () {
html += recordPrefix + actionName;
html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>"
}
else if(record.OpType == "25" || record.OpType == "29"){
else if(record.OpType == "25" || record.OpType == "29" || record.OpType == "39" || record.OpType == "40"){
html += recordPrefix + actionName;
html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>"
}
@@ -294,7 +294,10 @@ function getTaskLink(record){
re = re + "/cloudbrain/train-job/" + record.Content;
}else if(record.OpType == 32 || record.OpType == 33){
re = re + "/grampus/train-job/" + record.Content;
}else if(record.OpType == 39 || record.OpType == 40){
re = re + "/grampus/notebook/" + record.Content;
}
re = encodeURI(re);
return re;
}
@@ -450,7 +453,9 @@ var actionNameZH={
"33":"创建了CPU/GPU类型训练任务",
"35":"创建的数据集 {dataset} 被设置为推荐数据集",
"36":"提交了镜像 {image}",
"37":"提交的镜像 {image} 被设置为推荐镜像",
"37": "提交的镜像 {image} 被设置为推荐镜像",
"39":"创建了CPU/GPU类型调试任务",
"40":"创建了NPU类型调试任务",
};

var actionNameEN={
@@ -481,7 +486,9 @@ var actionNameEN={
"33":" created CPU/GPU type training task",
"35":" created dataset {dataset} was set as recommended dataset",
"36":"committed image {image}",
"37":"committed image {image} was set as recommended image",
"37": "committed image {image} was set as recommended image",
"39":" created CPU/GPU type debugging task ",
"40":" created NPU type debugging task ",
};

var repoAndOrgZH={


+ 3
- 0
routers/api/v1/api.go View File

@@ -1062,6 +1062,9 @@ func RegisterRoutes(m *macaron.Macaron) {
})
}, reqRepoReader(models.UnitTypeCloudBrain))
m.Group("/grampus", func() {
m.Group("/notebook", func() {
m.Get("/:id", repo_ext.GetGrampusNotebook)
})
m.Group("/train-job", func() {
m.Group("/:jobid", func() {
m.Get("", repo.GetModelArtsTrainJobVersion)


+ 56
- 9
routers/api/v1/repo/cloudbrain.go View File

@@ -9,6 +9,7 @@ import (
"bufio"
"encoding/json"
"io"
"io/ioutil"
"net/http"
"os"
"path"
@@ -237,7 +238,7 @@ func GetCloudbrainTask(ctx *context.APIContext) {

ID := ctx.Params(":id")

job, err := cloudbrain.GetCloudBrainByIdOrJobId(ID)
job, err := cloudbrain.GetCloudBrainByIdOrJobId(ID, "id")

if err != nil {
ctx.NotFound(err)
@@ -647,6 +648,19 @@ func CloudbrainDownloadLogFile(ctx *context.Context) {
}
}

existStr := ""
if job.JobType == string(models.JobTypeTrain) || job.JobType == string(models.JobTypeInference) {
if job.Type == models.TypeCloudBrainOne {
result, err := cloudbrain.GetJob(job.JobID)
if err == nil && result != nil {
jobRes, _ := models.ConvertToJobResultPayload(result.Payload)
taskRoles := jobRes.TaskRoles
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
existStr = taskRes.TaskStatuses[0].ExitDiagnostics
}
}
}

logDir := "/model"
if job.JobType == string(models.JobTypeInference) || job.JobType == string(models.JobTypeModelSafety) {
logDir = cloudbrain.ResultPath
@@ -664,17 +678,30 @@ func CloudbrainDownloadLogFile(ctx *context.Context) {
}
}
if fileName != "" {
prefix := "/" + setting.CBCodePathPrefix + job.JobName + logDir
url, err := storage.Attachments.PresignedGetURL(prefix+"/"+fileName, fileName)
prefix := "/" + setting.CBCodePathPrefix + job.JobName + "/model"
filePath := setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + prefix + "/" + fileName
// Read the file contents into a byte slice
data, err := ioutil.ReadFile(filePath)
if err != nil {
log.Error("Get minio get SignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
ctx.ServerError("ReadFile", err)
return
}

// Set the appropriate response headers
ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+fileName)

// Write the file contents to the response
if _, err := ctx.Resp.Write(data); err != nil {
ctx.ServerError("Write", err)
return
}
if _, err := ctx.Resp.Write([]byte(existStr)); err != nil {
log.Error("Write failed: %v", err.Error(), ctx.Data["msgID"])
return
}
log.Info("fileName=" + fileName)
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect)
} else {
log.Info("fileName is null.")

}
}

@@ -760,8 +787,28 @@ func CloudbrainGetLog(ctx *context.APIContext) {
content = result["Content"].(string)
}

if ctx.Data["existStr"] != nil && result["Lines"].(int) < 50 {
content = content + ctx.Data["existStr"].(string)
if (job.JobType == string(models.JobTypeTrain) || job.JobType == string(models.JobTypeInference)) && job.Type == models.TypeCloudBrainOne && job.Status == string(models.JobFailed) {
if ctx.Data["existStr"] != nil {
if baseLine == "" && order == "desc" && result["Lines"].(int) == 0 {
result["Lines"] = 1
result["EndLine"] = 1
content = content + ctx.Data["existStr"].(string)
}

if result["Lines"].(int) == 0 && result["StartLine"] == result["EndLine"] && result["StartLine"].(int) != 0 {
content = content + ctx.Data["existStr"].(string)
result["Lines"] = 1
result["StartLine"] = result["StartLine"].(int) - 1
}
if result["Lines"].(int) == 1 && result["StartLine"] == result["EndLine"] {
result["Lines"] = 0
result["StartLine"] = result["StartLine"].(int) + 1
}
}
} else {
if ctx.Data["existStr"] != nil && result["Lines"].(int) < 50 {
content = content + ctx.Data["existStr"].(string)
}
}

logFileName := result["FileName"]


+ 36
- 60
routers/api/v1/repo/cloudbrain_dashboard.go View File

@@ -103,86 +103,62 @@ func GetAllCloudbrainsOverview(ctx *context.Context) {
})
}
func GetOverviewDuration(ctx *context.Context) {
recordCloudbrain, err := models.GetRecordBeginTime()
if err != nil {
log.Error("Can not get recordCloudbrain", err)
ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
return
}
recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix
now := time.Now()
endTime := now
var workServerNumber int64
var cardNum int64
durationSum := 0
cardDurationSum := 0

durationAllSum := int64(0)
cardDuSum := int64(0)
cloudBrainOneCardDuSum := 0
cloudBrainTwoCardDuSum := 0
c2NetCardDuSum := 0
cDNetCardDuSum := 0

cloudBrainOneCardDuSum := int64(0)
cloudBrainTwoCardDuSum := int64(0)
c2NetCardDuSum := int64(0)
cDNetCardDuSum := int64(0)
cloudBrainOneDuration := 0
cloudBrainTwoDuration := 0
c2NetDuration := 0
cDCenterDuration := 0

cloudBrainOneDuration := int64(0)
cloudBrainTwoDuration := int64(0)
c2NetDuration := int64(0)
cDCenterDuration := int64(0)

cloudbrains, _, err := models.CloudbrainAllKanBan(&models.CloudbrainsOptions{
Type: models.TypeCloudBrainAll,
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
})
cloudbrainTypeDuration, err := models.GetCloudbrainTypeCardDuration()
if err != nil {
ctx.ServerError("Get cloudbrains failed:", err)
log.Error("GetCloudbrainTypeCardDuration err!", err)
return
}
models.LoadSpecs4CloudbrainInfo(cloudbrains)

for _, cloudbrain := range cloudbrains {
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.Spec != nil {
cardNum = int64(cloudbrain.Cloudbrain.Spec.AccCardsNum)
} else {
cardNum = 1
for _, result := range cloudbrainTypeDuration {
if result.Type == models.TypeCloudBrainOne {
cloudBrainOneDuration = result.DurationSum
cloudBrainOneCardDuSum = result.CardDurationSum
}
if cloudbrain.Cloudbrain.WorkServerNumber >= 1 {
workServerNumber = int64(cloudbrain.Cloudbrain.WorkServerNumber)
} else {
workServerNumber = 1
if result.Type == models.TypeCloudBrainTwo {
cloudBrainTwoDuration = result.DurationSum
cloudBrainTwoCardDuSum = result.CardDurationSum
}
duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration)
CardDuration := workServerNumber * int64(cardNum) * duration

if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne {
cloudBrainOneDuration += duration
cloudBrainOneCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo {
cloudBrainTwoDuration += duration
cloudBrainTwoCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeC2Net {
c2NetDuration += duration
c2NetCardDuSum += CardDuration
} else if cloudbrain.Cloudbrain.Type == models.TypeCDCenter {
cDCenterDuration += duration
cDNetCardDuSum += CardDuration
if result.Type == models.TypeC2Net {
c2NetDuration = result.DurationSum
c2NetCardDuSum = result.CardDurationSum
}

durationAllSum += duration
cardDuSum += CardDuration
if result.Type == models.TypeCDCenter {
cDCenterDuration = result.DurationSum
cDNetCardDuSum = result.CardDurationSum
}
}
cloudbrainAllDuration, err := models.GetCloudbrainAllCardDuration()
if err != nil {
log.Error("GetCloudbrainAllCardDuration err!", err)
return
}
durationSum = cloudbrainAllDuration.DurationSum
cardDurationSum = cloudbrainAllDuration.CardDurationSum

ctx.JSON(http.StatusOK, map[string]interface{}{
"cloudBrainOneCardDuSum": cloudBrainOneCardDuSum,
"cloudBrainTwoCardDuSum": cloudBrainTwoCardDuSum,
"c2NetCardDuSum": c2NetCardDuSum,
"cDNetCardDuSum": cDNetCardDuSum,
"cardDuSum": cardDuSum,
"cardDuSum": cardDurationSum,

"cloudBrainOneDuration": cloudBrainOneDuration,
"cloudBrainTwoDuration": cloudBrainTwoDuration,
"c2NetDuration": c2NetDuration,
"cDCenterDuration": cDCenterDuration,
"durationSum": durationAllSum,
"durationSum": durationSum,
})
}



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

@@ -88,7 +88,7 @@ func getModelArtsImages(ctx *context.APIContext) {
}

func getC2netNpuImages(ctx *context.APIContext) {
images, err := grampus.GetImages(grampus.ProcessorTypeNPU)
images, err := grampus.GetImages(grampus.ProcessorTypeNPU, string(models.JobTypeTrain))
var npuImageInfos []NPUImageINFO
if err != nil {
log.Error("GetImages failed:", err.Error())


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

@@ -39,7 +39,7 @@ func GetModelArtsNotebook2(ctx *context.APIContext) {

ID := ctx.Params(":id")

job,err := cloudbrain.GetCloudBrainByIdOrJobId(ID)
job, err := cloudbrain.GetCloudBrainByIdOrJobId(ID, "id")

if err != nil {
ctx.NotFound(err)


+ 8
- 6
routers/api/v1/repo/repo_dashbord.go View File

@@ -601,7 +601,7 @@ func getSummaryFileName(ctx *context.Context, beginTime time.Time, endTime time.
func allProjectsPeroidHeader(ctx *context.Context) map[string]string {

return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.openi"), "F1": ctx.Tr("admin.repos.visit"), "G1": ctx.Tr("admin.repos.download"), "H1": ctx.Tr("admin.repos.pr"), "I1": ctx.Tr("admin.repos.commit"),
"J1": ctx.Tr("admin.repos.watches"), "K1": ctx.Tr("admin.repos.stars"), "L1": ctx.Tr("admin.repos.forks"), "M1": ctx.Tr("admin.repos.issues"), "N1": ctx.Tr("admin.repos.closedIssues"), "O1": ctx.Tr("admin.repos.contributor"), "P1": ctx.Tr("admin.repos.isFork"), "Q1": ctx.Tr("admin.repos.isMirror"), "R1": ctx.Tr("admin.repos.create")}
"J1": ctx.Tr("admin.repos.watches"), "K1": ctx.Tr("admin.repos.stars"), "L1": ctx.Tr("admin.repos.forks"), "M1": ctx.Tr("admin.repos.issues"), "N1": ctx.Tr("admin.repos.closedIssues"), "O1": ctx.Tr("admin.repos.contributor"), "P1": ctx.Tr("admin.repos.numDataset"), "Q1": ctx.Tr("admin.repos.numCloudbrain"), "R1": ctx.Tr("admin.repos.numModel"), "S1": ctx.Tr("admin.repos.numModelConvert"), "T1": ctx.Tr("admin.repos.isFork"), "U1": ctx.Tr("admin.repos.isMirror"), "V1": ctx.Tr("admin.repos.create")}

}

@@ -619,11 +619,13 @@ func allProjectsPeriodSummaryValues(row int, rs *ProjectSummaryBaseData, ctx *co
}

func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string {

return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64),
getCellName("F", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("G", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("H", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("I", row): strconv.FormatInt(rs.NumCommits, 10),
getCellName("J", row): strconv.FormatInt(rs.NumWatches, 10), getCellName("K", row): strconv.FormatInt(rs.NumStars, 10), getCellName("L", row): strconv.FormatInt(rs.NumForks, 10), getCellName("M", row): strconv.FormatInt(rs.NumIssues, 10),
getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("P", row): getBoolDisplay(rs.IsFork, ctx), getCellName("Q", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("R", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT),
getCellName("N", row): strconv.FormatInt(rs.NumClosedIssues, 10), getCellName("O", row): strconv.FormatInt(rs.NumContributor, 10), getCellName("P", row): strconv.FormatInt(rs.NumDatasetFile, 10), getCellName("Q", row): strconv.FormatInt(rs.NumCloudbrain, 10), getCellName("R", row): strconv.FormatInt(rs.NumModels, 10), getCellName("S", row): strconv.FormatInt(rs.NumModelConvert, 10), getCellName("T", row): getBoolDisplay(rs.IsFork, ctx), getCellName("U", row): getBoolDisplay(rs.IsMirror, ctx), getCellName("V", row): time.Unix(int64(rs.RepoCreatedUnix), 0).Format(CREATE_TIME_FORMAT),
}

}

func allProjectsOpenIHeader() map[string]string {
@@ -804,11 +806,11 @@ func generateOpenICountSql(latestDate string) string {
}

func generateTypeAllSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string {
sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " +
sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor,num_models,num_model_convert,num_cloudbrain,num_dataset_file FROM " +
"(SELECT repo_id,sum(num_visits) as num_visits " +
" FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
" and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," +
"(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor from public.repo_statistic where date='" + latestDate + "') B" +
"(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor,num_models,num_model_convert,num_cloudbrain,num_dataset_file from public.repo_statistic where date='" + latestDate + "') B" +
" where A.repo_id=B.repo_id"

if q != "" {
@@ -828,8 +830,8 @@ func generateTypeAllOpenISql(latestDate string, page int, pageSize int) string {

func generatePageSql(beginTime time.Time, endTime time.Time, latestDate string, q string, orderBy string, page int, pageSize int) string {

sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor FROM " +
"(SELECT repo_id,sum(num_watches_added) as num_watches,sum(num_visits) as num_visits, sum(num_downloads_added) as num_downloads,sum(num_pulls_added) as num_pulls,sum(num_commits_added) as num_commits,sum(num_stars_added) as num_stars,sum(num_forks_added) num_forks,sum(num_issues_added) as num_issues,sum(num_closed_issues_added) as num_closed_issues,sum(num_contributor_added) as num_contributor " +
sql := "SELECT A.repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total,num_watches,num_visits,num_downloads,num_pulls,num_commits,num_stars,num_forks,num_issues,num_closed_issues,num_contributor,num_models,num_model_convert,num_cloudbrain,num_dataset_file FROM " +
"(SELECT repo_id,sum(num_watches_added) as num_watches,sum(num_visits) as num_visits, sum(num_downloads_added) as num_downloads,sum(num_pulls_added) as num_pulls,sum(num_commits_added) as num_commits,sum(num_stars_added) as num_stars,sum(num_forks_added) num_forks,sum(num_issues_added) as num_issues,sum(num_closed_issues_added) as num_closed_issues,sum(num_contributor_added) as num_contributor,sum(num_models_added) as num_models,sum(num_model_convert_added) as num_model_convert,sum(num_dataset_file_added) as num_dataset_file, sum(num_cloudbrain_added) as num_cloudbrain " +
" FROM repo_statistic where created_unix >=" + strconv.FormatInt(beginTime.Unix(), 10) +
" and created_unix<" + strconv.FormatInt(endTime.Unix(), 10) + " group by repo_id) A," +
"(SELECT repo_id,name,alias,owner_name,is_private,is_mirror,is_fork,repo_created_unix,radar_total from public.repo_statistic where date='" + latestDate + "') B" +


+ 17
- 11
routers/repo/ai_model_manage.go View File

@@ -1319,19 +1319,25 @@ func QueryModelFileForPredict(ctx *context.Context) {

func QueryModelFileByID(id string) []storage.FileInfo {
model, err := models.QueryModelById(id)
if err == nil {
if model.Type == models.TypeCloudBrainTwo {
prefix := model.Path[len(setting.Bucket)+1:]
fileinfos, _ := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, prefix)
return fileinfos
} else if model.Type == models.TypeCloudBrainOne {
prefix := model.Path[len(setting.Attachment.Minio.Bucket)+1:]
fileinfos, _ := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, prefix)
return fileinfos
}
} else {
if err != nil {
log.Error("no such model!", err.Error())
return nil
}
return QueryModelFileByModel(model)
}

func QueryModelFileByModel(model *models.AiModelManage) []storage.FileInfo {

if model.Type == models.TypeCloudBrainTwo {
prefix := model.Path[len(setting.Bucket)+1:]
fileinfos, _ := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, prefix)
return fileinfos
} else if model.Type == models.TypeCloudBrainOne {
prefix := model.Path[len(setting.Attachment.Minio.Bucket)+1:]
fileinfos, _ := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, prefix)
return fileinfos
}

return nil
}



+ 120
- 57
routers/repo/cloudbrain.go View File

@@ -81,6 +81,7 @@ var (

const BENCHMARK_TYPE_CODE = "repo.cloudbrain.benchmark.types"
const CLONE_FILE_PREFIX = "file:///"
const README = "README"

var benchmarkTypesMap = make(map[string]*models.BenchmarkTypes, 0)

@@ -373,6 +374,13 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) {
}

if form.ModelName != "" { //使用预训练模型训练
_, err := models.QueryModelByPath(form.PreTrainModelUrl)
if err != nil {
log.Error("Can not find model", err)
cloudBrainNewDataPrepare(ctx, jobType)
ctx.RenderWithErr(ctx.Tr("repo.modelconvert.manage.model_not_exist"), tpl, &form)
return
}
req.ModelName = form.ModelName
req.LabelName = form.LabelName
req.CkptName = form.CkptName
@@ -411,8 +419,13 @@ func loadCodeAndMakeModelPath(repo *models.Repository, codePath string, branchNa
return "cloudbrain.load_code_failed"
}

return initModelPath(jobName, resultPath)

}

func initModelPath(jobName string, resultPath string) string {
modelPath := setting.JobPath + jobName + resultPath + "/"
err = mkModelPath(modelPath)
err := mkModelPath(modelPath)
if err != nil {
return "cloudbrain.load_code_failed"
}
@@ -691,6 +704,17 @@ func CloudBrainRestart(ctx *context.Context) {
break
}
}
if !HasModelFile(task) {
resultCode = "-1"
errorMsg = ctx.Tr("repo.debug.manage.model_not_exist")
break
}

if hasDatasetDeleted(task) {
resultCode = "-1"
errorMsg = ctx.Tr("repo.debug.manage.dataset_not_exist")
break
}

err = cloudbrain.RestartTask(ctx, task, &ID)
if err != nil {
@@ -711,6 +735,40 @@ func CloudBrainRestart(ctx *context.Context) {
})
}

func hasDatasetDeleted(task *models.Cloudbrain) bool {
if task.Uuid == "" {
return false
}
uuids := strings.Split(task.Uuid, ";")
attachs, _ := models.GetAttachmentsByUUIDs(uuids)
return len(attachs) < len(uuids)
}

func HasModelFile(task *models.Cloudbrain) bool {
if task.PreTrainModelUrl == "" {
return true
}

model, err := models.QueryModelByPath(task.PreTrainModelUrl)
if err != nil {
log.Error("Can not find model", err)
return false
}

fileInfos := QueryModelFileByModel(model)
isFind := false
if fileInfos != nil {
for _, fileInfo := range fileInfos {
if fileInfo.FileName == task.CkptName {
isFind = true
break
}
}

}
return isFind
}

func getOldJobPath(task *models.Cloudbrain) string {
return setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + task.JobName
}
@@ -1772,7 +1830,7 @@ func mkPathAndReadMeFile(path string, text string) error {
return err
}

fileName := path + "README"
fileName := path + README
f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm)
if err != nil {
log.Error("OpenFile failed", err.Error())
@@ -1830,6 +1888,7 @@ func SyncCloudbrainStatus() {
if task.JobType == string(models.JobTypeModelSafety) {
continue
}

if task.Type == models.TypeCloudBrainOne {

task, err = cloudbrainTask.SyncCloudBrainOneStatus(task)
@@ -1838,32 +1897,7 @@ func SyncCloudbrainStatus() {
continue
}

if task.Status != string(models.JobWaiting) {
if task.Duration >= setting.MaxDuration && task.JobType == string(models.JobTypeDebug) {
log.Info("begin to stop job(%s), because of the duration", task.DisplayJobName)
err = cloudbrain.StopJob(task.JobID)
if err != nil {
log.Error("StopJob(%s) failed:%v", task.DisplayJobName, err)
continue
}
oldStatus := task.Status
task.Status = string(models.JobStopped)
if task.EndTime == 0 {
task.EndTime = timeutil.TimeStampNow()
}
task.ComputeAndSetDuration()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err)
continue
}
}

}
} else if task.Type == models.TypeCloudBrainTwo {
} else if task.Type == models.TypeCloudBrainTwo || task.Type == models.TypeCDCenter {
if task.JobType == string(models.JobTypeDebug) {
err := modelarts.HandleNotebookInfo(task)
if err != nil {
@@ -1880,48 +1914,77 @@ func SyncCloudbrainStatus() {
log.Error("task.JobType(%s) is error:%s", task.DisplayJobName, task.JobType)
}
} else if task.Type == models.TypeC2Net {
result, err := grampus.GetJob(task.JobID)
if err != nil {
log.Error("GetTrainJob(%s) failed:%v", task.DisplayJobName, err)
continue
}

if result != nil {
if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 {
task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0]
if task.JobType == string(models.JobTypeDebug) {
cloudbrainTask.SyncGrampusNotebookStatus(task)
} else {
result, err := grampus.GetJob(task.JobID)
if err != nil {
log.Error("GetTrainJob(%s) failed:%v", task.DisplayJobName, err)
continue
}
oldStatus := task.Status
task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status)
task.Duration = result.JobInfo.RunSec

if task.Duration < 0 {
task.Duration = 0
}
task.TrainJobDuration = models.ConvertDurationToStr(task.Duration)
if result != nil {
if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 {
task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0]
}
oldStatus := task.Status
task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status)
task.Duration = result.JobInfo.RunSec

if task.StartTime == 0 && result.JobInfo.StartedAt > 0 {
task.StartTime = timeutil.TimeStamp(result.JobInfo.StartedAt)
if task.Duration < 0 {
task.Duration = 0
}
task.TrainJobDuration = models.ConvertDurationToStr(task.Duration)

if task.StartTime == 0 && result.JobInfo.StartedAt > 0 {
task.StartTime = timeutil.TimeStamp(result.JobInfo.StartedAt)
}
if task.EndTime == 0 && models.IsTrainJobTerminal(task.Status) && task.StartTime > 0 {
task.EndTime = task.StartTime.Add(task.Duration)
}
task.CorrectCreateUnix()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
if models.IsTrainJobTerminal(task.Status) && task.ComputeResource == models.NPUResource {
if len(result.JobInfo.Tasks[0].CenterID) == 1 {
urchin.GetBackNpuModel(task.ID, grampus.GetRemoteEndPoint(result.JobInfo.Tasks[0].CenterID[0]), grampus.BucketRemote, grampus.GetNpuModelObjectKey(task.JobName), grampus.GetCenterProxy(setting.Grampus.LocalCenterID))
}
}
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)
continue
}
}
}
} else {
log.Error("task.Type(%s) is error:%d", task.JobName, task.Type)
}
if task.Status != string(models.JobWaiting) {
if task.Duration >= setting.MaxDuration && task.JobType == string(models.JobTypeDebug) {
log.Info("begin to stop job(%s), because of the duration", task.DisplayJobName)
err = cloudbrainTask.StopDebugJob(task)
if err != nil {
log.Error("StopJob(%s) failed:%v", task.DisplayJobName, err)
continue
}
if task.EndTime == 0 && models.IsTrainJobTerminal(task.Status) && task.StartTime > 0 {
task.EndTime = task.StartTime.Add(task.Duration)
oldStatus := task.Status
task.Status = string(models.JobStopped)
if task.EndTime == 0 {
task.EndTime = timeutil.TimeStampNow()
}
task.CorrectCreateUnix()
task.ComputeAndSetDuration()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
if models.IsTrainJobTerminal(task.Status) && task.ComputeResource == models.NPUResource {
if len(result.JobInfo.Tasks[0].CenterID) == 1 {
urchin.GetBackNpuModel(task.ID, grampus.GetRemoteEndPoint(result.JobInfo.Tasks[0].CenterID[0]), grampus.BucketRemote, grampus.GetNpuModelObjectKey(task.JobName), grampus.GetCenterProxy(setting.Grampus.LocalCenterID))
}
}
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob(%s) failed:%v", task.JobName, err)
log.Error("UpdateJob(%s) failed:%v", task.DisplayJobName, err)
continue
}
}
} else {
log.Error("task.Type(%s) is error:%d", task.JobName, task.Type)

}
}



+ 74
- 120
routers/repo/cloudbrain_statistic.go View File

@@ -14,13 +14,7 @@ import (
)

func CloudbrainDurationStatisticHour() {
defer func() {
err := recover()
if err == nil {
return
}
}()
if setting.IsCloudbrainTimingEnabled {
if setting.IsCloudbrainTimingEnabled {
var statisticTime time.Time
var count int64
recordDurationUpdateTime, err := models.GetDurationRecordUpdateTime()
@@ -35,17 +29,16 @@ func CloudbrainDurationStatisticHour() {
statisticTime = currentTime
}

err = models.DeleteCloudbrainDurationStatistic(timeutil.TimeStamp(statisticTime.Add(-1*time.Hour).Unix()), timeutil.TimeStamp(currentTime.Unix()))
err = models.DeleteCloudbrainDurationStatistic(timeutil.TimeStamp(statisticTime.Unix()), timeutil.TimeStamp(currentTime.Unix()))
if err != nil {
log.Error("DeleteCloudbrainDurationStatistic failed", err)
}
statisticTime = statisticTime.Add(+1 * time.Hour)
for statisticTime.Before(currentTime) || statisticTime.Equal(currentTime) {
countEach := summaryDurationStat(statisticTime)
count += countEach
statisticTime = statisticTime.Add(+1 * time.Hour)
}
log.Info("summaryDurationStat count: %v", count)
}
}
func UpdateDurationStatisticHistoryData(beginTime time.Time, endTime time.Time) int64 {
@@ -71,15 +64,18 @@ func summaryDurationStat(statisticTime time.Time) int64 {

ciTasks, err := models.GetCloudbrainByTime(beginTime, endTime)
if err != nil {
log.Info("GetCloudbrainByTime err: %v", err)
log.Error("GetCloudbrainByTime err: %v", err)
return 0
}
models.LoadSpecs4CloudbrainInfo(ciTasks)
cloudBrainCenterCodeAndCardTypeInfo, cloudbrainMap := getcloudBrainCenterCodeAndCardTypeInfo(ciTasks, beginTime, endTime)
err = models.LoadSpecs4CloudbrainInfo(ciTasks)
if err != nil {
log.Error("LoadSpecs4CloudbrainInfo err: %v", err)
}
cloudBrainCenterCodeAndCardTypeInfo := getcloudBrainCenterCodeAndCardTypeInfo(ciTasks, int(beginTime), int(endTime))

resourceQueues, err := models.GetCanUseCardInfo()
if err != nil {
log.Info("GetCanUseCardInfo err: %v", err)
log.Error("GetCanUseCardInfo err: %v", err)
return 0
}

@@ -91,56 +87,45 @@ func summaryDurationStat(statisticTime time.Time) int64 {
cardsTotalDurationMap[resourceQueue.Cluster+"/"+resourceQueue.AiCenterCode+"/"+resourceQueue.AccCardType] += resourceQueue.CardsTotalNum * 1 * 60 * 60
}
}

for centerCode, CardTypes := range cloudBrainCenterCodeAndCardTypeInfo {
for cardType, cardDuration := range CardTypes {
cloudbrainTable := cloudbrainMap[centerCode+"/"+cardType]
if cloudbrainTable != nil {
if _, ok := cardsTotalDurationMap[cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType]; !ok {
cardsTotalDurationMap[cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType] = 0
}
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: cloudbrainTable.Cluster,
AiCenterName: GetAiCenterNameByCode(centerCode, "zh-CN"),
AiCenterCode: centerCode,
AccCardType: cardType,
CardsUseDuration: cardDuration,
CardsTotalDuration: cardsTotalDurationMap[cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType],
CreatedUnix: timeutil.TimeStampNow(),
}
if _, err = models.InsertCloudbrainDurationStatistic(&cloudbrainDurationStat); err != nil {
log.Error("Insert cloudbrainDurationStat failed: %v", err.Error())
}
count++
delete(cardsTotalDurationMap, cloudbrainTable.Cluster+"/"+centerCode+"/"+cardType)
}
}
}

for key, cardsTotalDuration := range cardsTotalDurationMap {
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: strings.Split(key, "/")[0],
AiCenterName: GetAiCenterNameByCode(strings.Split(key, "/")[1], "zh-CN"),
AiCenterCode: strings.Split(key, "/")[1],
AccCardType: strings.Split(key, "/")[2],
CardsUseDuration: 0,
CardsTotalDuration: cardsTotalDuration,
CardsTotalNum: cardsTotalDuration / 1 / 60 / 60,
CreatedUnix: timeutil.TimeStampNow(),
}
if _, err = models.InsertCloudbrainDurationStatistic(&cloudbrainDurationStat); err != nil {
log.Error("Insert cloudbrainDurationStat failed: %v", err.Error())
if _, ok := cloudBrainCenterCodeAndCardTypeInfo[strings.Split(key, "/")[0]+"/"+strings.Split(key, "/")[1]][strings.Split(key, "/")[2]]; ok {
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: strings.Split(key, "/")[0],
AiCenterName: GetAiCenterNameByCode(strings.Split(key, "/")[1], "zh-CN"),
AiCenterCode: strings.Split(key, "/")[1],
AccCardType: strings.Split(key, "/")[2],
CardsUseDuration: cloudBrainCenterCodeAndCardTypeInfo[strings.Split(key, "/")[0]+"/"+strings.Split(key, "/")[1]][strings.Split(key, "/")[2]],
CardsTotalDuration: cardsTotalDuration,
CardsTotalNum: cardsTotalDuration / 1 / 60 / 60,
CreatedUnix: timeutil.TimeStampNow(),
}
if _, err = models.InsertCloudbrainDurationStatistic(&cloudbrainDurationStat); err != nil {
log.Error("Insert cloudbrainDurationStat failed: %v", err.Error())
}
count++
} else {
cloudbrainDurationStat := models.CloudbrainDurationStatistic{
DateTimeUnix: dateTimeUnix,
DayTime: dayTime,
HourTime: hourTime,
Cluster: strings.Split(key, "/")[0],
AiCenterName: GetAiCenterNameByCode(strings.Split(key, "/")[1], "zh-CN"),
AiCenterCode: strings.Split(key, "/")[1],
AccCardType: strings.Split(key, "/")[2],
CardsUseDuration: 0,
CardsTotalDuration: cardsTotalDuration,
CardsTotalNum: cardsTotalDuration / 1 / 60 / 60,
CreatedUnix: timeutil.TimeStampNow(),
}
if _, err = models.InsertCloudbrainDurationStatistic(&cloudbrainDurationStat); err != nil {
log.Error("Insert cloudbrainDurationStat failed: %v", err.Error())
}
count++
}
count++
}

log.Info("finish summary cloudbrainDurationStat")
return count
}

@@ -159,33 +144,21 @@ func GetAiCenterNameByCode(centerCode string, language string) string {
return aiCenterName
}

func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, beginTime int64, endTime int64) (map[string]map[string]int, map[string]*models.Cloudbrain) {
func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, hourBeginTime int, hourEndTime int) map[string]map[string]int {
var WorkServerNumber int
var AccCardsNum int
cloudbrainMap := make(map[string]*models.Cloudbrain)
cloudBrainCenterCodeAndCardType := make(map[string]map[string]int)
for _, cloudbrain := range ciTasks {
if cloudbrain.Cloudbrain.StartTime == 0 {
cloudbrain.Cloudbrain.StartTime = cloudbrain.Cloudbrain.CreatedUnix
}
if cloudbrain.Cloudbrain.EndTime == 0 {
cloudbrain.Cloudbrain.EndTime = timeutil.TimeStamp(time.Now().Unix())
}
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.Spec != nil {
if _, ok := cloudbrainMap[cloudbrain.Cloudbrain.AiCenter+"/"+cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
if cloudbrain.Cloudbrain.Spec != nil {
cloudbrainMap[cloudbrain.Cloudbrain.AiCenter+"/"+cloudbrain.Cloudbrain.Spec.AccCardType] = &cloudbrain.Cloudbrain
}
}
}

cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain)
if cloudbrain.Cloudbrain.StartTime == 0 {
cloudbrain.Cloudbrain.StartTime = cloudbrain.Cloudbrain.CreatedUnix
}
if cloudbrain.Cloudbrain.EndTime == 0 {
cloudbrain.Cloudbrain.EndTime = cloudbrain.Cloudbrain.UpdatedUnix
if cloudbrain.Cloudbrain.Status == string(models.JobRunning) {
cloudbrain.Cloudbrain.EndTime = timeutil.TimeStamp(time.Now().Unix())
} else {
cloudbrain.Cloudbrain.EndTime = cloudbrain.Cloudbrain.StartTime + timeutil.TimeStamp(cloudbrain.Cloudbrain.Duration)
}
}
if cloudbrain.Cloudbrain.WorkServerNumber >= 1 {
WorkServerNumber = cloudbrain.Cloudbrain.WorkServerNumber
@@ -197,55 +170,36 @@ func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, be
} else {
AccCardsNum = cloudbrain.Cloudbrain.Spec.AccCardsNum
}
if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter]; !ok {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter] = make(map[string]int)
if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter]; !ok {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter] = make(map[string]int)
}
taskStartTime := int(cloudbrain.Cloudbrain.StartTime)
taskEndTime := int(cloudbrain.Cloudbrain.EndTime)
if cloudbrain.Cloudbrain.Spec != nil {
if cloudbrain.Cloudbrain.Status == string(models.ModelArtsRunning) && cloudbrain.Cloudbrain.DeletedAt.IsZero() {
if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
} else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) < endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
} else if int64(cloudbrain.Cloudbrain.StartTime) >= endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = 0
}
} else {
if int64(cloudbrain.Cloudbrain.StartTime) < beginTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
} else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) < endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
} else if int64(cloudbrain.Cloudbrain.StartTime) >= endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += 0
}
if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
if taskStartTime < hourBeginTime && taskEndTime >= hourBeginTime && taskEndTime <= hourEndTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (taskEndTime - hourBeginTime)
} else if taskStartTime < hourBeginTime && taskEndTime > hourEndTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (hourEndTime - hourBeginTime)
} else if taskStartTime >= hourBeginTime && taskStartTime <= hourEndTime && taskEndTime >= hourBeginTime && taskEndTime <= hourEndTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (taskEndTime - taskStartTime)
} else if taskStartTime >= hourBeginTime && taskStartTime <= hourEndTime && taskEndTime > hourEndTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (hourEndTime - taskStartTime)
}
} else {
if _, ok := cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType]; !ok {
if int64(cloudbrain.Cloudbrain.StartTime) <= beginTime && int64(cloudbrain.Cloudbrain.EndTime) <= endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(beginTime))
} else if int64(cloudbrain.Cloudbrain.StartTime) <= beginTime && int64(cloudbrain.Cloudbrain.EndTime) > endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
} else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) <= endTime && int64(cloudbrain.Cloudbrain.EndTime) <= endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(cloudbrain.Cloudbrain.StartTime))
} else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) <= endTime && int64(cloudbrain.Cloudbrain.EndTime) > endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] = AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
}
} else {
if int64(cloudbrain.Cloudbrain.StartTime) <= beginTime && int64(cloudbrain.Cloudbrain.EndTime) <= endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(beginTime))
} else if int64(cloudbrain.Cloudbrain.StartTime) <= beginTime && int64(cloudbrain.Cloudbrain.EndTime) > endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(beginTime))
} else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) <= endTime && int64(cloudbrain.Cloudbrain.EndTime) <= endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(cloudbrain.Cloudbrain.EndTime) - int(cloudbrain.Cloudbrain.StartTime))
} else if beginTime <= int64(cloudbrain.Cloudbrain.StartTime) && int64(cloudbrain.Cloudbrain.StartTime) <= endTime && int64(cloudbrain.Cloudbrain.EndTime) > endTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (int(endTime) - int(cloudbrain.Cloudbrain.StartTime))
}
if taskStartTime < hourBeginTime && taskEndTime >= hourBeginTime && taskEndTime <= hourEndTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (taskEndTime - hourBeginTime)
} else if taskStartTime < hourBeginTime && taskEndTime > hourEndTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (hourEndTime - hourBeginTime)
} else if taskStartTime >= hourBeginTime && taskStartTime <= hourEndTime && taskEndTime >= hourBeginTime && taskEndTime <= hourEndTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (taskEndTime - taskStartTime)
} else if taskStartTime >= hourBeginTime && taskStartTime <= hourEndTime && taskEndTime > hourEndTime {
cloudBrainCenterCodeAndCardType[cloudbrain.Cloudbrain.Cluster+"/"+cloudbrain.Cloudbrain.AiCenter][cloudbrain.Cloudbrain.Spec.AccCardType] += AccCardsNum * WorkServerNumber * (hourEndTime - taskStartTime)
}
}
}
}

return cloudBrainCenterCodeAndCardType, cloudbrainMap
return cloudBrainCenterCodeAndCardType
}

func CloudbrainUpdateHistoryData(ctx *context.Context) {


+ 662
- 80
routers/repo/grampus.go View File

@@ -44,14 +44,37 @@ import (

const (
tplGrampusTrainJobShow base.TplName = "repo/grampus/trainjob/show"
tplGrampusNotebookShow base.TplName = "repo/grampus/notebook/show"

//GPU
tplGrampusNotebookGPUNew base.TplName = "repo/grampus/notebook/gpu/new"
tplGrampusTrainJobGPUNew base.TplName = "repo/grampus/trainjob/gpu/new"

//NPU
tplGrampusNotebookNPUNew base.TplName = "repo/grampus/notebook/npu/new"
tplGrampusTrainJobNPUNew base.TplName = "repo/grampus/trainjob/npu/new"
)

func GrampusNotebookNew(ctx *context.Context) {
ctx.Data["IsCreate"] = true
notebookType := ctx.QueryInt("type")
processType := grampus.ProcessorTypeGPU
if notebookType == 1 {
processType = grampus.ProcessorTypeNPU
}
err := grampusNotebookNewDataPrepare(ctx, processType)
if err != nil {
ctx.ServerError("get new notebook-job info failed", err)
return
}
if processType == grampus.ProcessorTypeGPU {
ctx.HTML(http.StatusOK, tplGrampusNotebookGPUNew)
} else {
ctx.HTML(http.StatusOK, tplGrampusNotebookNPUNew)
}

}

func GrampusTrainJobGPUNew(ctx *context.Context) {
ctx.Data["IsCreate"] = true
err := grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU)
@@ -72,57 +95,262 @@ func GrampusTrainJobNPUNew(ctx *context.Context) {
}
ctx.HTML(200, tplGrampusTrainJobNPUNew)
}
func GrampusNotebookCreate(ctx *context.Context, form auth.CreateGrampusNotebookForm) {
ctx.Data["IsCreate"] = true
displayJobName := form.DisplayJobName
jobName := util.ConvertDisplayJobNameToJobName(displayJobName)
uuid := form.Attachment
description := form.Description
repo := ctx.Repo.Repository
branchName := form.BranchName
image := strings.TrimSpace(form.Image)

func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) error {
codeStoragePath := setting.CBCodePathPrefix + jobName + cloudbrain.CodeMountPath + "/"

tpl := tplGrampusNotebookGPUNew
processType := grampus.ProcessorTypeGPU
computeSource := models.GPUResource
computeSourceSimple := models.GPU
if form.Type == 1 {
tpl = tplGrampusNotebookNPUNew
processType = grampus.ProcessorTypeNPU
computeSource = models.NPUResource
computeSourceSimple = models.NPU
codeStoragePath = grampus.JobPath + jobName + modelarts.CodePath
}

lock := redis_lock.NewDistributeLock(redis_key.CloudbrainBindingJobNameKey(fmt.Sprint(repo.ID), string(models.JobTypeDebug), displayJobName))
defer lock.UnLock()
isOk, err := lock.Lock(models.CloudbrainKeyDuration)
if !isOk {
log.Error("lock processed failed:%v", err, ctx.Data["MsgID"])
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_samejob_err"), tpl, &form)
return
}

if !jobNamePattern.MatchString(displayJobName) {
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form)
return
}

//check count limit
count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeC2Net, string(models.JobTypeDebug), computeSource)
if err != nil {
log.Error("GetGrampusCountByUserID failed:%v", err, ctx.Data["MsgID"])
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr("system error", tpl, &form)
return
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr("you have already a running or waiting task, can not create more", tpl, &form)
return
}
}

//check whether the task name in the project is duplicated
tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeDebug), displayJobName)
if err == nil {
if len(tasks) != 0 {
log.Error("the job name did already exist", ctx.Data["MsgID"])
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr("the job name did already exist", tpl, &form)
return
}
} else {
if !models.IsErrJobNotExist(err) {
log.Error("system error, %v", err, ctx.Data["MsgID"])
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr("system error", tpl, &form)
return
}
}

//check specification
spec, err := resource.GetAndCheckSpec(ctx.User.ID, form.SpecId, models.FindSpecsOptions{
JobType: models.JobTypeDebug,
ComputeResource: computeSourceSimple,
Cluster: models.C2NetCluster,
})
if err != nil || spec == nil {
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr("Resource specification not available", tpl, &form)
return
}

if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID)
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("points.insufficient_points_balance"), tpl, &form)
return
}

var datasetInfos map[string]models.DatasetInfo
var datasetNames string
//var
if uuid != "" {
datasetInfos, datasetNames, err = models.GetDatasetInfo(uuid, computeSourceSimple)
if err != nil {
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"])
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form)
return
}
}

//prepare code and out path
codeLocalPath := setting.JobPath + jobName + cloudbrain.CodeMountPath + "/"
_, err = ioutil.ReadDir(codeLocalPath)
if err == nil {
os.RemoveAll(codeLocalPath)
}

if err := downloadZipCode(ctx, codeLocalPath, branchName); err != nil {
log.Error("downloadZipCode failed, server timed out: %s (%v)", repo.FullName(), err)
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tpl, &form)
return
}

if processType == grampus.ProcessorTypeGPU {
if err := uploadCodeToMinio(codeLocalPath+"/", jobName, cloudbrain.CodeMountPath+"/"); err != nil {
log.Error("Failed to uploadCodeToMinio: %s (%v)", repo.FullName(), err, ctx.Data["MsgID"])
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tpl, &form)
return
}

} else {

if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil {
log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err)
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("cloudbrain.load_code_failed"), tpl, &form)
return
}
}

commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName)

req := &grampus.GenerateNotebookJobReq{
JobName: jobName,
DisplayJobName: displayJobName,
ComputeResource: computeSource,
ProcessType: processType,
ImageUrl: image,
ImageId: form.ImageID,
Description: description,
Uuid: uuid,
CommitID: commitID,
BranchName: branchName,
DatasetNames: datasetNames,
DatasetInfos: datasetInfos,
Spec: spec,
CodeStoragePath: codeStoragePath,
CodeName: strings.ToLower(repo.Name),
}

if form.ModelName != "" { //使用预训练模型训练

_, err := models.QueryModelByPath(form.PreTrainModelUrl)
if err != nil {
log.Error("Can not find model", err)
grampusNotebookNewDataPrepare(ctx, processType)
ctx.RenderWithErr(ctx.Tr("repo.modelconvert.manage.model_not_exist"), tpl, &form)
return
}
req.ModelName = form.ModelName
req.LabelName = form.LabelName
req.CkptName = form.CkptName
req.ModelVersion = form.ModelVersion
req.PreTrainModelUrl = form.PreTrainModelUrl
req.PreTrainModelPath = getPreTrainModelPath(form.PreTrainModelUrl, form.CkptName)

}

_, err = grampus.GenerateNotebookJob(ctx, req)
if err != nil {
log.Error("GenerateNotebookJob failed:%v", err.Error(), ctx.Data["MsgID"])
grampusTrainJobNewDataPrepare(ctx, processType)
ctx.RenderWithErr(err.Error(), tpl, &form)
return
}
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all")
}
func grampusNotebookNewDataPrepare(ctx *context.Context, processType string) error {
ctx.Data["PageIsCloudBrain"] = true

var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName

//get valid images
images, err := grampus.GetImages(processType)
if processType == grampus.ProcessorTypeNPU {
images, err := grampus.GetImages(processType, string(models.JobTypeDebug))
if err != nil {
log.Error("GetImages failed:", err.Error())
} else {
ctx.Data["images"] = images.Infos
}
}
//prepare available specs
computeResourceSimple := models.GPU
datasetType := models.TypeCloudBrainOne
computeResource := models.GPUResource
if processType == grampus.ProcessorTypeNPU {
computeResourceSimple = models.NPU
datasetType = models.TypeCloudBrainTwo
computeResource = models.NPUResource
}

prepareGrampusSpecs(ctx, computeResourceSimple, models.JobTypeDebug)

//get branches
branches, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
if err != nil {
log.Error("GetImages failed:", err.Error())
log.Error("GetBranches error:", err.Error())
} else {
ctx.Data["images"] = images.Infos
ctx.Data["branches"] = branches
}

grampus.InitSpecialPool()
ctx.Data["branchName"] = ctx.Repo.BranchName

ctx.Data["GPUEnabled"] = true
ctx.Data["NPUEnabled"] = true
includeCenters := make(map[string]struct{})
excludeCenters := make(map[string]struct{})
if grampus.SpecialPools != nil {
for _, pool := range grampus.SpecialPools.Pools {
if pool.IsExclusive {
if !IsUserInOrgPool(ctx.User.ID, pool) {
ctx.Data[pool.Type+"Enabled"] = false
}
} else {
if strings.Contains(strings.ToLower(processType), strings.ToLower(pool.Type)) {
if IsUserInOrgPool(ctx.User.ID, pool) {
for _, center := range pool.Pool {
includeCenters[center.Queue] = struct{}{}
}
} else {
for _, center := range pool.Pool {
excludeCenters[center.Queue] = struct{}{}
}
ctx.Data["datasetType"] = datasetType
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, computeResource, models.JobTypeDebug)
ctx.Data["WaitCount"] = waitCount
NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeC2Net, string(models.JobTypeDebug), computeResource)
ctx.Data["NotStopTaskCount"] = NotStopTaskCount

}
ctx.Data["code_path"] = cloudbrain.CodeMountPath
ctx.Data["dataset_path"] = cloudbrain.DataSetMountPath
ctx.Data["model_path"] = cloudbrain.ModelMountPath

}
return nil
}

}
func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) error {
ctx.Data["PageIsCloudBrain"] = true

var displayJobName = cloudbrainService.GetDisplayJobName(ctx.User.Name)
ctx.Data["display_job_name"] = displayJobName

//get valid images
if processType == grampus.ProcessorTypeNPU {
images, err := grampus.GetImages(processType, string(models.JobTypeTrain))
if err != nil {
log.Error("GetImages failed:", err.Error())
} else {
ctx.Data["images"] = images.Infos
}
}

//prepare available specs
if processType == grampus.ProcessorTypeNPU {
prepareGrampusTrainSpecs(ctx, models.NPU)
prepareGrampusSpecs(ctx, models.NPU)
} else if processType == grampus.ProcessorTypeGPU {
prepareGrampusTrainSpecs(ctx, models.GPU)
prepareGrampusSpecs(ctx, models.GPU)
}

//get branches
@@ -201,55 +429,19 @@ func GrampusTrainJobVersionNew(ctx *context.Context) {
}
}

func prepareGrampusTrainSpecs(ctx *context.Context, computeResource string) {
func prepareGrampusSpecs(ctx *context.Context, computeResource string, jobType ...models.JobType) {
tempJobType := models.JobTypeTrain
if len(jobType) > 0 {
tempJobType = jobType[0]
}
noteBookSpecs, _ := resource.FindAvailableSpecs(ctx.User.ID, models.FindSpecsOptions{
JobType: models.JobTypeTrain,
JobType: tempJobType,
ComputeResource: computeResource,
Cluster: models.C2NetCluster,
})
ctx.Data["Specs"] = noteBookSpecs
}

func getFilterSpecBySpecialPool(specs *models.GetGrampusResourceSpecsResult, includeCenters map[string]struct{}, excludeCenters map[string]struct{}) []models.GrampusSpec {
if len(includeCenters) == 0 && len(excludeCenters) == 0 {
return specs.Infos
}
var grampusSpecs []models.GrampusSpec
for _, info := range specs.Infos {
if isInIncludeCenters(info, includeCenters) || (len(excludeCenters) != 0 && isNotAllInExcludeCenters(info, excludeCenters)) {
grampusSpecs = append(grampusSpecs, info)
}

}
return grampusSpecs
}

func isInIncludeCenters(grampusSpec models.GrampusSpec, centers map[string]struct{}) bool {
for _, center := range grampusSpec.Centers {
if _, ok := centers[center.ID]; ok {
return true
}
}
return false
}
func isNotAllInExcludeCenters(grampusSpec models.GrampusSpec, centers map[string]struct{}) bool {
for _, center := range grampusSpec.Centers {
if _, ok := centers[center.ID]; !ok {
return true
}
}
return false
}

func IsUserInOrgPool(userId int64, pool *models.SpecialPool) bool {
org, _ := models.GetOrgByName(pool.Org)
if org != nil {
isOrgMember, _ := models.IsOrganizationMember(org.ID, userId)
return isOrgMember
}
return false
}

func grampusParamCheckCreateTrainJob(form auth.CreateGrampusTrainJobForm) error {
if !strings.HasSuffix(strings.TrimSpace(form.BootFile), ".py") {
log.Error("the boot file(%s) must be a python file", form.BootFile)
@@ -721,30 +913,64 @@ func grampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job")
}

func GetGrampusNotebook(ctx *context.APIContext) {
var (
err error
)

ID := ctx.Params(":id")
job, err := models.GetCloudbrainByID(ID)
if err != nil {
ctx.NotFound("", err)
log.Error("GetCloudbrainByID failed:", err)
return
}

jobAfter, err := cloudbrainTask.SyncGrampusNotebookStatus(job)

aiCenterName := cloudbrainService.GetAiCenterShow(jobAfter.AiCenter, ctx.Context)

if err != nil {
ctx.NotFound(err)
log.Error("Sync cloud brain one status failed:", err)
return
}

ctx.JSON(http.StatusOK, map[string]interface{}{
"ID": ID,
"JobName": jobAfter.JobName,
"JobStatus": jobAfter.Status,
"AiCenter": aiCenterName,
"CreatedTime": jobAfter.CreatedUnix.Format("2006-01-02 15:04:05"),
"CompletedTime": jobAfter.UpdatedUnix.Format("2006-01-02 15:04:05"),
"JobDuration": jobAfter.TrainJobDuration,
})
}

func GrampusStopJob(ctx *context.Context) {
var ID = ctx.Params(":jobid")
var ID = ctx.Params(":id")
var resultCode = "0"
var errorMsg = ""
var status = ""

task := ctx.Cloudbrain
for {
if task.Status == string(models.GrampusStatusStopped) || task.Status == string(models.GrampusStatusFailed) || task.Status == string(models.GrampusStatusSucceeded) {
if task.Status == models.GrampusStatusStopped || task.Status == models.GrampusStatusFailed || task.Status == models.GrampusStatusSucceeded {
log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"])
resultCode = "-1"
errorMsg = "system error"
errorMsg = ctx.Tr("cloudbrain.Already_stopped")
break
}

res, err := grampus.StopJob(task.JobID)
res, err := grampus.StopJob(task.JobID, task.JobType)
if err != nil {
log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"])
resultCode = strconv.Itoa(res.ErrorCode)
errorMsg = res.ErrorMsg
errorMsg = ctx.Tr("cloudbrain.Stopped_failed")
break
}
oldStatus := task.Status
task.Status = string(models.GrampusStatusStopped)
task.Status = getStopJobResponseStatus(res)
if task.EndTime == 0 {
task.EndTime = timeutil.TimeStampNow()
}
@@ -773,6 +999,33 @@ func GrampusStopJob(ctx *context.Context) {
})
}

func getStopJobResponseStatus(res *models.GrampusStopJobResponse) string {
newStatus := models.GrampusStatusStopping
if res.Status != "" {
newStatus = grampus.TransTrainJobStatus(res.Status)
}
return newStatus
}

func GrampusNotebookDel(ctx *context.Context) {
var listType = ctx.Query("listType")
if err := deleteGrampusJob(ctx); err != nil {
log.Error("deleteGrampusJob failed: %v", err, ctx.Data["msgID"])
ctx.ServerError(err.Error(), err)
return
}

var isAdminPage = ctx.Query("isadminpage")
var isHomePage = ctx.Query("ishomepage")
if ctx.IsUserSiteAdmin() && isAdminPage == "true" {
ctx.Redirect(setting.AppSubURL + "/admin" + "/cloudbrains")
} else if isHomePage == "true" {
ctx.Redirect(setting.AppSubURL + "/cloudbrains")
} else {
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=" + listType)
}
}

func GrampusTrainJobDel(ctx *context.Context) {
var listType = ctx.Query("listType")
if err := deleteGrampusJob(ctx); err != nil {
@@ -795,9 +1048,9 @@ func GrampusTrainJobDel(ctx *context.Context) {
func deleteGrampusJob(ctx *context.Context) error {
task := ctx.Cloudbrain

if task.Status != string(models.GrampusStatusStopped) && task.Status != string(models.GrampusStatusSucceeded) && task.Status != string(models.GrampusStatusFailed) {
if task.Status != models.GrampusStatusStopped && task.Status != models.GrampusStatusSucceeded && task.Status != models.GrampusStatusFailed {
log.Error("the job(%s) has not been stopped", task.JobName, ctx.Data["msgID"])
return errors.New("the job has not been stopped")
return errors.New(ctx.Tr("cloudbrain.Not_Stopped"))
}

err := models.DeleteJob(task)
@@ -815,6 +1068,166 @@ func deleteGrampusJob(ctx *context.Context) error {
return nil
}

type NotebookDataset struct {
DatasetUrl string `json:"dataset_url"`
}

func GrampusNotebookShow(ctx *context.Context) {
ctx.Data["PageIsCloudBrain"] = true

var task *models.Cloudbrain
task, err := models.GetCloudbrainByIDWithDeleted(ctx.Params(":id"))
if err != nil {
log.Error("GetCloudbrainByID failed:" + err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}
task.ContainerIp = ""

if task.DeletedAt.IsZero() && cloudbrainTask.IsTaskNotStop(task) { //normal record
result, err := grampus.GetNotebookJob(task.JobID)
if err != nil {
log.Error("GetJob failed:" + err.Error())
ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
return
}

if result != nil {
if len(result.JobInfo.Tasks[0].CenterID) == 1 && len(result.JobInfo.Tasks[0].CenterName) == 1 {
task.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0]
}
oldStatus := task.Status
task.Status = grampus.TransTrainJobStatus(result.JobInfo.Status)
if task.Status != oldStatus || task.Status == models.GrampusStatusRunning {
task.Duration = result.JobInfo.RunSec
if task.Duration < 0 {
task.Duration = 0
}
task.TrainJobDuration = models.ConvertDurationToStr(task.Duration)

if task.StartTime == 0 && result.JobInfo.StartedAt > 0 {
task.StartTime = timeutil.TimeStamp(result.JobInfo.StartedAt)
}
if task.EndTime == 0 && models.IsTrainJobTerminal(task.Status) && task.StartTime > 0 {
task.EndTime = task.StartTime.Add(task.Duration)
}
task.CorrectCreateUnix()
if oldStatus != task.Status {
notification.NotifyChangeCloudbrainStatus(task, oldStatus)
if models.IsTrainJobTerminal(task.Status) && task.ComputeResource == models.NPUResource {
if len(result.JobInfo.Tasks[0].CenterID) == 1 {
urchin.GetBackNpuModel(task.ID, grampus.GetRemoteEndPoint(result.JobInfo.Tasks[0].CenterID[0]), grampus.BucketRemote, grampus.GetNpuModelObjectKey(task.JobName), grampus.GetCenterProxy(setting.Grampus.LocalCenterID))
}
}
}
}
err = models.UpdateJob(task)
if err != nil {
log.Error("UpdateJob failed:" + err.Error())
}
}
}

if len(task.Parameters) > 0 {
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)
ctx.ServerError("system error", err)
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 = ""
}
}
user, err := models.GetUserByID(task.UserID)
if err == nil {
task.User = user
}

prepareSpec4Show(ctx, task)

ctx.Data["task"] = task
ctx.Data["datasetDownload"] = getDatasetDownloadInfo(ctx, task)
ctx.Data["modelDownload"] = getModelDownloadInfo(ctx, task)
ctx.Data["canDownload"] = cloudbrain.CanModifyJob(ctx, task)
ctx.Data["ai_center"] = cloudbrainService.GetAiCenterShow(task.AiCenter, ctx)
ctx.Data["code_path"] = cloudbrain.CodeMountPath
ctx.Data["dataset_path"] = cloudbrain.DataSetMountPath
ctx.Data["model_path"] = cloudbrain.ModelMountPath
ctx.HTML(http.StatusOK, tplGrampusNotebookShow)
}

func getDatasetDownloadInfo(ctx *context.Context, task *models.Cloudbrain) []*models.DatasetDownload {
datasetDownload := make([]*models.DatasetDownload, 0)
if ctx.IsSigned {
if task.Uuid != "" && task.UserID == ctx.User.ID {
if task.IsGPUTask() {
return GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false)
} else {
datasetDownload = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, false)
datasetObsUrlList := make([]NotebookDataset, 0)
_ = json.Unmarshal([]byte(task.DataUrl), &datasetObsUrlList)

for _, datasetInfo := range datasetDownload {

for _, datasetObs := range datasetObsUrlList {
log.Info("datasetObsUrl:" + datasetObs.DatasetUrl + "datasetName:" + datasetInfo.DatasetName)
if strings.Contains(datasetObs.DatasetUrl, datasetInfo.DatasetName) {
datasetInfo.DatasetDownloadLink = datasetObs.DatasetUrl
break
}
}

}

}

}
}

return datasetDownload
}

func getModelDownloadInfo(ctx *context.Context, task *models.Cloudbrain) *models.ModelDownload {
var modelDownload models.ModelDownload
if ctx.IsSigned {
if task.ModelName != "" && task.UserID == ctx.User.ID {
if task.IsNPUTask() {
modelDownload = models.ModelDownload{
Name: task.CkptName,
DownloadLink: "",
IsDelete: false,
}
if !HasModelFile(task) {
modelDownload.IsDelete = true
}
datasetObsUrlList := make([]NotebookDataset, 0)
_ = json.Unmarshal([]byte(task.DataUrl), &datasetObsUrlList)
for _, datasetObs := range datasetObsUrlList {
if strings.Contains(datasetObs.DatasetUrl, task.CkptName) {
modelDownload.DownloadLink = datasetObs.DatasetUrl
break
}
}

}

}

}

return &modelDownload
}

func GrampusTrainJobShow(ctx *context.Context) {
ctx.Data["PageIsCloudBrain"] = true

@@ -1158,3 +1571,172 @@ func HandleTaskWithAiCenter(ctx *context.Context) {
r["updateCounts"] = updateCounts
ctx.JSON(http.StatusOK, response.SuccessWithData(r))
}

func GrampusNotebookDebug(ctx *context.Context) {

result, err := grampus.GetNotebookJob(ctx.Cloudbrain.JobID)

if err != nil {
ctx.RenderWithErr(err.Error(), tplDebugJobIndex, nil)
return
}
if len(result.JobInfo.Tasks) > 0 {

ctx.Redirect(result.JobInfo.Tasks[0].Url + "?token=" + result.JobInfo.Tasks[0].Token)
return
}
ctx.NotFound("Can not find the job.", nil)

}

func GrampusNotebookRestart(ctx *context.Context) {
var id = ctx.Params(":id")
var resultCode = "-1"
var errorMsg = ""
var status = ""
var spec *models.Specification

task := ctx.Cloudbrain
if ctx.Written() {
return
}

for {

if task.Status != models.GrampusStatusStopped && task.Status != models.GrampusStatusSucceeded && task.Status != models.GrampusStatusFailed {
log.Error("the job(%s) is not stopped", task.JobName, ctx.Data["MsgID"])
errorMsg = "the job is not stopped"
break
}

count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeC2Net, string(models.JobTypeDebug), task.ComputeResource)

if err != nil {
log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"])
errorMsg = "system error"
break
} else {
if count >= 1 {
log.Error("the user already has running or waiting task", ctx.Data["MsgID"])
resultCode = "2"
errorMsg = ctx.Tr("repo.cloudbrain.morethanonejob")
break
}
}

oldSpec, err := resource.GetCloudbrainSpec(task.ID)
if err != nil || oldSpec == nil {
log.Error("NotebookManage GetCloudbrainSpec error.%v", err)
errorMsg = "Resource specification not available"
break
}

computeSourceSimple := models.GPU
action := models.ActionCreateGrampusGPUDebugTask
if task.ComputeResource == models.NPUResource {
computeSourceSimple = models.NPU
action = models.ActionCreateGrampusNPUDebugTask
}
spec, err = resource.GetAndCheckSpec(ctx.User.ID, oldSpec.ID, models.FindSpecsOptions{
JobType: models.JobType(task.JobType),
ComputeResource: computeSourceSimple,
Cluster: models.C2NetCluster,
})
if err != nil || spec == nil {
log.Error("NotebookManage GetAndCheckSpec error.task.id = %d", task.ID)
errorMsg = "Resource specification not support any more"
break
}
if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) {
log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID)
errorMsg = ctx.Tr("points.insufficient_points_balance")
break
}
if task.IsGPUTask() {
if _, err := os.Stat(getOldJobPath(task)); err != nil {
log.Error("Can not find job minio path", err)
resultCode = "-1"
errorMsg = ctx.Tr("cloudbrain.result_cleared")
break
}
}

if !HasModelFile(task) { //使用预训练模型训练
errorMsg = ctx.Tr("repo.debug.manage.model_not_exist")
break
}
if hasDatasetDeleted(task) {
errorMsg = ctx.Tr("repo.debug.manage.dataset_not_exist")
break
}

createTime := timeutil.TimeStampNow()

res, err := grampus.RestartNotebookJob(task.JobID)
if err != nil {
log.Error("ManageNotebook2(%s) failed:%v", task.DisplayJobName, err.Error(), ctx.Data["MsgID"])
errorMsg = ctx.Tr("repo.debug_again_fail")
break
}

if res.GrampusResult.ErrorCode != 0 || res.NewId == "" {
log.Error("ManageNotebook2 failed:" + res.GrampusResult.ErrorMsg)
errorMsg = ctx.Tr("repo.debug_again_fail")
break
}

newTask := &models.Cloudbrain{
Status: res.Status,
UserID: task.UserID,
RepoID: task.RepoID,
JobID: res.NewId,
JobName: task.JobName,
DisplayJobName: task.DisplayJobName,
JobType: task.JobType,
Type: task.Type,
Uuid: task.Uuid,
Image: task.Image,
ImageID: task.ImageID,
EngineID: task.EngineID,
CommitID: task.CommitID,
EngineName: task.EngineName,
IsLatestVersion: "1",
BranchName: task.BranchName,
DatasetName: task.DatasetName,
ComputeResource: task.ComputeResource,
Description: task.Description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: spec,
ModelName: task.ModelName,
ModelVersion: task.ModelVersion,
LabelName: task.LabelName,
PreTrainModelUrl: task.PreTrainModelUrl,
CkptName: task.CkptName,
WorkServerNumber: 1,
}

err = models.RestartCloudbrain(task, newTask)
if err != nil {
log.Error("RestartCloudbrain(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
errorMsg = "system error"
break
}

id = strconv.FormatInt(newTask.ID, 10)

status = res.Status
resultCode = "0"

notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, id, newTask.DisplayJobName, action)

break
}

ctx.JSON(200, map[string]string{
"result_code": resultCode,
"error_msg": errorMsg,
"status": status,
"id": id,
})
}

+ 104
- 33
routers/repo/modelarts.go View File

@@ -239,10 +239,37 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm
return
}

req := cloudbrain.GenerateModelArtsNotebookReq{
DisplayJobName: displayJobName,
JobName: jobName,
Description: description,
Uuid: uuid,
ImageId: imageId,
Spec: spec,
BootFile: "",
AutoStopDurationMs: modelarts.AutoStopDurationMs,
}

if form.ModelName != "" { //使用预训练模型训练
_, err := models.QueryModelByPath(form.PreTrainModelUrl)
if err != nil {
log.Error("Can not find model", err)
notebookNewDataPrepare(ctx)
ctx.RenderWithErr(ctx.Tr("repo.modelconvert.manage.model_not_exist"), tplModelArtsNotebookNew, &form)
return
}
req.ModelName = form.ModelName
req.LabelName = form.LabelName
req.CkptName = form.CkptName
req.ModelVersion = form.ModelVersion
req.PreTrainModelUrl = form.PreTrainModelUrl

}

if setting.ModelartsCD.Enabled {
_, err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, uuid, description, imageId, spec, "", modelarts.AutoStopDurationMs)
_, err = modelarts_cd.GenerateNotebook(ctx, req)
} else {
_, err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, uuid, description, imageId, spec, "", modelarts.AutoStopDurationMs)
_, err = modelarts.GenerateNotebook2(ctx, req)
}

if err != nil {
@@ -279,11 +306,17 @@ func NotebookShow(ctx *context.Context) {

}

datasetDownload := make([]models.DatasetDownload, 0)
datasetDownload := make([]*models.DatasetDownload, 0)
var modelDownload models.ModelDownload
if ctx.IsSigned {
if task.Uuid != "" && task.UserID == ctx.User.ID {
datasetDownload = GetCloudBrainDataSetInfo(task.Uuid, task.DatasetName, true)
}
if task.ModelName != "" && task.UserID == ctx.User.ID {
modelDownload = GetModelDownload(task)

}

}
user, err := models.GetUserByID(task.UserID)
if err == nil {
@@ -304,6 +337,7 @@ func NotebookShow(ctx *context.Context) {
}
ctx.Data["duration"] = task.TrainJobDuration
ctx.Data["datasetDownload"] = datasetDownload
ctx.Data["modelDownload"] = modelDownload
ctx.Data["task"] = task
ctx.Data["ID"] = ID
ctx.Data["jobName"] = task.JobName
@@ -311,8 +345,25 @@ func NotebookShow(ctx *context.Context) {
ctx.HTML(200, tplModelArtsNotebookShow)
}

func GetCloudBrainDataSetInfo(uuid string, datasetname string, isNeedDown bool) []models.DatasetDownload {
datasetDownload := make([]models.DatasetDownload, 0)
func GetModelDownload(task *models.Cloudbrain) models.ModelDownload {
index := strings.Index(task.PreTrainModelUrl, "/")
key := task.PreTrainModelUrl[index+1:] + task.CkptName
url, _ := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, key)
modelDownload := models.ModelDownload{
Name: task.CkptName,
DownloadLink: url,
IsDelete: false,
}

if !HasModelFile(task) {
log.Warn("Can not get model by path:" + task.PreTrainModelUrl)
modelDownload.IsDelete = true
}
return modelDownload
}

func GetCloudBrainDataSetInfo(uuid string, datasetname string, isNeedDown bool) []*models.DatasetDownload {
datasetDownload := make([]*models.DatasetDownload, 0)
if len(uuid) == 0 {
return datasetDownload
}
@@ -349,7 +400,7 @@ func GetCloudBrainDataSetInfo(uuid string, datasetname string, isNeedDown bool)
}
}

datasetDownload = append(datasetDownload, models.DatasetDownload{
datasetDownload = append(datasetDownload, &models.DatasetDownload{
DatasetName: name,
DatasetDownloadLink: url,
RepositoryLink: link,
@@ -476,6 +527,16 @@ func NotebookRestart(ctx *context.Context) {
errorMsg = ctx.Tr("points.insufficient_points_balance")
break
}
if !HasModelFile(task) { //使用预训练模型训练
errorMsg = ctx.Tr("repo.debug.manage.model_not_exist")
break
}

if hasDatasetDeleted(task) {
errorMsg = ctx.Tr("repo.debug.manage.dataset_not_exist")
break
}

createTime := timeutil.TimeStampNow()
param := models.NotebookAction{
Action: models.ActionStart,
@@ -511,21 +572,26 @@ func NotebookRestart(ctx *context.Context) {
}

newTask := &models.Cloudbrain{
Status: res.Status,
UserID: task.UserID,
RepoID: task.RepoID,
JobID: task.JobID,
JobName: task.JobName,
DisplayJobName: task.DisplayJobName,
JobType: task.JobType,
Type: task.Type,
Uuid: task.Uuid,
Image: task.Image,
ComputeResource: task.ComputeResource,
Description: task.Description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: spec,
Status: res.Status,
UserID: task.UserID,
RepoID: task.RepoID,
JobID: task.JobID,
JobName: task.JobName,
DisplayJobName: task.DisplayJobName,
JobType: task.JobType,
Type: task.Type,
Uuid: task.Uuid,
Image: task.Image,
ComputeResource: task.ComputeResource,
Description: task.Description,
CreatedUnix: createTime,
UpdatedUnix: createTime,
Spec: spec,
ModelName: task.ModelName,
ModelVersion: task.ModelVersion,
LabelName: task.LabelName,
PreTrainModelUrl: task.PreTrainModelUrl,
CkptName: task.CkptName,
}

err = models.RestartCloudbrain(task, newTask)
@@ -568,17 +634,7 @@ func NotebookStop(ctx *context.Context) {
break
}

param := models.NotebookAction{
Action: models.ActionStop,
}

var err error
var res *models.NotebookActionResult
if task.Type == models.TypeCloudBrainTwo {
res, err = modelarts.ManageNotebook2(task.JobID, param)
} else if task.Type == models.TypeCDCenter {
res, err = modelarts_cd.ManageNotebook(task.JobID, param)
}
err, res := StopModelArtsNotebook(task)

if err != nil {
log.Error("ManageNotebook2(%s) failed:%v", task.JobName, err.Error(), ctx.Data["MsgID"])
@@ -619,6 +675,21 @@ func NotebookStop(ctx *context.Context) {
})
}

func StopModelArtsNotebook(task *models.Cloudbrain) (error, *models.NotebookActionResult) {
param := models.NotebookAction{
Action: models.ActionStop,
}

var err error
var res *models.NotebookActionResult
if task.Type == models.TypeCloudBrainTwo {
res, err = modelarts.ManageNotebook2(task.JobID, param)
} else if task.Type == models.TypeCDCenter {
res, err = modelarts_cd.ManageNotebook(task.JobID, param)
}
return err, res
}

func NotebookDel(ctx *context.Context) {
var listType = ctx.Query("debugListType")
task := ctx.Cloudbrain
@@ -1791,7 +1862,7 @@ func TrainJobShow(ctx *context.Context) {
return
}
ctx.Data["canNewJob"] = canNewJob
datasetList := make([][]models.DatasetDownload, 0)
datasetList := make([][]*models.DatasetDownload, 0)
//将运行参数转化为epoch_size = 3, device_target = Ascend的格式
for i, task := range VersionListTasks {



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

@@ -75,7 +75,7 @@ func RepoStatisticDaily(date string) {
if repo.NumIssues != 0 {
issueFixedRate = float32(repo.NumClosedIssues) / float32(repo.NumIssues)
} else {
issueFixedRate = 1.0
issueFixedRate = float32(setting.RadarMap.ProjectHealth0IssueCloseRatio)
}

var numVersions int64
@@ -124,7 +124,7 @@ func RepoStatisticDaily(date string) {
NumDevMonths: numDevMonths,
RepoSize: repo.Size,
DatasetSize: datasetSize,
NumModels: 0,
NumModels: repo.ModelCnt,
NumWikiViews: numWikiViews,
NumCommits: numCommits,
NumIssues: int64(repo.NumIssues),
@@ -135,6 +135,9 @@ func RepoStatisticDaily(date string) {
NumCommitsGrowth: numCommitsGrowth,
NumCommitLinesGrowth: numCommitLinesGrowth,
NumContributorsGrowth: numContributorsGrowth,
NumCloudbrain: repo.AiTaskCnt,
NumDatasetFile: repo.DatasetCnt,
NumModelConvert: models.QueryModelConvertCountByRepoID(repo.ID),
}

dayBeforeDate := t.AddDate(0, 0, -1).Format("2006-01-02")
@@ -155,6 +158,10 @@ func RepoStatisticDaily(date string) {
repoStat.NumIssuesAdded = repoStat.NumIssues - repoStatisticBefore.NumIssues
repoStat.NumPullsAdded = repoStat.NumPulls - repoStatisticBefore.NumPulls
repoStat.NumContributorAdded = repoStat.NumContributor - repoStatisticBefore.NumContributor
repoStat.NumModelsAdded = repoStat.NumModels - repoStatisticBefore.NumModels
repoStat.NumCloudbrainAdded = repoStat.NumCloudbrain - repoStatisticBefore.NumCloudbrain
repoStat.NumModelConvertAdded = repoStat.NumModelConvert - repoStatisticBefore.NumModelConvert
repoStat.NumDatasetFileAdded = repoStat.NumDatasetFile - repoStatisticBefore.NumDatasetFile
}
}
day4MonthsAgo := t.AddDate(0, -4, 0)


+ 14
- 11
routers/routes/routes.go View File

@@ -1231,10 +1231,23 @@ func RegisterRoutes(m *macaron.Macaron) {
})
}, context.RepoRef())
m.Group("/grampus", func() {
m.Group("/notebook", func() {
m.Group("/:id", func() {
m.Get("", reqRepoCloudBrainReader, repo.GrampusNotebookShow)
m.Get("/debug", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.GrampusNotebookDebug)
m.Post("/restart", reqWechatBind, cloudbrain.AdminOrJobCreaterRight, repo.GrampusNotebookRestart)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.GrampusStopJob)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.GrampusNotebookDel)
})

m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, context.PointAccount(), repo.GrampusNotebookNew)
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateGrampusNotebookForm{}), repo.GrampusNotebookCreate)
})

m.Group("/train-job", func() {
m.Group("/:jobid", func() {
m.Get("", reqRepoCloudBrainReader, repo.GrampusTrainJobShow)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.GrampusStopJob)
m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.GrampusStopJob)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.GrampusTrainJobDel)
m.Get("/model_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.ModelDownload)
m.Get("/create_version", reqWechatBind, cloudbrain.AdminOrJobCreaterRightForTrain, repo.GrampusTrainJobVersionNew)
@@ -1304,16 +1317,6 @@ func RegisterRoutes(m *macaron.Macaron) {

m.Group("/modelarts", func() {
m.Group("/notebook", func() {
/* v1.0
m.Group("/:jobid", func() {
m.Get("", reqRepoCloudBrainReader, repo.NotebookShow)
m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.NotebookDebug)
m.Post("/:action", reqRepoCloudBrainWriter, repo.NotebookManage)
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.NotebookDel)
})
m.Get("/create", reqRepoCloudBrainWriter, repo.NotebookNew)
m.Post("/create", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsNotebookForm{}), repo.NotebookCreate)
*/
m.Group("/:id", func() {
m.Get("", reqRepoCloudBrainReader, repo.NotebookShow)
m.Get("/debug", cloudbrain.AdminOrJobCreaterRight, repo.NotebookDebug2)


+ 10
- 0
services/cloudbrain/cloudbrainTask/count.go View File

@@ -62,6 +62,16 @@ var StatusInfoDict = map[string]StatusInfo{string(models.JobTypeDebug) + "-" + s
JobType: []models.JobType{models.JobTypeTrain},
NotFinalStatuses: GrampusNotFinalStatuses,
ComputeResource: models.NPUResource,
}, string(models.JobTypeDebug) + "-" + strconv.Itoa(models.TypeC2Net) + "-" + models.GPUResource: {
CloudBrainTypes: []int{models.TypeC2Net},
JobType: []models.JobType{models.JobTypeDebug},
NotFinalStatuses: GrampusNotFinalStatuses,
ComputeResource: models.GPUResource,
}, string(models.JobTypeDebug) + "-" + strconv.Itoa(models.TypeC2Net) + "-" + models.NPUResource: {
CloudBrainTypes: []int{models.TypeC2Net},
JobType: []models.JobType{models.JobTypeDebug},
NotFinalStatuses: GrampusNotFinalStatuses,
ComputeResource: models.NPUResource,
}}

func GetNotFinalStatusTaskCount(uid int64, cloudbrainType int, jobType string, computeResource ...string) (int, error) {


+ 14
- 3
services/cloudbrain/cloudbrainTask/notebook.go View File

@@ -82,7 +82,7 @@ func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOp
})
}
if err != nil {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.failed_to_create_notebook_repo",setting.FileNoteBook.ProjectName)))
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.failed_to_create_notebook_repo", setting.FileNoteBook.ProjectName)))
return
}
if option.Type <= 1 {
@@ -291,10 +291,21 @@ func modelartsFileNoteBookCreate(ctx *context.Context, option api.CreateFileNote
}

var jobId string
req := cloudbrain.GenerateModelArtsNotebookReq{
DisplayJobName: displayJobName,
JobName: jobName,
Description: getDescription(option),
ImageId: setting.FileNoteBook.ImageIdNPU,
Spec: spec,
BootFile: "",
AutoStopDurationMs: modelarts.AutoStopDurationMs / 4,
}

if setting.ModelartsCD.Enabled {
jobId, err = modelarts_cd.GenerateNotebook(ctx, displayJobName, jobName, "", getDescription(option), setting.FileNoteBook.ImageIdNPUCD, spec, option.File,modelarts.AutoStopDurationMs/4)
req.ImageId = setting.FileNoteBook.ImageIdNPUCD
jobId, err = modelarts_cd.GenerateNotebook(ctx, req)
} else {
jobId, err = modelarts.GenerateNotebook2(ctx, displayJobName, jobName, "", getDescription(option), setting.FileNoteBook.ImageIdNPU, spec, option.File,modelarts.AutoStopDurationMs/4)
jobId, err = modelarts.GenerateNotebook2(ctx, req)
}

if err != nil {


+ 78
- 0
services/cloudbrain/cloudbrainTask/sync_status.go View File

@@ -3,9 +3,13 @@ package cloudbrainTask
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/cloudbrain"
"code.gitea.io/gitea/modules/grampus"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/modelarts_cd"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"net/http"
"strconv"
)
@@ -58,6 +62,55 @@ func SyncCloudBrainOneStatus(task *models.Cloudbrain) (*models.Cloudbrain, error

}

func SyncGrampusNotebookStatus(job *models.Cloudbrain) (*models.Cloudbrain, error) {
result, err := grampus.GetNotebookJob(job.JobID)
if err != nil {

log.Error("GetJob(%s) failed:%v", job.JobName, err)

return job, err
}

if job.StartTime == 0 && result.JobInfo.StartedAt > 0 {
job.StartTime = timeutil.TimeStamp(result.JobInfo.StartedAt)
}
oldStatus := job.Status
job.Status = grampus.TransTrainJobStatus(result.JobInfo.Status)
job.Duration = result.JobInfo.RunSec
job.TrainJobDuration = models.ConvertDurationToStr(job.Duration)

if job.EndTime == 0 && models.IsTrainJobTerminal(job.Status) && job.StartTime > 0 {
job.EndTime = job.StartTime.Add(job.Duration)
}
job.CorrectCreateUnix()

if len(job.AiCenter) == 0 {
if len(result.JobInfo.Tasks) > 0 {
if len(result.JobInfo.Tasks[0].CenterID) > 0 && len(result.JobInfo.Tasks[0].CenterName) > 0 {
job.AiCenter = result.JobInfo.Tasks[0].CenterID[0] + "+" + result.JobInfo.Tasks[0].CenterName[0]
}
}
}

if job.Status != models.GrampusStatusWaiting {
if oldStatus != job.Status {
notification.NotifyChangeCloudbrainStatus(job, oldStatus)
}
if job.ComputeResource == models.NPUResource {
job.TrainUrl = result.JobInfo.Tasks[0].CodeUrl
job.DataUrl = result.JobInfo.Tasks[0].DataUrl
}
err = models.UpdateJob(job)
if err != nil {
log.Error("UpdateJob failed:", err)
return nil, err
}
}

return job, nil

}

func isNoteBookReady(task *models.Cloudbrain) bool {
if task.JobType != string(models.JobTypeDebug) {
return true
@@ -90,3 +143,28 @@ func isNoteBookReady(task *models.Cloudbrain) bool {
return false

}

func StopDebugJob(task *models.Cloudbrain) error {
param := models.NotebookAction{
Action: models.ActionStop,
}
var err error = nil

if task.JobType == string(models.JobTypeDebug) {
if task.Type == models.TypeCloudBrainOne {
return cloudbrain.StopJob(task.JobID)
} else if task.Type == models.TypeCloudBrainTwo {
_, err = modelarts.ManageNotebook2(task.JobID, param)

} else if task.Type == models.TypeCDCenter {
_, err = modelarts_cd.ManageNotebook(task.JobID, param)

} else if task.Type == models.TypeC2Net {
_, err = grampus.StopJob(task.JobID, task.JobType)

}

}
return err

}

+ 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}
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}

type ClientsManager struct {
Clients *orderedmap.OrderedMap


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

@@ -98,7 +98,7 @@
<div class="two wide column nowrap" style="width:10% !important;">
{{if eq .JobType "DEBUG"}}
<a class="title"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{$JobID}}"
title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px">
<span class="fitted"
style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
@@ -135,13 +135,13 @@
</div>
<!-- 集群 -->
<div class="one wide column text center nowrap" style="width:6% !important;">
<span style="font-size: 12px;" class="cluster_{{.DisplayJobName}}_{{$JobID}}">{{if .Cluster}}{{.Cluster}}{{else}}--{{end}}</span>
<span style="font-size: 12px;" class="cluster_{{.DisplayJobName}}_{{$JobID}}">{{if .Cluster}}{{.Cluster}}{{else}}--{{end}}</span>
</div>
<!-- 任务状态 -->
<div class="two wide column text center nowrap"
style="width: 6% !important;">
<span class="job-status" id="{{$JobID}}"
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK" "MODELSAFETY"}}/cloudbrain{{end}}'
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{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-jobid="{{$JobID}}" data-version="{{.VersionName}}">
<span><i id="{{$JobID}}-icon" style="vertical-align: middle;"
class="{{.Status}}"></i><span id="{{$JobID}}-text"
@@ -170,7 +170,7 @@
</div>
<!-- 智算中心 -->
<div class="one wide column text center nowrap" style="width:8% !important;">
<span style="font-size: 12px;" class="aicenter_{{.DisplayJobName}}_{{$JobID}}" title="{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}">{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}</span>
<span style="font-size: 12px;" id="cluster-{{$JobID}}" class="aicenter_{{.DisplayJobName}}_{{$JobID}}" title="{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}">{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}</span>
</div>
<!-- XPU类型 -->
<div class="one wide column text center nowrap" style="width:8% !important;">
@@ -234,7 +234,7 @@
<a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button'
data-jobid="{{$JobID}}"
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'>
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{$JobID}}/'>
{{$.i18n.Tr "repo.debug"}}
</a>
{{else}}
@@ -242,7 +242,7 @@
<a id="ai-debug-{{$JobID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button'
data-jobid="{{$JobID}}"
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'>
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{$JobID}}/'>
{{$.i18n.Tr "repo.debug_again"}}
</a>
{{end}}
@@ -268,8 +268,8 @@
{{$.CsrfTokenHtml}}
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}"
class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING"}}disabled {{else}} blue {{end}}button'
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop'
data-jobid="{{$JobID}}">
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}{{end}}/{{$JobID}}/stop'
data-jobid="{{$JobID}}" data-bootfile="{{.BootFile}}">
{{$.i18n.Tr "repo.stop"}}
</a>
</form>
@@ -304,17 +304,17 @@
</a>
</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")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{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'
method="post">
{{$.CsrfTokenHtml}}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}"
data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?isadminpage=true"
data-version="" class="ui basic ai_delete blue button"
style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
</a>
</form>
<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")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{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'
method="post">
{{$.CsrfTokenHtml}}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}"
data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?ishomepage=true"
data-version="{{.VersionName}}" class="ui basic ai_delete blue button"
style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
</a>
</form>
{{end}}
</div>
</div>


+ 2
- 2
templates/custom/select_model.tmpl View File

@@ -1,6 +1,6 @@
<input type="hidden" id="ai_model_version" name="model_version" value="{{$.model_version}}">
<div class="inline min_title fields" style="{{if not .job_name}}width: 96.8%{{else}}width: 94.8%{{end}};">
<label class="{{if not .job_name}}label-fix-width{{end}}" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>&nbsp;
<div class="inline min_title required 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" id="select_model">
<input type="hidden" name="model_name" required value="{{$.model_name}}">


+ 1
- 197
templates/repo/cloudbrain/benchmark/show.tmpl View File

@@ -1,200 +1,4 @@
{{template "base/head" .}}
<style>
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}

.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}

.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}

.acc-margin-bottom {
margin-bottom: 5px;
}

.title_text {
font-size: 12px;
}

.ac-display-inblock {
display: inline-block;
}

.cti-mgRight-sm {
margin-right: 8px;
}

.ac-text-normal {
font-size: 14px;
color: #575d6c;
}

.uc-accordionTitle-black {
color: #333;
}

.accordion-border {
border: 1px solid #cce2ff;
}

.padding0 {
padding: 0 !important;
}

.content-pad {
padding: 15px 35px;
}

.content-margin {
margin: 10px 5px;
}

.tab_2_content {
min-height: 425px;
margin-left: 10px;
}

.ac-grid {
display: block;
*zoom: 1;
}

.ac-grid-col {
float: left;
width: 100%;
}

.ac-grid-col2 .ac-grid-col {
width: 50%;
}

.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}

.ti-form>tbody {
font-size: 12px;
}

.ti-form>tbody,
.ti-form>tbody>tr {
vertical-align: inherit;
}

.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}

.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
}

.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}

td,
th {
padding: 0;
}

.ac-grid-col .text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.redo-color {
color: #3291F8;
}

.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}

.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}

.text-width80 {
width: 100px;
line-height: 30px;
}

.border-according {
border: 1px solid #dfe1e6;
}

.disabled {
cursor: default;
pointer-events: none;
color: rgba(0, 0, 0, .6) !important;
opacity: .45 !important;
}

.pad20 {

border: 0px !important;
}

.model_file_bread {
margin-bottom: -0.5rem !important;
padding-left: 1rem;
padding-top: 0.5rem;
}
</style>
<div id="mask">
<div id="loadingPage">
<div class="rect1"></div>
@@ -520,7 +324,7 @@
</div>
</div>
</div>
<div style="clear: both;"></div>
</div>
</div>
<div class="ui tab" data-tab="second{{$k}}">


+ 6
- 10
templates/repo/cloudbrain/inference/new.tmpl View File

@@ -1,9 +1,5 @@
{{template "base/head" .}}
<style>
.unite{
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
}

.title{
font-size: 16px !important;
@@ -63,7 +59,7 @@
<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="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<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">
@@ -100,7 +96,7 @@
<span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span>
</div>

<div class="unite min_title inline field">
<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>
@@ -111,10 +107,10 @@
<div class="ui divider"></div>

<!-- 模型相关配置 -->
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<div class="required unite inline min_title fields" style="width: 96.8%;">
<div class="required eight wide field">
<label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>
<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>


+ 0
- 195
templates/repo/cloudbrain/inference/show.tmpl View File

@@ -1,200 +1,5 @@
{{template "base/head" .}}
<style>
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}

.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}

.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}

.acc-margin-bottom {
margin-bottom: 5px;
}

.title_text {
font-size: 12px;
}

.ac-display-inblock {
display: inline-block;
}

.cti-mgRight-sm {
margin-right: 8px;
}

.ac-text-normal {
font-size: 14px;
color: #575d6c;
}

.uc-accordionTitle-black {
color: #333;
}

.accordion-border {
border: 1px solid #cce2ff;
}

.padding0 {
padding: 0 !important;
}

.content-pad {
padding: 15px 35px;
}

.content-margin {
margin: 10px 5px;
}

.tab_2_content {
min-height: 360px;
margin-left: 10px;
}

.ac-grid {
display: block;
*zoom: 1;
}

.ac-grid-col {
float: left;
width: 100%;
}

.ac-grid-col2 .ac-grid-col {
width: 50%;
}

.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}

.ti-form>tbody {
font-size: 12px;
}

.ti-form>tbody,
.ti-form>tbody>tr {
vertical-align: inherit;
}

.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}

.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
}

.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}

td,
th {
padding: 0;
}

.info_text {
padding-bottom: 20px;
padding-right: 20px;
font-size: 12px;
}

.ac-grid-col .text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.redo-color {
color: #3291F8;
}

.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}

.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}

.text-width80 {
width: 100px;
line-height: 30px;
}

.border-according {
border: 1px solid #dfe1e6;
}

.disabled {
cursor: default;
pointer-events: none;
color: rgba(0, 0, 0, .6) !important;
opacity: .45 !important;
}

.pad20 {

border: 0px !important;
}

.model_file_bread {
margin-bottom: -0.5rem !important;
padding-left: 1rem;


+ 141
- 191
templates/repo/cloudbrain/new.tmpl View File

@@ -13,72 +13,101 @@
.inline.required.field.cloudbrain_brainscore {
display: none;
}

.width80{
width: 80.7% !important;
}

</style>

{{template "custom/global_mask" .}}

<div class="repository">
{{template "repo/header" .}}
<div class="repository new repo ui middle very relaxed page grid">
<div class="column">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" id="messageInfo" style="display:none;">
<p></p>
</div>
{{template "custom/alert_cb" .}}
<div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}" data-flag-model="true"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" id="messageInfo" style="display:none;">
<p></p>
</div>
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new_debug"}}
</h4>
{{template "custom/alert_cb" .}}
<div class="ui attached segment">
<form id="form_id" class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name='isBranches' value="{{.Branches}}">
<h3 class="ui top attached header">
{{.i18n.Tr "repo.cloudbrain.new"}}
</h3>
<div class="ui attached segment">
<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<a class="active item" href="{{.RepoLink}}/cloudbrain/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/notebook/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="inline field">
<label></label>
{{template "custom/task_wait_count" .}}
<h4 class="train-job-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.resource_cluster"}}</label>
<div class="ui blue mini menu compact selectcloudbrain">
<a class="active item" href="{{.RepoLink}}/cloudbrain/create">
<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" href="{{.RepoLink}}/grampus/notebook/create?type=0">
<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 class="inline required field">
<label>{{.i18n.Tr "cloudbrain.task_name"}}</label>
<input name="display_job_name" id="cloudbrain_job_name"
placeholder="{{.i18n.Tr "cloudbrain.task_name"}}" value="{{.display_job_name}}" tabindex="3"
autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')">
</div>
<div class="inline required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<a class="active item" href="{{.RepoLink}}/cloudbrain/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/notebook/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 class="inline required field">
<label>{{.i18n.Tr "cloudbrain.task_type"}}</label>
<select id="cloudbrain_job_type" class="ui search dropdown"
placeholder="{{.i18n.Tr "cloudbrain.task_type"}}" style='width:385px' name="job_type">
<option name="job_type" value="DEBUG">DEBUG</option>
</select>
</div>
<div class="min_title inline field">
<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_debug_gpu_tooltips" "/code" "/dataset" "/pretrainmodel" "/model" | Safe}}</span>
</div>
</div>
<div class="inline min_title required field" style="margin-bottom: 0rem !important;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_name"}}</label>
<input name="display_job_name" id="cloudbrain_job_name" style="width: 60%;"
placeholder="{{.i18n.Tr "cloudbrain.task_name"}}" value="{{.display_job_name}}" tabindex="3"
autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')">
</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span>
<div class="inline min_title 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>

<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_type"}}</label>
<select id="cloudbrain_job_type" class="ui search dropdown width80"
placeholder="{{.i18n.Tr "cloudbrain.task_type"}}" name="job_type">
<option name="job_type" value="DEBUG">DEBUG</option>
</select>
</div>
<div class="inline required field cloudbrain_benchmark">
<label style="vertical-align: top; margin-top:9px">数据集类别</label>
<select class="ui search dropdown" multiple="multiple" id="cloudbrain_benchmark_category"
@@ -94,27 +123,27 @@
</div>
</div>
<input id="store_category" type="hidden" name="get_benchmark_category">
<div class="inline required field">
<label>{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2 {{if not .Branches}}error{{end}}" 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 class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" 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 class="inline required field">
<label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label>
<select id="cloudbrain_gpu_type" class="ui search dropdown gpu-type" placeholder="选择GPU类型"
@@ -124,14 +153,14 @@
{{end}}
</select>
</div>-->
{{template "custom/select_model" .}}
<div id="images-new-cb">

<div id="images-new-cb">

</div>
<div id="select-multi-dataset">

</div>
</div>
<div id="select-multi-dataset">

</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span>
<!--<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="cloudbrain_resource_spec" class="ui search dropdown"
@@ -144,42 +173,27 @@
{{end}}
</select>
</div>-->

<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="__specs__" class="ui search dropdown"
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}"
{{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}
name="spec_id">
</select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
{{end}}
</div>

<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.dataset_storage_path"}}</label>
<input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3"
disabled autofocus required maxlength="255" readonly="readonly">
</div>
<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.model_storage_path"}}</label>
<input name="model_path" id="cloudbrain_model_path" value="{{.model_path}}" tabindex="3"
disabled autofocus required maxlength="255" readonly="readonly">
</div>
<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.code_storage_path"}}</label>
<input name="code_path" id="cloudbrain_code_path" value="{{.code_path}}" tabindex="3" disabled
autofocus required maxlength="255" readonly="readonly">
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="__specs__" class="ui search dropdown width48"
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}"
{{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}
name="spec_id">
</select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
{{end}}
</div>
<div class="inline required field cloudbrain_benchmark">
<label>{{.i18n.Tr "cloudbrain.benchmark_path"}}</label>
<input name="benchmark_path" id="cloudbrain_benchmark_path" value="{{.benchmark_path}}"
@@ -199,22 +213,25 @@
<label>{{.i18n.Tr "cloudbrain.start_command"}}</label>
<textarea name="command" rows="10" readonly="readonly">{{.command}}</textarea>
</div>

<div class="inline field">
<label></label>
<button class="ui green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button cancel"
href="{{.RepoLink}}/debugjob?debugListType=all">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
<div class="inline 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 cancel"
href="{{.RepoLink}}/debugjob?debugListType=all">{{.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 src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
let form = document.getElementById('form_id');
$('#messageInfo').css('display', 'none')
@@ -223,63 +240,6 @@
context.value = ''
$(".icon.icons").css("visibility", "hidden")
}
var isValidate = false;
function validate(){
$('.ui.form').form({
on: 'blur',
fields: {
display_job_name:{
identifier : 'display_job_name',
rules: [
{
type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]',
}
]
},
spec_id: {
identifier: 'spec_id',
rules: [{ type: 'empty' }]
}
},
onSuccess: function(){
isValidate = true;
},
onFailure: function(e){
isValidate = false;
return false;
}
})
}
validate();
let createFlag = false
form.onsubmit = function (e) {
if (!isValidate) return false;
if(createFlag) return false
let value_task = $("input[name='display_job_name']").val()
let value_image = $("input[name='image']").val()
let value_data = $("input[name='attachment']").val()
let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/
let flag = re.test(value_task)
if (!flag) {
$('#messageInfo').css('display', 'block')
let str = '只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。'
$('#messageInfo p').text(str)
return false
}
let min_value_task = value_task.toLowerCase()
$("input[name='display_job_name']").attr("value", min_value_task)
createFlag = true
document.getElementById("mask").style.display = "block"
}

// 页面加载完毕后遮罩层隐藏
document.onreadystatechange = function () {
if (document.readyState === "complete") {
document.getElementById("mask").style.display = "none"
}

}

$('#cloudbrain_benchmark_category')
.dropdown({
placeholder: "选择数据集类别",
@@ -314,16 +274,6 @@
}
})
})

$('.ui.green.button').click(function () {
if (!$('input[name="isBranches"]').val()) {
return false
}
selected_value = $("#cloudbrain_benchmark_category").val()
$('#store_category').attr("value", selected_value)
validate();
})

;(function() {
var SPECS = {{ .debug_specs }};
var showPoint = {{ .CloudBrainPaySwitch }};


+ 71
- 255
templates/repo/cloudbrain/show.tmpl View File

@@ -1,208 +1,4 @@
{{template "base/head" .}}
<style>
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}

.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}

.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}

.acc-margin-bottom {
margin-bottom: 5px;
}

.title_text {
font-size: 12px;
}

.ac-display-inblock {
display: inline-block;
}

.cti-mgRight-sm {
margin-right: 8px;
}

.ac-text-normal {
font-size: 14px;
color: #575d6c;
}

.uc-accordionTitle-black {
color: #333;
}

.accordion-border {
border: 1px solid #cce2ff;
}

.padding0 {
padding: 0 !important;
}

.content-pad {
padding: 15px 35px;
}

.content-margin {
margin: 10px 5px;
}

.tab_2_content {
min-height: 420px;
margin-left: 10px;
}

.ac-grid {
display: block;
*zoom: 1;
}

.ac-grid-col {
float: left;
width: 100%;
}

.ac-grid-col2 .ac-grid-col {
width: 50%;
}

.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}

.ti-form>tbody {
font-size: 12px;
}

.ti-form>tbody,
.ti-form>tbody>tr {
vertical-align: inherit;
}

.info_text {
padding-bottom: 20px;
padding-right: 20px;
font-size: 12px;
}

.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}

.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
}

.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}

td,
th {
padding: 0;
}

.ac-grid-col .text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.redo-color {
color: #3291F8;
}

.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}

.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}

.text-width80 {
width: 100px;
line-height: 30px;
}

.border-according {
border: 1px solid #dfe1e6;
}

.disabled {
cursor: default;
pointer-events: none;
color: rgba(0, 0, 0, .6) !important;
opacity: .45 !important;
}

.pad20 {

border: 0px !important;
}

.model_file_bread {
margin-bottom: -0.5rem !important;
padding-left: 1rem;
padding-top: 0.5rem;
}
</style>


<div id="mask">
<div id="loadingPage">
<div class="rect1"></div>
@@ -310,6 +106,17 @@
</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" id="{{.VersionName}}-code">
{{.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.computing_resources"}}
</td>
<td class="ti-text-form-content">
@@ -321,52 +128,71 @@
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.task_type"}}
{{$.i18n.Tr "repo.modelarts.createtime"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-computeresource">
{{.JobType}}
id="{{.VersionName}}-createtime">
{{TimeSinceUnix1 .CreatedUnix}}
</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"}}
{{$.i18n.Tr "repo.cloudbrain.time.starttime"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-code">
{{.BranchName}}
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span>
<div class="text-span text-span-w"
id="{{.VersionName}}-startTime">
{{if not (eq .StartTime 0)}}
{{TimeSinceUnix1 .StartTime}}
{{else}}
--
{{end}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.gpu_type"}}
{{$.i18n.Tr "repo.cloudbrain.time.endtime"}}
</td>

<td class="ti-text-form-content resorce_type">
<div class="text-span text-span-w"></div>
<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-EndTime">
{{if not (eq .EndTime 0)}}
{{TimeSinceUnix1 .EndTime}}
{{else}}
--
{{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.createtime"}}
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-createtime">
{{TimeSinceUnix1 .CreatedUnix}}
id="{{.VersionName}}-duration">
{{$.duration}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.description"}}
</td>




<td class="ti-text-form-content">
<div class="text-span-new" id="model_description">
{{.Description}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
@@ -392,8 +218,6 @@
</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"}}
@@ -405,24 +229,29 @@
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.dataset_storage_path"}}
{{$.i18n.Tr "repo.modelarts.model_name"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="dataset_storage_path">
{{$.dataset_path}}
</div>
<div class="text-span text-span-w">{{if .ModelName}}{{.ModelName}}{{else}}--{{end}}</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.model_storage_path"}}
{{$.i18n.Tr "repo.modelconvert.modelversion"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="model_storage_path">
{{$.model_path}}
</div>
<div class="text-span text-span-w">{{if .ModelVersion}}{{.ModelVersion}}{{else}}--{{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.infer_job_model_file"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .CkptName}}{{.CkptName}}{{else}}--{{end}}</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
@@ -438,56 +267,43 @@
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.cloudbrain.time.starttime"}}
{{$.i18n.Tr "cloudbrain.dataset_storage_path"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-startTime">
{{if not (eq .StartTime 0)}}
{{TimeSinceUnix1 .StartTime}}
{{else}}
--
{{end}}
<div class="text-span text-span-w" id="dataset_storage_path">
{{$.dataset_path}}
</div>
</td>
</tr>

<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.cloudbrain.time.endtime"}}
{{$.i18n.Tr "cloudbrain.model_storage_path"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-EndTime">
{{if not (eq .EndTime 0)}}
{{TimeSinceUnix1 .EndTime}}
{{else}}
--
{{end}}
<div class="text-span text-span-w" id="code_storage_path">
/pretrainmodel
</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"}}
{{$.i18n.Tr "cloudbrain.output_storage_path"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-duration">
{{$.duration}}
<div class="text-span text-span-w" id="model_storage_path">
{{$.model_path}}
</div>
</td>
</tr>

</tbody>
</table>
</div>
</div>
</div>
<div style="clear:both">
{{if $.datasetDownload}}
<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>
@@ -508,6 +324,7 @@

</tbody>
</table>
{{end}}
</div>
</div>
</div>
@@ -609,6 +426,5 @@
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}},
});
$('td.ti-text-form-content.spec div').text(specStr);
SPEC && $('td.ti-text-form-content.resorce_type div').text(getListValueWithKey(ACC_CARD_TYPE, SPEC.AccCardType));
})();
</script>

+ 1
- 15
templates/repo/cloudbrain/trainjob/new.tmpl View File

@@ -1,11 +1,5 @@
{{template "base/head" .}}
<style>
.train-job-title {
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 16px !important;
padding-left: 3rem !important;
}
.min_title{
font-size: 14px !important;
margin-bottom: 2rem !important;
@@ -57,14 +51,6 @@
text-align: center;
color: #C2C7CC;
}
.label-fix-width{
width: 140px !important;
text-align: right;
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 14px !important;
}

</style>
{{template "custom/global_mask" .}}
<div class="repository">
@@ -85,7 +71,7 @@
<input type="hidden" name="action" value="update">
<input type="hidden" id="ai_image_name" value="{{.image}}">
<h4 class="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required unite min_title inline field">
<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="active item" href="{{.RepoLink}}/cloudbrain/train-job/create">


+ 2
- 195
templates/repo/cloudbrain/trainjob/show.tmpl View File

@@ -1,201 +1,6 @@
{{template "base/head" .}}
<link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css">
<style>
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}

.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}

.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}

.acc-margin-bottom {
margin-bottom: 5px;
}

.title_text {
font-size: 12px;
}

.ac-display-inblock {
display: inline-block;
}

.cti-mgRight-sm {
margin-right: 8px;
}

.ac-text-normal {
font-size: 14px;
color: #575d6c;
}

.uc-accordionTitle-black {
color: #333;
}

.accordion-border {
border: 1px solid #cce2ff;
}

.padding0 {
padding: 0 !important;
}

.content-pad {
padding: 15px 35px;
}

.content-margin {
margin: 10px 5px;
}

.tab_2_content {
min-height: 360px;
margin-left: 10px;
}

.ac-grid {
display: block;
*zoom: 1;
}

.ac-grid-col {
float: left;
width: 100%;
}

.ac-grid-col2 .ac-grid-col {
width: 50%;
}

.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}

.ti-form>tbody {
font-size: 12px;
}

.ti-form>tbody,
.ti-form>tbody>tr {
vertical-align: inherit;
}

.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}

.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
}

.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}

td,
th {
padding: 0;
}

.info_text {
padding-bottom: 20px;
padding-right: 20px;
font-size: 12px;
}

.ac-grid-col .text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.redo-color {
color: #3291F8;
}

.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}

.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}

.text-width80 {
width: 100px;
line-height: 30px;
}

.border-according {
border: 1px solid #dfe1e6;
}

.disabled {
cursor: default;
pointer-events: none;
color: rgba(0, 0, 0, .6) !important;
opacity: .45 !important;
}

.pad20 {

border: 0px !important;
}

.model_file_bread {
margin-bottom: -0.5rem !important;
padding-left: 1rem;
@@ -472,6 +277,7 @@
</div>
</div>
<div style="clear:both">
{{if $.datasetDownload}}
<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>
@@ -492,6 +298,7 @@

</tbody>
</table>
{{end}}
</div>
</div>



+ 20
- 16
templates/repo/debugjob/index.tmpl View File

@@ -195,7 +195,7 @@
<span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span>
</div>
<div class="two wide column text center">
<span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span>
<span>{{$.i18n.Tr "repo.modelarts.cluster.computing_resources"}}</span>
</div>
<div class="one wide column text center">
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
@@ -211,7 +211,7 @@
<!-- 任务名 -->
<div class="four wide column">
<a class="title"
href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}{{else}}{{$.RepoLink}}/modelarts/notebook/{{.Cloudbrain.ID}}{{end}}'
href='{{$.RepoLink}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{.Cloudbrain.ID}}/'
title="{{.DisplayJobName}}" style="font-size: 14px;">
<span class="fitted text_over"
style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
@@ -220,8 +220,8 @@
<div class="two wide column text center">
<!--任务状态 -->
<span class="job-status" id="{{.Cloudbrain.ID}}"
data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}"
data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}" data-bootfile="{{.BootFile}}">
data-repopath="{{$.RepoRelPath}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}"
data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}">
<span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;"
class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text"
style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span>
@@ -234,9 +234,14 @@
</div>
<div class="two wide column text center">
<!-- 任务计算资源 -->
<span style="font-size: 12px;margin-left: 0.4rem;"
class="">
{{.ComputeResource}}</span>
<span style="font-size: 12px;margin-left: 0.4rem;">
{{if eq .Cloudbrain.Type 2}}
{{$.i18n.Tr "cloudbrain.resource_cluster_c2net_simple"}}
{{else}}
{{$.i18n.Tr "cloudbrain.resource_cluster_openi_simple"}}
{{end}}
{{.ComputeResource}}
</span>
</div>
<div class="one wide column text center">
{{if .User.Name}}
@@ -262,7 +267,7 @@
<a style="margin: 0 1rem;" id="ai-debug-{{.Cloudbrain.ID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button'
data-jobid="{{.Cloudbrain.ID}}"
data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/'>
data-repopath='{{$.RepoLink}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{.Cloudbrain.ID}}/'>
{{$.i18n.Tr "repo.debug"}}
</a>
{{else}}
@@ -270,7 +275,7 @@
<a id="ai-debug-{{.Cloudbrain.ID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button'
data-jobid="{{.Cloudbrain.ID}}"
data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/'
data-repopath='{{$.RepoLink}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{.Cloudbrain.ID}}/'
data-linkpath='{{$.Link}}'>
{{$.i18n.Tr "repo.debug_again"}}
</a>
@@ -295,9 +300,8 @@
{{if .CanDel}}
<a id="ai-stop-{{.Cloudbrain.ID}}"
class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED" "CREATE_FAILED" "DELETED"}}disabled {{else}}blue {{end}}button'
data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop"
data-jobid="{{.Cloudbrain.ID}}"
{{if .BootFile}}data-bootfile="{{.BootFile}}"{{end}}>
data-repopath='{{$.RepoLink}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{.Cloudbrain.ID}}/stop'
data-jobid="{{.Cloudbrain.ID}}">
{{$.i18n.Tr "repo.stop"}}
</a>
@@ -309,7 +313,7 @@
</form>
<!-- 删除 -->
<form id="delForm-{{.Cloudbrain.ID}}"
action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del"
action="{{$.RepoLink}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{.Cloudbrain.ID}}/del"
method="post">
<input type="hidden" name="debugListType" value="{{$.ListType}}">
{{$.CsrfTokenHtml}}
@@ -328,7 +332,7 @@
</div>
{{if not .BootFile}}
<div class="ui compact buttons"
style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}">
style="{{if and (ne .Cloudbrain.Type 2) (eq .ComputeResource "CPU/GPU")}} visibility: visible {{else}} visibility: hidden{{end}}">
<div class="ui dropdown" id="model_more"
style="padding: .58928571em 1.125em .58928571em;">
<div class="text">{{$.i18n.Tr "repo.more"}}</div>
@@ -427,7 +431,7 @@
</div>

<div class="ui modal debug-again-alert">
<div class="ui message" style="background-color: rgba(242, 113, 28, 0.05);border: 1px solid rgba(242, 113, 28, 1);border-radius: 5px;">
<div class="ui message" style="background-color: rgba(242, 113, 28, 0.05);border: 1px solid rgba(242, 113, 28, 1);border-radius: 5px;">
<div style="display: flex;align-items: center;">
<i class="ri-information-line" style="font-size: 35px;color: rgba(242, 113, 28, 1);;"></i>
<div style="text-align: left;margin-left: 1rem;">
@@ -477,4 +481,4 @@
})
})

</script>
</script>

+ 163
- 0
templates/repo/grampus/notebook/gpu/new.tmpl View File

@@ -0,0 +1,163 @@
{{template "base/head" .}}
{{template "custom/global_mask" .}}

<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}" data-flag-model="true"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" id="messageInfo" style="display:none;">
<p></p>
</div>
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new_debug"}}
</h4>
{{template "custom/alert_cb" .}}
<div class="ui attached segment">
<form id="form_id" class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="type" value="0">
<h4 class="train-job-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.resource_cluster"}}</label>
<div class="ui blue mini menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/cloudbrain/create">
<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="active item" href="{{.RepoLink}}/grampus/notebook/create?type=0">
<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 required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<a class="active item" href="{{.RepoLink}}/grampus/notebook/create?type=0">
<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}}/grampus/notebook/create?type=1">
<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">
<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_debug_gpu_tooltips1" "/code" "/dataset" "/pretrainmodel" | Safe}}</span>
</div>
</div>
<div class="inline min_title required field" style="margin-bottom: 0rem !important;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_name"}}</label>
<input name="display_job_name" id="cloudbrain_job_name" style="width: 60%;"
placeholder="{{.i18n.Tr "cloudbrain.task_name"}}" value="{{.display_job_name}}" tabindex="3"
autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')">
</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span>
<div class="inline min_title 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>
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" 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>
{{template "custom/select_model" .}}
<div id="images-new-cb">

</div>
<div id="select-multi-dataset">

</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span>
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label>
<select id="__specs__" class="ui search dropdown width48"
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' ovalue="{{.spec_id}}"
{{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}
name="spec_id">
</select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
{{end}}
</div>
<div class="inline 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 cancel"
href="{{.RepoLink}}/debugjob?debugListType=all">{{.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 src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
;(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"}},
});
})();
</script>

+ 151
- 0
templates/repo/grampus/notebook/npu/new.tmpl View File

@@ -0,0 +1,151 @@
{{template "base/head" .}}
{{template "custom/global_mask" .}}
<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-flag-model="true"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" id="messageInfo" style="display: none;">
<p></p>
</div>
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new_debug"}}
</h4>
{{template "custom/alert_cb" .}}
<div class="ui attached segment">
<form class="ui form" id="form_id" action="{{.Link}}" method="post">
<input type="hidden" name="type" value="1">
<input type="hidden" name="image" value="">
{{.CsrfTokenHtml}}
<h4 class="train-job-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.resource_cluster"}}</label>
<div class="ui blue mini menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/cloudbrain/create">
<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="active item" href="{{.RepoLink}}/grampus/notebook/create?type=1">
<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 required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/grampus/notebook/create?type=0">
<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}}/grampus/notebook/create?type=1">
<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="inline field">
<label class="label-fix-width" style="font-weight: normal;"></label>
{{template "custom/task_wait_count" .}}
</div>
<div class="inline min_title required field" style="margin-bottom: 0rem !important;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_name"}}</label>
<input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" style="width: 60%;" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="36" onkeyup="this.value=this.value.replace(/[, ]/g,'')">
</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span>
<div class="inline min_title 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>
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" 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>
{{template "custom/select_model" .}}
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label>
<select class="ui search dropdown cloudbrain_image width48" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" style='width:385px' name="image_id">
{{range .images}}
<option name="image_id" value="{{.ID}}">{{.Name}}</option>
{{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 required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.specification"}}</label>
<select id="__specs__" class="ui search dropdown width48" ovalue="{{.spec_id}}"
{{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="spec_id"></select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
{{end}}
</div>
<div class="inline 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 cancel" href="{{.RepoLink}}/debugjob?debugListType=all">{{.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 src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
;(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"}},
});
})();
</script>

+ 439
- 0
templates/repo/grampus/notebook/show.tmpl View File

@@ -0,0 +1,439 @@
{{template "base/head" .}}
<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 backTodeBug" href="{{.RepoLink}}/debugjob?debugListType=all">
{{$.i18n.Tr "repo.modelarts.notebook"}}
</a>
<div class="divider"> / </div>
{{with .task}}
<div class="active section">{{.DisplayJobName}}</div>
{{end}}
</div>
</h4>
{{with .task}}
<div class="ui accordion border-according" id="accordion" data-repopath="{{$.RepoRelPath}}/grampus/notebook"
data-jobid="{{.ID}}" data-version="">
<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">{{ConvertDurationToStr .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>
</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.cloudbrain_creator"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.User.Name}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.code_version"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{if .BranchName}}
{{.BranchName}}
{{else}}
--
{{end}}
<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.computing_resources"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-computeresource">
{{.ComputeResource}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.createtime"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-createtime">
{{TimeSinceUnix1 .CreatedUnix}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.cloudbrain.time.starttime"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
<div class="text-span text-span-w"
id="{{.VersionName}}-startTime">
{{if not (eq .StartTime 0)}}
{{TimeSinceUnix1 .StartTime}}
{{else}}
--
{{end}}
</div>
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.cloudbrain.time.endtime"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-EndTime">
{{if not (eq .EndTime 0)}}
{{TimeSinceUnix1 .EndTime}}
{{else}}
--
{{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.dura_time"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w"
id="{{.VersionName}}-duration">
{{if not (eq .Duration 0)}}
{{ConvertDurationToStr .Duration}}
{{else}}
--
{{end}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.description"}}
</td>

<td class="ti-text-form-content">
<div class="text-span-new" id="model_description">
{{.Description}}
</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 "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-image" style="cursor:pointer"
data-clipboard-text="{{.EngineName}}"
data-success="{{$.i18n.Tr "repo.copied"}}"
data-error="{{$.i18n.Tr "repo.copied_error"}}"
data-content="{{$.i18n.Tr "repo.copy"}}"
data-variation="inverted tiny"
>
<span title="{{.EngineName}}">{{.EngineName}}</span>
</span>
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.modelarts.train_job.standard"}}
</td>

<td class="ti-text-form-content spec">
<div class="text-span text-span-w"></div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.grampus.train_job.ai_center"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-ai_center">
{{if $.ai_center}}{{$.ai_center}}{{else}}--{{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.model_name"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .ModelName}}{{.ModelName}}{{else}}--{{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.modelconvert.modelversion"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .ModelVersion}}{{.ModelVersion}}{{else}}--{{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.infer_job_model_file"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .CkptName}}{{.CkptName}}{{else}}--{{end}}</div>
</td>
</tr>
{{if eq .ComputeResource "CPU/GPU"}}
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.code_storage_path"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="code_storage_path">
{{$.code_path}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.dataset_storage_path"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="dataset_storage_path">
{{$.dataset_path}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.model_storage_path"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w" id="code_storage_path">
/pretrainmodel
</div>
</td>
</tr>
{{end}}
{{if eq .ComputeResource "NPU"}}
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "cloudbrain.code_obs_address"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-trainUrl">
<span class="ui poping up clipboard" data-position="top center" id="clipboard-btn-trainUrl" style="cursor:pointer"
data-clipboard-text="{{.TrainUrl}}"
data-success="{{$.i18n.Tr "repo.copied"}}"
data-error="{{$.i18n.Tr "repo.copied_error"}}"
data-content="{{$.i18n.Tr "repo.copy"}}"
data-variation="inverted tiny"
>
<span title="{{.TrainUrl}}">
{{if .TrainUrl}}
{{.TrainUrl}}
{{else}}
--
{{end}}
</span>
</span>
</div>
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
</div>
</div>
<div style="clear:both">
{{if $.datasetDownload}}
<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>
{{if eq .ComputeResource "NPU"}}
<th style="color: #8a8e99;font-size:12px"class="eleven wide">{{$.i18n.Tr "dataset.download_url"}}</th>
<th style="color: #8a8e99;font-size:12px" class="two wide center aligned">{{$.i18n.Tr "dataset.download_oper"}}</th>
{{end}}
{{$Resource := .ComputeResource}}
</tr></thead>
<tbody>
{{range $k,$v := $.datasetDownload}}
<tr>
<td class="dataset_nowrap_two_line">
{{if eq .IsDelete true}}
{{.DatasetName}}({{$.i18n.Tr "dataset.file_deleted"}})
{{else}}
<a href="{{.RepositoryLink}}" target="_blank">{{.DatasetName}}</a>
{{end}}
</td>
{{if eq $Resource "NPU"}}
<td><div class="dataset_nowrap_two_line">{{.DatasetDownloadLink}}</div></td>
<td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn-dataset-{{$k}}" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{.DatasetDownloadLink}}">{{if .DatasetDownloadLink}}{{$.i18n.Tr "dataset.download_copy"}}{{end}}</a></td>
{{end}}
</tr>
{{end}}
</tbody>
{{end}}
</table>
{{if and (eq .ComputeResource "NPU") ($.modelDownload.Name)}}
<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 "repo.modelarts.infer_job_model_file"}}</th>
<th style="color: #8a8e99;font-size:12px"class="eleven wide">{{$.i18n.Tr "dataset.download_model_url"}}</th>
<th style="color: #8a8e99;font-size:12px" class="two wide center aligned">{{$.i18n.Tr "dataset.download_oper"}}</th>
</tr>
</thead>
<tbody>
<tr>
<td class="dataset_nowrap_two_line">
{{if eq $.modelDownload.IsDelete true}}
{{$.modelDownload.Name}}({{$.i18n.Tr "dataset.file_deleted"}})
{{else}}
<a href="{{$.RepoLink}}/modelmanage/show_model_info?name={{.ModelName}}" target="_blank">{{$.modelDownload.Name}}</a>
{{end}}
</td>
<td><div class="dataset_nowrap_two_line">{{$.modelDownload.DownloadLink}}</div></td>
<td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn-model" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{$.modelDownload.DownloadLink}}">{{if $.modelDownload.DownloadLink}}{{$.i18n.Tr "dataset.download_copy"}}{{end}}</a></td>
</tr>
</tbody>
</table>
{{end}}
</div>
</div>
</div>


</div>
</div>
</div>
{{end}}
{{template "base/paginate" .}}
</div>
<!-- 确认模态框 -->
<div id="deletemodel">
<div class="ui basic modal">
<div class="ui icon header">
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}}
</div>

<div class="content">
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p>
</div>
<div class="actions">
<div class="ui red basic inverted cancel button">
<i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}}
</div>
<div class="ui green basic inverted ok button">
<i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}}
</div>
</div>
</div>
</div>


</div>
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
;(function() {
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"}},
});
$('td.ti-text-form-content.spec div').text(specStr);
})();
</script>

+ 2
- 8
templates/repo/grampus/trainjob/gpu/new.tmpl View File

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

.train-job-title {
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 16px !important;
padding-left: 3rem !important;
}
.min_title{
font-size: 14px !important;
margin-bottom: 2rem !important;
@@ -96,14 +90,14 @@
<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 {{if.GPUEnabled}}class="active item" href="{{.RepoLink}}/grampus/train-job/gpu/create"{{else}}href="javascript:return false;" class="item disabled" {{end}}>
<a class="active item" href="{{.RepoLink}}/grampus/train-job/gpu/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 {{if.NPUEnabled}}class="item" href="{{.RepoLink}}/grampus/train-job/npu/create"{{else}}href="javascript:return false;" class="item disabled" {{end}} >
<a class="item" href="{{.RepoLink}}/grampus/train-job/npu/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"/>


+ 2
- 15
templates/repo/grampus/trainjob/npu/new.tmpl View File

@@ -1,11 +1,5 @@
{{template "base/head" .}}
<style>
.train-job-title {
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 16px !important;
padding-left: 3rem !important;
}
.min_title{
font-size: 14px !important;
margin-bottom: 2rem !important;
@@ -45,13 +39,6 @@
text-align: center;
color: #C2C7CC;
}
.label-fix-width{
width: 140px !important;
text-align: right;
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 14px !important;
}
</style>
{{template "custom/global_mask" .}}
<div class="repository">
@@ -89,14 +76,14 @@
<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 {{if.GPUEnabled}}class="item" href="{{.RepoLink}}/grampus/train-job/gpu/create"{{else}}href="javascript:return false;" class="item disabled" {{end}}>
<a class="item" href="{{.RepoLink}}/grampus/train-job/gpu/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 {{if.NPUEnabled}}class="active item" href="{{.RepoLink}}/grampus/train-job/npu/create"{{else}}href="javascript:return false;" class="item disabled" {{end}} >
<a class="active item" href="{{.RepoLink}}/grampus/train-job/npu/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"/>


+ 0
- 189
templates/repo/grampus/trainjob/show.tmpl View File

@@ -1,195 +1,6 @@
{{template "base/head" .}}
<link rel="stylesheet" href="/self/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css">
<style>
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}

.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}

.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}

.acc-margin-bottom {
margin-bottom: 5px;
}

.title_text {
font-size: 12px;
}

.ac-display-inblock {
display: inline-block;
}

.cti-mgRight-sm {
margin-right: 8px;
}

.ac-text-normal {
font-size: 14px;
color: #575d6c;
}

.uc-accordionTitle-black {
color: #333;
}

.accordion-border {
border: 1px solid #cce2ff;
}

.padding0 {
padding: 0 !important;
}

.content-pad {
padding: 15px 35px;
}

.content-margin {
margin: 10px 5px;
}

.tab_2_content {
min-height: 360px;
margin-left: 10px;
}

.ac-grid {
display: block;
*zoom: 1;
}

.ac-grid-col {
float: left;
width: 100%;
}

.ac-grid-col2 .ac-grid-col {
width: 50%;
}

.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}

.ti-form>tbody {
font-size: 12px;
}

.ti-form>tbody,
.ti-form>tbody>tr {
vertical-align: inherit;
}

.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}

.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
}

.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}

td,
th {
padding: 0;
}

.ac-grid-col .text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.redo-color {
color: #3291F8;
}

.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}

.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}

.text-width80 {
width: 100px;
line-height: 30px;
}

.border-according {
border: 1px solid #dfe1e6;
}

.disabled {
cursor: default;
pointer-events: none;
color: rgba(0, 0, 0, .6) !important;
opacity: .45 !important;
}

.pad20 {

border: 0px !important;
}

.model_file_bread {
margin-bottom: -0.5rem !important;
padding-left: 1rem;


+ 6
- 11
templates/repo/modelarts/inferencejob/new.tmpl View File

@@ -1,10 +1,5 @@
{{template "base/head" .}}
<style>
.unite{
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
}

.title{
font-size: 16px !important;
padding-left: 3rem !important;
@@ -64,7 +59,7 @@
<input type="hidden" id="fail_dataset_name" value="{{$.dataset_name}}">
<input type="hidden" id="fail_dataset_uuid" value="{{$.attachment}}">

<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<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">
@@ -111,10 +106,10 @@
</div>
<div class="ui divider"></div>
<!-- 模型相关配置 -->
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<div class="required unite inline min_title fields" style="width: 96.8%;">
<div class="required eight wide field">
<label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>
<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>
@@ -148,7 +143,7 @@
</span>
</div>
<!-- AI引擎 -->
<div class="required inline min_title fields" style="width: 95%;">
<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">


+ 0
- 155
templates/repo/modelarts/inferencejob/show.tmpl View File

@@ -1,160 +1,5 @@
{{template "base/head" .}}
<style>
.according-panel-heading{
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}
.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}
.accordion-panel-title-content{
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}
.acc-margin-bottom {
margin-bottom: 5px;
}
.title_text {
font-size: 12px;
}
.ac-display-inblock {
display: inline-block;
}
.cti-mgRight-sm {
margin-right: 8px;
}
.ac-text-normal {
font-size: 14px;
color: #575d6c;
}
.uc-accordionTitle-black {
color: #333;
}
.accordion-border{
border:1px solid #cce2ff;
}
.padding0{
padding: 0 !important;
}
.content-pad{
padding: 15px 35px;
}
.content-margin{
margin:10px 5px ;
}
.tab_2_content {
min-height: 360px;
margin-left: 10px;
}
.ac-grid {
display: block;
*zoom: 1;
}
.ac-grid-col {
float: left;
width: 100%;
}
.ac-grid-col2 .ac-grid-col {
width: 50%;
}
.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}
.ti-form>tbody {
font-size: 12px;
}
.ti-form>tbody, .ti-form>tbody>tr {
vertical-align: inherit;
}
.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}
.ti-text-form-content{
line-height: 30px;
padding-bottom: 20px;
}
.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}
td, th {
padding: 0;
}
.ac-grid-col .text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.redo-color{
color: #3291F8;
}
.ti-action-menu-item:not(:last-child){
margin-right: 10px;
padding-right: 11px;
text-decoration: none!important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}
.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}
.text-width80{
width: 100px;
line-height: 30px;
}
.border-according{
border: 1px solid #dfe1e6;
}
.disabled {
cursor: default;
pointer-events: none;
color: rgba(0,0,0,.6) !important;
opacity: .45 !important;
}
.pad20{

border:0px !important;
}
.model_file_bread{
margin-bottom: -0.5rem !important;
padding-left: 1rem;


+ 104
- 188
templates/repo/modelarts/notebook/new.tmpl View File

@@ -1,208 +1,125 @@
{{template "base/head" .}}
<style>
.inline.required.field.cloudbrain_benchmark {
display: none;
}
</style>

{{template "custom/global_mask" .}}
<div class="repository">
{{template "repo/header" .}}
<div class="repository new repo ui middle very relaxed page grid">
<div class="column">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" id="messageInfo" style="display: none;">
<p></p>
</div>
{{template "custom/alert_cb" .}}
<div class="ui container">
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-flag-model="true"></div>
{{if eq .NotStopTaskCount 0}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" id="messageInfo" style="display: none;">
<p></p>
</div>
{{template "custom/alert_cb" .}}
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new_debug"}}
</h4>
<div class="ui attached segment">
<form class="ui form" id="form_id" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<h3 class="ui top attached header">
{{.i18n.Tr "repo.cloudbrain.new"}}
</h3>
<div class="ui attached segment">
<!-- <br> -->
<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/cloudbrain/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/notebook/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="inline field">
<label></label>
{{template "custom/task_wait_count" .}}
</div>
<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.task_name"}}</label>
<input name="display_job_name" id="cloudbrain_job_name" placeholder="任务名称" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="36" onkeyup="this.value=this.value.replace(/[, ]/g,'')">
</div>

<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.mirror"}}</label>
<select id="cloudbrain_image" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" style='width:385px' name="image_id">
{{range .images}}
<option name="image_id" value="{{.Id}}">{{.Value}}</option>
{{end}}
</select>
</div>
<div id="select-multi-dataset">

<!-- <br> -->
<h4 class="train-job-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.resource_cluster"}}</label>
<div class="ui blue mini menu compact selectcloudbrain">
<a class="active item" href="{{.RepoLink}}/cloudbrain/create">
<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" href="{{.RepoLink}}/grampus/notebook/create?type=0">
<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 class="inline required field">
<label>工作环境</label>
<input name="de" id="cloudbrain_de" value="{{.env}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly">
</div>
<div class="inline required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<div class="ui blue small menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/cloudbrain/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/notebook/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 class="inline required field">
<label>类型</label>
<input name="job_type" id="cloudbrain_job_type" value="{{.notebook_type}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly">
</div> -->
<!--<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.specification"}}</label>
<select id="cloudbrain_flavor" class="ui search dropdown" placeholder="选择规格" style='width:385px' name="flavor">
{{range .flavors}}
<option name="flavor" value="{{.Value}}">{{.Desc}}</option>

{{end}}
</select>
</div>-->
<div class="inline required field">
<label>{{.i18n.Tr "cloudbrain.specification"}}</label>
<select id="__specs__" class="ui search dropdown" ovalue="{{.spec_id}}"
{{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="spec_id"></select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
</div>
<div class="inline field">
<label class="label-fix-width" style="font-weight: normal;"></label>
{{template "custom/task_wait_count" .}}
</div>
<div class="required min_title inline field" style="margin-bottom: 0rem !important;">
<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}}"
tabindex="3" onkeyup="this.value=this.value.replace(/[, ]/g,'')" autofocus required
maxlength="36">
</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "repo.cloudbrain_jobname_err"}}</span>
<div class="inline min_title 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="train-job-title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
{{template "custom/select_model" .}}
<div class="inline min_title required field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}}</label>
<select id="cloudbrain_image" class="ui search dropdown width48" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image_id">
{{range .images}}
<option name="image_id" value="{{.Id}}">{{.Value}}</option>
{{end}}
</select>
</div>
<div id="select-multi-dataset">

</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span>
<div class="inline required min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.specification"}}</label>
<select id="__specs__" class="ui search dropdown width48" ovalue="{{.spec_id}}"
{{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="spec_id"></select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip" style="padding:0 5px;margin:6px 0;margin-left:265px;font-size:12px;width: 50%!important;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
<a href="{{AppSubUrl}}/reward/point/rule" target="_blank">{{$.i18n.Tr "points.points_acquisition_instructions"}}</a>
</span>
</div>
<!--<div class="inline required field">
<label>数据集存放路径</label>
<input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly">
</div> -->
<div class="inline field">
<label>{{.i18n.Tr "cloudbrain.description"}}</label>
<input name="description" id="cloudbrain_description" tabindex="3" autofocus maxlength="255">
</div>
<div class="inline field">
<label></label>
<button class="ui green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button cancel" href="{{.RepoLink}}/debugjob?debugListType=all">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
{{end}}
</div>
<div class="inline field">
<label class="label-fix-width"></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 cancel" href="{{.RepoLink}}/debugjob?debugListType=all">{{.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 src="{{StaticUrlPrefix}}/js/cloudbrainNew.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
// 判断必填选项是否填写正确
let form = document.getElementById('form_id');

$('#messageInfo').css('display','none')

var isValidate = false;
function validate(){
$('.ui.form').form({
on: 'blur',
fields: {
display_job_name:{
identifier : 'display_job_name',
rules: [
{
type: 'regExp[/^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/]',
}
]
},
spec_id: {
identifier: 'spec_id',
rules: [{ type: 'empty' }]
}
},
onSuccess: function(){
isValidate = true;
},
onFailure: function(e){
isValidate = false;
return false;
}
})
}
validate();
let createFlag = false
form.onsubmit = function(e){
if(!isValidate) return false;
if(createFlag) return false;
let value_task = $("input[name='display_job_name']").val()
let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/
let flag = re.test(value_task)
if(!flag){
$('#messageInfo').css('display','block')
let str = '只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。'
$('#messageInfo p').text(str)
return false
}
let min_value_task = value_task.toLowerCase()
$("input[name='display_job_name']").attr("value",min_value_task)
document.getElementById("mask").style.display = "block"
createFlag = true

}
// 点击按钮后遮罩层显示
// function showmask() {
// document.getElementById("mask").style.display = "block"
// }

// 页面加载完毕后遮罩层隐藏
document.onreadystatechange = function() {
if (document.readyState === "complete") {
document.getElementById("mask").style.display = "none"
}
}
$('select.dropdown')
.dropdown();

$(function() {
$("#cloudbrain_job_type").change(function() {
if ($(this).val() == 'BENCHMARK') {
$(".cloudbrain_benchmark").show();
} else {
$(".cloudbrain_benchmark").hide();
}
})
})
$(document).ready(function(){
$(document).keydown(function(event){
if(event.keyCode==13){
event.preventDefault();
}
});
});

;(function() {
var SPECS = {{ .Specs }};
var showPoint = {{ .CloudBrainPaySwitch }};
@@ -214,5 +131,4 @@
shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}},
});
})();
console.log("-------------:",{{.NotStopTaskCount}})
</script>

+ 69
- 239
templates/repo/modelarts/notebook/show.tmpl View File

@@ -1,225 +1,4 @@
{{template "base/head" .}}
<style>
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}

.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}

.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}

.acc-margin-bottom {
margin-bottom: 5px;
}

.title_text {
font-size: 12px;
}

.ac-display-inblock {
display: inline-block;
}

.cti-mgRight-sm {
margin-right: 8px;
}

.ac-text-normal {
font-size: 14px;
color: #575d6c;
}

.uc-accordionTitle-black {
color: #333;
}

.accordion-border {
border: 1px solid #cce2ff;
}

.padding0 {
padding: 0 !important;
}

.content-pad {
padding: 15px 35px;
}

.content-margin {
margin: 10px 5px;
}

.tab_2_content {
margin-left: 10px;
}

.ac-grid {
display: block;
*zoom: 1;
}

.ac-grid-col {
float: left;
width: 100%;
}

.ac-grid-col2 .ac-grid-col {
width: 50%;
}

.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}

.ti-form>tbody {
font-size: 12px;
}

.ti-form>tbody,
.ti-form>tbody>tr {
vertical-align: inherit;
}

.info_text {
padding-bottom: 20px;
padding-right: 20px;
font-size: 12px;
}

.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}

.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
}

.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}

td,
th {
padding: 0;
}

.ac-grid-col .text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.text-span-new {
width: 800px;
overflow: hidden;
text-overflow: ellipsis;
height: 20%;
word-break: break-all;
}

.redo-color {
color: #3291F8;
}

.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}

.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}

.text-width80 {
width: 100px;
line-height: 30px;
}

.border-according {
border: 1px solid #dfe1e6;
}

.disabled {
cursor: default;
pointer-events: none;
color: rgba(0, 0, 0, .6) !important;
opacity: .45 !important;
}

.pad20 {

border: 0px !important;
}

.model_file_bread {
margin-bottom: -0.5rem !important;
padding-left: 1rem;
padding-top: 0.5rem;
}
.dataset_nowrap_two_line{
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
line-clamp: 2;
-webkit-line-clamp: 2;
text-overflow: -o-ellipsis-lastline;
max-height: 50px;
}
</style>
<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
@@ -308,7 +87,7 @@
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-mirror">
<div class="text-span text-span-w">
{{.User.Name}}
</div>
</td>
@@ -338,6 +117,25 @@
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.cloudbrain.time.starttime"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
<div class="text-span text-span-w"
id="{{.VersionName}}-startTime">
{{if not (eq .StartTime 0)}}
{{TimeSinceUnix1 .StartTime}}
{{else}}
--
{{end}}
</div>
</div>
</td>
</tr>

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

@@ -385,23 +183,31 @@
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80">
{{$.i18n.Tr "repo.cloudbrain.time.starttime"}}
{{$.i18n.Tr "repo.modelarts.model_name"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">
<div class="text-span text-span-w"
id="{{.VersionName}}-startTime">
{{if not (eq .StartTime 0)}}
{{TimeSinceUnix1 .StartTime}}
{{else}}
--
{{end}}
</div>
</div>
<div class="text-span text-span-w">{{if .ModelName}}{{.ModelName}}{{else}}--{{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.modelconvert.modelversion"}}
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .ModelVersion}}{{.ModelVersion}}{{else}}--{{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.infer_job_model_file"}}
</td>

<td class="ti-text-form-content">
<div class="text-span text-span-w">{{if .CkptName}}{{.CkptName}}{{else}}--{{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.time.endtime"}}
@@ -440,14 +246,15 @@

</div>
<div style="clear:both">
{{if $.datasetDownload}}
<table style="border:none" class="ui fixed small stackable table">
<thead>
<tr><th style="color: #8a8e99;font-size:12px" class="three wide center aligned">{{$.i18n.Tr "dataset.file"}}</th>
<tr><th style="color: #8a8e99;font-size:12px" class="three wide left aligned">{{$.i18n.Tr "dataset.file"}}</th>
<th style="color: #8a8e99;font-size:12px"class="eleven wide">{{$.i18n.Tr "dataset.download_url"}}</th>
<th style="color: #8a8e99;font-size:12px" class="two wide center aligned">{{$.i18n.Tr "dataset.download_oper"}}</th>
</tr></thead>
<tbody>
{{range $.datasetDownload}}
{{range $k,$v := $.datasetDownload}}
<tr>
<td class="dataset_nowrap_two_line">
{{if eq .IsDelete true}}
@@ -457,12 +264,37 @@
{{end}}
</td>
<td><div class="dataset_nowrap_two_line">{{.DatasetDownloadLink}}</div></td>
<td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn-dataset" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{.DatasetDownloadLink}}">{{$.i18n.Tr "dataset.download_copy"}}</a></td>
<td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn-dataset-{{$k}}" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{.DatasetDownloadLink}}">{{$.i18n.Tr "dataset.download_copy"}}</a></td>
</tr>
{{end}}
</tbody>
</table>
</div>
{{end}}
{{if $.modelDownload.Name}}
<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 "repo.modelarts.infer_job_model_file"}}</th>
<th style="color: #8a8e99;font-size:12px"class="eleven wide">{{$.i18n.Tr "dataset.download_model_url"}}</th>
<th style="color: #8a8e99;font-size:12px" class="two wide center aligned">{{$.i18n.Tr "dataset.download_oper"}}</th>
</tr>
</thead>
<tbody>
<tr>
<td class="dataset_nowrap_two_line">
{{if eq $.modelDownload.IsDelete true}}
{{$.modelDownload.Name}}({{$.i18n.Tr "dataset.file_deleted"}})
{{else}}
<a href="{{$.RepoLink}}/modelmanage/show_model_info?name={{.ModelName}}" target="_blank">{{$.modelDownload.Name}}</a>
{{end}}
</td>
<td><div class="dataset_nowrap_two_line">{{$.modelDownload.DownloadLink}}</div></td>
<td class="center aligned"><a class="ui poping up clipboard" id="clipboard-btn-model" data-original="{{$.i18n.Tr "repo.copy_link"}}" data-success="{{$.i18n.Tr "repo.copy_link_success"}}" data-error="{{$.i18n.Tr "repo.copy_link_error"}}" data-content="{{$.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny" data-clipboard-text="{{$.modelDownload.DownloadLink}}">{{if $.modelDownload.DownloadLink}}{{$.i18n.Tr "dataset.download_copy"}}{{end}}</a></td>
</tr>
</tbody>
</table>
{{end}}
</div>
</div>
</div>

@@ -507,8 +339,6 @@
$(document).ready(function () {
$('.secondary.menu .item').tab();
});
console.log({{$.datasetDownload}})

;(function() {
var SPEC = {{ .Spec }};
var showPoint = false;


+ 1
- 15
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -1,11 +1,5 @@
{{template "base/head" .}}
<style>
.train-job-title {
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 16px !important;
padding-left: 3rem !important;
}
.min_title{
font-size: 14px !important;
margin-bottom: 2rem !important;
@@ -18,7 +12,6 @@
}
.width80{
width: 80.7% !important;
margin-left: 10px;
}
.width85{
width: 85% !important;
@@ -47,13 +40,6 @@
text-align: center;
color: #C2C7CC;
}
.label-fix-width{
width: 140px !important;
text-align: right;
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 14px !important;
}
</style>
<!-- <div class="ui page dimmer">
<div class="ui text loader">{{.i18n.Tr "loading"}}</div>
@@ -163,7 +149,7 @@
{{template "custom/select_model" .}}

<div class="required inline min_title fields" style="width: 95%;">
<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">


+ 0
- 195
templates/repo/modelarts/trainjob/show.tmpl View File

@@ -3,201 +3,6 @@
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>

<style>
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}

.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}

.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}

.acc-margin-bottom {
margin-bottom: 5px;
}

.title_text {
font-size: 12px;
}

.ac-display-inblock {
display: inline-block;
}

.cti-mgRight-sm {
margin-right: 8px;
}

.ac-text-normal {
font-size: 14px;
color: #575d6c;
}

.uc-accordionTitle-black {
color: #333;
}

.accordion-border {
border: 1px solid #cce2ff;
}

.padding0 {
padding: 0 !important;
}

.content-pad {
padding: 15px 35px;
}

.content-margin {
margin: 10px 5px;
}

.tab_2_content {
min-height: 360px;
margin-left: 10px;
}

.ac-grid {
display: block;
*zoom: 1;
}

.ac-grid-col {
float: left;
width: 100%;
}

.ac-grid-col2 .ac-grid-col {
width: 50%;
}

.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}

.ti-form>tbody {
font-size: 12px;
}

.ti-form>tbody,
.ti-form>tbody>tr {
vertical-align: inherit;
}

.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}

.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
}

.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}

td,
th {
padding: 0;
}

.ac-grid-col .text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.redo-color {
color: #3291F8;
}

.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}

.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}

.text-width80 {
width: 100px;
line-height: 30px;
}

.border-according {
border: 1px solid #dfe1e6;
}

.ti-download-file {
display: flex;
align-items: center;
margin: 0.5rem 0;
}

.disabled {
cursor: default;
pointer-events: none;
color: rgba(0, 0, 0, .6) !important;
opacity: .45 !important;
}

.pad20 {

border: 0px !important;
}

.model_file_bread {
margin-bottom: -0.5rem !important;
padding-left: 1rem;


+ 38
- 69
templates/repo/modelarts/trainjob/version_new.tmpl View File

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

.unite{
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
}

.title{
font-size: 16px !important;
padding-left: 3rem !important;
}
.min_title{
font-size: 14px !important;
padding-left: 6rem !important;
margin-bottom: 2rem !important;

}
.width80{
width: 80.7% !important;
}
.width{
width:100% !important;
}
.width80{
width: 80.7% !important;
margin-left: 10px;
.width48{
width: 48.5% !important;
}
.width85{
width: 85% !important;
margin-left: 4.5rem !important;
}
.width81{
margin-left: 1.5rem;
width: 81% !important;
}

.add{font-size: 18px;
padding: 0.5rem;
border: 1px solid rgba(187, 187, 187, 100);
border-radius: 0px 5px 5px 0px;
line-height: 21px;
text-align: center;
color: #C2C7CC;
}
.min{
font-size: 18px;
padding: 0.5rem;
border: 1px solid rgba(187, 187, 187, 100);
border-radius: 5px 0px 0px 5px;
line-height: 21px;
text-align: center;
color: #C2C7CC;"
margin-left: 10.5rem !important;
align-items: center;
}

</style>
{{template "custom/global_mask" .}}
<div class="repository">
@@ -76,9 +44,9 @@
<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="display_job_name" name="display_job_name" value="{{.display_job_name}}">
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<h4 class="title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required min_title inline field">
<label class="" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_cluster"}}</label>
<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="active item" href="javascript:void 0;" style="cursor:not-allowed;">
<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>
@@ -91,7 +59,7 @@
</div>
</div>
<div class="required inline min_title field">
<label class="" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label>
<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="javascript:void 0;" style="cursor:not-allowed;background:rgba(0,0,0,.03);">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16"
@@ -119,13 +87,13 @@
<i class="ri-error-warning-line" style="color: #f2711c;margin-right: 0.5rem;"></i>
<span style="color: #888;font-size: 12px;">{{.i18n.Tr "cloudbrain.train_dataset_path_rule" | Safe}}</span>
</div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<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 type="hidden" style="width: 60%;" name="job_name" id="job_name" value="{{.job_name}}">
<input style="width: 60%;" name="display_job_name" id="display_job_name" value="{{.display_job_name}}" tabindex="3" disabled >
</div>
<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.parents_version"}}</label>
<div class="required min_title inline field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.parents_version"}}</label>
{{if .version_name}}
<input style="width: 60%;" value="{{.version_name}}" tabindex="3" disabled >
{{else}}
@@ -133,18 +101,18 @@
{{end}}
</div>

<div class="unite min_title inline field">
<label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label>
<div class="min_title inline field">
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label>
<textarea style="width: 80%;" id="description" value="{{.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, 256)">{{.description}}</textarea>
</div>
<div class="ui divider"></div>

<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>
<h4 class="title ui header ">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}:</h4>


<div class="required unite min_title inline field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80 left2" id="code_version" name="branch_name">
<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 left2 width80" id="code_version" name="branch_name">
{{if .branch_name}}
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option>
{{end}}
@@ -159,8 +127,8 @@

{{template "custom/select_model" .}}

<div class="required unite min_title inline fields" style="width: 90%;">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
<div class="required min_title inline 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}}
@@ -170,7 +138,7 @@
</div>

<div class="field" style="flex: 2;" id="engine_name">
<select class="ui dropdown width" id="trainjob_engine_versions" style='width: 100%;' name="engine_id">
<select class="ui dropdown width" id="trainjob_engine_versions" name="engine_id">
{{if .engine_id}}
<option name="engine_id" value="{{.engine_id}}">{{.engine_name}}</option>
{{end}}
@@ -185,12 +153,12 @@

</div>

<div class="inline unite min_title field required">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
<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: 33.5%;" name="boot_file" id="trainjob_boot_file" value="{{.boot_file}}" tabindex="3" autofocus required maxlength="255" >
<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: 33.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" >
<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 link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i>
@@ -201,8 +169,8 @@

</div>
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span>
<div class="inline unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<div class="inline min_title field">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<span id="add_run_para" style="margin-left: 0.5rem;cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span>
<input id="store_run_para" type="hidden" name="run_para_list">
<div class="dynamic field" style="margin-top: 1rem;" data-params="{{.run_para_list}}" data-params-value="{{.i18n.Tr "repo.modelarts.train_job.parameter_value"}}" data-params-name="{{.i18n.Tr "repo.modelarts.train_job.parameter_name"}}">
@@ -213,7 +181,7 @@

<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">
<select class="ui dropdown" id="trainjob_resource_pool" style="width: 48.5%;" name="pool_id">
{{range .resource_pools}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
@@ -236,13 +204,13 @@
</div>
</div>

<div class="required unite min_title inline field" id="flaver_name">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<select id="__specs__" class="ui dropdown width80" style='width:385px' name="spec_id" ovalue="{{.spec_id}}" {{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}></select>
<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 id="__specs__" class="ui dropdown width48" name="spec_id" ovalue="{{.spec_id}}" {{if .CloudBrainPaySwitch}}blance="{{.PointAccount.Balance}}"{{end}}></select>
<span><i class="question circle icon link"></i></span>
<a href="{{AppSubUrl}}/resource_desc" target="_blank">{{.i18n.Tr "custom.resource_description"}}</a>
{{if .CloudBrainPaySwitch}}
<div class="cloudbrain_resource_spec_blance_tip width80" style="padding:0 5px;margin:6px 0;margin-left:60px;font-size:12px;">
<div class="cloudbrain_resource_spec_blance_tip width48" style="padding:0 5px;margin:6px 0;margin-left:60px;font-size:12px;">
<span>{{$.i18n.Tr "points.balance_of_points"}}<span style="color:red;margin: 0 3px">{{.PointAccount.Balance}}</span>{{$.i18n.Tr "points.points"}}</span><span>{{$.i18n.Tr "points.expected_time"}}<span style="color:red;margin: 0 3px" class="can-use-time"></span>{{$.i18n.Tr "points.hours"}}</span>
<span style="float:right;">
<i class="question circle icon link" data-position="right center" data-variation="mini"></i>
@@ -251,8 +219,8 @@
</div>
{{end}}
</div>
<div class="inline required unite min_title field">
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<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%;">

@@ -262,7 +230,8 @@
</div>
</div>

<div class="inline unite min_title field">
<div class="inline min_title field">
<label class="label-fix-width"></label>
<button class="ui create_train_job green button {{if eq .NotStopTaskCount 1}}disabled{{end}}">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>


+ 15
- 5
templates/repo/modelmanage/convertshowinfo.tmpl View File

@@ -400,7 +400,7 @@ td, th {
</div>
</div>
</div>
<div style="clear: both;"></div>
</div>
</div>

@@ -426,7 +426,10 @@ td, th {
<div class="ui message message" style="display: none;">
<div id="header"></div>
</div>
<div class="ui attached log" id="log" style="height: 300px !important; overflow: auto;">
<div class="ui attached log" id="log" style="height: 300px !important; overflow: auto;position: relative;">
<div class="ui inverted active dimmer">
<div class="ui loader"></div>
</div>
<input type="hidden" name="end_line">
<input type="hidden" name="start_line">
<pre id="log_file"></pre>
@@ -517,15 +520,22 @@ td, th {
$(document).ready(loadJobStatus);

function loadLog(version_name){
document.getElementById("mask").style.display = "block"
$('.log .ui.inverted.active.dimmer').css({
"background-color": "#fff",
"display": "block",
});
$.get(`/api/v1/repos/${userName}/${repoPath}/modelmanage/${taskID}/log?version_name=${version_name}&lines=50&order=asc`, (data) => {
$('input[name=end_line]').val(data.EndLine)
$('input[name=start_line]').val(data.StartLine)
$(`#log_file`).text(data.Content)
document.getElementById("mask").style.display = "none"
$('.log .ui.inverted.active.dimmer').css({
"display": "none",
});
}).fail(function(err) {
console.log(err);
document.getElementById("mask").style.display = "none"
$('.log .ui.inverted.active.dimmer').css({
"display": "none",
});
});
}
function loadModelFile(version_name,parents,filename,init){


+ 9
- 14
templates/repo/modelsafety/new.tmpl View File

@@ -1,10 +1,5 @@
{{template "base/head" .}}
<style>
.unite {
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
}

.title {
font-size: 16px !important;
padding-left: 3rem !important;
@@ -81,7 +76,7 @@
href="{{.Link}}">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
</div>
</div>
<!-- <div class="required unite min_title inline field">
<!-- <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">
@@ -147,9 +142,9 @@
onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea>
</div>
<input type="hidden" id="ai_model_version" name="model_version" value="{{$.model_version}}">
<div class="required unite inline min_title fields" style="width: 96.8%;">
<div class="required eight wide field">
<label style="font-size:14px;font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>
<div class="required inline min_title fields" style="width: 93.5%;">
<label class="label-fix-width label-required" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label>
<div class="six wide field">
<div class="ui fluid selection dropdown" id="select_model">
<input type="hidden" name="model_name" required value="{{.model_name}}">
<div class="text"></div>
@@ -193,7 +188,7 @@
<div id="images-new-cb"></div>
<input type="hidden" id="ai_image_name" value="{{.image}}">
{{else}}
<div class="required inline min_title fields" style="width: 95%;">
<div class="required inline min_title fields" style="width: 92%;">
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}</label>
<div class="field" style="flex: 1.5;">
<select class="ui dropdown width100" id="trainjob_engines">
@@ -262,13 +257,13 @@
</span>
<a href="https://openi.pcl.ac.cn/OpenIOSSG/aisafety" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a>
</div>
<div class="inline field min_title required fields" style="width: 95%;">
<label class="label-fix-width label-required" style="font-weight: normal;">{{.i18n.Tr "modelsafety.base_data_set"}}</label>
<div class="inline field min_title required fields" style="width: 92%;">
<label class="label-fix-width label-required" style="font-weight: normal;">{{.i18n.Tr "modelsafety.base_data_set"}}</label>&nbsp;
<div class="field" style="flex:1.5">
<select id="baseDataSet-sel" class="ui dropdown width100" name="src_dataset" ovalue="{{.src_dataset}}"></select>
</div>
<div class="field" style="flex:2;display:flex;">
<label class="label-fix-width label-required" style="font-weight:normal;display:flex;justify-content:right;align-items: center;">{{.i18n.Tr "modelsafety.combat_data_set"}}</label>
<label class="label-required" style="font-weight:normal;display:flex;justify-content:right;align-items: center;">{{.i18n.Tr "modelsafety.combat_data_set"}}</label>
<div style="flex:1">
<select id="combatDataSet-sel" class="ui dropdown width100" name="combat_dataset" ovalue="{{.combat_dataset}}"></select>
</div>
@@ -316,7 +311,7 @@
</div>
{{end}}
</div>
<div class="inline unite min_title field">
<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"}}


+ 1
- 197
templates/repo/modelsafety/show.tmpl View File

@@ -1,200 +1,4 @@
{{template "base/head" .}}
<style>
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
}

.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
}

.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
}

.acc-margin-bottom {
margin-bottom: 5px;
}

.title_text {
font-size: 12px;
}

.ac-display-inblock {
display: inline-block;
}

.cti-mgRight-sm {
margin-right: 8px;
}

.ac-text-normal {
font-size: 14px;
color: #575d6c;
}

.uc-accordionTitle-black {
color: #333;
}

.accordion-border {
border: 1px solid #cce2ff;
}

.padding0 {
padding: 0 !important;
}

.content-pad {
padding: 15px 35px;
}

.content-margin {
margin: 10px 5px;
}

.tab_2_content {
min-height: 600px;
margin-left: 10px;
}

.ac-grid {
display: block;
*zoom: 1;
}

.ac-grid-col {
float: left;
width: 100%;
}

.ac-grid-col2 .ac-grid-col {
width: 50%;
}

.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
}

.ti-form>tbody {
font-size: 12px;
}

.ti-form>tbody,
.ti-form>tbody>tr {
vertical-align: inherit;
}

.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}

.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
}

.ti-form>tbody>tr>td {
vertical-align: top;
white-space: normal;
}

td,
th {
padding: 0;
}

.ac-grid-col .text-span {
width: 420px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.redo-color {
color: #3291F8;
}

.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}

.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}

.text-width80 {
width: 100px;
line-height: 30px;
}

.border-according {
border: 1px solid #dfe1e6;
}

.disabled {
cursor: default;
pointer-events: none;
color: rgba(0, 0, 0, .6) !important;
opacity: .45 !important;
}

.pad20 {

border: 0px !important;
}

.model_file_bread {
margin-bottom: -0.5rem !important;
padding-left: 1rem;
padding-top: 0.5rem;
}
</style>
<div id="mask">
<div id="loadingPage">
<div class="rect1"></div>
@@ -463,7 +267,7 @@
</div>
</div>
</div>
<div style="clear: both;"></div>
</div>
</div>
<div class="ui tab" data-tab="second0">


+ 10
- 11
templates/user/dashboard/cloudbrains.tmpl View File

@@ -80,7 +80,7 @@
<div class="three wide column nowrap" style="width:12% !important">
{{if eq .JobType "DEBUG"}}
<a class="title"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}"
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{$JobID}}"
title="{{.DisplayJobName}}" style="font-size: 14px;padding-right:0px">
<span class="fitted"
style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span>
@@ -123,7 +123,7 @@
<div class="two wide column text center nowrap"
style="width: 8% !important;">
<span class="job-status" id="{{$JobID}}"
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK" "MODELSAFETY"}}/cloudbrain{{end}}'
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK" "MODELSAFETY"}}/cloudbrain{{end}}'
data-jobid="{{$JobID}}" data-version="{{.VersionName}}"
data-bootfile="{{.BootFile}}">
<span><i id="{{$JobID}}-icon" style="vertical-align: middle;"
@@ -155,7 +155,7 @@
<!-- 智算中心 -->
<div class="one wide column text center nowrap" style="width:8% !important;">
<span style="font-size: 12px;" class="aicenter_{{.DisplayJobName}}_{{$JobID}}" title="{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}">{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}</span>
<span style="font-size: 12px;" id="cluster-{{$JobID}}" class="aicenter_{{.DisplayJobName}}_{{$JobID}}" title="{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}">{{if .AiCenter}}{{.AiCenter}}{{else}}--{{end}}</span>
</div>
<!-- XPU类型 -->
<div class="one wide column text center nowrap" style="width:10% !important;">
@@ -195,7 +195,7 @@
<a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button'
data-jobid="{{$JobID}}"
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'>
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{$JobID}}/'>
{{$.i18n.Tr "repo.debug"}}
</a>
{{else}}
@@ -203,7 +203,7 @@
<a id="ai-debug-{{$JobID}}"
class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button'
data-jobid="{{$JobID}}"
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'>
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{end}}/{{$JobID}}/'>
{{$.i18n.Tr "repo.debug_again"}}
</a>
{{end}}
@@ -227,9 +227,9 @@
{{if eq .JobType "DEBUG" "BENCHMARK" "SNN4IMAGENET" "BRAINSCORE"}}
<form id="stopForm-{{$JobID}}" style="margin-left:-1px;">
{{$.CsrfTokenHtml}}
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}"
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}"
class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button'
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop'
data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 2}}/grampus/notebook{{else}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}{{end}}/{{$JobID}}/stop'
data-jobid="{{$JobID}}" data-bootfile="{{.BootFile}}">
{{$.i18n.Tr "repo.stop"}}
</a>
@@ -274,18 +274,17 @@
</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")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{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")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{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'
method="post">
{{$.CsrfTokenHtml}}
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}"
data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?ishomepage=true"
data-version="" class="ui basic ai_delete blue button"
data-version="{{.VersionName}}" class="ui basic ai_delete blue button"
style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
</a>
</form>
{{end}}
{{end}}
</div>
</div>
</div>


+ 4
- 0
templates/user/dashboard/feeds.tmpl View File

@@ -92,6 +92,10 @@
{{$.i18n.Tr "action.task_c2netgputrainjob" .GetRepoLink .Content .RefName | Str2html}}
{{else if eq .GetOpType 35}}
{{$.i18n.Tr "action.dataset_recommended" .GetRepoLink (index .GetIssueInfos 1 | RenderEmoji) | Str2html}}
{{else if eq .GetOpType 39}}
{{$.i18n.Tr "action.task_c2net_npudebugjob" .GetRepoLink .Content .RefName | Str2html}}
{{else if eq .GetOpType 40}}
{{$.i18n.Tr "action.task_c2net_gpudebugjob" .GetRepoLink .Content .RefName | Str2html}}
{{end}}
</p>
{{if or (eq .GetOpType 5) (eq .GetOpType 18)}}


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

@@ -1,23 +1,18 @@
<template>
<div
class="inline field"
class="inline field margin_b_0"
:class="{
dataset_flex: confirmDatasetList && confirmFlag,
required: required,
margin_b_0: benchmarkNew,
}"
>
<label
v-if="benchmarkNew"
class="label-fix-width"
style="font-weight: normal"
>{{ i18n.dataset_label }}</label
>
<label v-else>{{ i18n.dataset_label }}</label>
<span
:class="
benchmarkNew === true ? 'dataset-train-span' : 'dataset-debug-span'
"
class="dataset-train-span"
v-if="confirmDatasetList && confirmFlag"
>
<input type="hidden" name="attachment" :value="confirmDatasetList" />
@@ -39,19 +34,11 @@
</span>
<span v-else>
<input
v-if="benchmarkNew"
type="text"
class="disabled"
style="width: 48.5%"
:placeholder="i18n.dataset_select_placeholder"
required
/>
<input
v-else
type="text"
class="disabled"
:required="required"
:placeholder="i18n.dataset_select_placeholder"
/>
</span>

@@ -593,7 +580,6 @@ export default {
},
dialogWidth: "65%",
dialogVisible: false,
benchmarkNew: false,
imageAddress: "",
activeName: "first",
search: "",
@@ -1007,18 +993,9 @@ export default {
}
this.confirmDataset();
}

if (
location.href.indexOf("benchmark") !== -1 ||
location.href.indexOf("train-job") !== -1 ||
location.href.indexOf("inference") !== -1 ||
location.href.indexOf("modelsafety") !== -1
) {
this.benchmarkNew = true;
}
if (
location.href.indexOf("modelarts/notebook/create") !== -1 ||
location.href.indexOf("/cloudbrain/create") !== -1
location.href.indexOf("/cloudbrain/create") !== -1 || location.href.indexOf('grampus/notebook/create') !== -1
) {
this.required = false;
}


+ 1
- 22
web_src/js/components/images/selectImages.vue View File

@@ -1,17 +1,13 @@
<template>
<div
class="inline required field"
:class="{ min_title: benchmarkNew, unite: benchmark }"
class="inline required min_title field"
>
<label
v-if="benchmarkNew"
class="label-fix-width"
style="font-weight: normal"
>{{i18n.image_label}}</label
>
<label v-else>{{i18n.image_label}}</label>
<input
v-if="benchmarkNew"
type="text"
name="image"
:value="imageAddress"
@@ -19,14 +15,6 @@
:placeholder="i18n.image_select_placeholder"
required
/>
<input
v-else
type="text"
name="image"
:value="imageAddress"
:placeholder="i18n.image_select_placeholder"
required
/>
<el-button
type="text"
@click="dialogVisible = true"
@@ -357,7 +345,6 @@ export default {
data() {
return {
dialogVisible: false,
benchmarkNew: false,
benchmark: false,
imageAddress: "",
activeName: "first",
@@ -503,14 +490,6 @@ export default {
this.imageAddress = document.getElementById("ai_image_name").value;
}
this.getImageListPublic();
if (
location.href.indexOf("train-job") !== -1 ||
location.href.indexOf("inference-job") !== -1 ||
location.href.indexOf("benchmark") !== -1 ||
location.href.indexOf("modelsafety") !== -1
) {
this.benchmarkNew = true;
}
if (location.href.indexOf("cloudbrain/benchmark/") !== -1) {
this.benchmark = true;
}


+ 5
- 1
web_src/js/features/cloudbrainShow.js View File

@@ -823,6 +823,7 @@ export default async function initCloudrainSow() {
$("#select_model_version").dropdown("set value", "");
$("#select_model_checkpoint").dropdown("set text", "");
$("#select_model_checkpoint").dropdown("set value", "");
$("#model_checkpoint").empty();
}
},
});
@@ -861,11 +862,14 @@ export default async function initCloudrainSow() {
!element.IsDir &&
loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length - 1])
) {
html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>`;
html += `<div class="item" data-value="${element.FileName}">${element.FileName}</div>`;
}
});
$("#model_checkpoint").append(html);
$("#select_model_checkpoint").removeClass("loading");
if (html) {
$("#select_model_checkpoint").removeClass("error");
}
const initVersionText = $(
"#model_checkpoint div.item:first-child"
).text();


+ 13
- 2
web_src/js/features/cloudrbanin.js View File

@@ -56,7 +56,10 @@ export default async function initCloudrain() {
const ID = data.ID || data.JobID;
const status = data.JobStatus;
const duration = data.JobDuration;
$("#duration-" + ID).text(duration);
const aiCenter = data.AiCenter || '--'
$("#duration-" + ID).text(duration);
$("#cluster-" + ID).text(aiCenter);
$("#" + versionname + "-ai_center").text(data.AiCenter);
if (status != status_text) {
$("#" + ID + "-icon")
.removeClass()
@@ -456,8 +459,16 @@ export default async function initCloudrain() {
.text(debug_button)
.css("margin", "0 1rem");
}
} else {
} else if (res.result_code == "2") {
$(".ui.modal.debug-again-alert").modal("show");
} else {
$(".alert")
.html(res.error_msg)
.removeClass("alert-success")
.addClass("alert-danger")
.show()
.delay(3000)
.fadeOut();
}
},
error: function (res) {


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

@@ -5226,3 +5226,6 @@ function initTopToHome() {
}

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

+ 12
- 5
web_src/js/standalone/cloudbrainNew.js View File

@@ -67,11 +67,6 @@
$(this).attr("id", "para" + cur_index);
});
});

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

var isValidate = false;
function validate() {
$(".ui.form").form({
@@ -113,9 +108,14 @@
identifier: "spec_id",
rules: [{ type: "empty" }],
},
branch_name: {
identifier: "branch_name",
rules: [{ type: "empty" }],
},
},
onSuccess: function () {
// $('.ui.page.dimmer').dimmer('show')
document.getElementById("mask").style.display = "block";
isValidate = true;
},
@@ -164,6 +164,9 @@
let name2 = $("#flaver_name .text").text();
$("input#ai_engine_name").val(name1);
$("input#ai_flaver_name").val(name2);
if ($(".cloudbrain_image .text").text()) {
$("input[name='image']").val($(".cloudbrain_image .text").text());
}
}

validate();
@@ -173,6 +176,10 @@
if (!paramNotValue) {
return false;
}
if($('input[name="model_name"]').val() && !$('input[name="ckpt_name"]').val()){
$('input[name="ckpt_name"]').parent().addClass("error")
return false
}
validate();
});
})();

+ 170
- 2
web_src/less/openi.less View File

@@ -1289,7 +1289,22 @@ i.SUCCEEDED {
max-width: 6.38px;
visibility: hidden;
}

.ui.form .train-job-title {
font-family: SourceHanSansSC-medium !important;
color: rgba(16, 16, 16, 100) !important;
font-size: 16px !important;
padding-left: 3rem !important;
}
.ui.attached.segment .ui.form .min_title{
font-size: 14px !important;
margin-bottom: 2rem !important;
}
.ui.attached.segment .ui.form .min_title .width48{
width: 48.5% !important;
}
.ui.attached.segment .ui.form .min_title .width80{
width: 80.7% !important;
}
.tooltip-wati-count {
display: flex;
align-items: center;
@@ -1301,6 +1316,159 @@ i.SUCCEEDED {
max-height: 500px;
overflow: auto;
}

.border-according {
border: 1px solid #dfe1e6;
.padding0 {
padding: 0 !important;
}
.according-panel-heading {
box-sizing: border-box;
padding: 8px 16px;
color: #252b3a;
background-color: #f2f5fc;
line-height: 1.5;
cursor: pointer;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
.accordion-panel-title {
margin-top: 0;
margin-bottom: 0;
color: #252b3a;
.accordion-panel-title-content {
vertical-align: middle;
display: inline-block;
width: calc(100% - 32px);
cursor: default;
.redo-color {
color: #3291F8;
}
.ti-action-menu-item:not(:last-child) {
margin-right: 10px;
padding-right: 11px;
text-decoration: none !important;
color: #526ecc;
cursor: pointer;
display: inline-block;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
user-select: none;
position: relative;
}
.ti-action-menu-item:not(:last-child):after {
content: "";
display: inline-block;
position: absolute;
height: 12px;
right: 0;
top: 50%;
-webkit-transform: translateY(-6px);
-ms-transform: translateY(-6px);
-o-transform: translateY(-6px);
transform: translateY(-6px);
border-right: 1px solid #dfe1e6;
}
.acc-margin-bottom {
margin-bottom: 5px;
}
.title_text {
font-size: 12px;
}
.ac-display-inblock {
display: inline-block;
.cti-mgRight-sm {
margin-right: 8px;
}
}
.uc-accordionTitle-black {
color: #333;
}
}
}
}
.content-pad {
padding: 15px 35px;
.dataset_nowrap_two_line{
word-wrap: break-word;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
line-clamp: 2;
-webkit-line-clamp: 2;
text-overflow: -o-ellipsis-lastline;
max-height: 50px;
}
.tab_2_content {
margin-left: 10px;
.ac-grid {
display: block;
*zoom: 1;
.ac-grid-col {
width: 50%;
float: left;
.ti-form {
text-align: left;
max-width: 100%;
vertical-align: middle;
tbody {
font-size: 12px;
vertical-align: inherit;
tr {
vertical-align: inherit;
.td{
vertical-align: top;
white-space: normal;
padding: 0;
}
.th{padding: 0;}
.ti-text-form-label {

padding-bottom: 20px;
padding-right: 20px;
color: #8a8e99;
font-size: 12px;
white-space: nowrap !important;
width: 80px;
line-height: 30px;
}
.text-width80 {
width: 100px;
line-height: 30px;
}
.ti-text-form-content {
line-height: 30px;
padding-bottom: 20px;
.text-span {
width: 450px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.text-span-new {
width: 800px;
overflow: hidden;
text-overflow: ellipsis;
height: 20%;
word-break: break-all;
}
}
}
}
}
}
}
}
}
}

.chang-email .content {
display: block;
width: 100%;
@@ -1314,4 +1482,4 @@ i.SUCCEEDED {
padding: 1rem 1rem;
border-top: 1px solid rgba(34,36,38,.15);
text-align: right;
}
}

+ 8
- 0
web_src/vuepages/pages/notebook/debug/index.vue View File

@@ -343,6 +343,10 @@ export default {
if(err.response.status===403 && err.response.data.code===1 ){
location.href=`${AppSubUrl}/authentication/wechat/bind`
}
if(err.response.status===401){
location.href=`${AppSubUrl}/user/login?redirect_to=${location.origin}${location.pathname}?type=login`
return
}
this.btnStatus[index]=0
this.alertCb = false
Message.error(err)
@@ -407,6 +411,10 @@ export default {
this.fileInfo.project_name = selfData.getAttribute('data-project')
this.fileInfo.sign_name = selfData.getAttribute('data-name')
let that = this;
if(new URLSearchParams(window.location.search).get("type")==='login'){
that.getNotebookInfo()
that.dialogVisible = true;
}
document
.querySelector("#notebook-debug")
.addEventListener("click", function () {


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

@@ -29,7 +29,11 @@ const getJobTypeLink = (record, type) => {
const cloudbrain = type === 'INCREASE' ? record.Action?.Cloudbrain : record.Cloudbrain;
switch (cloudbrain?.JobType) {
case 'DEBUG':
if (cloudbrain.ComputeResource === 'CPU/GPU') {
console.log("cloudbrain")
if (cloudbrain.Type === 2) {
link += `/grampus/notebook/${cloudbrain.ID}`;
}
else if (cloudbrain.ComputeResource === 'CPU/GPU') {
link += `/cloudbrain/${cloudbrain.ID}`;
} else {
link += `/modelarts/notebook/${cloudbrain.ID}`;


Loading…
Cancel
Save