| @@ -1141,3 +1141,9 @@ growth_issue=0.2 | |||||
| growth_contributors=0.2 | growth_contributors=0.2 | ||||
| growth_commit=0.2 | growth_commit=0.2 | ||||
| growth_comments=0.2 | growth_comments=0.2 | ||||
| [grampus] | |||||
| USERNAME = | |||||
| PASSWORD = | |||||
| SERVER_HOST = | |||||
| @@ -0,0 +1,294 @@ | |||||
| package grampus | |||||
| import ( | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| "strconv" | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/notification" | |||||
| ) | |||||
| const ( | |||||
| //notebook | |||||
| storageTypeOBS = "obs" | |||||
| autoStopDuration = 4 * 60 * 60 | |||||
| autoStopDurationMs = 4 * 60 * 60 * 1000 | |||||
| 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/" | |||||
| LogPath = "/log/" | |||||
| JobPath = "/job/" | |||||
| OrderDesc = "desc" //向下查询 | |||||
| OrderAsc = "asc" //向上查询 | |||||
| Lines = 500 | |||||
| TrainUrl = "train_url" | |||||
| DataUrl = "data_url" | |||||
| ResultUrl = "result_url" | |||||
| CkptUrl = "ckpt_url" | |||||
| DeviceTarget = "device_target" | |||||
| Ascend = "Ascend" | |||||
| PerPage = 10 | |||||
| IsLatestVersion = "1" | |||||
| NotLatestVersion = "0" | |||||
| VersionCount = 1 | |||||
| SortByCreateTime = "create_time" | |||||
| ConfigTypeCustom = "custom" | |||||
| TotalVersionCount = 1 | |||||
| ) | |||||
| var ( | |||||
| poolInfos *models.PoolInfos | |||||
| FlavorInfos *models.FlavorInfos | |||||
| ImageInfos *models.ImageInfosModelArts | |||||
| ) | |||||
| type GenerateTrainJobReq struct { | |||||
| JobName string | |||||
| DisplayJobName string | |||||
| Uuid string | |||||
| Description string | |||||
| CodeObsPath string | |||||
| BootFile string | |||||
| BootFileUrl string | |||||
| DataUrl string | |||||
| TrainUrl string | |||||
| FlavorCode string | |||||
| LogUrl string | |||||
| PoolID string | |||||
| WorkServerNumber int | |||||
| EngineID int64 | |||||
| Parameters []models.Parameter | |||||
| CommitID string | |||||
| IsLatestVersion string | |||||
| Params string | |||||
| BranchName string | |||||
| PreVersionId int64 | |||||
| PreVersionName string | |||||
| FlavorName string | |||||
| VersionCount int | |||||
| EngineName string | |||||
| TotalVersionCount int | |||||
| } | |||||
| type GenerateInferenceJobReq struct { | |||||
| JobName string | |||||
| DisplayJobName string | |||||
| Uuid string | |||||
| Description string | |||||
| CodeObsPath string | |||||
| BootFile string | |||||
| BootFileUrl string | |||||
| DataUrl string | |||||
| TrainUrl string | |||||
| FlavorCode string | |||||
| LogUrl string | |||||
| PoolID string | |||||
| WorkServerNumber int | |||||
| EngineID int64 | |||||
| Parameters []models.Parameter | |||||
| CommitID string | |||||
| Params string | |||||
| BranchName string | |||||
| FlavorName string | |||||
| EngineName string | |||||
| LabelName string | |||||
| IsLatestVersion string | |||||
| VersionCount int | |||||
| TotalVersionCount int | |||||
| ModelName string | |||||
| ModelVersion string | |||||
| CkptName string | |||||
| ResultUrl string | |||||
| } | |||||
| type VersionInfo struct { | |||||
| Version []struct { | |||||
| ID int `json:"id"` | |||||
| Value string `json:"value"` | |||||
| } `json:"version"` | |||||
| } | |||||
| type Flavor struct { | |||||
| Info []struct { | |||||
| Code string `json:"code"` | |||||
| Value string `json:"value"` | |||||
| } `json:"flavor"` | |||||
| } | |||||
| type Engine struct { | |||||
| Info []struct { | |||||
| ID int `json:"id"` | |||||
| Value string `json:"value"` | |||||
| } `json:"engine"` | |||||
| } | |||||
| type ResourcePool struct { | |||||
| Info []struct { | |||||
| ID string `json:"id"` | |||||
| Value string `json:"value"` | |||||
| } `json:"resource_pool"` | |||||
| } | |||||
| // type Parameter struct { | |||||
| // Label string `json:"label"` | |||||
| // Value string `json:"value"` | |||||
| // } | |||||
| // type Parameters struct { | |||||
| // Parameter []Parameter `json:"parameter"` | |||||
| // } | |||||
| type Parameters struct { | |||||
| Parameter []struct { | |||||
| Label string `json:"label"` | |||||
| Value string `json:"value"` | |||||
| } `json:"parameter"` | |||||
| } | |||||
| func GenerateTrainJob(ctx *context.Context, req *GenerateTrainJobReq) (err error) { | |||||
| createTime := timeutil.TimeStampNow() | |||||
| jobResult, err := createTrainJob(models.CreateTrainJobParams{ | |||||
| JobName: req.JobName, | |||||
| Description: req.Description, | |||||
| Config: models.Config{ | |||||
| WorkServerNum: req.WorkServerNumber, | |||||
| AppUrl: req.CodeObsPath, | |||||
| BootFileUrl: req.BootFileUrl, | |||||
| DataUrl: req.DataUrl, | |||||
| EngineID: req.EngineID, | |||||
| TrainUrl: req.TrainUrl, | |||||
| LogUrl: req.LogUrl, | |||||
| PoolID: req.PoolID, | |||||
| CreateVersion: true, | |||||
| Flavor: models.Flavor{ | |||||
| Code: req.FlavorCode, | |||||
| }, | |||||
| Parameter: req.Parameters, | |||||
| }, | |||||
| }) | |||||
| if err != nil { | |||||
| log.Error("CreateJob failed: %v", err.Error()) | |||||
| return err | |||||
| } | |||||
| attach, err := models.GetAttachmentByUUID(req.Uuid) | |||||
| if err != nil { | |||||
| log.Error("GetAttachmentByUUID(%s) failed:%v", strconv.FormatInt(jobResult.JobID, 10), err.Error()) | |||||
| return err | |||||
| } | |||||
| jobId := strconv.FormatInt(jobResult.JobID, 10) | |||||
| err = models.CreateCloudbrain(&models.Cloudbrain{ | |||||
| Status: TransTrainJobStatus(jobResult.Status), | |||||
| UserID: ctx.User.ID, | |||||
| RepoID: ctx.Repo.Repository.ID, | |||||
| JobID: jobId, | |||||
| JobName: req.JobName, | |||||
| DisplayJobName: req.DisplayJobName, | |||||
| JobType: string(models.JobTypeTrain), | |||||
| Type: models.TypeCloudBrainTwo, | |||||
| VersionID: jobResult.VersionID, | |||||
| VersionName: jobResult.VersionName, | |||||
| Uuid: req.Uuid, | |||||
| DatasetName: attach.Name, | |||||
| CommitID: req.CommitID, | |||||
| IsLatestVersion: req.IsLatestVersion, | |||||
| ComputeResource: models.NPUResource, | |||||
| EngineID: req.EngineID, | |||||
| TrainUrl: req.TrainUrl, | |||||
| BranchName: req.BranchName, | |||||
| Parameters: req.Params, | |||||
| BootFile: req.BootFile, | |||||
| DataUrl: req.DataUrl, | |||||
| LogUrl: req.LogUrl, | |||||
| FlavorCode: req.FlavorCode, | |||||
| Description: req.Description, | |||||
| WorkServerNumber: req.WorkServerNumber, | |||||
| FlavorName: req.FlavorName, | |||||
| EngineName: req.EngineName, | |||||
| VersionCount: req.VersionCount, | |||||
| TotalVersionCount: req.TotalVersionCount, | |||||
| CreatedUnix: createTime, | |||||
| UpdatedUnix: createTime, | |||||
| }) | |||||
| if err != nil { | |||||
| log.Error("CreateCloudbrain(%s) failed:%v", req.DisplayJobName, err.Error()) | |||||
| return err | |||||
| } | |||||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobId, req.DisplayJobName, models.ActionCreateTrainTask) | |||||
| return nil | |||||
| } | |||||
| func TransTrainJobStatus(status int) string { | |||||
| switch status { | |||||
| case 0: | |||||
| return "UNKNOWN" | |||||
| case 1: | |||||
| return "INIT" | |||||
| case 2: | |||||
| return "IMAGE_CREATING" | |||||
| case 3: | |||||
| return "IMAGE_FAILED" | |||||
| case 4: | |||||
| return "SUBMIT_TRYING" | |||||
| case 5: | |||||
| return "SUBMIT_FAILED" | |||||
| case 6: | |||||
| return "DELETE_FAILED" | |||||
| case 7: | |||||
| return "WAITING" | |||||
| case 8: | |||||
| return "RUNNING" | |||||
| case 9: | |||||
| return "KILLING" | |||||
| case 10: | |||||
| return "COMPLETED" | |||||
| case 11: | |||||
| return "FAILED" | |||||
| case 12: | |||||
| return "KILLED" | |||||
| case 13: | |||||
| return "CANCELED" | |||||
| case 14: | |||||
| return "LOST" | |||||
| case 15: | |||||
| return "SCALING" | |||||
| case 16: | |||||
| return "SUBMIT_MODEL_FAILED" | |||||
| case 17: | |||||
| return "DEPLOY_SERVICE_FAILED" | |||||
| case 18: | |||||
| return "CHECK_INIT" | |||||
| case 19: | |||||
| return "CHECK_RUNNING" | |||||
| case 20: | |||||
| return "CHECK_RUNNING_COMPLETED" | |||||
| case 21: | |||||
| return "CHECK_FAILED" | |||||
| default: | |||||
| return strconv.Itoa(status) | |||||
| } | |||||
| } | |||||
| @@ -528,6 +528,13 @@ var ( | |||||
| FlavorInfos string | FlavorInfos string | ||||
| TrainJobFLAVORINFOS string | TrainJobFLAVORINFOS string | ||||
| //grampus config | |||||
| Grampus = struct { | |||||
| Host string | |||||
| UserName string | |||||
| Password string | |||||
| }{} | |||||
| //elk config | //elk config | ||||
| ElkUrl string | ElkUrl string | ||||
| ElkUser string | ElkUser string | ||||
| @@ -1382,6 +1389,15 @@ func NewContext() { | |||||
| Course.OrgName = sec.Key("org_name").MustString("") | Course.OrgName = sec.Key("org_name").MustString("") | ||||
| Course.TeamName = sec.Key("team_name").MustString("") | Course.TeamName = sec.Key("team_name").MustString("") | ||||
| GetGrampusConfig() | |||||
| } | |||||
| func GetGrampusConfig() { | |||||
| sec := Cfg.Section("grampus") | |||||
| Grampus.Host = sec.Key("SERVER_HOST").MustString("") | |||||
| Grampus.UserName = sec.Key("USERNAME").MustString("") | |||||
| Grampus.Password = sec.Key("PASSWORD").MustString("") | |||||
| } | } | ||||
| func SetRadarMapConfig() { | func SetRadarMapConfig() { | ||||
| @@ -1,22 +1,435 @@ | |||||
| package repo | package repo | ||||
| import ( | import ( | ||||
| "code.gitea.io/gitea/modules/base" | |||||
| "code.gitea.io/gitea/modules/auth" | |||||
| "code.gitea.io/gitea/modules/git" | |||||
| "code.gitea.io/gitea/modules/modelarts" | |||||
| "code.gitea.io/gitea/modules/util" | |||||
| "encoding/json" | |||||
| "io/ioutil" | |||||
| "net/http" | "net/http" | ||||
| "os" | |||||
| "path" | |||||
| "strconv" | |||||
| "strings" | |||||
| "time" | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/base" | |||||
| "code.gitea.io/gitea/modules/cloudbrain" | |||||
| "code.gitea.io/gitea/modules/context" | "code.gitea.io/gitea/modules/context" | ||||
| "code.gitea.io/gitea/modules/log" | |||||
| "code.gitea.io/gitea/modules/setting" | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| tplGrampusTrainJobNew base.TplName = "repo/grampus/trainjob/new" | |||||
| tplGrampusTrainJobShow base.TplName = "repo/grampus/trainjob/show" | |||||
| //GPU | |||||
| tplGrampusTrainJobGPUNew base.TplName = "repo/grampus/trainjob/gpu/new" | |||||
| tplGrampusTrainJobGPUShow base.TplName = "repo/grampus/trainjob/gpu/show" | |||||
| //NPU | |||||
| tplGrampusTrainJobNPUNew base.TplName = "repo/grampus/trainjob/npu/new" | |||||
| tplGrampusTrainJobNPUShow base.TplName = "repo/grampus/trainjob/npu/show" | |||||
| ) | ) | ||||
| func GrampusNew(ctx *context.Context) { | |||||
| err := cloudBrainNewDataPrepare(ctx) | |||||
| func GrampusTrainJobGPUNew(ctx *context.Context) { | |||||
| err := grampusGpuNewDataPrepare(ctx) | |||||
| if err != nil { | |||||
| ctx.ServerError("get new train-job info failed", err) | |||||
| return | |||||
| } | |||||
| ctx.HTML(http.StatusOK, tplGrampusTrainJobGPUNew) | |||||
| } | |||||
| func grampusGpuNewDataPrepare(ctx *context.Context) error { | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| t := time.Now() | |||||
| var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["display_job_name"] = displayJobName | |||||
| //get valid images | |||||
| result, err := cloudbrain.GetImages() | |||||
| if err != nil { | |||||
| ctx.Data["error"] = err.Error() | |||||
| log.Error("cloudbrain.GetImages failed:", err.Error(), ctx.Data["MsgID"]) | |||||
| } | |||||
| for i, payload := range result.Payload.ImageInfo { | |||||
| if strings.HasPrefix(result.Payload.ImageInfo[i].Place, "192.168") { | |||||
| result.Payload.ImageInfo[i].PlaceView = payload.Place[strings.Index(payload.Place, "/"):len(payload.Place)] | |||||
| } else { | |||||
| result.Payload.ImageInfo[i].PlaceView = payload.Place | |||||
| } | |||||
| } | |||||
| ctx.Data["images"] = result.Payload.ImageInfo | |||||
| resultPublic, err := cloudbrain.GetPublicImages() | |||||
| if err != nil { | |||||
| ctx.Data["error"] = err.Error() | |||||
| log.Error("cloudbrain.GetPublicImages failed:", err.Error(), ctx.Data["MsgID"]) | |||||
| } | |||||
| for i, payload := range resultPublic.Payload.ImageInfo { | |||||
| if strings.HasPrefix(resultPublic.Payload.ImageInfo[i].Place, "192.168") { | |||||
| resultPublic.Payload.ImageInfo[i].PlaceView = payload.Place[strings.Index(payload.Place, "/"):len(payload.Place)] | |||||
| } else { | |||||
| resultPublic.Payload.ImageInfo[i].PlaceView = payload.Place | |||||
| } | |||||
| } | |||||
| ctx.Data["public_images"] = resultPublic.Payload.ImageInfo | |||||
| //get valid dataset | |||||
| attachs, err := models.GetAllUserAttachments(ctx.User.ID) | |||||
| if err != nil { | |||||
| log.Error("GetAllUserAttachments failed: %v", err, ctx.Data["MsgID"]) | |||||
| return err | |||||
| } | |||||
| ctx.Data["attachments"] = attachs | |||||
| ctx.Data["command"] = cloudbrain.Command | |||||
| ctx.Data["code_path"] = cloudbrain.CodeMountPath | |||||
| ctx.Data["dataset_path"] = cloudbrain.DataSetMountPath | |||||
| ctx.Data["model_path"] = cloudbrain.ModelMountPath | |||||
| ctx.Data["benchmark_path"] = cloudbrain.BenchMarkMountPath | |||||
| ctx.Data["is_benchmark_enabled"] = setting.IsBenchmarkEnabled | |||||
| //get valid resource specs | |||||
| if categories == nil { | |||||
| json.Unmarshal([]byte(setting.BenchmarkCategory), &categories) | |||||
| } | |||||
| ctx.Data["benchmark_categories"] = categories.Category | |||||
| ctx.Data["benchmark_types"] = GetBenchmarkTypes(ctx).BenchmarkType | |||||
| if gpuInfos == nil { | |||||
| json.Unmarshal([]byte(setting.GpuTypes), &gpuInfos) | |||||
| } | |||||
| ctx.Data["gpu_types"] = gpuInfos.GpuInfo | |||||
| if trainGpuInfos == nil { | |||||
| json.Unmarshal([]byte(setting.TrainGpuTypes), &trainGpuInfos) | |||||
| } | |||||
| ctx.Data["train_gpu_types"] = trainGpuInfos.GpuInfo | |||||
| if benchmarkGpuInfos == nil { | |||||
| json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | |||||
| } | |||||
| ctx.Data["benchmark_gpu_types"] = benchmarkGpuInfos.GpuInfo | |||||
| if benchmarkResourceSpecs == nil { | |||||
| json.Unmarshal([]byte(setting.BenchmarkResourceSpecs), &benchmarkResourceSpecs) | |||||
| } | |||||
| ctx.Data["benchmark_resource_specs"] = benchmarkResourceSpecs.ResourceSpec | |||||
| if cloudbrain.ResourceSpecs == nil { | |||||
| json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||||
| } | |||||
| ctx.Data["resource_specs"] = cloudbrain.ResourceSpecs.ResourceSpec | |||||
| if cloudbrain.TrainResourceSpecs == nil { | |||||
| json.Unmarshal([]byte(setting.TrainResourceSpecs), &cloudbrain.TrainResourceSpecs) | |||||
| } | |||||
| ctx.Data["train_resource_specs"] = cloudbrain.TrainResourceSpecs.ResourceSpec | |||||
| ctx.Data["params"] = "" | |||||
| ctx.Data["branchName"] = ctx.Repo.BranchName | |||||
| ctx.Data["snn4imagenet_path"] = cloudbrain.Snn4imagenetMountPath | |||||
| ctx.Data["is_snn4imagenet_enabled"] = setting.IsSnn4imagenetEnabled | |||||
| ctx.Data["brainscore_path"] = cloudbrain.BrainScoreMountPath | |||||
| ctx.Data["is_brainscore_enabled"] = setting.IsBrainScoreEnabled | |||||
| ctx.Data["cloudbraintype"] = models.TypeCloudBrainOne | |||||
| ctx.Data["benchmarkMode"] = ctx.Query("benchmarkMode") | |||||
| return nil | |||||
| } | |||||
| func GrampusTrainJobNPUNew(ctx *context.Context) { | |||||
| err := trainJobNpuNewDataPrepare(ctx) | |||||
| if err != nil { | if err != nil { | ||||
| ctx.ServerError("get new train-job info failed", err) | ctx.ServerError("get new train-job info failed", err) | ||||
| return | return | ||||
| } | } | ||||
| ctx.HTML(http.StatusOK, tplGrampusTrainJobNew) | |||||
| ctx.HTML(200, tplGrampusTrainJobNPUNew) | |||||
| } | |||||
| func trainJobNpuNewDataPrepare(ctx *context.Context) error { | |||||
| ctx.Data["PageIsCloudBrain"] = true | |||||
| t := time.Now() | |||||
| var displayJobName = cutString(ctx.User.Name, 5) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||||
| ctx.Data["display_job_name"] = displayJobName | |||||
| //get valid dataset | |||||
| attachs, err := models.GetModelArtsTrainAttachments(ctx.User.ID) | |||||
| if err != nil { | |||||
| ctx.ServerError("GetAllUserAttachments failed:", err) | |||||
| return err | |||||
| } | |||||
| ctx.Data["attachments"] = attachs | |||||
| //get valid resource specs | |||||
| var resourcePools modelarts.ResourcePool | |||||
| if err = json.Unmarshal([]byte(setting.ResourcePools), &resourcePools); err != nil { | |||||
| ctx.ServerError("json.Unmarshal failed:", err) | |||||
| return err | |||||
| } | |||||
| ctx.Data["resource_pools"] = resourcePools.Info | |||||
| var engines modelarts.Engine | |||||
| if err = json.Unmarshal([]byte(setting.Engines), &engines); err != nil { | |||||
| ctx.ServerError("json.Unmarshal failed:", err) | |||||
| return err | |||||
| } | |||||
| ctx.Data["engines"] = engines.Info | |||||
| var versionInfos modelarts.VersionInfo | |||||
| if err = json.Unmarshal([]byte(setting.EngineVersions), &versionInfos); err != nil { | |||||
| ctx.ServerError("json.Unmarshal failed:", err) | |||||
| return err | |||||
| } | |||||
| ctx.Data["engine_versions"] = versionInfos.Version | |||||
| var flavorInfos modelarts.Flavor | |||||
| if err = json.Unmarshal([]byte(setting.TrainJobFLAVORINFOS), &flavorInfos); err != nil { | |||||
| ctx.ServerError("json.Unmarshal failed:", err) | |||||
| return err | |||||
| } | |||||
| ctx.Data["flavor_infos"] = flavorInfos.Info | |||||
| ctx.Data["params"] = "" | |||||
| ctx.Data["branchName"] = ctx.Repo.BranchName | |||||
| configList, err := getConfigList(modelarts.PerPage, 1, modelarts.SortByCreateTime, "desc", "", modelarts.ConfigTypeCustom) | |||||
| if err != nil { | |||||
| ctx.ServerError("getConfigList failed:", err) | |||||
| return err | |||||
| } | |||||
| ctx.Data["config_list"] = configList.ParaConfigs | |||||
| ctx.Data["cloudbraintype"] = models.TypeCloudBrainTwo | |||||
| return nil | |||||
| } | |||||
| func GrampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) { | |||||
| VersionOutputPath := modelarts.GetOutputPathByCount(modelarts.TotalVersionCount) | |||||
| displayJobName := form.DisplayJobName | |||||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||||
| uuid := form.Attachment | |||||
| description := form.Description | |||||
| workServerNumber := form.WorkServerNumber | |||||
| engineID := form.EngineID | |||||
| bootFile := form.BootFile | |||||
| flavorCode := form.Flavor | |||||
| params := form.Params | |||||
| poolID := form.PoolID | |||||
| isSaveParam := form.IsSaveParam | |||||
| repo := ctx.Repo.Repository | |||||
| codeLocalPath := setting.JobPath + jobName + modelarts.CodePath | |||||
| codeObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.CodePath | |||||
| outputObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.OutputPath + VersionOutputPath + "/" | |||||
| logObsPath := "/" + setting.Bucket + modelarts.JobPath + jobName + modelarts.LogPath + VersionOutputPath + "/" | |||||
| dataPath := "/" + setting.Bucket + "/" + setting.BasePath + path.Join(uuid[0:1], uuid[1:2]) + "/" + uuid + uuid + "/" | |||||
| branch_name := form.BranchName | |||||
| isLatestVersion := modelarts.IsLatestVersion | |||||
| FlavorName := form.FlavorName | |||||
| VersionCount := modelarts.VersionCount | |||||
| EngineName := form.EngineName | |||||
| count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID) | |||||
| if err != nil { | |||||
| log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("system error", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } else { | |||||
| if count >= 1 { | |||||
| log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| if err := paramCheckCreateTrainJob(form); err != nil { | |||||
| log.Error("paramCheckCreateTrainJob failed:(%v)", err) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| //Determine whether the task name of the task in the project is duplicated | |||||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeTrain), displayJobName) | |||||
| if err == nil { | |||||
| if len(tasks) != 0 { | |||||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("the job name did already exist", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| } else { | |||||
| if !models.IsErrJobNotExist(err) { | |||||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("system error", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| //todo: del the codeLocalPath | |||||
| _, err = ioutil.ReadDir(codeLocalPath) | |||||
| if err == nil { | |||||
| os.RemoveAll(codeLocalPath) | |||||
| } | |||||
| gitRepo, _ := git.OpenRepository(repo.RepoPath()) | |||||
| commitID, _ := gitRepo.GetBranchCommitID(branch_name) | |||||
| if err := downloadCode(repo, codeLocalPath, branch_name); err != nil { | |||||
| log.Error("downloadCode failed, server timed out: %s (%v)", repo.FullName(), err) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("Create task failed, server timed out", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| //todo: upload code (send to file_server todo this work?) | |||||
| if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.OutputPath + VersionOutputPath + "/"); err != nil { | |||||
| log.Error("Failed to obsMkdir_output: %s (%v)", repo.FullName(), err) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("Failed to obsMkdir_output", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| if err := obsMkdir(setting.CodePathPrefix + jobName + modelarts.LogPath + VersionOutputPath + "/"); err != nil { | |||||
| log.Error("Failed to obsMkdir_log: %s (%v)", repo.FullName(), err) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("Failed to obsMkdir_log", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| // parentDir := VersionOutputPath + "/" | |||||
| if err := uploadCodeToObs(codeLocalPath, jobName, ""); err != nil { | |||||
| // if err := uploadCodeToObs(codeLocalPath, jobName, parentDir); err != nil { | |||||
| log.Error("Failed to uploadCodeToObs: %s (%v)", repo.FullName(), err) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("Failed to uploadCodeToObs", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| var parameters models.Parameters | |||||
| param := make([]models.Parameter, 0) | |||||
| existDeviceTarget := false | |||||
| if len(params) != 0 { | |||||
| err := json.Unmarshal([]byte(params), ¶meters) | |||||
| if err != nil { | |||||
| log.Error("Failed to Unmarshal params: %s (%v)", params, err) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("运行参数错误", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| for _, parameter := range parameters.Parameter { | |||||
| if parameter.Label == modelarts.DeviceTarget { | |||||
| existDeviceTarget = true | |||||
| } | |||||
| if parameter.Label != modelarts.TrainUrl && parameter.Label != modelarts.DataUrl { | |||||
| param = append(param, models.Parameter{ | |||||
| Label: parameter.Label, | |||||
| Value: parameter.Value, | |||||
| }) | |||||
| } | |||||
| } | |||||
| } | |||||
| if !existDeviceTarget { | |||||
| param = append(param, models.Parameter{ | |||||
| Label: modelarts.DeviceTarget, | |||||
| Value: modelarts.Ascend, | |||||
| }) | |||||
| } | |||||
| //save param config | |||||
| if isSaveParam == "on" { | |||||
| saveparams := append(param, models.Parameter{ | |||||
| Label: modelarts.TrainUrl, | |||||
| Value: outputObsPath, | |||||
| }, models.Parameter{ | |||||
| Label: modelarts.DataUrl, | |||||
| Value: dataPath, | |||||
| }) | |||||
| if form.ParameterTemplateName == "" { | |||||
| log.Error("ParameterTemplateName is empty") | |||||
| trainJobNewDataPrepare(ctx) | |||||
| ctx.RenderWithErr("保存作业参数时,作业参数名称不能为空", tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| _, err := modelarts.CreateTrainJobConfig(models.CreateConfigParams{ | |||||
| ConfigName: form.ParameterTemplateName, | |||||
| Description: form.PrameterDescription, | |||||
| DataUrl: dataPath, | |||||
| AppUrl: codeObsPath, | |||||
| BootFileUrl: codeObsPath + bootFile, | |||||
| TrainUrl: outputObsPath, | |||||
| Flavor: models.Flavor{ | |||||
| Code: flavorCode, | |||||
| }, | |||||
| WorkServerNum: workServerNumber, | |||||
| EngineID: int64(engineID), | |||||
| LogUrl: logObsPath, | |||||
| PoolID: poolID, | |||||
| Parameter: saveparams, | |||||
| }) | |||||
| if err != nil { | |||||
| log.Error("Failed to CreateTrainJobConfig: %v", err) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr("保存作业参数失败:"+err.Error(), tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| } | |||||
| req := &modelarts.GenerateTrainJobReq{ | |||||
| JobName: jobName, | |||||
| DisplayJobName: displayJobName, | |||||
| DataUrl: dataPath, | |||||
| Description: description, | |||||
| CodeObsPath: codeObsPath, | |||||
| BootFileUrl: codeObsPath + bootFile, | |||||
| BootFile: bootFile, | |||||
| TrainUrl: outputObsPath, | |||||
| FlavorCode: flavorCode, | |||||
| WorkServerNumber: workServerNumber, | |||||
| EngineID: int64(engineID), | |||||
| LogUrl: logObsPath, | |||||
| PoolID: poolID, | |||||
| Uuid: uuid, | |||||
| Parameters: param, | |||||
| CommitID: commitID, | |||||
| IsLatestVersion: isLatestVersion, | |||||
| BranchName: branch_name, | |||||
| Params: form.Params, | |||||
| FlavorName: FlavorName, | |||||
| EngineName: EngineName, | |||||
| VersionCount: VersionCount, | |||||
| TotalVersionCount: modelarts.TotalVersionCount, | |||||
| } | |||||
| //将params转换Parameters.Parameter,出错时返回给前端 | |||||
| var Parameters modelarts.Parameters | |||||
| if err := json.Unmarshal([]byte(params), &Parameters); err != nil { | |||||
| ctx.ServerError("json.Unmarshal failed:", err) | |||||
| return | |||||
| } | |||||
| err = modelarts.GenerateTrainJob(ctx, req) | |||||
| if err != nil { | |||||
| log.Error("GenerateTrainJob failed:%v", err.Error()) | |||||
| trainJobErrorNewDataPrepare(ctx, form) | |||||
| ctx.RenderWithErr(err.Error(), tplModelArtsTrainJobNew, &form) | |||||
| return | |||||
| } | |||||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/train-job") | |||||
| } | } | ||||
| @@ -1085,14 +1085,26 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| }, context.RepoRef()) | }, context.RepoRef()) | ||||
| m.Group("/grampus", func() { | m.Group("/grampus", func() { | ||||
| m.Group("/train-job", func() { | m.Group("/train-job", func() { | ||||
| m.Group("/:jobid", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainTrainJobShow) | |||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel) | |||||
| m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel) | |||||
| m.Group("/gpu", func() { | |||||
| m.Group("/:jobid", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainTrainJobShow) | |||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel) | |||||
| m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel) | |||||
| }) | |||||
| m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.GrampusTrainJobGPUNew) | |||||
| //m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.GrampusTrainJobCreate) | |||||
| }) | |||||
| m.Group("/npu", func() { | |||||
| m.Group("/:jobid", func() { | |||||
| m.Get("", reqRepoCloudBrainReader, repo.CloudBrainTrainJobShow) | |||||
| m.Post("/stop", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.CloudBrainStop) | |||||
| m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainTrainJobDel) | |||||
| m.Get("/download_model", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo.CloudBrainDownloadModel) | |||||
| }) | |||||
| m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.GrampusTrainJobNPUNew) | |||||
| //m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.GrampusTrainJobCreate) | |||||
| }) | }) | ||||
| m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.GrampusNew) | |||||
| m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.GrampusCreate) | |||||
| }) | }) | ||||
| }, context.RepoRef()) | }, context.RepoRef()) | ||||
| m.Group("/modelmanage", func() { | m.Group("/modelmanage", func() { | ||||
| @@ -0,0 +1,447 @@ | |||||
| {{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; | |||||
| } | |||||
| .width806{ | |||||
| width: 80.6% !important; | |||||
| margin-left: -2px; | |||||
| } | |||||
| .width85{ | |||||
| width: 85% !important; | |||||
| margin-left: 4.5rem !important; | |||||
| } | |||||
| .width81{ | |||||
| margin-left: 1.5rem !important; | |||||
| 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; | |||||
| } | |||||
| </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="{{.Link}}" method="post"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <input type="hidden" name="action" value="update"> | |||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
| <div class="ui blue mini menu compact selectcloudbrain"> | |||||
| <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 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"/> | |||||
| </svg> | |||||
| Ascend NPU</a> | |||||
| </div> | |||||
| </div> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label 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="64"> | |||||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| </div> | |||||
| <div class="unite min_title inline field"> | |||||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="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> | |||||
| </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 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" style="display: none;"> | |||||
| <label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||||
| <select id="cloudbrain_job_type" class="ui search dropdown" placeholder="选择任务类型" style='width:385px' name="job_type"> | |||||
| <option name="job_type" value="TRAIN">TRAIN</option> | |||||
| </select> | |||||
| </div> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||||
| <select id="cloudbrain_gpu_type" class="ui search width806 dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | |||||
| {{range .train_gpu_types}} | |||||
| <option value="{{.Queue}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| <!-- <div class="required unite min_title inline field" style="position: relative;"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.mirror"}} </label> | |||||
| <input class="width81" type="text" list="cloudbrain_image" placeholder="{{.i18n.Tr "cloudbrain.choose_mirror"}}" name="image" required autofocus maxlength="255"> | |||||
| <i class="times circle outline icon icons" style="visibility: hidden;" onclick="clearValue()"></i> | |||||
| <datalist class="ui search" id="cloudbrain_image" name="image"> | |||||
| {{range .images}} | |||||
| <option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
| {{end}} | |||||
| {{range .public_images}} | |||||
| <option name="image" value="{{.Place}}">{{.PlaceView}}</option> | |||||
| {{end}} | |||||
| </datalist> | |||||
| </div> --> | |||||
| <div id="images-new-cb"> | |||||
| </div> | |||||
| <div class="inline unite min_title field required"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||||
| {{if .bootFile}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{else}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||||
| {{end}} | |||||
| <span> | |||||
| <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||||
| </span> | |||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU" target="_blank">查看样例</a> | |||||
| </div> | |||||
| {{template "custom/select_dataset_train" .}} | |||||
| <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span> | |||||
| <div class="inline unite min_title field"> | |||||
| <label 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;"> | |||||
| {{if .params}} | |||||
| {{if ne 0 (len .params)}} | |||||
| {{range $k ,$v := .params}} | |||||
| <div class="two fields width85" id="para{{$k}}"> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
| </div> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
| </div> | |||||
| <span> | |||||
| <i class="trash icon"></i> | |||||
| </span> | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| <div class="required inline unite min_title field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="选择资源规格" style='width:385px' name="resource_spec_id"> | |||||
| {{range .train_resource_specs}} | |||||
| <option name="resource_spec_id" value="{{.Id}}">GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </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="{{.RepoLink}}/modelarts/train-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||||
| </div> | |||||
| <!-- 模态框 --> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| <script> | |||||
| //let url_href = window.location.pathname.split('create')[0] | |||||
| //$(".ui.button").attr('href',url_href) | |||||
| $('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()) | |||||
| }) | |||||
| }); | |||||
| $('.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(); | |||||
| function validate(){ | |||||
| $('.ui.form') | |||||
| .form({ | |||||
| on: 'blur', | |||||
| fields: { | |||||
| boot_file: { | |||||
| identifier : 'boot_file', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/.+\.py$/g]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| attachment:{ | |||||
| identifier : 'attachment', | |||||
| rules: [ | |||||
| { | |||||
| type: 'empty', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| work_server_number: { | |||||
| identifier : 'work_server_number', | |||||
| rules: [ | |||||
| { | |||||
| type : 'integer[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) | |||||
| } | |||||
| function get_name(){ | |||||
| let name1=$("#engine_name .text").text() | |||||
| let name2=$("#flaver_name .text").text() | |||||
| $("input#ai_engine_name").val(name1) | |||||
| $("input#ai_flaver_name").val(name2) | |||||
| } | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | |||||
| get_name() | |||||
| send_run_para() | |||||
| validate() | |||||
| }) | |||||
| </script> | |||||
| @@ -0,0 +1,731 @@ | |||||
| {{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; | |||||
| padding-top: 0.5rem; | |||||
| } | |||||
| </style> | |||||
| <div id="mask"> | |||||
| <div id="loadingPage"> | |||||
| <div class="rect1"></div> | |||||
| <div class="rect2"></div> | |||||
| <div class="rect3"></div> | |||||
| <div class="rect4"></div> | |||||
| <div class="rect5"></div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="repository"> | |||||
| {{template "repo/header" .}} | |||||
| <div class="ui container"> | |||||
| <h4 class="ui header" id="vertical-segment"> | |||||
| <div class="ui breadcrumb"> | |||||
| <a class="section" href="{{.RepoLink}}/debugjob?debugListType=all"> | |||||
| {{.i18n.Tr "repo.cloudbrain"}} | |||||
| </a> | |||||
| <div class="divider"> / </div> | |||||
| <a class="section" href="{{$.RepoLink}}/modelarts/train-job"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job"}} | |||||
| </a> | |||||
| <div class="divider"> / </div> | |||||
| <div class="active section">{{.displayJobName}}</div> | |||||
| </div> | |||||
| </h4> | |||||
| {{range $k ,$v := .version_list_task}} | |||||
| <div class="ui accordion border-according" id="accordion{{.VersionName}}" | |||||
| data-repopath="{{$.RepoRelPath}}/cloudbrain" data-jobid="{{.ID}}" data-version="{{.VersionName}}"> | |||||
| <input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | |||||
| <div class="{{if eq $k 0}}active{{end}} title padding0"> | |||||
| <div class="according-panel-heading"> | |||||
| <div class="accordion-panel-title"> | |||||
| <i class="dropdown icon"></i> | |||||
| <span class="accordion-panel-title-content"> | |||||
| <span> | |||||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | |||||
| <span class="cti-mgRight-sm">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||||
| <span id="{{.VersionName}}-status-span"><i id="icon" | |||||
| style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" | |||||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||||
| </span> | |||||
| <span | |||||
| class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||||
| <span class="cti-mgRight-sm uc-accordionTitle-black" | |||||
| id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||||
| </div> | |||||
| </span> | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="{{if eq $k 0}}active{{end}} 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{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||||
| <a class="item" data-tab="second{{$k}}" | |||||
| onclick="javascript:parseInfo()">{{$.i18n.Tr "repo.cloudbrain.runinfo"}}</a> | |||||
| <a class="item" data-tab="third{{$k}}" | |||||
| onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||||
| <a class="item" data-tab="four{{$k}}" | |||||
| onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | |||||
| </div> | |||||
| <div class="ui tab active" data-tab="first{{$k}}"> | |||||
| <div style="padding-top: 10px;"> | |||||
| <div class="tab_2_content"> | |||||
| <div class="ac-grid ac-grid-col2"> | |||||
| <div class="ac-grid-col"> | |||||
| <table class="ti-form"> | |||||
| <tbody class="ti-text-form"> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.cloudbrain_task"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{.DisplayJobName}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.status"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" id="{{.VersionName}}-status"> | |||||
| {{.Status}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| <span style="font-size: 12px;" | |||||
| class="">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" | |||||
| 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 "repo.modelarts.train_job.resource_type"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{$.resource_type}} | |||||
| </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"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{$.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{$.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{$.ShareMemMiB}} | |||||
| </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"> | |||||
| {{.Image}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.code_version"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{.BranchName}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.start_file"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{.BootFile}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.train_dataset"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w"> | |||||
| {{.DatasetName}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.run_parameter"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" title="{{.Parameters}}"> | |||||
| {{.Parameters}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| <tr class="ti-no-ng-animate"> | |||||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||||
| </td> | |||||
| <td class="ti-text-form-content"> | |||||
| <div class="text-span text-span-w" title="{{.Description}}"> | |||||
| {{.Description}} | |||||
| </div> | |||||
| </td> | |||||
| </tr> | |||||
| </tbody> | |||||
| </table> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui tab" data-tab="second{{$k}}"> | |||||
| <div> | |||||
| <div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
| <div id="header"></div> | |||||
| </div> | |||||
| <div class="ui attached log" id="log{{.VersionName}}" | |||||
| style="height: 390px !important; overflow: auto;"> | |||||
| <input type="hidden" id="json_value" value="{{$.result.JobStatus.AppExitDiagnostics}}"> | |||||
| <input type="hidden" id="ExitDiagnostics" value="{{$.ExitDiagnostics}}"> | |||||
| <span id="info_display" class="info_text"> | |||||
| </span> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui tab" data-tab="third{{$k}}"> | |||||
| <div> | |||||
| <div class="ui message message{{.VersionName}}" style="display: none;"> | |||||
| <div id="header"></div> | |||||
| </div> | |||||
| <div class="ui attached log" id="log{{.VersionName}}" | |||||
| style="height: 300px !important; overflow: auto;"> | |||||
| <input type="hidden" name="end_line" value> | |||||
| <input type="hidden" name="start_line" value> | |||||
| <pre id="log_file{{.VersionName}}"></pre> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui tab" data-tab="four{{$k}}"> | |||||
| <input type="hidden" name="model{{.VersionName}}" value="-1"> | |||||
| <input type="hidden" name="modelback{{.VersionName}}" value="-1"> | |||||
| <div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'> | |||||
| <div class="active section">{{.VersionName}}</div> | |||||
| <div class="divider"> / </div> | |||||
| </div> | |||||
| <div id="dir_list{{.VersionName}}"> | |||||
| </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> 删除任务 | |||||
| </div> | |||||
| <div class="content"> | |||||
| <p>你确认删除该任务么?此任务一旦删除不可恢复。</p> | |||||
| </div> | |||||
| <div class="actions"> | |||||
| <div class="ui red basic inverted cancel button"> | |||||
| <i class="remove icon"></i> 取消操作 | |||||
| </div> | |||||
| <div class="ui green basic inverted ok button"> | |||||
| <i class="checkmark icon"></i> 确定操作 | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| <script> | |||||
| $('.menu .item').tab() | |||||
| $(document).ready(function () { | |||||
| $('.ui.accordion').accordion({ selector: { trigger: '.icon' } }); | |||||
| }); | |||||
| $(document).ready(function () { | |||||
| $('.secondary.menu .item').tab(); | |||||
| }); | |||||
| let userName | |||||
| let repoPath | |||||
| let jobID | |||||
| let downlaodFlag = {{ $.canDownload }} | |||||
| let taskID = {{ $.task.ID }} | |||||
| let realJobName = {{ $.task.JobName }} | |||||
| $(document).ready(function () { | |||||
| let url = window.location.href; | |||||
| let urlArr = url.split('/') | |||||
| userName = urlArr.slice(-5)[0] | |||||
| repoPath = urlArr.slice(-4)[0] | |||||
| jobID = urlArr.slice(-1)[0] | |||||
| }) | |||||
| function stopBubbling(e) { | |||||
| e = window.event || e; | |||||
| if (e.stopPropagation) { | |||||
| e.stopPropagation(); //阻止事件 冒泡传播 | |||||
| } else { | |||||
| e.cancelBubble = true; //ie兼容 | |||||
| } | |||||
| } | |||||
| function loadLog(version_name) { | |||||
| document.getElementById("mask").style.display = "block" | |||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${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${version_name}`).text(data.Content) | |||||
| document.getElementById("mask").style.display = "none" | |||||
| }).fail(function (err) { | |||||
| console.log(err); | |||||
| document.getElementById("mask").style.display = "none" | |||||
| }); | |||||
| } | |||||
| function loadModelFile(version_name, parents, filename, init) { | |||||
| parents = parents || '' | |||||
| filename = filename || '' | |||||
| init = init || '' | |||||
| console.log("start") | |||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/train-job/${jobID}/model_list?version_name=${version_name}&parentDir=${parents}`, (data) => { | |||||
| $(`#dir_list${version_name}`).empty() | |||||
| renderDir(data, version_name) | |||||
| if (init === "init") { | |||||
| $(`input[name=model${version_name}]`).val("") | |||||
| $(`input[name=modelback${version_name}]`).val(version_name) | |||||
| $(`#file_breadcrumb${version_name}`).empty() | |||||
| let htmlBread = "" | |||||
| htmlBread += `<div class='active section'>${version_name}</div>` | |||||
| htmlBread += "<div class='divider'> / </div>" | |||||
| $(`#file_breadcrumb${version_name}`).append(htmlBread) | |||||
| } else { | |||||
| renderBrend(version_name, parents, filename, init) | |||||
| } | |||||
| }).fail(function (err) { | |||||
| console.log(err, version_name); | |||||
| }); | |||||
| } | |||||
| function renderBrend(version_name, parents, filename, init) { | |||||
| if (init == "folder") { | |||||
| let htmlBrend = "" | |||||
| let sectionName = $(`#file_breadcrumb${version_name} .active.section`).text() | |||||
| let parents1 = $(`input[name=model${version_name}]`).val() | |||||
| let filename1 = $(`input[name=modelback${version_name}]`).val() | |||||
| if (parents1 === "") { | |||||
| $(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','','init')">${sectionName}</a>`) | |||||
| } else { | |||||
| $(`#file_breadcrumb${version_name} .active.section`).replaceWith(`<a class='section' onclick="loadModelFile('${version_name}','${parents1}','${filename1}')">${sectionName}</a>`) | |||||
| } | |||||
| htmlBrend += `<div class='active section'>${filename}</div>` | |||||
| htmlBrend += "<div class='divider'> / </div>" | |||||
| $(`#file_breadcrumb${version_name}`).append(htmlBrend) | |||||
| $(`input[name=model${version_name}]`).val(parents) | |||||
| $(`input[name=modelback${version_name}]`).val(filename) | |||||
| } else { | |||||
| $(`input[name=model${version_name}]`).val(parents) | |||||
| $(`input[name=modelback${version_name}]`).val(filename) | |||||
| $(`#file_breadcrumb${version_name} a.section:contains(${filename})`).nextAll().remove() | |||||
| $(`#file_breadcrumb${version_name} a.section:contains(${filename})`).replaceWith(`<div class='active section'>${filename}</div>`) | |||||
| $(`#file_breadcrumb${version_name} div.section:contains(${filename})`).append("<div class='divider'> / </div>") | |||||
| } | |||||
| } | |||||
| function renderDir(data, version_name) { | |||||
| let html = "" | |||||
| html += "<div class='ui grid' style='margin:0;'>" | |||||
| html += "<div class='row' style='padding: 0;'>" | |||||
| html += "<div class='ui sixteen wide column' style='padding:1rem;'>" | |||||
| html += "<div class='dir list'>" | |||||
| html += "<table id='repo-files-table' class='ui single line table pad20'>" | |||||
| html += '<tbody>' | |||||
| // html += "</tbody>" | |||||
| for (let i = 0; i < data.Dirs.length; i++) { | |||||
| let dirs_size = renderSize(data.Dirs[i].Size) | |||||
| html += "<tr>" | |||||
| html += "<td class='name six wid'>" | |||||
| html += "<span class='truncate'>" | |||||
| html += "<span class='octicon octicon-file-directory'>" | |||||
| html += "</span>" | |||||
| if (data.Dirs[i].IsDir) { | |||||
| html += `<a onclick="loadModelFile('${version_name}','${data.Dirs[i].ParenDir}','${data.Dirs[i].FileName}','folder')">` | |||||
| html += "<span class='fitted'><i class='folder icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | |||||
| } else { | |||||
| if (downlaodFlag) { | |||||
| html += `<a href="${location.href}/download_model?version_name=${version_name}&fileName=${data.Dirs[i].FileName}&parentDir=${data.Dirs[i].ParenDir}&jobName=${realJobName}">` | |||||
| } | |||||
| else { | |||||
| html += `<a class="disabled">` | |||||
| } | |||||
| html += "<span class='fitted'><i class='file icon' width='16' height='16' aria-hidden='true'></i>" + data.Dirs[i].FileName + "</span>" | |||||
| } | |||||
| html += '</a>' | |||||
| html += "</span>" | |||||
| html += "</td>" | |||||
| html += "<td class='message seven wide'>" | |||||
| if (data.Dirs[i].IsDir) { | |||||
| html += "<span class='truncate has-emoji'></span>" | |||||
| } else { | |||||
| html += "<span class='truncate has-emoji'>" + `${dirs_size}` + "</span>" | |||||
| } | |||||
| html += "</td>" | |||||
| html += "<td class='text right age three wide'>" | |||||
| html += "<span class='truncate has-emoji'>" + data.Dirs[i].ModTime + "</span>" | |||||
| html += "</td>" | |||||
| html += "</tr>" | |||||
| } | |||||
| html += "</tbody>" | |||||
| html += "</table>" | |||||
| html += "</div>" | |||||
| html += "</div>" | |||||
| html += "</div>" | |||||
| html += "</div>" | |||||
| $(`#dir_list${version_name}`).append(html) | |||||
| } | |||||
| function renderSize(value) { | |||||
| if (null == value || value == '') { | |||||
| return "0 Bytes"; | |||||
| } | |||||
| var unitArr = new Array("Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"); | |||||
| var index = 0; | |||||
| var srcsize = parseFloat(value); | |||||
| index = Math.floor(Math.log(srcsize) / Math.log(1024)); | |||||
| var size = srcsize / Math.pow(1024, index); | |||||
| size = size.toFixed(0);//保留的小数位数 | |||||
| return size + unitArr[index]; | |||||
| } | |||||
| function refreshStatus(version_name) { | |||||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${taskID}?version_name=${versionname}`, (data) => { | |||||
| // header status and duration | |||||
| //$(`#${version_name}-duration-span`).text(data.JobDuration) | |||||
| $(`#${version_name}-status-span span`).text(data.JobStatus) | |||||
| $(`#${version_name}-status-span i`).attr("class", data.JobStatus) | |||||
| // detail status and duration | |||||
| //$('#'+version_name+'-duration').text(data.JobDuration) | |||||
| $('#' + version_name + '-status').text(data.JobStatus) | |||||
| loadLog(version_name) | |||||
| }).fail(function (err) { | |||||
| console.log(err); | |||||
| }); | |||||
| stopBubbling(arguments.callee.caller.arguments[0]) | |||||
| } | |||||
| function parseInfo() { | |||||
| let jsonValue = document.getElementById("json_value").value; | |||||
| let jsonObj = JSON.parse(jsonValue); | |||||
| let podRoleName = jsonObj["podRoleName"]; | |||||
| let html = ""; | |||||
| if (podRoleName != null) { | |||||
| let task0 = podRoleName["task1-0"]; | |||||
| let podEvents = jsonObj["podEvents"]; | |||||
| let podEventArray = podEvents[task0]; | |||||
| if (podEventArray != null) { | |||||
| for (var i = 0; i < podEventArray.length; i++) { | |||||
| if (podEventArray[i]["reason"] != "") { | |||||
| html += "<p><b>[" + podEventArray[i]["reason"] + "]</b></p>"; | |||||
| html += "<p>" + podEventArray[i]["message"] + "</p>"; | |||||
| html += "<p>" + podEventArray[i]["action"] + "</p>"; | |||||
| } | |||||
| } | |||||
| } | |||||
| let extras = jsonObj["extras"]; | |||||
| if (extras != null) { | |||||
| for (var i = 0; i < extras.length; i++) { | |||||
| if (extras[i]["reason"] != "") { | |||||
| html += "<p><b>[" + extras[i]["reason"] + "]</b></p>"; | |||||
| html += "<p>" + extras[i]["message"] + "</p>"; | |||||
| html += "<p>" + extras[i]["action"] + "</p>"; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| let string = document.getElementById("ExitDiagnostics").value; | |||||
| string = string.replace(/\r\n/g, "<br>") | |||||
| string = string.replace(/\n/g, "<br>"); | |||||
| string = string.replace(/(\r\n)|(\n)/g, '<br>'); | |||||
| if (string != "") { | |||||
| html += "<p><b>[ExitDiagnostics]</b></p>"; | |||||
| html += "<p>" + string + "</p>"; | |||||
| } | |||||
| document.getElementById("info_display").innerHTML = html; | |||||
| } | |||||
| </script> | |||||
| @@ -0,0 +1,475 @@ | |||||
| {{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; | |||||
| } | |||||
| </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="{{.Link}}" method="post"> | |||||
| {{.CsrfTokenHtml}} | |||||
| <input type="hidden" name="action" value="update"> | |||||
| <input type="hidden" id="ai_engine_name" name="engine_names" value=""> | |||||
| <input type="hidden" id="ai_flaver_name" name="flaver_names" value=""> | |||||
| <h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||||
| <div class="ui blue mini menu compact selectcloudbrain"> | |||||
| <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 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"/> | |||||
| </svg> | |||||
| Ascend NPU</a> | |||||
| </div> | |||||
| </div> | |||||
| <div class="required unite min_title inline field"> | |||||
| <label 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="64"> | |||||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||||
| </div> | |||||
| <div class="unite min_title inline field"> | |||||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="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> | |||||
| </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 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="required unite min_title inline fields" style="width: 90%;"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}} </label> | |||||
| <div class="field" style="flex: 1.5;"> | |||||
| <select class="ui dropdown width" id="trainjob_engines" > | |||||
| {{range .engines}} | |||||
| <option value="{{.Value}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| <div class="field" style="flex: 2;" id="engine_name"> | |||||
| <select class="ui dropdown width" id="trainjob_engine_versions" style='width: 100%;' name="engine_id"> | |||||
| {{range .engine_versions}} | |||||
| <option name="engine_id" value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| </div> | |||||
| <div class="inline unite min_title field required"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||||
| {{if .bootFile}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||||
| {{else}} | |||||
| <input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||||
| {{end}} | |||||
| <span> | |||||
| <i class="question circle icon link" data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} data-position="right center" data-variation="mini"></i> | |||||
| </span> | |||||
| <a href="https://git.openi.org.cn/OpenIOSSG/MINIST_Example" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||||
| </div> | |||||
| {{template "custom/select_dataset_train" .}} | |||||
| <span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 2rem;">{{.i18n.Tr "cloudbrain.dataset_path_rule"}}</span> | |||||
| <div class="inline unite min_title field"> | |||||
| <label 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;"> | |||||
| {{if ne 0 (len .params)}} | |||||
| {{range $k ,$v := .params}} | |||||
| <div class="two fields width85" id="para{{$k}}"> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||||
| </div> | |||||
| <div class="field"> | |||||
| <input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||||
| </div> | |||||
| <span> | |||||
| <i class="trash icon"></i> | |||||
| </span> | |||||
| </div> | |||||
| {{end}} | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| <div class="required field " style="display: none;"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | |||||
| <select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | |||||
| {{range .resource_pools}} | |||||
| <option value="{{.ID}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </div> | |||||
| <div class="required grouped fields" style="display: none;"> | |||||
| <label style="font-weight: normal;" 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" id="flaver_name"> | |||||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||||
| <select class="ui dropdown width81" id="trainjob-flavor" style='width:385px' name="flavor"> | |||||
| {{range .flavor_infos}} | |||||
| <option name="flavor" value="{{.Code}}">{{.Value}}</option> | |||||
| {{end}} | |||||
| </select> | |||||
| </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="ui labeled input" style="width: 5%;"> | |||||
| <input style="border-radius: 0;text-align: center;"type="hidden" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | |||||
| <div class="field" id="trainjob_work_server_num_select" name="work_server_number_select"> | |||||
| <select class="ui dropdown width" style='width: 100%;' name="work_server_id"> | |||||
| <option name="server_id" value="1">1</option> | |||||
| <option name="server_id" value="2">2</option> | |||||
| </select> | |||||
| </div> | |||||
| </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> | |||||
| let url_href = window.location.pathname.split('create')[0] | |||||
| $(".ui.button").attr('href',url_href) | |||||
| $('select.dropdown') | |||||
| .dropdown(); | |||||
| $('.menu .item') | |||||
| .tab(); | |||||
| // let sever_num = $("#trainjob_work_server_num_select .text").text() //$('#trainjob_work_server_num') | |||||
| // console.log("sever_num:",sever_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()) | |||||
| }) | |||||
| }); | |||||
| $('.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(); | |||||
| function validate(){ | |||||
| $('.ui.form') | |||||
| .form({ | |||||
| on: 'blur', | |||||
| fields: { | |||||
| boot_file: { | |||||
| identifier : 'boot_file', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/.+\.py$/g]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| display_job_name:{ | |||||
| identifier : 'display_job_name', | |||||
| rules: [ | |||||
| { | |||||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| attachment:{ | |||||
| identifier : 'attachment', | |||||
| rules: [ | |||||
| { | |||||
| type: 'empty', | |||||
| } | |||||
| ] | |||||
| }, | |||||
| work_server_number: { | |||||
| identifier : 'work_server_number', | |||||
| rules: [ | |||||
| { | |||||
| type : 'integer[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) | |||||
| } | |||||
| function get_name(){ | |||||
| let name1=$("#engine_name .text").text() | |||||
| let name2=$("#flaver_name .text").text() | |||||
| $("input#ai_engine_name").val(name1) | |||||
| $("input#ai_flaver_name").val(name2) | |||||
| let val_server_num_select = $("#trainjob_work_server_num_select .text").text() | |||||
| // console.log("val_server_num_select:",val_server_num_select) | |||||
| $("input#trainjob_work_server_num").val(val_server_num_select) | |||||
| } | |||||
| $('.ui.create_train_job.green.button').click(function(e) { | |||||
| get_name() | |||||
| send_run_para() | |||||
| validate() | |||||
| }) | |||||
| </script> | |||||