本文為您介紹如何使用C或C++開發自訂Processor。
快速上手Demo
下載EAS預測服務樣本,該專案包含兩個自訂Processor,其中:
echo:請求時將使用者輸入原樣返回,同時返回模型中的檔案清單。
image_classification:mnist文本分類,輸入mnist jpg圖片,返回圖片分類類別。
編譯方法請參見專案下的README檔案,每個Processor的本地調試方法請參見各目錄下的README檔案。
介面定義
使用C或C++開發自訂Processor,需要定義initialize()和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返回的資料長度。 |
傳回值 | 返回0或200表示成功,可以直接返回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)