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.

README_CN.md 12 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. # MindConverter教程
  2. [Switch to English version](./README.md)
  3. <!-- TOC -->
  4. - [MindConverter教程](#mindconverter教程)
  5. - [概述](#概述)
  6. - [安装](#安装)
  7. - [命令行用法](#命令行用法)
  8. - [使用场景](#使用场景)
  9. - [使用示例](#使用示例)
  10. - [基于AST的脚本转换示例](#基于ast的脚本转换示例)
  11. - [基于图结构的脚本生成示例](#基于图结构的脚本生成示例)
  12. - [注意事项](#注意事项)
  13. - [AST方案不支持场景](#ast方案不支持场景)
  14. - [场景1](#场景1)
  15. - [场景2](#场景2)
  16. <!-- /TOC -->
  17. ## 概述
  18. MindConverter是一款用于将PyTorch脚本转换到MindSpore脚本的工具。结合转换报告的信息,用户只需对转换后的脚本进行微小的改动,即可快速将PyTorch框架的模型迁移到MindSpore。
  19. ## 安装
  20. 此工具为MindInsight的子模块,安装MindInsight后,即可使用MindConverter,MindInsight安装请参考该[安装文档](https://www.mindspore.cn/install/)。
  21. ## 命令行用法
  22. ```buildoutcfg
  23. usage: mindconverter [-h] [--version] [--in_file IN_FILE]
  24. [--model_file MODEL_FILE] [--shape SHAPE]
  25. [--output OUTPUT] [--report REPORT]
  26. [--project_path PROJECT_PATH]
  27. optional arguments:
  28. -h, --help show this help message and exit
  29. --version show program version number and exit
  30. --in_file IN_FILE Specify path for script file to use AST schema to do
  31. script conversation.
  32. --model_file MODEL_FILE
  33. PyTorch .pth model file path to use graph based schema
  34. to do script generation. When `--in_file` and
  35. `--model_file` are both provided, use AST schema as
  36. default.
  37. --shape SHAPE Optional, expected input tensor shape of
  38. `--model_file`. It is required when use graph based
  39. schema. Usage: --shape 3,244,244
  40. --output OUTPUT Optional, specify path for converted script file
  41. directory. Default output directory is `output` folder
  42. in the current working directory.
  43. --report REPORT Optional, specify report directory. Default is
  44. converted script directory.
  45. --project_path PROJECT_PATH
  46. Optional, PyTorch scripts project path. If PyTorch
  47. project is not in PYTHONPATH, please assign
  48. `--project_path` when use graph based schema. Usage:
  49. --project_path ~/script_file/
  50. ```
  51. **MindConverter提供两种模型脚本迁移方案:**
  52. 1. **基于抽象语法树(Abstract syntax tree, AST)的脚本转换**:指定`--in_file`的值,将使用基于AST的脚本转换方案;
  53. 2. **基于图结构的脚本生成**:指定`--model_file`与`--shape`将使用基于图结构的脚本生成方案。
  54. > 若同时指定了`--in_file`,`--model_file`将默认使用AST方案进行脚本迁移。
  55. 当使用基于图结构的脚本生成方案时,要求必须指定`--shape`的值;当使用基于AST的脚本转换方案时,`--shape`会被忽略。
  56. 其中,`--output`与`--report`参数可省略。若省略,MindConverter将在当前工作目录(Working directory)下自动创建`output`目录,将生成的脚本、转换报告输出至该目录。
  57. 另外,当使用基于图结构的脚本生成方案时,请确保原PyTorch项目已在Python包搜索路径中,可通过CLI进入Python交互式命令行,通过import的方式判断是否已满足;若未加入,可通过`--project_path`命令手动将项目路径传入,以确保MindConverter可引用到原PyTorch脚本。
  58. > 假设用户项目目录为`/home/user/project/model_training`,用户可通过如下命令手动项目添加至包搜索路径中:`export PYTHONPATH=/home/user/project/model_training:$PYTHONPATH`
  59. > 此处MindConverter需要引用原PyTorch脚本,是因为PyTorch模型反向序列化过程中会引用原脚本。
  60. ## 使用场景
  61. MindConverter提供两种技术方案,以应对不同脚本迁移场景:
  62. 1. 用户希望迁移后脚本保持原有PyTorch脚本结构(包括变量、函数、类命名等与原脚本保持一致);
  63. 2. 用户希望迁移后脚本保持较高的转换率,尽量少的修改、甚至不需要修改,即可实现迁移后模型脚本的执行。
  64. 对于上述第一种场景,推荐用户使用基于AST的方案进行转换,AST方案通过对原PyTorch脚本的抽象语法树进行解析、编辑,将其替换为MindSpore的抽象语法树,再利用抽象语法树生成代码。理论上,AST方案支持任意模型脚本迁移,但语法树解析操作受原脚本用户编码风格影响,可能导致同一模型的不同脚本最终的转换率存在一定差异。
  65. 对于上述第二种场景,推荐用户使用基于图结构的脚本生成方案,计算图作为一种标准的模型描述语言,可以消除用户代码风格多样导致的脚本转换率不稳定的问题。在已支持算子的情况下,该方案可提供优于AST方案的转换率。
  66. 目前已基于典型图像分类网络(Resnet, VGG)对图结构的脚本转换方案进行测试。
  67. > 1. 基于图结构的脚本生成方案,目前仅支持单输入、单输出模型,对于多输入模型暂不支持;
  68. > 2. 基于图结构的脚本生成方案,由于要基于推理模式加载PyTorch模型,会导致转换后网络中Dropout算子丢失,需要用户手动补齐;
  69. > 3. 基于图结构的脚本生成方案持续优化中。
  70. 支持网络列表:
  71. | 支持网络 | PyTorch脚本 |
  72. | :----: | :----:|
  73. | ResNet18 | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/resnet.py) |
  74. | ResNet34 | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/resnet.py) |
  75. | ResNet50 | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/resnet.py) |
  76. | ResNet101 | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/resnet.py) |
  77. | VGG11/11BN | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/vgg.py) |
  78. | VGG13/13BN | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/vgg.py) |
  79. | VGG16/16BN | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/vgg.py) |
  80. | VGG19/19BN | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/vgg.py) |
  81. | AlexNet | [脚本链接](https://github.com/pytorch/vision/blob/v0.5.0/torchvision/models/alexnet.py) |
  82. ## 使用示例
  83. ### 基于AST的脚本转换示例
  84. 若用户希望使用基于AST的方案进行脚本迁移,假设原PyTorch脚本路径为`/home/user/model.py`,希望将脚本输出至`/home/user/output`,转换报告输出至`/home/user/output/report`,则脚本转换命令为:
  85. ```bash
  86. mindconverter --in_file /home/user/model.py \
  87. --output /home/user/output \
  88. --report /home/user/output/report
  89. ```
  90. 转换报告中,对于未转换的代码行形式为如下,其中x, y指明的是原PyTorch脚本中代码的行、列号。对于未成功转换的算子,可参考[MindSporeAPI映射查询功能](https://www.mindspore.cn/doc/note/zh-CN/master/index.html#operator_api) 手动对代码进行迁移。对于工具无法迁移的算子,会保留原脚本中的代码。
  91. ```text
  92. line x:y: [UnConvert] 'operator' didn't convert. ...
  93. ```
  94. 转换报告示例如下所示:
  95. ```text
  96. [Start Convert]
  97. [Insert] 'import mindspore.ops.operations as P' is inserted to the converted file.
  98. line 1:0: [Convert] 'import torch' is converted to 'import mindspore'.
  99. ...
  100. line 157:23: [UnConvert] 'nn.AdaptiveAvgPool2d' didn't convert. Maybe could convert to mindspore.ops.operations.ReduceMean.
  101. ...
  102. [Convert Over]
  103. ```
  104. 对于部分未成功转换的算子,报告中会提供修改建议,如`line 157:23`,MindConverter建议将`torch.nn.AdaptiveAvgPool2d`替换为`mindspore.ops.operations.ReduceMean`。
  105. ### 基于图结构的脚本生成示例
  106. 若用户已将PyTorch模型保存为.pth格式,假设模型绝对路径为`/home/user/model.pth`,该模型期望的输入样本shape为(3, 224, 224),原PyTorch脚本位于`/home/user/project/model_training`,希望将脚本输出至`/home/user/output`,转换报告输出至`/home/user/output/report`,则脚本生成命令为:
  107. ```bash
  108. mindconverter --model_file /home/user/model.pth --shape 3,224,224 \
  109. --output /home/user/output \
  110. --report /home/user/output/report \
  111. --project_path /home/user/project/model_training
  112. ```
  113. 执行该命令,MindSpore代码文件、转换报告生成至相应目录。
  114. 基于图结构的脚本生成方案产生的转换报告格式与AST方案相同。然而,由于基于图结构方案属于生成式方法,转换过程中未参考原PyTorch脚本,因此生成的转换报告中涉及的代码行、列号均指生成后脚本。
  115. 另外对于未成功转换的算子,在代码中会相应的标识该节点输入、输出Tensor的shape(以`input_shape`, `output_shape`标识),便于用户手动修改。以Reshape算子为例(暂不支持Reshape),将生成如下代码:
  116. ```python
  117. class Classifier(nn.Cell):
  118. def __init__(self):
  119. super(Classifier, self).__init__()
  120. ...
  121. self.reshape = onnx.Reshape(input_shape=(1, 1280, 1, 1),
  122. output_shape=(1, 1280))
  123. ...
  124. def construct(self, x):
  125. ...
  126. # Suppose input of `reshape` is x.
  127. reshape_output = self.reshape(x)
  128. ...
  129. ```
  130. 通过`input_shape`、`output_shape`参数,用户可以十分便捷地完成算子替换,替换结果如下:
  131. ```python
  132. from mindspore.ops import operations as P
  133. ...
  134. class Classifier(nn.Cell):
  135. def __init__(self):
  136. super(Classifier, self).__init__()
  137. ...
  138. self.reshape = P.Reshape(input_shape=(1, 1280, 1, 1),
  139. output_shape=(1, 1280))
  140. ...
  141. def construct(self, x):
  142. ...
  143. # Suppose input of `reshape` is x.
  144. reshape_output = self.reshape(x, (1, 1280))
  145. ...
  146. ```
  147. > 注意:其中`--output`与`--report`参数可省略,若省略,该命令将在当前工作目录(Working directory)下自动创建`output`目录,将生成的脚本、转换报告输出至该目录。
  148. ## 注意事项
  149. 1. PyTorch不作为MindInsight明确声明的依赖库。若想使用基于图结构的脚本生成工具,需要用户手动安装与生成PyTorch模型版本一致的PyTorch库(MindConverter推荐使用PyTorch 1.4.0或PyTorch 1.6.0进行脚本生成);
  150. 2. 脚本转换工具本质上为算子驱动,对于MindConverter未维护的PyTorch或ONNX算子与MindSpore算子映射,将会出现相应的算子无法转换的问题,对于该类算子,用户可手动修改,或基于MindConverter实现映射关系,向MindInsight仓库贡献。
  151. ## AST方案不支持场景
  152. ### 场景1
  153. 部分类和方法目前无法转换:
  154. * 使用```torch.Tensor```的```shape```,```ndim```和```dtype```成员
  155. * ```torch.nn.AdaptiveXXXPoolXd```和```torch.nn.functional.adaptive_XXX_poolXd()```
  156. * ```torch.nn.functional.Dropout```
  157. * ```torch.unsqueeze()```和```torch.Tensor.unsqueeze()```
  158. * ```torch.chunk()```和```torch.Tensor.chunk()```
  159. ### 场景2
  160. 继承的父类是nn.Module的子类。
  161. 例如:(如下代码片段摘自torchvision.models.mobilenet)
  162. ```python
  163. from torch import nn
  164. class ConvBNReLU(nn.Sequential):
  165. def __init__(self, in_planes, out_planes, kernel_size=3, stride=1, groups=1):
  166. padding = (kernel_size - 1) // 2
  167. super(ConvBNReLU, self).__init__(
  168. nn.Conv2d(in_planes, out_planes, kernel_size, stride, padding, groups=groups, bias=False),
  169. nn.BatchNorm2d(out_planes),
  170. nn.ReLU6(inplace=True)
  171. )
  172. ```