提交 4d401fc8 编写于 作者: W wjj19950828

fixed readme

...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
## 简介 ## 简介
X2Paddle是飞桨生态下的模型转换工具,致力于帮助其它深度学习框架用户快速迁移至飞桨框架。目前支持**推理模型的框架转换****PyTorch训练代码迁移**,我们还提供了详细的不同框架间API对比文档,降低开发者上手飞桨核心的学习成本。 X2Paddle是飞桨生态下的模型转换工具,致力于帮助其它深度学习框架用户快速迁移至飞桨框架。目前支持**推理模型的框架转换****PyTorch训练代码迁移**,我们还提供了详细的不同框架间API对比文档,降低开发者将模型迁移到飞桨的时间成本。
...@@ -22,7 +22,7 @@ X2Paddle是飞桨生态下的模型转换工具,致力于帮助其它深度学 ...@@ -22,7 +22,7 @@ X2Paddle是飞桨生态下的模型转换工具,致力于帮助其它深度学
- **支持的模型丰富** - **支持的模型丰富**
- 在主流的CV和NLP模型上均支持转换,涵盖了19+个Caffe预测模型转换、27+个TensorFlow预测模型转换、32+个ONNX预测模型转换、27+个PyTorch预测模型转换、2+个PyTorch训练项目转换,详见 ***[支持列表](./docs/introduction/x2paddle_model_zoo.md)*** - 在主流的CV和NLP模型上支持大部分模型转换,目前X2Paddle支持130+ PyTorch OP,90+ ONNX OP,90+ TensorFlow OP 以及 30+ Caffe OP,详见 ***[支持列表](./docs/inference_model_convertor/op_list.md)***
- **简洁易用** - **简洁易用**
......
# X2Paddle支持OP列表 # X2Paddle支持OP列表
> 目前X2Paddle支持90+的TensorFlow OP,30+的Caffe Layer,80+的ONNX OP,120+的PyTorch Aten,10+的PyTorch Prim覆盖了大部分CV分类模型常用的操作。我们在如下列表中给出了目前X2Paddle支持的全部OP。 > 目前X2Paddle支持90+ TensorFlow OP,30+ Caffe OP,90+ ONNX OP,130+ PyTorch OP,覆盖了大部分CV分类模型常用的操作。我们在如下列表中给出了目前X2Paddle支持的全部OP。
**注:** 目前,部分OP暂未支持,如您在转换过程中出现OP不支持的情况,可自行添加或反馈给我们。欢迎通过[ISSUE反馈](https://github.com/PaddlePaddle/X2Paddle/issues/new)的方式告知我们(模型名,代码实现或模型获取方式),我们会及时跟进:) **注:** 目前,部分OP暂未支持,如您在转换过程中出现OP不支持的情况,可自行添加或反馈给我们。欢迎通过[ISSUE反馈](https://github.com/PaddlePaddle/X2Paddle/issues/new)的方式告知我们(模型名,代码实现或模型获取方式),我们会及时跟进:)
......
...@@ -15,9 +15,6 @@ ...@@ -15,9 +15,6 @@
from auto_scan_test import OPConvertAutoScanTest from auto_scan_test import OPConvertAutoScanTest
from hypothesis import reproduce_failure from hypothesis import reproduce_failure
import hypothesis.strategies as st import hypothesis.strategies as st
import onnx
from onnx import helper
from onnx import TensorProto
import numpy as np import numpy as np
import unittest import unittest
......
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from auto_scan_test import OPConvertAutoScanTest
from hypothesis import reproduce_failure
import hypothesis.strategies as st
import numpy as np
import unittest
import random
class TestHardSigmoidCovert(OPConvertAutoScanTest):
"""
ONNX op: HardSigmoid
OPset version: 7~15
"""
def sample_convert_config(self, draw):
input_shape = draw(
st.lists(
st.integers(
min_value=2, max_value=6), min_size=2, max_size=5))
input_dtype = draw(st.sampled_from(["float32"]))
alpha = random.random()
beta = random.random()
config = {
"op_names": ["HardSigmoid"],
"test_data_shapes": [input_shape],
"test_data_types": [[input_dtype]],
"inputs_shape": [input_shape],
"min_opset_version": 7,
"inputs_name": ["x"],
"outputs_name": ["y"],
"delta": 1e-4,
"rtol": 1e-4
}
attrs = {
"alpha": alpha,
"beta": beta,
}
return (config, attrs)
def test(self):
self.run_and_statis(max_examples=30)
if __name__ == "__main__":
unittest.main()
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from auto_scan_test import OPConvertAutoScanTest
from hypothesis import reproduce_failure
import hypothesis.strategies as st
import numpy as np
import unittest
import random
class TestIsInfConvert(OPConvertAutoScanTest):
"""
ONNX op: IsInf
OPset version: 10~15
"""
def sample_convert_config(self, draw):
input_shape = draw(
st.lists(
st.integers(
min_value=20, max_value=30), min_size=3, max_size=5))
input_dtype = draw(st.sampled_from(["float32"]))
config = {
"op_names": ["IsInf"],
"test_data_shapes": [input_shape],
"test_data_types": [input_dtype],
"inputs_shape": [input_shape],
"min_opset_version": 10,
"max_opset_version": 15,
"inputs_name": ["x"],
"outputs_name": ["y"],
"delta": 1e-4,
"rtol": 1e-4,
"run_dynamic": True,
}
attrs = {}
return (config, attrs)
def test(self):
self.run_and_statis(max_examples=50)
if __name__ == "__main__":
unittest.main()
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from auto_scan_test import OPConvertAutoScanTest
from hypothesis import reproduce_failure
import hypothesis.strategies as st
import numpy as np
import unittest
import random
class TestIsNaNConcert(OPConvertAutoScanTest):
"""
ONNX op: IsNaN
OPset version: 9~15
"""
def sample_convert_config(self, draw):
input_shape = draw(
st.lists(
st.integers(
min_value=20, max_value=30), min_size=3, max_size=5))
input_dtype = draw(st.sampled_from(["float32"]))
config = {
"op_names": ["IsNaN", ],
"test_data_shapes": [input_shape],
"test_data_types": [input_dtype],
"inputs_shape": [input_shape],
"min_opset_version": 9,
"inputs_name": ["x"],
"outputs_name": ["y"],
"delta": 1e-4,
"rtol": 1e-4,
"run_dynamic": True,
}
attrs = {}
return (config, attrs)
def test(self):
self.run_and_statis(max_examples=50)
if __name__ == "__main__":
unittest.main()
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from auto_scan_test import OPConvertAutoScanTest
from hypothesis import reproduce_failure
import hypothesis.strategies as st
import numpy as np
import unittest
import random
class TestReduceOpsConvert(OPConvertAutoScanTest):
"""
ONNX op: Reduce Ops
OPset version: 7~15
"""
def sample_convert_config(self, draw):
input_shape = draw(
st.lists(
st.integers(
min_value=20, max_value=30), min_size=3, max_size=5))
input_dtype = draw(st.sampled_from(["float32", "int32", "int64"]))
axes = draw(
st.lists(
st.integers(
min_value=-len(input_shape), max_value=len(input_shape) -
1),
min_size=1,
max_size=1))
keep_dim = draw(st.integers(min_value=0, max_value=1))
config = {
"op_names": ["ReduceL1", "ReduceL2"],
"test_data_shapes": [input_shape],
"test_data_types": [input_dtype],
"inputs_shape": [input_shape],
"min_opset_version": 7,
"max_opset_version": 15,
"inputs_name": ["x"],
"outputs_name": ["y"],
"delta": 1e-4,
"rtol": 1e-4,
}
attrs = {
"axes": axes,
"keepdims": keep_dim,
}
return (config, attrs)
def test(self):
self.run_and_statis(max_examples=50)
if __name__ == "__main__":
unittest.main()
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from auto_scan_test import OPConvertAutoScanTest
from hypothesis import reproduce_failure
from onnxbase import randtool
import hypothesis.strategies as st
import numpy as np
import unittest
class TestSumConvert(OPConvertAutoScanTest):
"""
ONNX op: Sum
OPset version: 7
"""
def sample_convert_config(self, draw):
input1_shape = draw(
st.lists(
st.integers(
min_value=10, max_value=20), min_size=2, max_size=4))
input_dtype = draw(st.sampled_from(["float32"]))
config = {
"op_names": ["Sum"],
"test_data_shapes": [input1_shape, input1_shape],
"test_data_types": [[input_dtype], [input_dtype]],
"inputs_shape": [],
"min_opset_version": 7,
"max_opset_version": 7,
"inputs_name": ["x", "y"],
"outputs_name": ["z"],
"delta": 1e-4,
"rtol": 1e-4
}
attrs = {}
return (config, attrs)
def test(self):
self.run_and_statis(max_examples=30)
if __name__ == "__main__":
unittest.main()
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from auto_scan_test import OPConvertAutoScanTest
from hypothesis import reproduce_failure
from onnxbase import randtool
import hypothesis.strategies as st
import numpy as np
import unittest
class TestSumConvert(OPConvertAutoScanTest):
"""
ONNX op: Sum
OPset version: 8~15
"""
def sample_convert_config(self, draw):
input1_shape = draw(
st.lists(
st.integers(
min_value=10, max_value=20), min_size=2, max_size=4))
if draw(st.booleans()):
input2_shape = [input1_shape[-1]]
else:
input2_shape = input1_shape
def generator_data():
input_data = randtool("float", -5.0, 5.0, input2_shape)
input_data[abs(input_data) < 1.0] = 1.0
return input_data
input_dtype = draw(st.sampled_from(["float32"]))
config = {
"op_names": ["Sum"],
"test_data_shapes": [input1_shape, generator_data],
"test_data_types": [[input_dtype], [input_dtype]],
"inputs_shape": [],
"min_opset_version": 8,
"inputs_name": ["x", "y"],
"outputs_name": ["z"],
"delta": 1e-4,
"rtol": 1e-4
}
attrs = {}
return (config, attrs)
def test(self):
self.run_and_statis(max_examples=30)
if __name__ == "__main__":
unittest.main()
...@@ -112,3 +112,17 @@ class OpSet10(OpSet9): ...@@ -112,3 +112,17 @@ class OpSet10(OpSet9):
inputs={"x": val_x.name, inputs={"x": val_x.name,
"y": val_y.name}, "y": val_y.name},
outputs=[node.name]) outputs=[node.name])
@print_mapping_info
def IsInf(self, node):
val_x = self.graph.get_input_node(node, idx=0, copy=True)
if node.get_attr('detect_negative') != None or node.get_attr(
'detect_positive') != None:
if node.get_attr('detect_negative') != 1 or node.get_attr(
'detect_positive') != 1:
raise Exception(
"x2addle does not currently support IsINF with attributes 'detect_negative' and 'detect_positive'."
)
else:
self.paddle_graph.add_layer(
'paddle.isinf', inputs={"x": val_x.name}, outputs=[node.name])
...@@ -132,3 +132,69 @@ class OpSet7(OpSet): ...@@ -132,3 +132,69 @@ class OpSet7(OpSet):
inputs={"x": val_x.name}, inputs={"x": val_x.name},
axis=axes, axis=axes,
outputs=[node.name]) outputs=[node.name])
@print_mapping_info
def ReduceL1(self, node):
output_name = node.name
layer_outputs = [output_name]
val_x = self.graph.get_input_node(node, idx=0, copy=True)
axes = node.get_attr('axes')
keepdims = False if node.get_attr('keepdims') == 0 else True
layer_attrs = {'p': 1, 'axis': axes, 'keepdim': keepdims}
if val_x.dtype != 'float32' and val_x.dtype != 'float64':
indices_cast = val_x.name + '_cast'
mid_norm = val_x.name + '_norm'
self.paddle_graph.add_layer(
'paddle.cast',
inputs={"x": val_x.name},
outputs=[indices_cast],
dtype=string('float32'))
self.paddle_graph.add_layer(
"paddle.norm",
inputs={"x": indices_cast},
outputs=[mid_norm],
**layer_attrs)
self.paddle_graph.add_layer(
'paddle.cast',
inputs={"x": mid_norm},
outputs=[node.name],
dtype=string(val_x.dtype))
else:
self.paddle_graph.add_layer(
"paddle.norm",
inputs={"x": val_x.name},
outputs=layer_outputs,
**layer_attrs)
@print_mapping_info
def ReduceL2(self, node):
output_name = node.name
layer_outputs = [output_name]
val_x = self.graph.get_input_node(node, idx=0, copy=True)
axes = node.get_attr('axes')
keepdims = False if node.get_attr('keepdims') == 0 else True
layer_attrs = {'p': 2, 'axis': axes, 'keepdim': keepdims}
if val_x.dtype != 'float32' and val_x.dtype != 'float64':
indices_cast = val_x.name + '_cast'
mid_norm = val_x.name + '_norm'
self.paddle_graph.add_layer(
'paddle.cast',
inputs={"x": val_x.name},
outputs=[indices_cast],
dtype=string('float32'))
self.paddle_graph.add_layer(
"paddle.norm",
inputs={"x": indices_cast},
outputs=[mid_norm],
**layer_attrs)
self.paddle_graph.add_layer(
'paddle.cast',
inputs={"x": mid_norm},
outputs=[node.name],
dtype=string(val_x.dtype))
else:
self.paddle_graph.add_layer(
"paddle.norm",
inputs={"x": val_x.name},
outputs=layer_outputs,
**layer_attrs)
...@@ -32,3 +32,4 @@ def print_mapping_info(func): ...@@ -32,3 +32,4 @@ def print_mapping_info(func):
class OpSet9(OpSet8): class OpSet9(OpSet8):
def __init__(self, decoder, paddle_graph): def __init__(self, decoder, paddle_graph):
super(OpSet9, self).__init__(decoder, paddle_graph) super(OpSet9, self).__init__(decoder, paddle_graph)
self.directly_map_ops.update({'IsNaN': ['paddle.isnan'], })
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册