AI 模型 - 服务部署 (FastDeploy 及其 VisualDL(可视化部署))-- 吸烟检测(目标检测)

avatar
作者
筋斗云
阅读量:2

FastDeploy 及其 VisualDL(可视化部署)

1. Docker 安装

CPU版本
docker-compose.yml

version: '4.0' services:   paddle_serving_cpu:     image: registry.baidubce.com/paddlepaddle/fastdeploy:1.0.7-cpu-only-21.10     container_name: fastdeploy     ports:       - 9393:8080     command: bash     tty: true     working_dir: /root     # 挂载目录     volumes:       - /var/data/FastDeploy/root:/root 

1.1 容器内操作

  1. 安装 VisualDL 2.5.0 ,此版本界面如下。
    注意:不同版本之间界面会有差异功能也有差异。
python -m pip install visualdl==2.5.0 

在这里插入图片描述

  1. git 示例
git clone https://github.com/PaddlePaddle/FastDeploy.git 
  1. 从指定目录启动,FastDeploy 项目下的 examples 目录
cd FastDeploy/examples visualdl --host 0.0.0.0 --port 8080 

在这里插入图片描述

2. VisualDL 可视化部署

2.1 PPYOLOE 模型,部署示例 – 吸烟检测

  1. 载入模型库
    注意:这里的只是提供调用模型的结构,如前处理、后处理等…

FastDeploy/examples/vision/detection/paddledetection/serving/models

在这里插入图片描述
在这里插入图片描述

  1. 将训练好的模型,按照以下规则分别放入文件夹。
    如果没有自己训练的模型也可以下载一个预训练模型-吸烟
目录文件备注
models/preprocess/1infer_cfg.yml配置文件
models/runtime/1model.pdmodel模型
models/runtime/1model.pdiparams

将ppdet和runtime目录下的ppyoloe配置文件重命名成标准的config名字

cp models/ppdet/ppyoloe_config.pbtxt models/ppdet/config.pbtxt cp models/runtime/ppyoloe_runtime_config.pbtxt models/runtime/config.pbtxt # 注意: 由于mask_rcnn模型多一个输出,需要将后处理目录(models/postprocess)中的mask_config.pbtxt重命名为config.pbtxt cp models/postprocess/mask_config.pbtxt models/postprocess/config.pbtxt  
  1. 配置模型
    注意 这里根据自己机器的实际情况配置,由于本文使用的CPU版本的 FastDeploy 且也没有 GPU ,所以有关 GPU 的配置一概不选。
    在这里插入图片描述

  2. 启动服务
    提供HTTP\GRPC服务
    在这里插入图片描述

3. 远程调用

3.1 Java 调用 - HTTP

package cn.nhd.fsl.controller.test;  import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.squareup.okhttp.*;  import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException;  public class FastDeploy {       public static void main(String[] args) throws IOException {           int[][][] ints = readImagePath("D:\\code\\fastdeploy\\pythonProject1\\image\\OIP1.jpg"); 		// 这里 640, 640,填写图片实际的像素尺寸 		// 也可以直接获取图片尺寸大小,这里懒得改了         JSONObject json = generateJson(640, 640, ints);          String s = fastDeployConnect(json.toJSONString());          System.out.println(s);           // 使用Fastjson解析JSON字符串         JSONObject jsonObject = JSON.parseObject(s);          // 访问outputs对象         JSONArray outputsArray = jsonObject.getJSONArray("outputs");          JSONObject jsonObject1 = outputsArray.getJSONObject(0);          JSONArray data = jsonObject1.getJSONArray("data");         String dataStr = data.getString(0);          JSONObject dataJson = JSON.parseObject(dataStr);          JSONArray scores = dataJson.getJSONArray("scores");          String scoresStr = scores.getString(0);          double score = Double.parseDouble(scoresStr); 		// 阈值,超过阈值的认为是吸烟行为。范围 0 ~ 1         if (score > 0.5) {             System.out.println("异常行为");         } else {             System.out.println("正常行为");         }       }       /**      * 返回图片的RGB三维数组      * @param path 图片路径      * @return      * @throws IOException      */     public static int[][][] readImagePath(String path) throws IOException {         BufferedImage image = ImageIO.read(new File(path));         int height = image.getHeight();         int width = image.getWidth();         int[][][] rgbArray = new int[height][width][3];         for (int row = 0; row < height; row++) {             for (int col = 0; col < width; col++) {                 int pixel = image.getRGB(col, row);                 rgbArray[row][col][0] = (pixel >> 16) & 0xff; // R                 rgbArray[row][col][1] = (pixel >> 8) & 0xff; // G                 rgbArray[row][col][2] = pixel & 0xff; // B             }         }         return rgbArray;     }       /**      * 生成json对象,懒得搞一堆对应的类了      * @param imgHeight      * @param imgWidth      * @param rgbArray      * @return      */     public static JSONObject generateJson(int imgHeight, int imgWidth, int[][][] rgbArray) {         JSONObject jsonObject = new JSONObject();         JSONArray inputArray = new JSONArray();         JSONObject inputObject = new JSONObject();         JSONArray shapeArray = new JSONArray();         shapeArray.add(1);         shapeArray.add(imgHeight);         shapeArray.add(imgWidth);         shapeArray.add(3);         JSONArray dataArray=new JSONArray();         JSONArray datajsonArray = JSONArray.parseArray(JSONArray.toJSONString(rgbArray));         dataArray.add(datajsonArray);         inputObject.put("name", "INPUT");         inputObject.put("shape", shapeArray);         inputObject.put("datatype", "UINT8");         inputObject.put("data", dataArray);         inputArray.add(inputObject);         jsonObject.put("inputs", inputArray);         return jsonObject;     }       /**      * 连接新方式部署的ocr服务      *      * @param jsonParamStr      * @return      */     public static String fastDeployConnect(String jsonParamStr) throws IOException {          MediaType mediaType = MediaType.parse("application/json");         RequestBody body = RequestBody.create(mediaType, jsonParamStr);  		// 填写实际的地址         Request request = new Request.Builder()                 .url("http://{IP}:{接口}/v2/models/ppdet/versions/1/infer")                 .post(body)                 .build();          OkHttpClient client = new OkHttpClient();          Response response = client.newCall(request).execute();          String str = response.body().string();          return str;     } } 

3.2 Python 调用 - HTTP

from PIL import Image, ImageDraw import numpy as np import json import requests  img_path = 'D:\\code\\fastdeploy\pythonProject1\image\\OIP1.jpg'  # 打开图片文件 img = Image.open(img_path)  # 检查图片是否已经是RGB格式 if img.mode != 'RGB':     # 将图片转换为RGB格式     img_rgb = img.convert('RGB') else:     # 图片已经是RGB格式,无需转换     img_rgb = img  # 修改图片尺寸为 640x640 # 也可不用修改,但对应的入参,要填入图片实际尺寸 #"shape": [ #               1, #               640, #               640, #               3 #           ] img_resized = img_rgb.resize((640, 640))  # 将图片解析成 RGB 三维数组 img_array = np.array(img_resized)  # 确保数据类型为 float32 # img_array = img_array.astype(np.float32)  # 定义请求的URL url = 'http://{IP}:{接口}}/v2/models/ppdet/versions/1/infer'  # 初始化请求体的数据结构 data1 = {     "inputs": [         {             "name": "INPUT",             "datatype": "UINT8",             "shape": [                 1,                 640,                 640,                 3             ],             "data": img_array.tolist()         }     ] }  # 将字典转换为JSON字符串 json_data = json.dumps(data)  # 发送POST请求 response = requests.post(url, headers={'Content-Type': 'application/json'}, data=json_data)  # 打印响应内容 print(response.text) 

3.3 Python 调用 - GRPC

import logging import numpy as np import time from typing import Optional import cv2 import json  from tritonclient import utils as client_utils from tritonclient.grpc import InferenceServerClient, InferInput, InferRequestedOutput, service_pb2_grpc, service_pb2  LOGGER = logging.getLogger("run_inference_on_triton")   class SyncGRPCTritonRunner:     DEFAULT_MAX_RESP_WAIT_S = 120      def __init__(             self,             server_url: str,             model_name: str,             model_version: str,             *,             verbose=False,             resp_wait_s: Optional[float] = None, ):         self._server_url = server_url         self._model_name = model_name         self._model_version = model_version         self._verbose = verbose         self._response_wait_t = self.DEFAULT_MAX_RESP_WAIT_S if resp_wait_s is None else resp_wait_s          self._client = InferenceServerClient(             self._server_url, verbose=self._verbose)         error = self._verify_triton_state(self._client)         if error:             raise RuntimeError(                 f"Could not communicate to Triton Server: {error}")          LOGGER.debug(             f"Triton server {self._server_url} and model {self._model_name}:{self._model_version} "             f"are up and ready!")          model_config = self._client.get_model_config(self._model_name,                                                      self._model_version)         model_metadata = self._client.get_model_metadata(self._model_name,                                                          self._model_version)         LOGGER.info(f"Model config {model_config}")         LOGGER.info(f"Model metadata {model_metadata}")          for tm in model_metadata.inputs:             print("tm:", tm)         self._inputs = {tm.name: tm for tm in model_metadata.inputs}         self._input_names = list(self._inputs)         self._outputs = {tm.name: tm for tm in model_metadata.outputs}         self._output_names = list(self._outputs)         self._outputs_req = [             InferRequestedOutput(name) for name in self._outputs         ]      def Run(self, inputs):         """         Args:             inputs: list, Each value corresponds to an input name of self._input_names         Returns:             results: dict, {name : numpy.array}         """         infer_inputs = []         for idx, data in enumerate(inputs):             infer_input = InferInput(self._input_names[idx], data.shape,                                      "FP32")             infer_input.set_data_from_numpy(data)             infer_inputs.append(infer_input)          infer_input1 = InferInput(self._input_names[1], [1, 2],                                   "FP32")         data = np.array([[1, 1]], dtype=np.float32)         infer_input1.set_data_from_numpy(data)         infer_inputs.append(infer_input1)          results = self._client.infer(             model_name=self._model_name,             model_version=self._model_version,             inputs=infer_inputs,             outputs=self._outputs_req,             client_timeout=self._response_wait_t, )         results = {name: results.as_numpy(name) for name in self._output_names}         return results      def _verify_triton_state(self, triton_client):         if not triton_client.is_server_live():             return f"Triton server {self._server_url} is not live"         elif not triton_client.is_server_ready():             return f"Triton server {self._server_url} is not ready"         elif not triton_client.is_model_ready(self._model_name,                                               self._model_version):             return f"Model {self._model_name}:{self._model_version} is not ready"         return None   if __name__ == "__main__":     model_name = "ppdet"     model_version = "1"     url = "{IP}:{接口}"     runner = SyncGRPCTritonRunner(url, model_name, model_version)     im = cv2.imread("D:\code\\fastdeploy\pythonProject1\image\OIP1.jpg")     im = np.transpose(im, (2, 0, 1))  # 转换通道顺序     im = np.array([im, ])     im = im.astype(np.float32)      for i in range(1):         for i in range(1):             result = runner.Run([im, ])             for name, values in result.items():                 print("output_name:", name)                 # values is batch                 for value in values:                     value = json.loads(value)                     print(value['boxes']) 

3.4 调用成功

后台监控
在这里插入图片描述

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!