Browse Source

Merge branch 'liuzx_trainjob' of https://git.openi.org.cn/OpenI/aiforge into liuzx_trainjob

update
.
pull/883/head
liuzx 3 years ago
parent
commit
02bcfbe072
7 changed files with 204 additions and 46 deletions
  1. +1
    -0
      options/locale/locale_en-US.ini
  2. +3
    -1
      options/locale/locale_zh-CN.ini
  3. +13
    -1
      templates/repo/cloudbrain/show.tmpl
  4. +13
    -1
      templates/repo/modelarts/notebook/show.tmpl
  5. +4
    -2
      templates/repo/modelarts/trainjob/new.tmpl
  6. +164
    -41
      templates/repo/modelarts/trainjob/show.tmpl
  7. +6
    -0
      templates/repo/modelarts/trainjob/version_new.tmpl

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

@@ -846,6 +846,7 @@ modelarts.train_job.start_file=Start File
modelarts.train_job.boot_file_helper=The startup file is the entry file that your program executes, and it must be a file ending in .py modelarts.train_job.boot_file_helper=The startup file is the entry file that your program executes, and it must be a file ending in .py
modelarts.train_job.dataset=Dataset modelarts.train_job.dataset=Dataset
modelarts.code_version = Code Version modelarts.code_version = Code Version
modelarts.parents_version = Parents Version
modelarts.train_job.run_parameter=Run Parameter modelarts.train_job.run_parameter=Run Parameter
modelarts.train_job.add_run_parameter=Add Run Parameter modelarts.train_job.add_run_parameter=Add Run Parameter
modelarts.train_job.parameter_name=Parameter Name modelarts.train_job.parameter_name=Parameter Name


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

@@ -849,7 +849,9 @@ modelarts.train_job.start_file=启动文件
modelarts.train_job.boot_file_helper=启动文件是您程序执行的入口文件,必须是以.py结尾的文件。 modelarts.train_job.boot_file_helper=启动文件是您程序执行的入口文件,必须是以.py结尾的文件。
modelarts.train_job.boot_file_place=填写启动文件路径,默认为train.py modelarts.train_job.boot_file_place=填写启动文件路径,默认为train.py
modelarts.train_job.dataset=数据集 modelarts.train_job.dataset=数据集
modelarts.code_version=代码版本
modelarts.code_version=代码分支
modelarts.parents_version=基于版本

modelarts.train_job.run_parameter=运行参数 modelarts.train_job.run_parameter=运行参数
modelarts.train_job.add_run_parameter=增加运行参数 modelarts.train_job.add_run_parameter=增加运行参数
modelarts.train_job.parameter_name=参数名 modelarts.train_job.parameter_name=参数名


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

@@ -6,7 +6,19 @@
{{template "base/alert" .}} {{template "base/alert" .}}


<h4 class="ui header" id="vertical-segment"> <h4 class="ui header" id="vertical-segment">
<a href="javascript:window.history.back();"><i class="arrow left icon"></i>返回</a>
<div class="ui breadcrumb">
<a class="section" href="{{.RepoLink}}/cloudbrain">
{{.i18n.Tr "repo.cloudbrain"}}
</a>
<div class="divider"> / </div>
<a class="section" href="{{.RepoLink}}/modelarts/notebook">
{{$.i18n.Tr "repo.modelarts.notebook"}}
</a>
<div class="divider"> / </div>
{{with .task}}
<div class="active section">{{.JobName}}</div>
{{end}}
</div>
</h4> </h4>
<div> <div>
<div class="ui yellow segment"> <div class="ui yellow segment">


+ 13
- 1
templates/repo/modelarts/notebook/show.tmpl View File

@@ -6,7 +6,19 @@
{{template "base/alert" .}} {{template "base/alert" .}}


<h4 class="ui header" id="vertical-segment"> <h4 class="ui header" id="vertical-segment">
<a href="javascript:window.history.back();"><i class="arrow left icon"></i>返回</a>
<div class="ui breadcrumb">
<a class="section" href="{{.RepoLink}}/cloudbrain">
{{.i18n.Tr "repo.cloudbrain"}}
</a>
<div class="divider"> / </div>
<a class="section" href="{{.RepoLink}}/cloudbrain">
{{$.i18n.Tr "repo.modelarts.notebook"}}
</a>
<div class="divider"> / </div>
{{with .task}}
<div class="active section">{{.JobName}}</div>
{{end}}
</div>
</h4> </h4>
<div> <div>
<div class="ui yellow segment"> <div class="ui yellow segment">


+ 4
- 2
templates/repo/modelarts/trainjob/new.tmpl View File

@@ -103,7 +103,9 @@
-webkit-animation-delay: -0.8s; -webkit-animation-delay: -0.8s;
animation-delay: -0.8s; animation-delay: -0.8s;
} }
.left2{
margin-left: -2px;
}
@-webkit-keyframes sk-stretchdelay { @-webkit-keyframes sk-stretchdelay {
0%, 0%,
40%, 40%,
@@ -172,7 +174,7 @@


<div class="required unite min_title inline field"> <div class="required unite min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.code_version"}}</label> <label>{{.i18n.Tr "repo.modelarts.code_version"}}</label>
<select class="ui dropdown width80" id="code_version" name="branch_name">
<select class="ui dropdown width80 left2" id="code_version" name="branch_name">
{{range $k, $v :=.Branches}} {{range $k, $v :=.Branches}}
<option name="branch_name" value="{{$v}}">{{$v}}</option> <option name="branch_name" value="{{$v}}">{{$v}}</option>
{{end}} {{end}}


+ 164
- 41
templates/repo/modelarts/trainjob/show.tmpl View File

@@ -149,17 +149,37 @@ td, th {
pointer-events: none; pointer-events: none;
color: rgba(0,0,0,.6) !important; color: rgba(0,0,0,.6) !important;
opacity: .45 !important; opacity: .45 !important;
}
}
.pad20{
border:0px !important;
}
.model_file_bread{
margin-bottom: -0.5rem !important;
padding-left: 1rem;
padding-top: 0.5rem ;
}
</style> </style>
<div class="repository"> <div class="repository">
{{template "repo/header" .}} {{template "repo/header" .}}
<div class="ui container"> <div class="ui container">
<h4 class="ui header" id="vertical-segment"> <h4 class="ui header" id="vertical-segment">
<a href="javascript:window.history.back();"><i class="arrow left icon"></i>返回</a>
<!-- <a href="javascript:window.history.back();"><i class="arrow left icon"></i>返回</a> -->
<div class="ui breadcrumb">
<a class="section" href="{{.RepoLink}}/cloudbrain">
{{.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"></div>
</div>
</h4> </h4>
{{range $k ,$v := .version_list_task}} {{range $k ,$v := .version_list_task}}
<div class="ui accordion border-according" id="accordion{{.VersionName}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> <div class="ui accordion border-according" id="accordion{{.VersionName}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}">
<div class="title padding0">
<div class="{{if eq $k 0}}active{{end}} title padding0">
<div class="according-panel-heading"> <div class="according-panel-heading">
<div class="accordion-panel-title"> <div class="accordion-panel-title">
<i class="dropdown icon"></i> <i class="dropdown icon"></i>
@@ -190,12 +210,13 @@ td, th {
</div> </div>
</div> </div>
</div> </div>
<div class="content accordion-border">
<div class="{{if eq $k 0}}active{{end}} content accordion-border">
<div class="content-pad"> <div class="content-pad">
<div class="ui pointing secondary menu"> <div class="ui pointing secondary menu">
<a class="active item" data-tab="first{{$k}}">配置信息</a> <a class="active item" data-tab="first{{$k}}">配置信息</a>
<a class="item" data-tab="second{{$k}}" onclick="loadLog({{.VersionName}})">日志文件</a> <a class="item" data-tab="second{{$k}}" onclick="loadLog({{.VersionName}})">日志文件</a>
<!-- <a class="item" data-tab="third{{$k}}" href="{{$.Link}}/models?version_name={{.VersionName}}" target="_blank">模型下载</a> -->
<a class="item" data-tab="third{{$k}}" onclick="loadModelFile({{.VersionName}},'','','init')">模型下载</a>
</div> </div>
<div class="ui tab active" data-tab="first{{$k}}"> <div class="ui tab active" data-tab="first{{$k}}">
<div style="padding-top: 10px;"> <div style="padding-top: 10px;">
@@ -300,7 +321,7 @@ td, th {
</tr> </tr>
<tr class="ti-no-ng-animate"> <tr class="ti-no-ng-animate">
<td class="ti-no-ng-animate ti-text-form-label text-width80"> <td class="ti-no-ng-animate ti-text-form-label text-width80">
代码分支
{{$.i18n.Tr "repo.modelarts.code_version"}}
</td> </td>
<td class="ti-text-form-content"> <td class="ti-text-form-content">
@@ -374,7 +395,7 @@ td, th {
</div> </div>
<div class="ui tab" data-tab="second{{$k}}"> <div class="ui tab" data-tab="second{{$k}}">
<div> <div>
<div class="ui message" style="display: none;">
<div class="ui message{{.VersionName}}" style="display: none;">
<div id="header"></div> <div id="header"></div>
</div> </div>
<div class="ui top attached segment" style="background: #f0f0f0;"> <div class="ui top attached segment" style="background: #f0f0f0;">
@@ -387,8 +408,8 @@ td, th {
</div> </div>
</div> </div>
<div class="ui attached segment log" style="height: 300px !important; overflow: auto;">
<input type="hidden" class="version_name" name="version_name" value={{.VersionName}}>
<div class="ui attached segment log" onscroll="logScroll({{.VersionName}})" id="log{{.VersionName}}" style="height: 300px !important; overflow: auto;">
<!-- <input type="hidden" class="version_name" name="version_name" value={{.VersionName}}> -->
<input type="hidden" name="end_line" value> <input type="hidden" name="end_line" value>
<input type="hidden" name="start_line" value> <input type="hidden" name="start_line" value>
<pre id="log_file{{.VersionName}}"></pre> <pre id="log_file{{.VersionName}}"></pre>
@@ -397,11 +418,18 @@ td, th {
</div> </div>
</div> </div>
<!-- <div class="ui tab" data-tab="third{{$k}}">
<div>
<div class="ui tab" data-tab="third{{$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> </div>
</div> </div>
@@ -432,7 +460,6 @@ td, th {
{{template "base/footer" .}} {{template "base/footer" .}}


<script> <script>
console.log({{.version_list_task}})
$('.menu .item').tab() $('.menu .item').tab()
// $('.ui.style.accordion').accordion(); // $('.ui.style.accordion').accordion();
@@ -464,9 +491,12 @@ td, th {
} }
// var timeid = window.setInterval(refreshStatus(version_name), 30000); // var timeid = window.setInterval(refreshStatus(version_name), 30000);
// document.ready(refreshStatus(version_name)) // document.ready(refreshStatus(version_name))
var timeid = window.setInterval(loadJobStatus, 30000);
$(document).ready(loadJobStatus);


function loadJobStatus() { function loadJobStatus() {
$(".ui.accordion.border-according").each((index, job) => { $(".ui.accordion.border-according").each((index, job) => {
const jobID = job.dataset.jobid; const jobID = job.dataset.jobid;
const repoPath = job.dataset.repopath; const repoPath = job.dataset.repopath;
const versionname = job.dataset.version const versionname = job.dataset.version
@@ -477,9 +507,15 @@ td, th {
} }


$.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => { $.get(`/api/v1/repos/${repoPath}/modelarts/train-job/${jobID}?version_name=${versionname}`, (data) => {
const jobID = data.JobID
const status = data.JobStatus
const duration = data.JobDuration
// const jobID = data.JobID
// const status = data.JobStatus
// const duration = data.JobDuration
$(`#${versionname}-duration-span`).text(data.JobDuration)
$(`#${versionname}-status-span span`).text(data.JobStatus)
$(`#${versionname}-status-span i`).attr("class",data.JobStatus)
// detail status and duration
$('#'+versionname+'-duration').text(data.JobDuration)
$('#'+versionname+'-status').text(data.JobStatus)
// $('#duration-'+jobID).text(duration) // $('#duration-'+jobID).text(duration)
// if (status != job.textContent.trim()) { // if (status != job.textContent.trim()) {
// $('#' + jobID+'-icon').removeClass().addClass(status) // $('#' + jobID+'-icon').removeClass().addClass(status)
@@ -553,51 +589,138 @@ td, th {
console.log(err); console.log(err);
}); });
} }
// function loadModelFile(version_name){
// $.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/model_list?version_name=${version_name}&lines=20&order=asc`, (data) => {
// console.log(data)
// }).fail(function(err) {
// console.log(err);
// });
// }
$(".log").scroll(function () {
var scrollTop = $(this)[0].scrollTop; // 滚动距离
var scrollHeight = $(this)[0].scrollHeight; // 文档高度
var divHeight = $(this).height(); // 可视区高度
let version_name=$(this).find('input[name=version_name]').val()
function loadModelFile(version_name,parents,filename,init){
parents = parents || ''
filename = filename || ''
init = init || ''
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/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++){
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{
html += `<a href='${location.href}/download_model?parentDir=&fileName=${data.Dirs[i].FileName}&jobName=${data.task.JobName}'>`
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'>"
html += "<span class='truncate has-emoji'>" + data.Dirs[i].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)
}
// $(`.log{}`).scroll()
function logScroll(version_name) {
var scrollTop = $(`#log${version_name}`)[0].scrollTop; // 滚动距离
var scrollHeight = $(`#log${version_name}`)[0].scrollHeight; // 文档高度
var divHeight = $(`#log${version_name}`).height(); // 可视区高度
// let version_name=$(this).find('input[name=version_name]').val()
console.log("scrollTo,scrollHeight,divHeight",scrollTop,scrollHeight,divHeight)
if(parseInt(scrollTop) + divHeight + 18 == scrollHeight){ if(parseInt(scrollTop) + divHeight + 18 == scrollHeight){
var end_line = $('input[name=end_line]').val()
var end_line = $(`#log${version_name} input[name=end_line]`).val()
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=${end_line}&order=desc`, (data) => { $.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=${end_line}&order=desc`, (data) => {
if (data.Lines == 0){ if (data.Lines == 0){
$('#header').text('您已翻阅至日志底部')
$('.message').css('display', 'block')
$(`.message${version_name} #header`).text('您已翻阅至日志底部')
$(`.message${version_name}`).css('display', 'block')
setTimeout(function(){ setTimeout(function(){
$('.message').css('display', 'none')
$(`.message${version_name}`).css('display', 'none')
}, 1000) }, 1000)
}else{ }else{
$('input[name=end_line]').val(data.EndLine)
$('.log').append('<pre>' + data.Content)
$(`#log${version_name} input[name=end_line]`).val(data.EndLine)
$(`#log${version_name}`).append('<pre>' + data.Content)
} }
}).fail(function(err) { }).fail(function(err) {
console.log(err); console.log(err);
}); });
} }
if(scrollTop == 0){ if(scrollTop == 0){
var start_line = $('input[name=start_line]').val()
var start_line = $(`#log${version_name} input[name=start_line]`).val()
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=${start_line}&order=asc`, (data) => { $.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=${start_line}&order=asc`, (data) => {
if (data.Lines == 0){ if (data.Lines == 0){
$('#header').text('您已翻阅至日志顶部')
$('.message').css('display', 'block')
$(`.message${version_name} #header`).text('您已翻阅至日志顶部')
$(`.message${version_name}`).css('display', 'block')
setTimeout(function(){ setTimeout(function(){
$('.message').css('display', 'none')
$(`.message${version_name}`).css('display', 'none')
}, 1000) }, 1000)
}else{ }else{
$('input[name=start_line]').val(data.StartLine) //如果变动就改变所对应的值
$(".log").prepend('<pre>' + data.Content)
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值
$(`#log${version_name}`).prepend('<pre>' + data.Content)
} }
}).fail(function(err) { }).fail(function(err) {
console.log(err); console.log(err);
}); });
} }
})
}
</script> </script>

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

@@ -165,6 +165,11 @@
<input type="hidden" style="width: 60%;" name="job_name" id="trainjob_job_name" value="{{.job_name}}"> <input type="hidden" style="width: 60%;" name="job_name" id="trainjob_job_name" value="{{.job_name}}">
<input style="width: 60%;" value="{{.job_name}}" tabindex="3" disabled > <input style="width: 60%;" value="{{.job_name}}" tabindex="3" disabled >
</div> </div>
<div class="required unite min_title inline field">
<label>{{.i18n.Tr "repo.modelarts.parents_version"}}</label>
<input id="parents_version" style="width: 60%;" value="" tabindex="3" disabled >
</div>
<div class="unite min_title inline field"> <div class="unite min_title inline field">
<label for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label> <label for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}&nbsp;&nbsp;</label>
<textarea style="width: 80%;" id="description" value="{{.description}}" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 256)"></textarea> <textarea style="width: 80%;" id="description" value="{{.description}}" name="description" rows="3" maxlength="255" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 256)"></textarea>
@@ -336,6 +341,7 @@
let url_href = {{.RepoLink}}+'/modelarts/train-job' let url_href = {{.RepoLink}}+'/modelarts/train-job'
let url_post = location.pathname let url_post = location.pathname
let version_name = location.search.split('?version_name=')[1] let version_name = location.search.split('?version_name=')[1]
$("#parents_version").val(version_name)
$(".ui.button").attr('href',url_href) $(".ui.button").attr('href',url_href)
$(".ui.form").attr('action',url_post) $(".ui.form").attr('action',url_post)
$("input[name=version_name]").attr('value',version_name) $("input[name=version_name]").attr('value',version_name)


Loading…
Cancel
Save