Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/2458 Reviewed-by: lewis <747342561@qq.com>fix-2452
@@ -0,0 +1,688 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-US"> | |||
<head data-suburl=""> | |||
<meta charset="utf-8"> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<meta http-equiv="x-ua-compatible" content="ie=edge"> | |||
<title> OpenI</title> | |||
<link rel="manifest" href="/manifest.json" crossorigin="use-credentials"> | |||
<script> | |||
if ('serviceWorker' in navigator) { | |||
navigator.serviceWorker.register('/serviceworker.js').then(function(registration) { | |||
console.info('ServiceWorker registration successful with scope: ', registration.scope); | |||
}, function(err) { | |||
console.info('ServiceWorker registration failed: ', err); | |||
}); | |||
} | |||
</script> | |||
<meta name="theme-color" content="#6cc644"> | |||
<meta name="author" content="OpenI - open i project management" /> | |||
<meta name="description" content="Efficient code management center, you can host and review code" /> | |||
<meta name="keywords" content="OpenI,git"> | |||
<meta name="referrer" content="no-referrer" /> | |||
<meta name="_csrf" content="R3EY-tMaxCo3C6fhAmc_WpVunPc6MTY1NzcwODA3NTE2MjQ4NTgzMQ" /> | |||
<script> | |||
/* | |||
@licstart The following is the entire license notice for the | |||
JavaScript code in this page. | |||
Copyright (c) 2016 The Gitea Authors | |||
Copyright (c) 2015 The Gogs Authors | |||
Permission is hereby granted, free of charge, to any person obtaining a copy | |||
of this software and associated documentation files (the "Software"), to deal | |||
in the Software without restriction, including without limitation the rights | |||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
copies of the Software, and to permit persons to whom the Software is | |||
furnished to do so, subject to the following conditions: | |||
The above copyright notice and this permission notice shall be included in | |||
all copies or substantial portions of the Software. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
THE SOFTWARE. | |||
--- | |||
Licensing information for additional javascript libraries can be found at: | |||
{{StaticUrlPrefix}}/vendor/librejs.html | |||
@licend The above is the entire license notice | |||
for the JavaScript code in this page. | |||
*/ | |||
</script> | |||
<script> | |||
window.config = { | |||
AppSubUrl: '', | |||
StaticUrlPrefix: '', | |||
csrf: 'R3EY-tMaxCo3C6fhAmc_WpVunPc6MTY1NzcwODA3NTE2MjQ4NTgzMQ', | |||
HighlightJS: false, | |||
Minicolors: false, | |||
SimpleMDE: false, | |||
Tribute: false, | |||
U2F: false, | |||
Heatmap: false, | |||
heatmapUser: null, | |||
NotificationSettings: { | |||
MinTimeout: 10000 , | |||
TimeoutStep: 10000 , | |||
MaxTimeout: 60000 , | |||
EventSourceUpdateTime: 10000 , | |||
}, | |||
}; | |||
</script> | |||
<link rel="shortcut icon" href="/img/favicon.png"> | |||
<link rel="mask-icon" href="/img/openi-safari.svg" color="#609926"> | |||
<link rel="fluid-icon" href="/img/gitea-lg.png" title="OpenI"> | |||
<link rel="stylesheet" href="/vendor/assets/font-awesome/css/font-awesome.min.css"> | |||
<link rel="preload" as="font" href="/fomantic/themes/default/assets/fonts/icons.woff2" type="font/woff2" crossorigin="anonymous"> | |||
<link rel="preload" as="font" href="/fomantic/themes/default/assets/fonts/outline-icons.woff2" type="font/woff2" crossorigin="anonymous"> | |||
<link rel="stylesheet" href="/css/git.openi.css"> | |||
<link rel="stylesheet" href="/fomantic/semantic.min.css?v=eef985e4d4b587d055fc7c3eff3f18e9"> | |||
<link rel="stylesheet" href="/css/index.css?v=eef985e4d4b587d055fc7c3eff3f18e9"> | |||
<noscript> | |||
<style> | |||
.dropdown:hover > .menu { display: block; } | |||
.ui.secondary.menu .dropdown.item > .menu { margin-top: 0; } | |||
</style> | |||
</noscript> | |||
<style class="list-search-style"></style> | |||
<meta property="og:title" content="OpenI"> | |||
<meta property="og:type" content="website" /> | |||
<meta property="og:image" content="/img/gitea-lg.png" /> | |||
<meta property="og:url" content="https://git.openi.org.cn/" /> | |||
<meta property="og:description" content="Efficient code management center, you can host and review code"> | |||
<meta property="og:site_name" content="OpenI" /> | |||
<script> | |||
var _hmt = _hmt || []; | |||
(function() { | |||
var hm = document.createElement("script"); | |||
hm.src = "https://hm.baidu.com/hm.js?46149a0b61fdeddfe427ff4de63794ba"; | |||
var s = document.getElementsByTagName("script")[0]; | |||
s.parentNode.insertBefore(hm, s); | |||
})(); | |||
</script> | |||
<script src="/self/func.js" type="text/javascript"></script> | |||
<link rel="stylesheet" href="/RemixIcon_Fonts_v2.5.0/fonts/remixicon.css"> | |||
<link rel="stylesheet" href="/swiper/swiper-bundle.min.css"> | |||
<script src="/swiper/swiper-bundle.min.js"></script> | |||
<link rel="stylesheet" href="/rotation3D/rotation3D.css"> | |||
</head> | |||
<body> | |||
<div class="full height"> | |||
<noscript>This website works better with JavaScript.</noscript> | |||
<div class="ui top secondary stackable main menu following bar dark"> | |||
<div class="ui container" id="navbar"> | |||
<div class="item brand" style="justify-content: space-between;"> | |||
<a href="https://openi.org.cn/"> | |||
<img class="ui mini image" src="/img/logo-w.svg"> | |||
</a> | |||
<div class="ui basic icon button mobile-only" id="navbar-expand-toggle"> | |||
<i class="sidebar icon"></i> | |||
</div> | |||
</div> | |||
<div style="width:1px;background:#606266;height:80%;margin:auto 0.5rem"></div> | |||
<div class="item brand" style="margin-left: 0.9rem;"> | |||
<a href="/"> | |||
<img class="ui mini image" style="height: 1.3rem;" src="/img/git-logo.svg"> | |||
</a> | |||
</div> | |||
<div class="item edge"> | |||
<div class="dropdown-menu"> | |||
<a class=" item lfpd" href="/user/login"> | |||
Home <i class="dropdown icon mglf"></i> | |||
</a> | |||
<div class="dropdown-content" style="min-width: 110px;border-radius:4px;min-width: max-content;"> | |||
<a style="border: none;color: #000;" class=" item" href="/user/login">Issues</a> | |||
<a style="border: none;color: #000; white-space: nowrap;" class=" item" href="/user/login">Pull Requests</a> | |||
<a style="border: none;color: #000;" class=" item" href="/user/login">Milestones</a> | |||
<a style="border: none;color: #000;" class=" item" href="/cloudbrains">Cloudbrain Task</a> | |||
</div> | |||
</div> | |||
</div> | |||
<a class="item" href="/explore/repos">Repositories</a> | |||
<a class="item" href="/explore/datasets">Datasets</a> | |||
<div class="ui simple dropdown item" id='dropdown_PageHome'> | |||
Explore | |||
<i class="dropdown icon"></i> | |||
<div class="menu" > | |||
<a class="item" href="/explore/users">Users</a> | |||
<a class="item" href="/explore/organizations">Organizations</a> | |||
<a class="item" href="/explore/images">Cloudbrain Mirror</a> | |||
<a class="item" href="/OpenI">OpenI Projects</a> | |||
</div> | |||
</div> | |||
<div class="right stackable menu"> | |||
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post"> | |||
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> | |||
<input name="q" value="" placeholder="Search..." | |||
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> | |||
<input type="hidden" name="tab" value=""> | |||
<input type="hidden" name="sort" value="hot"> | |||
<button style="border: none;background-color: #363840;outline: none;border-radius:5px"><img type = "submit" style="width: 25px; height: 25px;margin: auto;" src="/img/search.svg" > | |||
</button> | |||
</div> | |||
</form> | |||
<a class="item" href="/user/sign_up"> | |||
<svg class="svg octicon-person" width="16" height="16" aria-hidden="true"><use xlink:href="#octicon-person" /></svg> Register | |||
</a> | |||
<a class="item" rel="nofollow" href="/user/login"> | |||
<svg class="svg octicon-sign-in" width="16" height="16" aria-hidden="true"><use xlink:href="#octicon-sign-in" /></svg> Sign In | |||
</a> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="notic_content" id ="notic_content" style="display: block; position: relative"> | |||
<div class="ui container"> | |||
<marquee behavior="scroll" direction="left"> | |||
<a href=https://openi.org.cn/html/2022/notices_0701/636.html class="a_width" style = 'margin-left: 0px !important;' target="_blank"> | |||
<i class="ri-arrow-right-s-line"></i> | |||
“我为开源打榜狂”上榜领奖者名单公示1周,10万奖金被瓜分,请大家自行确认>>> | |||
</a> | |||
<a href=https://git.openi.org.cn/OpenIOSSG/promote/src/branch/master/notice/Other_notes/RegisterMobileNumber.md class="a_width" target="_blank"> | |||
<i class="ri-arrow-right-s-line"></i> | |||
7月中下旬登录启智AI协作平台,需登记手机号码啦>>> | |||
</a> | |||
<a href=https://openi.org.cn/html/2022/dongtai_0628/634.html class="a_width" target="_blank"> | |||
<i class="ri-arrow-right-s-line"></i> | |||
智算网络Beta版本上线,大大缩短算力排队时间,速来体验吧~>>> | |||
</a> | |||
<a href=https://wj.qq.com/s2/10362208/5c0c class="a_width" target="_blank"> | |||
<i class="ri-arrow-right-s-line"></i> | |||
启智AI协作平台问卷调查,邀请您参加>>> | |||
</a> | |||
</marquee> | |||
<div class="item right" style="position:absolute;right: 1px;top:0px;"> | |||
<i class="ri-close-fill x_icon" onclick="closeNoice()"></i> | |||
</div> | |||
</div> | |||
</div> | |||
<script> | |||
function closeNoice(){ | |||
document.getElementById("notic_content").style.display='none' | |||
localStorage.setItem("isCloseNotice",true) | |||
} | |||
function isShowNotice(){ | |||
var current_notice = localStorage.getItem("notices") | |||
if (current_notice != "f43dc1a5866fbf7a29c92a1eef3b6a020d4a30de"){ | |||
localStorage.setItem('notices',"f43dc1a5866fbf7a29c92a1eef3b6a020d4a30de"); | |||
isNewNotice=true; | |||
localStorage.setItem("isCloseNotice",false) | |||
}else{ | |||
isNewNotice=false; | |||
} | |||
let isShowNoticeTag = false; | |||
let notices= [{"Title":"“我为开源打榜狂”上榜领奖者名单公示1周,10万奖金被瓜分,请大家自行确认\u003e\u003e\u003e","Link":"https://openi.org.cn/html/2022/notices_0701/636.html","Visible":1},{"Title":"7月中下旬登录启智AI协作平台,需登记手机号码啦\u003e\u003e\u003e","Link":"https://git.openi.org.cn/OpenIOSSG/promote/src/branch/master/notice/Other_notes/RegisterMobileNumber.md","Visible":1},{"Title":"智算网络Beta版本上线,大大缩短算力排队时间,速来体验吧~\u003e\u003e\u003e","Link":"https://openi.org.cn/html/2022/dongtai_0628/634.html","Visible":1},{"Title":"启智AI协作平台问卷调查,邀请您参加\u003e\u003e\u003e","Link":"https://wj.qq.com/s2/10362208/5c0c","Visible":1}] | |||
if(notices != null && notices!=''){ | |||
for (i =0;i<notices.length;i++){ | |||
if (notices[i].Visible==1){ | |||
isShowNoticeTag =true; | |||
break; | |||
} | |||
} | |||
} | |||
if (isShowNoticeTag){ | |||
if(isNewNotice){ | |||
document.getElementById("notic_content").style.display='block' | |||
}else{ | |||
isCloseNotice = localStorage.getItem("isCloseNotice") | |||
if (JSON.parse(isCloseNotice)){ | |||
document.getElementById("notic_content").style.display='none' | |||
}else{ | |||
document.getElementById("notic_content").style.display='block' | |||
} | |||
} | |||
}else{ | |||
if (document.getElementById("notic_content") != null){ | |||
document.getElementById("notic_content").style.display='none' | |||
} | |||
} | |||
} | |||
if(!("" == true || "" =='true')) { | |||
isShowNotice(); | |||
} | |||
</script> | |||
<div class="ui vertical masthead secondary hometop segment"> | |||
<div class="ui container" style="position: relative;"> | |||
<div class="ui center homebanner"> | |||
<h1 class="ui huge header"> | |||
Explore Better AI | |||
<div class="sub header"> | |||
OpenI AI Development Cooperation Platform | |||
</div> | |||
</h1> | |||
<p class="ui am-lh-18">The one-stop collaborative development environment for AI field provides AI development pipeline integrating code development, data management, model debugging, reasoning and evaluation</p> | |||
<a class="circular huge ui secondary button" href="/user/login">Use Now <i class="right arrow icon"></i></a> | |||
</div> | |||
<div class="bannerpic"><img class="ui fluid image" src="/img/gitopeni-index-01.svg"></div> | |||
<div id="homenews"> | |||
<p>* Only show the dynamics of open source projects</p> | |||
<div class="ui grid"> | |||
<div class="sixteen wide mobile twelve wide tablet ten wide computer column homenews"> | |||
<div class="newslist"> | |||
<div class="ui mini aligned list swiper-wrapper" id="newmessage"> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="ui container homeorg"> | |||
<div class="ui stackable grid"> | |||
<div class="sixteen wide tablet four wide computer column homeorg-tit"> | |||
<h2>Recommended Organizations</h2> | |||
<p><span class="ui text grey">These excellent organizations are using the OpenI AI Collaboration Platform for collaborative development of projects. To show your organization here, </span><a href="/OpenIOSSG/promote/">Click here to submit.</a></p> | |||
<a href="/explore/organizations" class="circular ui primary basic button">More Organizations <i class="arrow circle right icon"></i></a> | |||
</div> | |||
<div class="sixteen wide tablet twelve wide computer column"> | |||
<div class="homeorg-list"> | |||
<div class="swiper-wrapper" id="recommendorg"> | |||
</div> | |||
<div class="swiper-pagination"></div> | |||
</div> | |||
</div> | |||
<div class="sixteen wide tablet four wide computer column homeorg-tit"> | |||
<h2>Community Activities</h2> | |||
<p><span class="ui text grey">The community has prepared a wealth of activities, waiting for you to participate!</p> | |||
</div> | |||
<div class="sixteen wide tablet twelve wide computer column"> | |||
<div class="event-list"> | |||
<div class="swiper-wrapper" id="recommendactivity"> | |||
</div> | |||
<div class="swiper-pagination"></div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="leftline01"></div> | |||
</div> | |||
<div class="ui container homepro"> | |||
<div class="leftline02"></div> | |||
<div class="leftline02-2"></div> | |||
<div class="ui center homepro-tit am-mb-20"> | |||
<h2>Recommended Projects</h2> | |||
<p><span class="ui text grey">Excellent AI projects recommendation. To show your project here, </span><a href="/OpenIOSSG/promote/">Click here to submit.</a>Click here to <a href="/explore/">explore more projects.</a></p> | |||
</div> | |||
<div class="homepro-list"> | |||
<div class="swiper-wrapper" id="recommendrepo"> | |||
</div> | |||
<div class="swiper-pagination"></div> | |||
</div> | |||
</div> | |||
<div class="ui vertical masthead secondary c2net segment"> | |||
<div class="ui container"> | |||
<div class="ui center am-pt-30 am-pb-30"> | |||
<h2>智算网络</h2> | |||
<p><span class="ui text grey">人工智能算力网络推进联盟已接入10家智算中心,算力总规模1542P</p> | |||
</div> | |||
<div id="app" v-cloak> | |||
<div class="rotation3D-baseMap"></div> | |||
<div id="rotation3D" class="rotation3D"> | |||
<button class="center">中心</button> | |||
<div class="itemList"> | |||
<div class="rotation3D__item" :class="item.type" v-for="item in itemList"> | |||
<div class="scale"> | |||
<div class="baseImg"></div> | |||
<div class="cont"> | |||
<i class="iconfont" :class="item.icon"></i> | |||
<p></p> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="lineList"> | |||
<div class="rotation3D__line" v-for="item in itemList" :class="item.type"> | |||
<div v-if="item.type=='blue'" class="pos"> | |||
<svg width="50" height="400"> | |||
<path id="path1" d="M0 400, 0 0" stroke-dasharray="5,10"/> | |||
</svg> | |||
<div class="dot dot1 ri-arrow-left-s-line"><span></span></div> | |||
</div> | |||
<div v-if="item.type=='yellow'" class="pos"> | |||
<svg width="10" height="400"> | |||
<path id="path2" d="M0 400, 0 0" stroke-dasharray="5,10"/> | |||
</svg> | |||
<div class="dot dot2"><i class="el-icon-close"></i></div> | |||
</div> | |||
<div v-if="item.type=='green'" class="pos"> | |||
<svg width="50" height="400"> | |||
<path id="path1" d="M0 400, 0 0" stroke-dasharray="5,10"/> | |||
</svg> | |||
<div class="dot dot1 ri-arrow-left-s-line"></div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<a name="fourth"></a> | |||
<div class="ui container i-env"> | |||
<div class="ui center am-pb-30"> | |||
<h2>Collaborative Development Environment</h2> | |||
<p><span class="ui text grey">Provide a collaborative development environment for AI development, which is the biggest highlight that distinguishes the OpenI AI Collaboration Platform from other traditional Git platforms.</p> | |||
</div> | |||
<div class="ui four doubling cards"> | |||
<div class="card"> | |||
<div class="image"> | |||
<img src="/img/i-pic-01.jpg"> | |||
</div> | |||
<div class="content"> | |||
<h3 class="ui centered small header">Unified Management of Development Elements</h3> | |||
<div class="description ui text grey"> | |||
The platform provides four elements of AI development: unified management of model code, data set, model and execution environment. | |||
</div> | |||
</div> | |||
</div> | |||
<div class="card"> | |||
<div class="image"> | |||
<img src="/img/i-pic-02.jpg"> | |||
</div> | |||
<div class="content"> | |||
<h3 class="ui centered small header">Data Collaboration and Sharing</h3> | |||
<div class="description ui text grey"> | |||
By uploading data sets in the project, many project members cooperate to complete data preprocessing. You can also establish a better model with community developers by setting the data as a public dataset. | |||
</div> | |||
</div> | |||
</div> | |||
<div class="card"> | |||
<div class="image"> | |||
<img src="/img/i-pic-03.jpg"> | |||
</div> | |||
<div class="content"> | |||
<h3 class="ui centered small header">Model Management and Sharing</h3> | |||
<div class="description ui text grey"> | |||
Associate the model with the code version, you can adjust the model in different ways based on the historical version of the code and save the results. The trained model can be open and shared, so that more people can use the model to test and give feedback. | |||
</div> | |||
</div> | |||
</div> | |||
<div class="card"> | |||
<div class="image"> | |||
<img src="/img/i-pic-04.jpg"> | |||
</div> | |||
<div class="content"> | |||
<h3 class="ui centered small header">Once Configuration, Multiple Reuse</h3> | |||
<div class="description ui text grey"> | |||
Provide execution environment sharing, Once Configuration, Multiple Reuse. Lower the threshold of model development, and avoid spending repetitive time configuring complex environments. | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<a name="fifth"></a> | |||
<div class="ui container"> | |||
<div class="ui very padded inverted segment radius15"> | |||
<div class="ui stackable grid"> | |||
<div class="six wide column"> | |||
<img class="ui centered large image" src="/img/i-yunnao.svg"> | |||
</div> | |||
<div class="ten wide column am-pt-30"> | |||
<h2 class="ui grey inverted header">PengCheng Cloudbrain Open Source Collaboration</h2> | |||
<p class="am-lh-18 ui text grey"> | |||
The platform has been connected with Pengcheng Cloudbrain and can use the rich computing resources of Pengcheng Cloudbrain to complete AI development tasks.<br> | |||
Pengcheng Cloudbrain's existing AI computing power is 100p FLOPS@FP16 (billions of half precision floating-point calculations per second), the main hardware infrastructure is composed of GPU server equipped with NVIDIA Tesla V100 and Atlas 900 AI cluster equipped with Kunpeng and Ascend processors.<br> | |||
Developers can freely choose the corresponding computing resources according to their needs, and can test the adaptability, performance, stability of the model in different hardware environments.<br> | |||
If your model requires more computing resources, you can also apply for it separately.<br> | |||
</p> | |||
<a class="ui blue basic button am-mt-20" href="/user/login">Use Now</a> | |||
<a class="ui grey basic button am-mt-20" href="mailto:aiforge@openi.org.cn">Apply Separately</a> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="am-mt-30"></div> | |||
<script src="/self/js/jquery.min.js" type="text/javascript"></script> | |||
<script src="/home/home.js?v=eef985e4d4b587d055fc7c3eff3f18e9" type="text/javascript"></script> | |||
</div> | |||
<footer> | |||
<div class="ui container"> | |||
<div class="ui grid"> | |||
<div class="sixteen wide mobile eight wide tablet eight wide computer column"> | |||
<div class="ui three column grid"> | |||
<div class="column ui vertical text menu"> | |||
<div class="header item">Community</div> | |||
<a href="https://openi.org.cn/html/Club/2019/0227/14.html" class="item">Council</a> | |||
<a href="https://openi.org.cn/html/Club/2019/0227/14.html" class="item">Technical Committee</a> | |||
<a href="https://openi.org.cn/html/Club/2019/0228/17.html" class="item">Join OpenI</a> | |||
<a href="/home/term/" class="item">Use agreement</a> | |||
</div> | |||
<div class="column ui vertical text menu"> | |||
<div class="header item">News</div> | |||
<a href="https://openi.org.cn/html/news/dongtai/" class="item">Community News</a> | |||
<a href="https://openi.org.cn/html/news/huodong/" class="item">Member news</a> | |||
<a href="https://openi.org.cn/html/news/zixun/" class="item">Industry Advisory</a> | |||
</div> | |||
<div class="column ui vertical text menu"> | |||
<div class="header item">help</div> | |||
<div class="ui language bottom floating slide up dropdown link item"> | |||
<i class="world icon"></i> | |||
<div class="text">English</div> | |||
<div class="menu"> | |||
<a lang="en-US" class="item active selected" href="#">English</a> | |||
<a lang="zh-CN" class="item " href="?lang=zh-CN">简体中文</a> | |||
</div> | |||
</div> | |||
<a href="https://git.openi.org.cn/zeizei/OpenI_Learning" class=" item a_margin" target="_blank"><i class="ri-creative-commons-by-line footer_icon" ></i><p class="footer_icon">Tutorial</p> </a> | |||
<a href="/api/swagger" class=" item a_margin"><i class="ri-exchange-line footer_icon" > </i><p class="footer_icon">API</p> </a> | |||
<a href="/user/login" class=" item a_margin" ><i class="ri-mail-send-line footer_icon" ></i><p class="footer_icon">Feedback</p></a> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="sixteen wide mobile eight wide tablet eight wide computer column" style=" margin:2.0rem 0"> | |||
Copyright: New Generation Artificial Intelligence Open Source Open Platform (OpenI) <a href="http://beian.miit.gov.cn/" target="_blank">京ICP备18004880号</a> | |||
<br> | |||
Powered_by 鹏城实验室云脑、<a href="https://www.trustie.net/" target="_blank">Trustie确实</a>、gitea | |||
<br> | |||
</div> | |||
</div> | |||
</div> | |||
</footer> | |||
<script src="/js/jquery.js?v=eef985e4d4b587d055fc7c3eff3f18e9"></script> | |||
<script rel="stylesheet" src="/vendor/plugins/jquery.particleground/jquery.particleground.min.js"></script> | |||
<script src="/fomantic/semantic.min.js?v=eef985e4d4b587d055fc7c3eff3f18e9"></script> | |||
<script src="/js/index.js?v=eef985e4d4b587d055fc7c3eff3f18e9"></script> | |||
<script src="/rotation3D/vue-2.6.10.min.js"></script> | |||
<script src="/rotation3D/rotation3D.js?v=eef985e4d4b587d055fc7c3eff3f18e9"></script> | |||
<script> | |||
var app = new Vue({ | |||
el: "#app", | |||
data: { | |||
itemList: [ | |||
{ name:'鹏城云脑一号', type:'blue', icon:'', }, | |||
{ name:'鹏城云脑二号', type:'blue', icon:'', }, | |||
{ name:'北大人工智能集群系统', type:'green', icon:'', }, | |||
{ name:'合肥类脑智能开放平台', type:'green', icon:'', }, | |||
{ name:'武汉人工智能计算中心', type:'green', icon:'', }, | |||
{ name:'西安未来人工智能计算中心', type:'green', icon:'', }, | |||
{ name:'……', type:'yellow', icon:'', }, | |||
{ name:'中原人工智能计算中心', type:'green', icon:'', }, | |||
{ name:'成都人工智能计算中心', type:'green', icon:'', }, | |||
{ name:'横琴先进智能计算中心', type:'green', icon:'', }, | |||
{ name:'国家超级计算济南中心', type:'green', icon:'', }, | |||
], | |||
}, | |||
mounted: function () { | |||
new Rotation3D({ | |||
id: '#rotation3D', | |||
farScale: 0.6, | |||
xRadius: 0, | |||
yRadius: 130, | |||
}) | |||
}, | |||
methods: {}, | |||
}); | |||
</script> | |||
</body> | |||
</html> | |||
@@ -306,6 +306,22 @@ type CreateJobResult struct { | |||
Payload map[string]interface{} `json:"payload"` | |||
} | |||
type QueueDetailResult struct { | |||
Code string `json:"code"` | |||
Msg string `json:"msg"` | |||
Payload map[string]QueueDetail `json:"payload"` | |||
} | |||
type QueueDetail struct { | |||
JobScheduleInfo JobScheduleInfo `json:"JobScheduleInfo"` | |||
} | |||
type JobScheduleInfo struct { | |||
Pending int `json:"Pending"` | |||
Running int `json:"Running"` | |||
MedianPendingJobDurationSec int `json:"MedianPendingJobDurationSec"` | |||
} | |||
type GetJobResult struct { | |||
Code string `json:"code"` | |||
Msg string `json:"msg"` | |||
@@ -1743,6 +1759,17 @@ func GetBenchmarkCountByUserID(userID int64) (int, error) { | |||
return int(count), err | |||
} | |||
func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTypes ...JobType) (int64, error) { | |||
sess := x.Where("status=? and type=?", JobWaiting, cloudbrainType) | |||
if len(jobTypes) >= 0 { | |||
sess.In("JobType", jobTypes) | |||
} | |||
if computeResource != "" { | |||
sess.And("compute_resource=?", computeResource) | |||
} | |||
return sess.Count(new(Cloudbrain)) | |||
} | |||
func GetCloudbrainNotebookCountByUserID(userID int64) (int, error) { | |||
count, err := x.In("status", ModelArtsCreateQueue, ModelArtsCreating, ModelArtsStarting, ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsRestarting). | |||
And("job_type = ? and user_id = ? and type = ?", JobTypeDebug, userID, TypeCloudBrainTwo).Count(new(Cloudbrain)) | |||
@@ -50,6 +50,27 @@ type EditImageCloudBrainForm struct { | |||
Topics string `form:"topics"` | |||
} | |||
type CreateCloudBrainInferencForm struct { | |||
JobName string `form:"job_name" binding:"Required"` | |||
DisplayJobName string `form:"display_job_name" binding:"Required"` | |||
Image string `form:"image" binding:"Required"` | |||
Command string `form:"command" binding:"Required"` | |||
Attachment string `form:"attachment" binding:"Required"` | |||
JobType string `form:"job_type" binding:"Required"` | |||
BenchmarkCategory string `form:"get_benchmark_category"` | |||
GpuType string `form:"gpu_type"` | |||
TrainUrl string `form:"train_url"` | |||
TestUrl string `form:"test_url"` | |||
Description string `form:"description"` | |||
ResourceSpecId int `form:"resource_spec_id" binding:"Required"` | |||
BootFile string `form:"boot_file"` | |||
Params string `form:"run_para_list"` | |||
BranchName string `form:"branch_name"` | |||
ModelName string `form:"model_name" binding:"Required"` | |||
ModelVersion string `form:"model_version" binding:"Required"` | |||
CkptName string `form:"ckpt_name" binding:"Required"` | |||
} | |||
func (f *CreateCloudBrainForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
return validate(errs, ctx.Data, f, ctx.Locale) | |||
} | |||
@@ -61,3 +82,7 @@ func (f *CommitImageCloudBrainForm) Validate(ctx *macaron.Context, errs binding. | |||
func (f *EditImageCloudBrainForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
return validate(errs, ctx.Data, f, ctx.Locale) | |||
} | |||
func (f *CreateCloudBrainInferencForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
return validate(errs, ctx.Data, f, ctx.Locale) | |||
} |
@@ -3,6 +3,7 @@ package cloudbrain | |||
import ( | |||
"encoding/json" | |||
"errors" | |||
"os" | |||
"strconv" | |||
"code.gitea.io/gitea/modules/timeutil" | |||
@@ -37,12 +38,15 @@ const ( | |||
Success = "S000" | |||
DefaultBranchName = "master" | |||
ResultPath = "/result" | |||
) | |||
var ( | |||
ResourceSpecs *models.ResourceSpecs | |||
TrainResourceSpecs *models.ResourceSpecs | |||
SpecialPools *models.SpecialPools | |||
ResourceSpecs *models.ResourceSpecs | |||
TrainResourceSpecs *models.ResourceSpecs | |||
InferenceResourceSpecs *models.ResourceSpecs | |||
SpecialPools *models.SpecialPools | |||
) | |||
type GenerateCloudBrainTaskReq struct { | |||
@@ -69,6 +73,11 @@ type GenerateCloudBrainTaskReq struct { | |||
BenchmarkTypeID int | |||
BenchmarkChildTypeID int | |||
ResourceSpecId int | |||
ResultPath string | |||
TrainUrl string | |||
ModelName string | |||
ModelVersion string | |||
CkptName string | |||
} | |||
func GetCloudbrainDebugCommand() string { | |||
@@ -219,7 +228,6 @@ func AdminOrImageCreaterRight(ctx *context.Context) { | |||
func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
var resourceSpec *models.ResourceSpec | |||
var versionCount int | |||
if req.JobType == string(models.JobTypeTrain) { | |||
versionCount = 1 | |||
if TrainResourceSpecs == nil { | |||
@@ -231,6 +239,17 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
break | |||
} | |||
} | |||
} else if req.JobType == string(models.JobTypeInference) { | |||
if InferenceResourceSpecs == nil { | |||
json.Unmarshal([]byte(setting.InferenceResourceSpecs), &InferenceResourceSpecs) | |||
} | |||
for _, spec := range InferenceResourceSpecs.ResourceSpec { | |||
if req.ResourceSpecId == spec.Id { | |||
resourceSpec = spec | |||
break | |||
} | |||
} | |||
} else { | |||
if ResourceSpecs == nil { | |||
json.Unmarshal([]byte(setting.ResourceSpecs), &ResourceSpecs) | |||
@@ -245,21 +264,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
} | |||
//如果没有匹配到spec信息,尝试从专属资源池获取 | |||
if resourceSpec == nil && SpecialPools != nil { | |||
for _, specialPool := range SpecialPools.Pools { | |||
if resourceSpec != nil { | |||
break | |||
} | |||
if specialPool.ResourceSpec != nil { | |||
if IsElementExist(specialPool.JobType, req.JobType) && IsQueueInSpecialtPool(specialPool.Pool, req.GpuQueue) { | |||
for _, spec := range specialPool.ResourceSpec { | |||
if req.ResourceSpecId == spec.Id { | |||
resourceSpec = spec | |||
break | |||
} | |||
} | |||
} | |||
} | |||
} | |||
resourceSpec = geMatchResourceSpec(req.JobType, req.GpuQueue, req.ResourceSpecId) | |||
} | |||
if resourceSpec == nil { | |||
@@ -303,6 +308,13 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
ReadOnly: true, | |||
}, | |||
}, | |||
{ | |||
HostPath: models.StHostPath{ | |||
Path: req.ResultPath, | |||
MountPath: ResultPath, | |||
ReadOnly: false, | |||
}, | |||
}, | |||
} | |||
if len(req.DatasetInfos) == 1 { | |||
@@ -383,6 +395,11 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
BootFile: req.BootFile, | |||
DatasetName: req.DatasetNames, | |||
Parameters: req.Params, | |||
TrainUrl: req.TrainUrl, | |||
ModelName: req.ModelName, | |||
ModelVersion: req.ModelVersion, | |||
CkptName: req.CkptName, | |||
ResultUrl: req.ResultPath, | |||
CreatedUnix: createTime, | |||
UpdatedUnix: createTime, | |||
CommitID: req.CommitID, | |||
@@ -403,6 +420,8 @@ func GenerateTask(req GenerateCloudBrainTaskReq) error { | |||
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, stringId, req.DisplayJobName, models.ActionCreateBenchMarkTask) | |||
} else if string(models.JobTypeTrain) == req.JobType { | |||
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, jobID, req.DisplayJobName, models.ActionCreateGPUTrainTask) | |||
} else if string(models.JobTypeInference) == req.JobType { | |||
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, jobID, req.DisplayJobName, models.ActionCreateInferenceTask) | |||
} else { | |||
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, stringId, req.DisplayJobName, models.ActionCreateDebugGPUTask) | |||
} | |||
@@ -414,6 +433,15 @@ func IsBenchmarkJob(jobType string) bool { | |||
return string(models.JobTypeBenchmark) == jobType || string(models.JobTypeBrainScore) == jobType || string(models.JobTypeSnn4imagenet) == jobType | |||
} | |||
func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTypes ...models.JobType) int64 { | |||
num, err := models.GetWaitingCloudbrainCount(cloudbrainType, computeResource, jobTypes...) | |||
if err != nil { | |||
log.Warn("Get waiting count err", err) | |||
num = 0 | |||
} | |||
return num | |||
} | |||
func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) error { | |||
jobName := task.JobName | |||
@@ -427,6 +455,11 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e | |||
} | |||
} | |||
//如果没有匹配到spec信息,尝试从专属资源池获取 | |||
if resourceSpec == nil && SpecialPools != nil { | |||
resourceSpec = geMatchResourceSpec(task.JobType, task.GpuQueue, task.ResourceSpecId) | |||
} | |||
if resourceSpec == nil { | |||
log.Error("no such resourceSpecId(%d)", task.ResourceSpecId, ctx.Data["MsgID"]) | |||
return errors.New("no such resourceSpec") | |||
@@ -565,6 +598,63 @@ func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) e | |||
return nil | |||
} | |||
func geMatchResourceSpec(jobType string, gpuQueue string, resourceSpecId int) *models.ResourceSpec { | |||
for _, specialPool := range SpecialPools.Pools { | |||
if specialPool.ResourceSpec != nil { | |||
if IsElementExist(specialPool.JobType, jobType) && IsQueueInSpecialtPool(specialPool.Pool, gpuQueue) { | |||
for _, spec := range specialPool.ResourceSpec { | |||
if resourceSpecId == spec.Id { | |||
return spec | |||
} | |||
} | |||
} | |||
} | |||
} | |||
return nil | |||
} | |||
func DelCloudBrainJob(jobId string) string { | |||
task, err := models.GetCloudbrainByJobID(jobId) | |||
if err != nil { | |||
log.Error("get cloud brain err:", err) | |||
return "cloudbrain.Delete_failed" | |||
} | |||
if task.Status != string(models.JobStopped) && task.Status != string(models.JobFailed) && task.Status != string(models.JobSucceeded) { | |||
log.Error("the job(%s) has not been stopped", task.JobName) | |||
return "cloudbrain.Not_Stopped" | |||
} | |||
err = models.DeleteJob(task) | |||
if err != nil { | |||
log.Error("DeleteJob failed:", err) | |||
return "cloudbrain.Delete_failed" | |||
} | |||
deleteJobStorage(task.JobName) | |||
return "" | |||
} | |||
func deleteJobStorage(jobName string) error { | |||
//delete local | |||
localJobPath := setting.JobPath + jobName | |||
err := os.RemoveAll(localJobPath) | |||
if err != nil { | |||
log.Error("RemoveAll(%s) failed:%v", localJobPath, err) | |||
} | |||
dirPath := setting.CBCodePathPrefix + jobName + "/" | |||
err = storage.Attachments.DeleteDir(dirPath) | |||
if err != nil { | |||
log.Error("DeleteDir(%s) failed:%v", localJobPath, err) | |||
} | |||
return nil | |||
} | |||
func InitSpecialPool() { | |||
if SpecialPools == nil && setting.SpecialPools != "" { | |||
json.Unmarshal([]byte(setting.SpecialPools), &SpecialPools) | |||
@@ -30,6 +30,7 @@ const ( | |||
LogPageSize = 500 | |||
LogPageTokenExpired = "5m" | |||
pageSize = 15 | |||
QueuesDetailUrl = "/rest-server/api/v2/queuesdetail" | |||
) | |||
func getRestyClient() *resty.Client { | |||
@@ -73,12 +74,44 @@ func loginCloudbrain() error { | |||
return nil | |||
} | |||
func GetQueuesDetail() (*map[string]int, error) { | |||
checkSetting() | |||
client := getRestyClient() | |||
var jobResult models.QueueDetailResult | |||
var result = make(map[string]int, 0) | |||
res, err := client.R(). | |||
SetHeader("Content-Type", "application/json"). | |||
SetAuthToken(TOKEN). | |||
SetResult(&jobResult). | |||
Get(HOST + QueuesDetailUrl) | |||
if err != nil { | |||
return nil, fmt.Errorf("resty get queues detail failed: %s", err) | |||
} | |||
if jobResult.Code != Success { | |||
return nil, fmt.Errorf("jobResult err: %s", res.String()) | |||
} | |||
for k, v := range jobResult.Payload { | |||
result[k] = v.JobScheduleInfo.Pending | |||
} | |||
return &result, nil | |||
} | |||
func CreateJob(jobName string, createJobParams models.CreateJobParams) (*models.CreateJobResult, error) { | |||
checkSetting() | |||
client := getRestyClient() | |||
var jobResult models.CreateJobResult | |||
retry := 0 | |||
reqPara, _ := json.Marshal(createJobParams) | |||
log.Warn("job req:", string(reqPara[:])) | |||
sendjob: | |||
res, err := client.R(). | |||
@@ -143,16 +176,6 @@ sendjob: | |||
return &getJobResult, nil | |||
} | |||
func GetImages() (*models.GetImagesResult, error) { | |||
return GetImagesPageable(1, 100, Custom, "") | |||
} | |||
func GetPublicImages() (*models.GetImagesResult, error) { | |||
return GetImagesPageable(1, 100, Public, "") | |||
} | |||
func GetImagesPageable(page int, size int, imageType string, name string) (*models.GetImagesResult, error) { | |||
checkSetting() | |||
client := getRestyClient() | |||
@@ -463,20 +463,23 @@ var ( | |||
DecompressOBSTaskName string | |||
//cloudbrain config | |||
CBAuthUser string | |||
CBAuthPassword string | |||
RestServerHost string | |||
JobPath string | |||
CBCodePathPrefix string | |||
JobType string | |||
GpuTypes string | |||
SpecialPools string | |||
DebugServerHost string | |||
ResourceSpecs string | |||
MaxDuration int64 | |||
TrainGpuTypes string | |||
TrainResourceSpecs string | |||
MaxDatasetNum int | |||
CBAuthUser string | |||
CBAuthPassword string | |||
RestServerHost string | |||
JobPath string | |||
CBCodePathPrefix string | |||
JobType string | |||
GpuTypes string | |||
SpecialPools string | |||
DebugServerHost string | |||
ResourceSpecs string | |||
MaxDuration int64 | |||
TrainGpuTypes string | |||
TrainResourceSpecs string | |||
InferenceGpuTypes string | |||
InferenceResourceSpecs string | |||
MaxDatasetNum int | |||
CullIdleTimeout string | |||
CullInterval string | |||
@@ -1327,6 +1330,8 @@ func NewContext() { | |||
MaxDuration = sec.Key("MAX_DURATION").MustInt64(14400) | |||
TrainGpuTypes = sec.Key("TRAIN_GPU_TYPES").MustString("") | |||
TrainResourceSpecs = sec.Key("TRAIN_RESOURCE_SPECS").MustString("") | |||
InferenceGpuTypes = sec.Key("INFERENCE_GPU_TYPES").MustString("") | |||
InferenceResourceSpecs = sec.Key("INFERENCE_RESOURCE_SPECS").MustString("") | |||
SpecialPools = sec.Key("SPECIAL_POOL").MustString("") | |||
MaxDatasetNum = sec.Key("MAX_DATASET_NUM").MustInt(5) | |||
@@ -1037,8 +1037,9 @@ image_delete_fail=Failed to delete image, please try again later. | |||
image_overwrite=You had submitted the same name image before, are you sure to overwrite the original image? | |||
download=Download | |||
score=Score | |||
wait_count_start = There are currently | |||
wait_count_end = tasks queued | |||
file_limit_100 = Display up to 100 files or folders in a single directory | |||
images.name = Image Tag | |||
images.name_placerholder = Please enter the image name | |||
image.label_tooltips = Example Python 3.7, Tensorflow 2.0, cuda 10, pytorch 1.6 | |||
@@ -3122,4 +3123,10 @@ INFERENCE = INFERENCE | |||
BENCHMARK = BENCHMARK | |||
brain_area = Brain Area | |||
error.dataset_select = dataset select error:the count exceed the limit or has same name | |||
Delete_failed=Fail to delete the job, please try again later. | |||
Not_Stopped=The job is not stopped, can not be deleted. | |||
Already_stopped=The job is already stopped. | |||
Stopped_failed=Fail to stop the job, please try again later. | |||
Stopped_success_update_status_fail=Succeed in stopping th job, but failed to update the job status and duration time. | |||
error.dataset_select = dataset select error:the count exceed the limit or has same name |
@@ -1037,8 +1037,9 @@ image_delete_fail=删除镜像失败,请稍后再试。 | |||
image_overwrite=您已经提交过相同名称的镜像,您确定要覆盖原来提交的镜像吗? | |||
download=模型下载 | |||
score=评分 | |||
wait_count_start = 当前有 | |||
wait_count_end = 个任务正在排队 | |||
file_limit_100 = 单目录下最多显示100个文件或文件夹 | |||
images.name = 镜像Tag | |||
images.name_placerholder = 请输入镜像Tag | |||
image.label_tooltips = 如Python 3.7, Tensorflow 2.0, cuda 10, pytorch 1.6 | |||
@@ -3136,4 +3137,11 @@ INFERENCE = 推理任务 | |||
BENCHMARK = 评测任务 | |||
brain_area = 脑区 | |||
error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集 | |||
Delete_failed=任务删除失败,请稍后再试。 | |||
Not_Stopped=任务还未终止,不能删除。 | |||
Already_stopped=任务已停止。 | |||
Stopped_failed=任务停止失败,请稍后再试。 | |||
Stopped_success_update_status_fail=任务停止成功,状态及运行时间更新失败。 | |||
error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集 |
@@ -922,6 +922,13 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Post("/stop_version", cloudbrain.AdminOrOwnerOrJobCreaterRightForTrain, repo_ext.CloudBrainStop) | |||
}) | |||
}) | |||
m.Group("/inference-job", func() { | |||
m.Group("/:jobid", func() { | |||
m.Get("", repo.GetCloudBrainInferenceJob) | |||
m.Post("/del", cloudbrain.AdminOrOwnerOrJobCreaterRight, repo.DelCloudBrainJob) | |||
m.Get("/result_list", repo.InferencJobResultList) | |||
}) | |||
}) | |||
}, reqRepoReader(models.UnitTypeCloudBrain)) | |||
m.Group("/modelarts", func() { | |||
m.Group("/notebook", func() { | |||
@@ -101,6 +101,122 @@ func GetCloudbrainTask(ctx *context.APIContext) { | |||
} | |||
func GetCloudBrainInferenceJob(ctx *context.APIContext) { | |||
jobID := ctx.Params(":jobid") | |||
job, err := models.GetCloudbrainByJobID(jobID) | |||
if err != nil { | |||
ctx.NotFound(err) | |||
return | |||
} | |||
jobResult, err := cloudbrain.GetJob(job.JobID) | |||
if err != nil { | |||
ctx.NotFound(err) | |||
log.Error("GetJob failed:", err) | |||
return | |||
} | |||
result, err := models.ConvertToJobResultPayload(jobResult.Payload) | |||
if err != nil { | |||
ctx.NotFound(err) | |||
log.Error("ConvertToJobResultPayload failed:", err) | |||
return | |||
} | |||
job.Status = result.JobStatus.State | |||
if result.JobStatus.State != string(models.JobWaiting) && result.JobStatus.State != string(models.JobFailed) { | |||
taskRoles := result.TaskRoles | |||
taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | |||
job.ContainerID = taskRes.TaskStatuses[0].ContainerID | |||
job.Status = taskRes.TaskStatuses[0].State | |||
} | |||
if result.JobStatus.State != string(models.JobWaiting) { | |||
models.ParseAndSetDurationFromCloudBrainOne(result, job) | |||
err = models.UpdateJob(job) | |||
if err != nil { | |||
log.Error("UpdateJob failed:", err) | |||
} | |||
} | |||
ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
"JobID": jobID, | |||
"JobStatus": job.Status, | |||
"JobDuration": job.TrainJobDuration, | |||
}) | |||
} | |||
func DelCloudBrainJob(ctx *context.APIContext) { | |||
jobID := ctx.Params(":jobid") | |||
errStr := cloudbrain.DelCloudBrainJob(jobID) | |||
if errStr != "" { | |||
ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
"message": ctx.Tr(errStr), | |||
"VersionName": "1", | |||
"code": 1, | |||
}) | |||
} else { | |||
ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
"message": "", | |||
"VersionName": "1", | |||
"code": 0, | |||
}) | |||
} | |||
} | |||
func InferencJobResultList(ctx *context.APIContext) { | |||
jobID := ctx.Params(":jobid") | |||
parentDir := ctx.Query("parentDir") | |||
dirArray := strings.Split(parentDir, "/") | |||
task, err := models.GetCloudbrainByJobID(jobID) | |||
if err != nil { | |||
log.Error("get cloud brain err:", err) | |||
ctx.ServerError("get cloud brain information failed:", err) | |||
} | |||
//get dirs | |||
dirs, err := routerRepo.GetResultDirs(task.JobName, parentDir) | |||
if err != nil { | |||
log.Error("GetModelDirs failed:%v", err.Error(), ctx.Data["msgID"]) | |||
ctx.ServerError("GetModelDirs failed:", err) | |||
return | |||
} | |||
var fileInfos []storage.FileInfo | |||
err = json.Unmarshal([]byte(dirs), &fileInfos) | |||
if err != nil { | |||
log.Error("json.Unmarshal failed:%v", err.Error(), ctx.Data["msgID"]) | |||
ctx.ServerError("json.Unmarshal failed:", err) | |||
return | |||
} | |||
for i, fileInfo := range fileInfos { | |||
temp, _ := time.Parse("2006-01-02 15:04:05", fileInfo.ModTime) | |||
fileInfos[i].ModTime = temp.Local().Format("2006-01-02 15:04:05") | |||
} | |||
sort.Slice(fileInfos, func(i, j int) bool { | |||
return fileInfos[i].ModTime > fileInfos[j].ModTime | |||
}) | |||
ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
"JobID": jobID, | |||
"StatusOK": 0, | |||
"Path": dirArray, | |||
"Dirs": fileInfos, | |||
"task": task, | |||
"PageIsCloudBrain": true, | |||
}) | |||
} | |||
func CloudbrainGetLog(ctx *context.Context) { | |||
ID := ctx.Params(":id") | |||
job, err := models.GetCloudbrainByID(ID) | |||
@@ -766,7 +766,7 @@ func QueryModelListForPredict(ctx *context.Context) { | |||
PageSize: -1, | |||
}, | |||
RepoID: repoId, | |||
Type: -1, | |||
Type: ctx.QueryInt("type"), | |||
New: -1, | |||
}) | |||
if err != nil { | |||
@@ -47,6 +47,9 @@ const ( | |||
tplCloudBrainTrainJobNew base.TplName = "repo/cloudbrain/trainjob/new" | |||
tplCloudBrainTrainJobShow base.TplName = "repo/cloudbrain/trainjob/show" | |||
tplCloudBrainInferenceJobNew base.TplName = "repo/cloudbrain/inference/new" | |||
tplCloudBrainInferenceJobShow base.TplName = "repo/cloudbrain/inference/show" | |||
) | |||
var ( | |||
@@ -56,6 +59,7 @@ var ( | |||
benchmarkGpuInfos *models.GpuInfos | |||
benchmarkResourceSpecs *models.ResourceSpecs | |||
trainGpuInfos *models.GpuInfos | |||
inferenceGpuInfos *models.GpuInfos | |||
) | |||
const BENCHMARK_TYPE_CODE = "repo.cloudbrain.benchmark.types" | |||
@@ -97,45 +101,6 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] | |||
ctx.Data["display_job_name"] = displayJobName | |||
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 | |||
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.GetCloudbrainDebugCommand() | |||
ctx.Data["code_path"] = cloudbrain.CodeMountPath | |||
ctx.Data["dataset_path"] = cloudbrain.DataSetMountPath | |||
@@ -149,6 +114,10 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
ctx.Data["benchmark_categories"] = categories.Category | |||
ctx.Data["benchmark_types"] = GetBenchmarkTypes(ctx).BenchmarkType | |||
queuesDetail, _ := cloudbrain.GetQueuesDetail() | |||
if queuesDetail != nil { | |||
ctx.Data["QueuesDetail"] = queuesDetail | |||
} | |||
cloudbrain.InitSpecialPool() | |||
@@ -162,6 +131,11 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
} | |||
ctx.Data["train_gpu_types"] = trainGpuInfos.GpuInfo | |||
if inferenceGpuInfos == nil { | |||
json.Unmarshal([]byte(setting.InferenceGpuTypes), &inferenceGpuInfos) | |||
} | |||
ctx.Data["inference_gpu_types"] = inferenceGpuInfos.GpuInfo | |||
if benchmarkGpuInfos == nil { | |||
json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | |||
} | |||
@@ -182,6 +156,11 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
} | |||
ctx.Data["train_resource_specs"] = cloudbrain.TrainResourceSpecs.ResourceSpec | |||
if cloudbrain.InferenceResourceSpecs == nil { | |||
json.Unmarshal([]byte(setting.InferenceResourceSpecs), &cloudbrain.InferenceResourceSpecs) | |||
} | |||
ctx.Data["inference_resource_specs"] = cloudbrain.InferenceResourceSpecs.ResourceSpec | |||
if cloudbrain.SpecialPools != nil { | |||
var debugGpuTypes []*models.GpuInfo | |||
var trainGpuTypes []*models.GpuInfo | |||
@@ -372,6 +351,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
BenchmarkTypeID: 0, | |||
BenchmarkChildTypeID: 0, | |||
ResourceSpecId: resourceSpecId, | |||
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | |||
} | |||
err = cloudbrain.GenerateTask(req) | |||
@@ -388,6 +368,125 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
} | |||
} | |||
func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBrainInferencForm) { | |||
ctx.Data["PageIsCloudBrain"] = true | |||
displayJobName := form.DisplayJobName | |||
jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
image := strings.TrimSpace(form.Image) | |||
uuid := form.Attachment | |||
jobType := string(models.JobTypeInference) | |||
gpuQueue := form.GpuType | |||
codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | |||
resourceSpecId := form.ResourceSpecId | |||
branchName := form.BranchName | |||
repo := ctx.Repo.Repository | |||
ckptUrl := setting.Attachment.Minio.RealPath + form.TrainUrl + form.CkptName | |||
log.Info("ckpt url:" + ckptUrl) | |||
tpl := tplCloudBrainInferenceJobNew | |||
command, err := getInferenceJobCommand(form) | |||
if err != nil { | |||
log.Error("getTrainJobCommand failed: %v", err) | |||
ctx.RenderWithErr(err.Error(), tpl, &form) | |||
return | |||
} | |||
tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName) | |||
if err == nil { | |||
if len(tasks) != 0 { | |||
log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
cloudBrainNewDataPrepare(ctx) | |||
ctx.RenderWithErr("the job name did already exist", tpl, &form) | |||
return | |||
} | |||
} else { | |||
if !models.IsErrJobNotExist(err) { | |||
log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
cloudBrainNewDataPrepare(ctx) | |||
ctx.RenderWithErr("system error", tpl, &form) | |||
return | |||
} | |||
} | |||
if !jobNamePattern.MatchString(displayJobName) { | |||
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) | |||
return | |||
} | |||
count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, jobType) | |||
if err != nil { | |||
log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | |||
cloudBrainNewDataPrepare(ctx) | |||
ctx.RenderWithErr("system error", tpl, &form) | |||
return | |||
} else { | |||
if count >= 1 { | |||
log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | |||
cloudBrainNewDataPrepare(ctx) | |||
ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form) | |||
return | |||
} | |||
} | |||
if branchName == "" { | |||
branchName = cloudbrain.DefaultBranchName | |||
} | |||
downloadCode(repo, codePath, branchName) | |||
uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | |||
resultPath := setting.JobPath + jobName + cloudbrain.ResultPath + "/" | |||
mkResultPath(resultPath) | |||
uploadCodeToMinio(resultPath, jobName, cloudbrain.ResultPath+"/") | |||
commitID, _ := ctx.Repo.GitRepo.GetBranchCommitID(branchName) | |||
datasetInfos, datasetNames, err := models.GetDatasetInfo(uuid) | |||
if err != nil { | |||
log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) | |||
cloudBrainNewDataPrepare(ctx) | |||
ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) | |||
return | |||
} | |||
req := cloudbrain.GenerateCloudBrainTaskReq{ | |||
Ctx: ctx, | |||
DisplayJobName: displayJobName, | |||
JobName: jobName, | |||
Image: image, | |||
Command: command, | |||
Uuids: uuid, | |||
DatasetNames: datasetNames, | |||
DatasetInfos: datasetInfos, | |||
CodePath: storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||
ModelPath: setting.Attachment.Minio.RealPath + form.TrainUrl, | |||
BenchmarkPath: storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), | |||
Snn4ImageNetPath: storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | |||
BrainScorePath: storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), | |||
JobType: jobType, | |||
GpuQueue: gpuQueue, | |||
Description: form.Description, | |||
BranchName: branchName, | |||
BootFile: form.BootFile, | |||
Params: form.Params, | |||
CommitID: commitID, | |||
ResourceSpecId: resourceSpecId, | |||
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | |||
ModelName: form.ModelName, | |||
ModelVersion: form.ModelVersion, | |||
CkptName: form.CkptName, | |||
TrainUrl: form.TrainUrl, | |||
} | |||
err = cloudbrain.GenerateTask(req) | |||
if err != nil { | |||
cloudBrainNewDataPrepare(ctx) | |||
ctx.RenderWithErr(err.Error(), tpl, &form) | |||
return | |||
} | |||
ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelarts/inference-job") | |||
} | |||
/** | |||
检查用户传输的参数是否符合专属资源池 | |||
*/ | |||
@@ -459,7 +558,18 @@ func CloudBrainRestart(ctx *context.Context) { | |||
for _, resourceType := range gpuInfos.GpuInfo { | |||
if resourceType.Queue == task.GpuQueue { | |||
hasSameResource = true | |||
continue | |||
break | |||
} | |||
} | |||
if !hasSameResource && cloudbrain.SpecialPools != nil { | |||
for _, specialPool := range cloudbrain.SpecialPools.Pools { | |||
cloudbrain.IsElementExist(specialPool.JobType, string(models.JobTypeDebug)) | |||
for _, pool := range specialPool.Pool { | |||
if pool.Queue == task.GpuQueue { | |||
hasSameResource = true | |||
} | |||
} | |||
} | |||
} | |||
@@ -522,7 +632,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
var task *models.Cloudbrain | |||
var err error | |||
if jobType == models.JobTypeTrain { | |||
if jobType == models.JobTypeTrain || jobType == models.JobTypeInference { | |||
task, err = models.GetCloudbrainByJobID(ctx.Params(":jobid")) | |||
} else { | |||
task, err = models.GetCloudbrainByIDWithDeleted(ctx.Params(":id")) | |||
@@ -553,6 +663,18 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
} | |||
} | |||
} else if task.JobType == string(models.JobTypeInference) { | |||
if cloudbrain.InferenceResourceSpecs == nil { | |||
json.Unmarshal([]byte(setting.InferenceResourceSpecs), &cloudbrain.InferenceResourceSpecs) | |||
} | |||
for _, tmp := range cloudbrain.InferenceResourceSpecs.ResourceSpec { | |||
if tmp.Id == task.ResourceSpecId { | |||
ctx.Data["GpuNum"] = tmp.GpuNum | |||
ctx.Data["CpuNum"] = tmp.CpuNum | |||
ctx.Data["MemMiB"] = tmp.MemMiB | |||
ctx.Data["ShareMemMiB"] = tmp.ShareMemMiB | |||
} | |||
} | |||
} else { | |||
if cloudbrain.ResourceSpecs == nil { | |||
json.Unmarshal([]byte(setting.ResourceSpecs), &cloudbrain.ResourceSpecs) | |||
@@ -581,6 +703,15 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
ctx.Data["resource_type"] = resourceType.Value | |||
} | |||
} | |||
} else if task.JobType == string(models.JobTypeInference) { | |||
if inferenceGpuInfos == nil { | |||
json.Unmarshal([]byte(setting.InferenceGpuTypes), &inferenceGpuInfos) | |||
} | |||
for _, resourceType := range inferenceGpuInfos.GpuInfo { | |||
if resourceType.Queue == jobRes.Config.GpuType { | |||
ctx.Data["resource_type"] = resourceType.Value | |||
} | |||
} | |||
} else if cloudbrain.IsBenchmarkJob(task.JobType) { | |||
if benchmarkGpuInfos == nil { | |||
json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &benchmarkGpuInfos) | |||
@@ -938,7 +1069,7 @@ func CloudBrainStop(ctx *context.Context) { | |||
if task.Status == string(models.JobStopped) || task.Status == string(models.JobFailed) || task.Status == string(models.JobSucceeded) { | |||
log.Error("the job(%s) has been stopped", task.JobName, ctx.Data["msgID"]) | |||
resultCode = "-1" | |||
errorMsg = "system error" | |||
errorMsg = "cloudbrain.Already_stopped" | |||
break | |||
} | |||
@@ -946,7 +1077,7 @@ func CloudBrainStop(ctx *context.Context) { | |||
if err != nil { | |||
log.Error("StopJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | |||
resultCode = "-1" | |||
errorMsg = "system error" | |||
errorMsg = "cloudbrain.Stopped_failed" | |||
break | |||
} | |||
@@ -959,7 +1090,7 @@ func CloudBrainStop(ctx *context.Context) { | |||
if err != nil { | |||
log.Error("UpdateJob(%s) failed:%v", task.JobName, err, ctx.Data["msgID"]) | |||
resultCode = "-1" | |||
errorMsg = "system error" | |||
errorMsg = "cloudbrain.Stopped_success_update_status_fail" | |||
break | |||
} | |||
@@ -969,7 +1100,7 @@ func CloudBrainStop(ctx *context.Context) { | |||
ctx.JSON(200, map[string]interface{}{ | |||
"result_code": resultCode, | |||
"error_msg": errorMsg, | |||
"error_msg": ctx.Tr(errorMsg), | |||
"status": status, | |||
"id": ID, | |||
"StatusOK": 0, | |||
@@ -1259,6 +1390,18 @@ func GetModelDirs(jobName string, parentDir string) (string, error) { | |||
return getDirs(req) | |||
} | |||
func GetResultDirs(jobName string, parentDir string) (string, error) { | |||
var req string | |||
modelActualPath := storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/") | |||
if parentDir == "" { | |||
req = "baseDir=" + modelActualPath | |||
} else { | |||
req = "baseDir=" + modelActualPath + "&parentDir=" + parentDir | |||
} | |||
return getDirs(req) | |||
} | |||
func CloudBrainDownloadModel(ctx *context.Context) { | |||
parentDir := ctx.Query("parentDir") | |||
fileName := ctx.Query("fileName") | |||
@@ -1273,6 +1416,20 @@ func CloudBrainDownloadModel(ctx *context.Context) { | |||
ctx.Resp.Header().Set("Cache-Control", "max-age=0") | |||
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently) | |||
} | |||
func CloudBrainDownloadInferenceResult(ctx *context.Context) { | |||
parentDir := ctx.Query("parentDir") | |||
fileName := ctx.Query("fileName") | |||
jobName := ctx.Query("jobName") | |||
filePath := "jobs/" + jobName + "/result/" + parentDir | |||
url, err := storage.Attachments.PresignedGetURL(filePath, fileName) | |||
if err != nil { | |||
log.Error("PresignedGetURL failed: %v", err.Error(), ctx.Data["msgID"]) | |||
ctx.ServerError("PresignedGetURL", err) | |||
return | |||
} | |||
ctx.Resp.Header().Set("Cache-Control", "max-age=0") | |||
http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently) | |||
} | |||
func GetRate(ctx *context.Context) { | |||
isObjectDetcionAll := ctx.QueryBool("isObjectDetcionAll") | |||
@@ -1426,13 +1583,21 @@ func uploadCodeToMinio(codePath, jobName, parentDir string) error { | |||
} | |||
func mkModelPath(modelPath string) error { | |||
err := os.MkdirAll(modelPath, os.ModePerm) | |||
return mkPathAndReadMeFile(modelPath, "You can put the model file into this directory and download it by the web page.") | |||
} | |||
func mkResultPath(resultPath string) error { | |||
return mkPathAndReadMeFile(resultPath, "You can put the result file into this directory and download it by the web page.") | |||
} | |||
func mkPathAndReadMeFile(path string, text string) error { | |||
err := os.MkdirAll(path, os.ModePerm) | |||
if err != nil { | |||
log.Error("MkdirAll(%s) failed:%v", modelPath, err) | |||
log.Error("MkdirAll(%s) failed:%v", path, err) | |||
return err | |||
} | |||
fileName := modelPath + "README" | |||
fileName := path + "README" | |||
f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.ModePerm) | |||
if err != nil { | |||
log.Error("OpenFile failed", err.Error()) | |||
@@ -1441,7 +1606,7 @@ func mkModelPath(modelPath string) error { | |||
defer f.Close() | |||
_, err = f.WriteString("You can put the model file into this directory and download it by the web page.") | |||
_, err = f.WriteString(text) | |||
if err != nil { | |||
log.Error("WriteString failed", err.Error()) | |||
return err | |||
@@ -2160,6 +2325,7 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo | |||
BenchmarkTypeID: benchmarkTypeID, | |||
BenchmarkChildTypeID: benchmarkChildTypeID, | |||
ResourceSpecId: resourceSpecId, | |||
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | |||
} | |||
err = cloudbrain.GenerateTask(req) | |||
@@ -2288,6 +2454,7 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) | |||
BenchmarkTypeID: 0, | |||
BenchmarkChildTypeID: benchmarkChildTypeID, | |||
ResourceSpecId: resourceSpecId, | |||
ResultPath: storage.GetMinioPath(jobName, cloudbrain.ResultPath+"/"), | |||
} | |||
err = cloudbrain.GenerateTask(req) | |||
@@ -2338,6 +2505,64 @@ func CloudBrainTrainJobNew(ctx *context.Context) { | |||
ctx.HTML(http.StatusOK, tplCloudBrainTrainJobNew) | |||
} | |||
func InferenceCloudBrainJobNew(ctx *context.Context) { | |||
err := cloudBrainNewDataPrepare(ctx) | |||
if err != nil { | |||
ctx.ServerError("get new train-job info failed", err) | |||
return | |||
} | |||
ctx.HTML(http.StatusOK, tplCloudBrainInferenceJobNew) | |||
} | |||
func InferenceCloudBrainJobShow(ctx *context.Context) { | |||
cloudBrainShow(ctx, tplCloudBrainInferenceJobShow, models.JobTypeInference) | |||
} | |||
func DownloadInferenceResultFile(ctx *context.Context) { | |||
var jobID = ctx.Params(":jobid") | |||
var versionName = ctx.Query("version_name") | |||
task, err := models.GetCloudbrainByJobIDAndVersionName(jobID, versionName) | |||
if err != nil { | |||
log.Error("GetCloudbrainByJobID(%s) failed:%v", task.JobName, err.Error()) | |||
return | |||
} | |||
allFile, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, task.ResultUrl) | |||
returnFileName := task.DisplayJobName + ".zip" | |||
MinioDownloadManyFile(task.ResultUrl, ctx, returnFileName, allFile) | |||
} | |||
func getInferenceJobCommand(form auth.CreateCloudBrainInferencForm) (string, error) { | |||
var command string | |||
bootFile := strings.TrimSpace(form.BootFile) | |||
params := form.Params | |||
if !strings.HasSuffix(bootFile, ".py") { | |||
log.Error("bootFile(%s) format error", bootFile) | |||
return command, errors.New("bootFile format error") | |||
} | |||
var parameters models.Parameters | |||
var param string | |||
if len(params) != 0 { | |||
err := json.Unmarshal([]byte(params), ¶meters) | |||
if err != nil { | |||
log.Error("Failed to Unmarshal params: %s (%v)", params, err) | |||
return command, err | |||
} | |||
for _, parameter := range parameters.Parameter { | |||
param += " --" + parameter.Label + "=" + parameter.Value | |||
} | |||
} | |||
param += " --modelname" + "=" + form.CkptName | |||
command += "python /code/" + bootFile + param + " > " + cloudbrain.ResultPath + "/" + form.DisplayJobName + "-" + cloudbrain.LogFile | |||
return command, nil | |||
} | |||
func getTrainJobCommand(form auth.CreateCloudBrainForm) (string, error) { | |||
var command string | |||
bootFile := strings.TrimSpace(form.BootFile) | |||
@@ -43,6 +43,8 @@ func GrampusTrainJobGPUNew(ctx *context.Context) { | |||
ctx.ServerError("get new train-job info failed", err) | |||
return | |||
} | |||
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.GPUResource, models.JobTypeTrain) | |||
ctx.Data["WaitCount"] = waitCount | |||
ctx.HTML(http.StatusOK, tplGrampusTrainJobGPUNew) | |||
} | |||
@@ -53,6 +55,8 @@ func GrampusTrainJobNPUNew(ctx *context.Context) { | |||
ctx.ServerError("get new train-job info failed", err) | |||
return | |||
} | |||
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.NPUResource, models.JobTypeTrain) | |||
ctx.Data["WaitCount"] = waitCount | |||
ctx.HTML(200, tplGrampusTrainJobNPUNew) | |||
} | |||
@@ -119,7 +119,8 @@ func MustEnableModelArts(ctx *context.Context) { | |||
func NotebookNew(ctx *context.Context) { | |||
notebookNewDataPrepare(ctx) | |||
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") | |||
ctx.Data["WaitCount"] = waitCount | |||
ctx.HTML(200, tplModelArtsNotebookNew) | |||
} | |||
@@ -630,6 +631,8 @@ func TrainJobNew(ctx *context.Context) { | |||
ctx.ServerError("get new train-job info failed", err) | |||
return | |||
} | |||
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") | |||
ctx.Data["WaitCount"] = waitCount | |||
ctx.HTML(200, tplModelArtsTrainJobNew) | |||
} | |||
@@ -782,6 +785,8 @@ func TrainJobNewVersion(ctx *context.Context) { | |||
ctx.ServerError("get new train-job info failed", err) | |||
return | |||
} | |||
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") | |||
ctx.Data["WaitCount"] = waitCount | |||
ctx.HTML(200, tplModelArtsTrainJobVersionNew) | |||
} | |||
@@ -1876,8 +1881,8 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference | |||
modelName := form.ModelName | |||
modelVersion := form.ModelVersion | |||
ckptName := form.CkptName | |||
ckptUrl := form.TrainUrl + form.CkptName | |||
ckptUrl := "/" + form.TrainUrl + form.CkptName | |||
log.Info("ckpt url:" + ckptUrl) | |||
count, err := models.GetCloudbrainInferenceJobCountByUserID(ctx.User.ID) | |||
if err != nil { | |||
@@ -2044,6 +2049,13 @@ func InferenceJobIndex(ctx *context.Context) { | |||
page = 1 | |||
} | |||
listType := ctx.Query("listType") | |||
ctx.Data["ListType"] = listType | |||
if listType == models.AllResource { | |||
listType = "" | |||
} | |||
var jobTypes []string | |||
jobTypes = append(jobTypes, string(models.JobTypeInference)) | |||
tasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||
@@ -2051,9 +2063,10 @@ func InferenceJobIndex(ctx *context.Context) { | |||
Page: page, | |||
PageSize: setting.UI.IssuePagingNum, | |||
}, | |||
RepoID: repo.ID, | |||
Type: models.TypeCloudBrainTwo, | |||
JobTypes: jobTypes, | |||
RepoID: repo.ID, | |||
ComputeResource: listType, | |||
JobTypes: jobTypes, | |||
Type: models.TypeCloudBrainAll, | |||
}) | |||
if err != nil { | |||
ctx.ServerError("Cloudbrain", err) | |||
@@ -2063,7 +2076,9 @@ func InferenceJobIndex(ctx *context.Context) { | |||
for i, task := range tasks { | |||
tasks[i].CanDel = cloudbrain.CanDeleteJob(ctx, &task.Cloudbrain) | |||
tasks[i].CanModify = cloudbrain.CanModifyJob(ctx, &task.Cloudbrain) | |||
tasks[i].ComputeResource = models.NPUResource | |||
if tasks[i].ComputeResource == "" { | |||
tasks[i].ComputeResource = models.NPUResource | |||
} | |||
} | |||
repoId := ctx.Repo.Repository.ID | |||
@@ -2095,6 +2110,8 @@ func InferenceJobNew(ctx *context.Context) { | |||
ctx.ServerError("get new inference-job info failed", err) | |||
return | |||
} | |||
waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") | |||
ctx.Data["WaitCount"] = waitCount | |||
ctx.HTML(200, tplModelArtsInferenceJobNew) | |||
} | |||
func inferenceJobNewDataPrepare(ctx *context.Context) error { | |||
@@ -1105,6 +1105,16 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.CloudBrainTrainJobNew) | |||
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainForm{}), repo.CloudBrainCreate) | |||
}) | |||
m.Group("/inference-job", func() { | |||
m.Group("/:jobid", func() { | |||
m.Get("", reqRepoCloudBrainReader, repo.InferenceCloudBrainJobShow) | |||
m.Get("/result_download", cloudbrain.AdminOrJobCreaterRightForTrain, repo.CloudBrainDownloadInferenceResult) | |||
m.Get("/downloadall", repo.DownloadInferenceResultFile) | |||
}) | |||
m.Get("/create", reqWechatBind, reqRepoCloudBrainWriter, repo.InferenceCloudBrainJobNew) | |||
m.Post("/create", reqWechatBind, reqRepoCloudBrainWriter, bindIgnErr(auth.CreateCloudBrainInferencForm{}), repo.CloudBrainInferenceJobCreate) | |||
}) | |||
}, context.RepoRef()) | |||
m.Group("/grampus", func() { | |||
m.Group("/train-job", func() { | |||
@@ -204,7 +204,7 @@ | |||
{{else}} | |||
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | |||
class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED"}}disabled {{else}} blue {{end}}button" | |||
data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{else}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}{{end}}" | |||
data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 1}}modelarts/inference-job{{else}}cloudbrain/train-job{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}modelarts/train-job{{else if eq .Cloudbrain.Type 0}}cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}grampus/train-job{{end}}{{end}}" | |||
data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
{{$.i18n.Tr "repo.stop"}} | |||
</a> | |||
@@ -212,7 +212,7 @@ | |||
</div> | |||
<!-- 删除任务 --> | |||
<form class="ui compact buttons" id="delForm-{{$JobID}}" | |||
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{end}}/{{$JobID}}/del?isadminpage=true' | |||
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?isadminpage=true' | |||
method="post"> | |||
{{$.CsrfTokenHtml}} | |||
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" | |||
@@ -1,19 +1,20 @@ | |||
<div class="dataset-repolink" id="dataset-repolink-init" style="display: none;" data-repolink="{{.RepoLink}}" | |||
data-dataset-type="{{.datasetType}}"></div> | |||
<div class="inline required min_title field" id="dataset-base" style="margin-bottom: 0 !important;"> | |||
{{if or (.benchmarkMode) (.newInference)}} | |||
<!-- {{if .benchmarkMode}} | |||
<label | |||
style="font-weight: normal;">{{if .benchmarkMode}}{{.i18n.Tr "repo.model_manager"}}</label><span> </span>{{else}}{{.i18n.Tr "dataset.dataset"}}</label> {{end}} | |||
{{else}} | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "dataset.dataset"}}</label> | |||
{{end}} | |||
{{end}} --> | |||
<label class="label-fix-width" style="font-weight: normal;">{{if .benchmarkMode}}{{.i18n.Tr "repo.model_manager"}}{{else}}{{.i18n.Tr "dataset.dataset"}}{{end}}</label> | |||
<input type="hidden" name="attachment" :value="dataset_uuid"> | |||
<input class="disabled" type="text" :value="dataset_name" required onfocus="this.blur();" style="width: 48.5%;"> | |||
<el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;"> | |||
{{if .benchmarkMode}}{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}{{else}}{{.i18n.Tr "dataset.select_dataset"}}{{end}} | |||
</el-button> | |||
{{if .benchmarkMode}} | |||
<span class="tooltips" style="display: block;padding-left: 0.5rem;">说明:先使用数据集功能上传模型,然后从数据集列表选模型。</span> | |||
<span class="tooltips" style="display: block;margin-left:11.5rem;">说明:先使用数据集功能上传模型,然后从数据集列表选模型。</span> | |||
{{end}} | |||
<el-dialog title="{{.i18n.Tr "dataset.select_dataset"}}" :visible.sync="dialogVisible" width="50%"> | |||
<div v-loading="loadingDataIndex" style="position: relative;"> | |||
@@ -0,0 +1,28 @@ | |||
<div class="tooltip-wati-count"> | |||
{{$queue := ""}} | |||
{{$gpuQueue := 0}} | |||
{{range $k,$v :=.gpu_types}} | |||
{{if eq $k 0}} | |||
{{ $queue := $v.Queue }} | |||
{{ end }} | |||
{{ end }} | |||
{{ range $k,$v :=.QueuesDetail }} | |||
{{if eq $k $queue}} | |||
{{$gpuQueue :=$v}} | |||
{{ end }} | |||
{{ end }} | |||
<i | |||
class="ri-error-warning-line" | |||
style="margin-right: 0.5rem; font-size: 16px" | |||
></i> | |||
<span id="gpu-nums" | |||
>{{.i18n.Tr "repo.wait_count_start"}} | |||
{{if .QueuesDetail}} | |||
{{ $gpuQueue }} | |||
{{else}} | |||
{{.WaitCount}} | |||
{{ end }} | |||
{{.i18n.Tr "repo.wait_count_end"}}</span | |||
> | |||
</div> |
@@ -0,0 +1,28 @@ | |||
<div class="tooltip-wati-count" style="margin-left: 155px"> | |||
{{$queue := ""}} | |||
{{$gpuQueue := 0}} | |||
{{range $k,$v :=.gpu_types}} | |||
{{if eq $k 0}} | |||
{{ $queue := $v.Queue }} | |||
{{ end }} | |||
{{ end }} | |||
{{ range $k,$v :=.QueuesDetail }} | |||
{{if eq $k $queue}} | |||
{{$gpuQueue :=$v}} | |||
{{ end }} | |||
{{ end }} | |||
<i | |||
class="ri-error-warning-line" | |||
style="margin-right: 0.5rem; font-size: 16px" | |||
></i> | |||
<span | |||
>{{.i18n.Tr "repo.wait_count_start"}} | |||
{{if .QueuesDetail}} | |||
{{ $gpuQueue }} | |||
{{else}} | |||
{{.WaitCount}} | |||
{{ end }} | |||
{{.i18n.Tr "repo.wait_count_end"}}</span | |||
> | |||
</div> |
@@ -10,11 +10,9 @@ | |||
padding-left: 3rem !important; | |||
} | |||
.min_title { | |||
.min_title{ | |||
font-size: 14px !important; | |||
padding-left: 6rem !important; | |||
margin-bottom: 2rem !important; | |||
} | |||
.width81 { | |||
@@ -56,25 +54,26 @@ | |||
<form class="ui form model_form" action="{{.Link}}?benchmarkMode=model" method="post"> | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label> | |||
<div class="ui blue small menu compact selectcloudbrain"> | |||
<a class="item alogrithm_benchmark" | |||
href="{{.Link}}?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a> | |||
<a class="active item model_benchmark" | |||
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
</div> | |||
{{template "custom/wait_count_train" .}} | |||
</div> | |||
<div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | |||
placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | |||
tabindex="3" autofocus required maxlength="254"> | |||
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||
<span class="tooltips" style="display: block;margin-left:11.5rem;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||
</div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;" | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;" | |||
for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||
<textarea style="width: 80%;" id="description" name="description" rows="3" required | |||
maxlength="254" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} | |||
@@ -83,8 +82,8 @@ | |||
onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
</div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
<select id="cloudbrain_gpu_type" class="ui search dropdown width48" placeholder="选择GPU类型" | |||
name="gpu_type"> | |||
{{range .benchmark_gpu_types}} | |||
@@ -92,9 +91,9 @@ | |||
{{end}} | |||
</select> | |||
</div> | |||
<div class="required unite min_title two inline fields "> | |||
<div class="required unite min_title two inline fields" style="margin-left: 80px;"> | |||
<div class="required ten wide field" style="width: 26.5% !important;"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||
<select id="cloudbrain_job_type" class="ui search dropdown job_type" | |||
placeholder="select {{.i18n.Tr "cloudbrain.task_type"}}" name="job_type"> | |||
<option value="SNN4IMAGENET">SNN4IMAGENET</option> | |||
@@ -124,8 +123,8 @@ | |||
<div id="images-new-cb"> | |||
</div> | |||
{{template "custom/select_dataset_train" .}} | |||
<div class="required unite min_title inline field" style="margin-top:2rem;"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
<div class="required min_title inline field" style="margin-top:2rem;"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
<select id="cloudbrain_resource_spec" class="ui search dropdown" | |||
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | |||
name="resource_spec_id"> | |||
@@ -136,7 +135,8 @@ | |||
{{end}} | |||
</select> | |||
</div> | |||
<div class="inline unite min_title field"> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;"></label> | |||
<button class="ui create_train_job green button"> | |||
{{.i18n.Tr "repo.cloudbrain.new"}} | |||
</button> | |||
@@ -149,27 +149,28 @@ | |||
{{.CsrfTokenHtml}} | |||
<input type="hidden" name="action" value="update"> | |||
<input type="hidden" name="job_type" value="BENCHMARK"> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label> | |||
<div class="ui blue small menu compact selectcloudbrain"> | |||
<a class="active item alogrithm_benchmark" | |||
href="{{.Link}}?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a> | |||
<a class="item model_benchmark" | |||
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
</div> | |||
{{template "custom/wait_count_train" .}} | |||
</div> | |||
<div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | |||
placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | |||
tabindex="3" autofocus required maxlength="254"> | |||
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||
<span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.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> | |||
<div class="min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;" | |||
for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||
<textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="254" | |||
placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} | |||
onchange="this.value=this.value.substring(0, 255)" | |||
@@ -177,8 +178,8 @@ | |||
onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
</div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
<select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" | |||
style='width:385px' name="gpu_type"> | |||
{{range .benchmark_gpu_types}} | |||
@@ -186,11 +187,11 @@ | |||
{{end}} | |||
</select> | |||
</div> | |||
<div class="required unite inline min_title fields" style="width: 90%;"> | |||
<div class="required unite inline min_title fields" style="width: 90%;margin-left: 5.7rem;"> | |||
<div class="required eight wide field"> | |||
<label | |||
style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</label> | |||
<span> </span> | |||
<select class="ui fluid selection search dropdown" id="benchmark_types_id" | |||
name="benchmark_types_id"> | |||
{{range .benchmark_types}} | |||
@@ -215,8 +216,8 @@ | |||
<div id="images-new-cb"> | |||
</div> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
<select id="cloudbrain_resource_spec" class="ui search dropdown" | |||
placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | |||
name="resource_spec_id"> | |||
@@ -228,18 +229,16 @@ | |||
</select> | |||
</div> | |||
<div class="inline unite min_title field required"> | |||
<label | |||
style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label> | |||
<div class="inline min_title field required"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label> | |||
<input disabled="disabled" style="width: 33.5%;" name="train_file" id="train_file" | |||
value="train.py" tabindex="3" autofocus required maxlength="254"> | |||
<a id="train_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" | |||
target="_blank">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</a> | |||
</div> | |||
<div class="inline unite min_title field required"> | |||
<label | |||
style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label> | |||
<div class="inline min_title field required"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label> | |||
<input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py" | |||
tabindex="3" autofocus required maxlength="254"> | |||
<a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" | |||
@@ -248,6 +247,7 @@ | |||
<div class="inline unite min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;"></label> | |||
<button class="ui create_train_job green button"> | |||
{{.i18n.Tr "repo.cloudbrain.new"}} | |||
</button> | |||
@@ -273,7 +273,6 @@ | |||
$(document).ready(() => { | |||
$('.ui.search.dropdown.job_type').dropdown({ | |||
onChange: function (value, text, $selectedItem) { | |||
console.log(value, text) | |||
if (value === "BRAINSCORE") { | |||
$('#brainscore_child_type').css('display', 'block') | |||
$('#benchmark_model_example').attr('href', 'https://git.openi.org.cn/BDIP/similarity2brain_ann') | |||
@@ -0,0 +1,480 @@ | |||
{{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; | |||
margin-bottom: 2rem !important; | |||
} | |||
.width{ | |||
width:100% !important; | |||
} | |||
.width80{ | |||
width: 80.7% !important; | |||
} | |||
.width85 { | |||
width: 85% !important; | |||
margin-left: 10.5rem !important; | |||
align-items: center; | |||
} | |||
.width35{ | |||
width: 35.5% !important; | |||
} | |||
.width48{ | |||
width: 48.5% !important; | |||
} | |||
.nowrapx { | |||
white-space: nowrap !important; | |||
} | |||
</style> | |||
<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" .}} | |||
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}"></div> | |||
<h4 class="ui top attached header"> | |||
{{.i18n.Tr "repo.modelarts.train_job.new_infer"}} | |||
</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=""> | |||
{{if $.model_version}} | |||
<input type="hidden" id="ai_model_version" name="model_version" value="{{$.model_version}}"> | |||
{{else}} | |||
<input type="hidden" id="ai_model_version" name="model_version" value=""> | |||
{{end}} | |||
{{if $.label_names}} | |||
<input type="hidden" id="ai_model_label" name="label_names" value="{{$.label_names}}"> | |||
{{else}} | |||
<input type="hidden" id="ai_model_label" name="label_names" value=""> | |||
{{end}} | |||
<h4 class="unite title ui header ">{{.i18n.Tr "repo.modelarts.train_job.basic_info"}}:</h4> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||
<div class="ui blue mini menu compact selectcloudbrain"> | |||
<a class="active item" href="{{.RepoLink}}/cloudbrain/inference-job/create"> | |||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||
height="16"> | |||
<path fill="none" d="M0 0h24v24H0z" /> | |||
<path | |||
d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
</svg> | |||
CPU/GPU | |||
</a> | |||
<a class="item" href="{{.RepoLink}}/modelarts/inference-job/create"> | |||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||
height="16"> | |||
<path fill="none" d="M0 0h24v24H0z" /> | |||
<path | |||
d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
</svg> | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" .}} | |||
</div> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | |||
<span class="tooltips" style="margin-left:11.5rem;display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||
</div> | |||
<div class="unite min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||
<textarea style="width: 80%;" id="description" 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 inline min_title fields" style="width: 96.8%;"> | |||
<div class="required eight wide field"> | |||
<label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label> | |||
<div class="ui fluid search selection dropdown loading " id="select_model"> | |||
{{if $.ckpt_name}} | |||
<input type="hidden" name="model_name" value="{{$.model_name}}" required> | |||
<div class="text">{{$.model_name}}</div> | |||
{{else}} | |||
<input type="hidden" name="model_name" required> | |||
<div class="text"></div> | |||
{{end}} | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="model_name"> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="three wide field"> | |||
<div class="ui fluid search selection dropdown" id="select_model_version"> | |||
{{if $.ckpt_name}} | |||
<input type="hidden" name="train_url" value="{{$.train_url}}" required> | |||
<div class="text">{{$.model_version}}</div> | |||
{{else}} | |||
<input type="hidden" name="train_url" required> | |||
<div class="text"></div> | |||
{{end}} | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="model_name_version"> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="five wide field"> | |||
<div class="ui fluid search selection dropdown" id="select_model_checkpoint"> | |||
{{if $.ckpt_name}} | |||
<input type="hidden" name="ckpt_name" value="{{$.ckpt_name}}" required> | |||
<div class="text">{{$.ckpt_name}}</div> | |||
{{else}} | |||
<input type="hidden" name="ckpt_name" required> | |||
<div class="text"></div> | |||
{{end}} | |||
<i class="dropdown icon"></i> | |||
<div class="menu" id="model_checkpoint"> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<!-- AI引擎 --> | |||
<div id="images-new-cb"> | |||
</div> | |||
<!-- 代码分支 --> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||
<select class="ui dropdown width48" id="code_version" name="branch_name"> | |||
{{if .branch_name}} | |||
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||
{{range $k, $v :=.Branches}} | |||
{{ if ne $v $.branch_name }} | |||
<option name="branch_name" value="{{$v}}">{{$v}}</option> | |||
{{end}} | |||
{{end}} | |||
{{else}} | |||
<option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||
{{range $k, $v :=.Branches}} | |||
{{ if ne $v $.branchName }} | |||
<option name="branch_name" value="{{$v}}">{{$v}}</option> | |||
{{end}} | |||
{{end}} | |||
{{end}} | |||
</select> | |||
</div> | |||
<!-- GPU 卡的类型 --> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
<select id="cloudbrain_gpu_type" class="ui search width48 dropdown gpu-type" placeholder="选择GPU类型" | |||
style='width:385px' name="gpu_type"> | |||
{{range .inference_gpu_types}} | |||
<option value="{{.Queue}}">{{.Value}}</option> | |||
{{end}} | |||
</select> | |||
</div> | |||
<!-- 数据集 --> | |||
{{template "custom/select_dataset_train" .}} | |||
<span class="tooltips" style="margin-left: 11.5rem;margin-bottom: 1rem;"></span> | |||
<div class="inline min_title field required"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
{{if .bootFile}} | |||
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||
{{else}} | |||
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="" tabindex="3" autofocus required maxlength="255" > | |||
{{end}} | |||
<span > | |||
<i class="question circle icon" data-content={{.i18n.Tr "repo.modelarts.infer_job.boot_file_helper"}} data-position="top center" data-variation="inverted mini"></i> | |||
</span> | |||
<a href="https://git.openi.org.cn/OpenIOSSG/MNIST_PytorchExample_GPU/src/branch/master/inference.py" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
</div> | |||
<!-- 运行参数 --> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||
<span id="add_run_para" style="cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
<input id="store_run_para" type="hidden" name="run_para_list"> | |||
<div class="dynamic field" style="margin-top: 1rem;"> | |||
{{if ne 0 (len .params)}} | |||
{{range $k ,$v := .params}} | |||
<div class="two fields width85" id="para{{$k}}"> | |||
<div class="field"> | |||
<input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||
</div> | |||
<div class="field"> | |||
<input type="text" name="shipping_last-name" value={{$v.Value}} required> | |||
</div> | |||
<span> | |||
<i class="trash icon"></i> | |||
</span> | |||
</div> | |||
{{end}} | |||
{{end}} | |||
</div> | |||
</div> | |||
<div class="required field " style="display: none;"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.resource_pool"}}</label> | |||
<select class="ui dropdown" id="trainjob_resource_pool" style='width:385px' name="pool_id"> | |||
{{range .resource_pools}} | |||
<option value="{{.ID}}">{{.Value}}</option> | |||
{{end}} | |||
</select> | |||
</div> | |||
<!-- 规格 --> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
<select id="cloudbrain_resource_spec" class="ui search dropdown width80" placeholder="选择资源规格" name="resource_spec_id"> | |||
{{range .inference_resource_specs}} | |||
<option name="resource_spec_id" value="{{.Id}}"> | |||
GPU数:{{.GpuNum}},CPU数:{{.CpuNum}},内存(MB):{{.MemMiB}},共享内存(MB):{{.ShareMemMiB}}</option> | |||
{{end}} | |||
</select> | |||
</div> | |||
<!-- 表单操作 --> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;"></label> | |||
<button class="ui create_train_job green button"> | |||
{{.i18n.Tr "repo.cloudbrain.new"}} | |||
</button> | |||
<a class="ui button" href="{{.RepoLink}}/modelarts/inference-job">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
</div> | |||
<!-- 模态框 --> | |||
</form> | |||
</div> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
<script> | |||
const RepoLink = {{.RepoLink}} | |||
let nameMap,nameList | |||
// 获取模型列表和模型名称对应的模型版本 | |||
$.get(`${RepoLink}/modelmanage/query_model_for_predict?type=0`, (data) => { | |||
modelVersion() | |||
modelCkpt() | |||
nameMap = data.nameMap | |||
nameList = data.nameList | |||
let html = '' | |||
nameList.forEach(element => { | |||
html += `<div class="item" data-value=${element}>${element}</div>` | |||
}); | |||
if(nameList.length!==0){ | |||
const initModelVersion = nameMap[nameList[0]][0] | |||
const initTrainTaskInfo = JSON.parse(initModelVersion.TrainTaskInfo) | |||
$('#model_name').append(html) | |||
$("#select_model").dropdown('set text',nameList[0]) | |||
$("#select_model").dropdown('set value',nameList[0],nameList[0]) | |||
} | |||
$('#select_model').removeClass("loading") | |||
}) | |||
// 根据选中的模型名称获取相应的模型版本 | |||
function modelVersion(){ | |||
$('#select_model').dropdown({ | |||
onChange: function(value, text, $selectedItem) { | |||
$("#select_model_version").addClass("loading") | |||
$('#model_name_version').empty() | |||
let html = '' | |||
nameMap[value].forEach(element => { | |||
let {TrainTaskInfo} = element | |||
TrainTaskInfo = JSON.parse(TrainTaskInfo) | |||
html += `<div class="item" data-label="${element.Label}" data-id="${element.ID}" data-value="${element.Path}">${element.Version}</div>` | |||
}); | |||
$('#model_name_version').append(html) | |||
$("#select_model_version").removeClass("loading") | |||
const initVersionText = $('#model_name_version div.item:first-child').text() | |||
const initVersionValue = $('#model_name_version div.item:first-child').data('value') | |||
$("#select_model_version").dropdown('set text',initVersionText) | |||
$("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||
} | |||
}) | |||
} | |||
// 根据选中的模型版本获取相应的模型权重文件 | |||
function modelCkpt(){ | |||
$('#select_model_version').dropdown({ | |||
onChange: function(value, text, $selectedItem) { | |||
const dataID = $selectedItem[0].getAttribute("data-id") | |||
const label = $selectedItem[0].getAttribute("data-label") | |||
$("#select_model_checkpoint").addClass("loading") | |||
$("#model_checkpoint").empty() | |||
let html = '' | |||
loadCheckpointList(dataID).then((res)=>{ | |||
res.forEach(element => { | |||
const ckptSuffix = element.FileName.split(".") | |||
const loadCheckpointFile = ['ckpt','pb','h5','json','pkl','pth','t7'] | |||
if(!element.IsDir && loadCheckpointFile.includes(ckptSuffix[ckptSuffix.length-1])){ | |||
html += `<div class="item" data-value=${element.FileName}>${element.FileName}</div>` | |||
} | |||
}) | |||
$('#model_checkpoint').append(html) | |||
$("#select_model_checkpoint").removeClass("loading") | |||
const initVersionText = $('#model_checkpoint div.item:first-child').text() | |||
const initVersionValue = $('#model_checkpoint div.item:first-child').data('value') | |||
$("#select_model_checkpoint").dropdown('set text',initVersionText) | |||
$("#select_model_checkpoint").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||
}) | |||
$("input#ai_model_version").val(text) | |||
$("input#ai_model_label").val(label) | |||
} | |||
}) | |||
} | |||
function loadCheckpointList(value){ | |||
return new Promise((resolve,reject)=>{ | |||
$.get(`${RepoLink}/modelmanage/query_modelfile_for_predict`,{ID:value}, (data) => { | |||
resolve(data) | |||
}) | |||
}) | |||
} | |||
$('.question.circle.icon').hover(function(){ | |||
$(this).popup('show') | |||
}); | |||
// 参数增加、删除、修改、保存 | |||
function Add_parameter(i){ | |||
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) | |||
}) | |||
}); | |||
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) | |||
} | |||
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}[^-]$/]', | |||
} | |||
] | |||
}, | |||
attachment:{ | |||
identifier : 'attachment', | |||
rules: [ | |||
{ | |||
type: 'empty', | |||
} | |||
] | |||
}, | |||
model_name:{ | |||
identifier : 'model_name', | |||
rules: [ | |||
{ | |||
type: 'empty', | |||
} | |||
] | |||
}, | |||
train_url:{ | |||
identifier : 'train_url', | |||
rules: [ | |||
{ | |||
type: 'empty', | |||
} | |||
] | |||
}, | |||
ckpt_name:{ | |||
identifier : 'ckpt_name', | |||
rules: [ | |||
{ | |||
type: 'empty', | |||
} | |||
] | |||
} | |||
}, | |||
onSuccess: function(){ | |||
document.getElementById("mask").style.display = "block" | |||
}, | |||
onFailure: function(e){ | |||
return false; | |||
} | |||
}) | |||
} | |||
document.onreadystatechange = function() { | |||
if (document.readyState === "complete") { | |||
document.getElementById("mask").style.display = "none" | |||
} | |||
} | |||
$('.ui.create_train_job.green.button').click(function(e) { | |||
send_run_para() | |||
get_name() | |||
validate() | |||
}) | |||
</script> |
@@ -0,0 +1,605 @@ | |||
{{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/inference-job"> | |||
{{$.i18n.Tr "repo.modelarts.infer_job"}} | |||
</a> | |||
<div class="divider"> / </div> | |||
<div class="active section">{{.displayJobName}}</div> | |||
</div> | |||
</h4> | |||
{{with .task}} | |||
<div class="ui accordion border-according" id="accordion{{.VersionName}}" | |||
data-repopath="{{$.RepoRelPath}}/cloudbrain/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
<input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | |||
<div class="active title padding0"> | |||
<div class="according-panel-heading"> | |||
<div class="accordion-panel-title"> | |||
<i class="dropdown icon"></i> | |||
<span class="accordion-panel-title-content"> | |||
<span> | |||
<div class="ac-display-inblock title_text acc-margin-bottom"> | |||
<span class="cti-mgRight-sm">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||
<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||
<span id="{{.VersionName}}-status-span"><i id="icon" | |||
style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" | |||
style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
</span> | |||
<span | |||
class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
<span class="cti-mgRight-sm uc-accordionTitle-black" | |||
id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||
<span id="refresh-status" data-tooltip="刷新" style="cursor: pointer;" data-inverted="" data-version="{{.VersionName}}"><i | |||
class="redo icon redo-color"></i></span> | |||
</div> | |||
</span> | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="active content"> | |||
<div class="content-pad"> | |||
<div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
<a class="active item" | |||
data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
<a class="item" data-tab="second" | |||
onclick="javascript:parseInfo()">{{$.i18n.Tr "repo.cloudbrain.runinfo"}}</a> | |||
<a class="item load-model-file" data-tab="four" | |||
data-path="{{$.RepoLink}}/cloudbrain/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first" style="height:400px"> | |||
<div style="padding-top: 10px;"> | |||
<div class="tab_2_content"> | |||
<div class="ac-grid ac-grid-col2"> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain_task"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.DisplayJobName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.status"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-status"> | |||
{{.Status}} | |||
</div> | |||
</td> | |||
</tr> | |||
<!-- <tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.run_version"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.VersionName}} | |||
</div> | |||
</td> | |||
</tr> --> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
<span style="font-size: 12px;" class=""> | |||
{{if not (eq .StartTime 0)}} | |||
{{TimeSinceUnix1 .StartTime}} | |||
{{else}} | |||
{{TimeSinceUnix1 .CreatedUnix}} | |||
{{end}} | |||
</span> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
{{.TrainJobDuration}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.resource_type"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<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.model.manage.description"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-desc" style="width: 380px;"> | |||
{{if .Description}} | |||
<span title="{{.Description}}">{{.Description}}</span> | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
创建人 | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-creator"> | |||
{{.User.Name}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "cloudbrain.mirror"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
{{.Image}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.infer_job_model"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
<span>{{.ModelName}}</span> | |||
<span style="color: #8a8e99">{{$.i18n.Tr "repo.modelarts.version"}}:</span><span>{{.ModelVersion}}</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.infer_job_model_file"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.CkptName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.model_label"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-labels"> | |||
{{if .LabelName}} | |||
{{range $.labelName}} | |||
<a class="ui label" title="{{.}}">{{.}}</a> | |||
{{end}} | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.code_version"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.BranchName}} | |||
</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.infer_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}}"> | |||
{{if .Parameters}} | |||
<span>{{.Parameters}}</span> | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<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> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="ui tab" data-tab="second"> | |||
<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="four"> | |||
<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}} | |||
</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 }} | |||
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> |
@@ -121,7 +121,7 @@ | |||
{{template "repo/header" .}} | |||
<div class="repository new repo ui middle very relaxed page grid"> | |||
<div class="column"> | |||
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div> | |||
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}"></div> | |||
{{template "base/alert" .}} | |||
<div class="ui negative message" id="messageInfo"> | |||
<p></p> | |||
@@ -154,6 +154,7 @@ | |||
</svg> | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count" .}} | |||
</div> | |||
<div class="inline required field"> | |||
<label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | |||
@@ -208,7 +209,7 @@ | |||
</div> | |||
<div class="inline required field"> | |||
<label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
<select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" | |||
<select id="cloudbrain_gpu_type" class="ui search dropdown gpu-type" placeholder="选择GPU类型" | |||
style='width:385px' name="gpu_type"> | |||
{{range .gpu_types}} | |||
<option value="{{.Queue}}">{{.Value}}</option> | |||
@@ -287,8 +288,6 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
let form = document.getElementById('form_id'); | |||
$('#messageInfo').css('display', 'none') | |||
function clearValue() { | |||
context = inputs[0] | |||
@@ -318,6 +317,7 @@ | |||
if (document.readyState === "complete") { | |||
document.getElementById("mask").style.display = "none" | |||
} | |||
} | |||
$('#cloudbrain_benchmark_category') | |||
@@ -325,14 +325,36 @@ | |||
placeholder: "选择数据集类别", | |||
}) | |||
$('select.dropdown') | |||
.dropdown(); | |||
console.log("=======================") | |||
// $(document).ready(function(){ | |||
// let waitNums = $('.cloudbrain-type').data('queue').split('map')[1] | |||
// let test = new Map() | |||
// let waitNumsArray = waitNums.split(' ') | |||
// waitNumsArray.forEach((element,index) => { | |||
// if(index===0){ | |||
// test.set(element.slice(1,-2),parseInt(element.slice(-1))) | |||
// }else if(index===waitNumsArray.length-1){ | |||
// test.set(element.slice(0,-3),parseInt(element.slice(-2,-1))) | |||
// }else{ | |||
// test.set(element.slice(0,-2),parseInt(element.slice(-1))) | |||
// } | |||
// }); | |||
// console.log(test) | |||
// $('.ui.search.dropdown.gpu-type').dropdown({ | |||
// onChange: function(value, text, $selectedItem) { | |||
// console.log("=-------------",value) | |||
// console.log("=-------------",test.get(value)) | |||
// let gpuTypeNums= test.get(value) | |||
// $('#gpu-nums').text("{{.i18n.Tr "repo.wait_count_start"}}"+gpuTypeNums+"{{.i18n.Tr "repo.wait_count_end"}}") | |||
// } | |||
// }); | |||
// }) | |||
// $('#cloudbrain_image').select2({ | |||
// placeholder: "选择镜像" | |||
// }); | |||
$(".ui.button.reset").click(function (e) { | |||
e.preventDefault() | |||
@@ -79,7 +79,7 @@ | |||
<div class="repository"> | |||
{{template "repo/header" .}} | |||
<div class="ui container"> | |||
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}"></div> | |||
<div class="cloudbrain-type" style="display: none;" data-cloudbrain-type="{{.datasetType}}" data-repo-link="{{.RepoLink}}" data-queue="{{.QueuesDetail}}" data-queue-start="{{.i18n.Tr "repo.wait_count_start"}}" data-queue-end="{{.i18n.Tr "repo.wait_count_end"}}"></div> | |||
{{template "base/alert" .}} | |||
<h4 class="ui top attached header"> | |||
{{.i18n.Tr "repo.modelarts.train_job.new"}} | |||
@@ -126,6 +126,7 @@ | |||
</svg> | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" .}} | |||
</div> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
@@ -181,7 +182,7 @@ | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
<select id="cloudbrain_gpu_type" class="ui search width806 dropdown" placeholder="选择GPU类型" | |||
<select id="cloudbrain_gpu_type" class="ui search width806 dropdown gpu-type" placeholder="选择GPU类型" | |||
style='width:385px' name="gpu_type"> | |||
{{range .train_gpu_types}} | |||
<option value="{{.Queue}}">{{.Value}}</option> | |||
@@ -211,10 +212,6 @@ | |||
<div id="select-multi-dataset"> | |||
</div> | |||
<!-- {{template "custom/select_dataset_train" .}} --> | |||
<span class="tooltips" | |||
style="margin-left: 11.5rem;margin-bottom: 1rem;">训练脚本存储在/code中,数据集存储在/dataset中,训练输出请存储在/model中以供后续下载。</span> | |||
<div class="inline min_title field"> | |||
@@ -274,8 +271,6 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
//let url_href = window.location.pathname.split('create')[0] | |||
//$(".ui.button").attr('href',url_href) | |||
$('select.dropdown') | |||
.dropdown(); | |||
@@ -264,8 +264,7 @@ | |||
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> | |||
<a class="item load-model-file" data-tab="four{{$k}}" data-path="{{$.RepoLink}}/cloudbrain/train-job/{{.JobID}}/model_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first{{$k}}"> | |||
<div style="padding-top: 10px;"> | |||
@@ -467,7 +466,7 @@ | |||
<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="active section">result</div> | |||
<div class="divider"> / </div> | |||
</div> | |||
@@ -554,122 +553,6 @@ | |||
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) => { | |||
@@ -113,6 +113,7 @@ | |||
</svg> | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" .}} | |||
</div> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
@@ -108,11 +108,13 @@ | |||
</svg> | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" .}} | |||
</div> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" 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> | |||
<span class="tooltips" style="display: block;margin-left: 11.5rem;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||
</div> | |||
<div class="min_title inline field"> | |||
@@ -273,8 +273,7 @@ | |||
data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
<a class="item" data-tab="second{{$k}}" | |||
onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
<a class="item" data-tab="third{{$k}}" | |||
onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | |||
<a class="item load-model-file" data-tab="third{{$k}}" data-path="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/model_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first{{$k}}"> | |||
<div style="padding-top: 10px;"> | |||
@@ -663,18 +662,6 @@ | |||
$('#name').val(modelName) | |||
$('#version').val("0.0.1") | |||
} | |||
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}/grampus/train-job/${jobID}?version_name=${version_name}`, (data) => { | |||
// header status and duration | |||
@@ -745,243 +732,4 @@ | |||
console.log(err); | |||
}); | |||
} | |||
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++) { | |||
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}/model_download?version_name=${version_name}&file_name=${data.Dirs[i].FileName}&parent_dir=${data.Dirs[i].ParenDir}">` | |||
} | |||
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 debounce(fn, delay) { | |||
let timer; | |||
return (...args) => { | |||
// 判断定时器是否存在,清除定时器 | |||
if (timer) { | |||
clearTimeout(timer); | |||
} | |||
// 重新调用setTimeout | |||
timer = setTimeout(() => { | |||
fn.apply(this, args); | |||
}, delay); | |||
}; | |||
} | |||
const fn = debounce(logScroll, 500) | |||
function logScroll(version_name) { | |||
let container = document.querySelector(`#log${version_name}`) | |||
let scrollTop = container.scrollTop | |||
let scrollHeight = container.scrollHeight | |||
let clientHeight = container.clientHeight | |||
let scrollLeft = container.scrollLeft | |||
if (((parseInt(scrollTop) + clientHeight == scrollHeight || parseInt(scrollTop) + clientHeight + 1 == scrollHeight || parseInt(scrollTop) + clientHeight - 1 == scrollHeight)) && parseInt(scrollTop) !== 0 && scrollLeft == 0) { | |||
let 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}&lines=50&order=desc`, (data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text('您已翻阅至日志底部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
} else { | |||
if (end_line === data.EndLine) { | |||
return | |||
} | |||
else { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) | |||
$(`#log${version_name}`).append('<pre>' + data.Content) | |||
} | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
if ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].includes(scrollTop) && scrollLeft == 0) { | |||
let 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}&lines=50&order=asc`, (data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text('您已翻阅至日志顶部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
} else { | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值 | |||
$(`#log${version_name}`).prepend('<pre>' + data.Content) | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
} | |||
function scrollAnimation(dom, currentY, targetY, currentX) { | |||
let needScrollTop = targetY - currentY; | |||
let _currentY = currentY; | |||
setTimeout(() => { | |||
// 一次调用滑动帧数,每次调用会不一样 | |||
//取总距离的十分之一 | |||
const dist = Math.ceil(needScrollTop / 10); | |||
_currentY += dist; | |||
//移动一个十分之一 | |||
dom.scrollTo(currentX || 0, _currentY, 'smooth'); | |||
// 如果移动幅度小于十个像素,直接移动,否则递归调用,实现动画效果 | |||
if (needScrollTop > 10 || needScrollTop < -10) { | |||
scrollAnimation(dom, _currentY, targetY) | |||
} else { | |||
dom.scrollTo(0, targetY, 'smooth') | |||
} | |||
}, 1) | |||
} | |||
$('.log_top').click(function () { | |||
// let logContentDom = document.querySelector('.log') | |||
// if(!logContentDom) | |||
// return | |||
// let version_name = $('.log_top').data('version') | |||
let version_name = $(this).data('version') | |||
let logContentDom = document.querySelector(`#log${version_name}`) | |||
$(`#log_file${version_name}`).siblings('pre').remove() | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/grampus/train-job/${jobID}/log?version_name=${version_name}&base_line=&lines=50&order=asc`, (data) => { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) //如果变动就改变所对应的值 | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) | |||
$(`#log${version_name}`).prepend('<pre>' + data.Content) | |||
$(`.message${version_name} #header`).text('您已翻阅至日志顶部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
scrollAnimation(logContentDom, logContentDom.scrollTop, 0); | |||
}) | |||
}) | |||
$('.log_bottom').click(function (e) { | |||
let version_name = $(this).data('version') | |||
let logContentDom = document.querySelector(`#log${version_name}`) | |||
$(`#log_file${version_name}`).siblings('pre').remove() | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/grampus/train-job/${jobID}/log?version_name=${version_name}&base_line=&lines=50&order=desc`, (data) => { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) //如果变动就改变所对应的值 | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) | |||
$(`#log${version_name}`).append('<pre>' + data.Content) | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/grampus/train-job/${jobID}/log?version_name=${version_name}&base_line=${data.EndLine}&lines=50&order=desc`, (data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text('您已翻阅至日志底部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
} else { | |||
if (end_line === data.EndLine) { | |||
return | |||
} | |||
else { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) | |||
$(`#log${version_name}`).append('<pre>' + data.Content) | |||
} | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
scrollAnimation(logContentDom, logContentDom.scrollTop + 1, logContentDom.scrollHeight - logContentDom.clientHeight); | |||
}) | |||
}) | |||
</script> |
@@ -39,8 +39,18 @@ | |||
</div> | |||
</div> | |||
<div class="column right aligned"> | |||
<div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
{{svg "octicon-server" 16}} | |||
<div class="default text" style="color: rgba(0,0,0,.87);"></div> | |||
<i class="dropdown icon"></i> | |||
<div class="menu"> | |||
<div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div> | |||
<div class="item" data-value="CPU/GPU">CPU/GPU</div> | |||
<div class="item" data-value="NPU">NPU</div> | |||
</div> | |||
</div> | |||
{{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||
<a class="ui green button" href="{{.RepoLink}}/modelarts/inference-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a> | |||
<a class="ui green button" href="{{.RepoLink}}/cloudbrain/inference-job/create">{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a> | |||
{{else}} | |||
<a class="ui disabled button" >{{$.i18n.Tr "repo.modelarts.train_job.new_infer"}}</a> | |||
{{end}} | |||
@@ -72,28 +82,28 @@ | |||
<!-- 表头 --> | |||
<div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
<div class="row"> | |||
<div class="three wide column padding0"> | |||
<div class="three wide column padding0" style="width: 17% !important;"> | |||
<span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||
</div> | |||
<div class="three wide column text center padding0"> | |||
<div class="three wide column text center padding0" style="width: 17% !important;"> | |||
<span style="margin:0 6px">{{$.i18n.Tr "repo.modelarts.infer_job.model_version"}}</span> | |||
</div> | |||
<div class="two wide column text center padding0"> | |||
<div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
<span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | |||
</div> | |||
<div class="two wide column text center padding0"> | |||
<div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
<span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
</div> | |||
<div class="two wide column text center padding0"> | |||
<div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
<span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||
</div> | |||
<!-- <div class="two wide column text center padding0"> | |||
<div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
<span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
</div> --> | |||
<div class="one wide column text center padding0"> | |||
</div> | |||
<div class="one wide column text center padding0" style="width: 6% !important;"> | |||
<span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
</div> | |||
<div class="three wide column text center padding0"> | |||
<div class="three wide column text center padding0" style="width: 18% !important;"> | |||
<span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | |||
</div> | |||
</div> | |||
@@ -104,37 +114,37 @@ | |||
<div class="row"> | |||
<!-- 任务名 --> | |||
<div class="three wide column padding0"> | |||
<a class="title" href="{{$.Link}}/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
<div class="three wide column padding0" style="width: 17% !important;"> | |||
<a class="title" href="/{{$.RepoRelPath}}/{{if eq .Cloudbrain.Type 0 }}cloudbrain{{else}}modelarts{{end}}/inference-job/{{.JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
<span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
</a> | |||
</div> | |||
<!-- 模型版本 --> | |||
<!-- href="{{$.RepoLink}}/modelmanage/show_model_info?name={{.ModelName}}" --> | |||
<div class="three wide column text center padding0" style="display: flex;"> | |||
<div class="three wide column text center padding0" style="display: flex;width: 17% !important;"> | |||
<a id="{{.JobName}}" class="goto_modelmanage nowrap" title="{{.ModelName}}" href="javascript:void(0);" data-variation="inverted" data-position="top center" data-content="{{$.i18n.Tr "repo.modelarts.infer_job.tooltip"}}" data-jobname={{.JobName}} data-modelname={{.ModelName}} data-version={{.ModelVersion}} data-repopath="{{$.RepoLink}}">{{.ModelName}} </a> <span style="font-size: 12px;">{{.ModelVersion}}</span> | |||
</div> | |||
<!-- 任务状态 --> | |||
<div class="two wide column text center padding0" > | |||
<span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
<div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
<span class="job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}/{{if eq .Cloudbrain.Type 0 }}cloudbrain{{else}}modelarts{{end}}/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
<span><i id="{{.JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
</span> | |||
</div> | |||
<!-- 任务创建时间 --> | |||
<div class="two wide column text center padding0"> | |||
<div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
<span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | |||
</div> | |||
<!-- 任务运行时间 --> | |||
<div class="two wide column text center padding0"> | |||
<div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
<span style="font-size: 12px;" id="duration-{{.JobID}}">{{.TrainJobDuration}}</span> | |||
</div> | |||
<!-- 计算资源 --> | |||
<!-- <div class="two wide column text center padding0"> | |||
<div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
<span style="font-size: 12px;">{{.ComputeResource}}</span> | |||
</div> --> | |||
</div> | |||
<!-- 创建者 --> | |||
<div class="one wide column text center padding0"> | |||
<div class="one wide column text center padding0" style="width: 6% !important;"> | |||
{{if .User.Name}} | |||
<a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
{{else}} | |||
@@ -142,8 +152,27 @@ | |||
{{end}} | |||
</div> | |||
<div class="three wide column text center padding0"> | |||
<div class="three wide column text center padding0" style="width: 18% !important;"> | |||
<!-- 停止任务 --> | |||
{{if eq .Cloudbrain.Type 0 }} | |||
<div class="ui compact buttons"> | |||
<form id="stopForm-{{.JobID}}" style="margin-left:-1px;"> | |||
{{$.CsrfTokenHtml}} | |||
{{if .CanDel}} | |||
<a id="ai-stop-{{.JobID}}" | |||
class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' | |||
data-repopath="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/stop" | |||
data-jobid="{{.JobID}}"> | |||
{{$.i18n.Tr "repo.stop"}} | |||
</a> | |||
{{else}} | |||
<a class="ui basic disabled button"> | |||
{{$.i18n.Tr "repo.stop"}} | |||
</a> | |||
{{end}} | |||
</form> | |||
</div> | |||
{{else}} | |||
<div class="ui compact buttons"> | |||
{{$.CsrfTokenHtml}} | |||
{{if .CanDel}} | |||
@@ -157,11 +186,12 @@ | |||
{{end}} | |||
</div> | |||
{{end}} | |||
<!-- 下载 --> | |||
<div class="ui compact buttons"> | |||
{{$.CsrfTokenHtml}} | |||
{{if .CanModify}} | |||
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-download-{{.JobID}}" href="{{$.RepoLink}}/modelarts/inference-job/{{.JobID}}/downloadall?version_name={{.VersionName}}" class="ui basic blue button" style="border-radius: .28571429rem;"> | |||
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="model-download-{{.JobID}}" href="{{$.RepoLink}}/{{if eq .Cloudbrain.Type 0 }}cloudbrain{{else}}modelarts{{end}}/inference-job/{{.JobID}}/downloadall?version_name={{.VersionName}}" class="ui basic blue button" style="border-radius: .28571429rem;"> | |||
{{$.i18n.Tr "repo.model_download"}} | |||
</a> | |||
{{else}} | |||
@@ -174,9 +204,16 @@ | |||
<div class="ui compact buttons"> | |||
{{$.CsrfTokenHtml}} | |||
{{if .CanDel}} | |||
{{if eq .Cloudbrain.Type 0 }} | |||
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" data-repopath="{{$.RepoRelPath}}/cloudbrain/inference-job/{{.JobID}}/del" data-version="V0001" style="border-radius: .28571429rem;"> | |||
{{$.i18n.Tr "repo.delete"}} | |||
</a> | |||
{{else}} | |||
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{.JobID}}" class="ui basic ai_delete blue button" data-repopath="{{$.RepoRelPath}}/modelarts/inference-job/{{.JobID}}/del_version" data-version="{{.VersionName}}" style="border-radius: .28571429rem;"> | |||
{{$.i18n.Tr "repo.delete"}} | |||
</a> | |||
{{end}} | |||
{{else}} | |||
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" class="ui basic button disabled" style="border-radius: .28571429rem;"> | |||
{{$.i18n.Tr "repo.delete"}} | |||
@@ -237,3 +274,27 @@ | |||
</div> | |||
{{template "base/footer" .}} | |||
<script> | |||
let url = {{$.RepoLink}}; | |||
let all = {{$.i18n.Tr "repo.gpu_type_all"}} | |||
$(document).ready(function(){ | |||
const params = new URLSearchParams(location.search) | |||
if(!location.search){ | |||
$('.default.text').text(all) | |||
}else{ | |||
if(!params.has('listType') || params.get('listType')=='all'){ | |||
$('.default.text').text(all) | |||
} | |||
else{ | |||
$('.default.text').text(params.get('listType')) | |||
} | |||
} | |||
$('.ui.selection.dropdown').dropdown({ | |||
onChange:function(value){ | |||
location.href = `${url}/modelarts/inference-job?listType=${value}` | |||
} | |||
}) | |||
}) | |||
</script> | |||
@@ -11,16 +11,18 @@ | |||
} | |||
.min_title{ | |||
font-size: 14px !important; | |||
padding-left: 6rem !important; | |||
margin-bottom: 2rem !important; | |||
} | |||
.width80{ | |||
width: 80.7% !important; | |||
} | |||
.width84{ | |||
width: 84% !important; | |||
margin-left: 5.1rem !important; | |||
.width{ | |||
width:100% !important; | |||
} | |||
.width85 { | |||
width: 85% !important; | |||
margin-left: 10.5rem !important; | |||
align-items: center; | |||
} | |||
.width35{ | |||
width: 35.5% !important; | |||
@@ -67,23 +69,46 @@ | |||
<input type="hidden" id="ai_model_label" name="label_names" value=""> | |||
{{end}} | |||
<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 "repo.modelarts.train_job.job_name"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||
<div class="ui blue mini menu compact selectcloudbrain"> | |||
<a class="item" href="{{.RepoLink}}/cloudbrain/inference-job/create"> | |||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||
height="16"> | |||
<path fill="none" d="M0 0h24v24H0z" /> | |||
<path | |||
d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
</svg> | |||
CPU/GPU | |||
</a> | |||
<a class="active item" href="{{.RepoLink}}/modelarts/inference-job/create"> | |||
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||
height="16"> | |||
<path fill="none" d="M0 0h24v24H0z" /> | |||
<path | |||
d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
</svg> | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" .}} | |||
</div> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
<input style="width: 60%;" name="display_job_name" id="display_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" onkeyup="this.value=this.value.replace(/[, ]/g,'')" tabindex="3" autofocus required maxlength="64"> | |||
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||
<span class="tooltips" style="margin-left:11.5rem;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> | |||
<div class="min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||
<textarea style="width: 80%;" id="description" 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 inline min_title fields" style="width: 91.8%;"> | |||
<div class="required unite inline min_title fields" style="width: 96.8%;"> | |||
<div class="required eight wide field"> | |||
<label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label> | |||
<label style="font-weight: normal;white-space: nowrap;width: 210px;text-align: right;">{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}</label> | |||
<div class="ui fluid search selection dropdown loading " id="select_model"> | |||
{{if $.ckpt_name}} | |||
<input type="hidden" name="model_name" value="{{$.model_name}}" required> | |||
@@ -132,26 +157,29 @@ | |||
</span> | |||
</div> | |||
<!-- AI引擎 --> | |||
<div class="required unite inline min_title fields" style="width: 90%;"> | |||
<div class="required eight wide field"> | |||
<label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}</label> | |||
<select class="ui fluid selection search dropdown" id="trainjob_engines"> | |||
<div class="required inline min_title fields" style="width: 95%;"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.AI_driver"}}</label> | |||
<div class="field" style="flex: 1.5;"> | |||
<select class="ui dropdown width" id="trainjob_engines"> | |||
{{range .engines}} | |||
<option value="{{.Value}}">{{.Value}}</option> | |||
{{end}} | |||
</select> | |||
</div> | |||
<div class="eight wide field" id="engine_name"> | |||
<select class="ui fluid selection dropdown nowrapx" id="trainjob_engine_versions" name="engine_id" style="white-space: nowrap;!"> | |||
{{range .engine_versions}} | |||
<option name="engine_id" value="{{.ID}}">{{.Value}}</option> | |||
<option value="{{.Value}}">{{.Value}}</option> | |||
{{end}} | |||
</select> | |||
</div> | |||
</div> | |||
<div class="field" style="flex: 2;" id="engine_name"> | |||
<select class="ui dropdown width" id="trainjob_engine_versions" name="engine_id"> | |||
{{range .engine_versions}} | |||
<option name="engine_id" value="{{.ID}}">{{.Value}}</option> | |||
{{end}} | |||
</select> | |||
</div> | |||
</div> | |||
<!-- 代码分支 --> | |||
<div class="required unite min_title inline field"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||
<div class="required min_title inline field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||
<select class="ui dropdown width48" id="code_version" name="branch_name"> | |||
{{if .branch_name}} | |||
<option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||
@@ -173,8 +201,8 @@ | |||
<!-- 数据集 --> | |||
{{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 required"> | |||
<label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
<div class="inline min_title field required"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.start_file"}}</label> | |||
{{if .bootFile}} | |||
<input style="width: 48.5%;" name="boot_file" id="trainjob_boot_file" value="{{.bootFile}}" tabindex="3" autofocus required maxlength="255" > | |||
{{else}} | |||
@@ -187,14 +215,14 @@ | |||
</div> | |||
<!-- 运行参数 --> | |||
<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> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.run_parameter"}}</label> | |||
<span id="add_run_para" style="cursor:pointer;color: rgba(3, 102, 214, 100);font-size: 14px;line-height: 26px;font-family: SourceHanSansSC-medium;"><i class="plus square outline icon"></i>{{.i18n.Tr "repo.modelarts.train_job.add_run_parameter"}}</span> | |||
<input id="store_run_para" type="hidden" name="run_para_list"> | |||
<div class="dynamic field" style="margin-top: 1rem;"> | |||
{{if ne 0 (len .params)}} | |||
{{range $k ,$v := .params}} | |||
<div class="two fields width84" id="para{{$k}}"> | |||
<div class="two fields width85" id="para{{$k}}"> | |||
<div class="field"> | |||
<input type="text" name="shipping_first-name" value={{$v.Label}} required> | |||
</div> | |||
@@ -220,8 +248,8 @@ | |||
</select> | |||
</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> | |||
<div class="required min_title inline field" id="flaver_name"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.standard"}}</label> | |||
<select class="ui dropdown width80" id="trainjob-flavor" name="flavor"> | |||
{{range .flavor_infos}} | |||
<option name="flavor" value="{{.Code}}">{{.Value}}</option> | |||
@@ -229,16 +257,17 @@ | |||
</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="inline required min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.amount_of_compute_node"}}</label> | |||
<div class="ui labeled input" style="width: 5%;"> | |||
<input style="border-radius: 0;text-align: center;" name="work_server_number" id="trainjob_work_server_num" tabindex="3" autofocus required maxlength="255" value="1" readonly> | |||
</div> | |||
<span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.inference_output_path_rule"}}</span> | |||
<span class="tooltips" style="margin-left: 11.5rem;display: block;">{{.i18n.Tr "cloudbrain.inference_output_path_rule"}}</span> | |||
</div> | |||
<!-- 表单操作 --> | |||
<div class="inline unite min_title field"> | |||
<div class="inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;"></label> | |||
<button class="ui create_train_job green button"> | |||
{{.i18n.Tr "repo.cloudbrain.new"}} | |||
</button> | |||
@@ -252,13 +281,14 @@ | |||
{{template "base/footer" .}} | |||
<script> | |||
console.log({{.newInference}}) | |||
const RepoLink = {{.RepoLink}} | |||
const url_href = window.location.pathname.split('create')[0] | |||
let nameMap,nameList | |||
$(".ui.button").attr('href',url_href) | |||
// 获取模型列表和模型名称对应的模型版本 | |||
$.get(`${RepoLink}/modelmanage/query_model_for_predict`, (data) => { | |||
$.get(`${RepoLink}/modelmanage/query_model_for_predict?type=1`, (data) => { | |||
modelVersion() | |||
modelCkpt() | |||
nameMap = data.nameMap | |||
nameList = data.nameList | |||
let html = '' | |||
@@ -276,16 +306,17 @@ | |||
$('#select_model').removeClass("loading") | |||
}) | |||
// 根据选中的模型名称获取相应的模型版本 | |||
$(function(){ | |||
function modelVersion(){ | |||
$('#select_model').dropdown({ | |||
onChange: function(value, text, $selectedItem) { | |||
console.log("-----------------") | |||
$("#select_model_version").addClass("loading") | |||
$('#model_name_version').empty() | |||
let html = '' | |||
nameMap[value].forEach(element => { | |||
let {TrainTaskInfo} = element | |||
TrainTaskInfo = JSON.parse(TrainTaskInfo) | |||
html += `<div class="item" data-label="${element.Label}" data-id="${element.ID}" data-value="${TrainTaskInfo.TrainUrl}">${element.Version}</div>` | |||
html += `<div class="item" data-label="${element.Label}" data-id="${element.ID}" data-value="${element.Path}">${element.Version}</div>` | |||
}); | |||
$('#model_name_version').append(html) | |||
$("#select_model_version").removeClass("loading") | |||
@@ -295,9 +326,9 @@ | |||
$("#select_model_version").dropdown('set value',initVersionValue,initVersionText,$('#model_name_version div.item:first-child')) | |||
} | |||
}) | |||
}) | |||
} | |||
// 根据选中的模型版本获取相应的模型权重文件 | |||
$(function(){ | |||
function modelCkpt(){ | |||
$('#select_model_version').dropdown({ | |||
onChange: function(value, text, $selectedItem) { | |||
const dataID = $selectedItem[0].getAttribute("data-id") | |||
@@ -327,7 +358,7 @@ | |||
$("input#ai_model_label").val(label) | |||
} | |||
}) | |||
}) | |||
} | |||
function loadCheckpointList(value){ | |||
return new Promise((resolve,reject)=>{ | |||
$.get(`${RepoLink}/modelmanage/query_modelfile_for_predict`,{ID:value}, (data) => { | |||
@@ -342,7 +373,7 @@ | |||
// 参数增加、删除、修改、保存 | |||
function Add_parameter(i){ | |||
value = '<div class="two fields width84" id= "para'+ 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> ' + | |||
@@ -178,272 +178,323 @@ td, th { | |||
</div> | |||
</h4> | |||
{{with .task}} | |||
<div class="content-pad" style="border: 1px solid #e2e2e2;margin-top: 24px;padding: 20px 60px 40px 60px;"> | |||
<div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
<div class="ui accordion border-according" id="accordion{{.VersionName}}" | |||
data-repopath="{{$.RepoRelPath}}/modelarts/inference-job" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
<input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | |||
<div class="active title padding0"> | |||
<div class="according-panel-heading"> | |||
<div class="accordion-panel-title"> | |||
<i class="dropdown icon"></i> | |||
<span class="accordion-panel-title-content"> | |||
<span> | |||
<div class="ac-display-inblock title_text acc-margin-bottom"> | |||
<span class="cti-mgRight-sm">{{TimeSinceUnix1 .CreatedUnix}}</span> | |||
<span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||
<span id="{{.VersionName}}-status-span"><i id="icon" | |||
style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" | |||
style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
</span> | |||
<span | |||
class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
<span class="cti-mgRight-sm uc-accordionTitle-black" | |||
id="{{.VersionName}}-duration-span">{{.TrainJobDuration}}</span> | |||
<span id="refresh-status" data-tooltip="刷新" style="cursor: pointer;" data-inverted="" data-version="{{.VersionName}}"><i | |||
class="redo icon redo-color"></i></span> | |||
<a class="active item" data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
<a class="item" data-tab="second" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
<a class="item" data-tab="third" onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
</span> | |||
</span> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="active content"> | |||
<div class="content-pad"> | |||
<div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
<div class="ui tab active" data-tab="first"> | |||
<div style="padding-top: 10px;"> | |||
<div class="tab_2_content"> | |||
<div class="ac-grid ac-grid-col2"> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain_task"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.DisplayJobName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.status"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-status"> | |||
{{.Status}} | |||
</div> | |||
</td> | |||
</tr> | |||
<!-- <tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.run_version"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.VersionName}} | |||
</div> | |||
</td> | |||
</tr> --> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
<span style="font-size: 12px;" class=""> | |||
{{if not (eq .StartTime 0)}} | |||
{{TimeSinceUnix1 .StartTime}} | |||
{{else}} | |||
{{TimeSinceUnix1 .CreatedUnix}} | |||
{{end}} | |||
</span> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
{{.TrainJobDuration}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.EngineName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.model.manage.description"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-desc" style="width: 380px;"> | |||
{{if .Description}} | |||
<span title="{{.Description}}">{{.Description}}</span> | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
创建人 | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-creator"> | |||
{{$.userName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.compute_node"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.WorkServerNumber}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.infer_job_model"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
<span>{{.ModelName}}</span> | |||
<span style="color: #8a8e99">{{$.i18n.Tr "repo.modelarts.version"}}:</span><span>{{.ModelVersion}}</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.infer_job_model_file"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.CkptName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.model_label"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-labels"> | |||
{{if .LabelName}} | |||
{{range $.labelName}} | |||
<a class="ui label" title="{{.}}">{{.}}</a> | |||
<a class="active item" data-tab="first">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
<a class="item log_bottom" data-tab="second" data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
<a class="item load-model-file" data-tab="third" data-path="{{$.RepoLink}}/modelarts/inference-job/{{.JobID}}/result_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first" style="height:400px"> | |||
<div style="padding-top: 10px;"> | |||
<div class="tab_2_content"> | |||
<div class="ac-grid ac-grid-col2"> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.cloudbrain_task"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.DisplayJobName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.status"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-status"> | |||
{{.Status}} | |||
</div> | |||
</td> | |||
</tr> | |||
<!-- <tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.run_version"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.VersionName}} | |||
</div> | |||
</td> | |||
</tr> --> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
<span style="font-size: 12px;" class=""> | |||
{{if not (eq .StartTime 0)}} | |||
{{TimeSinceUnix1 .StartTime}} | |||
{{else}} | |||
{{TimeSinceUnix1 .CreatedUnix}} | |||
{{end}} | |||
</span> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
{{.TrainJobDuration}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.EngineName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.model.manage.description"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-desc" style="width: 380px;"> | |||
{{if .Description}} | |||
<span title="{{.Description}}">{{.Description}}</span> | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.code_version"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.BranchName}} | |||
</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.infer_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}}"> | |||
{{if .Parameters}} | |||
<span>{{.Parameters}}</span> | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.FlavorName}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
创建人 | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-creator"> | |||
{{$.userName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.compute_node"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.WorkServerNumber}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
<div class="ac-grid-col"> | |||
<table class="ti-form"> | |||
<tbody class="ti-text-form"> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.infer_job_model"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
<span>{{.ModelName}}</span> | |||
<span style="color: #8a8e99">{{$.i18n.Tr "repo.modelarts.version"}}:</span><span>{{.ModelVersion}}</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.infer_job_model_file"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.CkptName}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.model_label"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-labels"> | |||
{{if .LabelName}} | |||
{{range $.labelName}} | |||
<a class="ui label" title="{{.}}">{{.}}</a> | |||
{{end}} | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.code_version"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.BranchName}} | |||
</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.infer_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}}"> | |||
{{if .Parameters}} | |||
<span>{{.Parameters}}</span> | |||
{{else}} | |||
<span>--</span> | |||
{{end}} | |||
</div> | |||
</td> | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
{{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.FlavorName}} | |||
</div> | |||
</td> | |||
</tr> | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="ui tab" data-tab="second"> | |||
<div> | |||
<a id="{{.VersionName}}-log-down" | |||
class='{{if and (.CanModify) (eq .Status "KILLED" "FAILED" "START_FAILED" "STOPPED" "COMPLETED") }}ti-download-file{{else}}disabled{{end}}' | |||
href="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/download_log_file?version_name={{.VersionName}}"> | |||
<i class="ri-download-cloud-2-line"></i> | |||
<span style="margin-left: 0.3rem;">{{$.i18n.Tr "repo.modelarts.download_log"}}</span>{{.CanModify}} | |||
</a> | |||
<div class="ui tab" data-tab="second"> | |||
<div> | |||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||
<div id="header"></div> | |||
</div> | |||
<div class="ui attached log" onscroll="logScroll({{.VersionName}})" 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 style="position: relative;border: 1px solid rgba(0,0,0,.2);padding: 0 10px;margin-top: 10px;"> | |||
<span> | |||
<a title="滚动到顶部" style="position: absolute; right: -32px;cursor: pointer;" | |||
class="log_top" data-version="{{.VersionName}}"><i class="icon-to-top"></i></a> | |||
</span> | |||
<span> | |||
<a title="滚动到底部" style="position: absolute; bottom: 10px;right: -32px;cursor: pointer;" | |||
class="log_bottom" data-version="{{.VersionName}}"><i | |||
class="icon-to-bottom"></i></a> | |||
</span> | |||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||
<div id="header"></div> | |||
</div> | |||
<div class="ui attached log log-scroll" data-version="{{.VersionName}}" id="log{{.VersionName}}" style="height: 300px !important; overflow: auto;"> | |||
<input type="hidden" name="end_line" value> | |||
<input type="hidden" name="start_line" value> | |||
<pre id="log_file{{.VersionName}}"></pre> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="ui tab" data-tab="third"> | |||
<input type="hidden" name="model{{.VersionName}}" value="-1"> | |||
<input type="hidden" name="modelback{{.VersionName}}" value="-1"> | |||
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'> | |||
<div class="active section">result</div> | |||
<div class="divider"> / </div> | |||
</div> | |||
<div class="ui tab" data-tab="third"> | |||
<input type="hidden" name="model{{.VersionName}}" value="-1"> | |||
<input type="hidden" name="modelback{{.VersionName}}" value="-1"> | |||
<div class='ui breadcrumb model_file_bread' id='file_breadcrumb{{.VersionName}}'> | |||
<div class="active section">result</div> | |||
<div class="divider"> / </div> | |||
</div> | |||
<div id="dir_list{{.VersionName}}"> | |||
</div> | |||
<div id="dir_list{{.VersionName}}"> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
{{end}} | |||
@@ -453,28 +504,10 @@ td, th { | |||
</div> | |||
<!-- 确认模态框 --> | |||
<div id="deletemodel"> | |||
<div class="ui basic modal"> | |||
<div class="ui icon header"> | |||
<i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||
</div> | |||
<div class="content"> | |||
<p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||
</div> | |||
<div class="actions"> | |||
<div class="ui red basic inverted cancel button"> | |||
<i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||
</div> | |||
<div class="ui green basic inverted ok button"> | |||
<i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
<script> | |||
console.log('{{.CanModify}}') | |||
$(document).ready(function(){ | |||
$('.secondary.menu .item').tab(); | |||
}); | |||
@@ -489,176 +522,5 @@ $(document).ready(function(){ | |||
repoPath = urlArr.slice(-4)[0] | |||
jobID = urlArr.slice(-1)[0] | |||
}) | |||
function loadLog(version_name){ | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/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) | |||
}).fail(function(err) { | |||
console.log(err); | |||
}); | |||
} | |||
function logScroll(version_name) { | |||
let container = document.querySelector(`#log${version_name}`) | |||
let scrollTop = container.scrollTop | |||
let scrollHeight = container.scrollHeight | |||
let clientHeight = container.clientHeight | |||
let scrollLeft = container.scrollLeft | |||
if((parseInt(scrollTop) + clientHeight == scrollHeight || parseInt(scrollTop) + clientHeight +1 == scrollHeight || parseInt(scrollTop) + clientHeight - 1 == scrollHeight) && (scrollLeft===0)){ | |||
let end_line = $(`#log${version_name} input[name=end_line]`).val() | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/log?version_name=${version_name}&base_line=${end_line}&lines=50&order=desc`, (data) => { | |||
if (data.Lines == 0){ | |||
$(`.message${version_name} #header`).text('您已翻阅至日志底部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function(){ | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
}else{ | |||
if(end_line===data.EndLine){ | |||
return | |||
} | |||
else{ | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) | |||
$(`#log${version_name}`).append('<pre>' + data.Content) | |||
} | |||
} | |||
}).fail(function(err) { | |||
console.log(err); | |||
}); | |||
} | |||
if(scrollTop == 0 && scrollLeft==0){ | |||
let start_line = $(`#log${version_name} input[name=start_line]`).val() | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/log?version_name=${version_name}&base_line=${start_line}&lines=50&order=asc`, (data) => { | |||
if (data.Lines == 0){ | |||
$(`.message${version_name} #header`).text('您已翻阅至日志顶部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function(){ | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
}else{ | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值 | |||
$(`#log${version_name}`).prepend('<pre>' + data.Content) | |||
} | |||
}).fail(function(err) { | |||
console.log(err); | |||
}); | |||
} | |||
} | |||
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 loadModelFile(version_name,parents,filename,init){ | |||
parents = parents || '' | |||
filename = filename || '' | |||
init = init || '' | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/result_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'>result</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}/result_download?version_name=${version_name}&file_name=${data.Dirs[i].FileName}&parent_dir=${data.Dirs[i].ParenDir}">` | |||
} | |||
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) | |||
} | |||
</script> |
@@ -46,6 +46,7 @@ | |||
</svg> | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count" .}} | |||
</div> | |||
<div class="inline required field"> | |||
<label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | |||
@@ -96,6 +96,7 @@ | |||
</a> | |||
</div> | |||
</div> | |||
<div class="required inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||
<div class="ui blue mini menu compact selectcloudbrain"> | |||
@@ -117,6 +118,7 @@ | |||
</svg> | |||
Ascend NPU</a> | |||
</div> | |||
{{template "custom/wait_count_train" .}} | |||
</div> | |||
<div class="required inline min_title field"> | |||
<label class="label-fix-width" style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
@@ -313,8 +313,7 @@ | |||
<a class="item log_bottom" data-tab="second{{$k}}" | |||
data-version="{{.VersionName}}">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
<a class="item metric_chart" data-tab="four{{$k}}" data-version="{{.VersionName}}">资源占用情况</a> | |||
<a class="item" data-tab="third{{$k}}" | |||
onclick="loadModelFile({{.VersionName}},'','','init')">{{$.i18n.Tr "repo.model_download"}}</a> | |||
<a class="item load-model-file" data-tab="third{{$k}}" data-path="{{$.RepoLink}}/modelarts/train-job/{{.JobID}}/model_list" data-version="{{.VersionName}}" data-parents="" data-filename="" data-init="init" >{{$.i18n.Tr "repo.model_download"}}</a> | |||
</div> | |||
<div class="ui tab active" data-tab="first{{$k}}"> | |||
<div style="padding-top: 10px;"> | |||
@@ -509,7 +508,7 @@ | |||
<div class="ui message message{{.VersionName}}" style="display: none;"> | |||
<div id="header"></div> | |||
</div> | |||
<div class="ui attached log" onscroll="fn({{.VersionName}})" id="log{{.VersionName}}" | |||
<div class="ui attached log log-scroll" id="log{{.VersionName}}" data-version="{{.VersionName}}" | |||
style="height: 300px !important; overflow: auto;"> | |||
<input type="hidden" name="end_line" value> | |||
<input type="hidden" name="start_line" value> | |||
@@ -729,18 +728,6 @@ | |||
$('#name').val(modelName) | |||
$('#version').val("0.0.1") | |||
} | |||
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}/modelarts/train-job/${jobID}?version_name=${version_name}`, (data) => { | |||
// header status and duration | |||
@@ -815,246 +802,5 @@ | |||
console.log(err); | |||
}); | |||
} | |||
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++) { | |||
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}/model_download?version_name=${version_name}&file_name=${data.Dirs[i].FileName}&parent_dir=${data.Dirs[i].ParenDir}">` | |||
} | |||
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 debounce(fn, delay) { | |||
let timer; | |||
return (...args) => { | |||
// 判断定时器是否存在,清除定时器 | |||
if (timer) { | |||
clearTimeout(timer); | |||
} | |||
// 重新调用setTimeout | |||
timer = setTimeout(() => { | |||
fn.apply(this, args); | |||
}, delay); | |||
}; | |||
} | |||
const fn = debounce(logScroll, 500) | |||
function logScroll(version_name) { | |||
let container = document.querySelector(`#log${version_name}`) | |||
let scrollTop = container.scrollTop | |||
let scrollHeight = container.scrollHeight | |||
let clientHeight = container.clientHeight | |||
let scrollLeft = container.scrollLeft | |||
if (((parseInt(scrollTop) + clientHeight == scrollHeight || parseInt(scrollTop) + clientHeight + 1 == scrollHeight || parseInt(scrollTop) + clientHeight - 1 == scrollHeight)) && parseInt(scrollTop) !== 0 && scrollLeft == 0) { | |||
let 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}&lines=50&order=desc`, (data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text('您已翻阅至日志底部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
} else { | |||
if (end_line === data.EndLine) { | |||
return | |||
} | |||
else { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) | |||
$(`#log${version_name}`).append('<pre>' + data.Content) | |||
} | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
if ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].includes(scrollTop) && scrollLeft == 0) { | |||
let 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}&lines=50&order=asc`, (data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text('您已翻阅至日志顶部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
} else { | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) //如果变动就改变所对应的值 | |||
$(`#log${version_name}`).prepend('<pre>' + data.Content) | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
} | |||
function scrollAnimation(dom, currentY, targetY, currentX) { | |||
let needScrollTop = targetY - currentY; | |||
let _currentY = currentY; | |||
setTimeout(() => { | |||
// 一次调用滑动帧数,每次调用会不一样 | |||
//取总距离的十分之一 | |||
const dist = Math.ceil(needScrollTop / 10); | |||
_currentY += dist; | |||
//移动一个十分之一 | |||
dom.scrollTo(currentX || 0, _currentY, 'smooth'); | |||
// 如果移动幅度小于十个像素,直接移动,否则递归调用,实现动画效果 | |||
if (needScrollTop > 10 || needScrollTop < -10) { | |||
scrollAnimation(dom, _currentY, targetY) | |||
} else { | |||
dom.scrollTo(0, targetY, 'smooth') | |||
} | |||
}, 1) | |||
} | |||
$('.log_top').click(function () { | |||
// let logContentDom = document.querySelector('.log') | |||
// if(!logContentDom) | |||
// return | |||
// let version_name = $('.log_top').data('version') | |||
let version_name = $(this).data('version') | |||
let logContentDom = document.querySelector(`#log${version_name}`) | |||
$(`#log_file${version_name}`).siblings('pre').remove() | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=&lines=50&order=asc`, (data) => { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) //如果变动就改变所对应的值 | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) | |||
$(`#log${version_name}`).prepend('<pre>' + data.Content) | |||
$(`.message${version_name} #header`).text('您已翻阅至日志顶部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
scrollAnimation(logContentDom, logContentDom.scrollTop, 0); | |||
}) | |||
}) | |||
$('.log_bottom').click(function (e) { | |||
let version_name = $(this).data('version') | |||
let logContentDom = document.querySelector(`#log${version_name}`) | |||
$(`#log_file${version_name}`).siblings('pre').remove() | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=&lines=50&order=desc`, (data) => { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) //如果变动就改变所对应的值 | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine) | |||
$(`#log${version_name}`).append('<pre>' + data.Content) | |||
if(!data.CanLogDownload){ | |||
$(`#${version_name}-log-down`).removeClass('ti-download-file').addClass('disabled') | |||
} | |||
$.get(`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=${data.EndLine}&lines=50&order=desc`, (data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text('您已翻阅至日志底部') | |||
$(`.message${version_name}`).css('display', 'block') | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css('display', 'none') | |||
}, 1000) | |||
} else { | |||
if (end_line === data.EndLine) { | |||
return | |||
} | |||
else { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine) | |||
$(`#log${version_name}`).append('<pre>' + data.Content) | |||
} | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
scrollAnimation(logContentDom, logContentDom.scrollTop + 1, logContentDom.scrollHeight - logContentDom.clientHeight); | |||
}) | |||
}) | |||
</script> |
@@ -87,7 +87,7 @@ | |||
</a> | |||
{{else if eq .JobType "INFERENCE"}} | |||
<a class="title" | |||
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}" | |||
href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .Cloudbrain.Type 1}}modelarts{{else if eq .Cloudbrain.Type 0}}cloudbrain{{end}}/inference-job/{{$JobID}}" | |||
title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
<span class="fitted" | |||
style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
@@ -113,7 +113,7 @@ | |||
<div class="two wide column text center nowrap" | |||
style="padding-left: 2.2rem !important; width: 11% !important;"> | |||
<span class="job-status" id="{{$JobID}}" | |||
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | |||
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | |||
data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
<span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | |||
class="{{.Status}}"></i><span id="{{$JobID}}-text" | |||
@@ -186,7 +186,7 @@ | |||
{{else}} | |||
<a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | |||
class='ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "STOPPED" "SUCCEEDED" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button' | |||
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .JobType "INFERENCE"}}modelarts/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}modelarts/train-job{{else if eq .Cloudbrain.Type 0}}cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}grampus/train-job{{end}}{{end}}' | |||
data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 1}}modelarts/inference-job{{else}}cloudbrain/train-job{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}modelarts/train-job{{else if eq .Cloudbrain.Type 0}}cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}grampus/train-job{{end}}{{end}}' | |||
data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
{{$.i18n.Tr "repo.stop"}} | |||
</a> | |||
@@ -203,7 +203,7 @@ | |||
{{end}} | |||
<!-- 删除任务 --> | |||
<form class="ui compact buttons" id="delForm-{{$JobID}}" | |||
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true' | |||
action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .Cloudbrain.Type 1}}/modelarts/train-job{{else if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{else if eq .Cloudbrain.Type 2}}/grampus/train-job{{end}}{{else if eq .JobType "INFERENCE"}}{{if eq .Cloudbrain.Type 0}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true' | |||
method="post"> | |||
{{$.CsrfTokenHtml}} | |||
<a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" | |||
@@ -10,7 +10,6 @@ | |||
>镜像</label | |||
> | |||
<label v-else>镜像</label> | |||
<span v-if="benchmark"> </span> | |||
<input | |||
v-if="benchmarkNew" | |||
type="text" | |||
@@ -502,6 +501,7 @@ export default { | |||
this.getImageListPublic(); | |||
if ( | |||
location.href.indexOf("train-job") !== -1 || | |||
location.href.indexOf("inference-job") !== -1 || | |||
location.href.indexOf("benchmark") !== -1 | |||
) { | |||
this.benchmarkNew = true; | |||
@@ -0,0 +1,314 @@ | |||
export default async function initCloudrainSow() { | |||
function debounce(fn, delay) { | |||
let timer; | |||
return (...args) => { | |||
// 判断定时器是否存在,清除定时器 | |||
if (timer) { | |||
clearTimeout(timer); | |||
} | |||
// 重新调用setTimeout | |||
timer = setTimeout(() => { | |||
fn.apply(this, args); | |||
}, delay); | |||
}; | |||
} | |||
function logScroll(version_name) { | |||
let container = document.querySelector(`#log${version_name}`); | |||
console.log(container); | |||
let scrollTop = container.scrollTop; | |||
let scrollHeight = container.scrollHeight; | |||
let clientHeight = container.clientHeight; | |||
let scrollLeft = container.scrollLeft; | |||
if ( | |||
(parseInt(scrollTop) + clientHeight == scrollHeight || | |||
parseInt(scrollTop) + clientHeight + 1 == scrollHeight || | |||
parseInt(scrollTop) + clientHeight - 1 == scrollHeight) && | |||
scrollLeft === 0 | |||
) { | |||
let end_line = $(`#log${version_name} input[name=end_line]`).val(); | |||
$.get( | |||
`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/log?version_name=${version_name}&base_line=${end_line}&lines=50&order=desc`, | |||
(data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text("您已翻阅至日志底部"); | |||
$(`.message${version_name}`).css("display", "block"); | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css("display", "none"); | |||
}, 1000); | |||
} else { | |||
if (end_line === data.EndLine) { | |||
return; | |||
} else { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine); | |||
$(`#log${version_name}`).append("<pre>" + data.Content); | |||
} | |||
} | |||
} | |||
).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
if (scrollTop == 0 && scrollLeft == 0) { | |||
let start_line = $(`#log${version_name} input[name=start_line]`).val(); | |||
$.get( | |||
`/api/v1/repos/${userName}/${repoPath}/modelarts/inference-job/${jobID}/log?version_name=${version_name}&base_line=${start_line}&lines=50&order=asc`, | |||
(data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text("您已翻阅至日志顶部"); | |||
$(`.message${version_name}`).css("display", "block"); | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css("display", "none"); | |||
}, 1000); | |||
} else { | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine); //如果变动就改变所对应的值 | |||
$(`#log${version_name}`).prepend("<pre>" + data.Content); | |||
} | |||
} | |||
).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
} | |||
const fn = debounce(logScroll, 500); | |||
$(".log-scroll").scroll(function () { | |||
let version_name = $(this).data("version"); | |||
fn(version_name); | |||
}); | |||
function scrollAnimation(dom, currentY, targetY, currentX) { | |||
let needScrollTop = targetY - currentY; | |||
let _currentY = currentY; | |||
setTimeout(() => { | |||
// 一次调用滑动帧数,每次调用会不一样 | |||
//取总距离的十分之一 | |||
const dist = Math.ceil(needScrollTop / 10); | |||
_currentY += dist; | |||
//移动一个十分之一 | |||
dom.scrollTo(currentX || 0, _currentY, "smooth"); | |||
// 如果移动幅度小于十个像素,直接移动,否则递归调用,实现动画效果 | |||
if (needScrollTop > 10 || needScrollTop < -10) { | |||
scrollAnimation(dom, _currentY, targetY); | |||
} else { | |||
dom.scrollTo(0, targetY, "smooth"); | |||
} | |||
}, 1); | |||
} | |||
$(".log_top").click(function () { | |||
// let logContentDom = document.querySelector('.log') | |||
// if(!logContentDom) | |||
// return | |||
// let version_name = $('.log_top').data('version') | |||
let version_name = $(this).data("version"); | |||
let logContentDom = document.querySelector(`#log${version_name}`); | |||
$(`#log_file${version_name}`).siblings("pre").remove(); | |||
$.get( | |||
`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=&lines=50&order=asc`, | |||
(data) => { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine); //如果变动就改变所对应的值 | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine); | |||
$(`#log${version_name}`).prepend("<pre>" + data.Content); | |||
$(`.message${version_name} #header`).text("您已翻阅至日志顶部"); | |||
$(`.message${version_name}`).css("display", "block"); | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css("display", "none"); | |||
}, 1000); | |||
scrollAnimation(logContentDom, logContentDom.scrollTop, 0); | |||
} | |||
); | |||
}); | |||
$(".log_bottom").click(function (e) { | |||
let version_name = $(this).data("version"); | |||
let logContentDom = document.querySelector(`#log${version_name}`); | |||
$(`#log_file${version_name}`).siblings("pre").remove(); | |||
$.get( | |||
`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=&lines=50&order=desc`, | |||
(data) => { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine); //如果变动就改变所对应的值 | |||
$(`#log${version_name} input[name=start_line]`).val(data.StartLine); | |||
$(`#log${version_name}`).append("<pre>" + data.Content); | |||
$.get( | |||
`/api/v1/repos/${userName}/${repoPath}/modelarts/train-job/${jobID}/log?version_name=${version_name}&base_line=${data.EndLine}&lines=50&order=desc`, | |||
(data) => { | |||
if (data.Lines == 0) { | |||
$(`.message${version_name} #header`).text("您已翻阅至日志底部"); | |||
$(`.message${version_name}`).css("display", "block"); | |||
setTimeout(function () { | |||
$(`.message${version_name}`).css("display", "none"); | |||
}, 1000); | |||
} else { | |||
if (end_line === data.EndLine) { | |||
return; | |||
} else { | |||
$(`#log${version_name} input[name=end_line]`).val(data.EndLine); | |||
$(`#log${version_name}`).append("<pre>" + data.Content); | |||
} | |||
} | |||
} | |||
).fail(function (err) { | |||
console.log(err); | |||
}); | |||
scrollAnimation( | |||
logContentDom, | |||
logContentDom.scrollTop + 1, | |||
logContentDom.scrollHeight - logContentDom.clientHeight | |||
); | |||
} | |||
); | |||
}); | |||
// | |||
$(".content-pad").on("click", ".load-model-file", function () { | |||
console.log("11111111111"); | |||
let version_name = $(this).data("version"); | |||
let parents = $(this).data("parents") || ""; | |||
let filename = $(this).data("filename") || ""; | |||
let init = $(this).data("init") || ""; | |||
let path = $(this).data("path"); | |||
let url = `/api/v1/repos${path}?version_name=${version_name}&parentDir=${parents}`; | |||
console.log(url); | |||
$.get(url, (data) => { | |||
$(`#dir_list${version_name}`).empty(); | |||
renderDir(path, 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 = ""; | |||
if (version_name) { | |||
htmlBread += `<div class='active section'>${version_name}</div>`; | |||
} else { | |||
htmlBread += `<div class='active section'>result</div>`; | |||
} | |||
htmlBread += "<div class='divider'> / </div>"; | |||
$(`#file_breadcrumb${version_name}`).append(htmlBread); | |||
} else { | |||
renderBrend(path, version_name, parents, filename, init); | |||
} | |||
}).fail(function (err) { | |||
console.log(err, version_name); | |||
}); | |||
}); | |||
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 renderBrend(path, 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 load-model-file' data-path='${path}' data-version='${version_name}' data-parents='${parents1}' data-filename='' data-init='init'>${sectionName}</a>` | |||
); | |||
} else { | |||
$(`#file_breadcrumb${version_name} .active.section`).replaceWith( | |||
`<a class='section load-model-file' data-path='${path}' data-version='${version_name}' data-parents='${parents1}' data-filename='${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(path, 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 class='load-model-file' data-path='${path}' data-version='${version_name}' data-parents='${data.Dirs[i].ParenDir}' data-filename='${data.Dirs[i].FileName}' data-init='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}/result_download?version_name=${version_name}&file_name=${data.Dirs[i].FileName}&parent_dir=${data.Dirs[i].ParenDir}">`; | |||
} 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); | |||
} | |||
} |
@@ -1,330 +1,546 @@ | |||
export default async function initCloudrain() { | |||
let debug_button = $('.cloudbrain_debug').data('debug') | |||
let debug_again_button = $('.cloudbrain_debug').data('debug-again') | |||
let timeid = window.setInterval(loadJobStatus, 15000); | |||
let timeidShow = window.setInterval(loadShowJobStatus, 15000); | |||
$(document).ready(loadJobStatus); | |||
$(document).ready(loadShowJobStatus); | |||
function loadJobStatus() { | |||
$(".job-status").each((index, job) => { | |||
const ID = job.dataset.jobid; | |||
const repoPath = job.dataset.repopath; | |||
// const computeResource = job.dataset.resource | |||
const versionname = job.dataset.version | |||
const status_text = $(`#${ID}-text`).text() | |||
const finalState = ['STOPPED', 'CREATE_FAILED', 'UNAVAILABLE', 'DELETED', 'RESIZE_FAILED', 'SUCCEEDED', 'IMAGE_FAILED', 'SUBMIT_FAILED', 'DELETE_FAILED', 'KILLED', 'COMPLETED', 'FAILED', 'CANCELED', 'LOST', 'START_FAILED', 'SUBMIT_MODEL_FAILED', 'DEPLOY_SERVICE_FAILED', 'CHECK_FAILED'] | |||
if (finalState.includes(status_text)) { | |||
return | |||
} | |||
// const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' | |||
$.get(`/api/v1/repos/${repoPath}/${ID}?version_name=${versionname}`, (data) => { | |||
const ID = data.ID || data.JobID | |||
const status = data.JobStatus | |||
const duration = data.JobDuration | |||
$('#duration-' + ID).text(duration) | |||
if (status != status_text) { | |||
$('#' + ID + '-icon').removeClass().addClass(status) | |||
$('#' + ID + '-text').text(status) | |||
finalState.includes(status) && $('#' + ID + '-stop').removeClass('blue').addClass('disabled') | |||
} | |||
if (status === "RUNNING") { | |||
$('#ai-debug-' + ID).removeClass('disabled').addClass('blue').text(debug_button).css("margin", "0 1rem") | |||
$('#model-image-' + ID).removeClass('disabled').addClass('blue') | |||
} | |||
if (status !== "RUNNING") { | |||
// $('#model-debug-'+ID).removeClass('blue') | |||
// $('#model-debug-'+ID).addClass('disabled') | |||
$('#model-image-' + ID).removeClass('blue').addClass('disabled') | |||
} | |||
if (["CREATING", "STOPPING", "WAITING", "STARTING"].includes(status)) { | |||
$('#ai-debug-' + ID).removeClass('blue').addClass('disabled') | |||
} | |||
if (['STOPPED', 'FAILED', 'START_FAILED', 'CREATE_FAILED', 'SUCCEEDED'].includes(status)) { | |||
$('#ai-debug-' + ID).removeClass('disabled').addClass('blue').text(debug_again_button).css("margin", "0") | |||
} | |||
if (["RUNNING", "WAITING"].includes(status)) { | |||
$('#ai-stop-' + ID).removeClass('disabled').addClass('blue') | |||
} | |||
if (["CREATING", "STOPPING", "STARTING", "STOPPED", "FAILED", "START_FAILED", "SUCCEEDED", "COMPLETED", "CREATE_FAILED"].includes(status)) { | |||
$('#ai-stop-' + ID).removeClass('blue').addClass('disabled') | |||
} | |||
if (["STOPPED", "FAILED", "START_FAILED", "KILLED", "COMPLETED", "SUCCEEDED"].includes(status)) { | |||
$('#ai-delete-' + ID).removeClass('disabled').addClass('blue') | |||
} else { | |||
$('#ai-delete-' + ID).removeClass('blue').addClass('disabled') | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
}); | |||
}; | |||
function loadShowJobStatus() { | |||
$(".ui.accordion.border-according").each((index, job) => { | |||
const jobID = job.dataset.jobid; | |||
const repoPath = job.dataset.repopath; | |||
const versionname = job.dataset.version | |||
// ['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'] | |||
// if (job.textContent.trim() == 'IMAGE_FAILED' || job.textContent.trim() == 'SUBMIT_FAILED' || job.textContent.trim() == 'DELETE_FAILED' | |||
// || job.textContent.trim() == 'KILLED' || job.textContent.trim() == 'COMPLETED' || job.textContent.trim() == 'FAILED' | |||
// || job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') { | |||
// return | |||
// } | |||
let status = $(`#${versionname}-status-span`).text() | |||
let debug_button = $(".cloudbrain_debug").data("debug"); | |||
let debug_again_button = $(".cloudbrain_debug").data("debug-again"); | |||
let timeid = window.setInterval(loadJobStatus, 15000); | |||
let timeidShow = window.setInterval(loadShowJobStatus, 15000); | |||
$(document).ready(loadJobStatus); | |||
$(document).ready(loadShowJobStatus); | |||
function loadJobStatus() { | |||
$(".job-status").each((index, job) => { | |||
const ID = job.dataset.jobid; | |||
const repoPath = job.dataset.repopath; | |||
// const computeResource = job.dataset.resource | |||
const versionname = job.dataset.version; | |||
const status_text = $(`#${ID}-text`).text(); | |||
const finalState = [ | |||
"STOPPED", | |||
"CREATE_FAILED", | |||
"UNAVAILABLE", | |||
"DELETED", | |||
"RESIZE_FAILED", | |||
"SUCCEEDED", | |||
"IMAGE_FAILED", | |||
"SUBMIT_FAILED", | |||
"DELETE_FAILED", | |||
"KILLED", | |||
"COMPLETED", | |||
"FAILED", | |||
"CANCELED", | |||
"LOST", | |||
"START_FAILED", | |||
"SUBMIT_MODEL_FAILED", | |||
"DEPLOY_SERVICE_FAILED", | |||
"CHECK_FAILED", | |||
]; | |||
if (finalState.includes(status_text)) { | |||
return; | |||
} | |||
// const diffResource = computeResource == "NPU" ? 'modelarts/notebook' : 'cloudbrain' | |||
$.get( | |||
`/api/v1/repos/${repoPath}/${ID}?version_name=${versionname}`, | |||
(data) => { | |||
const ID = data.ID || data.JobID; | |||
const status = data.JobStatus; | |||
const duration = data.JobDuration; | |||
$("#duration-" + ID).text(duration); | |||
if (status != status_text) { | |||
$("#" + ID + "-icon") | |||
.removeClass() | |||
.addClass(status); | |||
$("#" + ID + "-text").text(status); | |||
finalState.includes(status) && | |||
$("#" + ID + "-stop") | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
} | |||
if (status === "RUNNING") { | |||
$("#ai-debug-" + ID) | |||
.removeClass("disabled") | |||
.addClass("blue") | |||
.text(debug_button) | |||
.css("margin", "0 1rem"); | |||
$("#model-image-" + ID) | |||
.removeClass("disabled") | |||
.addClass("blue"); | |||
} | |||
if (status !== "RUNNING") { | |||
// $('#model-debug-'+ID).removeClass('blue') | |||
// $('#model-debug-'+ID).addClass('disabled') | |||
$("#model-image-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
} | |||
if ( | |||
["CREATING", "STOPPING", "WAITING", "STARTING"].includes(status) | |||
) { | |||
$("#ai-debug-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
} | |||
if ( | |||
[ | |||
"STOPPED", | |||
"FAILED", | |||
"START_FAILED", | |||
"CREATE_FAILED", | |||
"SUCCEEDED", | |||
].includes(status) | |||
) { | |||
$("#ai-debug-" + ID) | |||
.removeClass("disabled") | |||
.addClass("blue") | |||
.text(debug_again_button) | |||
.css("margin", "0"); | |||
} | |||
if (["RUNNING", "WAITING"].includes(status)) { | |||
$("#ai-stop-" + ID) | |||
.removeClass("disabled") | |||
.addClass("blue"); | |||
} | |||
if ( | |||
[ | |||
"CREATING", | |||
"STOPPING", | |||
"STARTING", | |||
"STOPPED", | |||
"FAILED", | |||
"START_FAILED", | |||
"SUCCEEDED", | |||
"COMPLETED", | |||
"CREATE_FAILED", | |||
].includes(status) | |||
) { | |||
$("#ai-stop-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
} | |||
if (['IMAGE_FAILED', 'SUBMIT_FAILED', 'DELETE_FAILED', 'KILLED', 'COMPLETED', 'FAILED', 'CANCELED', 'LOST', 'START_FAILED', 'SUCCEEDED', 'STOPPED'].includes(status)) { | |||
return | |||
} | |||
let stopArray = ["KILLED", "FAILED", "START_FAILED", "KILLING", "COMPLETED", "SUCCEEDED", "STOPPED"] | |||
$.get(`/api/v1/repos/${repoPath}/${jobID}?version_name=${versionname}`, (data) => { | |||
//$(`#${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) | |||
if (stopArray.includes(data.JobStatus)) { | |||
$('#' + versionname + '-stop').addClass('disabled') | |||
} | |||
if (data.JobStatus === "COMPLETED") { | |||
$('#' + versionname + '-create-model').removeClass('disabled').addClass('blue') | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
}); | |||
}; | |||
if ( | |||
[ | |||
"STOPPED", | |||
"FAILED", | |||
"START_FAILED", | |||
"KILLED", | |||
"COMPLETED", | |||
"SUCCEEDED", | |||
].includes(status) | |||
) { | |||
$("#ai-delete-" + ID) | |||
.removeClass("disabled") | |||
.addClass("blue"); | |||
} else { | |||
$("#ai-delete-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
} | |||
} | |||
).fail(function (err) { | |||
console.log(err); | |||
}); | |||
}); | |||
} | |||
function loadShowJobStatus() { | |||
$(".ui.accordion.border-according").each((index, job) => { | |||
const jobID = job.dataset.jobid; | |||
const repoPath = job.dataset.repopath; | |||
const versionname = job.dataset.version; | |||
// ['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'] | |||
// if (job.textContent.trim() == 'IMAGE_FAILED' || job.textContent.trim() == 'SUBMIT_FAILED' || job.textContent.trim() == 'DELETE_FAILED' | |||
// || job.textContent.trim() == 'KILLED' || job.textContent.trim() == 'COMPLETED' || job.textContent.trim() == 'FAILED' | |||
// || job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') { | |||
// return | |||
// } | |||
let status = $(`#${versionname}-status-span`).text(); | |||
function assertDelete(obj, versionName, repoPath) { | |||
if (obj.style.color == "rgb(204, 204, 204)") { | |||
return | |||
} else { | |||
const delId = obj.parentNode.id | |||
let flag = 1; | |||
$('.ui.basic.modal') | |||
.modal({ | |||
onDeny: function () { | |||
flag = false | |||
}, | |||
onApprove: function () { | |||
if (!versionName) { | |||
document.getElementById(delId).submit() | |||
} | |||
else { | |||
deleteVersion(versionName, repoPath) | |||
} | |||
flag = true | |||
}, | |||
onHidden: function () { | |||
if (flag == false) { | |||
$('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||
} | |||
} | |||
}) | |||
.modal('show') | |||
} | |||
} | |||
function deleteVersion(versionName, repoPath) { | |||
const url = `/api/v1/repos/${repoPath}` | |||
$.post(url, { version_name: versionName }, (data) => { | |||
if (data.StatusOK === 0) { | |||
location.reload() | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
$('.ui.basic.ai_delete').click(function () { | |||
const repoPath = this.dataset.repopath | |||
const versionName = this.dataset.version | |||
if (repoPath && versionName) { | |||
assertDelete(this, versionName, repoPath) | |||
if ( | |||
[ | |||
"IMAGE_FAILED", | |||
"SUBMIT_FAILED", | |||
"DELETE_FAILED", | |||
"KILLED", | |||
"COMPLETED", | |||
"FAILED", | |||
"CANCELED", | |||
"LOST", | |||
"START_FAILED", | |||
"SUCCEEDED", | |||
"STOPPED", | |||
].includes(status) | |||
) { | |||
return; | |||
} | |||
let stopArray = [ | |||
"KILLED", | |||
"FAILED", | |||
"START_FAILED", | |||
"KILLING", | |||
"COMPLETED", | |||
"SUCCEEDED", | |||
"STOPPED", | |||
]; | |||
$.get( | |||
`/api/v1/repos/${repoPath}/${jobID}?version_name=${versionname}`, | |||
(data) => { | |||
$(`#${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); | |||
if (stopArray.includes(data.JobStatus)) { | |||
$("#" + versionname + "-stop").addClass("disabled"); | |||
} | |||
if (data.JobStatus === "COMPLETED") { | |||
$("#" + versionname + "-create-model") | |||
.removeClass("disabled") | |||
.addClass("blue"); | |||
} | |||
} | |||
else { | |||
assertDelete(this) | |||
} | |||
}) | |||
function stopDebug(ID, stopUrl) { | |||
$.ajax({ | |||
type: "POST", | |||
url: stopUrl, | |||
data: $('#stopForm-' + ID).serialize(), | |||
success: function (res) { | |||
if (res.result_code === "0") { | |||
$('#' + ID + '-icon').removeClass().addClass(res.status) | |||
$('#' + ID + '-text').text(res.status) | |||
if (res.status === "STOPPED") { | |||
$('#ai-debug-' + ID).removeClass('disabled').addClass('blue').text(debug_again_button).css("margin", "0") | |||
$('#ai-image-' + ID).removeClass('blue').addClass('disabled') | |||
$('#ai-model-debug-' + ID).removeClass('blue').addClass('disabled') | |||
$('#ai-delete-' + ID).removeClass('disabled').addClass('blue') | |||
$('#ai-stop-' + ID).removeClass('blue').addClass('disabled') | |||
} | |||
else { | |||
$('#ai-debug-' + ID).removeClass('blue').addClass('disabled') | |||
$('#ai-stop-' + ID).removeClass('blue').addClass('disabled') | |||
} | |||
} else { | |||
$('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||
} | |||
}, | |||
error: function (res) { | |||
console.log(res) | |||
).fail(function (err) { | |||
console.log(err); | |||
}); | |||
}); | |||
} | |||
function assertDelete(obj, versionName, repoPath) { | |||
if (obj.style.color == "rgb(204, 204, 204)") { | |||
return; | |||
} else { | |||
const delId = obj.parentNode.id; | |||
let flag = 1; | |||
$(".ui.basic.modal") | |||
.modal({ | |||
onDeny: function () { | |||
flag = false; | |||
}, | |||
onApprove: function () { | |||
if (!versionName) { | |||
document.getElementById(delId).submit(); | |||
} else { | |||
deleteVersion(versionName, repoPath); | |||
} | |||
flag = true; | |||
}, | |||
onHidden: function () { | |||
if (flag == false) { | |||
$(".alert") | |||
.html("您已取消操作") | |||
.removeClass("alert-success") | |||
.addClass("alert-danger") | |||
.show() | |||
.delay(1500) | |||
.fadeOut(); | |||
} | |||
}, | |||
}) | |||
.modal("show"); | |||
} | |||
$('.ui.basic.ai_stop').click(function () { | |||
const ID = this.dataset.jobid | |||
const repoPath = this.dataset.repopath | |||
stopDebug(ID, repoPath) | |||
}) | |||
function stopVersion(version_name, ID, repoPath) { | |||
const url = `/api/v1/repos/${repoPath}/${ID}/stop_version` | |||
$.post(url, { version_name: version_name }, (data) => { | |||
if (data.StatusOK === 0) { | |||
$('#ai-stop-' + ID).removeClass('blue') | |||
$('#ai-stop-' + ID).addClass('disabled') | |||
refreshStatus(version_name, ID, repoPath) | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
function deleteVersion(versionName, repoPath) { | |||
const url = `/api/v1/repos/${repoPath}`; | |||
$.post(url, { version_name: versionName }, (data) => { | |||
if (data.StatusOK === 0 || data.Code === 0) { | |||
location.reload(); | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
$(".ui.basic.ai_delete").click(function () { | |||
const repoPath = this.dataset.repopath; | |||
const versionName = this.dataset.version; | |||
if (repoPath && versionName) { | |||
assertDelete(this, versionName, repoPath); | |||
} else { | |||
assertDelete(this); | |||
} | |||
function refreshStatus(version_name, ID, repoPath) { | |||
}); | |||
function stopDebug(ID, stopUrl) { | |||
$.ajax({ | |||
type: "POST", | |||
url: stopUrl, | |||
data: $("#stopForm-" + ID).serialize(), | |||
success: function (res) { | |||
if (res.result_code === "0") { | |||
$("#" + ID + "-icon") | |||
.removeClass() | |||
.addClass(res.status); | |||
$("#" + ID + "-text").text(res.status); | |||
if (res.status === "STOPPED") { | |||
$("#ai-debug-" + ID) | |||
.removeClass("disabled") | |||
.addClass("blue") | |||
.text(debug_again_button) | |||
.css("margin", "0"); | |||
$("#ai-image-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
$("#ai-model-debug-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
$("#ai-delete-" + ID) | |||
.removeClass("disabled") | |||
.addClass("blue"); | |||
$("#ai-stop-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
} else { | |||
$("#ai-debug-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
$("#ai-stop-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
} | |||
} else { | |||
$(".alert") | |||
.html(res.error_msg) | |||
.removeClass("alert-success") | |||
.addClass("alert-danger") | |||
.show() | |||
.delay(2000) | |||
.fadeOut(); | |||
} | |||
}, | |||
error: function (res) { | |||
console.log(res); | |||
}, | |||
}); | |||
} | |||
$(".ui.basic.ai_stop").click(function () { | |||
const ID = this.dataset.jobid; | |||
const repoPath = this.dataset.repopath; | |||
stopDebug(ID, repoPath); | |||
}); | |||
const url = `/api/v1/repos/${repoPath}/${ID}/?version_name${version_name}` | |||
$.get(url, (data) => { | |||
$(`#${ID}-icon`).attr("class", data.JobStatus) | |||
// detail status and duration | |||
$(`#${ID}-text`).text(data.JobStatus) | |||
if (["STOPPED", "FAILED", "START_FAILED", "KILLED", "COMPLETED", "SUCCEEDED"].includes(data.JobStatus)) { | |||
$('#ai-delete-' + ID).removeClass('disabled').addClass('blue') | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
$('.ui.basic.ai_stop_version').click(function () { | |||
const ID = this.dataset.jobid | |||
const repoPath = this.dataset.repopath | |||
const versionName = this.dataset.version | |||
stopVersion(versionName, ID, repoPath) | |||
}) | |||
function getModelInfo(repoPath, modelName, versionName, jobName) { | |||
$.get(`${repoPath}/modelmanage/show_model_info_api?name=${modelName}`, (data) => { | |||
if (data.length === 0) { | |||
$(`#${jobName}`).popup('toggle') | |||
function stopVersion(version_name, ID, repoPath) { | |||
const url = `/api/v1/repos/${repoPath}/${ID}/stop_version`; | |||
$.post(url, { version_name: version_name }, (data) => { | |||
if (data.StatusOK === 0) { | |||
$("#ai-stop-" + ID).removeClass("blue"); | |||
$("#ai-stop-" + ID).addClass("disabled"); | |||
refreshStatus(version_name, ID, repoPath); | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
$("#refresh-status").click(function (e) { | |||
let version_name = $(this).data("version"); | |||
let ID = $(`#accordion${version_name}`).data("jobid"); | |||
let repoPath = $(`#accordion${version_name}`).data("repopath"); | |||
refreshStatusShow(version_name, ID, repoPath); | |||
e.stopPropagation(); | |||
}); | |||
function refreshStatusShow(version_name, ID, repoPath) { | |||
$.get( | |||
`/api/v1/repos/${repoPath}/${ID}?version_name=${version_name}`, | |||
(data) => { | |||
$(`#${version_name}-status-span span`).text(data.JobStatus); | |||
$(`#${version_name}-status-span i`).attr("class", data.JobStatus); | |||
$(`#${version_name}-duration-span`).text(data.JobDuration); | |||
$("#" + versionname + "-duration").text(data.JobDuration); | |||
$("#" + versionname + "-status").text(data.JobStatus); | |||
} | |||
).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
function refreshStatus(version_name, ID, repoPath) { | |||
const url = `/api/v1/repos/${repoPath}/${ID}/?version_name${version_name}`; | |||
$.get(url, (data) => { | |||
$(`#${ID}-icon`).attr("class", data.JobStatus); | |||
// detail status and duration | |||
$(`#${ID}-text`).text(data.JobStatus); | |||
if ( | |||
[ | |||
"STOPPED", | |||
"FAILED", | |||
"START_FAILED", | |||
"KILLED", | |||
"COMPLETED", | |||
"SUCCEEDED", | |||
].includes(data.JobStatus) | |||
) { | |||
$("#ai-delete-" + ID) | |||
.removeClass("disabled") | |||
.addClass("blue"); | |||
} | |||
}).fail(function (err) { | |||
console.log(err); | |||
}); | |||
} | |||
$(".ui.basic.ai_stop_version").click(function () { | |||
const ID = this.dataset.jobid; | |||
const repoPath = this.dataset.repopath; | |||
const versionName = this.dataset.version; | |||
stopVersion(versionName, ID, repoPath); | |||
}); | |||
function getModelInfo(repoPath, modelName, versionName, jobName) { | |||
$.get( | |||
`${repoPath}/modelmanage/show_model_info_api?name=${modelName}`, | |||
(data) => { | |||
if (data.length === 0) { | |||
$(`#${jobName}`).popup("toggle"); | |||
} else { | |||
let versionData = data.filter((item) => { | |||
return item.Version === versionName; | |||
}); | |||
if (versionData.length == 0) { | |||
$(`#${jobName}`).popup("toggle"); | |||
} else { | |||
location.href = `${repoPath}/modelmanage/show_model_info?name=${modelName}`; | |||
} | |||
} | |||
} | |||
); | |||
} | |||
$(".goto_modelmanage").click(function () { | |||
const repoPath = this.dataset.repopath; | |||
const modelName = this.dataset.modelname; | |||
const versionName = this.dataset.version; | |||
const jobName = this.dataset.jobname; | |||
getModelInfo(repoPath, modelName, versionName, jobName); | |||
}); | |||
function debugAgain(ID, debugUrl, redirect_to) { | |||
if ($("#" + ID + "-text").text() === "RUNNING") { | |||
window.open(debugUrl + "debug"); | |||
} else { | |||
$.ajax({ | |||
type: "POST", | |||
url: debugUrl + "restart?redirect_to=" + redirect_to, | |||
data: $("#debugAgainForm-" + ID).serialize(), | |||
success: function (res) { | |||
if (res["WechatRedirectUrl"]) { | |||
window.location.href = res["WechatRedirectUrl"]; | |||
} else if (res.result_code === "0") { | |||
if (res.id !== ID) { | |||
location.reload(); | |||
} else { | |||
let versionData = data.filter((item) => { | |||
return item.Version === versionName | |||
}) | |||
if (versionData.length == 0) { | |||
$(`#${jobName}`).popup('toggle') | |||
} | |||
else { | |||
location.href = `${repoPath}/modelmanage/show_model_info?name=${modelName}` | |||
} | |||
$("#" + ID + "-icon") | |||
.removeClass() | |||
.addClass(res.status); | |||
$("#" + ID + "-text").text(res.status); | |||
$("#ai-debug-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
$("#ai-delete-" + ID) | |||
.removeClass("blue") | |||
.addClass("disabled"); | |||
$("#ai-debug-" + ID) | |||
.text(debug_button) | |||
.css("margin", "0 1rem"); | |||
} | |||
}) | |||
} else { | |||
$(".alert") | |||
.html(res.error_msg) | |||
.removeClass("alert-success") | |||
.addClass("alert-danger") | |||
.show() | |||
.delay(2000) | |||
.fadeOut(); | |||
} | |||
}, | |||
error: function (res) { | |||
console.log(res); | |||
}, | |||
}); | |||
} | |||
$('.goto_modelmanage').click(function () { | |||
const repoPath = this.dataset.repopath | |||
const modelName = this.dataset.modelname | |||
const versionName = this.dataset.version | |||
const jobName = this.dataset.jobname | |||
getModelInfo(repoPath, modelName, versionName, jobName) | |||
}) | |||
function debugAgain(ID, debugUrl, redirect_to) { | |||
if ($('#' + ID + '-text').text() === "RUNNING") { | |||
window.open(debugUrl + 'debug') | |||
} else { | |||
$.ajax({ | |||
type: "POST", | |||
url: debugUrl + 'restart?redirect_to=' + redirect_to, | |||
data: $('#debugAgainForm-' + ID).serialize(), | |||
success: function (res) { | |||
if (res['WechatRedirectUrl']) { | |||
window.location.href = res['WechatRedirectUrl'] | |||
} | |||
else if (res.result_code === "0") { | |||
if (res.id !== ID) { | |||
location.reload() | |||
} else { | |||
$('#' + ID + '-icon').removeClass().addClass(res.status) | |||
$('#' + ID + '-text').text(res.status) | |||
$('#ai-debug-' + ID).removeClass('blue').addClass('disabled') | |||
$('#ai-delete-' + ID).removeClass('blue').addClass('disabled') | |||
$('#ai-debug-' + ID).text(debug_button).css("margin", "0 1rem") | |||
} | |||
} else { | |||
$('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||
} | |||
}, | |||
error: function (res) { | |||
console.log(res) | |||
} | |||
}) | |||
} | |||
} | |||
$(".ui.basic.ai_debug").click(function () { | |||
const ID = this.dataset.jobid; | |||
const repoPath = this.dataset.repopath; | |||
const redirect_to = this.dataset.linkpath; | |||
debugAgain(ID, repoPath, redirect_to); | |||
}); | |||
function setWaitNums() { | |||
console.log($(".cloudbrain-type")); | |||
if ($(".cloudbrain-type").length === 0 && $(".gpu-type").length === 0) { | |||
return; | |||
} | |||
$('.ui.basic.ai_debug').click(function () { | |||
const ID = this.dataset.jobid | |||
const repoPath = this.dataset.repopath | |||
const redirect_to = this.dataset.linkpath | |||
debugAgain(ID, repoPath, redirect_to) | |||
}) | |||
let waitNums = $(".cloudbrain-type").data("queue").split("map")[1]; | |||
let test = new Map(); | |||
let waitNumsArray = waitNums.split(" "); | |||
waitNumsArray.forEach((element, index) => { | |||
if (index === 0) { | |||
test.set(element.slice(1, -2), parseInt(element.slice(-1))); | |||
} else if (index === waitNumsArray.length - 1) { | |||
test.set(element.slice(0, -3), parseInt(element.slice(-2, -1))); | |||
} else { | |||
test.set(element.slice(0, -2), parseInt(element.slice(-1))); | |||
} | |||
}); | |||
$(".ui.search.dropdown.gpu-type").dropdown({ | |||
onChange: function (value, text, $selectedItem) { | |||
let gpuTypeNums = test.get(value); | |||
let gpuTypeNumString = | |||
$(".cloudbrain-type").data("queue-start") + | |||
" " + | |||
gpuTypeNums + | |||
" " + | |||
$(".cloudbrain-type").data("queue-end"); | |||
$("#gpu-nums").text(gpuTypeNumString); | |||
}, | |||
}); | |||
} | |||
setWaitNums(); | |||
} | |||
function userSearchControll() { | |||
if ($('#userCloud').length === 0) { | |||
return | |||
if ($("#userCloud").length === 0) { | |||
return; | |||
} | |||
const params = new URLSearchParams(window.location.search); | |||
let jobType; | |||
if ($(".cloudbrain_debug").length === 1) { | |||
if (!params.get("jobType")) { | |||
jobType = $(".cloudbrain_debug").data("allTask"); | |||
} else { | |||
if (params.get("jobType") === "DEBUG") { | |||
jobType = $(".cloudbrain_debug").data("debug-task"); | |||
} else if (params.get("jobType") === "TRAIN") { | |||
jobType = $(".cloudbrain_debug").data("train-task"); | |||
} else if (params.get("jobType") === "INFERENCE") { | |||
jobType = $(".cloudbrain_debug").data("inference-task"); | |||
} else { | |||
jobType = $(".cloudbrain_debug").data("benchmark-task"); | |||
} | |||
} | |||
const params = new URLSearchParams(window.location.search) | |||
let jobType | |||
if ($('.cloudbrain_debug').length === 1) { | |||
if (!params.get('jobType')) { | |||
jobType = $('.cloudbrain_debug').data('allTask') | |||
} else { | |||
if (params.get('jobType') === 'DEBUG') { | |||
jobType = $('.cloudbrain_debug').data('debug-task') | |||
} else if (params.get('jobType') === 'TRAIN') { | |||
jobType = $('.cloudbrain_debug').data('train-task') | |||
} | |||
else if (params.get('jobType') === 'INFERENCE') { | |||
jobType = $('.cloudbrain_debug').data('inference-task') | |||
} | |||
else { | |||
jobType = $('.cloudbrain_debug').data('benchmark-task') | |||
} | |||
} | |||
} | |||
let listType = !params.get('listType') ? $('.cloudbrain_debug').data('all-compute') : params.get('listType') | |||
let jobStatus = !params.get('jobStatus') ? $('.cloudbrain_debug').data('all-status') : params.get('jobStatus').toUpperCase() | |||
const dropdownValueArray = [jobType, listType, jobStatus] | |||
$('#userCloud .default.text ').each(function (index, e) { | |||
$(e).text(dropdownValueArray[index]) | |||
}) | |||
} | |||
let listType = !params.get("listType") | |||
? $(".cloudbrain_debug").data("all-compute") | |||
: params.get("listType"); | |||
let jobStatus = !params.get("jobStatus") | |||
? $(".cloudbrain_debug").data("all-status") | |||
: params.get("jobStatus").toUpperCase(); | |||
const dropdownValueArray = [jobType, listType, jobStatus]; | |||
$("#userCloud .default.text ").each(function (index, e) { | |||
$(e).text(dropdownValueArray[index]); | |||
}); | |||
} | |||
function AdaminSearchControll() { | |||
if ($('#adminCloud').length === 0) { | |||
return | |||
} | |||
const params = new URLSearchParams(window.location.search) | |||
let jobType = !params.get('jobType') ? $('.cloudbrain_debug').data('all-task') : params.get('jobType') | |||
let listType = !params.get('listType') ? $('.cloudbrain_debug').data('all-compute') : params.get('listType') | |||
let jobStatus = !params.get('jobStatus') ? $('.cloudbrain_debug').data('all-status') : params.get('jobStatus').toUpperCase() | |||
const dropdownValueArray = [jobType, listType, jobStatus] | |||
$('#adminCloud .default.text ').each(function (index, e) { | |||
$(e).text(dropdownValueArray[index]) | |||
}) | |||
if ($("#adminCloud").length === 0) { | |||
return; | |||
} | |||
const params = new URLSearchParams(window.location.search); | |||
let jobType = !params.get("jobType") | |||
? $(".cloudbrain_debug").data("all-task") | |||
: params.get("jobType"); | |||
let listType = !params.get("listType") | |||
? $(".cloudbrain_debug").data("all-compute") | |||
: params.get("listType"); | |||
let jobStatus = !params.get("jobStatus") | |||
? $(".cloudbrain_debug").data("all-status") | |||
: params.get("jobStatus").toUpperCase(); | |||
const dropdownValueArray = [jobType, listType, jobStatus]; | |||
$("#adminCloud .default.text ").each(function (index, e) { | |||
$(e).text(dropdownValueArray[index]); | |||
}); | |||
} | |||
userSearchControll() | |||
AdaminSearchControll() | |||
userSearchControll(); | |||
AdaminSearchControll(); |
@@ -43,6 +43,7 @@ import Contributors from "./components/Contributors.vue"; | |||
import Model from "./components/Model.vue"; | |||
import WxAutorize from "./components/WxAutorize.vue"; | |||
import initCloudrain from "./features/cloudrbanin.js"; | |||
import initCloudrainSow from "./features/cloudbrainShow.js"; | |||
import initImage from "./features/images.js"; | |||
import selectDataset from "./components/dataset/selectDataset.vue"; | |||
// import $ from 'jquery.js' | |||
@@ -2917,6 +2918,7 @@ $(document).ready(async () => { | |||
initTribute(); | |||
initDropDown(); | |||
initCloudrain(); | |||
initCloudrainSow(); | |||
initImage(); | |||
initContextMenu(); | |||
@@ -3711,9 +3713,9 @@ function initVueDataset() { | |||
if (!el) { | |||
return; | |||
} | |||
let link = $('#square-link').data('link') | |||
let repolink = $('.dataset-repolink').data('repolink') | |||
let datasetType = $('.dataset-repolink').data('dataset-type') | |||
let link = $("#square-link").data("link"); | |||
let repolink = $(".dataset-repolink").data("repolink"); | |||
let datasetType = $(".dataset-repolink").data("dataset-type"); | |||
const clearBtn = document.getElementsByClassName("clear_dataset_value"); | |||
const params = new URLSearchParams(location.search); | |||
for (let i = 0; i < clearBtn.length; i++) { | |||
@@ -3873,10 +3875,10 @@ function initVueDataset() { | |||
mounted() { | |||
this.getTypeList(); | |||
if (!!document.getElementById('dataset-repolink-init')) { | |||
if (!!document.getElementById("dataset-repolink-init")) { | |||
// this.datasetType = location.href.indexOf('cloudbrain') !== -1 ? 0 : 1 | |||
this.datasetType = $('#dataset-repolink-init').data("dataset-type") | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType) | |||
this.datasetType = $("#dataset-repolink-init").data("dataset-type"); | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType); | |||
} | |||
const params = new URLSearchParams(location.search); | |||
@@ -3897,13 +3899,13 @@ function initVueDataset() { | |||
this.ruleForm1 = ruleForm; | |||
// this.getEditInit() | |||
this.starItems = starItems | |||
this.starActives = starActives | |||
this.taskLists = taskLists | |||
this.licenseLists = licenseLists | |||
this.descfile = dataset_file_desc | |||
this.repolink = repolink | |||
this.datasetType = datasetType | |||
this.starItems = starItems; | |||
this.starActives = starActives; | |||
this.taskLists = taskLists; | |||
this.licenseLists = licenseLists; | |||
this.descfile = dataset_file_desc; | |||
this.repolink = repolink; | |||
this.datasetType = datasetType; | |||
}, | |||
methods: { | |||
copyUrl(url) { | |||
@@ -3924,18 +3926,18 @@ function initVueDataset() { | |||
handleCurrentChange(val) { | |||
this.page = val; | |||
switch (this.activeName) { | |||
case 'first': | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType) | |||
break | |||
case 'second': | |||
this.getMyDataset(this.repolink, this.datasetType) | |||
break | |||
case 'third': | |||
this.getPublicDataset(this.repolink, this.datasetType) | |||
break | |||
case 'fourth': | |||
this.getStarDataset(this.repolink, this.datasetType) | |||
break | |||
case "first": | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType); | |||
break; | |||
case "second": | |||
this.getMyDataset(this.repolink, this.datasetType); | |||
break; | |||
case "third": | |||
this.getPublicDataset(this.repolink, this.datasetType); | |||
break; | |||
case "fourth": | |||
this.getStarDataset(this.repolink, this.datasetType); | |||
break; | |||
} | |||
}, | |||
handleCheckedChange(val) { | |||
@@ -4276,18 +4278,18 @@ function initVueDataset() { | |||
}, | |||
refreshStatusDataset() { | |||
switch (this.activeName) { | |||
case 'first': | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType) | |||
break | |||
case 'second': | |||
this.getMyDataset(this.repolink, this.datasetType) | |||
break | |||
case 'third': | |||
this.getPublicDataset(this.repolink, this.datasetType) | |||
break | |||
case 'fourth': | |||
this.getStarDataset(this.repolink, this.datasetType) | |||
break | |||
case "first": | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType); | |||
break; | |||
case "second": | |||
this.getMyDataset(this.repolink, this.datasetType); | |||
break; | |||
case "third": | |||
this.getPublicDataset(this.repolink, this.datasetType); | |||
break; | |||
case "fourth": | |||
this.getStarDataset(this.repolink, this.datasetType); | |||
break; | |||
} | |||
}, | |||
getCurrentRepoDataset(repoLink, type) { | |||
@@ -4398,44 +4400,44 @@ function initVueDataset() { | |||
}, | |||
searchDataset() { | |||
switch (this.activeName) { | |||
case 'first': | |||
this.page = 1 | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType) | |||
break | |||
case 'second': | |||
this.page = 1 | |||
this.getMyDataset(this.repolink, this.datasetType) | |||
break | |||
case 'third': | |||
this.page = 1 | |||
this.getPublicDataset(this.repolink, this.datasetType) | |||
break | |||
case 'fourth': | |||
this.page = 1 | |||
this.getStarDataset(this.repolink, this.datasetType) | |||
break | |||
case "first": | |||
this.page = 1; | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType); | |||
break; | |||
case "second": | |||
this.page = 1; | |||
this.getMyDataset(this.repolink, this.datasetType); | |||
break; | |||
case "third": | |||
this.page = 1; | |||
this.getPublicDataset(this.repolink, this.datasetType); | |||
break; | |||
case "fourth": | |||
this.page = 1; | |||
this.getStarDataset(this.repolink, this.datasetType); | |||
break; | |||
} | |||
}, | |||
}, | |||
watch: { | |||
searchDataItem() { | |||
switch (this.activeName) { | |||
case 'first': | |||
this.page = 1 | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType) | |||
break | |||
case 'second': | |||
this.page = 1 | |||
this.getMyDataset(this.repolink, this.datasetType) | |||
break | |||
case 'third': | |||
this.page = 1 | |||
this.getPublicDataset(this.repolink, this.datasetType) | |||
break | |||
case 'fourth': | |||
this.page = 1 | |||
this.getStarDataset(this.repolink, this.datasetType) | |||
break | |||
case "first": | |||
this.page = 1; | |||
this.getCurrentRepoDataset(this.repolink, this.datasetType); | |||
break; | |||
case "second": | |||
this.page = 1; | |||
this.getMyDataset(this.repolink, this.datasetType); | |||
break; | |||
case "third": | |||
this.page = 1; | |||
this.getPublicDataset(this.repolink, this.datasetType); | |||
break; | |||
case "fourth": | |||
this.page = 1; | |||
this.getStarDataset(this.repolink, this.datasetType); | |||
break; | |||
} | |||
}, | |||
}, | |||
@@ -1210,12 +1210,27 @@ i.SUCCEEDED { | |||
max-width: 6.38px; | |||
visibility: hidden; | |||
} | |||
.label-fix-width { | |||
width: 140px !important; | |||
text-align: right; | |||
font-family: SourceHanSansSC-medium !important; | |||
color: rgba(16, 16, 16, 100) !important; | |||
font-size: 14px !important; | |||
} | |||
.inline.min_title.fields.required .label-fix-width:after { | |||
margin: -0.2em 0 0 0.2em; | |||
content: "*"; | |||
max-width: 6.38px; | |||
visibility: hidden; | |||
} | |||
.tooltip-wati-count { | |||
display: flex; | |||
align-items: center; | |||
margin-left: 260px; | |||
color: #f2711c; | |||
margin-top: 0.5rem; | |||
} | |||
#dir_list { | |||
max-height: 500px; | |||
overflow: auto; | |||