内容简介:本文经作者授权翻译,原作者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 之速率限制
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Inside Larry's and Sergey's Brain
Richard Brandt / Portfolio / 17 Sep 2009 / USD 24.95
You’ve used their products. You’ve heard about their skyrocketing wealth and “don’t be evil” business motto. But how much do you really know about Google’s founders, Larry Page and Sergey Brin? Inside......一起来看看 《Inside Larry's and Sergey's Brain》 这本书的介绍吧!