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
python -m pip install visualdl==2.5.0
git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy/examples visualdl --host 0.0.0.0 --port 8080
FastDeploy/examples/vision/detection/paddledetection/serving/models
目录 | 文件 | 备注 |
---|---|---|
models/preprocess/1 | infer_cfg.yml | 配置文件 |
models/runtime/1 | model.pdmodel | 模型 |
models/runtime/1 | model.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
配置模型
注意 这里根据自己机器的实际情况配置,由于本文使用的CPU版本的 FastDeploy 且也没有 GPU ,所以有关 GPU 的配置一概不选。
启动服务
提供HTTP\GRPC服务
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; } }
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)
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'])
后台监控