-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.py
1054 lines (945 loc) · 34.4 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
from flask import Flask, request, render_template, send_file
from flask_cors import CORS
from os import path as osp
import os
import json
import workspace_pb2 as w
from utils import CustomEncoder, ShareData, is_pic, get_logger, TaskStatus, get_ip
from dataset.utils import get_encoding
import numpy as np
import pickle
# 创建全局变量
app = Flask(__name__) # flask应用
CORS(app, supports_credentials=True) # 解除跨域访问限制
SESSION_TYPE = 'filesystem' # 设置flask-session会话机制
SD = ShareData()
@app.errorhandler(Exception)
def handle_exception(e):
ret = {"status": -1, 'message': repr(e)}
return ret
@app.route('/workspace', methods=['GET', 'PUT'])
def workspace():
"""
methods=='GET':获取工作目录中项目、数据集、任务的属性
Args:
struct(str):结构类型,可以是'dataset', 'project'或'task',
id(str):结构类型对应的id
attr_list(list):需要获取的属性的列表
Return:
attr(dict):key为属性,value为属性的值,
status
methods=='PUT':修改工作目录中项目、数据集、任务的属性
Args:
struct(str):结构类型,可以是'dataset', 'project'或'task',
id(str):结构类型对应的id
attr_dict(dict):key:需要修改的属性,value:需要修改属性的值
Return:
status
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
if data:
from workspace import get_attr
ret = get_attr(data, SD.workspace)
return ret
return {'status': 1, 'dirname': SD.workspace_dir}
if request.method == 'PUT':
from workspace import set_attr
ret = set_attr(data, SD.workspace)
return ret
@app.route('/dataset', methods=['GET', 'POST', 'PUT', 'DELETE'])
def dataset():
"""
methods=='GET':获取所有数据集或者单个数据集的信息
Args:
did(str, optional):数据集id(可选),如果存在就返回数据集id对应数据集的信息
Ruturn:
status
if 'did' in Args:
id(str):数据集id,
dataset_status(int):数据集状态(DatasetStatus)枚举变量的值
message(str):数据集状态信息
attr(dict):数据集属性
else:
datasets(list):所有数据集属性的列表
methods=='POST':创建一个新的数据集
Args:
name(str):数据集名字
desc(str):数据集描述
dataset_type(str):数据集类型,可以是['classification', 'detection', 'segmentation','instance_segmentation','remote_segmentation']
Return:
did(str):数据集id
status
methods=='PUT':异步,向数据集导入数据,支持分类、检测、语义分割、实例分割、摇杆分割数据集类型
Args:
did(str):数据集id
path(str):数据集路径
Return:
status
methods=='DELETE':删除已有的某个数据集
Args:
did(str):数据集id
Return:
status
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
if 'did' in data:
from dataset.dataset import get_dataset_status
ret = get_dataset_status(data, SD.workspace)
return ret
from dataset.dataset import list_datasets
ret = list_datasets(SD.workspace)
return ret
if request.method == 'POST':
from dataset.dataset import create_dataset
ret = create_dataset(data, SD.workspace)
return ret
if request.method == 'PUT':
from dataset.dataset import import_dataset
ret = import_dataset(data, SD.workspace, SD.monitored_processes,
SD.load_demo_proc_dict)
return ret
if request.method == 'DELETE':
from dataset.dataset import delete_dataset
ret = delete_dataset(data, SD.workspace)
return ret
@app.route('/dataset/details', methods=['GET'])
def dataset_details():
"""
methods=='GET':获取某个数据集的详细信息
Args:
did(str):数据集id
Return:
details(dict):数据集详细信息,
status
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
from dataset.dataset import get_dataset_details
ret = get_dataset_details(data, SD.workspace)
return ret
@app.route('/dataset/split', methods=['PUT'])
def dataset_split():
"""
Args:
did(str):数据集id
val_split(float): 验证集比例
test_split(float): 测试集比例
Return:
status
"""
try:
data = request.get_json()
except:
data = None
if request.method == 'PUT':
from dataset.dataset import split_dataset
ret = split_dataset(data, SD.workspace)
return ret
@app.route('/dataset/image', methods=['GET'])
def dataset_img_base64():
"""
Args:
GET: 获取图片base64数据,参数:'path' 图片绝对路径
"""
try:
data = request.get_json()
except:
data = None
if request.method == 'GET':
from dataset.dataset import img_base64
ret = img_base64(data)
return ret
@app.route('/dataset/file', methods=['GET'])
def get_image_file():
"""
Args:
GET: 获取文件数据,参数:'path' 文件绝对路径
"""
try:
data = request.get_json()
except:
data = None
if request.method == 'GET':
ret = data['path']
assert os.path.abspath(ret).startswith(
os.path.abspath(SD.workspace_dir)
) and ".." not in ret, "Illegal path {}.".format(ret)
return send_file(ret)
@app.route('/dataset/npy', methods=['GET'])
def get_npyfile():
"""
Args:
GET: 获取文件数据,参数:'path' npy文件绝对路径
"""
try:
data = request.get_json()
except:
data = None
if request.method == 'GET':
npy = np.load(data['path'], allow_pickle=True).tolist()
npy['gt_bbox'] = npy['gt_bbox'].tolist()
return npy
@app.route('/file', methods=['GET'])
def get_file():
"""
Args:
path'(str):文件在服务端的路径
Return:
#数据为图片
img_data(str): base64图片数据
status
#数据为xml文件
ret:数据流
#数据为log文件
ret:json数据
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
path = data['path']
if not os.path.exists(path):
return {'status': -1}
if is_pic(path):
from dataset.dataset import img_base64
ret = img_base64(data, SD.workspace)
return ret
file_type = path[(path.rfind('.') + 1):]
if file_type in ['xml', 'npy', 'log']:
return send_file(path)
else:
pass
@app.route('/project', methods=['GET', 'POST', 'DELETE'])
def project():
"""
methods=='GET':获取指定项目id的信息
Args:
'id'(str, optional):项目id,可选,如果存在就返回项目id对应项目的信息
Return:
status,
if 'id' in Args:
attr(dict):项目属性
else:
projects(list):所有项目属性
methods=='POST':创建一个项目
Args:
name(str): 项目名
desc(str):项目描述
project_type(str):项目类型
Return:
pid(str):项目id
status
methods=='DELETE':删除一个项目,以及项目相关的task
Args:
pid(str):项目id
Return:
status
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
from project.project import list_projects
from project.project import get_project
if 'id' in data:
ret = get_project(data, SD.workspace)
return ret
ret = list_projects(SD.workspace)
return ret
if request.method == 'POST':
from project.project import create_project
ret = create_project(data, SD.workspace)
return ret
if request.method == 'DELETE':
from project.project import delete_project
ret = delete_project(data, SD.workspace)
return ret
@app.route('/project/task', methods=['GET', 'POST', 'DELETE'])
def task():
"""
methods=='GET':#获取某个任务的信息或者所有任务的信息
Args:
tid(str, optional):任务id,可选,若存在即返回id对应任务的信息
resume(str, optional):获取是否可以恢复训练的状态,可选,需在存在tid的情况下才生效
pid(str, optional):项目id,可选,若存在即返回该项目id下所有任务信息
Return:
status
if 'tid' in Args:
task_status(int):任务状态(TaskStatus)枚举变量的值
message(str):任务状态信息
type:任务类型包括{'classification', 'detection', 'segmentation', 'instance_segmentation'}
resumable(bool):仅Args中存在resume时返回,任务训练是否可以恢复
max_saved_epochs(int):仅Args中存在resume时返回,当前训练模型保存的最大epoch
else:
tasks(list):所有任务属性
methods=='POST':#创建任务(训练或者裁剪)
Args:
pid(str):项目id
train(dict):训练参数
desc(str, optional):任务描述,可选
parent_id(str, optional):可选,若存在即表示新建的任务为裁剪任务,parent_id的值为裁剪任务对应的训练任务id
Return:
tid(str):任务id
status
methods=='DELETE':#删除任务
Args:
tid(str):任务id
Return:
status
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
if data:
if 'pid' not in data:
from project.task import get_task_status
ret = get_task_status(data, SD.workspace)
return ret
from project.task import list_tasks
ret = list_tasks(data, SD.workspace)
return ret
if request.method == 'POST':
from project.task import create_task
ret = create_task(data, SD.workspace)
return ret
if request.method == 'DELETE':
from project.task import delete_task
ret = delete_task(data, SD.workspace)
return ret
@app.route('/project/task/params', methods=['GET', 'POST'])
def task_params():
"""
methods=='GET':#获取任务id对应的参数,或者获取项目默认参数
Args:
tid(str, optional):获取任务对应的参数
pid(str,optional):获取项目对应的默认参数
model_type(str,optional):pid存在下有效,对应项目下获取指定模型的默认参数
gpu_list(list,optional):pid存在下有效,默认值为[0],使用指定的gpu并获取相应的默认参数
Return:
train(dict):训练或者裁剪的参数
status
methods=='POST':#设置任务参数,将前端用户设置训练参数dict保存在后端的pkl文件中
Args:
tid(str):任务id
train(dict):训练参数
Return:
status
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
if 'tid' in data:
from project.task import get_task_params
ret = get_task_params(data, SD.workspace)
ret['train'] = CustomEncoder().encode(ret['train'])
ret['train'] = json.loads(ret['train'])
return ret
if 'pid' in data:
from project.task import get_default_params
ret = get_default_params(data, SD.workspace, SD.machine_info)
return ret
if request.method == 'POST':
from project.task import set_task_params
ret = set_task_params(data, SD.workspace)
return ret
@app.route('/project/task/metrics', methods=['GET'])
def task_metrics():
"""
methods=='GET':#获取日志数据
Args:
tid(str):任务id
type(str):可以获取日志的类型,[train,eval,sensitivities,prune],包括训练,评估,敏感度与模型裁剪率关系图,裁剪的日志
Return:
status
if type == 'train':
train_log(dict): 训练日志
elif type == 'eval':
eval_metrics(dict): 评估结果
elif type == 'sensitivities':
sensitivities_loss_img(dict): 敏感度与模型裁剪率关系图
elif type == 'prune':
prune_log(dict):裁剪日志
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
if data['type'] == 'train':
from project.task import get_train_metrics
ret = get_train_metrics(data, SD.workspace)
return ret
if data['type'] == 'eval':
from project.task import get_eval_metrics
ret = get_eval_metrics(data, SD.workspace)
return ret
if data['type'] == 'eval_all':
from project.task import get_eval_all_metrics
ret = get_eval_all_metrics(data, SD.workspace)
return ret
if data['type'] == 'sensitivities':
from project.task import get_sensitivities_loss_img
ret = get_sensitivities_loss_img(data, SD.workspace)
return ret
if data['type'] == 'prune':
from project.task import get_prune_metrics
ret = get_prune_metrics(data, SD.workspace)
return ret
@app.route('/project/task/train', methods=['POST', 'PUT'])
def task_train():
"""
methods=='POST':#异步,启动训练或者裁剪任务
Args:
tid(str):任务id
eval_metric_loss(int,optional):可选,裁剪任务时可用,裁剪任务所需的评估loss
Return:
status
methods=='PUT':#改变任务训练的状态,即终止训练或者恢复训练
Args:
tid(str):任务id
act(str):[stop,resume]暂停或者恢复
epoch(int):(resume下可以设置)恢复训练的起始轮数
Return:
status
"""
try:
data = request.get_json()
except:
data = None
if request.method == 'POST':
from project.task import start_train_task
ret = start_train_task(data, SD.workspace, SD.monitored_processes)
return ret
if request.method == 'PUT':
if data['act'] == 'resume':
from project.task import resume_train_task
ret = resume_train_task(data, SD.workspace, SD.monitored_processes)
return ret
if data['act'] == 'stop':
from project.task import stop_train_task
ret = stop_train_task(data, SD.workspace)
return ret
@app.route('/project/task/train/file', methods=['GET'])
def log_file():
try:
data = request.get_json()
except:
data = None
if request.method == 'GET':
path = data['path']
if not os.path.exists(path):
return {'status': -1}
logs = open(path, encoding='utf-8').readlines()
if len(logs) < 50:
return {'status': 1, 'log': logs}
else:
logs = logs[-50:]
return {'status': 1, 'log': logs}
@app.route('/project/task/prune', methods=['GET', 'POST', 'PUT'])
def task_prune():
"""
methods=='GET':#获取裁剪任务的状态
Args:
tid(str):任务id
Return:
prune_status(int): 裁剪任务状态(PruneStatus)枚举变量的值
status
methods=='POST':#异步,创建一个裁剪分析,对于启动裁剪任务前需要先启动裁剪分析
Args:
tid(str):任务id
Return:
status
methods=='PUT':#改变裁剪分析任务的状态
Args:
tid(str):任务id
act(str):[stop],目前仅支持停止一个裁剪分析任务
Return
status
"""
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
from project.task import get_prune_status
ret = get_prune_status(data, SD.workspace)
return ret
if request.method == 'POST':
from project.task import start_prune_analysis
ret = start_prune_analysis(data, SD.workspace, SD.monitored_processes)
return ret
if request.method == 'PUT':
if data['act'] == 'stop':
from project.task import stop_prune_analysis
ret = stop_prune_analysis(data, SD.workspace)
return ret
@app.route('/project/task/evaluate', methods=['GET', 'POST'])
def task_evaluate():
'''
methods=='GET':#获取模型评估的结果
Args:
tid(str):任务id
Return:
evaluate_status(int): 任务状态(TaskStatus)枚举变量的值
message(str):描述评估任务的信息
result(dict):如果评估成功,返回评估结果的dict,否则为None
status
methods=='POST':#异步,创建一个评估任务
Args:
tid(str):任务id
epoch(int,optional):需要评估的epoch,如果为None则会评估训练时指标最好的epoch
topk(int,optional):分类任务topk指标,如果为None默认输入为5
score_thresh(float):检测任务类别的score threshhold值,如果为None默认输入为0.5
overlap_thresh(float):实例分割任务IOU threshhold值,如果为None默认输入为0.3
Return:
status
'''
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
from project.task import get_evaluate_result
ret = get_evaluate_result(data, SD.workspace)
if ret['evaluate_status'] == TaskStatus.XEVALUATED and ret[
'result'] is not None:
ret['result'] = CustomEncoder().encode(ret['result'])
ret['result'] = json.loads(ret['result'])
ret['evaluate_status'] = ret['evaluate_status'].value
return ret
if request.method == 'POST':
from project.task import evaluate_model
ret = evaluate_model(data, SD.workspace, SD.monitored_processes)
return ret
@app.route('/project/task/evaluate/file', methods=['GET'])
def task_evaluate_file():
try:
data = request.get_json()
except:
data = None
if request.method == 'GET':
if 'path' in data:
ret = data['path']
assert os.path.abspath(ret).startswith(
os.path.abspath(SD.workspace_dir)
) and ".." not in ret, "Illegal path {}.".format(ret)
return pickle.load(open(os.path.abspath(ret), 'rb'))
else:
from project.task import get_evaluate_result
from project.task import import_evaluate_excel
ret = get_evaluate_result(data, SD.workspace)
if ret['evaluate_status'] == TaskStatus.XEVALUATED and ret[
'result'] is not None:
result = ret['result']
excel_ret = dict()
excel_ret = import_evaluate_excel(data, result, SD.workspace)
return excel_ret
else:
excel_ret = dict()
excel_ret['path'] = None
excel_ret['status'] = -1
excel_ret['message'] = "评估尚未完成或评估失败"
return excel_ret
@app.route('/project/task/predict', methods=['GET', 'POST', 'PUT'])
def task_predict():
'''
methods=='GET':#获取预测状态
Args:
tid(str):任务id
Return:
predict_status(int): 预测任务状态(PredictStatus)枚举变量的值
message(str): 预测信息
status
methods=='POST':#创建预测任务,目前仅支持单张图片的预测
Args:
tid(str):任务id
image_data(str):base64编码的image数据
score_thresh(float,optional):可选,检测任务时有效,检测类别的score threashold值默认是0.5
epoch(int,float,optional):可选,选择需要做预测的ephoch,默认为评估指标最好的那一个epoch
Return:
path(str):服务器上保存预测结果图片的路径
status
'''
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
from project.task import get_predict_status
ret = get_predict_status(data, SD.workspace)
return ret
if request.method == 'POST':
from project.task import predict_test_pics
ret = predict_test_pics(data, SD.workspace, SD.monitored_processes)
if 'img_list' in data:
del ret['path']
return ret
return ret
if request.method == 'PUT':
from project.task import stop_predict_task
ret = stop_predict_task(data, SD.workspace)
return ret
@app.route('/project/task/export', methods=['GET', 'POST', 'PUT'])
def task_export():
'''
methods=='GET':#获取导出模型的状态
Args:
tid(str):任务id
quant(str,optional)可选,[log,result],导出量模型导出状态,若值为log则返回量化的日志;若值为result则返回量化的结果
Return:
status
if quant == 'log':
quant_log(dict):量化日志
if quant == 'result'
quant_result(dict):量化结果
if quant not in Args:
export_status(int):模型导出状态(PredictStatus)枚举变量的值
message(str):模型导出提示信息
methods=='POST':#导出inference模型或者导出lite模型
Args:
tid(str):任务id
type(str):保存模型的类别[infer,lite],支持inference模型导出和lite的模型导出
save_dir(str):保存模型的路径
epoch(str,optional)可选,指定导出的epoch数默认为评估效果最好的epoch
quant(bool,optional)可选,type为infer有效,是否导出量化后的模型,默认为False
model_path(str,optional)可选,type为lite时有效,inference模型的地址
Return:
status
if type == 'infer':
save_dir:模型保存路径
if type == 'lite':
message:模型保存信息
methods=='PUT':#停止导出模型
Args:
tid(str):任务id
Return:
export_status(int):模型导出状态(PredictStatus)枚举变量的值
message(str):停止模型导出提示信息
status
'''
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
if 'quant' in data:
if data['quant'] == 'log':
from project.task import get_quant_progress
ret = get_quant_progress(data, SD.workspace)
return ret
if data['quant'] == 'result':
from project.task import get_quant_result
ret = get_quant_result(data, SD.workspace)
return ret
from project.task import get_export_status
ret = get_export_status(data, SD.workspace)
ret['export_status'] = ret['export_status'].value
return ret
if request.method == 'POST':
if data['type'] == 'infer':
from project.task import export_infer_model
ret = export_infer_model(data, SD.workspace,
SD.monitored_processes)
return ret
if data['type'] == 'lite':
from project.task import export_lite_model
ret = export_lite_model(data, SD.workspace)
return ret
if request.method == 'PUT':
from project.task import stop_export_task
stop_export_task(data, SD.workspace)
return ret
@app.route('/project/task/vdl', methods=['GET'])
def task_vdl():
'''
methods=='GET':#打开某个任务的可视化分析工具(VisualDL)
Args:
tid(str):任务id
Return:
url(str):vdl地址
status
'''
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
from project.task import open_vdl
ret = open_vdl(data, SD.workspace, SD.current_port,
SD.monitored_processes, SD.running_boards)
return ret
@app.route('/system', methods=['GET', 'DELETE'])
def system():
'''
methods=='GET':#获取系统GPU、CPU信息
Args:
type(str):[machine_info,gpu_memory_size]选择需要获取的系统信息
Return:
status
if type=='machine_info'
info(dict):服务端信息
if type=='gpu_memory_size'
gpu_mem_infos(list):GPU内存信息
'''
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
if data['type'] == 'machine_info':
'''if 'path' not in data:
data['path'] = None
from .system import get_machine_info
ret = get_machine_info(data, SD.machine_info)'''
from system import get_system_info
ret = get_system_info(SD.machine_info)
return ret
if data['type'] == 'gpu_memory_size':
from system import get_gpu_memory_info
ret = get_gpu_memory_info(SD.machine_info)
return ret
if request.method == 'DELETE':
from system import exit_system
ret = exit_system(SD.monitored_processes)
return ret
@app.route('/demo', methods=['GET', 'POST', 'PUT'])
def demo():
'''
methods=='GET':#获取demo下载进度
Args:
prj_type(int):项目类型ProjectType枚举变量的int值
Return:
status
attr(dict):demo下载信息
methods=='POST':#下载或创建demo工程
Args:
type(str):{download,load}下载或者创建样例
prj_type(int):项目类型ProjectType枚举变量的int值
Return:
status
if type=='load':
did:数据集id
pid:项目id
methods=='PUT':#停止下载或创建demo工程
Args:
prj_type(int):项目类型ProjectType枚举变量的int值
Return:
status
'''
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
from demo import get_download_demo_progress
ret = get_download_demo_progress(data, SD.workspace)
return ret
if request.method == 'POST':
if data['type'] == 'download':
from demo import download_demo_dataset
ret = download_demo_dataset(data, SD.workspace,
SD.load_demo_proc_dict)
return ret
if data['type'] == 'load':
from demo import load_demo_project
ret = load_demo_project(data, SD.workspace, SD.monitored_processes,
SD.load_demo_proj_data_dict,
SD.load_demo_proc_dict)
return ret
if request.method == 'PUT':
from demo import stop_import_demo
ret = stop_import_demo(data, SD.workspace, SD.load_demo_proc_dict,
SD.load_demo_proj_data_dict)
return ret
@app.route('/model', methods=['GET', 'POST', 'DELETE'])
def model():
'''
methods=='GET':#获取一个或者所有模型的信息
Args:
mid(str,optional)可选,若存在则返回某个模型的信息
type(str,optional)可选,[pretrained,exported].若存在则返回对应类型下所有的模型信息
Return:
status
if mid in Args:
dataset_attr(dict):数据集属性
task_params(dict):模型训练参数
eval_result(dict):模型评估结果
if type in Args and type == 'pretrained':
pretrained_models(list):所有预训练模型信息
if type in Args and type == 'exported':
exported_models(list):所有inference模型的信息
methods=='POST':#创建一个模型
Args:
pid(str):项目id
tid(str):任务id
name(str):模型名字
type(str):创建模型的类型,[pretrained,exported],pretrained代表创建预训练模型、exported代表创建inference或者lite模型
source_path(str):仅type为pretrained时有效,训练好的模型的路径
path(str):仅type为exported时有效,inference或者lite模型的路径
exported_type(int):0为inference模型,1为lite模型
eval_results(dict,optional):可选,仅type为pretrained时有效,模型评估的指标
Return:
status
if type == 'pretrained':
pmid(str):预训练模型id
if type == 'exported':
emid(str):inference模型id
methods=='DELETE':删除一个模型
Args:
type(str):删除模型的类型,[pretrained,exported],pretrained代表创建预训练模型、exported代表创建inference或者lite模型
if type='pretrained':
pmid:预训练模型id
if type='exported':
emid:inference或者lite模型id
Return:
status
'''
try:
data = request.get_json()
except:
data = None
if data is None:
data = request.args
if request.method == 'GET':
if 'type' in data:
if data['type'] == 'pretrained':
from model import list_pretrained_models
ret = list_pretrained_models(SD.workspace)
return ret
if data['type'] == 'exported':
from model import list_exported_models
ret = list_exported_models(SD.workspace)
return ret
from model import get_model_details
ret = get_model_details(data, SD.workspace)
ret['eval_result'] = CustomEncoder().encode(ret['eval_result'])
ret['task_params'] = CustomEncoder().encode(ret['task_params'])
return ret
if request.method == 'POST':
if data['type'] == 'pretrained':
from model import create_pretrained_model
ret = create_pretrained_model(data, SD.workspace,
SD.monitored_processes)
return ret
if data['type'] == 'exported':
from model import create_exported_model
ret = create_exported_model(data, SD.workspace)
return ret
if request.method == 'DELETE':
if data['type'] == 'pretrained':
from model import delete_pretrained_model
ret = delete_pretrained_model(data, SD.workspace)
return ret
if data['type'] == 'exported':
from model import delete_exported_model
ret = delete_exported_model(data, SD.workspace)
return ret
@app.route('/model/file', methods=['GET'])
def model_file():
try:
data = request.get_json()
except:
data = None
if request.method == 'GET':
ret = data['path']
assert os.path.abspath(ret).startswith(
os.path.abspath(SD.workspace_dir)
) and ".." not in ret, "Illegal path {}.".format(ret)
return send_file(ret)
@app.route('/', methods=['GET'])
def gui():
if request.method == 'GET':
# 获取服务器默认IP地址
ip = get_ip()
url = 'http://' + ip + ':' + str(SD.port)