Press "Enter" to skip to content

用 WasmEdge 和 YoMo 对实时数据流进行 AI 推理

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

YoMo 是一个用于辅助开发者方便构建分布式云系统(Geo-Distributed Cloud System)的编程框架。YoMo 的通讯层构建在 QUIC 协议之上,带来高速数据传输的同时,内置了 Streaming Serverless 的“流函数”,大幅提升了分布式云系统的开发体验。YoMo 构建的分布式云系统在近场算力和终端之间提供了超高速通讯机制,在 Metaverse、VR/AR、IoT 等领域有广泛的应用场景。

 

YoMo 使用 Go 语言编写,Streaming Serverless 部分使用了 Golang 的插件和共享库动态加载用户代码和共享库,但也给开发者带来了一些局限性,尤其是使用 Windows 的开发者。加之Serverless 架构对隔离的刚性需求,这使得 WebAssembly 成为运行用户定义函数的绝佳选择。

 

例如在 AR/VR、智能工厂里做实时 AI 推理的过程中,摄像头可以通过 YoMo 将实时的非结构化数据发送到近场 MEC (多访问边缘计算)设备中的计算节点,并自动执行托管的 AI 推理函数。当 AI 推理完成,YoMo将 AI 计算结果实时发送给端设备。

 

然而,YoMo 面临的挑战是在边缘计算节点中合并和管理由多个外部开发者编写的处理程序函数。这需要在不牺牲性能的情况下对这些函数进行 runtime 隔离。传统的软件容器解决方案,如 Docker,无法胜任这项任务,因为太重且速度太慢,无法处理实时任务。

 

WebAssembly 提供了一个轻量级高性能的软件容器。它非常适合作为 YoMo 数据处理 handler 函数的 runtime。

 

本文中,我们将向你展示如何为基于 的图片识别创建 函数,将其编译为 WebAssembly,然后使用 YoMo 将其作为流数据 handler 运行。我们使用WasmEdge 作为 WebAssembly runtime,因为与其它 WebAssembly runtime 相比,WasmEdge 提供了最佳性能和最高灵活度。WasmEdge 是唯一稳定支持 Tensorflow 的 WebAssembly 虚拟机。 YoMo 通过 WasmEdge 的Golang API
管理 WasmEdge VM 实例和容器内的 WebAssembly 字节码应用。

 

GitHub 源代码:github.com/yomorun/yom…

 

准备工作

 

显然,需要安装Golang 。我们假设你已经安装。

 

Golang 版本需要比 1.15 新,我们的示例才能运行。

 

同时,需要安装 YoMo CLI 应用程序。它安排和协调数据流和 handler 函数调用。

 

$ go install github.com/yomorun/cli/[email protected]
$ yomo version
YoMo CLI version: v0.0.5

 

接下来,请安装 WasmEdge 及 Tensorflow 共享库。WasmEdge 是领先的 WebAssembly runtime,由 CNCF 托管。 我们将使用它嵌入和运行来自 YoMo 的 WebAssembly 程序。

 

# Install WasmEdge
$ wget https://github.com/second-state/WasmEdge-go/releases/download/v0.8.1/install_wasmedge.sh
$ chmod +x ./install_wasmedge.sh
$ sudo ./install_wasmedge.sh /usr/local
# Install WasmEdge Tensorflow extension
$ wget https://github.com/second-state/WasmEdge-go/releases/download/v0.8.1/install_wasmedge_tensorflow_deps.sh
$ wget https://github.com/second-state/WasmEdge-go/releases/download/v0.8.1/install_wasmedge_tensorflow.sh
$ chmod +x ./install_wasmedge_tensorflow_deps.sh
$ chmod +x ./install_wasmedge_tensorflow.sh
$ sudo ./install_wasmedge_tensorflow_deps.sh /usr/local
$ sudo ./install_wasmedge_tensorflow.sh /usr/local
# Install WasmEdge Images extension
$ wget https://github.com/second-state/WasmEdge-go/releases/download/v0.8.1/install_wasmedge_image_deps.sh
$ wget https://github.com/second-state/WasmEdge-go/releases/download/v0.8.1/install_wasmedge_image.sh
$ chmod +x ./install_wasmedge_image_deps.sh
$ chmod +x ./install_wasmedge_image.sh
$ sudo ./install_wasmedge_image_deps.sh /usr/local
$ sudo ./install_wasmedge_image.sh /usr/local

 

最后, 因为我们的 demo WebAssembly 函数是用 Rust 编写的,因此你还需要安装 Rust 编译器和rustwasmc工具链。

 

demo 的其它部分可以 fork 和 clone源代码 repo

 

$ git clone https://github.com/yomorun/yomo-wasmedge-tensorflow.git

 

图片分类函数

 

处理 YoMo 图片流的图片识别函数
是用 Rust 编写的。 它用 WasmEdge Tensorflow API 来处理输入图片。

 

#[wasm_bindgen]
pub fn infer(image_data: &[u8]) -> String {

    let model_data: &[u8] = include_bytes!("lite-model_aiy_vision_classifier_food_V1_1.tflite");
    let labels = include_str!("aiy_food_V1_labelmap.txt");

    let flat_img = wasmedge_tensorflow_interface::load_jpg_image_to_rgb8(image_data, 192, 192);
    

    let mut session = wasmedge_tensorflow_interface::Session::new(&model_data, wasmedge_tensorflow_interface::ModelType::TensorFlowLite);
    session.add_input("input", &flat_img, &[1, 192, 192, 3])
           .run();
    let res_vec: Vec<u8> = session.get_output("MobilenetV1/Predictions/Softmax");



    
    ret_str = format!(
        "It {} a <a href='https://www.google.com/search?q={}'>{}</a> in the picture",
        confidence, food_name, food_name
    );
    return ret_str;
}

 

你可以使用rustwasmc 工具将该函数编译为 WebAssembly 字节码。

 

这里,我们要求 Rust 编译器版本为 1.50 或更早,才能让 WebAssembly 函数与 WasmEdge 的 Golang API 一起使用。一旦 interface type 规范最终确定并得到支持,我们会赶上最新的Rust 编译器版本

 

$ rustup default 1.50.0
$ cd flow/rust_mobilenet_food
$ rustwasmc  build `--enable-ext`
# The output WASM will be pkg/rust_mobilenet_food_lib_bg.wasm.
# Copy the wasm bytecode file to the flow/ directory
$ cp pkg/rust_mobilenet_food_lib_bg.wasm ../

 

与 YoMo 集成

 

在 YoMo 这端,我们使用 WasmEdge Golang API 来为图片识别函数启动和运行 WasmEdge 虚拟机。app.go
文件在源代码项目中如下:

 

package main
... ...
var (
    vm      *wasmedge.VM
    vmConf  *wasmedge.Configure
    counter uint64
)
func main() {

    initVM()
    defer vm.Delete()
    defer vmConf.Delete()

    cli, err := client.NewServerless("image-recognition").Connect("localhost", 9000)
    if err != nil {
        log.Print(":x: Connect to zipper failure: ", err)
        return
    }
    defer cli.Close()
    cli.Pipe(Handler)
}

func Handler(rxStream rx.RxStream) rx.RxStream {
    stream := rxStream.
        Subscribe(ImageDataKey).
        OnObserve(decode).
        Encode(0x11)
        
    return stream
}

var decode = func(v []byte) (interface{}, error) {

    p, _, _, err := y3.DecodePrimitivePacket(v)
    if err != nil {
        return nil, err
    }
    img := p.ToBytes()

    res, err := vm.ExecuteBindgen("infer", wasmedge.Bindgen_return_array, img)
    
    return hash, nil
}
... ...

func initVM() {
    wasmedge.SetLogErrorLevel()
    vmConf = wasmedge.NewConfigure(wasmedge.WASI)
    vm = wasmedge.NewVMWithConfig(vmConf)
    var wasi = vm.GetImportObject(wasmedge.WASI)
    wasi.InitWasi(
        os.Args[1:],     
        os.Environ(),    
        []string{".:."}, 
        []string{},      
    )

    var tfobj = wasmedge.NewTensorflowImportObject()
    var tfliteobj = wasmedge.NewTensorflowLiteImportObject()
    vm.RegisterImport(tfobj)
    vm.RegisterImport(tfliteobj)
    var imgobj = wasmedge.NewImageImportObject()
    vm.RegisterImport(imgobj)

    vm.LoadWasmFile("rust_mobilenet_food_lib_bg.wasm")
    vm.Validate()
    vm.Instantiate()
}

 

运行

 

最后,我们启动 YoMo 并查看整个数据处理管道的运行情况。从项目文件夹启动 YoMo CLI 应用程序。yaml
文件定义了 YoMo 应听取的端口以及触发传入数据的工作流 handler。请注意,流名称image-recognition
与上面提到的数据 handlerapp.go
相匹配。

 

$ yomo serve -c ./zipper/workflow.yaml

 

通过运行上面提到的app.go
程序启动 handler 程序。

 

$ cd flow
$ go run --tags "tensorflow image" app.go

 

通过给 YoMo 发送数据来启动模拟数据源
。 视频是一系列图片帧。app.go
中的 WasmEdge 函数将针对视频中的每个图片帧进行调用。

 

# Download a video file
$ wget -P source 'https://github.com/yomorun/yomo-wasmedge-tensorflow/releases/download/v0.1.0/hot-dog.mp4'
# Stream the video to YoMo
$ go run ./source/main.go ./source/hot-dog.mp4

 

你可以在控制台中看到 WasmEdge handler函数的输出。它将在视频的每个图片帧中检测到的对象的名称进行打印。

 

展望未来

 

本文讨论了如何使用 YoMo 框架中的 WasmEdge Tensorflow API 和 Golang SDK 来几近实时地处理图片流。

 

与 YoMo 合作,我们很快将在智能工厂的实际生产中部署 WasmEdge,用于各种装配线上的任务。 WasmEdge 是边缘计算的软件 runtime!

Be First to Comment

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注