张小白带你玩转Atlas 200DK+CANN 5.0.4+MindStudio 3.0.4(九)ATC模型转换
九、MindStudio 3.0.4的模型转换
1、背景
在前文《 张小白带你玩转Atlas 200DK+CANN 5.0.4+MindStudio 3.0.4(四)MindStudio安装配置 》的《使用MindStudio打开resnet50_imagenet_classification样例工程》一节中,张小白为了生成200DK所需要的离线模型,是直接在运行环境200DK上用命令行完成了相关的转换功能:
在《 张小白带你玩转Atlas 200DK+CANN 5.0.4+MindStudio 3.0.4(五)OpenCV的安装 》的《使用MindStudio运行YoLoV3样例工程》一节中,也是如此。
但这件事情,其实在MindStudio上也是可以完成的。我们现在就来做一下尝试。
2、模型转换尝试1——resnet50的模型转换(不带AIPP的模型转换)
使用MindStudio打开 resnet50_imagenet_classification 样例工程:
我们建一个caffe_model的目录,将caffe模型的文件下载下来:
wget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/resnet50/resnet50.prototxt
wget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/resnet50/resnet50.caffemodel
打开Ascend菜单,点击Model Converter:
会弹出以下界面:
ModelFile选择以下内容:
系统自动弹出以下内容:
将Output Path打开,选择转换后的模型存放model目录:
当然这个时候跟原来的om重名了,我们可以改个名字:
改为:
点击Next:
这里我们暂时不需要AIPP,所以选择Next:
查看上面的预览窗口:
/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin/atc --input_shape="data:1,3,224,224" --weight="/home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/caffe_model/resnet50.caffemodel" --input_fp16_nodes="data" --check_report=/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/network_analysis.report --input_format=NCHW --output="/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/resnet50_zhanghui" --soc_version=Ascend310 --framework=0 --model="/home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/caffe_model/resnet50.prototxt"
提供的命令行命令参数:
atc --model=caffe_model/resnet50.prototxt --weight=caffe_model/resnet50.caffemodel --framework=0 --output=model/resnet50 --soc_version=Ascend310 --input_format=NCHW --input_fp16_nodes=data --output_type=FP32 --out_nodes=prob:0
好像缺少output_type和out_nodes两个参数。这个暂时不管(?)
再核对下,貌似output路径也不对,明明输入的是:
/home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/model
预览窗口却显示:
/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/resnet50_zhanghui
感觉先需要创建一下/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/ 这个目录。否则转换应该会报错:
我们点击Finish开始转换吧:
好像很快就转换完成了:
将转换日志贴出来看一下:
2022-04-15 16:05:08 Start to convert model
2022-04-15 16:05:08 export PATH=$PATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/ccec_compiler/bin:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin && export PYTHONPATH=$PYTHONPATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages/auto_tune.egg/auto_tune:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages/schedule_search.egg:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/opp/op_impl/built-in/ai_core/tbe && export LD_LIBRARY_PATH=/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/lib64:/usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64/driver:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/add-ons:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/acllib/lib64:$LD_LIBRARY_PATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/lib64/stub && export SLOG_PRINT_TO_STDOUT=1 && export ASCEND_OPP_PATH=/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/opp && /home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin/atc --input_shape="data:1,3,224,224" --weight="/home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/caffe_model/resnet50.caffemodel" --input_fp16_nodes="data" --check_report=/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/network_analysis.report --input_format=NCHW --output="/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/resnet50_zhanghui" --soc_version=Ascend310 --framework=0 --model="/home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/caffe_model/resnet50.prototxt"
2022-04-15 16:05:08 ATC start working now, please wait for a moment.
2022-04-15 16:05:23 ATC run success, welcome to the next use.
2022-04-15 16:05:24 Convert model environment variables:
2022-04-15 16:05:24 export PATH=$PATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/ccec_compiler/bin:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin && export PYTHONPATH=$PYTHONPATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages/auto_tune.egg/auto_tune:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages/schedule_search.egg:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/opp/op_impl/built-in/ai_core/tbe && export LD_LIBRARY_PATH=/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/lib64:/usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64/driver:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/add-ons:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/acllib/lib64:$LD_LIBRARY_PATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/lib64/stub && export SLOG_PRINT_TO_STDOUT=1 && export ASCEND_OPP_PATH=/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/opp
2022-04-15 16:05:24 Convert model command:
2022-04-15 16:05:24 /home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin/atc --input_shape="data:1,3,224,224" --weight="/home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/caffe_model/resnet50.caffemodel" --input_fp16_nodes="data" --check_report=/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/network_analysis.report --input_format=NCHW --output="/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/resnet50_zhanghui" --soc_version=Ascend310 --framework=0 --model="/home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/caffe_model/resnet50.prototxt"
2022-04-15 16:05:24 Model converted successfully.
2022-04-15 16:05:24 Model input path:/home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/caffe_model/resnet50.prototxt
2022-04-15 16:05:24 Model output path:/home/ascend/modelzoo/resnet50_zhanghui/Ascend310
2022-04-15 16:05:24 Model conversion log file path:/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/ModelConvert.txt
2022-04-15 16:05:24 Copy model file to destination folder /home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/model successfully.
2022-04-15 16:05:24 Model conversion config file path:/home/ascend/modelzoo/resnet50_zhanghui/Ascend310/resnet50_zhanghui_config.json
切换到 /home/ascend/modelzoo/resnet50_zhanghui/Ascend310/resnet50_zhanghui 目录,发现om文件在这里生成了。(希望MindStudio团队把这个改下吧,毕竟这样子转换找模型貌似不方便,都已经指定了说要到model目录,还给放到其他目录)
无奈,只好手动把这个模型结果拷贝回 /home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/model目录:
cp resnet50_zhanghui.om /home/ascend/tag/samples/cplusplus/level2_simple_inference/1_classification/resnet50_imagenet_classification/model/
再回到MindStudio页面:
既然这样,我们把sample_process.cpp中的模型文件改一下:
再重新编译:
运行:
对比前文(200DK模型转换)运行结果和现在(MindStudio模型转换)的运行结果:
推理结果是一模一样的。
张小白感觉,在200DK上运行atc,时间比较长,在MindStudio上运行Model Converter,却非常快,想必这个atc是在x86上运行的。
张小白在200DK上计算了一下模型转换的时间:
time atc --model=caffe_model/resnet50.prototxt --weight=caffe_model/resnet50.caffemodel --framework=0 --output=caffe_model/resnet50 --soc_version=Ascend310 --input_format=NCHW --input_fp16_nodes=data --output_type=FP32 --out_nodes=prob:0
基本上要花上3-4分钟左右才能完成模型转换。
3、模型转换尝试2——YoLoV3的模型转换(使用aipp.cfg配置文件)
好了,图片分类的样例试玩了,我们再看看复杂一点的带AIPP的YoLoV3的模型转换。
打开YoLoV3工程:
同样的建立caffe_model目录,并下载三个文件:
cd /home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model
wget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/Yolov3/yolov3.caffemodel
wget https://modelzoo-train-atc.obs.cn-north-4.myhuaweicloud.com/003_Atc_Models/AE/ATC%20Model/Yolov3/yolov3.prototxt
wget https://c7xcode.obs.cn-north-4.myhuaweicloud.com/models/YOLOV3_coco_detection_picture/aipp_nv12.cfg
由于YoLoV3的模型需要RGB输入,且模型需要416X416大小,所以带了个AIPP的配置文件.
我们同样的打开Model Converter页面,引入模型文件和权重文件:
同时改输出的模型名称:
输入这个不起作用的Output Path:
界面显示如下:
点击Next,打开Data Preprocessing:
这样不行,说所有的nodes都不支持AIPP,那应该怎么办呢?
点Previous回到前面的页面,将Type改为UINT8:
再点击Next,打开 Data Preprocessing:
我们打开Load AIPP Configuration:
并选择刚才下载的aipp_nv12.cfg文件:
结果变成了这个:
点击Next继续:
我们再对比下命令行方式跟 这个预览窗口的命令:
命令行:
atc --model=yolov3.prototxt --weight=yolov3.caffemodel --framework=0 --output=yolov3 --soc_version=Ascend310 --insert_op_conf=aipp_nv12.cfg
预览窗口:
/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin/atc --input_shape="data:1,3,416,416;img_info:1,4" --weight="/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.caffemodel" --check_report=/home/ascend/modelzoo/yolov3-zhanghui/Ascend310/network_analysis.report --input_format=NCHW --output="/home/ascend/modelzoo/yolov3-zhanghui/Ascend310/yolov3-zhanghui" --soc_version=Ascend310 --insert_op_conf=/home/ascend/modelzoo/yolov3-zhanghui/Ascend310/insert_op.cfg --framework=0 --model="/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.prototxt"
除了前面的output在modelzoo之外,好像还有其他的不太一样之处,比如输入的 aipp_nv12.cfg变成了 /home/ascend/modelzoo/yolov3-zhanghui/Ascend310/insert_op.cfg 还多了一个 --input_shape="data:1,3,416,416;img_info:1,4"
如果想关掉input Node(data),会告诉你不能选择UINT8 type:
经过几次尝试,只有将Input Nodes的data设为 FP16,将img_info设为UINT8
才能进入下面的页面:
这样再看看预览窗口:
比较预览的命令:
/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin/atc --input_shape="data:1,3,416,416;img_info:1,4" --weight="/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.caffemodel" --input_fp16_nodes="data" --check_report=/home/ascend/modelzoo/yolov3/Ascend310/network_analysis.report --input_format=NCHW --output="/home/ascend/modelzoo/yolov3/Ascend310/yolov3" --soc_version=Ascend310 --framework=0 --model="/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.prototxt"
命令行方式:
atc --model=yolov3.prototxt --weight=yolov3.caffemodel --framework=0 --output=yolov3 --soc_version=Ascend310 --insert_op_conf=aipp_nv12.cfg
貌似并没有用到aipp的cfg文件。
这么看来,只能采用 两个都改为UINT8的模式,才能正确选择 insert_op_conf
而据 @刘鹏程 老师说,这种情形是MindStudio重新生成了一个cfg文件。
那我们试一下吧:
点击Finish进行模型转换:
十几秒之后:
转换成功。MindStudio里面应该还是看不到,因为又跑到modelzoo目录下面去了:
我们把原来工程下的yolov3.om改个名字,然后将这个yoloV3.om拷贝过去:
cd ~/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/model
mv yolov3.om yolov3-200dk.om
cp ~/modelzoo/yolov3/Ascend310/yolov3.om .
因为这次我们是模型名称都没变,所以直接运行即可:
当然可以先删掉原来output目录下的图片:
然后运行推理:
点击Run:
耐心等待推理完毕:(这次运行的比较久,貌似是因为里面有1个caffee模型,两个om模型。。)
推理完毕,图片也生成了,打开看看:
好像不对了!
4、模型转换尝试3——YoLoV3的模型转换(使用附加参数方式调用aipp.cfg配置文件)
经过咨询 @刘鹏程 老师,暂时换一种方法做:
打开Model Converter页面:
在选择了modelfile之后,仅将data type改为UINT8,点击Next:
系统提示目录已经存在,选择replace:
第二页不打开,点击Next:
在第三页中,打开Additional Arguments:
并在下面录入AIPP的配置文件的参数:
--insert_op_conf=/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/aipp_nv12.cfg
此时需要点击TAB键,这时候,预览窗口会更新,增加这个参数(重要)
点击 Finish,系统开始模型转换:
十几秒之后转换完毕:
我们去终端将模型拷贝过来:
由于模型名称没变,我们直接运行即可:
推理成功。但是好像识别了5次狗。。。
打开结果图片,貌似确实如此。识别的结果都重叠了。
修改第一页的参数:
img_info改为1,1试试,同样第二页不选,跳到第三页,按上述方法填入AIPP参数文件名:
点击Finish进行模型转换:
将模型拷贝到model目录:
再重新运行推理:
好像结果是一样的。
这个结局并不完美。
5、模型转换尝试4——YoLoV3的模型转换(放弃aipp.cfg文件,使用Model Converter的Data Pre-Processing配置)
张小白心想,那就不读aipp.cfg文件,而是打开AIPP的配置,把配置做成跟aipp.cfg文件做成一样不就行了吗?
于是,张小白重新打开Model Converter:
选择两个INT8,这样才能打开下一页的AIPP:
在这一页,对比aipp.cfg文件,按照上面的方法录入Mean, Min和1/Variance参数:
尽管有好几个cfg文件的参数在 图形界面上找不到,但是死马当活马医,先这样Next下去吧:
点击Finish,开始模型转换:
把日志贴出来:
2022-04-15 19:27:08 insert op file content:
aipp_op {
related_input_rank : 0
src_image_size_w : 416
src_image_size_h : 416
crop : false
padding : false
input_format : YUV420SP_U8
aipp_mode: static
csc_switch : true
rbuv_swap_switch : false
matrix_r0c0 : 298
matrix_r0c1 : 0
matrix_r0c2 : 409
matrix_r1c0 : 298
matrix_r1c1 : -100
matrix_r1c2 : -208
matrix_r2c0 : 298
matrix_r2c1 : 516
matrix_r2c2 : 0
input_bias_0 : 16
input_bias_1 : 128
input_bias_2 : 128
mean_chn_0 : 0
mean_chn_1 : 0
mean_chn_2 : 0
min_chn_0 : 0.0
min_chn_1 : 0.0
min_chn_2 : 0.0
var_reci_chn_0 : 0.003921568627
var_reci_chn_1 : 0.003921568627
var_reci_chn_2 : 0.003921568627
}
2022-04-15 19:27:08 Start to convert model
2022-04-15 19:27:08 export PATH=$PATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/ccec_compiler/bin:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin && export PYTHONPATH=$PYTHONPATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages/auto_tune.egg/auto_tune:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages/schedule_search.egg:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/opp/op_impl/built-in/ai_core/tbe && export LD_LIBRARY_PATH=/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/lib64:/usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64/driver:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/add-ons:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/acllib/lib64:$LD_LIBRARY_PATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/lib64/stub && export SLOG_PRINT_TO_STDOUT=1 && export ASCEND_OPP_PATH=/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/opp && /home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin/atc --input_shape="data:1,3,416,416;img_info:1,4" --weight="/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.caffemodel" --check_report=/home/ascend/modelzoo/yolov3/Ascend310/network_analysis.report --input_format=NCHW --output="/home/ascend/modelzoo/yolov3/Ascend310/yolov3" --soc_version=Ascend310 --insert_op_conf=/home/ascend/modelzoo/yolov3/Ascend310/insert_op.cfg --framework=0 --model="/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.prototxt"
2022-04-15 19:27:08 ATC start working now, please wait for a moment.
2022-04-15 19:27:25 ATC run success, welcome to the next use.
2022-04-15 19:27:26 Convert model environment variables:
2022-04-15 19:27:26 export PATH=$PATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/ccec_compiler/bin:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin && export PYTHONPATH=$PYTHONPATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages/auto_tune.egg/auto_tune:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/python/site-packages/schedule_search.egg:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/opp/op_impl/built-in/ai_core/tbe && export LD_LIBRARY_PATH=/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/lib64:/usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64/driver:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/add-ons:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/acllib/lib64:$LD_LIBRARY_PATH:/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/lib64/stub && export SLOG_PRINT_TO_STDOUT=1 && export ASCEND_OPP_PATH=/home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/opp
2022-04-15 19:27:26 Convert model command:
2022-04-15 19:27:26 /home/ascend/Ascend/ascend-toolkit/5.0.4.alpha005/atc/bin/atc --input_shape="data:1,3,416,416;img_info:1,4" --weight="/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.caffemodel" --check_report=/home/ascend/modelzoo/yolov3/Ascend310/network_analysis.report --input_format=NCHW --output="/home/ascend/modelzoo/yolov3/Ascend310/yolov3" --soc_version=Ascend310 --insert_op_conf=/home/ascend/modelzoo/yolov3/Ascend310/insert_op.cfg --framework=0 --model="/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.prototxt"
2022-04-15 19:27:26 Model converted successfully.
2022-04-15 19:27:26 Model input path:/home/ascend/tag/samples/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_picture/caffe_model/yolov3.prototxt
2022-04-15 19:27:26 Model output path:/home/ascend/modelzoo/yolov3/Ascend310
2022-04-15 19:27:26 Aipp config file path:/home/ascend/modelzoo/yolov3/Ascend310/insert_op.cfg
2022-04-15 19:27:26 Model conversion log file path:/home/ascend/modelzoo/yolov3/Ascend310/ModelConvert.txt
2022-04-15 19:27:26 Model conversion config file path:/home/ascend/modelzoo/yolov3/Ascend310/yolov3_config.json
对比了一下,好像matrix开头的不一样,rbuv_swap_switch不一样,其他基本一样。
继续将模型拷贝到model目录下:
(这里可以看到张小白试了多少次了吧。。。)
那就开始试试运行一下,看看推理结果吧:
这次好像很有希望。
打开图片一看:
终于获得了跟 前文的200DK模型转换后的离线模型一样的结果了。
撒花,先休息吧。
(未完待续)
- 点赞
- 收藏
- 关注作者
评论(0)