内容简介:本文经作者授权翻译,原作者Luca Palmieri
本文经作者授权翻译,原作者Luca Palmieri
原文链接:
https://www.lpalmieri.com/posts/2019-12-01-taking-ml-to-production-with-rust-a-25x-speedup/
TDU导读: 随着Rust语言的强劲增长,也有许多数据科学家在探索Rust在数据科学、机器学习方面的应用,本文作者是一名机器学习工程师,他使用Rust和 Python 分别实现了K-Means算法,并进行了对比,并给出了自己的代码和材料,值得探索。
正文
如果我们抛弃所有小细节,纵观全局,那么机器学习开发中将只剩两个部分:
-
模型训练
-
做出预测(推论)
如今,机器学习的首选语言是 Python (除非您的工作环境有一些不同寻常的限制)。
下面,我将带你踏上一段旅程。希望这段旅行结束后,将 Rust 用于 后端训练和平台部署 不会像听起来那样疯狂或者令人困惑了。
为什么是Python?
我们可以花很多时间讨论机器学习开发的不同工作流,但毫无争议的是,模型训练通常是以一种 探索性的方式 进行的。你拥有一组数据,为了更好地理解,你将其切割成小块,然后尝试各种方法来解决某个你所关注的特定问题(例如在Google Street View 图片中识别小猫,天气预报,作物产量优化等等)。
一路上会有很多陷阱,你尝试的大多数技术最后可能都无法开箱即用。因此,重点是 快速设计出原型 然后 迭代改进 。所以像Python这样的动态编程语言是一个理想的选择。
动态编程语言: https://en.wikipedia.org/wiki/Dynamic_programming_language
更进一步,如果你了解到大部分机器学习的从业人员是统计学,数学,物理或类似的专业出身,而不是计算机科学的背景。就会知道他们几乎没有经过任何软件工程实践和 工具 的训练。
尽管Python同时支持函数性和面向对象模式,你可以使用命令式的脚本语言开始使用它。它的入门门槛很低,而且你会发现Python会随着你的经验和精通程度一起提高。
但是,仅仅易于使用不会帮你走得很远:训练机器学习模型需要进行大量的繁琐运算,而Python绝对不是最快的语言。所以,NumPy(1995/2006),SciPy(2001),Pandas(2008)和Scikit-learn(2007)出现了。如果没有这些用于机器学习和科学计算的高质量且全面的工具包,Python不会是今天的样子。
但是,如果你透过表象研究,会发现你只是使用Python来协调和利用了 C和C++ 的强大核心 。 Python是这些系统的前端 ,用户利用python轻松将各种东西缝合在一起;而 C和C ++是您的后端 ,是幕后神奇的魔法。
事实上,这往往是Python容易被人忽略的特点:利用外部功能接口( Foreign Function Interfa ce ),它很轻易可以与其他编程语言进行交互操作。特别是,Python库可以将需要大量数字运算的程序委派给C和C ++,这是Python科学生态系统中所有基础库所使用的策略。
当然,技术永远无法说明一切。即使有些人觉得难以接受,社会学因素对于大多数项目的成功(或消亡)都是至关重要的。因此,我们应该增加一种说法,即Python是一个开源项目,它在学术机构中的渗透水平不可忽略;当深度学习成为人们关注的焦点时,它的大多数科学生态系统早已建立。事后看来,将Python视为最终在机器学习领域占据统治地位的强大候选人并不奇怪。
未来还应该使用Python吗?
我们已经简要地介绍了将Python作为机器学习开发的首选编程语言的原因。但是,世界并不会保持静止:环境的改变可以大大改变人们对哪种工具是“最佳工作工具”的认识。
最新的趋势可能增强了Python在该领域的地位。
微服务
微服务架构目前在Design Space 中占主导地位:公司将其业务打包为服务集合来运行,这些服务通过网络相互通信。这使得运行多语言堆栈变得简单:您的主应用程序可以用 Java 编写-当您想利用机器学习来确定某笔信用卡交易是合法还是欺诈时,可以向Python的微服务提出POST请求。
数据科学家和机器学习工程师用Python执行模型探索后,将所有内容移交给“生产团队”以完全改写公司选择的语言,这样的日子已经一去不复返了
DevOps
"you build it, you run it" -Werner Vogels(Amazon CTO)
如果是在业务层面,需要强调的是机器学习模型并不是凭空存在的:它们是公司要启动,优化或改进某个产品或过程中的一部分。因此, 仅由 数据科学家组成的团队并不一定会具有出色的表现。如果要获得成功,则需要从产品到软件工程的各种技能组混合发挥效用。
那么这样的团队应该使用哪种编程语言?使用JavaScript和NodeJS可以使同一个人能够做前端和后端的工作(“全栈”)。
Python作为通用编程语言也提供了这样的便利。你可以将其用于机器学习开发,并利用其框架(Django,Flask,FastAPI)将模型部署为REST或gRPC API来进行预测。
网络效应
-
Python具有庞大的机器学习生态系统;
-
如果你希望你的机器学习算法或框架被采用,那么请使用Python编写代码(或使用FFI绑定Python);
-
Python生态系统越来越庞大
答案
未来我们可能仍将使用Python编写机器学习软件。我们会永远使用它吗?这不太可能,这个问题就像在问十年后计算机的未来是什么样的。但我推测未来5年我们将迎来Python的衰落。
那又怎样? 这不是一篇关于Rust的文章吗?
确实是的!但在开始之前,消除任何可能产生的误解是非常重要的。 从机器学习的语言选择来说,我不认为Rust会代替Python --事实上也没有发生,不管现在还是未来,这都不是个问题。
它们满足的是不同人群的需求,经过优化后,它们可以在不同的约束条件下解决不同的问题集。
但是Rust在机器学习的世界里也起了作用!
Rust有着巨大的潜力, 来代替C和C++优先成为Python在机器学习工作负荷的后端。
为什么是Rust?
没有比《Rust编程语言》这本书前言中所说的更好的答案了
「举个例子,“系统级别”工作就是处理内存管理、数据抽象和并发等底层细节。传统来说,这类编程领域被认为很神秘,只有少数人花了必要的时间学习,以避免一些臭名昭著的隐患。即使是那些实践它的人也要谨慎行事,以免他们的代码暴露于漏洞、崩溃或灾难之中。
Rust通过消除这些问题,提供了友好的、优雅的工具打破了这些障碍。那些需要“下潜”到底层控制的 程序员 可以使用Rust这样做,既不用承担日常的崩溃或安全漏洞风险,也不必学习易变的工具链。更好的是,这门语言旨在引导你自然而然地获得可靠的代码,并且执行效率高,内存使用充分.」
Rust在完全不同的置信水平上提供了可与C及C++媲美的性能。
你要相信编译器知道你所不知道的: 换句话说,你可以安全的从“这他妈的是什么?”转化到“让我们在生产中运行此代码!”的路线上.
这大大降低了门槛。
更多的人(又是我~)可以尝试编写高性能的机器学习算法。
越来越多的人有机会为他们日常使用的项目的后端做出贡献。
这会带来一个更大的社区、更多的实验以及更可持续的项目——换句话说,是一个更健康、更多样化的生态系统。
回到我前面提到的那些趋势,你会再次发现全栈的强大能量:同一个人既可以负责模型探索(使用Python),也可以使用Rust重写热路径,深入优化最终的解决方案。
那么这很容易实践么?
做个小实验:聚类
我为RustFest2019大会准备了一次研讨会:我们使用ndarray(一个与numpy等价的Rust的库)从头实现K-Means聚类。
workshop介绍地址:
https://barcelona.rustfest.eu/sessions/machine-learning-ndarray
RustFest2019大会介绍:
https://barcelona.rustfest.eu/
几周前,我在研讨会上写了一些笔记,这些材料可以在GitHub上找到。它是由一系列测试驱动的练习构成的,每一步都有助于最终的解决方案。
研讨会笔记:
https://www.lpalmieri.com/posts/2019-11-14-rustfest-2019-a-retrospective/
ndarray介绍:
https://github.com/LukeMathWalker/ndarray-koans
一个我不能回避的问题是:与scikit-learn提供的K-Means相比,Rust的教学实施速度有多快??
我和其他一些好奇的人们花掉了“implentation days”的时间给出了答案。如果没有 @sitegui, @dunnock and @ThomAub ,将花费更长时间,感谢你们的帮助!
实现
我已经发布了一个干净的K-Means算法实现,是名为linfa-clustering的Rust类库。linfa-clustering是linfa的一个子类-我们稍后将详细讨论它。
linfa-clustering:
https://crates.io/crates/linfa-clustering
你可以清楚的看到源代码着重在清晰的优化,而不是模糊的:这是 Lloyds’ 算法的教科书实现。
https://github.com/LukeMathWalker/linfa/blob/master/linfa-clustering/src/k_means/algorithm.rs
大多数提速机会都没有利用起来,绝对还存在分析和优化的空间——例如,它在分配阶段仅使用了多线程,而更新阶段使用了单线程。
为了进行比较,我编写了Python:在Python库--PyPi上使用linfa。
我着重想比较一下:
-
训练时间
-
预测时间 ,当该模型作为 gRPC微服务 公开时进行测量。
通过测量将模型作为微服务公开的预测所需时间,我们可以更接近在实际生产环境中使用此代码的实际效果。
GitHub上提供了重现基准测试的说明、结果和代码。
https://github.com/LukeMathWalker/clustering-benchmarks
训练基准
使用pytest-benchmark,在1百万点的数据集上,使用linfa(Python) 训练 一个K-Means模型,要比scikit-learn快 1.3倍
pytest-benchmark:https://pypi.org/project/pytest-benchmark/
总的来说,他们的速度具有可比性--由于并行的分配步骤,linfa可能稍微快一些
如果您发现这个现象,请再次思考:我们正在比较的双方,一方是为 两天的教学研讨会准备的实现 ,另一方是 最成熟机器学习框架使用的实现 。
从基准代码中可以看到,linfa 的 K-Means实现提供了一个类似scikit-learn接口。
from sklearn.datasets import make_blobs
import pytest
from linfa import KMeans
from sklearn.cluster import KMeans as sk_KMeans
@pytest.fixture(scope="session", autouse=True)
def make_data():
return make_blobs(n_samples=1000000)
def test_k_means_rust(benchmark, make_data):
dataset, cluster_index = make_data
model = KMeans(3, max_iter=100, tol=1e-4)
labels = benchmark(model.fit_predict, dataset)
assert len(labels) == len(cluster_index)
def test_k_means_python(benchmark, make_data):
dataset, cluster_index = make_data
# Using the same algorithm
model = sk_KMeans(3, init="random", algorithm="full", max_iter=100, tol=1e-4, n_init=1)
labels = benchmark(model.fit_predict, dataset)
assert len(labels) == len(cluster_index)
我也想鼓励你尝试一下Rust的版本——交互看起来有点不同(原因我可能会在另一篇博客文章中讨论),但相信你可以很容易地识别出相同的步骤:
use linfa::clustering::{generate_blobs, KMeans, KMeansHyperParams};
use ndarray::array;
use ndarray_rand::rand::SeedableRng;
use rand_isaac::Isaac64Rng;
fn main() {
// Our random number generator, seeded for reproducibility
let mut rng = Isaac64Rng::seed_from_u64(42);
// For each our expected centroids, generate 1000 data points around it (a "blob")
let expected_centroids = array![[10., 10.], [1., 12.], [20., 30.], [-20., 30.]];
let dataset = generate_blobs(10000, &expected_centroids, &mut rng);
// Configure our training algorithm
let n_clusters = 4;
let hyperparams = KMeansHyperParams::new(n_clusters)
.max_n_iterations(200)
.tolerance(1e-5)
.build();
// Infer an optimal set of centroids based on the training data distribution
let model = KMeans::fit(hyperparams, &dataset, &mut rng);
// Assign each point to a cluster using the set of centroids found using fit
let labels = model.predict(&dataset);
}
预测基准
如前所述,使用专用的微服务为机器学习模型提供服务是业界公认的模式。 不过,在这些微服务中,通常很少甚至没有业务逻辑:它只不过是一个 远程函数调用。
给定一个序列化的机器学习模型,我们能完全自动化/抽象掉API生成吗?我认为这是一定的,TensorFlow的流行已经证实了这一点。
因此,我决定对三个场景进行基准测试:
-
基于Python的gRPC服务器的scikit learn的K-means;
-
基于Python的gRPC服务器的linfa的K-means(Python包装器);
-
基于Rust的gRPC服务器(tonic)的linfa的K-means(Rust)。
我没有在这些gRPC web服务器上执行任何微调:我在寻找开箱即用的性能。你可以查看源代码:
Rust: https://github.com/LukeMathWalker/clustering-benchmarks/blob/master/rust-grpc/src/main.rs
Python: https://github.com/LukeMathWalker/clustering-benchmarks/blob/master/python-grpc/src/main.py
Rust web服务器上的linfa每秒处理的请求比scikit learn多25倍 ,比Python gRPC服务器上的linfa(Python wrapper)多7倍。
延迟(提供响应需要多长时间)也是如此, 其中Rust Web服务器上的linfa始终比scikit-learn 快26倍 ,比Python Web服务器上的linfa(Python包装器)快7倍。
Rust web服务器上的linfa在重载情况下的错误率也是最低的。
一个新的工作流
这是一个太小的实验,不能得出彻底的结论,我相信你可以为K-Means找到更快的Lloyds’ 算法实现。
但我希望这足以让你相信Rust可以在机器学习开发中发挥作用。每个人都可以通过对ndarray工作原理的一些训练来编写Rust实现(试试workshop的材料!),有多少机器学习实践者由于使用C和C++而被抑制了潜力?
如果这还不够,Rust不仅可以替代C和C++作为Python后端,Rust可以利用其日益增长的异步生态系统来处理部署。
这可能像下面这些工作一样简单:
-
使用Rust驱动的Python库识别您的候选模型;
-
将最终模型序列化;
-
提供最终模型的路径和输入数据的预期模式作为配置;;
-
盈利。
这绝对是2020年值得探索的方向!
继续前进
如前所述,linfa-clustering是linfa的一个子类,linfa是Rust中的一个通用机器学习框架,我计划在2020年重点关注它。
尽管称之为框架,但它目前并不成熟:linfa-clustering确实是唯一的一部分。
完成其大胆的使命宣言任重道远,但当涉及到机器学习及其环境时,在Rust生态系统中意义重大。有时,星星之火可以燎原。
Rust的宣言:
https://github.com/rust-ml/discussion/issues/1
事实上,我坚信只有社区才能在Rust中培育、构建,并维持一个机器学习生态系统-没有其他的出路。
https://www.youtube.com/watch?v=odI_LY8AIqo&t=8s
Rust生态系统中确实有大量的机器学习类库—只需在crates.io上搜索机器学习便可得到。
crates.io:
https://crates.io/search?q=machine%20learning
你不需要从头开始重写所有东西:我把linfa想象成一个元包,一个来自Rust生态系统的精确算法实现的集合。正如Python的scikit-learn一样,是您的ML需要的第一站。
如果少了什么,我们会写下来。
如果某些东西已经可用并且可以通过兼容的接口公开,我们将采用它。
提出一系列特征确实是最重要的贡献之一——但首先我们必须探索,然后我们将抽象。
如果这一点引起了你的共鸣,请看一看路线图-我期待着你的贡献!
路线图:
https://github.com/LukeMathWalker/linfa/issues
非常欢迎与我沟通这篇文章的笔记、建议和反馈
Twitter at @algo_luca
GitHub at @LukeMathWalker
email rust@lpalmieri.com
正文完
本文经作者授权翻译,原作者Luca Palmieri
原文链接:
https://www.lpalmieri.com/posts/2019-12-01-taking-ml-to-production-with-rust-a-25x-speedup/
文中图片、超链接来自原文
以上所述就是小编给大家介绍的《使用 Rust 将机器学习生产速率提升25倍!》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Envoy、gRPC和速率限制
- nginx 对同一 ip 访问请求速率限制
- 挖洞经验 | 雅虎(Yahoo)的速率限制漏洞($2k)
- SRE 弹性能力:使用 Envoy 对应用进行速率限制
- Spring Cloud Netflix Zuul中的速率限制
- Yii2.0 RESTful API 之速率限制
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Operating Systems
Remzi Arpaci-Dusseau、Andrea Arpaci-Dusseau / Arpaci-Dusseau Books / 2012-8-19 / USD 21.00
A book about modern operating systems. Topics are broken down into three major conceptual pieces: Virtualization, Concurrency, and Persistence. Includes all major components of modern systems includin......一起来看看 《Operating Systems》 这本书的介绍吧!