pybind11

Posted on 2022-12-25 20:05  Charlie_ODD  阅读(278)  评论(0编辑  收藏  举报

概述

https://zhuanlan.zhihu.com/p/444805518

背景:

目前 AI 算法开发特别是训练基本都以 Python 为主,主流的 AI 计算框架如 TensorFlow、PyTorch 等都提供了丰富的 Python 接口。

但由于 Python 属于动态语言,解释执行并缺少成熟的 JIT 方案,计算密集型场景多核并发受限等原因,很难直接满足较高性能要求的实时 Serving 需求。

GIL(Global Interpreter Lock)全局解释器锁:同一时刻在一个进程只允许一个线程使用解释器,导致多线程无法真正用到多核。由于持有锁的线程在执行到 I/O 密集函数等一些等待操作时会自动释放 GIL 锁,所以对于 I/O 密集型服务来说,多线程是有效果的。但对于 CPU 密集型操作,由于每次只能有一个线程真正执行计算,对性能的影响可想而知。

在一些对性能要求高的场景下,还是需要使用 C/C++来解决。但是如果要求算法同学全部使用 C++来开发线上推理服务,成本又非常高,导致开发效率和资源浪费。

如果有【轻便的方法】能将 Python 和部分 C++编写的核心代码结合起来,就能达到既保证开发效率又保证服务性能的效果。

轻便的方法——Pybind11

支持C++11 等新特性,Pybind11通过 C++ 编译时的自省来推断类型信息,来最大程度地减少传统拓展 Python 模块时繁杂的样板代码, 且实现了常见数据类型,如 STL 数据结构、智能指针、类、函数重载、实例方法等到 Python 的自动转换,其中函数可以接收和返回自定义数据类型的值、指针或引用。

业内来说,目前市面上大部分 AI 计算框架,如 TensorFlow、Pytorch、阿里 X-Deep Learning、百度 PaddlePaddle 等,均使用 pybind11 来提供 C++到 Python 端接口封装,其稳定性以及性能均已得到广泛验证。

MacOS环境安装:

检查最基本的python环境:

pip -V
pip3 -V
which pip
which pip3
which python
which python3

建议使用专门的python虚拟环境:

查看版本:virtualenv --version

到统一的一个自定义路径下(如/Users/yonglang/chy/PyEnv)创建环境名为“pybind11Env”的环境:

virtualenv pybind11Env
cd pybind11Env 
source bin/activate  # 激活并进入虚拟环境
      or  source activate pybind11Env
      or  conda activate pybind11Env


deactivate           # 退出环境

# 删除环境 1.直接删除虚拟环境所在目录 2.conda remove -n your_name --all # 查看虚拟环境列表 conda env list conda info -e virtualenv --python=/usr/local/bin/python3.8 sfEnv

在虚拟环境中安装包,不要带sudo哈

说明:确保virtualenv

pip3 install -i https://mirrors.aliyun.com/pypi/simple virtualenv 
pip3 install -i https://mirrors.aliyun.com/pypi/simple virtualenvwrapper

安装pybind11 (可使用-i换源下载)

python3 -m pip install pybind11

#其他以来项
python3 -m pip install python3-dev
brew uninstall cmake 

C++暴露给Python调用

1. 创建一个example.cpp

#include <pybind11/pybind11.h>

int add(int i, int j) {
    return i + j;
}

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin"; // optional module docstring

    m.def("add", &add, "A function that adds two numbers");
}

2. 编译

需要指定文件编译

#mac
g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`
或
g++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)

#linux
g++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`

3. 调用