You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ai_model_convert.go 20 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. package repo
  2. import (
  3. "bufio"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "io/ioutil"
  9. "net/http"
  10. "os"
  11. "strings"
  12. "code.gitea.io/gitea/models"
  13. "code.gitea.io/gitea/modules/cloudbrain"
  14. "code.gitea.io/gitea/modules/context"
  15. "code.gitea.io/gitea/modules/git"
  16. "code.gitea.io/gitea/modules/log"
  17. "code.gitea.io/gitea/modules/modelarts"
  18. "code.gitea.io/gitea/modules/setting"
  19. "code.gitea.io/gitea/modules/storage"
  20. "code.gitea.io/gitea/modules/timeutil"
  21. uuid "github.com/satori/go.uuid"
  22. )
  23. const (
  24. tplModelManageConvertIndex = "repo/modelmanage/convertIndex"
  25. tplModelConvertInfo = "repo/modelmanage/convertshowinfo"
  26. PYTORCH_ENGINE = 0
  27. TENSORFLOW_ENGINE = 1
  28. MINDSPORE_ENGIN = 2
  29. ModelMountPath = "/model"
  30. CodeMountPath = "/code"
  31. DataSetMountPath = "/dataset"
  32. LogFile = "log.txt"
  33. DefaultBranchName = "master"
  34. SubTaskName = "task1"
  35. GpuQueue = "openidgx"
  36. Success = "S000"
  37. GPU_PYTORCH_IMAGE = "dockerhub.pcl.ac.cn:5000/user-images/openi:tensorRT_7_zouap"
  38. GPU_TENSORFLOW_IMAGE = "dockerhub.pcl.ac.cn:5000/user-images/openi:tf2onnx"
  39. PytorchBootFile = "convert_pytorch.py"
  40. MindsporeBootFile = "convert_mindspore.py"
  41. TensorFlowNpuBootFile = "convert_tensorflow.py"
  42. TensorFlowGpuBootFile = "convert_tensorflow_gpu.py"
  43. ConvertRepoPath = "https://git.openi.org.cn/zouap/npu_test"
  44. REPO_ID = 33267
  45. NPU_MINDSPORE_IMAGE_ID = 122
  46. NPU_TENSORFLOW_IMAGE_ID = 121
  47. NPU_FlavorCode = "modelarts.bm.910.arm.public.1"
  48. NPU_PoolID = "pool7908321a"
  49. )
  50. var (
  51. TrainResourceSpecs *models.ResourceSpecs
  52. )
  53. func SaveModelConvert(ctx *context.Context) {
  54. log.Info("save model convert start.")
  55. if !ctx.Repo.CanWrite(models.UnitTypeModelManage) {
  56. ctx.JSON(403, ctx.Tr("repo.model_noright"))
  57. return
  58. }
  59. name := ctx.Query("name")
  60. desc := ctx.Query("desc")
  61. modelId := ctx.Query("modelId")
  62. modelPath := ctx.Query("ModelFile")
  63. SrcEngine := ctx.QueryInt("SrcEngine")
  64. InputShape := ctx.Query("inputshape")
  65. InputDataFormat := ctx.Query("inputdataformat")
  66. DestFormat := ctx.QueryInt("DestFormat")
  67. NetOutputFormat := ctx.QueryInt("NetOutputFormat")
  68. task, err := models.QueryModelById(modelId)
  69. if err != nil {
  70. log.Error("no such model!", err.Error())
  71. ctx.ServerError("no such model:", err)
  72. return
  73. }
  74. uuid := uuid.NewV4()
  75. id := uuid.String()
  76. modelConvert := &models.AiModelConvert{
  77. ID: id,
  78. Name: name,
  79. Description: desc,
  80. Status: string(models.JobWaiting),
  81. SrcEngine: SrcEngine,
  82. RepoId: ctx.Repo.Repository.ID,
  83. ModelName: task.Name,
  84. ModelVersion: task.Version,
  85. ModelId: modelId,
  86. ModelPath: modelPath,
  87. DestFormat: DestFormat,
  88. NetOutputFormat: NetOutputFormat,
  89. InputShape: InputShape,
  90. InputDataFormat: InputDataFormat,
  91. UserId: ctx.User.ID,
  92. }
  93. models.SaveModelConvert(modelConvert)
  94. go goCreateTask(modelConvert, ctx, task)
  95. ctx.JSON(200, map[string]string{
  96. "result_code": "0",
  97. })
  98. }
  99. func goCreateTask(modelConvert *models.AiModelConvert, ctx *context.Context, task *models.AiModelManage) error {
  100. if modelConvert.IsGpuTrainTask() {
  101. log.Info("create gpu train job.")
  102. return createGpuTrainJob(modelConvert, ctx, task)
  103. } else {
  104. //create npu job
  105. log.Info("create npu train job.")
  106. return createNpuTrainJob(modelConvert, ctx, task.Path)
  107. }
  108. }
  109. func createNpuTrainJob(modelConvert *models.AiModelConvert, ctx *context.Context, modelRelativePath string) error {
  110. VersionOutputPath := "V0001"
  111. codeLocalPath := setting.JobPath + modelConvert.ID + modelarts.CodePath
  112. codeObsPath := "/" + setting.Bucket + modelarts.JobPath + modelConvert.ID + modelarts.CodePath
  113. outputObsPath := "/" + setting.Bucket + modelarts.JobPath + modelConvert.ID + modelarts.OutputPath + VersionOutputPath + "/"
  114. logObsPath := "/" + setting.Bucket + modelarts.JobPath + modelConvert.ID + modelarts.LogPath + VersionOutputPath + "/"
  115. dataPath := "/" + modelRelativePath
  116. _, err := ioutil.ReadDir(codeLocalPath)
  117. if err == nil {
  118. os.RemoveAll(codeLocalPath)
  119. }
  120. if err := downloadConvertCode(ConvertRepoPath, codeLocalPath, DefaultBranchName); err != nil {
  121. log.Error("downloadCode failed, server timed out: %s (%v)", ConvertRepoPath, err)
  122. return err
  123. }
  124. if err := obsMkdir(setting.CodePathPrefix + modelConvert.ID + modelarts.OutputPath + VersionOutputPath + "/"); err != nil {
  125. log.Error("Failed to obsMkdir_output: %s (%v)", modelConvert.ID+modelarts.OutputPath, err)
  126. return err
  127. }
  128. if err := obsMkdir(setting.CodePathPrefix + modelConvert.ID + modelarts.LogPath + VersionOutputPath + "/"); err != nil {
  129. log.Error("Failed to obsMkdir_log: %s (%v)", modelConvert.ID+modelarts.LogPath, err)
  130. return err
  131. }
  132. if err := uploadCodeToObs(codeLocalPath, modelConvert.ID, ""); err != nil {
  133. log.Error("Failed to uploadCodeToObs: %s (%v)", modelConvert.ID, err)
  134. return err
  135. }
  136. intputshape := strings.Split(modelConvert.InputShape, ",")
  137. n := "256"
  138. c := "1"
  139. h := "28"
  140. w := "28"
  141. if len(intputshape) == 4 {
  142. n = intputshape[0]
  143. c = intputshape[1]
  144. h = intputshape[2]
  145. w = intputshape[3]
  146. }
  147. param := make([]models.Parameter, 0)
  148. modelPara := models.Parameter{
  149. Label: "model",
  150. Value: modelConvert.ModelPath,
  151. }
  152. param = append(param, modelPara)
  153. batchSizePara := models.Parameter{
  154. Label: "n",
  155. Value: fmt.Sprint(n),
  156. }
  157. param = append(param, batchSizePara)
  158. channelSizePara := models.Parameter{
  159. Label: "c",
  160. Value: fmt.Sprint(c),
  161. }
  162. param = append(param, channelSizePara)
  163. heightPara := models.Parameter{
  164. Label: "h",
  165. Value: fmt.Sprint(h),
  166. }
  167. param = append(param, heightPara)
  168. widthPara := models.Parameter{
  169. Label: "w",
  170. Value: fmt.Sprint(w),
  171. }
  172. param = append(param, widthPara)
  173. var engineId int64
  174. engineId = int64(NPU_MINDSPORE_IMAGE_ID)
  175. bootfile := MindsporeBootFile
  176. if modelConvert.SrcEngine == TENSORFLOW_ENGINE {
  177. engineId = int64(NPU_TENSORFLOW_IMAGE_ID)
  178. bootfile = TensorFlowNpuBootFile
  179. }
  180. req := &modelarts.GenerateTrainJobReq{
  181. JobName: modelConvert.ID,
  182. DisplayJobName: modelConvert.Name,
  183. DataUrl: dataPath,
  184. Description: modelConvert.Description,
  185. CodeObsPath: codeObsPath,
  186. BootFileUrl: codeObsPath + bootfile,
  187. BootFile: bootfile,
  188. TrainUrl: outputObsPath,
  189. FlavorCode: NPU_FlavorCode,
  190. WorkServerNumber: 1,
  191. IsLatestVersion: modelarts.IsLatestVersion,
  192. EngineID: engineId,
  193. LogUrl: logObsPath,
  194. PoolID: NPU_PoolID,
  195. Parameters: param,
  196. BranchName: DefaultBranchName,
  197. }
  198. result, err := modelarts.GenerateModelConvertTrainJob(req)
  199. if err == nil {
  200. log.Info("jobId=" + fmt.Sprint(result.JobID) + " versionid=" + fmt.Sprint(result.VersionID))
  201. models.UpdateModelConvertModelArts(modelConvert.ID, fmt.Sprint(result.JobID), fmt.Sprint(result.VersionID))
  202. }
  203. return err
  204. }
  205. func downloadConvertCode(repopath string, codePath, branchName string) error {
  206. //add "file:///" prefix to make the depth valid
  207. if err := git.Clone(repopath, codePath, git.CloneRepoOptions{Branch: branchName, Depth: 1}); err != nil {
  208. log.Error("Failed to clone repository: %s (%v)", repopath, err)
  209. return err
  210. }
  211. log.Info("srcPath=" + repopath + " codePath=" + codePath)
  212. configFile, err := os.OpenFile(codePath+"/.git/config", os.O_RDWR, 0666)
  213. if err != nil {
  214. log.Error("open file(%s) failed:%v", codePath+"/,git/config", err)
  215. return err
  216. }
  217. defer configFile.Close()
  218. pos := int64(0)
  219. reader := bufio.NewReader(configFile)
  220. for {
  221. line, err := reader.ReadString('\n')
  222. if err != nil {
  223. if err == io.EOF {
  224. log.Error("not find the remote-url")
  225. return nil
  226. } else {
  227. log.Error("read error: %v", err)
  228. return err
  229. }
  230. }
  231. if strings.Contains(line, "url") && strings.Contains(line, ".git") {
  232. originUrl := "\turl = " + repopath + "\n"
  233. if len(line) > len(originUrl) {
  234. originUrl += strings.Repeat(" ", len(line)-len(originUrl))
  235. }
  236. bytes := []byte(originUrl)
  237. _, err := configFile.WriteAt(bytes, pos)
  238. if err != nil {
  239. log.Error("WriteAt failed:%v", err)
  240. return err
  241. }
  242. break
  243. }
  244. pos += int64(len(line))
  245. }
  246. return nil
  247. }
  248. func downloadFromObsToLocal(task *models.AiModelManage, localPath string) error {
  249. path := Model_prefix + models.AttachmentRelativePath(task.ID) + "/"
  250. allFile, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, path)
  251. if err == nil {
  252. _, errState := os.Stat(localPath)
  253. if errState != nil {
  254. if err = os.MkdirAll(localPath, os.ModePerm); err != nil {
  255. return err
  256. }
  257. }
  258. for _, oneFile := range allFile {
  259. if oneFile.IsDir {
  260. log.Info(" dir name:" + oneFile.FileName)
  261. } else {
  262. allFileName := localPath + "/" + oneFile.FileName
  263. index := strings.LastIndex(allFileName, "/")
  264. if index != -1 {
  265. parentDir := allFileName[0:index]
  266. if err = os.MkdirAll(parentDir, os.ModePerm); err != nil {
  267. log.Info("make dir may be error," + err.Error())
  268. }
  269. }
  270. fDest, err := os.Create(allFileName)
  271. if err != nil {
  272. log.Info("create file error, download file failed: %s\n", err.Error())
  273. return err
  274. }
  275. body, err := storage.ObsDownloadAFile(setting.Bucket, path+oneFile.FileName)
  276. if err != nil {
  277. log.Info("download file failed: %s\n", err.Error())
  278. return err
  279. } else {
  280. defer body.Close()
  281. p := make([]byte, 1024)
  282. var readErr error
  283. var readCount int
  284. // 读取对象内容
  285. for {
  286. readCount, readErr = body.Read(p)
  287. if readCount > 0 {
  288. fDest.Write(p[:readCount])
  289. }
  290. if readErr != nil {
  291. break
  292. }
  293. }
  294. }
  295. }
  296. }
  297. } else {
  298. log.Info("error,msg=" + err.Error())
  299. return err
  300. }
  301. return nil
  302. }
  303. func createGpuTrainJob(modelConvert *models.AiModelConvert, ctx *context.Context, model *models.AiModelManage) error {
  304. modelRelativePath := model.Path
  305. command := ""
  306. IMAGE_URL := GPU_PYTORCH_IMAGE
  307. dataActualPath := setting.Attachment.Minio.RealPath + modelRelativePath
  308. if modelConvert.SrcEngine == PYTORCH_ENGINE {
  309. command = getGpuModelConvertCommand(modelConvert.ID, modelConvert.ModelPath, modelConvert, PytorchBootFile)
  310. } else if modelConvert.SrcEngine == TENSORFLOW_ENGINE {
  311. IMAGE_URL = GPU_TENSORFLOW_IMAGE
  312. command = getGpuModelConvertCommand(modelConvert.ID, modelConvert.ModelPath, modelConvert, TensorFlowGpuBootFile)
  313. //如果模型在OBS上,需要下载到本地,并上传到minio中
  314. if model.Type == models.TypeCloudBrainTwo {
  315. relatetiveModelPath := setting.JobPath + modelConvert.ID + "/dataset"
  316. log.Info("local dataset path:" + relatetiveModelPath)
  317. downloadFromObsToLocal(model, relatetiveModelPath)
  318. uploadCodeToMinio(relatetiveModelPath+"/", modelConvert.ID, "/dataset/")
  319. dataActualPath = setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + modelConvert.ID + "/dataset"
  320. }
  321. }
  322. log.Info("dataActualPath=" + dataActualPath)
  323. log.Info("command=" + command)
  324. codePath := setting.JobPath + modelConvert.ID + CodeMountPath
  325. downloadConvertCode(ConvertRepoPath, codePath, DefaultBranchName)
  326. uploadCodeToMinio(codePath+"/", modelConvert.ID, CodeMountPath+"/")
  327. minioCodePath := setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + modelConvert.ID + "/code"
  328. log.Info("minio codePath=" + minioCodePath)
  329. modelPath := setting.JobPath + modelConvert.ID + ModelMountPath + "/"
  330. log.Info("local modelPath=" + modelPath)
  331. mkModelPath(modelPath)
  332. uploadCodeToMinio(modelPath, modelConvert.ID, ModelMountPath+"/")
  333. minioModelPath := setting.Attachment.Minio.RealPath + setting.Attachment.Minio.Bucket + "/" + setting.CBCodePathPrefix + modelConvert.ID + "/model"
  334. log.Info("minio model path=" + minioModelPath)
  335. if TrainResourceSpecs == nil {
  336. json.Unmarshal([]byte(setting.TrainResourceSpecs), &TrainResourceSpecs)
  337. }
  338. resourceSpec := TrainResourceSpecs.ResourceSpec[1]
  339. jobResult, err := cloudbrain.CreateJob(modelConvert.ID, models.CreateJobParams{
  340. JobName: modelConvert.ID,
  341. RetryCount: 1,
  342. GpuType: GpuQueue,
  343. Image: IMAGE_URL,
  344. TaskRoles: []models.TaskRole{
  345. {
  346. Name: SubTaskName,
  347. TaskNumber: 1,
  348. MinSucceededTaskCount: 1,
  349. MinFailedTaskCount: 1,
  350. CPUNumber: resourceSpec.CpuNum,
  351. GPUNumber: resourceSpec.GpuNum,
  352. MemoryMB: resourceSpec.MemMiB,
  353. ShmMB: resourceSpec.ShareMemMiB,
  354. Command: command,
  355. NeedIBDevice: false,
  356. IsMainRole: false,
  357. UseNNI: false,
  358. },
  359. },
  360. Volumes: []models.Volume{
  361. {
  362. HostPath: models.StHostPath{
  363. Path: minioCodePath,
  364. MountPath: CodeMountPath,
  365. ReadOnly: false,
  366. },
  367. },
  368. {
  369. HostPath: models.StHostPath{
  370. Path: dataActualPath,
  371. MountPath: DataSetMountPath,
  372. ReadOnly: true,
  373. },
  374. },
  375. {
  376. HostPath: models.StHostPath{
  377. Path: minioModelPath,
  378. MountPath: ModelMountPath,
  379. ReadOnly: false,
  380. },
  381. },
  382. },
  383. })
  384. if err != nil {
  385. log.Error("CreateJob failed:", err.Error(), ctx.Data["MsgID"])
  386. return err
  387. }
  388. if jobResult.Code != Success {
  389. log.Error("CreateJob(%s) failed:%s", modelConvert.ID, jobResult.Msg, ctx.Data["MsgID"])
  390. return errors.New(jobResult.Msg)
  391. }
  392. var jobID = jobResult.Payload["jobId"].(string)
  393. log.Info("jobId=" + jobID)
  394. models.UpdateModelConvertCBTI(modelConvert.ID, jobID)
  395. return nil
  396. }
  397. func getGpuModelConvertCommand(name string, modelFile string, modelConvert *models.AiModelConvert, bootfile string) string {
  398. var command string
  399. intputshape := strings.Split(modelConvert.InputShape, ",")
  400. n := "256"
  401. c := "1"
  402. h := "28"
  403. w := "28"
  404. if len(intputshape) == 4 {
  405. n = intputshape[0]
  406. c = intputshape[1]
  407. h = intputshape[2]
  408. w = intputshape[3]
  409. }
  410. command += "python3 /code/" + bootfile + " --model " + modelFile + " --n " + n + " --c " + c + " --h " + h + " --w " + w + " > " + ModelMountPath + "/" + name + "-" + LogFile
  411. return command
  412. }
  413. func DeleteModelConvert(ctx *context.Context) {
  414. log.Info("delete model convert start.")
  415. id := ctx.Params(":id")
  416. err := models.DeleteModelConvertById(id)
  417. if err != nil {
  418. ctx.JSON(500, err.Error())
  419. } else {
  420. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelmanage/convert_model")
  421. }
  422. }
  423. func StopModelConvert(ctx *context.Context) {
  424. id := ctx.Params(":id")
  425. log.Info("stop model convert start.id=" + id)
  426. job, err := models.QueryModelConvertById(id)
  427. if err != nil {
  428. ctx.ServerError("Not found task.", err)
  429. return
  430. }
  431. if job.IsGpuTrainTask() {
  432. err = cloudbrain.StopJob(job.CloudBrainTaskId)
  433. if err != nil {
  434. log.Error("Stop cloudbrain Job(%s) failed:%v", job.CloudBrainTaskId, err)
  435. }
  436. } else {
  437. _, err = modelarts.StopTrainJob(job.CloudBrainTaskId, job.ModelArtsVersionId)
  438. if err != nil {
  439. log.Error("Stop modelarts Job(%s) failed:%v", job.CloudBrainTaskId, err)
  440. }
  441. }
  442. job.Status = string(models.JobStopped)
  443. if job.EndTime == 0 {
  444. job.EndTime = timeutil.TimeStampNow()
  445. }
  446. models.ModelConvertSetDuration(job)
  447. err = models.UpdateModelConvert(job)
  448. if err != nil {
  449. log.Error("UpdateModelConvert failed:", err)
  450. }
  451. ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/modelmanage/convert_model")
  452. }
  453. func ShowModelConvertInfo(ctx *context.Context) {
  454. ctx.Data["ID"] = ctx.Query("ID")
  455. ctx.Data["isModelManage"] = true
  456. ctx.Data["ModelManageAccess"] = ctx.Repo.CanWrite(models.UnitTypeModelManage)
  457. job, err := models.QueryModelConvertById(ctx.Query("ID"))
  458. if err == nil {
  459. ctx.Data["task"] = job
  460. } else {
  461. ctx.ServerError("Not found task.", err)
  462. return
  463. }
  464. ctx.Data["canDownload"] = isOper(ctx, job.UserId)
  465. user, err := models.GetUserByID(job.UserId)
  466. if err == nil {
  467. job.UserName = user.Name
  468. job.UserRelAvatarLink = user.RelAvatarLink()
  469. }
  470. if job.IsGpuTrainTask() {
  471. ctx.Data["npu_display"] = "none"
  472. ctx.Data["gpu_display"] = "block"
  473. result, err := cloudbrain.GetJob(job.CloudBrainTaskId)
  474. if err != nil {
  475. log.Info("error:" + err.Error())
  476. ctx.Data["error"] = err.Error()
  477. return
  478. }
  479. if result != nil {
  480. jobRes, _ := models.ConvertToJobResultPayload(result.Payload)
  481. ctx.Data["result"] = jobRes
  482. taskRoles := jobRes.TaskRoles
  483. taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{}))
  484. ctx.Data["taskRes"] = taskRes
  485. ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics
  486. ctx.Data["AppExitDiagnostics"] = jobRes.JobStatus.AppExitDiagnostics
  487. job.Status = jobRes.JobStatus.State
  488. if jobRes.JobStatus.State != string(models.JobWaiting) && jobRes.JobStatus.State != string(models.JobFailed) {
  489. job.ContainerIp = taskRes.TaskStatuses[0].ContainerIP
  490. job.ContainerID = taskRes.TaskStatuses[0].ContainerID
  491. job.Status = taskRes.TaskStatuses[0].State
  492. }
  493. if jobRes.JobStatus.State != string(models.JobWaiting) {
  494. models.ModelComputeAndSetDuration(job, jobRes)
  495. err = models.UpdateModelConvert(job)
  496. if err != nil {
  497. log.Error("UpdateModelConvert failed:", err)
  498. }
  499. }
  500. }
  501. } else {
  502. ctx.Data["npu_display"] = "block"
  503. ctx.Data["gpu_display"] = "none"
  504. ctx.Data["ExitDiagnostics"] = ""
  505. ctx.Data["AppExitDiagnostics"] = ""
  506. }
  507. ctx.HTML(200, tplModelConvertInfo)
  508. }
  509. func ConvertModelTemplate(ctx *context.Context) {
  510. ctx.Data["isModelManage"] = true
  511. ctx.Data["MODEL_COUNT"] = 0
  512. ctx.Data["ModelManageAccess"] = ctx.Repo.CanWrite(models.UnitTypeModelManage)
  513. ctx.Data["TRAIN_COUNT"] = 0
  514. ShowModelConvertPageInfo(ctx)
  515. ctx.HTML(200, tplModelManageConvertIndex)
  516. }
  517. func ShowModelConvertPageInfo(ctx *context.Context) {
  518. log.Info("ShowModelConvertInfo start.")
  519. if !isQueryRight(ctx) {
  520. log.Info("no right.")
  521. ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
  522. return
  523. }
  524. page := ctx.QueryInt("page")
  525. if page <= 0 {
  526. page = 1
  527. }
  528. pageSize := ctx.QueryInt("pageSize")
  529. if pageSize <= 0 {
  530. pageSize = setting.UI.IssuePagingNum
  531. }
  532. repoId := ctx.Repo.Repository.ID
  533. modelResult, count, err := models.QueryModelConvert(&models.AiModelQueryOptions{
  534. ListOptions: models.ListOptions{
  535. Page: page,
  536. PageSize: pageSize,
  537. },
  538. RepoID: repoId,
  539. })
  540. if err != nil {
  541. log.Info("query db error." + err.Error())
  542. ctx.ServerError("Cloudbrain", err)
  543. return
  544. }
  545. userIds := make([]int64, len(modelResult))
  546. for i, model := range modelResult {
  547. model.IsCanOper = isOper(ctx, model.UserId)
  548. model.IsCanDelete = isCanDelete(ctx, model.UserId)
  549. userIds[i] = model.UserId
  550. }
  551. userNameMap := queryUserName(userIds)
  552. for _, model := range modelResult {
  553. value := userNameMap[model.UserId]
  554. if value != nil {
  555. model.UserName = value.Name
  556. model.UserRelAvatarLink = value.RelAvatarLink()
  557. }
  558. }
  559. pager := context.NewPagination(int(count), page, pageSize, 5)
  560. ctx.Data["Page"] = pager
  561. ctx.Data["Tasks"] = modelResult
  562. }
  563. func ModelConvertDownloadModel(ctx *context.Context) {
  564. log.Info("enter here......")
  565. id := ctx.Params(":id")
  566. job, err := models.QueryModelConvertById(id)
  567. if err != nil {
  568. ctx.ServerError("Not found task.", err)
  569. return
  570. }
  571. AllDownload := ctx.QueryBool("AllDownload")
  572. if AllDownload {
  573. if job.IsGpuTrainTask() {
  574. path := setting.CBCodePathPrefix + job.ID + "/model/"
  575. allFile, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, path)
  576. if err == nil {
  577. returnFileName := job.Name + ".zip"
  578. MinioDownloadManyFile(path, ctx, returnFileName, allFile)
  579. } else {
  580. log.Info("error,msg=" + err.Error())
  581. ctx.ServerError("no file to download.", err)
  582. }
  583. } else {
  584. }
  585. } else {
  586. if job.IsGpuTrainTask() {
  587. parentDir := ctx.Query("parentDir")
  588. fileName := ctx.Query("fileName")
  589. jobName := ctx.Query("jobName")
  590. filePath := "jobs/" + jobName + "/model/" + parentDir
  591. url, err := storage.Attachments.PresignedGetURL(filePath, fileName)
  592. if err != nil {
  593. log.Error("PresignedGetURL failed: %v", err.Error(), ctx.Data["msgID"])
  594. ctx.ServerError("PresignedGetURL", err)
  595. return
  596. }
  597. //ctx.JSON(200, url)
  598. http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusTemporaryRedirect)
  599. } else {
  600. }
  601. }
  602. }