如果你对MindSpore感兴趣,可以关注昇思MindSpore社区
在这里插入图片描述
在这里插入图片描述

1. 写在前面

你有没有想过,手机相册是怎么聪明地认出你的朋友,购物软件又是如何通过一张照片就帮你找到同款?这些功能的背后,常常藏着一种叫“端侧推理”的技术。

说白了,就是让AI模型直接在你的手机、电脑这类设备上跑起来,而不是把数据传到云端再等结果。这样做的好处很直接:反应快,不联网也能用,还能更好地保护你的个人隐私。

这篇教程的主角——MindSpore Lite,是华为开源的一个轻量级AI推理框架,专门为端侧环境设计。它够小,也够快。

接下来,我会带你用一个图像分类的例子,一步步走完在Windows上部署MindSpore Lite的整个过程,让你亲手感受一下它的魅力。

端侧推理快速入门
h:ttps://www.mindspore.cn/lite/docs/zh-CN/master/quick_start/one_hour_introduction.html

1.1 准备工作

动手之前,先确保你的开发环境满足要求。这几样东西是必需的:

  • 操作系统: Windows 10或更新的版本。
  • 开发工具: Visual Studio 2019。我们需要用它来编译C++代码,社区版就足够了。安装时,记得把“使用C++的桌面开发”这个选项给勾上。
  • 构建工具: CMake 3.18.3以上。你可以把它看作一个项目构建的“总指挥”,能自动生成VS工程文件,省去我们不少手动配置的麻烦。

名词解释

  • IDE (Integrated Development Environment): 集成开发环境,比如Visual Studio,它把代码编辑器、编译器、调试器这些开发工具打包到了一起,用起来很方便。
  • CMake: 一个开源、跨平台的项目构建工具,用来管理软件的编译和链接过程。

1.2 上手实战

环境就绪,我们正式开干。

1.2.1 获取代码和相关文件

首先,从MindSpore的官方仓库把代码弄下来。用Git克隆或者直接下载zip包都可以。

git clone https://gitee.com/mindspore/mindspore.git

我们要用到的代码,在 mindspore/mindspore/lite/examples/quick_start_cpp 这个目录里。

光有代码还不够,还需要两个关键文件:

  1. MindSpore Lite推理库: 去MindSpore官网的下载页面,找到 mindspore-lite-{version}-windows-x64.zip 并下载。这里面是我们编译和运行C++程序要用到的头文件和库。
  2. AI模型: 同样在官网,下载 mobilenetv2.ms 这个模型文件。这是一个很经典的图像分类模型,不大,很适合拿来入门。

下载之后,把MindSpore Lite的压缩包解压,然后把 mobilenetv2.ms 模型文件放到 quick_start_cpp/model 目录下。

1.2.2 剖析编译脚本

quick_start_cpp 目录里,有个叫 build.bat 的文件。这是一个Windows批处理脚本,帮我们把编译过程自动化了。我们来看看它到底做了些什么。

@echo off
SETLOCAL

REM 设置当前目录为根目录
SET BASEPATH=%CD%

REM 关键步骤:设置MindSpore Lite库的路径
REM 把下面这个路径改成你自己的实际解压路径
SET MSLITE_HOME=D:\path\to\your\mindspore-lite-x.x.x-windows-x64

REM 检查路径对不对
IF NOT EXIST "%MSLITE_HOME%" (
    echo "MindSpore Lite home path: %MSLITE_HOME% does not exist"
    GOTO FAILED
)

REM 指定CMake要用的VS版本
SET CMAKE_GENERATOR="Visual Studio 16 2019"

REM 创建一个build目录,存放编译过程中生成的文件
IF EXIST build (
    RMDIR /S /Q build
)
MKDIR build

REM 调用CMake,生成VS工程文件
cmake -S . -B build -G %CMAKE_GENERATOR% -A x64 -DCMAKE_TOOLCHAIN_FILE="%MSLITE_HOME%\tools\cmake\toolchain.cmake" -DMSLITE_HOME="%MSLITE_HOME%"

REM 检查CMake有没有出错
IF %ERRORLEVEL% NEQ 0 (
    echo "cmake failed"
    GOTO FAILED
)

REM 调用CMake,执行编译
cmake --build build -j 4

REM 检查编译是否成功
IF %ERRORLEVEL% NEQ 0 (
    echo "build failed"
    GOTO FAILED
)

echo "build success"
GOTO END

:FAILED
    echo "build failed"
    exit /b 1

:END
    echo "success"

这个脚本的核心其实就两个CMake命令:

  1. cmake -S . -B build ...:这个命令是用来生成Visual Studio工程文件的。-S . 告诉CMake源码在当前目录,-B build 是让它把生成的东西都放在新建的 build 目录里。最重要的参数是 -DMSLITE_HOME="...",它告诉CMake去哪儿找MindSpore Lite的库文件。

  2. cmake --build build -j 4:这个命令是真正开始编译。它会调用VS的编译器,根据上一步生成的工程文件,把C++代码编译成可执行程序。-j 4 是说用4个CPU核心一起上,能快一点。

1.2.3 执行编译

搞明白脚本的原理后,操作就很简单了。

  1. 用记事本或者其他文本编辑器打开 build.bat
  2. MSLITE_HOME 的路径改成你自己的,确保它指向你解压的MindSpore Lite库的根目录。
  3. 打开CMD或者PowerShell,用 cd 命令进入 quick_start_cpp 目录。
  4. 执行脚本:.\build.bat

顺利的话,你会看到 build success 的字样。这时候,build/src 目录下就会多出一个 main.exe 文件,这就是我们最终要的推理程序。

1.3 代码解析

在运行程序之前,我们先花点时间看看 main.cc 里的核心代码。这能帮你更好地理解一个端侧AI应用到底是怎么工作的。

整个流程大致可以分成四步:加载模型 -> 准备输入 -> 执行推理 -> 解析输出

1.3.1 加载模型

// 创建和配置上下文
auto context = std::make_shared<mindspore::Context>();
auto &cpu_context = context->MutableDeviceInfo().front();
cpu_context->SetEnableFP16(enable_fp16); // 是否启用FP16半精度

// 从文件加载并构建模型
auto model = std::make_shared<mindspore::Model>();
auto build_ret = model->Build(model_path, mindspore::kMindSporeModel, context);

这段代码先是创建了一个 Context 对象,用来配置模型运行时的参数,比如指定在CPU上跑。然后,model->Build 这行代码会从指定路径读取 .ms 模型文件,把它解析、构建成一个可以在内存里直接运行的 Model 对象。

1.3.2 准备输入

// 获取模型的输入张量
auto inputs = model->GetInputs();

// 填充输入数据
// (为了简化,这个例子里用的是随机数据)
auto ret = GenerateInputDataWithRandom(inputs);

模型加载好了,就该给它喂数据了。model->GetInputs() 会返回模型需要的所有输入Tensor的信息。在实际应用里,我们通常需要在这里对图片做一些预处理,让它的格式符合模型的要求。不过为了简单起见,这个例子里直接用随机生成的数据来模拟输入。

名词解释

  • Tensor (张量): 这是AI世界里流通的“数据货币”。你可以把它简单理解成一个多维数组。一张彩色的图片,就可以用一个3维张量(高度 x 宽度 x 颜色通道)来表示。

1.3.3 执行推理

// 获取模型的输出张量
auto outputs = model->GetOutputs();

// 执行推理
auto predict_ret = model->Predict(inputs, &outputs);

这是最核心的一步。model->Predict 函数会启动整个推理计算。它把我们准备好的输入数据(inputs)送进模型,经过一层层的计算,最后把结果存到 outputs 里。

1.3.4 解析输出

// 打印输出结果
for (auto tensor : outputs) {
    // ...
    float *output_data = reinterpret_cast<float *>(tensor->MutableData());
    // ...
    // 找到概率最高的那个类别
    float max_score = 0;
    uint32_t max_idx = -1;
    for (int i = 0; i < tensor->ElementsNum(); ++i) {
        if (output_data[i] > max_score) {
            max_score = output_data[i];
            max_idx = i;
        }
    }
    // ...
}

模型吐出来的 outputs 通常是一堆原始的数字,我们直接看不懂。所以需要进行“后处理”。这段代码的作用就是解析输出的Tensor,它遍历了里面的数据,找到了概率值最大的那个元素,这个元素对应的索引(max_idx),就是模型给出的预测类别。

1.4 运行与结果分析

现在,所有准备工作都已完成。在命令行里进入 build\src 目录,然后运行 main.exe

cd build\src
main.exe

程序会让你输入模型文件的路径,把 mobilenetv2.ms 的相对路径(比如 ../../model/mobilenetv2.ms)输进去,然后敲回车。

如果一切正常,你会看到类似下面这样的输出:

...
prediction: 2, score: 0.98
...

这个结果告诉我们,模型预测的类别索引是 2,并且它对此的置信度是0.98。虽然我们用的是随机数据,但这个过程完整地跑通了一次推理。在真实的图像分类任务里,这个索引 2 可能就代表着“汽车”或者“卡车”这样的具体标签。

2. 总结

你已经独立在Windows上,完成了从编译到运行的整个端侧AI推理流程。

这虽然只是一个入门级的例子,但它为你打开了通往端侧AI世界的一扇门。从这里开始,你可以试着修改代码,用真实的图片数据来代替随机数;或者,也可以去寻找更多有意思的模型,替换掉现在的 MobileNetV2,去挑战人脸识别、物体检测这些更酷的功能。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐