| @@ -1,63 +1,82 @@ | |||
| # PyLite | |||
| Lite的python接口提供更加方便灵活的使用Lite进行模型Inference,支持各种平台上运行,X86-CUDA,X86-CPU,Arm-CPU,Arm-CUDA平台。 | |||
| Lite 的 python 接口提供更加方便灵活的使用 Lite 进行模型 Inference,满足如下条件的环境都可以使用: | |||
| * OS 可以安装 [Python3](https://www.python.org/downloads/) | |||
| * [BUILD_README](../../scripts/cmake-build/BUILD_README.md) 中支持推理编译的平台 | |||
| ## 安装 | |||
| ### whl包安装 | |||
| Lite python接口的whl包会随着megbrain的发版发布,版本号和megbrain保持一致,目前发布的Lite的whl包,包括Linux、windows、macos平台,这些平台可以直接通过pip3安装。 | |||
| ### whl 包安装 | |||
| 目前预编译发布的 Lite 的 whl 包详情如下: | |||
| * 提供 Linux-x64(with CUDA)、windows-x64(with CUDA)、macos-x64(cpu only) 平台预编译包 | |||
| * 可以直接通过 pip3 安装。其他 OS-ARCH 的包,如有需要,可以 build from src 参考 [BUILD_README](../../scripts/cmake-build/BUILD_README.md) | |||
| * 预编译包的构建流程可以参考 [BUILD_PYTHON_WHL_README.md](../../scripts/whl/BUILD_PYTHON_WHL_README.md) | |||
| 开源版本: 预编译的包会随着 MegEngine 的发版发布,版本号和 MegEngine 保持一致,安装方式: | |||
| ```shell | |||
| python3 -m pip install --upgrade pip | |||
| python3 -m pip install megenginelite -i https://pypi.megvii-inc.com/simple | |||
| python3 -m pip install --upgrade pip | |||
| python3 -m pip install megengine -f https://megengine.org.cn/whl/mge.html | |||
| ``` | |||
| ### develop 安装 | |||
| 开发模式下,可以使用Cmake编译出lite动态库liblite.so/liblite.dll/liblite_shared.dylib,并使用这个动态库进行开发和debug。该方式安装的pylite只能在本地机器上使用,不能copy到其他机器上使用。 | |||
| * 编译liblite.so。使用cmake编译出liblite.so | |||
| * clone megbrain工程到本地 | |||
| 安装后, 就可以通过 import megenginelite 进行使用了 | |||
| ### develop 调试 | |||
| 开发模式下,可以使用 Cmake 编译出 lite 动态库,依然参考 [BUILD_README](../../scripts/cmake-build/BUILD_README.md): | |||
| * Windows 平台,编译出来的 dll 是 lite_shared_whl.dll | |||
| * None Windows 平台,编译出来的 so 是 liblite_shared_whl.so | |||
| * 编译上述库的步骤: | |||
| * clone 代码 | |||
| ```shell | |||
| git clone git@git-core.megvii-inc.com:brain-sdk/MegBrain.git | |||
| 开源版本:git clone git@github.com:MegEngine/MegEngine.git | |||
| ``` | |||
| * 进行Cmake编译,这里的cmake编译同megbrain的cmake编译,使用参数和宏也完全一样 | |||
| * 编译准备 | |||
| ```shell | |||
| cd MegBrain | |||
| sh ./third_party/prepare.sh | |||
| mkdir build | |||
| cd build | |||
| 开源版本: cd MegEngine | |||
| bash ./third_party/prepare.sh | |||
| ``` | |||
| * 编译 HOST 版本: | |||
| ```shell | |||
| ./scripts/cmake-build/host_build.sh | |||
| ``` | |||
| * 编译X86-CUDA版本 | |||
| * 编译 HOST 版本 (with CUDA): | |||
| ```shell | |||
| cmake .. -DMGE_WITH_CUDA=ON -DMGE_WITH_TEST=ON -DCMAKE_BUILD_TYPE=Release && make -j$(nproc) | |||
| ./scripts/cmake-build/host_build.sh -c | |||
| ``` | |||
| * 编译X86 CPU Only版本 | |||
| * 编译 Android 平台: | |||
| ```shell | |||
| cmake .. -DMGE_WITH_CUDA=OFF -DMGE_WITH_TEST=ON -DCMAKE_BUILD_TYPE=Release && make -j$(nproc) | |||
| scripts/cmake-build/cross_build_android_arm_inference.sh | |||
| ``` | |||
| * 编译完成之后,liblite.so 保存在build目录中的lite文件下 | |||
| * 将liblite.so copy到megenginelite的python源文件目录下,就可以使用megenginelite了。 | |||
| * 其他OS-ARCH可参考 [BUILD_README](../../scripts/cmake-build/BUILD_README.md) | |||
| * 编译完成之后,相应的库可在 build_dir 下找到, 这里假设它的目录是LITE_LIB_PATH=path_of_lite_shared_whl | |||
| * 开始使用 megenginelite | |||
| ```shell | |||
| MegBrain的工程目录为 ${mgb_hone} | |||
| cp ${mgb_hone}/build/lite/liblite.so ${mgb_home}/lite/pylite/megenginelite/ | |||
| cd ${mgb_home}/lite/pylite | |||
| python3 -m "import megenginelite" | |||
| export LITE_LIB_PATH=path_of_lite_shared_whl | |||
| export PYTHONPATH=lite/pylite:$PYTHONPATH | |||
| 然后就可以 import megenginelite 进行使用了 | |||
| ``` | |||
| 这样就可以在${mgb_home}/lite/pylite 目录下面开发和debug lite的python接口了 | |||
| ## python3中使用megenginelite | |||
| Lite的python接口是对其C/C++接口的一层封装,他们使用的模型都是相同的模型格式。megenginelite提供两种数据接口,分别是LiteTensor和LiteNetwork。 | |||
| ## python3 中使用 megenginelite | |||
| Lite 的 python3 接口是对其 C/C++ 接口的一层封装,他们使用的模型都是相同的模型格式。megenginelite 提供两种数据接口,分别是 LiteTensor 和 LiteNetwork。 | |||
| ### LiteTensor | |||
| LiteTensor提供了用户对数据的操作接口,提供了接口包括: | |||
| * fill_zero: 将tensor的内存设置为全0 | |||
| * share_memory_with: 可以和其他LiteTensor的共享内存 | |||
| * copy_from: 从其他LiteTensor中copy数据到自身内存中 | |||
| * reshape: 改变该LiteTensor的shape,内存数据保持不变 | |||
| * slice: 对该LiteTensor中的数据进行切片,需要分别指定每一维切片的start,end,和step。 | |||
| * set_data_by_share: 调用之后使得该LiteTensor中的内存共享自输入的array的内存,输入的array必须是numpy的ndarray,并且tensor在CPU上 | |||
| * set_data_by_copy: 该LiteTensor将会从输入的data中copy数据,data可以是list和numpy的ndarray,需要保证data的数据量不超过tensor的容量,tensor在CPU上 | |||
| * to_numpy: 将该LiteTensor中数据copy到numpy的array中,返回给用户,如果是非连续的LiteTensor,如slice出来的,将copy到连续的numpy array中,该接口主要数为了debug,有性能问题。 | |||
| #### 使用example | |||
| * LiteTensor 设置数据example | |||
| LiteTensor 提供了用户对数据的操作接口,提供了接口包括: | |||
| * fill_zero: 将 tensor 的内存设置为全0 | |||
| * share_memory_with: 可以和其他 LiteTensor 的共享内存 | |||
| * copy_from: 从其他 LiteTensor 中 copy 数据到自身内存中 | |||
| * reshape: 改变该 LiteTensor 的 shape,内存数据保持不变 | |||
| * slice: 对该 LiteTensor 中的数据进行切片,需要分别指定每一维切片的 start,end,和 step。 | |||
| * set_data_by_share: 调用之后使得该 LiteTensor 中的内存共享自输入的 array 的内存,输入的 array 必须是numpy 的 ndarray,并且 tensor 在 CPU 上 | |||
| * set_data_by_copy: 该 LiteTensor 将会从输入的 data 中 copy 数据,data 可以是 list 和 numpy 的 ndarray,需要保证 data 的数据量不超过 tensor 的容量,tensor 在 CPU 上 | |||
| * to_numpy: 将该 LiteTensor 中数据 copy 到 numpy 的 array 中,返回给用户,如果是非连续的 LiteTensor,如 slice 出来的,将 copy 到连续的 numpy array 中,该接口主要数为了 debug,有性能问题。 | |||
| #### 使用 example | |||
| * LiteTensor 设置数据 example | |||
| ``` | |||
| def test_tensor_set_data(): | |||
| layout = LiteLayout([2, 16], "int8") | |||
| @@ -89,7 +108,7 @@ def test_tensor_set_data(): | |||
| assert real_data[0][8] == 100 | |||
| assert real_data[1][3] == 20 | |||
| ``` | |||
| * tensor 共享内存example | |||
| * tensor 共享内存 example | |||
| ```python | |||
| def test_tensor_share_memory_with(): | |||
| layout = LiteLayout([4, 32], "int16") | |||
| @@ -118,10 +137,10 @@ def test_tensor_share_memory_with(): | |||
| assert real_data[1][18] == 5 | |||
| assert real_data[3][7] == 345 | |||
| ``` | |||
| 更多的使用可以参考pylite中test/test_tensor.py中的使用 | |||
| 更多的使用可以参考 pylite 中 test/test_tensor.py 中的使用 | |||
| ### LiteNetwork | |||
| LiteNetwork主要为用户提供模型载入,运行等功能。使用的模型见lite的readme中关于模型的部分 | |||
| * CPU基本模型载入运行的example | |||
| LiteNetwork 主要为用户提供模型载入,运行等功能。使用的模型见 lite 的 readme 中关于模型的部分 | |||
| * CPU 基本模型载入运行的 example | |||
| ``` | |||
| def test_network_basic(): | |||
| source_dir = os.getenv("LITE_TEST_RESOUCE") | |||
| @@ -154,7 +173,7 @@ def test_network_basic(): | |||
| output_data = output_tensor.to_numpy() | |||
| print('shufflenet output max={}, sum={}'.format(output_data.max(), output_data.sum())) | |||
| ``` | |||
| * CUDA上使用device内存作为模型输入,需要在构造network候配置config和IO信息 | |||
| * CUDA 上使用 device 内存作为模型输入,需要在构造 network 候配置 config 和 IO 信息 | |||
| ``` | |||
| def test_network_device_IO(): | |||
| source_dir = os.getenv("LITE_TEST_RESOUCE") | |||
| @@ -196,4 +215,4 @@ def test_network_device_IO(): | |||
| output_data = output_tensor.to_numpy() | |||
| print('shufflenet output max={}, sum={}'.format(output_data.max(), output_data.sum())) | |||
| ``` | |||
| 更多的使用可以参考pylite中test/test_network.py和test/test_network_cuda.py中的使用 | |||
| 更多的使用可以参考 pylite 中 test/test_network.py 和 test/test_network_cuda.py 中的使用 | |||