yuenshome / yuenshome.github.io

https://yuenshome.github.io
MIT License
84 stars 15 forks source link

MegFlow 之 15 分钟把模型变为服务:x86平台在线视频流检测报警 #136

Open ysh329 opened 3 years ago

ysh329 commented 3 years ago

MegFlow 之 15 分钟 x86 CPU + GPU平台推理服务部署:在线视频流检测报警

MegFlow 是近期开源的一个推理 服务 框架,在推理框架中间插入了一个“服务”,因为根据文档,其试图解决的是长尾部署问题长尾,如何理解呢(下面第一点),第二与第三是根据其特点总结:

  1. 教程提供两个示例:图片、视频检测完整推理服务实例(但从这两个实例上就切中了很多需求场景)。打开即用,算法模型训练同学完全不用担心工程部署的各种问题(如搭建推理服务中的环境配置、各种第三方C/C++库的集成,纯流程化的改进人力不足的问题);
  2. 纯 Python 搭建计算图,好用易用。无需C/C++背景,算法同学,即可修改完整业务计算逻辑,建图语言toml简单好用;
  3. 计算图描述完整业务逻辑。从业务特定需求,到检测、跟踪、质量判别/识别。支持静态、动态、共享子图。

img

图:MegFlow 项目 Logo

目前 MegFlow 支持的平台,涵盖 3 个系统平台:

  1. Windows 10 Docker / WSL2;
  2. x86 Ubuntu 16.04 CPU/GPU;
  3. x86 MacOS。

我也是第一次使用,下面基于 Windows 10 WSL2 的环境,将根据文档尝试部(踩)署(坑)一个视频检测服务。下面按照这样的顺序来记录:

  1. 安装 MegFlow
  2. 建图语言:toml 2.1 计算图的调度与优化
  3. 应用案例:电梯电瓶车告警 3.1 准备模型 3.2 准备服务环境:Redis、RTSP Server、视频推流 推视频流方式一:笔记本推本地摄像头 推视频流方式二:笔记本推本地视频文件 3.3 启动 MegFlow 服务
  4. 参考
ysh329 commented 3 years ago

1. 安装 MegFlow

环境安装这部分完全按照 Run in 15 minutes 文档进行:先安装 MiniConda 等环境:

$ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
$ chmod a+x Miniconda3-latest-Linux-x86_64.sh
$ ./Miniconda3-latest-Linux-x86_64.sh

下载 MegFlow-v0.1.0-beta0-20210907 的预编译包,链接如下:https://github.com/MegEngine/MegFlow/releases (PS:因为开源协议的问题,可能未来会提供 whl 包),根据安装的 MiniConda 版本选择我是 Python3.8 ,浏览器下载完 whl 包后,安装:

$ conda activate  /home/stayua01/miniconda3/envs/py38
$ pip install ./pyflow-0.1.0-py38-none-linux_x86_64.whl

# logs below
Processing ./pyflow-0.1.0-py38-none-linux_x86_64.whl
Installing collected packages: pyflow
Successfully installed pyflow-0.1.0

但当执行 run_with_plugins_python_wrap 时,会报错:

$ run_with_plugins_python_wrap
/home/stayua01/miniforge3/envs/py38/lib/python3.8/site-packages/pyflow/run_with_plugins: error while loading shared libraries: libpython3.8.so.1.0: cannot open shared object file: No such file or directory

$ ldd /home/stayua01/miniforge3/envs/py38/lib/python3.8/site-packages/pyflow/run_with_plugins
        linux-vdso.so.1 (0x00007ffe68b68000)
        libpython3.8.so.1.0 => not found
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fdcd03b2000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fdcd01aa000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fdccff8b000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdccfbed000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdccf9e9000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdccf5f8000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fdcd2abd000)

上面,根据ldd命令定位到是没找到libpython3.8.so.1.0,啊呀这个咋办呢,原来文档给出了解决方案,只需要执行下面这句话,将 miniconda3 的路径追加到LD_LIBRARY_PATH中即可:

$ export LD_LIBRARY_PATH=/home/`whoami`/miniconda3/pkgs/python-3.8.11-h12debd9_0_cpython/lib:${LD_LIBRARY_PATH}

好了,下面一切如预期:

$ run_with_plugins_python_wrap --help
run_with_plugins 1.0
megvii

USAGE:
    run_with_plugins [FLAGS] [OPTIONS] --plugin <PLUGIN>

FLAGS:
        --dump       the path to dump graph
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -c, --config <CONFIG>    config path
        --debug <PORT>       debug mode
    -m, --module <MODULE>    module path
    -p, --plugin <PLUGIN>    plugin path

按照文档,可以通过 logical_test 自检一下 MegFlow 是否编译成功且语义无误,自检过程也是 MegFlow 的单元测试,测试遵循 建图->调度->优化 的顺序:

# 在 MegFlow 根目录下执行
$ cd ./flow-python/examples

# -p 参数指定 plugin 目录
$ run_with_plugins_python_wrap -p logical_test

# 执行成功会给出下面的日志
Printer[185] get msg: a message[send to 185] repeat 6 by process node, buf(global, parent, local): (7, 1, 2)
Printer[185] get msg: a message[send to 185] repeat 7 by process node, buf(global, parent, local): (8, 0, 3)
Printer[185] get msg: a message[send to 185] repeat 8 by process node, buf(global, parent, local): (9, 1, 4)
Printer[185] get msg: a message[send to 185] repeat 9 by process node, buf(global, parent, local): (0, 0, 0)

执行到这里,我们的安装也就完成了。

ysh329 commented 3 years ago

2. 建图语言:toml

上面的logical_test就会先根据预设的图结构文件flow-python/examples/logical_test/logical_test.toml来建图,而 MegFlow 的建图描述文件使用的是 toml 格式,tomlTom's Obvious, Minimal Language. 的缩写,一种配置文件的语法,可以根据键值对映射到哈希表,也支持复杂的严谨类型表示如类型嵌套,在 MegFlow 中的文档 appendix-A-graph-definition.md 有说明(建议这个文档从后往前读),这个 toml 有点类似 YMAL 或者 JSON,但 toml 特点在:

TOML always has a hash table at the top level of the file, which can easily have data nested inside its keys, but it doesn't permit top-level arrays or floats, so it cannot directly serialize some data. There is also no standard identifying the start or end of a TOML file, which can complicate sending it through a stream. These details must be negotiated on the application layer.

没有始末的标志,所以可以作为数据流来处理,但不能用于序列化数据。项目示例中有一个例子是 cat_finder/video_gpu.toml ,其可视化出来如下:

video_gpu

图:计算流图的逻辑

而刚刚的 logical_test来说,其 toml 内容也是类似的描述,每个文件对应一个 struct Config ,而进一步的定义为(更详细的说明见 appendix-A-graph-definition.md): 根据文档说明,run_with_plugins_python_wrap调用的pyflow仅仅是一层接口,但执行流程包含了建图>调度>优化。

struct Graph {
    name: String,                                       // 图的名字
    resources: Vec<Resource>             // 资源声明, 生命周期与该图绑定
    nodes: Vec<Node>,                          // 节点声明,生命周期与该图绑定
    inputs: Vec<NamedConn>,           // 图输入声明
    outputs: Vec<NamedConn>,        // 图输出声明
    connections: Vec<Connection>, // 节点间连接声明
}

struct Config {
    resources: Vec<Resource>            // 全局共享资源, 生命周期与整个应用绑定
    nodes: Vec<Node>,                          // 全局共享节点,生命周期与整个应用绑定
    graphs: Vec<Graph>,                      // 图声明
    main: String,                                      // 主图名字,及应用的进入点
}

通过对图的描述,可以将服务的完整流程,清晰地描述出来,通过使用 toml 建图的过程并不困难。

2.1 计算图的调度与优化

当前 GitHub 还没有关于 调度 与 优化 的文档。据了解:

期待后续,相关文档的补充。这里 at 一下白会长~

ysh329 commented 3 years ago

3. 应用案例:电梯电瓶车告警

我看案例是电瓶车,就搜索了一下电瓶车相关的新闻,有一条提到:把锂电池这种客观存在易燃易爆威胁的东西,带进客梯这种封闭狭小的空间,本身就属于祸己害人的大型作死行为。这可不仅仅是物业的规劝。事实上,在某些地区的最新版安全规章当中,已经明确将 " 电动车进入载客电梯 " 写成了禁止事项,例如《甘肃省消防条例》。

img

图:电梯内电瓶车起火

ysh329 commented 3 years ago

既然上面安装完了,下面按照 electric_bicycle 部署电瓶车报警服务。这个服务的部署背景是这样的:当镜头出现电瓶车时,会给出报警信号,但若已经报警过,则不会重复报警。

3.1 准备模型

文档 给了一个示例模型,从云盘(提取码:ebcn)下载后,软连接到 examples/models 目录:

$ cd flow-python/examples
$ ln -s ${DOWNLOAD_DIR}/models models

3.2 准备服务环境:Redis、RTSP Server、视频推流

下面也是按照文档的顺序继续准备环境:

# 一个窗口启动redis server,也可以启动后让其在后台运行
$ sudo apt install redis-server
$ redis-server
2242:C 10 Sep 00:32:59.587 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2242:C 10 Sep 00:32:59.587 # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=2242, just started
2242:C 10 Sep 00:32:59.587 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
2242:M 10 Sep 00:32:59.587 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
2242:M 10 Sep 00:32:59.587 # Server can't set maximum open files to 10032 because of OS error: Operation not permitted.
2242:M 10 Sep 00:32:59.587 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 4.0.9 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 2242
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

2242:M 10 Sep 00:32:59.588 # Server initialized
2242:M 10 Sep 00:32:59.588 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or
run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
2242:M 10 Sep 00:32:59.588 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
2242:M 10 Sep 00:32:59.588 * Ready to accept connections

# 一个窗口安装执行剩下的命令
$ conda activate py38
$ pip3 install onnxruntime --user

准备 rtsp 视频流地址,并作为输入,科普一下:

实时流协议(Real Time Streaming Protocol,RTSP)是一种网络应用协议,专为娱乐和通信系统的使用,以控制流媒体服务器。该协议用于创建和控制终端之间的媒体会话。媒体服务器的客户端发布VCR命令,例如播放,录制和暂停,以便于实时控制从服务器到客户端(视频点播)或从客户端到服务器(语音录音)的媒体流。

流数据本身的传输不是RTSP的任务。大多数RTSP服务器使用实时传输协议(RTP)和实时传输控制协议(RTCP)结合媒体流传输。然而,一些供应商实现专有传输协议。例如,RealNetworks公司的RTSP服务器软件也使用RealNetworks的专有实时数据传输(RDT)。

由于使用的是笔记本,按照文档的贴心教程:《如何生成自己的 rtsp 流地址》,进行准备:

$ wget https://github.com/aler9/rtsp-simple-server/releases/download/v0.17.2/rtsp-simple-server_v0.17.2_linux_amd64.tar.gz
$ tar xvf rtsp-simple-server_v0.17.2_linux_amd64.tar.gz && ./rtsp-simple-server

# 下面是日志
rtsp-simple-server
rtsp-simple-server.yml
2021/09/10 10:33:22 I [0/0] rtsp-simple-server v0.17.2
2021/09/10 10:33:22 I [0/0] [RTSP] UDP/RTP listener opened on :8000
2021/09/10 10:33:22 I [0/0] [RTSP] UDP/RTCP listener opened on :8001
2021/09/10 10:33:22 I [0/0] [RTSP] TCP listener opened on :8554
2021/09/10 10:33:22 I [0/0] [RTMP] listener opened on :1935
2021/09/10 10:33:22 I [0/0] [HLS] listener opened on :8888

表示 rtsp 服务成功启动。

推视频流方式一:笔记本推本地摄像头

接着,启动服务,但是考虑到我是笔记本环境win10-wsl2.0-ubuntu18.04环境,先尝试启动摄像头,但失败了:

$ ffmpeg -framerate 25 -video_size 640x480 -i /dev/video0 -vcodec h264 -f rtsp rtsp://127.0.0.1:8554/test
ffmpeg version 3.4.8-0ubuntu0.2 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
  configuration: --prefix=/usr --extra-version=0ubuntu0.2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
[video4linux2,v4l2 @ 0x5647f6402580] Cannot open video device /dev/video0: No such file or directory

推视频流方式二:笔记本推本地视频文件

因而转向尝试笔记本环境推本地视频文件的方式:首先将手机录制好的 *.mp4 转为 *.ts 格式,我在网上找了一段电动车的视频,然后用手机录像另存为 electric_bicycle_video.mp4 到电脑上,按照下面命令转为 ts 格式:

$ ffmpeg -i  electric_bicycle_video.mp4 -s 640x480  -q:v 2 -vcodec copy -an  electric_bicycle_video.ts

# 下面是日志
ffmpeg version 3.4.8-0ubuntu0.2 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
  configuration: --prefix=/usr --extra-version=0ubuntu0.2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'electric_bicycle_video.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.33.100
    copyright       :
    copyright-eng   :
  Duration: 00:00:08.53, start: 0.000000, bitrate: 2144 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720, 1972 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
    Metadata:
      rotate          : 90
      handler_name    : VideoHandler
    Side data:
      displaymatrix: rotation of -90.00 degrees
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 192 kb/s (default)
    Metadata:
      rotate          : 90
      handler_name    : SoundHandler
Output #0, mpegts, to 'electric_bicycle_video.ts':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    copyright-eng   :
    copyright       :
    encoder         : Lavf57.83.100
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1280x720, q=2-31, 1972 kb/s, 30 fps, 30 tbr, 90k tbn, 15360 tbc (default)
    Metadata:
      rotate          : 90
      handler_name    : VideoHandler
    Side data:
      displaymatrix: rotation of -90.00 degrees
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame=  252 fps=0.0 q=-1.0 Lsize=    2212kB time=00:00:08.30 bitrate=2182.8kbits/s speed=3.3e+03x
video:2022kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 9.354525%

转成功后,能看到有个同名的 electric_bicycle_video.ts 文件,下面将该文件推给 rtsp

$ ffmpeg -re -stream_loop -1 -i electric_bicycle_video.ts -c copy -f rtsp rtsp://127.0.0.1:8554/test

# 日志如下
ffmpeg version 3.4.8-0ubuntu0.2 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
  configuration: --prefix=/usr --extra-version=0ubuntu0.2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-stripping --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librubberband --enable-librsvg --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libopencv --enable-libx264 --enable-shared
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Input #0, mpegts, from 'electric_bicycle_video.ts':
  Duration: 00:00:08.40, start: 1.466667, bitrate: 2156 kb/s
  Program 1
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1280x720, 30 fps, 30 tbr, 90k tbn, 60 tbc
Output #0, rtsp, to 'rtsp://127.0.0.1:8554/test':
  Metadata:
    encoder         : Lavf57.83.100
    Stream #0:0: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, progressive), 1280x720, q=2-31, 30 fps, 30 tbr, 90k tbn, 30 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame=  230 fps= 30 q=-1.0 size=N/A time=00:00:07.56 bitrate=N/A speed=   1x

根据日志看来是成功的,其实也可以打开 VLC 媒体播放器 - “网络串流” 并在地址输入 “rtsp://127.0.0.1:8554/test” 确保视频可以正常播放,由于我这里是 WSL 环境目前还没有比较好的 Run Linux GUI app 的方法(微软官方要求Win11 Build 22000 及以上,且安装vGPU driver,我都不满足)。不过虽然是 WSL2 的环境,但是通过 WSL2 里的 IP 地址,也依然可以在 WIN10 播放流媒体视频,只是画质确实不好。我尝试了 Windows Player,以失败告终,安装了 Windows 版本的 VLC 播放器。验证过程如下图:

image-20210916203449592

图:启动 RTSP 服务、推流、查看 WSL2 内IP地址

image-20210916203606772

图:使用 VLC 播放器播放 WSL2 内的流媒体视频

image-20210916202900586

图:VLC 播放流媒体视频效果

除了笔记本设备外,在文档中,也有讲到树莓派实时推流的方法,我这里没有摄像头就不试了。

以上,我们便准备完了 Redis、RTSP Server、视频推流,这三个基本环境。

ysh329 commented 3 years ago

3.3 启动 MegFlow 服务

下面继续跟着文档,最后一步:启动 megflow app 电瓶车示例代码,即在 run_with_plugins_python_wrap 后接计算图路径 electric_bicyle/electric_bicyle.toml即可。

$ cd flow-python/examples
$ run_with_plugins_python_wrap -c electric_bicycle/electric_bicycle.toml  -p electric_bicycle # prebuilt 安装用这个,不需要`cargo run`来编译

# 发现报错如下
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ModuleNotFoundError: No module named 'loguru'', flow-rs/src/lib.rs:90:42
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

# 原因看来是少装了一些 Python required package
$ pip install -r requires.txt
Installing collected packages: scipy, redis, opencv-python, loguru
Successfully installed loguru-0.5.3 opencv-python-4.5.3.56 redis-3.5.3 scipy-1.7.1

# 再试一下
$ run_with_plugins_python_wrap -c electric_bicycle/electric_bicycle.toml  -p electric_bicycle # prebuilt 安装用这个,不需要`cargo run`来编译
2021-09-10 12:59:47.905 | INFO     | electric_bicycle.det:__init__:21 - loading MEMD detection...
2021-09-10 12:59:48.603 | INFO     | warehouse.detection_memd.onnx_model:run:111 - memd inference: 0.30202579498291016s
2021-09-10 12:59:48.603 | INFO     | electric_bicycle.det:__init__:33 -  MEMD loaded.
2021-09-10 12:59:48.606 | INFO     | electric_bicycle.redis_proxy:__init__:22 - init redis pool...
2021-09-10 12:59:48.606 | INFO     | electric_bicycle.redis_proxy:__init__:32 - redis pool initialized.

# 如果上面执行OK就完事儿了,如果是源码或 docker 安装用下面这个
$ cargo run --example run_with_plugins -- -c electric_bicycle/electric_bicycle.toml  -p electric_bicycle  

计算图的服务配置文件在electric_bicycle/electric_bicycle.toml,解释参考 appendix-A-graph-definition.md 。这里只需要打开 8083 端口服务,操作和另一个官方示例 猫猫围栏 近似。如果是 Linux 环境,可以直接用命令 google-chrome-stable http://127.0.0.1:8083/docs 启动。

但我用的是 WSL2 的环境,没有 GUI,见:但是可以 Win10 上浏览器打开上面的链接,其中将 127.0.0.1替换成前面所说的 WSL2 内的 IP 地址(其实不换也可):

image-20210916204454948

图:电瓶车检测推理服务 API Web 页面

image-20210916205122166 图:电瓶车检测推理服务 API Web控制台操作

然后,在GET/get_msgs/{id}类似的,点击“try it out”,填入刚得到的id,点击Execute,会出现检测到电瓶车的英文提示。对应的日志,在终端也会给出如下:

1632315909(1) 图:终端检测到电瓶车给出提示

如果想看画框的结果,那么可以调用 Web UI 里的 get msg 接口。

4. 总结

以上,就是尝试 MegFlow 部署在线视频流检测服务的例子。这个过程是按照教程来走的,实际中应该还有不少坑:

  1. 如自定义计算逻辑图:在发文时候,看到这方面的文档在增加:把模型变成服务
  2. 在使用过程中也发现视频检测流,当检到电瓶车会停掉,后来 @白会长 指导后修好,但还有个逻辑问题,期待完善;
  3. 文档:Debug/Profile等。在不同环节,如果出了问题如计算图,怎么debug等等,我想或许这是很多小白会遇到的;

其实,全流程的方案,目前已经有不少家,如 Google 的 MediaPipe、或者基于前者简化的 OPEN AI LAB 的 TengineInferPipe ,都希望能做到:通过解析部署配置文件,构建整个部署流程。可以用于快速构建算法部署 SDK。目前 MegFlow 这次主推的是非 Arm 平台,也期待后续其他平台慢慢跟进。

最后,希望 Face++ 能稳定持续对 MegEngine 投入资源,并做得更好!

下面列出参考链接。

ysh329 commented 3 years ago

参考

  1. MegEngine/MegFlow: Efficient ML solutions for long-tailed demands. https://github.com/MegEngine/MegFlow
  2. MegFlow/appendix-A-graph-definition.md at master · MegEngine/MegFlow https://github.com/MegEngine/MegFlow/blob/master/docs/how-to-add-my-service/appendix-A-graph-definition.md
  3. TOML: Tom's Obvious Minimal Language https://toml.io/en/
  4. toml-lang/toml: Tom's Obvious, Minimal Language https://github.com/toml-lang/toml
  5. Run Linux GUI apps with WSL | Microsoft Docs https://docs.microsoft.com/en-us/windows/wsl/tutorials/gui-apps
  6. MegFlow/how-to-generate-rtsp.zh.md at master · MegEngine/MegFlow https://github.com/MegEngine/MegFlow/blob/master/docs/how-to-generate-rtsp.zh.md
  7. 实时流协议 - 维基百科,自由的百科全书 https://zh.wikipedia.org/wiki/%E5%8D%B3%E6%99%82%E4%B8%B2%E6%B5%81%E5%8D%94%E5%AE%9A