当前位置:   article > 正文

在MacOS上使用OpenVINO CSharp API高效部署AI模型_openvino-csharp-api

openvino-csharp-api

作者:英特尔边缘计算创新大使:颜国进

OpenVINO™ C# API 是一个 OpenVINO™ 的 .Net wrapper,应用最新的 OpenVINO™ 库开发,通过 OpenVINO™ C API 实现 .Net 对 OpenVINO™ Runtime 调用,使用习惯与 OpenVINO™ C++ API 一致。OpenVINO™ C# API 由于是基于 OpenVINO™ 开发,所支持的平台与 OpenVINO™ 完全一致,具体信息可以参考 OpenVINO™。通过使用 OpenVINO™ C# API,可以在 .NET、.NET Framework等框架下使用 C# 语言实现深度学习模型在指定平台推理加速。

在本文中,将向大家展示如何在MacOS上使用OpenVINO CSharp API高效部署AI模型。

项目链接:

//GitHub
https://github.com/guojin-yan/OpenVINO-CSharp-API
//Gitee
https://gitee.com/guojin-yan/OpenVINO-CSharp-API

1.  配置开发环境

1.1 安装.NET运行环境

[.NET](https://learn.microsoft.com/zh-cn/dotnet/) 是由 Microsoft 创建的一个免费的、跨平台的、开源开发人员平台,可以使用 C#、F# 或 Visual Basic 语言编写代码,用于构建许多不同类型的应用程序,可以在任何兼容的操作系统上(Windows、Linux、Mac OS等)运行。

Microsoft官方提供了.NET环境的详细安装流程,大家可以参考以下文章进行安装:[在 macOS 上安装 .NET](https://learn.microsoft.com/zh-cn/dotnet/core/install/macos)。

首先访问网站[下载 .NET](https://dotnet.microsoft.com/zh-cn/download),具体下载选择如下所示:

文件下载完后,通过双击安装文件进行环境的安装:​

打开安装文件后,如下图所示,此处无需设置其他配置,只需要按照默认步骤进行安装即可。

1.2  配置C#开发环境

Linux环境下我们可以使用以下组合进行C#代码开发:

  • 代码构建工具:dotnet
  • 代码编辑工具:Visual Studio Code

在上文中我们安装.NET时已经同时安装了dotnet 工具。Visual Studio Code 是一款功能强大的代码编辑器,并且支持更多第三方插件,同时支持C#代码开发,Visual Studio Code安装比较简单,只需从VS Code官网下载安装文件,按照默认选项完成安装。

然后配置C#编辑环境,在扩展商店中搜索C#,安装C#扩展,如下图所示。

2.  创建并配置测试项目

2.1 创建C#项目

首先我们使用终端窗口命令创建一个C#项目项目,输入以下指令,创建一个.NET 6.0依赖的项目,输出如下图所示:

dotnet new console --framework net6.0 -o test_openvino_csharp --use-program-main

2.1  添加项目依赖

接下来就是添加项目所需的外部依赖项,首先可以通过VS Code打开上文创建的项目,接下来就可以使用VS Code的终端添加所需的依赖。此处主要需要添加两个依赖:

1). OpenVINO.CSharp.API

OpenVINO.CSharp.API是本文所演示项目主要使用的依赖库,目前该项目已经发布了Nuget Package,完全支持dotnet add package安装,该项目主要包含以下三个程序集:

  • OpenVINO.CSharp.API:OpenVINO 核心程序集,封装了OpenVINO™ 的 .Net wrapper接口,包含了OpenVINO™ 主要模型推理类。
  • OpenVINO.CSharp.API.Extensions:OpenVINO.CSharp.API项目中的扩展程序集,主要包含了一些扩展程序集,方便用户使用。
  • OpenVINO.runtime.macos-arm64:OpenVINO™ 在Mac OS平台运行所需的所有动态依赖库。

此处通过dotnet add package安装即可,在终端中输入以下指令即可,输出如下图所示:

  1. dotnet add package OpenVINO.CSharp.API
  2. dotnet add package OpenVINO.CSharp.API.Extensions
  3. dotnet add package OpenVINO.runtime.macos-arm64

如果开发者在使用时不确定自己所需的Nuget Package程序集名称,可以去[Nuget Package]( https://www.nuget.org/)官方网站进行查询,如下图所示:

2). OpenCvSharp4

OpenCvSharp4是OpenCV的 .Net wrapper,可以实现在C#中使用OpenCV,在该项目中由于我们需要进行图像处理,所以此处选择安装OpenCvSharp4。

  • OpenCvSharp4
  • OpenCvSharp4.Extensions
  • OpenCvSharp4.runtime.osx_arm64

关于在MacOS上搭建OpenCvSharp 开发环境请参考以下文章: [【OpenCV】在MacOS上使用OpenCvSharp]( https://mp.weixin.qq.com/s/8njRodtg7lRMggBfpZDHgw);或者直接在终端中输入以下指令:

  1. dotnet add package OpenCvSharp4
  2. dotnet add package OpenCvSharp4.Extensions
  3. dotnet add package OpenCvSharp4.runtime.osx_arm64 --prerelease

最终安装完所需的依赖后,项目配置文件为:

  1. <Project Sdk="Microsoft.NET.Sdk">
  2.  <PropertyGroup>
  3.    <OutputType>Exe</OutputType>
  4.    <TargetFramework>net6.0</TargetFramework>
  5.    <ImplicitUsings>enable</ImplicitUsings>
  6.    <Nullable>enable</Nullable>
  7.  </PropertyGroup>
  8.  <ItemGroup>
  9.    <PackageReference Include="OpenCvSharp4" Version="4.9.0.20240103" />
  10.    <PackageReference Include="OpenCvSharp4.Extensions" Version="4.9.0.20240103" />
  11.    <PackageReference Include="OpenCvSharp4.runtime.osx_arm64" Version="4.8.1-rc" />
  12.    <PackageReference Include="OpenVINO.CSharp.API" Version="2023.2.0.4" />
  13.    <PackageReference Include="OpenVINO.CSharp.API.Extensions" Version="1.0.1" />
  14.    <PackageReference Include="OpenVINO.runtime.macos-arm64" Version="2023.2.0.1" />
  15.  </ItemGroup>
  16. </Project>

3.  添加项目运行代码

接下来编写模型部署代码,OpenVINO CSharp API部署模型流程与OpenVINO C++ API部署流程一致,并且由于该项目开发时参考了C++ API名称,因此代码与在C++中使用基本一致。此处以Yolov8分类模型为例,其部署代码如下所示:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using OpenCvSharp;
  6. using OpenCvSharp.Dnn;
  7. using OpenVinoSharp;
  8. using OpenVinoSharp.Extensions;
  9. using OpenVinoSharp.Extensions.utility;
  10. namespace test_openvino_csharp;
  11. class Program
  12. {
  13.    static void Main(string[] args)
  14.   {
  15.        DateTime start = DateTime.Now;
  16.        // -------- Step 1. Initialize OpenVINO Runtime Core --------
  17.        Core core = new Core();
  18.        DateTime end = DateTime.Now;
  19.        Slog.INFO("1. Initialize OpenVINO Runtime Core success, time spend: " + (end-start).TotalMilliseconds + "ms.");
  20.        // -------- Step 2. Read inference model --------
  21.        start = DateTime.Now;
  22.        Model model = core.read_model("/Users/ygj/Program/temp/test_openvino_csharp/yolov8s-cls.xml");
  23.        end = DateTime.Now;
  24.        Slog.INFO("2. Read inference model success, time spend: " + (end - start).TotalMilliseconds + "ms.");
  25.        OvExtensions.printf_model_info(model);
  26.        // -------- Step 3. Loading a model to the device --------
  27.        start = DateTime.Now;
  28.        CompiledModel compiled_model = core.compile_model(model, "CPU");
  29.        end = DateTime.Now;
  30.        Slog.INFO("3. Loading a model to the device success, time spend:" + (end - start).TotalMilliseconds + "ms.");
  31.        // -------- Step 4. Create an infer request --------
  32.        start = DateTime.Now;
  33.        InferRequest infer_request = compiled_model.create_infer_request();
  34.        end = DateTime.Now;
  35.        Slog.INFO("4. Create an infer request success, time spend:" + (end - start).TotalMilliseconds + "ms.");
  36.        // -------- Step 5. Process input images --------
  37.        start = DateTime.Now;
  38.        Mat image = new Mat("/Users/ygj/Program/temp/test_openvino_csharp/image.jpg"); // Read image by opencvsharp
  39.        int max_image_length = image.Cols > image.Rows ? image.Cols : image.Rows;
  40.        Mat max_image = Mat.Zeros(new OpenCvSharp.Size(max_image_length, max_image_length), MatType.CV_8UC3);
  41.        Rect roi = new Rect(0, 0, image.Cols, image.Rows);
  42.        image.CopyTo(new Mat(max_image, roi));
  43.        float factor = (float)(max_image_length / 640.0);
  44.        end = DateTime.Now;
  45.        Slog.INFO("5. Process input images success, time spend:" + (end - start).TotalMilliseconds + "ms.");
  46.        // -------- Step 6. Set up input data --------
  47.        start = DateTime.Now;
  48.        Tensor input_tensor = infer_request.get_input_tensor();
  49.        Shape input_shape = input_tensor.get_shape();
  50.        Mat input_mat = CvDnn.BlobFromImage(max_image, 1.0 / 255.0, new OpenCvSharp.Size(input_shape[2], input_shape[3]), 0, true, false);
  51.        float[] input_data = new float[input_shape[1] * input_shape[2] * input_shape[3]];
  52.        Marshal.Copy(input_mat.Ptr(0), input_data, 0, input_data.Length);
  53.        input_tensor.set_data<float>(input_data);
  54.        end = DateTime.Now;
  55.        Slog.INFO("6. Set up input data success, time spend:" + (end - start).TotalMilliseconds + "ms.");
  56.        // -------- Step 7. Do inference synchronously --------
  57.        infer_request.infer();
  58.        start = DateTime.Now;
  59.        infer_request.infer();
  60.        end = DateTime.Now;
  61.        Slog.INFO("7. Do inference synchronously success, time spend:" + (end - start).TotalMilliseconds + "ms.");
  62.        // -------- Step 8. Get infer result data --------
  63.        start = DateTime.Now;
  64.        Tensor output_tensor = infer_request.get_output_tensor();
  65.        int output_length = (int)output_tensor.get_size();
  66.        float[] output_data = output_tensor.get_data<float>(output_length);
  67.        end = DateTime.Now;
  68.        Slog.INFO("8. Get infer result data success, time spend:" + (end - start).TotalMilliseconds + "ms.");
  69.        // -------- Step 9. Process reault --------  
  70.        List<float> results = new List<float>(output_data);
  71.        // 使用 LINQ 查询语法获取最大值及其索引
  72.        var max_pair = (from r in results select new { number = r, index = results.IndexOf(r) })
  73.                               .OrderByDescending(x => x.number).FirstOrDefault();
  74.        Slog.INFO("result: Class ID:" + max_pair.index + ", Score:" + max_pair.number);
  75.   }
  76. }

4. 运行测试项目

配置完项目依赖以及项目运行代码后,就可以运行项目了,在VS Code终端输入以下指令:

  1. dotnet build
  2. dotnet run --no-build

输入指令后,程序输出如下所示:

  1. [ INFO ] 1. Initialize OpenVINO Runtime Core success, time spend: 226.196ms.
  2. [ INFO ] 2. Read inference model success, time spend: 21.717ms.
  3. [ INFO ] Inference Model
  4. [ INFO ]   Model name: torch_jit
  5. [ INFO ]   Input:
  6. [ INFO ]     name: images
  7. [ INFO ]     type: float
  8. [ INFO ]     shape: Shape : {1,3,224,224}
  9. [ INFO ]   Output:
  10. [ INFO ]     name: output0
  11. [ INFO ]     type: float
  12. [ INFO ]     shape: Shape : {1,1000}
  13. [ INFO ] 3. Loading a model to the device success, time spend:153.319ms.
  14. [ INFO ] 4. Create an infer request success, time spend:2.103ms.
  15. [ INFO ] 5. Process input images success, time spend:38.503ms.
  16. [ INFO ] 6. Set up input data success, time spend:4.367ms.
  17. [ INFO ] 7. Do inference synchronously success, time spend:9.081ms.
  18. [ INFO ] 8. Get infer result data success, time spend:0.338ms.
  19. [ INFO ] result: Class ID:386, Score:0.49138233

5.  总结

该项目中,我们在MacOS 14.2.1 系统、M2芯片的 Macbook Air 电脑上,成功使用OpenVINO™ CSharp API 部署了Yolov8图片分类深度学习模型,并详细演示了OpenVINO™ CSharp API在苹果电脑上使用与配置流程,为使用MacOS系统的开发者提供了很好的范例与参考。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/839834
推荐阅读
相关标签
  

闽ICP备14008679号