所有文档

          EasyDL定制AI训练平台

          经典版图像分类EdgeBoard(VMX)专用SDK集成文档

          简介

          本文档旨在介绍 EasyDL在EdgeBoard USB加速卡VMX(以下简称VMX加速卡或加速卡)上的专用软件的使用流程。 EdgeBoard系列硬件适用于项目研发与部署,具有高性能、易携带、通用性强、开发简单等四大优点。 您可在AI市场了解EdgeBoard相关系列产品,同时可以在软硬一体方案了解性能数据。

          注意:本型号主要面向产品集成和企业项目,未同时售卖散热片和外壳,部分情况下芯片温度较高,开发过程中,请勿用手触摸,谨防烫伤

          硬件介绍

          VMX加速卡,采用Intel® Movidus™ 视觉 MyriadX处理器芯片,通过 USB3.0 通讯type-c接口方式,配合外围电路即可将该模组嵌入到第三方智能化产品中,采用标准 USB通讯协议,对接简单,开发速度快,具有强大的深度学习计算功能。可通过OpenVINO™和OpenCV软件库工具链移植算法,兼容百度PaddlePaddle支持Paddle2onnx和PaddleHub并集成EasyDL,使产品应用范围广,性能更稳定,增强用户体验。

          VMX加速卡适用于深度学习加速,能够解决复杂的人工智能软硬件设计挑战,它可以集成基于视觉的加速器和推理引擎来实现深度边缘学习的解决方案。(3D/2D人脸识别、人头检测、人脸属性分析(性别、年龄)、人脸特征比对、手势及姿态识别、物体检测及分类、算法移植等功能。)

          硬件配置与说明

          核心板模块: Intel® Movidus™ MyriadX,内置内存LP-DDR4 4GBit。

          • 硬件指标

          CPU

          o Intel® Movidius Myriad X MA2485 Vision Processing Unit
          o Total performance of over 4 trillion operations per second (TOPS) o Over 1 TOPS performance on neural network inference w/ NCE accelerator o 16 Programmable 128-bit VLIW Vector Processors o 16 Configurable MIPI Lanes w/ enhanced Vision Accelerators o 2.5 MB of Homogenous On-Chip Memory w/ 4Gbit LPDDR4

          Size

          o 38mm x 38mm

          Interface o USB TYPE C(USB3.0)辅助接口精简设计

          Boot o USB 启动模式 - 内置 switch 缺省模式设置

          Power o 平均功耗0.5W~2.2W

          Security o 支持 eFuse 加密

          运行说明

          VMX加速卡包含独立的AI运算芯片,采用 USB Type-C通讯方式,通讯协议简单可靠,可连接不同芯片架构主机,包括 X86、单片机、ARM SOC等。加速卡运行需要通过TypeC接口连接宿主机执行,宿主机目前支持的软硬件环境包括:

          • Linux: x86-64, aarch64, armv7hf
          • Windows: x86-64, Windows 10

          使用过程中,请尽量避免直接触碰板卡元器件;或者使用防静电锡纸包裹板卡。

          快速开始 Linux

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

          Release Notes

          时间 版本 说明
          2020.09.17 0.5.6 新增Linux aarch64, armv7hf的cpp SDK
          2020.06.23 0.5.4 新增C++语言的 SDK

          将加速卡连接宿主机

          请使用质量合规的usb线连接。连接之后,检查设备是否被操作系统识别: Linux 通过lsusb -v 命令检查是否有 Myriad设备:

          > sudo lsusb -v | grep -C 5 Myriad
            bMaxPacketSize0        64
            idVendor           0x03e7 
            idProduct          0x2485 
            bcdDevice            0.01
            iManufacturer           1 Movidius Ltd.
            iProduct                2 Movidius MyriadX
            iSerial                 3 03e72485

          Windows 可以在设备管理器中查询。

          如果使用 VirtualBox 之类的虚拟机,请在虚拟机加入 03e7:24 和 03e7:f63b 两个 usb 设备。

          获取并安装依赖

          1. 安装依赖

          对于宿主机为Linux x86-64和Windows x86-64, Windows 10的,请参考 OpenVINO toolkit 文档安装最新 2020.x 版本, 安装时可忽略Configure the Model Optimizer及后续部分。

          注意,运行sdk之前,请source openvino的 setup_vars.sh文件,配置环境变量。

          对于宿主机为Linux armv7hf的, >使用 OpenVINO™ toolkit 安装,请参考openvino toolkit raspberry 文档安装 2020.1版本。

          注意,运行sdk之前,请source openvino的 setup_vars.sh文件,配置环境变量。

          对于宿主机为Linux aarch64的,需要自行安装OpenCV4.2.0,并在使用SDK时指定4.2.0版本OpenCV的路径(注:不用单独安装openvino 预测引擎,SDK里已提供openvino 预测引擎)

          OpenCV源码编译安装地址

          1. 从EasyDL 控制台获取SDK 在任意位置解压缩。

          获取序列号

          AI市场订单详情或者EasyDL控制台获取序列号。

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

          请确保激活设备时使用的 操作系统账号与后续使用时运行的账号一致,否则会造成验证失败

          Python SDK

          1. 安装wheel包
           pip3 install -U BaiduAI_EasyEdge_SDK-1.1.13-cp37-cp37m-linux_x86_64.whl

          注意,请根据python的版本选择对应的whl文件,其中,1.1.13是SDK版本号,cp37表示是python3.7版本

          --

          注意,pip安装时请添加-U参数

          1. 将步骤2中获得的序列号 填入demo.py
          edge.set_auth_license_key("这里填写序列号")
          1. 测试demo.py
           python3 demo.py {模型资源文件夹RES路径} {待识别的图片路径}

          生成的样例结果图片如下:

          使用流程

          import BaiduAI.EasyEdge as edge
          
          edge.set_auth_license_key("这里填写序列号")
          
          pred = edge.Program()
          pred.init(model_dir={RES文件夹路径}, device=edge.Device.MOVIDIUS, engine=edge.Engine.OPENVINO)
          pred.infer_image({numpy.ndarray的图片})
          pred.close()

          接口的详细说明请主要参考 SDK 中的接口注释

          接口说明

          Program

          • 初始化
          def init(self,
                       model_dir,
                       device=Device.CPU,
                       engine=Engine.NCSDK,
                       config_file='conf.json',
                       preprocess_file='preprocess_args.json',
                       model_file='model',
                       params_file='params',
                       graph_file='graph.ncsmodel',
                       label_file='label_list.txt',
                       device_id=0,
                       **kwargs
                       ):
                  """
                  Args:
                      model_dir: str
                      device: BaiduAI.EasyEdge.Device
                      engine: BaiduAI.EasyEdge.Engine
                      preprocess_file: str
                      model_file: str
                      params_file: str
                      graph_file: str ncs的模型文件 或 PaddleV2的模型文件
                      label_file: str
                      device_id: int 设备ID
                      thread_num: int CPU的线程数
          
                  Raises:
                      RuntimeError, IOError
                  Returns:
                      bool: True if success
          
                  """
          • 预测单张图像
              def infer_image(self, img, threshold=None,
                              channel_order='HWC',
                              color_format='BGR',
                              data_type='numpy'
                              ):
                  """
          
                  Args:
          
                      img: np.ndarray or bytes
                      channel_order(string):
                          channel order: HWC or CHW
                      color_format(string):
                          color format order: RGB or BGR
                      threshold(float):
                          only return result with confidence larger than threshold
                      data_type(string): 仅在图像分割时有意义。 'numpy' or 'string'
                          'numpy': 返回已解析的mask
                          'string': 返回未解析的mask游程编码
                  Returns:
                      list
          
                  """
          • 返回格式: [dict1, dict2, ...]
          字段 类型 取值 说明
          confidence float 0~1 分类或检测的置信度
          label string 分类或检测的类别
          index number 分类或检测的类别
          x1, y1 float 0~1 物体检测,矩形的左上角坐标 (相对长宽的比例值)
          x2, y2 float 0~1 物体检测,矩形的右下角坐标(相对长宽的比例值)
          mask string/numpy.ndarray 图像分割的mask

          关于矩形坐标

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

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

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

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

          可以参考 demo 文件中使用 opencv 绘制矩形的逻辑。

          结果示例

          • i) 图像分类
          {
              "index": 736,
              "label": "table",
              "confidence": 0.9
          }
          • ii) 物体检测
          {
              "y2": 0.91211,
              "label": "cat",
              "confidence": 1.0,
              "x2": 0.91504,
              "index": 8,
              "y1": 0.12671,
              "x1": 0.21289
          }
          • iii) 图像分割
          {
          	  "name": "cat",
              "score": 1.0,
              "location": {
              	"left": ..., 
              	"top": ..., 
              	"width": ...,
              	"height": ...,
              },
              "mask": ...
          }

          mask字段中,data_type为numpy时,返回图像掩码的二维数组

          {
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          }
          其中1代表为目标区域,0代表非目标区域

          data_type为string时,mask的游程编码,解析方式可参考 demo

          C++ SDK

          使用流程

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

          请先将tar包整体拷贝到具体运行的设备中,再解压缩编译; 对于宿主机为Linux aarch64的,在编译前指定4.2.0版本OpenCV的路径: export OpenCV_DIR={opencv_install_prefix}/lib/cmake/opencv4

          如果openvino预测引擎找不到设备需要执行以下命令,可以查看官方参考

          sudo cp ${CPP_SDK_DIR}/openvino/97-myriad-usbboot.rules  /etc/udev/rules.d/
          或者:
          sudo cp /opt/intel/openvino/inference_engine/external/97-myriad-usbboot.rules /etc/udev/rules.d/
          
          sudo udevadm control --reload-rules
          sudo udevadm trigger
          sudo ldconfig
              // step 0: 设置序列号
              global_controller()->set_licence_key("set your license here");
          
              // step 1: 配置模型资源目录
              EdgePredictorConfig config;
          //    config.set_config(easyedge::params::KEY_CPU_THREADS_NUM, 4);
              config.model_dir = {模型文件目录};
          
              // step 2: 创建并初始化Predictor
              auto predictor = global_controller()->CreateEdgePredictor(config);
          
              auto img = cv::imread({图片路径});
              // step 3: 预测图像
              std::vector<EdgeResultData> result2;
              predictor->infer(img, result2);

          初始化

          • 接口
          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;

          图片的格式务必为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的长宽比例值。
          
              // 图像分割时才有
              cv::Mat mask;  // 0, 1 的mask
              std::string mask_rle;  // Run Length Encoding,游程编码的mask
          };

          关于矩形坐标

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

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

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

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

          关于图像分割mask

          cv::Mat mask为图像掩码的二维数组
          {
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
          }
          其中1代表为目标区域,0代表非目标区域

          关于图像分割mask_rle

          该字段返回了mask的游程编码,解析方式可参考 http demo

          以上字段可以参考demo文件中使用opencv绘制的逻辑进行解析

          设置序列号

          请在网页控制台中申请序列号,并在init初始化前设置。 LinuxSDK 首次使用需联网授权。

          virtual int set_licence_key(const std::string& license) = 0;

          日志配置

          设置 EdgeLogConfig 的相关参数。具体含义参考文件中的注释说明。

          EdgeLogConfig log_config;
          log_config.enable_debug = true;
          global_controller()->set_log_config(log_config);

          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);
            1. 请求http服务

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

          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 返回数据
          字段 类型说明 其他
          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::KEY_LOG_BRAND, "MY_BRAND");

          效果如下: 图片

          Linux FAQ

          1. EasyDL 离线 SDK 与云服务效果不一致,如何处理?

          我们会逐渐消除这部分差异,如果开发者发现差异较大,可通过工单论坛联系我们协助处理。

          2. 硬件出现问题或者出现故障怎么办? 软件使用有问题怎么处理?

          • 如果持续在静电较多的环境中使用,建议使用防静电锡纸包裹板卡
          • 如果硬件无法启动等故障,您可以通过商品页联系供应商处理;其它硬件问题,您可以邮件 edgeboard-vmx.com ,我们将在0-2日内处理您的问题。为加快处理进度,您在邮件中,尽量描述清楚问题或者需求细节,避免来回沟通。
          • 软件使用问题,请尽量通过工单论坛联系我们协助处理。

          3. 运行时报错:NC_ERROR

          Can not init Myriad device: NC_ERROR

          一般是硬件没有插上,请确保lsusb能够找到该硬件。或者等待几秒后再试。

          快速开始 Windows

          1. 安装依赖

          将操作系统升级到Windows 10

          安装.NET Framework4.5

          https://www.microsoft.com/zh-CN/download/details.aspx?id=42642

          Visual C++ Redistributable Packages for Visual Studio 2013

          https://www.microsoft.com/zh-cn/download/details.aspx?id=40784

          Visual C++ Redistributable Packages for Visual Studio 2015

          https://www.microsoft.com/zh-cn/download/details.aspx?id=48145

          注意事项

          1. 安装目录不能包含中文
          2. Windows Server 请自行开启,选择“我的电脑”——“属性”——“管理”——”添加角色和功能“——勾选”桌面体验“,点击安装,安装之后重启即可。

          2. 运行离线SDK

          解压下载好的SDK,打开EasyEdge.exe,输入Serial Num 点击"启动服务",等待数秒即可启动成功,本地服务默认运行在

          http://127.0.0.1:24401/

          其他任何语言只需通过HTTP调用即可。

          接口调用说明

          Python 使用示例代码如下

          import requests
          
          with open('./1.jpg', 'rb') as f:
              img = f.read()
          
          ## params 为GET参数 data 为POST Body
          result = requests.post('http://127.0.0.1:24401/', params={'threshold': 0.1},
                                                            data=img).json()

          C## 使用示例代码如下

          FileStream fs = new FileStream("./img.jpg", FileMode.Open);
          BinaryReader br = new BinaryReader(fs);
          byte[] img = br.ReadBytes((int)fs.Length);
          br.Close();
          fs.Close();
          string url = "http://127.0.0.1:8402?threshold=0.1";
          HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
          request.Method = "POST";
          Stream stream = request.GetRequestStream();
          stream.Write(img, 0, img.Length);
          stream.Close();
          
          WebResponse response = request.GetResponse();
          StreamReader sr = new StreamReader(response.GetResponseStream());
          Console.WriteLine(sr.ReadToEnd());
          sr.Close();
          response.Close();

          请求参数

          字段 类型 取值 说明
          threshold float 0 ~ 1 置信度阈值

          HTTP POST Body直接发送图片二进制。

          返回参数

          字段 类型 取值 说明
          confidence float 0~1 分类或检测的置信度
          label string 分类或检测的类别
          index number 分类或检测的类别
          x1, y1 float 0~1 物体检测,矩形的左上角坐标 (相对长宽的比例值)
          x2, y2 float 0~1 物体检测,矩形的右下角坐标(相对长宽的比例值)

          关于矩形坐标

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

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

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

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

          Windows FAQ

          1. 服务启动失败,怎么处理?

          请确保相关依赖都安装正确,版本必须如下: .NET Framework 4.5 Visual C++ Redistributable Packages for Visual Studio 2013 * Visual C++ Redistributable Packages for Visual Studio 2015

          2. 服务调用时返回为空,怎么处理?

          调用输入的图片必须是RGB格式,请确认是否有alpha通道。

          3. 多个模型怎么同时使用?

          SDK设置运行不同的端口,点击运行即可。

          4. JAVA、C#等其他语言怎么调用SDK?

          参考 http://ai.baidu.com/forum/topic/show/943765

          5. 启动失败,缺失DLL?

          打开EasyEdge.log,查看日志错误,根据提示处理 缺失DLL,请使用 http://www.dependencywalker.com/ 查看相应模块依赖DLL缺失哪些,请自行下载安装

          6. 启动失败,报错NotDecrypted?

          Windows下使用,当前用户名不能为中文,否则无法正确加载模型。

          7. 其他问题

          如果无法解决,可到论坛发帖: http://ai.baidu.com/forum/topic/list/199 描述使用遇到的问题,我们将及时回复您的问题。

          上一篇
          EdgeBoard(FZ)专用SDK集成文档
          下一篇
          Jetson专用SDK集成文档