开放能力
开发平台
行业应用
生态合作
开发与教学
资讯 社区 控制台
技术能力
语音技术
文字识别
人脸与人体
图像技术
语言与知识
视频技术
AR与VR
数据智能
场景方案
部署方案
行业应用
智能教育
智能医疗
智能零售
智能工业
企业服务
智能政务
信息服务
智能园区

EasyDL模型部署

EasyDL模型部署

专项适配模型训练
专项适配模型发布
专项适配模型获取
专项适配模型部署
接口使用说明
http服务
其他配置
EasyDL_SDK自动加载

EasyDL面向企业开发者提供零门槛AI开发平台,一站式支持智能标注、模型训练、服务部署等全流程功能,内置丰富的预训练模型,支持公有云/私有化/设备端等灵活部署方式。EasyDL面向不同人群提供经典版、专业版、零售版三款产品,已在工业、零售、制造、医疗等领域落地。EasyDL和EdgeBoard合作推出软硬一体方案。将EdgeBoard与EasyDL图像分类/物体检测模型深度适配,可应用于工业分拣、视频监控等多种设备端离线计算场景,让离线AI落地更轻松。现支持:图像分类、物体检测。

EasyDL零门槛AI开发平台:https://ai.baidu.com/easydl/

  • 图像分类

关于Easydl图像分类的相关介绍和使用请参考Easydl图像分类操作文档

  • 物体检测

关于Easydl物体检测的相关介绍和使用请参考Easydl物体检测操作文档

专项适配模型训练

Edgeboard部署模型在EasyDL训练阶段需要确定,如下图所示,在模型训练页面,部署方式选择EasyEdge本地部署,选择设备:专项适配硬件,选择硬件:Edgeboard(FZ),选择算法:高精度&高性能,然后添加训练数据开始训练。

image-20210420144457310

专项适配模型发布

模型部署方式在训练阶段确定后,才可以发布Edgeboard专项适配模型。点击发布

进入纯离线服务页面,选择专项适配硬件,选择硬件:Edgeboard(FZ),选择系统:Linux专用SDK。

专项适配模型获取

模型发布后,跳转到模型部署-纯离线服务页,可以查看模型的发布状态。

下载专用SDK

发布状态变更为已发布时,进入服务详情页面,此时可以点击下载sdk,同时获取EdgeBoard专用的序列号,如果还没有EdgeBoard硬件,可以前往AI市场购买。

获取专用序列号

EasyDL SDK需要专用序列号激活才可使用,并且购买账户需要和训练模型账户保持一致,序列号才可以顺利激活SDK。序列号获取方式有如下几种:

  • 从EasyDL服务详情页获取

如上图下载SDK页面,进入获取序列号。

  • 从订单中获取

用户可以通过AI市场订单详情查看对应版本的专项硬件适配服务,如下图所示:

img

如果连接中没有专用序列号,还请确认订单是否为EdgeBoard&EasyDL软硬一体方案,以及购买账户和模型训练账户是否是同一个。

  • 序列号购买和申请

如果获取序列号页面没有可用的序列号,可以进入百度智能云-EasyDL定制训练平台-专项硬件纯离线服务,购买永久授权序列号或者申请测试序列号。

在更换序列号、更换设备时,首次使用EasyDL SDK需要联网激活。激活成功之后,有效期内可离线使用。


专项适配模型部署

开发者从EasyDL训练模型之后,下载的SDK中,包含了简单易用的Demo和http服务接口。只需简单的几个步骤,即可快速部署运行EdgeBoard。

部署包中包含多版本SDK:

  • baidu*easyedge_linux_cpp_aarch64_EdgeBoardFZ1.5**:适用于EdgeBoard 1.8+内核
  • baidu*easyedge_linux_cpp_aarch64_EdgeBoardFZ1.4**:适用于EdgeBoard 1.4+内核

SDK文件结构如下:

EasyEdge-Linux-m43725-b121612-edgeboard/
├── RES #模型文件
│   ├── conf.json
│   ├── label_list.txt
│   ├── model
│   ├── params
│   └── preprocess_args.json
├── cpp 
│   ├── baidu_easyedge_linux_cpp_aarch64_EdgeBoardFZ1.4_gcc7.5_v1.3.0_20210602.zip
│   └── baidu_easyedge_linux_cpp_aarch64_EdgeBoardFZ1.5_gcc7.5_v1.3.0_20210602
│       ├── bin #demo可执行文件
│       ├── include #头文件
│       │   └── easyedge
│       ├── lib #动态库
│       ├── src #demo源文件
│       │   ├── CMakeLists.txt
│       │   ├── cmake
│       │   ├── common
│       │   ├── demo_image_inference #图像推理demo
│       │   ├── demo_serving #http服务demo
│       │   └── demo_video_inference #视频推理demo
│       └── thirdparty 
│           └── opencv

EdgeBoard环境搭建

  • 登录Edgeboard系统
  • 加载驱动,系统启动后加载一次即可(系统默认已自启动,此步骤可省略)

    insmod /home/root/workspace/driver/fpgadrv.ko

    若未加载驱动,可能报错:

    	Failed to to fpga device: -1
  • 设置系统时间(系统时间必须正确)

    date --set "2020-5-18 20:48:00"
  • 首次使用,需要联网激活SDK,激活成功之后,有效期内可离线使用
  • 设置EdgeBoard能够联网,参照连接外网方式

运行SDK

SDK激活方式是在联网状态下执行模型推理程序,激活后可以离线推理,运行SDK的方式可参考下文。

  • 解压

    请先将tar包整体拷贝到具体运行的设备中,再解压缩编译。

比如将SDK放到EdgeBoard的/home/root/目录,使用unzip以及tar命令解压zip包和tar.gz文件,

# 解压sdk
unzip EasyEdge-Linux-m8105-b33878-edgeboard.zip
# 解压tar.gz
cd cpp
tar xvf baidu_easyedge_linux_cpp_aarch64_EdgeBoardFZ1.5_gcc7.5_v1.2.2_20210412.tar.gz

  • 运行方式一

SDK中已经包含预先编译的二进制,如 bin/easyedge_image_inference, bin/easyedge_serving,配置LD_LIBRARY_PATH后,可直接运行:

# 设置LD_LIBRARY_PATH为SDK部署包中的lib目录
LD_LIBRARY_PATH=../lib 
# 执行easyedge_serving {RES资源文件夹路径} {序列号}
./bin/easyedge_serving  ../../../RES/ "1111-1111-1111-1111"
  • 运行方式二

    src编译

    #进入src目录,
    cd src
    mkdir build #创建build文件夹
    cd build #打开build文件夹
    rm -rf * #清空build文件夹
    cmake .. #调用cmake 创建Makefile
    make #编译工程

编译完成后,build文件夹下会产生demo_image_inference、demo_serving、demo_video_inference三个装有对应可执行文件的文件夹,进入对应文件夹目录,执行相应的功能,执行成功任意一个demo,就可以激活成功。

运行demo_image_inference

运行demo_image_inference前,需要提前拷贝一张测试图片到Edgeboard上,比如放到easydl sdk中的RES目录。

# 进入build文件夹
cd /home/root/cpp/baidu_easyedge_linux_cpp_aarch64_EdgeBoardFZ1.5_gcc7.5_v1.2.2_20210412/src/build/demo_image_inference
# 设置LD_LIBRARY_PATH为SDK部署包中的lib目录
export LD_LIBRARY_PATH=../../lib
# 执行easyedge_image_inference {RES资源文件夹路径} {测试图片路径} {序列号}
./easyedge_image_inference ../../../../../RES/ ../../../../../RES/1.jpeg "1111-1111-1111-1111"

打印信息中显示出预测结果,证明推理成功,首次执行也就激活成功。

运行demo_serving

SDK包含http服务功能

# 进入build文件夹
cd /home/root/cpp/baidu_easyedge_linux_cpp_aarch64_EdgeBoardFZ1.5_gcc7.5_v1.2.2_20210412/src/build/demo_serving
# ./easyedge_serving {res_dir} {serial_key} {host, default 0.0.0.0} {port, default 24401}
 ./easyedge_serving ../../../RES "1111-1111-1111-1111" 0.0.0.0  24401

执行后,日志会显示如下字样

HTTP is now serving at 0.0.0.0:24401

此时可直接在浏览器中输入http://{EdgeBoard计算盒ip地址}:24401/,例如:http://192.168.1.254:24401 ,在h5中测试模型效果。

img

同时,可以调用HTTP接口来访问服务,具体参考下文接口说明

运行demo_video_inference

SDK包含视频推理的demo,执行结果会以视频存储的方式将预测出的视频帧保存成build目录下的0.result.mp4文件。

# 进入build文件夹
cd /home/root/cpp/baidu_easyedge_linux_cpp_aarch64_EdgeBoardFZ1.5_gcc7.5_v1.2.2_20210412/src/build/demo_video_inference
# 执行方式:easyedge_image_inference {RES_dir} {video_type} {video_src} {serial_rum}
./easyedge_video_inference ../../../../../RES/ 1 /home/root/video.mp4 "1111-1111-1111-1111"

easyedge_image_inference参数定义:

RES_dir :模型存放目录

video-type:视频类型,1表示本地视频,视频位置写本地视频位置;2表示使用摄像头输入,目前只支持usb免驱摄像头,视频位置写摄像头的index,可在系统中执行ls /dev/video*查看插入的摄像头index,如果是/dev/video2,则视频位置写2。

video_src:视频位置,如果视频类型为1,写本地视频视频位置;如果视频类型为2,写摄像头index。

serial_rum:序列号,如果设备已激活,该参数可选。

注意: demo_video_inference功能暂不支持display,不支持接入minidp显示器实时显示。

接口使用说明

使用流程:

请优先参考Demo的使用流程。遇到错误,请优先参考文件中的注释解释,以及日志说明。

    // step 1: 配置模型资源目录
    EdgePredictorConfig config;
    config.model_dir = {模型文件目录};
    
    // step 2: 创建并初始化Predictor;在这里选择合适的引擎
    auto predictor = global_controller()->CreateEdgePredictor(config);


    // step 3-1: 预测图像
    auto img = cv::imread({图片路径});
    std::vector<EdgeResultData> results;
    predictor->infer(img, results);
	
	// step 3-2: 预测视频
	std::vector<EdgeResultData> results;
	FrameTensor frame_tensor;
    VideoConfig video_config;
    video_config.source_type = static_cast<SourceType>(video_type);  // source_type 定义参考头文件 easyedge_video.h
    video_config.source_value = video_src;
    /*
    ... more video_configs, 根据需要配置video_config的各选项
    */
    auto video_decoding = CreateVideoDecoding(video_config);
    while (video_decoding->next(frame_tensor) == EDGE_OK) {
        results.clear();
        if (frame_tensor.is_needed) {
            predictor->infer(frame_tensor.frame, results);
            render(frame_tensor.frame, results, predictor->model_info().kind);
        }
        //video_decoding->display(frame_tensor); // 显示当前frame,需在video_config中开启配置
        //video_decoding->save(frame_tensor); // 存储当前frame到视频,需在video_config中开启配置
    }

SDK参数配置

SDK的参数通过EdgePredictorConfig::set_configglobal_controller()->set_config配置。set_config的所有key在easyedge_xxxx_config.h中。其中

  • PREDICTOR前缀的key是不同模型相关的配置,通过EdgePredictorConfig::set_config设置
  • CONTROLLER前缀的key是整个SDK的全局配置,通过global_controller()->set_config设置

以序列号为例,KEY的说明如下:

/**
 * @brief 序列号设置;序列号不设置留空时,SDK将会自动尝试使用本地已经激活成功的有效期内的序列号
 * 值类型:string
 * 默认值:空
 */
static constexpr auto PREDICTOR_KEY_SERIAL_NUM = "PREDICTOR_KEY_SERIAL_NUM";

使用方法如下:

EdgePredictorConfig config;
config.model_dir = ...;
config.set_config(params::PREDICTOR_KEY_SERIAL_NUM, "1DB7-1111-1111-D27D");

具体支持的运行参数配置列表可以参考开发工具包中的头文件的详细说明。

相关配置均可以通过环境变量的方法来设置,对应的key名称加上前缀EDGE_即为环境变量的key。如序列号配置的环境变量key为EDGE_PREDICTOR_KEY_SERIAL_NUM,如指定CPU线程数的环境变量key为EDGE_PREDICTOR_KEY_CPU_THREADS_NUM。 注意:通过代码设置的配置会覆盖通过环境变量设置的值。

初始化

  • 接口
auto predictor = global_controller()->CreateEdgePredictor(config);
predictor->init();

若返回非0,请查看输出日志排查错误原因。

预测图像

  • 接口
 /**
  * @brief
  * 通用接口
  * @param image: must be BGR , HWC format (opencv default)
  * @param result
  * @return
  */
 virtual int infer(
         cv::Mat& image, std::vector<EdgeResultData>& result
 ) = 0;

 /**
  * @brief
  * GPU加速版批量图片推理接口
  * @param image: must be BGR , HWC format (opencv default)
  * @param result
  * @return
  */
 virtual int infer(
         std::vector<cv::Mat>& image, std::vector<std::vector<EdgeResultData>>& result
 ) = 0;

图片的格式务必为opencv默认的BGR, HWC格式。

  • 返回格式

EdgeResultData中可以获取对应的分类信息、位置信息。

struct EdgeResultData {
    int index;  // 分类结果的index
    std::string label;  // 分类结果的label
    float prob;  // 置信度

    // 物体检测、图像分割时才有意义
    float x1, y1, x2, y2;  // (x1, y1): 左上角, (x2, y2): 右下角; 均为0~1的长宽比例值。

    // 图像分割的模型,该字段才有意义
    // 请注意:图像分割时,以下两个字段会比较大,使用完成之后请及时释放EdgeResultData
    cv::Mat mask;  // 0, 1 的mask
    std::string mask_rle;  // Run Length Encoding,游程编码的mask

    // 目标追踪模型,该字段才有意义
    int trackid;  // 轨迹id
    int frame;  // 处于视频中的第几帧
    EdgeTrackStat track_stat;  // 跟踪状态
};

*关于矩形坐标*

x1 * 图片宽度 = 检测框的左上角的横坐标

y1 * 图片高度 = 检测框的左上角的纵坐标

x2 * 图片宽度 = 检测框的右下角的横坐标

y2 * 图片高度 = 检测框的右下角的纵坐标

http服务

1. 开启http服务

http服务的启动可以参考demo_serving.cpp文件。

 /**
     * @brief 开启一个简单的demo http服务。
     * 该方法会block直到收到sigint/sigterm。
     * http服务里,图片的解码运行在cpu之上,可能会降低推理速度。
     * @tparam ConfigT
     * @param config
     * @param host
     * @param port
     * @param service_id service_id  user parameter, uri '/get/service_id' will respond this value with 'text/plain'
     * @param instance_num 实例数量,根据内存/显存/时延要求调整
     * @return
     */
    template<typename ConfigT>
    int start_http_server(
            const ConfigT &config,
            const std::string &host,
            int port,
            const std::string &service_id,
            int instance_num = 1);

2. 请求http服务

开发者可以打开浏览器,http://{设备ip}:24401,选择图片来进行测试。

http 请求方式一:不使用图片base64格式

URL中的get参数:

参数 说明 默认值
threshold 阈值过滤, 0~1 如不提供,则会使用模型的推荐阈值

HTTP POST Body即为图片的二进制内容(无需base64, 无需json)

Python请求示例

import requests

with open('./1.jpg', 'rb') as f:
    img = f.read()
    result = requests.post(
	    'http://127.0.0.1:24401/',
	    params={'threshold': 0.1},
	    data=img).json()

Java请求示例

http 请求方法二:使用图片base64格式

HTTP方法:POST Header如下:

参数
Content-Type application/json

Body请求填写

  • 分类网络: body 中请求示例
{
	"image": "<base64数据>"
	"top_num": 5
}

body中参数详情

参数 是否必选 类型 可选值范围 说明
image string - 图像数据,base64编码,要求base64图片编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 注意去掉头部
top_num number - 返回分类数量,不填该参数,则默认返回全部分类结果
  • 检测和分割网络: Body请求示例:
{
	"image": "<base64数据>"
}

body中参数详情:

参数 是否必选 类型 可选值范围 说明
image string - 图像数据,base64编码,要求base64图片编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式 注意去掉头部
threshold number - 默认为推荐阈值,也可自行根据需要进行设置

3. http 返回数据

字段 类型说明 其他
error_code Number 0为成功,非0参考message获得具体错误信息
results Array 内容为具体的识别结果。其中字段的具体含义请参考预测图像-返回格式一节
cost_ms Number 预测耗时ms,不含网络交互时间

返回示例

{
    "cost_ms": 52,
    "error_code": 0,
    "results": [
        {
            "confidence": 0.94482421875,
            "index": 1,
            "label": "IronMan",
            "x1": 0.059185408055782318,
            "x2": 0.18795496225357056,
            "y1": 0.14762254059314728,
            "y2": 0.52510076761245728
        },
        {
            "confidence": 0.94091796875,
            "index": 1,
            "label": "IronMan",
            "x1": 0.79151463508605957,
            "x2": 0.92310667037963867,
            "y1": 0.045728668570518494,
            "y2": 0.42920106649398804
        }
      ]
}

其他配置

1. 日志名称、HTTP 网页标题设置

通过global_controller的set_config方法设置:

global_controller()->set_config(easyedge::params::CONTROLLER_KEY_LOG_BRAND, "MY_BRAND");

效果如下: 图片

2. CPU线程数设置

CPU线程数可通过 EdgePredictorConfig::set_config配置

EdgePredictorConfig config;
config.set_config(easyedge::params::PREDICTOR_KEY_CPU_THREADS_NUM, 4);

EasyDL_SDK自动加载

如需开机自启 EasyDL SDK,可参考设置程序开机自启动中的『EasyDL sdk自动加载』部分。

上一篇
模型预测示例
下一篇
BML模型部署