Browse Source

提交代码。

Signed-off-by: zouap <zouap@pcl.ac.cn>
tags/v1.21.12.1^2
zouap 4 years ago
parent
commit
baa59a310a
14 changed files with 1152 additions and 282 deletions
  1. +9
    -4
      models/cloudbrain.go
  2. +7
    -2
      modules/modelarts/modelarts.go
  3. +75
    -0
      modules/storage/obs.go
  4. +5
    -0
      options/locale/locale_en-US.ini
  5. +6
    -0
      options/locale/locale_zh-CN.ini
  6. +3
    -0
      routers/api/v1/api.go
  7. +49
    -13
      routers/api/v1/repo/modelarts.go
  8. +75
    -10
      routers/repo/modelarts.go
  9. +3
    -0
      routers/routes/routes.go
  10. +2
    -2
      templates/repo/cloudbrain/index.tmpl
  11. +61
    -55
      templates/repo/modelarts/trainjob/index.tmpl
  12. +18
    -75
      templates/repo/modelarts/trainjob/new.tmpl
  13. +262
    -121
      templates/repo/modelarts/trainjob/show.tmpl
  14. +577
    -0
      templates/repo/modelarts/trainjob/version_new.tmpl

+ 9
- 4
models/cloudbrain.go View File

@@ -73,7 +73,7 @@ type Cloudbrain struct {
VersionName string `xorm:"INDEX"`
Uuid string
DatasetName string
VersionCount int64 `xorm:"INDEX DEFAULT 1"`
VersionCount int `xorm:"INDEX DEFAULT 1"`
IsLatestVersion string
CommitID string
FatherVersionName string
@@ -971,7 +971,7 @@ func Cloudbrains(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
return cloudbrains, count, nil
}

func CloudbrainsVersionList(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
func CloudbrainsVersionList(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int, error) {
sess := x.NewSession()
defer sess.Close()

@@ -1034,7 +1034,7 @@ func CloudbrainsVersionList(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64,
}
sess.Close()

return cloudbrains, count, nil
return cloudbrains, int(count), nil
}

func CreateCloudbrain(cloudbrain *Cloudbrain) (err error) {
@@ -1066,6 +1066,11 @@ func GetRepoCloudBrainByJobID(repoID int64, jobID string) (*Cloudbrain, error) {
return getRepoCloudBrain(cb)
}

func GetRepoCloudBrainByJobIDAndVersionName(repoID int64, jobID string, versionName string) (*Cloudbrain, error) {
cb := &Cloudbrain{JobID: jobID, RepoID: repoID, VersionName: versionName}
return getRepoCloudBrain(cb)
}

func GetCloudbrainByJobID(jobID string) (*Cloudbrain, error) {
cb := &Cloudbrain{JobID: jobID}
return getRepoCloudBrain(cb)
@@ -1105,7 +1110,7 @@ func SetTrainJobStatusByJobID(jobID string, status string, duration int64, train
return
}

func SetVersionCountAndLatestVersionByJobIDAndVersionName(jobID string, versionName string, versionCount int64, isLatestVersion string) (err error) {
func SetVersionCountAndLatestVersionByJobIDAndVersionName(jobID string, versionName string, versionCount int, isLatestVersion string) (err error) {
cb := &Cloudbrain{JobID: jobID, VersionName: versionName, VersionCount: versionCount, IsLatestVersion: isLatestVersion}
_, err = x.Cols("version_Count", "is_latest_version").Where("cloudbrain.job_id=? AND cloudbrain.version_name=?", jobID, versionName).Update(cb)
return


+ 7
- 2
modules/modelarts/modelarts.go View File

@@ -49,6 +49,7 @@ const (
NotLatestVersion = "0"
ComputeResource = "NPU"
InitFatherVersionName = "V0001"
VersionCount = 1

SortByCreateTime = "create_time"
ConfigTypeCustom = "custom"
@@ -65,6 +66,7 @@ type GenerateTrainJobReq struct {
Description string
CodeObsPath string
BootFile string
BootFileUrl string
DataUrl string
TrainUrl string
FlavorCode string
@@ -79,6 +81,7 @@ type GenerateTrainJobReq struct {
BranchName string
FatherVersionName string
FlavorName string
VersionCount int
}

type GenerateTrainJobVersionReq struct {
@@ -87,6 +90,7 @@ type GenerateTrainJobVersionReq struct {
Description string
CodeObsPath string
BootFile string
BootFileUrl string
DataUrl string
TrainUrl string
FlavorCode string
@@ -208,7 +212,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
Config: models.Config{
WorkServerNum: req.WorkServerNumber,
AppUrl: req.CodeObsPath,
BootFileUrl: req.BootFile,
BootFileUrl: req.BootFileUrl,
DataUrl: req.DataUrl,
EngineID: req.EngineID,
TrainUrl: req.TrainUrl,
@@ -259,6 +263,7 @@ func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error
Description: req.Description,
WorkServerNumber: req.WorkServerNumber,
FlavorName: req.FlavorName,
VersionCount: req.VersionCount,
})

if err != nil {
@@ -275,7 +280,7 @@ func GenerateTrainJobVersion(ctx *context.Context, req *GenerateTrainJobVersionR
Config: models.TrainJobVersionConfig{
WorkServerNum: req.WorkServerNumber,
AppUrl: req.CodeObsPath,
BootFileUrl: req.BootFile,
BootFileUrl: req.BootFileUrl,
DataUrl: req.DataUrl,
EngineID: req.EngineID,
TrainUrl: req.TrainUrl,


+ 75
- 0
modules/storage/obs.go View File

@@ -389,8 +389,75 @@ func GetObsListObject(jobName, parentDir string) ([]FileInfo, error) {
}
fileName = str1[len(str1)-2]
isDir = true
<<<<<<< HEAD
nextParentDir = fileName
if fileName == parentDir || (fileName+"/") == setting.OutPutPath {
=======
if parentDir == "" {
nextParentDir = fileName
} else {
nextParentDir = parentDir + "/" + fileName
}

if fileName == strPrefix[len(strPrefix)-1] || (fileName+"/") == setting.OutPutPath {
>>>>>>> origin/liuzx_trainjob
continue
}
} else {
//files in next level dir
if len(str1)-len(strPrefix) > 1 {
continue
}
fileName = str1[len(str1)-1]
isDir = false
nextParentDir = parentDir
}
fileInfo := FileInfo{
ModTime: val.LastModified.Format("2006-01-02 15:04:05"),
FileName: fileName,
Size: val.Size,
IsDir: isDir,
<<<<<<< HEAD
=======
ParenDir: nextParentDir,
}
fileInfos = append(fileInfos, fileInfo)
}
return fileInfos, err
} else {
if obsError, ok := err.(obs.ObsError); ok {
log.Error("Code:%s, Message:%s", obsError.Code, obsError.Message)
}
return nil, err
}
}

func GetVersionObsListObject(jobName, parentDir string) ([]FileInfo, error) {
input := &obs.ListObjectsInput{}
input.Bucket = setting.Bucket
input.Prefix = strings.TrimPrefix(path.Join(setting.TrainJobModelPath, jobName, setting.OutPutPath, parentDir), "/")
strPrefix := strings.Split(input.Prefix, "/")
output, err := ObsCli.ListObjects(input)
fileInfos := make([]FileInfo, 0)
if err == nil {
for _, val := range output.Contents {
str1 := strings.Split(val.Key, "/")
var isDir bool
var fileName, nextParentDir string
if strings.HasSuffix(val.Key, "/") {
//dirs in next level dir
if len(str1)-len(strPrefix) > 2 {
continue
}
fileName = str1[len(str1)-2]
isDir = true
if parentDir == "" {
nextParentDir = fileName
} else {
nextParentDir = parentDir + "/" + fileName
}

if fileName == strPrefix[len(strPrefix)-1] || (fileName+"/") == setting.OutPutPath {
continue
}
} else {
@@ -402,11 +469,13 @@ func GetObsListObject(jobName, parentDir string) ([]FileInfo, error) {
isDir = false
nextParentDir = parentDir
}

fileInfo := FileInfo{
ModTime: val.LastModified.Format("2006-01-02 15:04:05"),
FileName: fileName,
Size: val.Size,
IsDir: isDir,
>>>>>>> origin/liuzx_trainjob
ParenDir: nextParentDir,
}
fileInfos = append(fileInfos, fileInfo)
@@ -445,8 +514,14 @@ func ObsGenMultiPartSignedUrl(uuid string, uploadId string, partNumber int, file

func GetObsCreateSignedUrlByBucketAndKey(bucket, key string) (string, error) {
input := &obs.CreateSignedUrlInput{}
<<<<<<< HEAD
input.Bucket = bucket
input.Key = key
=======
input.Bucket = setting.Bucket
input.Key = strings.TrimPrefix(path.Join(setting.TrainJobModelPath, jobName, setting.OutPutPath, parentDir, fileName), "/")

>>>>>>> origin/liuzx_trainjob
input.Expires = 60 * 60
input.Method = obs.HttpMethodGet
comma := strings.LastIndex(key, "/")


+ 5
- 0
options/locale/locale_en-US.ini View File

@@ -792,6 +792,10 @@ total_count_get_error=Can not get the total page.
last_update_time_error=Can not get the last updated time.
get_repo_stat_error=Can not get the statistics of the repository.
get_repo_info_error=Can not get the information of the repository.
modelarts.status=Status
modelarts.createtime=CreateTime
modelarts.version_nums = Version Nums
modelarts.computing_resources=compute Resources
modelarts.notebook=Debug Task
modelarts.train_job=Train Task
modelarts.train_job.new_debug= New Debug Task
@@ -820,6 +824,7 @@ modelarts.train_job.AI_driver=AI Engine
modelarts.train_job.start_file=Start File
modelarts.train_job.boot_file_helper=The startup file is the entry file that your program executes, and it must be a file ending in .py
modelarts.train_job.dataset=Dataset
modelarts.code_version = Code Version
modelarts.train_job.run_parameter=Run Parameter
modelarts.train_job.add_run_parameter=Add Run Parameter
modelarts.train_job.parameter_name=Parameter Name


+ 6
- 0
options/locale/locale_zh-CN.ini View File

@@ -794,6 +794,11 @@ total_count_get_error=查询总页数失败。
last_update_time_error=查询最新更新时间失败。
get_repo_stat_error=查询当前仓库的统计信息失败。
get_repo_info_error=查询当前仓库信息失败。

modelarts.status=状态
modelarts.createtime=创建时间
modelarts.version_nums=版本数
modelarts.computing_resources=计算资源
modelarts.notebook=调试任务
modelarts.train_job=训练任务
modelarts.train_job.new_debug=新建调试任务
@@ -823,6 +828,7 @@ modelarts.train_job.start_file=启动文件
modelarts.train_job.boot_file_helper=启动文件是您程序执行的入口文件,必须是以.py结尾的文件。
modelarts.train_job.boot_file_place=填写启动文件路径,默认为train.py
modelarts.train_job.dataset=数据集
modelarts.code_version=代码版本
modelarts.train_job.run_parameter=运行参数
modelarts.train_job.add_run_parameter=增加运行参数
modelarts.train_job.parameter_name=参数名


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

@@ -875,6 +875,9 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/:jobid", func() {
m.Get("", repo.GetModelArtsTrainJob)
m.Get("/log", repo.TrainJobGetLog)
m.Group("/:version-name", func() {
m.Get("", repo.GetModelArtsTrainJobVersion)
})
})
})
}, reqRepoReader(models.UnitTypeCloudBrain))


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

@@ -6,12 +6,13 @@
package repo

import (
"net/http"
"strconv"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/modelarts"
"net/http"
"strconv"
)

func GetModelArtsNotebook(ctx *context.APIContext) {
@@ -72,9 +73,44 @@ func GetModelArtsTrainJob(ctx *context.APIContext) {
}

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

}

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

jobID := ctx.Params(":jobid")
versionName := ctx.Params(":version-name")
repoID := ctx.Repo.Repository.ID
job, err := models.GetRepoCloudBrainByJobIDAndVersionName(repoID, jobID, versionName)
if err != nil {
ctx.NotFound(err)
return
}
result, err := modelarts.GetTrainJob(jobID, strconv.FormatInt(job.VersionID, 10))
if err != nil {
ctx.NotFound(err)
return
}

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

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

}
@@ -94,7 +130,7 @@ func TrainJobGetLog(ctx *context.APIContext) {
if order != modelarts.OrderDesc && order != modelarts.OrderAsc {
log.Error("order(%s) check failed", order)
ctx.JSON(http.StatusBadRequest, map[string]interface{}{
"err_msg": "order check failed",
"err_msg": "order check failed",
})
return
}
@@ -103,7 +139,7 @@ func TrainJobGetLog(ctx *context.APIContext) {
if err != nil {
log.Error("GetCloudbrainByJobID(%s) failed:%v", jobID, err.Error())
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err_msg": "GetCloudbrainByJobID failed",
"err_msg": "GetCloudbrainByJobID failed",
})
return
}
@@ -112,16 +148,16 @@ func TrainJobGetLog(ctx *context.APIContext) {
if err != nil {
log.Error("GetTrainJobLog(%s) failed:%v", jobID, err.Error())
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"err_msg": "GetTrainJobLog failed",
"err_msg": "GetTrainJobLog failed",
})
return
}

ctx.JSON(http.StatusOK, map[string]interface{}{
"JobID": jobID,
"StartLine": result.StartLine,
"EndLine": result.EndLine,
"Content": result.Content,
"Lines": result.Lines,
"JobID": jobID,
"StartLine": result.StartLine,
"EndLine": result.EndLine,
"Content": result.Content,
"Lines": result.Lines,
})
}

+ 75
- 10
routers/repo/modelarts.go View File

@@ -620,6 +620,7 @@ func TrainJobNewVersion(ctx *context.Context) {
func trainJobNewVersionDataPrepare(ctx *context.Context) error {
ctx.Data["PageIsCloudBrain"] = true
var jobID = ctx.Params(":jobid")
// var versionName = ctx.Params(":version-name")
var versionName = ctx.Query("version_name")

task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName)
@@ -683,6 +684,9 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error {
ctx.Data["params"] = task.Parameters
ctx.Data["work_server_number"] = task.WorkServerNumber
ctx.Data["flavor_name"] = task.FlavorName
ctx.Data["uuid"] = task.Uuid
ctx.Data["flavor_code"] = task.FlavorCode
ctx.Data["engine_id"] = task.EngineID

configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom)
if err != nil {
@@ -715,6 +719,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
branch_name := form.BranchName
isLatestVersion := modelarts.IsLatestVersion
FlavorName := form.FlavorName
VersionCount := modelarts.VersionCount

if err := paramCheckCreateTrainJob(form); err != nil {
log.Error("paramCheckCreateTrainJob failed:(%v)", err)
@@ -841,13 +846,21 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
return
}
}
//将引擎id转化为引擎名称
FlavorName, err = getFlavorNameByEngineID(engineID)
if err != nil {
log.Error("getFlavorNameByEngineID(%s) failed:%v", engineID, err.Error())
ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form)
return
}

req := &modelarts.GenerateTrainJobReq{
JobName: jobName,
DataUrl: dataPath,
Description: description,
CodeObsPath: codeObsPath,
BootFile: codeObsPath + bootFile,
BootFileUrl: codeObsPath + bootFile,
BootFile: bootFile,
TrainUrl: outputObsPath,
FlavorCode: flavorCode,
WorkServerNumber: workServerNumber,
@@ -862,6 +875,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
Params: form.Params,
FatherVersionName: modelarts.InitFatherVersionName,
FlavorName: FlavorName,
VersionCount: VersionCount,
}

err = modelarts.GenerateTrainJob(ctx, req)
@@ -910,9 +924,8 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm)
func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) {
ctx.Data["PageIsTrainJob"] = true
var jobID = ctx.Params(":jobid")
// var fatherVersionName = ctx.Query("versionName")
// jobID = "19373"
// versionName = "V0009"
// var versionName = ctx.Params(":version-name")
var versionName = ctx.Query("version_name")

jobName := form.JobName
uuid := form.Attachment
@@ -931,7 +944,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath
dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/"
branch_name := form.BranchName
fatherVersionName := form.VersionName
fatherVersionName := versionName
FlavorName := form.FlavorName

if err := paramCheckCreateTrainJob(form); err != nil {
@@ -1057,8 +1070,14 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
return
}
}
// JobVersionName := "V0001"
// PreVersionId := int64(67646)
//将引擎id转化为引擎名称
FlavorName, err = getFlavorNameByEngineID(engineID)
if err != nil {
log.Error("getFlavorNameByEngineID(%s) failed:%v", engineID, err.Error())
ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobVersionNew, &form)
return
}

task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, fatherVersionName)
if err != nil {
log.Error("GetCloudbrainByJobIDAndVersionName(%s) failed:%v", jobID, err.Error())
@@ -1070,7 +1089,8 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
DataUrl: dataPath,
Description: description,
CodeObsPath: codeObsPath,
BootFile: codeObsPath + bootFile,
BootFileUrl: codeObsPath + bootFile,
BootFile: bootFile,
TrainUrl: outputObsPath,
FlavorCode: flavorCode,
WorkServerNumber: workServerNumber,
@@ -1127,6 +1147,19 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ
ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
}

func getFlavorNameByEngineID(engineID int) (FlavorName string, err error) {
if engineID == 121 {
FlavorName = "TensorFlow-1.15"
return FlavorName, nil
} else if engineID == 122 {
FlavorName = "Mindspore-1.3"
return FlavorName, nil
} else {
log.Error("getFlavorName failed:%v", errors.New("getFlavorName failed"))
return "getFlavorName failed:", errors.New("getFlavorName failed")
}
}

// readDir reads the directory named by dirname and returns
// a list of directory entries sorted by filename.
func readDir(dirname string) ([]os.FileInfo, error) {
@@ -1219,6 +1252,10 @@ func TrainJobShow(ctx *context.Context) {

var jobID = ctx.Params(":jobid")
task, err := models.GetCloudbrainByJobID(jobID)
if err != nil {
ctx.ServerError("GetCloudbrainByJobID faild", err)
return
}

repo := ctx.Repo.Repository
page := ctx.QueryInt("page")
@@ -1290,8 +1327,8 @@ func TrainJobShow(ctx *context.Context) {
ctx.Data["task"] = task
ctx.Data["jobID"] = jobID
ctx.Data["result"] = result
ctx.Data["VersionListTasks"] = VersionListTasks
ctx.Data["VersionLisCount"] = VersionListCount
ctx.Data["version_list_task"] = VersionListTasks
ctx.Data["version_list_count"] = VersionListCount
ctx.HTML(http.StatusOK, tplModelArtsTrainJobShow)
}

@@ -1544,6 +1581,34 @@ func TrainJobShowModels(ctx *context.Context) {
ctx.HTML(200, tplModelArtsTrainJobShowModels)
}

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

jobID := ctx.Params(":jobid")
parentDir := ctx.Query("parentDir")
versionName := ctx.Query("version_name")
dirArray := strings.Split(parentDir, "/")
task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName)
if err != nil {
log.Error("no such job!", ctx.Data["msgID"])
ctx.ServerError("no such job:", err)
return
}
parentDir = versionName
models, err := storage.GetVersionObsListObject(task.JobName, parentDir)
if err != nil {
log.Info("get TrainJobListModel failed:", err)
ctx.ServerError("GetVersionObsListObject:", err)
return
}

ctx.Data["Path"] = dirArray
ctx.Data["Dirs"] = models
ctx.Data["task"] = task
ctx.Data["JobID"] = jobID
ctx.HTML(200, tplModelArtsTrainJobShowModels)
}

func TrainJobDownloadModel(ctx *context.Context) {
parentDir := ctx.Query("parentDir")
fileName := ctx.Query("fileName")


+ 3
- 0
routers/routes/routes.go View File

@@ -997,8 +997,11 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/log", reqRepoCloudBrainReader, repo.TrainJobGetLog)
m.Get("/models", reqRepoCloudBrainReader, repo.TrainJobShowModels)
m.Get("/download_model", reqRepoCloudBrainReader, repo.TrainJobDownloadModel)
m.Get("/version_models", reqRepoCloudBrainReader, repo.TrainJobVersionShowModels)
// m.Group("/:version-name", func() {
m.Get("/create_version", reqRepoCloudBrainReader, repo.TrainJobNewVersion)
m.Post("/create_version", reqRepoCloudBrainWriter, bindIgnErr(auth.CreateModelArtsTrainJobForm{}), repo.TrainJobCreateVersion)
// })
m.Post("/stop_version", reqRepoCloudBrainWriter, repo.TrainJobVersionStop)
m.Post("/del_version", reqRepoCloudBrainWriter, repo.TrainJobVersionDel)
})


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

@@ -239,8 +239,8 @@

<div class="column">
<div class="ui blue small menu compact selectcloudbrain">
<a class="active item">{{$.i18n.Tr "repo.modelarts.notebook"}}</a>
<!-- <a class="item" href="{{.RepoLink}}/modelarts">训练任务</a> -->
<a class="active item" href="{{.RepoLink}}/cloudbrain">{{$.i18n.Tr "repo.modelarts.notebook"}}</a>
<a class="item" href="{{.RepoLink}}/modelarts/train-job">{{$.i18n.Tr "repo.modelarts.train_job"}}</a>
</div>
</div>
<div class="column right aligned">


+ 61
- 55
templates/repo/modelarts/trainjob/index.tmpl View File

@@ -180,6 +180,12 @@
cursor: pointer;
pointer-events: none;
}
.fontsize14{
font-size: 14px;
}
.padding0{
padding: 0 !important;
}
</style>

<!-- 弹窗 -->
@@ -232,14 +238,14 @@

<div class="column">
<div class="ui blue small menu compact selectcloudbrain">
<a class="item" href="{{.RepoLink}}/modelarts/notebook">{{$.i18n.Tr "repo.modelarts.notebook"}}</a>
<a class="item" href="{{.RepoLink}}/cloudbrain">{{$.i18n.Tr "repo.modelarts.notebook"}}</a>
<a class="active item" href="{{.RepoLink}}/modelarts/train-job">{{$.i18n.Tr "repo.modelarts.train_job"}}</a>
<a class="item" href="{{.RepoLink}}/modelmanage/">模型管理</a>
</div>
</div>
<div class="column right aligned">
<div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;">
<!-- <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;">
{{svg "octicon-server" 16}}
<div class="default text" style="color: rgba(0,0,0,.87);"> Ascend NPU</div>
<i class="dropdown icon"></i>
@@ -247,7 +253,7 @@
<a class="item" href="{{.RepoLink}}/cloudbrain" data-value="11">CPU / GPU</a>
<a class="item" href="{{.RepoLink}}/modelarts/notebook" data-value="22">Ascend NPU</a>
</div>
</div>
</div> -->
{{if .Permission.CanWrite $.UnitTypeCloudBrain}}
<a class="ui green button" href="{{.RepoLink}}/modelarts/train-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_train"}}</a>{{end}}
</div>
@@ -279,20 +285,29 @@
<!-- 表头 -->
<div class="ui grid stackable" style="background: #f0f0f0;;">
<div class="row">
<div class="five wide column">
<div class="three wide column padding0">
<span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span>
</div>
<div class="three wide column">
<span>{{$.i18n.Tr "repo.cloudbrain_status_createtime"}}</span>
<div class="one wide column text center padding0">
<span style="margin:0 6px">{{$.i18n.Tr "repo.modelarts.version_nums"}}</span>
</div>
<div class="two wide column text center padding0">
<span>{{$.i18n.Tr "repo.modelarts.status"}}</span>
</div>
<div class="two wide column text center padding0">
<span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span>
</div>
<div class="two wide column">
<div class="two wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span>
</div>
<div class="one wide column text center">
<div class="two wide column text center padding0">
<span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span>
</div>
<div class="one wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span>
</div>
<div class="five wide column text center">
<span style="margin-left: 6rem;">{{$.i18n.Tr "repo.cloudbrain_operate"}}</span>
<div class="three wide column text center padding0">
<span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span>
</div>

</div>
@@ -306,38 +321,44 @@
<div class="row">
<!-- 任务名 -->
<div class="five wide column">
<a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.JobName}}" style="font-size: 15px;">
<div class="three wide column padding0">
<a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.JobName}}" style="font-size: 12px;">
<span class="fitted" style="vertical-align: middle;">{{svg "octicon-tasklist" 16}}</span>
<span class="fitted" style="width: 90%;vertical-align: middle;margin-left: 0.4rem;">{{.JobName}}</span>
</a>
</div>

<div class="three wide column">
<!--任务状态 -->
<!-- <span class="ui compact button job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}">
{{.Status}}
</span> -->
<!-- 版本数量 -->
<div class="one wide column text center padding0">
<span>{{.VersionCount}} </span>
</div>
<!-- 任务状态 -->
<div class="two wide column text center padding0">
<span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}">
<span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span>
</span>
</div>
<!-- 任务创建时间 -->
<div class="two wide column text center padding0">
<span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span>
</div>
<!-- <div class="two wide column">
<span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}">
<span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span>
</span>
<!-- 任务创建时间 -->
<span style="font-size: 12px;margin-left: 0.4rem;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span>
</div> -->
<!-- 任务运行时间 -->
<div class="two wide column text center padding0">
<span style="font-size: 12px;" id="duration-{{.JobID}}"></span>
</div>

<div class="two wide column">
<!--任务状态 -->
<!-- <span class="ui compact button job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}">
{{.Status}}
</span> -->
<span id="duration-{{.JobID}}"></span>
<!-- 任务创建时间 -->
<!-- <span style="font-size: 12px;margin-left: 0.4rem;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> -->
<!-- 计算资源 -->
<div class="two wide column text center padding0">
<span style="font-size: 12px;">{{.ComputeResource}}</span>
</div>
<div class="one wide column text center">
<!-- 创建者 -->
<div class="one wide column text center padding0">
{{if .User.Name}}
<a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a>
{{else}}
@@ -345,56 +366,41 @@
{{end}}
</div>

<div class="five wide column text right">
<div class="three wide column text center padding0">
<div class="ui compact buttons">
<!-- <a class="ui basic blue button" href="{{$.Link}}/{{.JobID}}">
查看
</a>
<a class="ui basic {{if not .CanDebug}}disabled {{else}}blue {{end}}button" href="{{$.Link}}/{{.JobID}}/debug" target="_blank">
调试
</a> -->
<form id="stopForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/stop" method="post" style="margin-left:-1px;">
<form id="stopForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/stop" method="post">
{{$.CsrfTokenHtml}}
{{if $.Permission.CanWrite $.UnitTypeCloudBrain}}
<a id="stop-model-debug-{{.JobID}}" class="ui basic {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}}blue {{end}}button" onclick="document.getElementById('stopForm-{{.JobID}}').submit();">
<a style="padding: 0.5rem 1rem;" id="stop-model-debug-{{.JobID}}" class="ui basic {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED"}}disabled {{else}}blue {{end}}button" onclick="document.getElementById('stopForm-{{.JobID}}').submit();">
{{$.i18n.Tr "repo.stop"}}
</a>
{{else}}
<a class="ui basic disabled button" onclick="document.getElementById('stopForm-{{.JobID}}').submit();">
<a style="padding: 0.5rem 1rem;" class="ui basic disabled button" onclick="document.getElementById('stopForm-{{.JobID}}').submit();">
{{$.i18n.Tr "repo.stop"}}
</a>
{{end}}
</form>
</div>
<div class="ui compact buttons" style="margin-right:10px;">
<div class="ui compact buttons">
<!-- 模型下载 -->
<a class="ui basic blue button" href="{{$.Link}}/{{.JobID}}/models" target="_blank">
<a style="padding: 0.5rem;" class="ui basic blue button" href="{{$.Link}}/{{.JobID}}/models" target="_blank">
{{$.i18n.Tr "repo.model_download"}}
</a>
<!-- 接收结果 -->
<!-- <iframe src="" frameborder="0" name="iframeContent" style="display: none;"></iframe>
<a class="imageBtn ui basic {{if not .CanDebug}}disabled {{else}}blue {{end}}button" value="{{.CanDebug}}">提交镜像</a> -->
</div>
<!-- 删除任务 -->
<form class="ui compact buttons" id="delForm-{{.JobID}}" action="{{$.Link}}/{{.JobID}}/del" method="post">
{{$.CsrfTokenHtml}}
{{if $.Permission.CanWrite $.UnitTypeCloudBrain}}
<a id="model-delete-{{.JobID}}" class="ui compact {{if or (eq .Status "RUNNING") (eq .Status "INIT") (eq .Status "CREATING") (eq .Status "WAITING") }}disabled {{else}}red {{end}}button" onclick="assertDelete(this)" style="border-radius: .28571429rem;">
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-delete-{{.JobID}}" class="ui compact {{if or (eq .Status "RUNNING") (eq .Status "INIT") (eq .Status "CREATING") (eq .Status "WAITING") }}disabled {{else}}red {{end}}button" onclick="assertDelete(this)" style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
</a>
{{else}}
<a class="ui compact disabled button" onclick="assertDelete(this)" style="border-radius: .28571429rem;">
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" class="ui compact disabled button" onclick="assertDelete(this)" style="border-radius: .28571429rem;">
{{$.i18n.Tr "repo.delete"}}
</a>
{{end}}
</form>
</div>



</div>
</div>
{{end}} {{template "base/paginate" .}}


+ 18
- 75
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -163,18 +163,22 @@
<label for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label>
<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, 256)"></textarea>
</div>
<!-- <h4 class="ui dividing header">{{.i18n.Tr "repo.modelarts.train_job.parameter_setting"}}</h4>
<div class="inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.fast_parameter_setting"}}</label>
<span>
{{.i18n.Tr "repo.modelarts.train_job.fast_parameter_setting_config"}}
<a class="item active parameter_config">{{.i18n.Tr "repo.modelarts.train_job.fast_parameter_setting_config_link"}}</a>
</span>
</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 min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80" id="code_version" name="branch_name">
{{range $k, $v :=.Branches}}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
</select>
</div>



<div class="required unite min_title inline fields" style="width: 90%;">
<label>{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
<div class="field" style="flex: 1.5;">
@@ -183,52 +187,19 @@
<option value="{{.Value}}">{{.Value}}</option>
{{end}}
</select>

</div>

<div class="field" style="flex: 2;">
<select class="ui dropdown width" id="trainjob_engine_versions" style='width: 100%;' name="engine_id">
{{range .engine_versions}}
<option name="engine_id" value="{{.ID}}">{{.Value}}</option>
{{end}}
</select>
</div>

</div>
<!-- <div class="required inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.algorithm_origin"}}</label>
<div class="ui top attached tabular menu">
<a class="item active" data-tab="frame">{{svg "octicon-repo" 16}}{{.i18n.Tr "repo.modelarts.train_job.frames"}}</a>
</div>
<div class="ui bottom attached tab active segment" data-tab="frame">
<div class="required field">
<label>{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}</label>
<div class="two fields">
<div class="field">
<select class="ui search dropdown" id="trainjob_engines" style='width:385px'>
{{range .engines}}
<option value="{{.Value}}">{{.Value}}</option>
{{end}}
</select>
</div>
<div class="field">
<select class="ui search dropdown" id="trainjob_engine_versions" style='width:385px' name="engine_id">
{{range .engine_versions}}
<option name="engine_id" value="{{.ID}}">{{.Value}}</option>
{{end}}
</select>
</div>
</div>
</div>
<div class="inline required field">
<label>{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
<input name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255">
<span>
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i>
</span>
</div>
</div>
</div> -->

<div class="inline unite min_title field required">
<label>{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label>
{{if .bootFile}}
@@ -255,16 +226,12 @@
<div class="inline unite min_title field">
<label>{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label>
<!-- <i class="plus square outline icon"></i> -->
<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;"></div>
<!-- <div class="dynamic field">
</div> -->
</div>

<!-- <h4 class="ui dividing header">{{.i18n.Tr "repo.modelarts.train_job.resource_setting"}}</h4> -->
<div class="required field " style="display: none;">
<label>{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label>
<select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id">
@@ -302,36 +269,12 @@
<label>{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<div class="ui labeled input" style="width: 5%;">
<!-- <span class="min"><i class="minus icon"></i></span> -->
<input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly>
<!-- <span class="add"><i class="plus icon"></i></span> -->
</div>
<!-- <input name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255"> -->
</div>
<!--
<div class="inline field">
<div class="ui save checkbox">
<input name="is_save_para" type="checkbox">
<label>{{.i18n.Tr "repo.modelarts.train_job.query_whether_save_parameter"}}
<span>
<i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.save_helper"}} data-position="right center" data-variation="mini"></i>
</span>
</label>
</div>
</div>
<div class="disabled field" id="save_para">
<div class="field">
<label>{{.i18n.Tr "repo.modelarts.train_job.job_parameter_name"}}</label>
<input name="parameter_template_name" id="parameter_template_name" tabindex="3" autofocus maxlength="255">
</div>
<div class="field">
<label for="parameter_description">{{.i18n.Tr "repo.modelarts.train_job.parameter_description"}}</label>
<textarea id="parameter_description" name="parameter_description" rows="2"></textarea>

</div>
</div>
-->
<div class="inline unite min_title field">
<button class="ui create_train_job green button">


+ 262
- 121
templates/repo/modelarts/trainjob/show.tmpl View File

@@ -1,150 +1,291 @@
{{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);
}
.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: 260px;
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;
color: #8a8e99;
font-size: 12px;
white-space: nowrap;
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 {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

</style>
<div class="repository">
{{template "repo/header" .}}
<div class="repository new repo ui middle very relaxed page grid">
<div class="column">
{{template "base/alert" .}}
<h4 class="ui top attached header">
<div class="ui two column grid">
<div class="column">
{{$.i18n.Tr "repo.modelarts.version_manage"}}
<div class="ui container">
<h4 class="ui header" id="vertical-segment">
<a href="javascript:window.history.back();"><i class="arrow left icon"></i>返回</a>
</h4>
{{range .version_list_task}}
<div class="ui accordion">
<div class="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 style="float: right;">
<button>创建模型</button>
<a href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/create_version?version_name={{.VersionName}}">修改</a>
<button>停止</button>
<button>删除</button>
</div>
<div class="ac-display-inblock title_text acc-margin-bottom">
<span class="cti-mgRight-sm">2021/11/08 19:35:19</span>
<span class="cti-mgRight-sm"> 当前版本:{{.VersionName}}</span>
<span class="cti-mgRight-sm"> 父版本:{{.FatherVersionName}}</span>
<span class="cti-mgRight-sm ac-text-normal title_text">状态
<span><i id="icon" style="vertical-align: middle;" class=""></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">运行成功</span></span>
</span>
<span class="ac-text-normal title_text">运行时间:</span>
<span class="cti-mgRight-sm uc-accordionTitle-black">01:09:50</span>
<span data-tooltip="刷新" data-inverted=""><i class="redo icon"></i></span>

</div>
</span>
</span>
</div>
<div class="column right aligned">
<a href="javascript:window.history.back();">{{svg "octicon-reply" 16}}{{$.i18n.Tr "repo.modelarts.back"}}</a>
</div>
</div>
<div class="content accordion-border">
<div class="content-pad">
<div class="ui pointing secondary menu">
<a class="active item" data-tab="first">配置信息</a>
<a class="item" data-tab="second">日志文件</a>
<a class="item" data-tab="third">模型下载</a>
</div>
</div>
</h4>
<div class="ui tab" 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">
任务名称
</td>

<div class="ui attached segment">
<div class="ui style accordion">
<div class="title active">
<i class="dropdown icon"></i>
{{$.i18n.Tr "repo.modelarts.train_job.version"}}
</div>
<div class="content active">
<div class="ui container">
<div class="ui top attached tabular menu">
<a class="item active" data-tab="configs">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a>
<a class="item logs" data-tab="logs">{{$.i18n.Tr "repo.modelarts.log"}}</a>
<!-- <a class="item" data-tab="resources">资源占用情况</a> -->
</div>
<div class="ui bottom attached tab segment active" data-tab="configs">
<div>
<div class="ui yellow segment">
<table class="ui celled striped table">
<thead>
<tr> <th colspan="2"> {{.i18n.Tr "repo.modelarts.train_job.basic_info"}} </th> </tr>
</thead>
<tbody>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.job_name"}} </td>
<td>{{.result.JobName}}</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.job_status"}} </td>
<td>{{.result.Status}}</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.version"}} </td>
<td>{{.result.VersionName}}</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.start_time"}} </td>
<td>{{.result.CreateTime}}</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.dura_time"}} </td>
<td>{{.result.TrainJobDuration}}</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.description"}} </td>
<td>{{.result.Description}}</td>
</tr>
</tbody>
</table>
</div>
<div class="ui green segment">
<table class="ui celled striped table">
<thead>
<tr> <th colspan="2"> {{.i18n.Tr "repo.modelarts.train_job.parameter_setting_info"}} </th> </tr>
</thead>
<tbody>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.AI_driver"}} </td>
<td>{{.result.EngineName}} | {{.result.EngineVersion}}</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.start_file"}}</td>
<td>{{.result.BootFileUrl}}</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.dataset"}} </td>
<td>{{.result.DatasetName}}</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.run_parameter"}} </td>
<td>{{.result.Parameter}}</td>
</tr>
</tbody>
</table>
</div>
<div class="ui blue segment">
<table class="ui celled striped table">
<thead>
<tr> <th colspan="2"> {{.i18n.Tr "repo.modelarts.train_job.resource_setting_info"}} </th> </tr>
</thead>
<tbody>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.resource_pool"}} </td>
<td>{{.result.PoolName}}</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.JobName}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label">
状态
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
{{.Status}}
</div>
</td>
</tr>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label">
开始时间
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
aaa
</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">
作业名称
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
trainjob-d672 | job15b681bc
</div>
</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</td>
<td>{{.result.WorkServerNum}}</td>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label">
作业名称
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
trainjob-d672 | job15b681bc
</div>
</td>
</tr>
<tr>
<td class="four wide"> {{.i18n.Tr "repo.modelarts.train_job.NAS_mount_path"}} </td>
<td>{{.result.NasMountPath}}</td>
<tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label">
作业名称
</td>
<td class="ti-text-form-content">
<div class="text-span text-span-w">
trainjob-d672 | job15b681bc
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="ui bottom attached tab segment" data-tab="logs">
<div class="ui message" style="display: none;">
<div class="header">
</div>
</div>
<div class="ui top attached segment" style="background: #f0f0f0;">
<div class="center aligned">
<label>{{$.i18n.Tr "repo.modelarts.log"}}:</label>
<span class="fitted file_name">{{.log_file_name}}</span>
<input type="hidden" name="file_name" value={{.log_file_name}}>
<input type="hidden" name="start_line" value={{.log.StartLine}}>
<input type="hidden" name="end_line" value={{.log.EndLine}}>
</div>
</div>
<div class="ui attached segment log" style="height: 300px !important; overflow: auto;">
<pre>{{.log.Content}}</pre>
</div>
</div>
</div>
</div>
</div>
<div class="ui tab" data-tab="second">
<div>
<div class="ui message" style="display: none;">
<div class="header"></div>
</div>
<div class="ui top attached segment" style="background: #f0f0f0;">
<div class="center aligned">
<label>{{$.i18n.Tr "repo.modelarts.log"}}:</label>
<!-- <span class="fitted file_name"></span>
<input type="hidden" name="file_name" value>
<input type="hidden" name="start_line" value>
<input type="hidden" name="end_line" value> -->
</div>
</div>
<div class="ui attached segment log" style="height: 300px !important; overflow: auto;">
<pre></pre>
</div>
</div>
</div>
<div class="ui tab" data-tab="third">
<div class="content-pad">
asdasd
</div>
</div>

</div>
</div>
</div>
{{end}}
</div>
</div>
{{template "base/footer" .}}

<script>
console.log({{.version_list_task}})
$('.menu .item').tab()
$('.ui.style.accordion').accordion();
// $('.ui.style.accordion').accordion();

// $(document).ready(function(){
// $('.ui.accordion').accordion({selector:{trigger:'.icon'}});
// });
$(document).ready(function(){
$('.secondary.menu .item').tab();
});
var userName
var repoPath
var jobID


+ 577
- 0
templates/repo/modelarts/trainjob/version_new.tmpl View File

@@ -0,0 +1,577 @@
{{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;

}
.width{
width:100% !important;
}
.width80{
width: 80.7% !important;
margin-left: 10px;
}
.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;"
}
#mask {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
filter: alpha(opacity=60);
background-color: #777;
z-index: 1000;
display: none;
opacity: 0.8;
-moz-opacity: 0.5;
padding-top: 100px;
color: #000000
}
/* 加载圈css效果图 */
#loadingPage {
margin: 200px auto;
width: 50px;
height: 40px;
text-align: center;
font-size: 10px;
display: block;
}
#loadingPage>div {
background-color: green;
height: 100%;
width: 6px;
display: inline-block;
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
animation: sk-stretchdelay 1.2s infinite ease-in-out;
}
#loadingPage .rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
#loadingPage .rect3 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
#loadingPage .rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
#loadingPage .rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
.left2{
margin-left: -2px;
}
@-webkit-keyframes sk-stretchdelay {
0%,
40%,
100% {
-webkit-transform: scaleY(0.4)
}
20% {
-webkit-transform: scaleY(1.0)
}
}
@keyframes sk-stretchdelay {
0%,
40%,
100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}

</style>
<!-- <div class="ui page dimmer">
<div class="ui text loader">{{.i18n.Tr "loading"}}</div>
</div> -->
<div id="mask">
<div id="loadingPage">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>
<div class="repository">
{{template "repo/header" .}}
<div class="ui container">
{{template "base/alert" .}}
<h4 class="ui top attached header">
{{.i18n.Tr "repo.modelarts.train_job.new"}}
</h4>
<div class="ui attached segment">
<!-- equal width -->
<form class="ui form" action="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/create_version" method="post">
{{.CsrfTokenHtml}}
<input type="hidden" name="action" value="update">
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4>
<div class="required unite min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label>
<input type="hidden" style="width: 60%;" name="job_name" id="trainjob_job_name" value="{{.job_name}}">
<input style="width: 60%;" value="{{.job_name}}" tabindex="3" disabled >
</div>
<input type="hidden" name="version_name" value="{{.version_name}}">
<div class="unite min_title inline field">
<label for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</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)"></textarea>
</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 min_title inline field">
<label>{{.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>
{{end}}
{{range $k, $v :=.branches}}
{{if ne $.branch_name $v}}
<option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}}
{{end}}
</select>
</div>



<div class="required unite min_title inline fields" style="width: 90%;">
<label>{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
<div class="field" style="flex: 1.5;">
<select class="ui dropdown width" id="trainjob_engines" >
{{range .engines}}
<option value="{{.Value}}">{{.Value}}</option>
{{end}}
</select>
</div>

<div class="field" style="flex: 2;">
<select class="ui dropdown width" id="trainjob_engine_versions" style='width: 100%;' name="engine_id">
{{if .engine_id}}
<option name="engine_id" value="{{.engine_id}}">{{.engine_id}}</option>
{{end}}
{{range .engine_versions}}
{{if ne $.engine_id .ID}}
<option name="engine_id" value="{{.ID}}">{{.Value}}</option>
{{end}}
{{end}}
</select>

</div>

</div>

<div class="inline unite min_title field required">
<label>{{.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" >
{{else}}
<input style="width: 33.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>
</span>
</div>
<div class="required unite min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.dataset"}}</label>
<select class="ui dropdown width80" id="trainjob_datasets" name="attachment" placeholder="选择数据集">
{{if .dataset_name}}
<option name="attachment" value="{{.uuid}}">{{.dataset_name}}</option>
{{end}}
{{range .attachments}}
<option value="">选择数据集</option>
{{if ne $.uuid .UUID}}
<option name="attachment" value="{{.UUID}}">{{.Attachment.Name}}</option>
{{end}}
{{end}}
</select>
</div>
<div class="inline unite min_title field">
<label>{{.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;"></div>
</div>


<div class="required field " style="display: none;">
<label>{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label>
<select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id">
{{range .resource_pools}}
<option value="{{.ID}}">{{.Value}}</option>
{{end}}
</select>
</div>

<div class="required grouped fields" style="display: none;">
<label for="resource_type">{{.i18n.Tr "repo.modelarts.train_job.resource_type"}}</label>
<div class="field">
<div class="ui grid">
<div class="column">
<div class="ui radio checkbox">
<input type="radio" name="resource_type" checked="" tabindex="0">
</div>
</div>
<div class="three wide column">train-private-1</div>
<div class="three wide column">{{svg "octicon-verified" 16}} 运行中</div>
<div class="three wide column"> CPU:192 核 2048GiB</div>
</div>
</div>
</div>

<div class="required unite min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label>
<select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor">
{{if .flavor_name}}
<option name="flavor" value="{{.flavor_code}}">{{.flavor_name}}</option>
{{end}}
{{range .flavor_infos}}
{{if ne $.flavor_code .Code}}
<option name="flavor" value="{{.Code}}">{{.Value}}</option>
{{end}}
{{end}}
</select>
</div>
<div class="inline required unite min_title field">
<label>{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label>
<div class="ui labeled input" style="width: 5%;">

<input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="{{.work_server_number}}" readonly>

</div>
</div>
<div class="inline unite min_title field">
<button class="ui create_train_job green button">
{{.i18n.Tr "repo.cloudbrain.new"}}
</button>
<a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a>
</div>
<!-- 模态框 -->
</form>
</div>
</div>
</div>
{{template "base/footer" .}}

<script>
console.log({{.dataset_name}})
console.log({{.params}})
console.log({{.flavor_name}})
console.log({{.flavor_code}})
let url_href = window.location.pathname.split('create')[0]
let url_post = window.location.pathname.split('?version_name=V0001')[0]
$(".ui.button").attr('href',url_href)
$(".ui.form").attr('action',url_post)
$('select.dropdown')
.dropdown();

$('.menu .item')
.tab();

let sever_num = $('#trainjob_work_server_num')
$('.add').click(function(){
sever_num.val(parseInt(sever_num.val())+1)
if(sever_num.val()>=26){
sever_num.val(parseInt(sever_num.val())-1)
}
})
$('.min').click(function(){
sever_num.val(parseInt(sever_num.val())-1)
if(sever_num.val()<=0){
sever_num.val(parseInt(sever_num.val())+1)
}
})

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

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

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

$('.ui.parameter.green.button').click(function(){
var parameters = [];
$('table tr').each(function() {
$(this).find('td:eq(1)').each(function(){
parameters.push($(this).text());
})
$(this).find('input').each(function(){
parameters.push($(this).text())
})
});
console.log(parameters)
$('.ui.parameter.modal')
.modal('hide');
for(var i = 2; i < parameters.length; i++){
switch(i) {
// 数据集uuid待完成
// case (2):
// console.log(1)
// break;
// $("#trainjob_datasets").val(parameters[i]);
// console.log($("#trainjob_datasets").val())
case (3):
$("input[name='boot_file']").val(parameters[i]);
break;
case (4):
var para = parameters[i].split(" ")
for(var j = 0; j < para.length; j++){
var para_name = para[j].split('=')[0]
var para_value = para[j].split('=')[1]
var len = $(".dynamic.field .two.fields").length
Add_parameter(len)
var pid = 'para' + len
$(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_first-name]").val(para_name)
$(".dynamic.field"+ " #" + pid + "").find("input[name=shipping_last-name]").val(para_value)
}
break;
// 数据集pool_id待完成
// case (5):
// $("select[name='pool_id']").val(parameters[i]);
// break;
case (6):
$("input[name='work_server_number']").val(parameters[i]);
break;
}
}
})

$('.ui.save.checkbox').click(function(){
$(this).checkbox({
onChange: function(){
if ($('.ui.save.checkbox').checkbox('is checked')){
$('#save_para').removeClass("disabled")
}else{
$('#save_para').addClass("disabled")
}
}
});
})

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

$(".item.active.parameter_config").click(function(){
$('.ui.parameter.modal')
.modal('setting', 'closable', false)
.modal('show');
})

$('.ui.deny.button').click(function(){
$('.ui.parameter.modal')
.modal('hide');
})
$('select.dropdown')
.dropdown();

$('.ui.form')
.form({
on: 'blur',
inline:true,
fields: {
boot_file: {
identifier : 'boot_file',
rules: [
{
type: 'regExp[/.+\.py$/g]',
prompt : '启动文件必须为.py结尾'
}
]
},
job_name:{
identifier : 'job_name',
rules: [
{
type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]',
prompt : '只包含大小写字母、数字、_和-,最长36个字符。'
}
]
},
attachment:{
identifier : 'attachment',
rules: [
{
type: 'empty',
prompt : '选择一个数据集'
}
]

},
work_server_number: {
identifier : 'work_server_number',
rules: [
{
type : 'integer[1..25]',
prompt : '计算节点需要在1-25之间,请您键入正确的值'
}
]
}
},
})



function validate(){
$('.ui.form')
.form({
on: 'blur',
inline:true,
fields: {
boot_file: {
identifier : 'boot_file',
rules: [
{
type: 'regExp[/.+\.py$/g]',
prompt : '启动文件必须为.py结尾'
}
]
},
job_name:{
identifier : 'job_name',
rules: [
{
type: 'regExp[/^[a-zA-Z0-9-_]{1,36}$/]',
prompt : '只包含大小写字母、数字、_和-,最长36个字符。'
}
]
},
attachment:{
identifier : 'attachment',
rules: [
{
type: 'empty',
prompt : '选择一个数据集'
}
]

},
work_server_number: {
identifier : 'work_server_number',
rules: [
{
type : 'integer[1..25]',
prompt : '计算节点需要在1-25之间,请您键入正确的值'
}
]
}
},
onSuccess: function(){
// $('.ui.page.dimmer').dimmer('show')
document.getElementById("mask").style.display = "block"
},
onFailure: function(e){
return false;
}
})
}
document.onreadystatechange = function() {
if (document.readyState === "complete") {
document.getElementById("mask").style.display = "none"
}
}
function send_run_para(){
var run_parameters = []
var msg = {}
$(".dynamic.field .two.fields").each(function(){
var para_name = $(this).find('input[name=shipping_first-name]').val()
var para_value = $(this).find('input[name=shipping_last-name]').val()
run_parameters.push({"label": para_name, "value": para_value})
})
msg["parameter"] = run_parameters
msg = JSON.stringify(msg)
$('#store_run_para').val(msg)
}

$('.ui.create_train_job.green.button').click(function(e) {
send_run_para()
validate()
})
</script>

Loading…
Cancel
Save