本文为您介绍如何使用C或C++开发自定义Processor。

快速上手Demo

下载PAI-EAS预测服务示例,该项目包含两个自定义Processor,其中:
  • echo:请求时将用户输入原样返回,同时返回模型中的文件列表。
  • image_classificationmnist文本分类,输入mnist jpg图片,返回图片分类类别。
编译方法请参见项目下的README文件,每个Processor的本地调试方法请参见各目录下的README文件。

接口定义

使用C或C++开发自定义Processor,需要定义Load()Process()函数,分别用于服务初始化时加载模型和处理客户端请求并返回结果。两个函数的声明如下。
void *initialize(const char *model_entry, const char *model_config, int *state)
参数 类型 描述
model_entry 输入参数 对应创建服务时配置文件中的model_entry字段,您可以传入一个文件名(例如randomforest.pmml)或目录(例如./model)。
model_config 输入参数 对应创建服务时配置文件中的model_config字段,表示自定义的模型配置信息。
state 输出参数 模型加载状态。如果为0,则表示模型加载成功,否则表示模型加载失败。
返回值 自定义的model变量内存地址,可以为任意类型。
int process(void *model_buf, const void *input_data, int input_size,void **output_data, int *output_size)
参数 类型 描述
model_buf 输入参数 initialize()函数返回的模型内存地址。
input_data 输入参数 用户数入数据,可以为任意字符串或BINARY类型。
input_size 输入参数 用户数入数据的长度。
output_data 输出参数 Processor返回的数据,需要在堆为其分配内存,模型负责释放该内存。
output_size 输出参数 Processor返回的数据长度。
返回值 返回0200表示成功,可以直接返回HTTP错误码。如果返回不识别的HTTP错误码,则自动转换为http 400 error

代码示例

以下是一个简单的示例,未加载任何模型数据,预测服务将用户请求直接返回给客户端。
#include <stdio.h>
#include <string.h>
extern "C" {
    void *initialize(const char *model_entry, const char *model_config, int *state)
    {
       *state = 0;
        return NULL;
    }
    int process(void *model_buf, const void *input_data, int input_size,
            void **output_data, int *output_size)
    {
        if (inputSize == 0) {
            const char *errmsg = "input data should not be empty";
            *outputData = strndup(errmsg, strlen(errmsg));
            *outputSize = strlen(errmsg);
            return 400;
        }
        *outputData = strndup((char *)inputData, inputSize);
        *outputSize = inputSize;
        return 200;
    }
}
该Processor未读取任何模型信息,将用户输入原样输出,可以通过如下的Makefile将其编译为SO文件。
CC=g++
CCFLAGS=-I./ -D_GNU_SOURCE -Wall -g -fPIC
LDFLAGS= -shared -Wl,-rpath=./
OBJS=processor.o
TARGET=libpredictor.so
all: $(TARGET)
$(TARGET): $(OBJS)
      $(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) -L./
%.o: %.cc
      $(CC) $(CCFLAGS) -c $< -o $@
clean:
      rm -f $(TARGET) $(OBJS)
如果有其它依赖的SO文件,则必须在Makefile文件中添加-rpath选项,指定SO文件的搜索目录。-rpath的原理详情请参见Rpath