使用WebAssembly提高模型部署的速度和可移植性

本文涉及的产品
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
交互式建模 PAI-DSW,5000CU*H 3个月
模型训练 PAI-DLC,5000CU*H 3个月
简介: 使用WebAssembly提高模型部署的速度和可移植性

image.png在最近几个月中,我们已经帮助许多公司在各种环境中部署其AI / ML模型。我们为医疗行业的模型部署做出了贡献,在过去的几个月中,我们已经帮助多家公司将经过训练的模型转移到不同类型的IoT设备上。特别是在IoT设备情况下,要求通常很严格:计算周期数和可用内存通常都受到限制。

在本文中,我阐明了如何确保使用标准ML库(例如PyTorch,Scikit-learn和Tensorflow)训练的模型可以有效地部署在各种边缘设备上。为了使事情变得切实,我们将研究简单的逻辑回归模型的训练和部署。但是,我们在这里讨论的大多数内容都直接转移到更复杂的模型上。

模型训练

为了说明模型训练与部署之间的区别,让我们首先模拟一些数据。下面的代码根据以下简单模型生成1000个观测值:

640.png

importnumpyasnpnp.random.seed(66) #Setseedforreplication#SimulateDataGeneratingProcessn=1000#1000observationsx1=np.random.uniform(-2,2,n) #x_1&x_2between-2and2x2=np.random.uniform(-2,2,n)
p=1/ (1+np.exp( -1*(.75+1.5*x1- .5*x2) )) #ImplementDGPy=np.random.binomial(1, p, n) #Drawoutcomes#Createdatasetandprintfirstfewlines:
data=np.column_stack((x1,x2,y))
print(data[:10])

生成数据后,我们可以专注于拟合模型。我们只需使用sklearn的LogisticRegression()函数即可:

fromsklearn.linear_modelimportLogisticRegressionmod=LogisticRegression().fit(data[:,[0,1]], np.ravel(data[:,[2]]))

仔细看看

在这一点上,梳理并简要考虑引擎盖下正在发生的事情非常有用。与许多其他有趣的ML模型一样,对逻辑回归模型进行迭代训练。为了训练模型,sklearn(或提供类似功能的任何其他软件包)将必须实现以下几个功能:

  1. 某种评分函数,指示模型的拟合度。这可能是误差函数或最大似然函数。
  2. 该函数可将拟合模型的参数从一次迭代更新到下一次迭代。

训练过程将有效地重复使用这两个功能:最初,模型的参数是随机实例化的。接下来,检查模型的分数。如果认为分数不够(通常是因为与以前的迭代相比,分数有所提高),则将更新模型参数并重复该过程。

即使对于这个简单的模型,sklearn仍需要遍历数据集。以下代码给出了迭代次数:

#Printthenumberofiterationsprint(f'The number of iterations is: {mod.n_iter_}.'

因此,要训练模型,我们需要访问数据,还有几个工具的函数,并且需要多次迭代/遍历数据集。总的来说,该训练过程对计算的要求很高,这说明了为什么对于复杂的模型,我们求助于并行计算以及GPU或NPU加速,以在合理的时间内执行。幸运的是,当训练模型时,所需的相当复杂的逻辑已被我们使用的各种ML库抽象化了。

生成预测

将其与从已经拟合的模型中生成预测进行比较(通常称为推理,但由于统计中使用的后者不同,因此我发现这个术语令人困惑,因此我坚持使用预测)。到模型拟合时,在这种情况下,我们实际上需要生成预测的全部就是逻辑回归函数(与上面示例中用于生成数据的数学函数相同)以及拟合模型的三个参数。这些很容易检索:

b=np.concatenate((mod.intercept_, mod.coef_.flatten()))
print(b)

参数最终相对接近我们用于数据生成的值:[0.84576563 1.39541631 -0.47393112]。

此外,在大多数部署情况下,我们通常最终仅使用单个输入来评估模型:在这种情况下,长度为2的数字向量。如果我们要部署模型,则不需要拟合函数,不需要数据,也不需要迭代。要生成预测,我们只需要简单有效地实现所涉及的数学函数即可。

边缘设备中部署模型

“所以呢?”你可能会问。当现代模型训练工具抽象出所有这些细节时,为什么还要关心训练和预测中涉及的细节呢?好吧,因为当您希望有效地部署模型时(例如,当您需要模型在小型设备上快速运行时),您可以更好地利用设备的差异。

为了便于讨论,请对比以下两种模型部署方法(即,将经过训练的模型投入生产,以便可以使用其预测):

将sklearn作为REST服务部署在Docker容器上:这种方法很简单并且经常使用:我们启动一个包含python和用于训练的工具的docker镜像:对于上面的示例逻辑回归模型sklearn。接下来,我们创建一个REST API服务,该服务使用拟合模型的mod.predict()函数来生成结果。

Scailable WebAssembly部署:除了上述方法以外,还可以将拟合模型转换为WebAssembly(使用与Scailable提供的服务类似的服务),并部署.WASM二进制文件,其中仅包含在最小的WebAssembly运行时中进行预测所需的逻辑。自动生成的二进制文件将仅包含必要的逻辑函数和估计的参数。二进制文件可能部署在服务器上因此也类似地通过REST调用使用,但是,它可以兼容可用的运行时,它也几乎可以在任何边缘设备上运行。


显然,第一个部署过程接近数据科学家的“我们所知道的”。直接使用我们惯用的工具是非常方便的,并且在许多方面它都有效:我们可以使用对REST端点的调用来生成预测。第二种解决方案与我们的标准实践相距甚远,并且对于模型训练毫无用处(即,没有“WebAssembly软件包来训练模型……”)。但是,我们仍然认为应该首选:第二种设置利用了训练和预测之间的差异,从而在几个方面使模型部署更好:

内存占用:上面两个选项中的第一个选项将需要至少75Mb的容器(要使容器变小需要大量的工程设计,使容器的大小接近1Gb更为常见)。在这种情况下,存储的模型本身很小(〜2Kb),因此容器占部署内存占用的最大块(请注意,例如大型神经网络可能不正确)。相反,WebAssembly运行时可以降至64Kb以下。WebAssembly二进制本身本身大于存储的sklearn模型(〜50kb),但是现在它包含生成预测所必需的全部。因此,虽然第一个部署选项至少占用75Mb,但第二个部署选项占用不到0.1Mb。

速度:与高效的WebAssembly部署相比,消耗一个在Docker容器中运行的REST端点并不能在执行时间上取得优势,因为Docker容器启动了所有训练所需的东西。下面是一些针对不同模型的速度比较,但是,不必说,利用训练和预测之间的差异,并且仅仅将预测的基本需求投入生产,就可以通过一个数量级提高速度,从而生成这些预测。

因此,内存占用更小,执行速度更快。有几个原因;其中一个原因是,我们可能希望有效地部署模型,而不会在每次做出预测时浪费能源。但是,一个小的内存占用和快速的执行也是很吸引人的,因为这正是我们在将模型投入生产的边缘所需要的:好运部署你的Docker容器(例如,)在ESP32 MCU板上。使用WebAssembly,这是小菜一碟。

综上所述,你一定对WebAssembly十分感兴趣,那么看看这个代码吧,它包含了本文的所有内容

https://github.com/scailable/sclbl-tutorials/tree/master/sclbl-train-vs-deploy


目录
相关文章
|
6月前
|
存储 Rust 监控
Rust代码编写高性能屏幕监控软件的核心算法
本文介绍了使用Rust编写的高性能屏幕监控软件的实现方法。核心算法包括:1) 使用`image`和`winit`库捕获并转换屏幕图像;2) 对图像进行处理,检测特定对象或活动;3) 利用Rust的并发性并行处理多个帧以提高效率;4) 提取数据后,通过`reqwest`库自动提交到网站进行分析或存储。通过结合Rust的高性能和丰富的库,可构建满足各种需求的高效屏幕监控工具。
239 5
|
Web App开发 存储 JavaScript
使用AssemblyScript 构建 WebAssembly 应用
WebAssembly,也称为 Wasm,是为 Web 创建的二进制格式。它允许通过从常规 JavaScript 访问的相同 Web API 访问浏览器功能。
745 0
使用AssemblyScript 构建 WebAssembly 应用
|
3月前
|
Rust 安全 Java
Rust语言在Web后端的应用:基于Actix-web构建高性能、安全可靠的服务器实践
【8月更文挑战第31天】随着互联网的发展,Web应用对性能和安全性要求不断提高。Rust凭借卓越的性能、内存安全及丰富生态,成为构建高性能Web服务器的理想选择。本文通过一个简单示例,展示如何使用Rust和Actix-web框架搭建基本Web服务器,从创建项目到运行服务器全程指导,帮助读者领略Rust在Web后端开发中的强大能力。通过实践,读者可以体验到Rust在性能和安全性方面的优势,以及其在Web开发领域的无限潜力。
116 0
|
4月前
|
移动开发 前端开发 API
探索移动开发的未来:跨平台框架与原生性能的平衡
随着智能手机的普及,移动应用成为人们日常生活的重要组成部分。开发者面临一个核心问题:如何高效地构建既兼容多平台又具备高性能的应用程序。本文将探讨跨平台框架和原生开发的优势、挑战及未来趋势,并分析如何在两者之间找到平衡点以适应不断变化的移动市场。
43 1
|
5月前
|
Rust 前端开发 JavaScript
Tauri框架:使用Rust构建轻量级桌面应用
Tauri是一个用Rust构建的开源框架,用于创建轻量、安全且高效的跨平台桌面应用,结合Rust与Web技术(HTML/CSS/JS)。它遵循最小权限原则,仅在必要时调用OS API。Tauri架构包括Rust后端、Web前端、Tauri API和包装器。通过`cargo tauri init`可创建新项目,Rust后端处理系统交互,前端负责UI,两者通过Tauri API通信。Tauri支持自定义API、集成前端框架、资源管理、自动更新、系统集成和安全配置。此外,Tauri拥有插件系统和丰富的扩展能力,提供调试和测试工具,并有性能优化建议。
304 4
|
5月前
|
边缘计算 安全 开发工具
探索未来计算的可能性:Wasmer — 高性能WebAssembly运行时
探索未来计算的可能性:Wasmer — 高性能WebAssembly运行时
199 2
|
6月前
|
开发框架 JavaScript 前端开发
WebAssembly:下一代跨平台代码执行环境
WebAssembly(简称Wasm)是一种新型的低级字节码格式,可以在现代Web浏览器上运行,同时也可以在其他平台上运行。它是未来互联网应用程序的重要组成部分。本文将介绍WebAssembly的基础知识、其与JavaScript的关系、以及使用WebAssembly进行高效计算的示例。
|
6月前
|
Rust 安全 程序员
使用Rust进行系统编程:安全性优势深度解析
【5月更文挑战第14天】Rust,Mozilla开发的系统编程语言,以其内存安全、并发支持和静态类型系统在系统编程中脱颖而出。所有权和借用检查机制消除内存错误,无锁并发原语提升安全性,静态类型减少运行时错误,最小权限原则降低权限风险。强大的社区支持和安全审计进一步确保了代码的安全性和稳定性,使Rust成为安全高效系统编程的理想选择。
|
6月前
|
弹性计算 Kubernetes 开发者
利用容器化技术实现跨平台部署的Web应用开发
本文将介绍如何利用容器化技术,例如Docker和Kubernetes,实现跨平台部署的Web应用开发。我们将探讨容器化的优势以及如何使用Docker容器打包应用程序,然后利用Kubernetes进行管理和部署。通过容器化技术,开发者可以更加便捷地进行Web应用的开发、测试和部署,提高开发效率和应用的可靠性。
|
6月前
|
Rust 开发者
Rust中的模块与包管理:构建高效、可扩展的代码库
本文详细阐述了Rust编程语言中模块与包管理的概念、特点和使用方法。通过深入了解模块与包的概念、组织方式、导入导出机制以及Rust的Cargo工具,我们将学会如何构建高效、可扩展的代码库,提高代码的可读性、可维护性和可重用性。