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_manage.go 38 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280
  1. package repo
  2. import (
  3. "archive/zip"
  4. "code.gitea.io/gitea/services/repository"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "net/http"
  9. "net/url"
  10. "path"
  11. "regexp"
  12. "strings"
  13. "code.gitea.io/gitea/models"
  14. "code.gitea.io/gitea/modules/context"
  15. "code.gitea.io/gitea/modules/log"
  16. "code.gitea.io/gitea/modules/notification"
  17. "code.gitea.io/gitea/modules/setting"
  18. "code.gitea.io/gitea/modules/storage"
  19. "code.gitea.io/gitea/services/cloudbrain/resource"
  20. uuid "github.com/satori/go.uuid"
  21. )
  22. const (
  23. Attachment_model = "model"
  24. Model_prefix = "aimodels/"
  25. tplModelManageIndex = "repo/modelmanage/index"
  26. tplModelManageDownload = "repo/modelmanage/download"
  27. tplModelInfo = "repo/modelmanage/showinfo"
  28. tplCreateLocalModelInfo = "repo/modelmanage/create_local_1"
  29. tplCreateLocalForUploadModelInfo = "repo/modelmanage/create_local_2"
  30. tplCreateOnlineModelInfo = "repo/modelmanage/create_online"
  31. MODEL_LATEST = 1
  32. MODEL_NOT_LATEST = 0
  33. MODEL_MAX_SIZE = 1024 * 1024 * 1024
  34. STATUS_COPY_MODEL = 1
  35. STATUS_FINISHED = 0
  36. STATUS_ERROR = 2
  37. MODEL_LOCAL_TYPE = 1
  38. MODEL_ONLINE_TYPE = 0
  39. )
  40. func saveModelByParameters(jobId string, versionName string, name string, version string, label string, description string, engine int, ctx *context.Context) (string, error) {
  41. aiTask, err := models.GetCloudbrainByJobIDAndVersionName(jobId, versionName)
  42. if err != nil {
  43. aiTask, err = models.GetRepoCloudBrainByJobID(ctx.Repo.Repository.ID, jobId)
  44. if err != nil {
  45. log.Info("query task error." + err.Error())
  46. return "", err
  47. } else {
  48. log.Info("query gpu train task.")
  49. }
  50. }
  51. uuid := uuid.NewV4()
  52. id := uuid.String()
  53. modelPath := id
  54. var lastNewModelId string
  55. var modelSize int64
  56. log.Info("find task name:" + aiTask.JobName)
  57. aimodels := models.QueryModelByName(name, aiTask.RepoID)
  58. if len(aimodels) > 0 {
  59. for _, model := range aimodels {
  60. if model.Version == version {
  61. return "", errors.New(ctx.Tr("repo.model.manage.create_error"))
  62. }
  63. if model.New == MODEL_LATEST {
  64. lastNewModelId = model.ID
  65. }
  66. }
  67. }
  68. cloudType := aiTask.Type
  69. modelSelectedFile := ctx.Query("modelSelectedFile")
  70. //download model zip //train type
  71. if aiTask.ComputeResource == models.NPUResource {
  72. cloudType = models.TypeCloudBrainTwo
  73. } else if aiTask.ComputeResource == models.GPUResource {
  74. cloudType = models.TypeCloudBrainOne
  75. }
  76. spec, err := resource.GetCloudbrainSpec(aiTask.ID)
  77. if err == nil {
  78. specJson, _ := json.Marshal(spec)
  79. aiTask.FlavorName = string(specJson)
  80. }
  81. accuracy := make(map[string]string)
  82. accuracy["F1"] = ""
  83. accuracy["Recall"] = ""
  84. accuracy["Accuracy"] = ""
  85. accuracy["Precision"] = ""
  86. accuracyJson, _ := json.Marshal(accuracy)
  87. log.Info("accuracyJson=" + string(accuracyJson))
  88. aiTask.ContainerIp = ""
  89. aiTaskJson, _ := json.Marshal(aiTask)
  90. model := &models.AiModelManage{
  91. ID: id,
  92. Version: version,
  93. VersionCount: len(aimodels) + 1,
  94. Label: label,
  95. Name: name,
  96. Description: description,
  97. New: MODEL_LATEST,
  98. Type: cloudType,
  99. Path: modelPath,
  100. Size: modelSize,
  101. AttachmentId: aiTask.Uuid,
  102. RepoId: aiTask.RepoID,
  103. UserId: ctx.User.ID,
  104. CodeBranch: aiTask.BranchName,
  105. CodeCommitID: aiTask.CommitID,
  106. Engine: int64(engine),
  107. TrainTaskInfo: string(aiTaskJson),
  108. Accuracy: string(accuracyJson),
  109. Status: STATUS_COPY_MODEL,
  110. }
  111. err = models.SaveModelToDb(model)
  112. if err != nil {
  113. return "", err
  114. }
  115. if modelSize > 0 {
  116. go repository.IncreaseRepoModelNum(aiTask.RepoID)
  117. }
  118. if len(lastNewModelId) > 0 {
  119. //udpate status and version count
  120. models.ModifyModelNewProperty(lastNewModelId, MODEL_NOT_LATEST, 0)
  121. }
  122. var units []models.RepoUnit
  123. var deleteUnitTypes []models.UnitType
  124. units = append(units, models.RepoUnit{
  125. RepoID: ctx.Repo.Repository.ID,
  126. Type: models.UnitTypeModelManage,
  127. Config: &models.ModelManageConfig{
  128. EnableModelManage: true,
  129. },
  130. })
  131. deleteUnitTypes = append(deleteUnitTypes, models.UnitTypeModelManage)
  132. models.UpdateRepositoryUnits(ctx.Repo.Repository, units, deleteUnitTypes)
  133. go asyncToCopyModel(aiTask, id, modelSelectedFile)
  134. log.Info("save model end.")
  135. notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, id, name, models.ActionCreateNewModelTask)
  136. return id, nil
  137. }
  138. func asyncToCopyModel(aiTask *models.Cloudbrain, id string, modelSelectedFile string) {
  139. if aiTask.ComputeResource == models.NPUResource {
  140. modelPath, modelSize, err := downloadModelFromCloudBrainTwo(id, aiTask.JobName, "", aiTask.TrainUrl, modelSelectedFile)
  141. if err != nil {
  142. updateStatus(id, 0, STATUS_ERROR, modelPath, err.Error())
  143. log.Info("download model from CloudBrainTwo faild." + err.Error())
  144. } else {
  145. updateStatus(id, modelSize, STATUS_FINISHED, modelPath, "")
  146. }
  147. } else if aiTask.ComputeResource == models.GPUResource {
  148. modelPath, modelSize, err := downloadModelFromCloudBrainOne(id, aiTask.JobName, "", aiTask.TrainUrl, modelSelectedFile)
  149. if err != nil {
  150. updateStatus(id, 0, STATUS_ERROR, modelPath, err.Error())
  151. log.Info("download model from CloudBrainOne faild." + err.Error())
  152. } else {
  153. updateStatus(id, modelSize, STATUS_FINISHED, modelPath, "")
  154. }
  155. }
  156. }
  157. func updateStatus(id string, modelSize int64, status int, modelPath string, statusDesc string) {
  158. if len(statusDesc) > 400 {
  159. statusDesc = statusDesc[0:400]
  160. }
  161. err := models.ModifyModelStatus(id, modelSize, status, modelPath, statusDesc)
  162. if err != nil {
  163. log.Info("update status error." + err.Error())
  164. }
  165. }
  166. func SaveNewNameModel(ctx *context.Context) {
  167. if !ctx.Repo.CanWrite(models.UnitTypeModelManage) {
  168. ctx.Error(403, ctx.Tr("repo.model_noright"))
  169. return
  170. }
  171. name := ctx.Query("name")
  172. if name == "" {
  173. ctx.Error(500, fmt.Sprintf("name or version is null."))
  174. return
  175. }
  176. aimodels := models.QueryModelByName(name, ctx.Repo.Repository.ID)
  177. if len(aimodels) > 0 {
  178. ctx.Error(500, ctx.Tr("repo.model_rename"))
  179. return
  180. }
  181. SaveModel(ctx)
  182. ctx.Status(200)
  183. log.Info("save model end.")
  184. }
  185. func SaveLocalModel(ctx *context.Context) {
  186. if !ctx.Repo.CanWrite(models.UnitTypeModelManage) {
  187. ctx.Error(403, ctx.Tr("repo.model_noright"))
  188. return
  189. }
  190. re := map[string]string{
  191. "code": "-1",
  192. }
  193. log.Info("save SaveLocalModel start.")
  194. uuid := uuid.NewV4()
  195. id := uuid.String()
  196. name := ctx.Query("name")
  197. version := ctx.Query("version")
  198. if version == "" {
  199. version = "0.0.1"
  200. }
  201. label := ctx.Query("label")
  202. description := ctx.Query("description")
  203. engine := ctx.QueryInt("engine")
  204. taskType := ctx.QueryInt("type")
  205. modelActualPath := ""
  206. if taskType == models.TypeCloudBrainOne {
  207. destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(id) + "/"
  208. modelActualPath = setting.Attachment.Minio.Bucket + "/" + destKeyNamePrefix
  209. } else if taskType == models.TypeCloudBrainTwo {
  210. destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(id) + "/"
  211. modelActualPath = setting.Bucket + "/" + destKeyNamePrefix
  212. } else {
  213. re["msg"] = "type is error."
  214. ctx.JSON(200, re)
  215. return
  216. }
  217. var lastNewModelId string
  218. repoId := ctx.Repo.Repository.ID
  219. aimodels := models.QueryModelByName(name, repoId)
  220. if len(aimodels) > 0 {
  221. for _, model := range aimodels {
  222. if model.Version == version {
  223. re["msg"] = ctx.Tr("repo.model.manage.create_error")
  224. ctx.JSON(200, re)
  225. return
  226. }
  227. if model.New == MODEL_LATEST {
  228. lastNewModelId = model.ID
  229. }
  230. }
  231. }
  232. model := &models.AiModelManage{
  233. ID: id,
  234. Version: version,
  235. ModelType: MODEL_LOCAL_TYPE,
  236. VersionCount: len(aimodels) + 1,
  237. Label: label,
  238. Name: name,
  239. Description: description,
  240. New: MODEL_LATEST,
  241. Type: taskType,
  242. Path: modelActualPath,
  243. Size: 0,
  244. AttachmentId: "",
  245. RepoId: repoId,
  246. UserId: ctx.User.ID,
  247. Engine: int64(engine),
  248. TrainTaskInfo: "",
  249. Accuracy: "",
  250. Status: STATUS_FINISHED,
  251. }
  252. err := models.SaveModelToDb(model)
  253. if err != nil {
  254. re["msg"] = err.Error()
  255. ctx.JSON(200, re)
  256. return
  257. }
  258. if len(lastNewModelId) > 0 {
  259. //udpate status and version count
  260. models.ModifyModelNewProperty(lastNewModelId, MODEL_NOT_LATEST, 0)
  261. }
  262. var units []models.RepoUnit
  263. var deleteUnitTypes []models.UnitType
  264. units = append(units, models.RepoUnit{
  265. RepoID: ctx.Repo.Repository.ID,
  266. Type: models.UnitTypeModelManage,
  267. Config: &models.ModelManageConfig{
  268. EnableModelManage: true,
  269. },
  270. })
  271. deleteUnitTypes = append(deleteUnitTypes, models.UnitTypeModelManage)
  272. models.UpdateRepositoryUnits(ctx.Repo.Repository, units, deleteUnitTypes)
  273. log.Info("save model end.")
  274. notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, id, name, models.ActionCreateNewModelTask)
  275. re["code"] = "0"
  276. re["id"] = id
  277. ctx.JSON(200, re)
  278. }
  279. func getSize(files []storage.FileInfo) int64 {
  280. var size int64
  281. for _, file := range files {
  282. size += file.Size
  283. }
  284. return size
  285. }
  286. func UpdateModelSize(modeluuid string) {
  287. model, err := models.QueryModelById(modeluuid)
  288. if err == nil {
  289. var size int64
  290. if model.Type == models.TypeCloudBrainOne {
  291. if strings.HasPrefix(model.Path, setting.Attachment.Minio.Bucket+"/"+Model_prefix) {
  292. files, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, model.Path[len(setting.Attachment.Minio.Bucket)+1:])
  293. if err != nil {
  294. log.Info("Failed to query model size from minio. id=" + modeluuid)
  295. }
  296. size = getSize(files)
  297. models.ModifyModelSize(modeluuid, size)
  298. }
  299. } else if model.Type == models.TypeCloudBrainTwo {
  300. if strings.HasPrefix(model.Path, setting.Bucket+"/"+Model_prefix) {
  301. files, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, model.Path[len(setting.Bucket)+1:])
  302. if err != nil {
  303. log.Info("Failed to query model size from obs. id=" + modeluuid)
  304. }
  305. size = getSize(files)
  306. models.ModifyModelSize(modeluuid, size)
  307. }
  308. }
  309. if model.Size == 0 && size > 0 {
  310. go repository.IncreaseRepoModelNum(model.RepoId)
  311. }
  312. } else {
  313. log.Info("not found model,uuid=" + modeluuid)
  314. }
  315. }
  316. func SaveModel(ctx *context.Context) {
  317. if !ctx.Repo.CanWrite(models.UnitTypeModelManage) {
  318. ctx.Error(403, ctx.Tr("repo.model_noright"))
  319. return
  320. }
  321. log.Info("save model start.")
  322. JobId := ctx.Query("jobId")
  323. VersionName := ctx.Query("versionName")
  324. name := ctx.Query("name")
  325. version := ctx.Query("version")
  326. label := ctx.Query("label")
  327. description := ctx.Query("description")
  328. engine := ctx.QueryInt("engine")
  329. modelSelectedFile := ctx.Query("modelSelectedFile")
  330. log.Info("engine=" + fmt.Sprint(engine) + " modelSelectedFile=" + modelSelectedFile)
  331. re := map[string]string{
  332. "code": "-1",
  333. }
  334. if JobId == "" || VersionName == "" {
  335. re["msg"] = "JobId or VersionName is null."
  336. ctx.JSON(200, re)
  337. return
  338. }
  339. if modelSelectedFile == "" {
  340. re["msg"] = "Not selected model file."
  341. ctx.JSON(200, re)
  342. return
  343. }
  344. if name == "" || version == "" {
  345. re["msg"] = "name or version is null."
  346. ctx.JSON(200, re)
  347. return
  348. }
  349. id, err := saveModelByParameters(JobId, VersionName, name, version, label, description, engine, ctx)
  350. if err != nil {
  351. log.Info("save model error." + err.Error())
  352. re["msg"] = err.Error()
  353. } else {
  354. re["code"] = "0"
  355. re["id"] = id
  356. }
  357. ctx.JSON(200, re)
  358. log.Info("save model end.")
  359. }
  360. func downloadModelFromCloudBrainTwo(modelUUID string, jobName string, parentDir string, trainUrl string, modelSelectedFile string) (string, int64, error) {
  361. objectkey := strings.TrimPrefix(path.Join(setting.TrainJobModelPath, jobName, setting.OutPutPath, parentDir), "/")
  362. if trainUrl != "" {
  363. objectkey = strings.Trim(trainUrl[len(setting.Bucket)+1:], "/")
  364. }
  365. prefix := objectkey + "/"
  366. filterFiles := strings.Split(modelSelectedFile, ";")
  367. Files := make([]string, 0)
  368. for _, shortFile := range filterFiles {
  369. Files = append(Files, prefix+shortFile)
  370. }
  371. totalSize := storage.ObsGetFilesSize(setting.Bucket, Files)
  372. if float64(totalSize) > setting.MaxModelSize*MODEL_MAX_SIZE {
  373. return "", 0, errors.New("Cannot create model, as model is exceed " + fmt.Sprint(setting.MaxModelSize) + "G.")
  374. }
  375. modelDbResult, err := storage.GetOneLevelAllObjectUnderDir(setting.Bucket, objectkey, "")
  376. log.Info("bucket=" + setting.Bucket + " objectkey=" + objectkey)
  377. if err != nil {
  378. log.Info("get TrainJobListModel failed:", err)
  379. return "", 0, err
  380. }
  381. if len(modelDbResult) == 0 {
  382. return "", 0, errors.New("Cannot create model, as model is empty.")
  383. }
  384. destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(modelUUID) + "/"
  385. size, err := storage.ObsCopyManyFile(setting.Bucket, prefix, setting.Bucket, destKeyNamePrefix, filterFiles)
  386. dataActualPath := setting.Bucket + "/" + destKeyNamePrefix
  387. return dataActualPath, size, nil
  388. }
  389. func downloadModelFromCloudBrainOne(modelUUID string, jobName string, parentDir string, trainUrl string, modelSelectedFile string) (string, int64, error) {
  390. modelActualPath := storage.GetMinioPath(jobName, "/model/")
  391. log.Info("modelActualPath=" + modelActualPath)
  392. modelSrcPrefix := setting.CBCodePathPrefix + jobName + "/model/"
  393. destKeyNamePrefix := Model_prefix + models.AttachmentRelativePath(modelUUID) + "/"
  394. bucketName := setting.Attachment.Minio.Bucket
  395. log.Info("destKeyNamePrefix=" + destKeyNamePrefix + " modelSrcPrefix=" + modelSrcPrefix + " bucket=" + bucketName)
  396. filterFiles := strings.Split(modelSelectedFile, ";")
  397. Files := make([]string, 0)
  398. for _, shortFile := range filterFiles {
  399. Files = append(Files, modelSrcPrefix+shortFile)
  400. }
  401. totalSize := storage.MinioGetFilesSize(bucketName, Files)
  402. if float64(totalSize) > setting.MaxModelSize*MODEL_MAX_SIZE {
  403. return "", 0, errors.New("Cannot create model, as model is exceed " + fmt.Sprint(setting.MaxModelSize) + "G.")
  404. }
  405. size, err := storage.MinioCopyFiles(bucketName, modelSrcPrefix, destKeyNamePrefix, filterFiles)
  406. if err == nil {
  407. dataActualPath := bucketName + "/" + destKeyNamePrefix
  408. return dataActualPath, size, nil
  409. } else {
  410. return "", 0, nil
  411. }
  412. }
  413. func DeleteModelFile(ctx *context.Context) {
  414. log.Info("delete model start.")
  415. id := ctx.Query("id")
  416. fileName := ctx.Query("fileName")
  417. model, err := models.QueryModelById(id)
  418. if err == nil {
  419. var totalSize int64
  420. if model.ModelType == MODEL_LOCAL_TYPE {
  421. if model.Type == models.TypeCloudBrainOne {
  422. bucketName := setting.Attachment.Minio.Bucket
  423. objectName := model.Path[len(bucketName)+1:] + fileName
  424. log.Info("delete bucket=" + bucketName + " path=" + objectName)
  425. if strings.HasPrefix(model.Path, bucketName+"/"+Model_prefix) {
  426. totalSize = storage.MinioGetFilesSize(bucketName, []string{objectName})
  427. err := storage.Attachments.DeleteDir(objectName)
  428. if err != nil {
  429. log.Info("Failed to delete model. id=" + id)
  430. re := map[string]string{
  431. "code": "-1",
  432. }
  433. re["msg"] = err.Error()
  434. ctx.JSON(200, re)
  435. return
  436. } else {
  437. log.Info("delete minio file size is:" + fmt.Sprint(totalSize))
  438. models.ModifyModelSize(id, model.Size-totalSize)
  439. }
  440. }
  441. } else if model.Type == models.TypeCloudBrainTwo {
  442. bucketName := setting.Bucket
  443. objectName := model.Path[len(setting.Bucket)+1:] + fileName
  444. log.Info("delete bucket=" + setting.Bucket + " path=" + objectName)
  445. if strings.HasPrefix(model.Path, bucketName+"/"+Model_prefix) {
  446. totalSize = storage.ObsGetFilesSize(bucketName, []string{objectName})
  447. err := storage.ObsRemoveObject(bucketName, objectName)
  448. if err != nil {
  449. log.Info("Failed to delete model. id=" + id)
  450. re := map[string]string{
  451. "code": "-1",
  452. }
  453. re["msg"] = err.Error()
  454. ctx.JSON(200, re)
  455. return
  456. } else {
  457. log.Info("delete obs file size is:" + fmt.Sprint(totalSize))
  458. models.ModifyModelSize(id, model.Size-totalSize)
  459. }
  460. }
  461. }
  462. }
  463. if (model.Size - totalSize) <= 0 {
  464. go repository.DecreaseRepoModelNum(model.RepoId)
  465. }
  466. }
  467. ctx.JSON(200, map[string]string{
  468. "code": "0",
  469. })
  470. }
  471. func DeleteModel(ctx *context.Context) {
  472. log.Info("delete model start.")
  473. id := ctx.Query("id")
  474. err := deleteModelByID(ctx, id)
  475. if err != nil {
  476. re := map[string]string{
  477. "code": "-1",
  478. }
  479. re["msg"] = err.Error()
  480. ctx.JSON(200, re)
  481. } else {
  482. ctx.JSON(200, map[string]string{
  483. "code": "0",
  484. })
  485. }
  486. }
  487. func deleteModelByID(ctx *context.Context, id string) error {
  488. log.Info("delete model start. id=" + id)
  489. model, err := models.QueryModelById(id)
  490. if !isCanDelete(ctx, model.UserId) {
  491. return errors.New(ctx.Tr("repo.model_noright"))
  492. }
  493. if err == nil {
  494. if model.Type == models.TypeCloudBrainOne {
  495. bucketName := setting.Attachment.Minio.Bucket
  496. log.Info("bucket=" + bucketName + " path=" + model.Path)
  497. if strings.HasPrefix(model.Path, bucketName+"/"+Model_prefix) {
  498. err := storage.Attachments.DeleteDir(model.Path[len(bucketName)+1:])
  499. if err != nil {
  500. log.Info("Failed to delete model. id=" + id)
  501. return err
  502. }
  503. }
  504. } else if model.Type == models.TypeCloudBrainTwo {
  505. log.Info("bucket=" + setting.Bucket + " path=" + model.Path)
  506. if strings.HasPrefix(model.Path, setting.Bucket+"/"+Model_prefix) {
  507. err := storage.ObsRemoveObject(setting.Bucket, model.Path[len(setting.Bucket)+1:])
  508. if err != nil {
  509. log.Info("Failed to delete model. id=" + id)
  510. return err
  511. }
  512. }
  513. }
  514. err = models.DeleteModelById(id)
  515. if err == nil { //find a model to change new
  516. aimodels := models.QueryModelByName(model.Name, model.RepoId)
  517. if model.New == MODEL_LATEST {
  518. if len(aimodels) > 0 {
  519. //udpate status and version count
  520. models.ModifyModelNewProperty(aimodels[0].ID, MODEL_LATEST, len(aimodels))
  521. }
  522. } else {
  523. for _, tmpModel := range aimodels {
  524. if tmpModel.New == MODEL_LATEST {
  525. models.ModifyModelNewProperty(tmpModel.ID, MODEL_LATEST, len(aimodels))
  526. break
  527. }
  528. }
  529. }
  530. if model.Size > 0 {
  531. go repository.DecreaseRepoModelNum(model.RepoId)
  532. }
  533. }
  534. }
  535. return err
  536. }
  537. func QueryModelByParameters(repoId int64, page int) ([]*models.AiModelManage, int64, error) {
  538. return models.QueryModel(&models.AiModelQueryOptions{
  539. ListOptions: models.ListOptions{
  540. Page: page,
  541. PageSize: setting.UI.IssuePagingNum,
  542. },
  543. RepoID: repoId,
  544. Type: -1,
  545. New: MODEL_LATEST,
  546. Status: -1,
  547. })
  548. }
  549. func DownloadMultiModelFile(ctx *context.Context) {
  550. log.Info("DownloadMultiModelFile start.")
  551. id := ctx.Query("id")
  552. log.Info("id=" + id)
  553. task, err := models.QueryModelById(id)
  554. if err != nil {
  555. log.Error("no such model!", err.Error())
  556. ctx.ServerError("no such model:", err)
  557. return
  558. }
  559. if !isOper(ctx, task.UserId) {
  560. ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
  561. return
  562. }
  563. path := Model_prefix + models.AttachmentRelativePath(id) + "/"
  564. if task.Type == models.TypeCloudBrainTwo {
  565. downloadFromCloudBrainTwo(path, task, ctx, id)
  566. } else if task.Type == models.TypeCloudBrainOne {
  567. downloadFromCloudBrainOne(path, task, ctx, id)
  568. }
  569. }
  570. func MinioDownloadManyFile(path string, ctx *context.Context, returnFileName string, allFile []storage.FileInfo) {
  571. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(returnFileName))
  572. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  573. w := zip.NewWriter(ctx.Resp)
  574. defer w.Close()
  575. for _, oneFile := range allFile {
  576. if oneFile.IsDir {
  577. log.Info("zip dir name:" + oneFile.FileName)
  578. } else {
  579. log.Info("zip file name:" + oneFile.FileName)
  580. fDest, err := w.Create(oneFile.FileName)
  581. if err != nil {
  582. log.Info("create zip entry error, download file failed: %s\n", err.Error())
  583. ctx.ServerError("download file failed:", err)
  584. return
  585. }
  586. log.Info("minio file path=" + (path + oneFile.FileName))
  587. body, err := storage.Attachments.DownloadAFile(setting.Attachment.Minio.Bucket, path+oneFile.FileName)
  588. if err != nil {
  589. log.Info("download file failed: %s\n", err.Error())
  590. ctx.ServerError("download file failed:", err)
  591. return
  592. } else {
  593. defer body.Close()
  594. p := make([]byte, 1024)
  595. var readErr error
  596. var readCount int
  597. // 读取对象内容
  598. for {
  599. readCount, readErr = body.Read(p)
  600. if readCount > 0 {
  601. fDest.Write(p[:readCount])
  602. }
  603. if readErr != nil {
  604. break
  605. }
  606. }
  607. }
  608. }
  609. }
  610. }
  611. func downloadFromCloudBrainOne(path string, task *models.AiModelManage, ctx *context.Context, id string) {
  612. allFile, err := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, path)
  613. if err == nil {
  614. //count++
  615. models.ModifyModelDownloadCount(id)
  616. returnFileName := task.Name + "_" + task.Version + ".zip"
  617. MinioDownloadManyFile(path, ctx, returnFileName, allFile)
  618. } else {
  619. log.Info("error,msg=" + err.Error())
  620. ctx.ServerError("no file to download.", err)
  621. }
  622. }
  623. func ObsDownloadManyFile(path string, ctx *context.Context, returnFileName string, allFile []storage.FileInfo) {
  624. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(returnFileName))
  625. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  626. w := zip.NewWriter(ctx.Resp)
  627. defer w.Close()
  628. for _, oneFile := range allFile {
  629. if oneFile.IsDir {
  630. log.Info("zip dir name:" + oneFile.FileName)
  631. } else {
  632. log.Info("zip file name:" + oneFile.FileName)
  633. fDest, err := w.Create(oneFile.FileName)
  634. if err != nil {
  635. log.Info("create zip entry error, download file failed: %s\n", err.Error())
  636. ctx.ServerError("download file failed:", err)
  637. return
  638. }
  639. body, err := storage.ObsDownloadAFile(setting.Bucket, path+oneFile.FileName)
  640. if err != nil {
  641. log.Info("download file failed: %s\n", err.Error())
  642. ctx.ServerError("download file failed:", err)
  643. return
  644. } else {
  645. defer body.Close()
  646. p := make([]byte, 1024)
  647. var readErr error
  648. var readCount int
  649. // 读取对象内容
  650. for {
  651. readCount, readErr = body.Read(p)
  652. if readCount > 0 {
  653. fDest.Write(p[:readCount])
  654. }
  655. if readErr != nil {
  656. break
  657. }
  658. }
  659. }
  660. }
  661. }
  662. }
  663. func downloadFromCloudBrainTwo(path string, task *models.AiModelManage, ctx *context.Context, id string) {
  664. allFile, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, path)
  665. if err == nil {
  666. //count++
  667. models.ModifyModelDownloadCount(id)
  668. returnFileName := task.Name + "_" + task.Version + ".zip"
  669. ObsDownloadManyFile(path, ctx, returnFileName, allFile)
  670. } else {
  671. log.Info("error,msg=" + err.Error())
  672. ctx.ServerError("no file to download.", err)
  673. }
  674. }
  675. func QueryTrainJobVersionList(ctx *context.Context) {
  676. log.Info("query train job version list. start.")
  677. JobID := ctx.Query("jobId")
  678. if JobID == "" {
  679. JobID = ctx.Query("JobId")
  680. }
  681. VersionListTasks, count, err := models.QueryModelTrainJobVersionList(JobID)
  682. log.Info("query return count=" + fmt.Sprint(count))
  683. if err != nil {
  684. ctx.ServerError("QueryTrainJobList:", err)
  685. } else {
  686. ctx.JSON(200, VersionListTasks)
  687. }
  688. }
  689. func QueryTrainJobList(ctx *context.Context) {
  690. log.Info("query train job list. start.")
  691. repoId := ctx.QueryInt64("repoId")
  692. VersionListTasks, count, err := models.QueryModelTrainJobList(repoId)
  693. log.Info("query return count=" + fmt.Sprint(count))
  694. if err != nil {
  695. ctx.ServerError("QueryTrainJobList:", err)
  696. } else {
  697. ctx.JSON(200, VersionListTasks)
  698. }
  699. }
  700. func QueryTrainModelFileById(ctx *context.Context) ([]storage.FileInfo, error) {
  701. JobID := ctx.Query("jobId")
  702. VersionListTasks, count, err := models.QueryModelTrainJobVersionList(JobID)
  703. if err == nil {
  704. if count == 1 {
  705. task := VersionListTasks[0]
  706. jobName := task.JobName
  707. taskType := task.Type
  708. VersionName := task.VersionName
  709. modelDbResult, err := getModelFromObjectSave(jobName, taskType, VersionName)
  710. return modelDbResult, err
  711. }
  712. }
  713. log.Info("get TypeCloudBrainTwo TrainJobListModel failed:", err)
  714. return nil, errors.New("Not found task.")
  715. }
  716. func getModelFromObjectSave(jobName string, taskType int, VersionName string) ([]storage.FileInfo, error) {
  717. if taskType == models.TypeCloudBrainTwo {
  718. objectkey := path.Join(setting.TrainJobModelPath, jobName, setting.OutPutPath, VersionName) + "/"
  719. modelDbResult, err := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, objectkey)
  720. log.Info("bucket=" + setting.Bucket + " objectkey=" + objectkey)
  721. if err != nil {
  722. log.Info("get TypeCloudBrainTwo TrainJobListModel failed:", err)
  723. return nil, err
  724. } else {
  725. return modelDbResult, nil
  726. }
  727. } else if taskType == models.TypeCloudBrainOne {
  728. modelSrcPrefix := setting.CBCodePathPrefix + jobName + "/model/"
  729. bucketName := setting.Attachment.Minio.Bucket
  730. modelDbResult, err := storage.GetAllObjectByBucketAndPrefixMinio(bucketName, modelSrcPrefix)
  731. if err != nil {
  732. log.Info("get TypeCloudBrainOne TrainJobListModel failed:", err)
  733. return nil, err
  734. } else {
  735. return modelDbResult, nil
  736. }
  737. }
  738. return nil, errors.New("Not support.")
  739. }
  740. func QueryTrainModelList(ctx *context.Context) {
  741. log.Info("query train job list. start.")
  742. jobName := ctx.Query("jobName")
  743. taskType := ctx.QueryInt("type")
  744. VersionName := ctx.Query("versionName")
  745. if VersionName == "" {
  746. VersionName = ctx.Query("VersionName")
  747. }
  748. modelDbResult, err := getModelFromObjectSave(jobName, taskType, VersionName)
  749. if err != nil {
  750. log.Info("get TypeCloudBrainTwo TrainJobListModel failed:", err)
  751. ctx.JSON(200, "")
  752. } else {
  753. ctx.JSON(200, modelDbResult)
  754. return
  755. }
  756. }
  757. func DownloadSingleModelFile(ctx *context.Context) {
  758. log.Info("DownloadSingleModelFile start.")
  759. id := ctx.Params(":ID")
  760. parentDir := ctx.Query("parentDir")
  761. fileName := ctx.Query("fileName")
  762. path := Model_prefix + models.AttachmentRelativePath(id) + "/" + parentDir + fileName
  763. task, err := models.QueryModelById(id)
  764. if err != nil {
  765. log.Error("no such model!", err.Error())
  766. ctx.ServerError("no such model:", err)
  767. return
  768. }
  769. if !isOper(ctx, task.UserId) {
  770. ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
  771. return
  772. }
  773. if task.Type == models.TypeCloudBrainTwo {
  774. if setting.PROXYURL != "" {
  775. body, err := storage.ObsDownloadAFile(setting.Bucket, path)
  776. if err != nil {
  777. log.Info("download error.")
  778. } else {
  779. //count++
  780. models.ModifyModelDownloadCount(id)
  781. defer body.Close()
  782. ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+fileName)
  783. ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
  784. p := make([]byte, 1024)
  785. var readErr error
  786. var readCount int
  787. // 读取对象内容
  788. for {
  789. readCount, readErr = body.Read(p)
  790. if readCount > 0 {
  791. ctx.Resp.Write(p[:readCount])
  792. //fmt.Printf("%s", p[:readCount])
  793. }
  794. if readErr != nil {
  795. break
  796. }
  797. }
  798. }
  799. } else {
  800. url, err := storage.GetObsCreateSignedUrlByBucketAndKey(setting.Bucket, path)
  801. if err != nil {
  802. log.Error("GetObsCreateSignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
  803. ctx.ServerError("GetObsCreateSignedUrl", err)
  804. return
  805. }
  806. //count++
  807. models.ModifyModelDownloadCount(id)
  808. http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
  809. }
  810. } else if task.Type == models.TypeCloudBrainOne {
  811. log.Info("start to down load minio file.")
  812. url, err := storage.Attachments.PresignedGetURL(path, fileName)
  813. if err != nil {
  814. log.Error("Get minio get SignedUrl failed: %v", err.Error(), ctx.Data["msgID"])
  815. ctx.ServerError("Get minio get SignedUrl failed", err)
  816. return
  817. }
  818. models.ModifyModelDownloadCount(id)
  819. http.Redirect(ctx.Resp, ctx.Req.Request, url, http.StatusMovedPermanently)
  820. }
  821. }
  822. func ShowModelInfo(ctx *context.Context) {
  823. ctx.Data["ID"] = ctx.Query("id")
  824. ctx.Data["name"] = ctx.Query("name")
  825. ctx.Data["isModelManage"] = true
  826. ctx.Data["ModelManageAccess"] = ctx.Repo.CanWrite(models.UnitTypeModelManage)
  827. ctx.HTML(200, tplModelInfo)
  828. }
  829. func QueryModelById(ctx *context.Context) {
  830. id := ctx.Query("id")
  831. model, err := models.QueryModelById(id)
  832. if err == nil {
  833. model.IsCanOper = isOper(ctx, model.UserId)
  834. model.IsCanDelete = isCanDelete(ctx, model.UserId)
  835. removeIpInfo(model)
  836. ctx.JSON(http.StatusOK, model)
  837. } else {
  838. ctx.JSON(http.StatusNotFound, nil)
  839. }
  840. }
  841. func ShowSingleModel(ctx *context.Context) {
  842. name := ctx.Query("name")
  843. log.Info("Show single ModelInfo start.name=" + name)
  844. models := models.QueryModelByName(name, ctx.Repo.Repository.ID)
  845. userIds := make([]int64, len(models))
  846. for i, model := range models {
  847. model.IsCanOper = isOper(ctx, model.UserId)
  848. model.IsCanDelete = isCanDelete(ctx, model.UserId)
  849. userIds[i] = model.UserId
  850. }
  851. userNameMap := queryUserName(userIds)
  852. for _, model := range models {
  853. removeIpInfo(model)
  854. value := userNameMap[model.UserId]
  855. if value != nil {
  856. model.UserName = value.Name
  857. model.UserRelAvatarLink = value.RelAvatarLink()
  858. }
  859. }
  860. ctx.JSON(http.StatusOK, models)
  861. }
  862. func removeIpInfo(model *models.AiModelManage) {
  863. reg, _ := regexp.Compile(`[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}`)
  864. taskInfo := model.TrainTaskInfo
  865. taskInfo = reg.ReplaceAllString(taskInfo, "")
  866. model.TrainTaskInfo = taskInfo
  867. }
  868. func queryUserName(intSlice []int64) map[int64]*models.User {
  869. keys := make(map[int64]string)
  870. uniqueElements := []int64{}
  871. for _, entry := range intSlice {
  872. if _, value := keys[entry]; !value {
  873. keys[entry] = ""
  874. uniqueElements = append(uniqueElements, entry)
  875. }
  876. }
  877. result := make(map[int64]*models.User)
  878. userLists, err := models.GetUsersByIDs(uniqueElements)
  879. if err == nil {
  880. for _, user := range userLists {
  881. result[user.ID] = user
  882. }
  883. }
  884. return result
  885. }
  886. func ShowOneVersionOtherModel(ctx *context.Context) {
  887. repoId := ctx.Repo.Repository.ID
  888. name := ctx.Query("name")
  889. aimodels := models.QueryModelByName(name, repoId)
  890. userIds := make([]int64, len(aimodels))
  891. for i, model := range aimodels {
  892. model.IsCanOper = isOper(ctx, model.UserId)
  893. model.IsCanDelete = isCanDelete(ctx, model.UserId)
  894. userIds[i] = model.UserId
  895. }
  896. userNameMap := queryUserName(userIds)
  897. for _, model := range aimodels {
  898. removeIpInfo(model)
  899. value := userNameMap[model.UserId]
  900. if value != nil {
  901. model.UserName = value.Name
  902. model.UserRelAvatarLink = value.RelAvatarLink()
  903. }
  904. }
  905. if len(aimodels) > 0 {
  906. ctx.JSON(200, aimodels[1:])
  907. } else {
  908. ctx.JSON(200, aimodels)
  909. }
  910. }
  911. func SetModelCount(ctx *context.Context) {
  912. repoId := ctx.Repo.Repository.ID
  913. Type := -1
  914. _, count, _ := models.QueryModel(&models.AiModelQueryOptions{
  915. ListOptions: models.ListOptions{
  916. Page: 1,
  917. PageSize: 2,
  918. },
  919. RepoID: repoId,
  920. Type: Type,
  921. New: MODEL_LATEST,
  922. Status: -1,
  923. })
  924. ctx.Data["MODEL_COUNT"] = count
  925. }
  926. func ShowModelTemplate(ctx *context.Context) {
  927. ctx.Data["isModelManage"] = true
  928. repoId := ctx.Repo.Repository.ID
  929. SetModelCount(ctx)
  930. ctx.Data["ModelManageAccess"] = ctx.Repo.CanWrite(models.UnitTypeModelManage)
  931. _, trainCount, _ := models.QueryModelTrainJobList(repoId)
  932. log.Info("query train count=" + fmt.Sprint(trainCount))
  933. ctx.Data["TRAIN_COUNT"] = trainCount
  934. ctx.HTML(200, tplModelManageIndex)
  935. }
  936. func isQueryRight(ctx *context.Context) bool {
  937. if ctx.Repo.Repository.IsPrivate {
  938. if ctx.Repo.CanRead(models.UnitTypeModelManage) || ctx.User.IsAdmin || ctx.Repo.IsAdmin() || ctx.Repo.IsOwner() {
  939. return true
  940. }
  941. return false
  942. } else {
  943. return true
  944. }
  945. }
  946. func isCanDelete(ctx *context.Context, modelUserId int64) bool {
  947. if ctx.User == nil {
  948. return false
  949. }
  950. if ctx.User.IsAdmin || ctx.User.ID == modelUserId {
  951. return true
  952. }
  953. if ctx.Repo.IsOwner() {
  954. return true
  955. }
  956. return false
  957. }
  958. func isOper(ctx *context.Context, modelUserId int64) bool {
  959. if ctx.User == nil {
  960. return false
  961. }
  962. if ctx.User.IsAdmin || ctx.User.ID == modelUserId {
  963. return true
  964. }
  965. return false
  966. }
  967. func ShowModelPageInfo(ctx *context.Context) {
  968. log.Info("ShowModelInfo start.")
  969. if !isQueryRight(ctx) {
  970. ctx.NotFound(ctx.Req.URL.RequestURI(), nil)
  971. return
  972. }
  973. page := ctx.QueryInt("page")
  974. if page <= 0 {
  975. page = 1
  976. }
  977. pageSize := ctx.QueryInt("pageSize")
  978. if pageSize <= 0 {
  979. pageSize = setting.UI.IssuePagingNum
  980. }
  981. repoId := ctx.Repo.Repository.ID
  982. Type := -1
  983. modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{
  984. ListOptions: models.ListOptions{
  985. Page: page,
  986. PageSize: pageSize,
  987. },
  988. RepoID: repoId,
  989. Type: Type,
  990. New: MODEL_LATEST,
  991. Status: -1,
  992. })
  993. if err != nil {
  994. ctx.ServerError("Cloudbrain", err)
  995. return
  996. }
  997. userIds := make([]int64, len(modelResult))
  998. for i, model := range modelResult {
  999. model.IsCanOper = isOper(ctx, model.UserId)
  1000. model.IsCanDelete = isCanDelete(ctx, model.UserId)
  1001. userIds[i] = model.UserId
  1002. }
  1003. userNameMap := queryUserName(userIds)
  1004. for _, model := range modelResult {
  1005. removeIpInfo(model)
  1006. value := userNameMap[model.UserId]
  1007. if value != nil {
  1008. model.UserName = value.Name
  1009. model.UserRelAvatarLink = value.RelAvatarLink()
  1010. }
  1011. }
  1012. mapInterface := make(map[string]interface{})
  1013. mapInterface["data"] = modelResult
  1014. mapInterface["count"] = count
  1015. ctx.JSON(http.StatusOK, mapInterface)
  1016. }
  1017. func ModifyModel(id string, description string) error {
  1018. err := models.ModifyModelDescription(id, description)
  1019. if err == nil {
  1020. log.Info("modify success.")
  1021. } else {
  1022. log.Info("Failed to modify.id=" + id + " desc=" + description + " error:" + err.Error())
  1023. }
  1024. return err
  1025. }
  1026. func ModifyModelInfo(ctx *context.Context) {
  1027. log.Info("modify model start.")
  1028. id := ctx.Query("id")
  1029. re := map[string]string{
  1030. "code": "-1",
  1031. }
  1032. task, err := models.QueryModelById(id)
  1033. if err != nil {
  1034. re["msg"] = err.Error()
  1035. log.Error("no such model!", err.Error())
  1036. ctx.JSON(200, re)
  1037. return
  1038. }
  1039. if !isOper(ctx, task.UserId) {
  1040. re["msg"] = "No right to operation."
  1041. ctx.JSON(200, re)
  1042. return
  1043. }
  1044. if task.ModelType == MODEL_LOCAL_TYPE {
  1045. name := ctx.Query("name")
  1046. label := ctx.Query("label")
  1047. description := ctx.Query("description")
  1048. engine := ctx.QueryInt("engine")
  1049. aimodels := models.QueryModelByName(name, task.RepoId)
  1050. if aimodels != nil && len(aimodels) > 0 {
  1051. if len(aimodels) == 1 {
  1052. if aimodels[0].ID != task.ID {
  1053. re["msg"] = ctx.Tr("repo.model.manage.create_error")
  1054. ctx.JSON(200, re)
  1055. return
  1056. }
  1057. } else {
  1058. re["msg"] = ctx.Tr("repo.model.manage.create_error")
  1059. ctx.JSON(200, re)
  1060. return
  1061. }
  1062. }
  1063. err = models.ModifyLocalModel(id, name, label, description, engine)
  1064. } else {
  1065. label := ctx.Query("label")
  1066. description := ctx.Query("description")
  1067. engine := task.Engine
  1068. name := task.Name
  1069. err = models.ModifyLocalModel(id, name, label, description, int(engine))
  1070. }
  1071. if err != nil {
  1072. re["msg"] = err.Error()
  1073. ctx.JSON(200, re)
  1074. return
  1075. } else {
  1076. re["code"] = "0"
  1077. ctx.JSON(200, re)
  1078. }
  1079. }
  1080. func QueryModelListForPredict(ctx *context.Context) {
  1081. repoId := ctx.Repo.Repository.ID
  1082. modelResult, count, err := models.QueryModel(&models.AiModelQueryOptions{
  1083. ListOptions: models.ListOptions{
  1084. Page: -1,
  1085. PageSize: -1,
  1086. },
  1087. RepoID: repoId,
  1088. Type: ctx.QueryInt("type"),
  1089. New: -1,
  1090. Status: 0,
  1091. })
  1092. if err != nil {
  1093. ctx.ServerError("Cloudbrain", err)
  1094. return
  1095. }
  1096. log.Info("query return count=" + fmt.Sprint(count))
  1097. nameList := make([]string, 0)
  1098. nameMap := make(map[string][]*models.AiModelManage)
  1099. for _, model := range modelResult {
  1100. removeIpInfo(model)
  1101. if _, value := nameMap[model.Name]; !value {
  1102. models := make([]*models.AiModelManage, 0)
  1103. models = append(models, model)
  1104. nameMap[model.Name] = models
  1105. nameList = append(nameList, model.Name)
  1106. } else {
  1107. nameMap[model.Name] = append(nameMap[model.Name], model)
  1108. }
  1109. }
  1110. mapInterface := make(map[string]interface{})
  1111. mapInterface["nameList"] = nameList
  1112. mapInterface["nameMap"] = nameMap
  1113. ctx.JSON(http.StatusOK, mapInterface)
  1114. }
  1115. func QueryModelFileForPredict(ctx *context.Context) {
  1116. id := ctx.Query("id")
  1117. if id == "" {
  1118. id = ctx.Query("ID")
  1119. }
  1120. ctx.JSON(http.StatusOK, QueryModelFileByID(id))
  1121. }
  1122. func QueryModelFileByID(id string) []storage.FileInfo {
  1123. model, err := models.QueryModelById(id)
  1124. if err == nil {
  1125. if model.Type == models.TypeCloudBrainTwo {
  1126. prefix := model.Path[len(setting.Bucket)+1:]
  1127. fileinfos, _ := storage.GetAllObjectByBucketAndPrefix(setting.Bucket, prefix)
  1128. return fileinfos
  1129. } else if model.Type == models.TypeCloudBrainOne {
  1130. prefix := model.Path[len(setting.Attachment.Minio.Bucket)+1:]
  1131. fileinfos, _ := storage.GetAllObjectByBucketAndPrefixMinio(setting.Attachment.Minio.Bucket, prefix)
  1132. return fileinfos
  1133. }
  1134. } else {
  1135. log.Error("no such model!", err.Error())
  1136. }
  1137. return nil
  1138. }
  1139. func QueryOneLevelModelFile(ctx *context.Context) {
  1140. id := ctx.Query("id")
  1141. if id == "" {
  1142. id = ctx.Query("ID")
  1143. }
  1144. parentDir := ctx.Query("parentDir")
  1145. model, err := models.QueryModelById(id)
  1146. if err != nil {
  1147. log.Error("no such model!", err.Error())
  1148. ctx.ServerError("no such model:", err)
  1149. return
  1150. }
  1151. if model.Type == models.TypeCloudBrainTwo {
  1152. log.Info("TypeCloudBrainTwo list model file.")
  1153. prefix := model.Path[len(setting.Bucket)+1:]
  1154. fileinfos, _ := storage.GetOneLevelAllObjectUnderDir(setting.Bucket, prefix, parentDir)
  1155. if fileinfos == nil {
  1156. fileinfos = make([]storage.FileInfo, 0)
  1157. }
  1158. ctx.JSON(http.StatusOK, fileinfos)
  1159. } else if model.Type == models.TypeCloudBrainOne {
  1160. log.Info("TypeCloudBrainOne list model file.")
  1161. prefix := model.Path[len(setting.Attachment.Minio.Bucket)+1:]
  1162. fileinfos, _ := storage.GetOneLevelAllObjectUnderDirMinio(setting.Attachment.Minio.Bucket, prefix, parentDir)
  1163. if fileinfos == nil {
  1164. fileinfos = make([]storage.FileInfo, 0)
  1165. }
  1166. ctx.JSON(http.StatusOK, fileinfos)
  1167. }
  1168. }
  1169. func CreateLocalModel(ctx *context.Context) {
  1170. ctx.Data["isModelManage"] = true
  1171. ctx.Data["ModelManageAccess"] = ctx.Repo.CanWrite(models.UnitTypeModelManage)
  1172. ctx.HTML(200, tplCreateLocalModelInfo)
  1173. }
  1174. func CreateLocalModelForUpload(ctx *context.Context) {
  1175. ctx.Data["uuid"] = ctx.Query("uuid")
  1176. ctx.Data["isModelManage"] = true
  1177. ctx.Data["ModelManageAccess"] = ctx.Repo.CanWrite(models.UnitTypeModelManage)
  1178. ctx.Data["max_model_size"] = setting.MaxModelSize * MODEL_MAX_SIZE
  1179. ctx.HTML(200, tplCreateLocalForUploadModelInfo)
  1180. }
  1181. func CreateOnlineModel(ctx *context.Context) {
  1182. ctx.Data["isModelManage"] = true
  1183. ctx.Data["ModelManageAccess"] = ctx.Repo.CanWrite(models.UnitTypeModelManage)
  1184. ctx.HTML(200, tplCreateOnlineModelInfo)
  1185. }