Paddle多语言SDK
Created by: reyoung
Paddle目前支持的预测库是使用swig转化成python的api进行预测的。但是很多时候大家并不想使用python作为线上系统的预测语言。而想使用Java或者C++/C进行模型的预测。让用户支持多语言的预测,目前可以有多种实现方式。这里我把实现的想法和目前swig的架构列一下,希望大家参与一下讨论。
目前Swig封装的结构
Paddle目前swig接口如上图所示。首先,最下面是Paddle的C++核心部分。这一块C++的核心部分使用的是C++ 11来进行编写(也不排除未来用C++ 14/17)。由于Paddle在最开始设计的时候,没有考虑过多语言接口,所以重构Paddle C++代码的核心部分,来支持swig,并用swig直接生成多语言脚本,是比较复杂的。特别是Paddle的C++使用风格是,尽量使用标准库,尽量使用第三方库,如果可以尽量使用新的feature。如果直接使用swig编译Paddle核心C++库(万一以后我们用C++ 14/17呢?),会非常复杂。
于是Paddle为了支持多语言的swig接口,写了一个 Paddle API
包。这个包是专为swig打造的,主体分为两个部分。
- Paddle.h 这个文件是swig编译的接口文件。这个文件的特点是
- 只使用C++ 03的feature
- 不使用任何第三方库,只使用 C++ 标准库
- 尽量在接口里做一些安全检查,不要将进程挂掉。
- 使用异常返回检查错误。(更接近于python,java的风格)
- 其余文件是Paddle的C++核心模块与Paddle.h的转接层,尽量做到内存无复制。
在这个Paddle API
模块之上,我们用swig编译出了 Python
语言的接口文件,swig_paddle.py
。但是,这个接口文件其实是非常C++
风格的,也和Paddle紧密相关。比如,
- Python的矩阵库常用的是numpy,但是Paddle里面有自己的矩阵库实现。
- Paddle本身载入模型、初始化模型需要很多步骤。但用户其实只需要一句话
loadModel
为了让用户可以更加自然的使用paddle python的封装,我们在python端写了一些工具函数/类,monkey patch掉Paddle的一些函数,比如让其能直接返回numpy的矩阵之类的,这样对Python更友好。
以上是Paddle目前的多语言实现。
Paddle 多语言接口 (Java/Go/Matlab)
Paddle的Java/Go/Matlab预测接口理论上应该和Python的风格一致。整体图示为:
这个事情感觉理解起来并不是很复杂,实际上就和Python的接口一样。
Paddle 多语言接口 (C/C++/ObjectiveC)
C/C++/Objective-C的接口和Java、Python的又不太一样。
- 因为,Java、Python不能直接include C/C++头文件
- 内存管理模式也和C/C++有很大差别。
- 例如Java和Python都是有垃圾回收的语言,所以,在swig和 API中的Paddle.h中,需要将内存管理托管给其他语言。
- 但是C/C++是手动管理内存的语言,所以需要显示的delete/free对象。
所以,C/C++/Objective-C的接口需要使用另一个思路来做。如果直接使用Paddle API
模块下的 Paddle.h
会有一下几个问题。
- 这个
Paddle.h
是为了swig接口做的,所以内存申请完了并没有释放的code。因为释放原本可以交由其他语言的垃圾回收来做。 - 这个
Paddle.h
使用了exception作为错误信息,但是C++ exception本质上并不应该被使用。 - 这个
Paddle.h
太接近于Paddle本身的实现了,需要用户去了解太多知识。
所以,我个人感觉Paddle的C/C++/ObjectiveC的多语言接口应该再在 Paddle API
之上封装一层C API。给用户预测使用。
整体模块图如下:
但这个事情这么做,有一种深深地过于复杂的感觉。所以我也不确定是不是这样会好一些。