Dask 开发日志
这项工作得到了 Continuum Analytics、XDATA 项目以及 摩尔基金会 (Moore Foundation) 数据驱动发现倡议的支持
为了提高透明度,我每周都会撰写博客,介绍前一周在 Dask 及相关项目上所做的工作。这篇日志涵盖了 2017-01-17 至 2016-01-30 期间完成的工作。这里的内容尚未准备好用于生产环境。这篇博文是匆忙写成的,因此请勿期待精雕细琢。
过去几周的主题
- 分布式调度器微小版本发布
- 用于异步算法的 as_completed
- 测试 ZeroMQ 和通信重构
- Persist 和 Dask-GLM
稳定性增强和微小版本发布
我们发布了 dask.distributed 1.15.2 版本,其中包括一些重要的性能改进,用于多维数组的通信,更清晰的自适应部署工作器调度器关闭,一个可以接受新未来对象在飞行中的改进的 as_completed 迭代器,以及一些其他较小的特性。
其中最令我兴奋的特性是改进了多维数组的网络通信。在最近一篇关于在集群上处理图像的博文中,我们注意到通信带宽远低于预期。这导致我们发现压缩启发式算法中的一个缺陷。Dask 不会压缩所有数据,而是抽取少量 10kB 的数据样本进行压缩,如果效果良好,就决定压缩整个数据。不幸的是,由于我们对 memoryview 的处理不当,在处理多维数组时,我们最终抽取的样本比 1kB 大得多。
XArray 版本发布
这项改进尤其及时,因为 XArray(一个围绕 Dask.array 构建用于处理大型标记数组的项目)的新版本现已发布,为分布式集群上的 NetCDF 数据提供了更好的数据摄入支持。这为 Dask 的第一个(也可能是最大的)科学用户社区——大气科学家——开启了分布式数组计算的大门。
as_completed 接受 future 对象。
除了数组、数据框和延迟装饰器之外,Dask.distributed 还实现了标准库中的 concurrent.futures 接口(只是 Dask 的版本可以在集群中并行执行,并有一些其他优势)。该接口的一部分是 as_completed 函数,它接受一个 future 对象列表,并按照它们完成的顺序 yield 这些 future 对象。这使得构建相当响应式的异步计算成为可能。一旦某些工作完成,您就可以查看结果并根据当前状态提交更多工作。
这在 Dask 中已经存在一段时间了。
新功能是,您现在可以向 as_completed 中推送更多 future 对象
futures = client.map(my_function, sequence)
ac = as_completed(futures)
for future in ac:
result = future.result() # future is already finished, so this is fast
if condition:
new_future = client.submit(function, *args, **kwargs)
ac.add(new_future) # <<---- This is the new ability
因此,as_completed
迭代器可以在一组 future 对象持续进行的情况下长时间运行。这个相对简单的改变使得表达广泛的异步算法变得容易。
ZeroMQ 和通信重构
作为一项大型工作的一部分,Antoine Pitrou 一直在重构 Dask 的通信系统。这次重构的一个子目标是允许我们以可插拔的方式探索 Tornado IOStreams 以外的其他传输机制。
其中一个替代方案是 ZeroMQ sockets。对于使用 ZeroMQ,我们听到了极度正面和极度负面的评价/警告。它并不是一个完美的匹配,因为 Dask 主要进行点对点通信,所以我们无法从 ZeroMQ 的所有模式中获益,这些模式现在反而成了阻碍而非优势。然而,我们对在一个完全独立管理的 C++ 线程中管理所有网络通信(不受 GIL 问题影响)的性能影响很感兴趣。
无论您喜欢或不喜欢 ZeroMQ,现在都可以自由选择。Antoine 的分支允许轻松切换传输机制,并为未来更多的可能性打开了大门,比如使用队列、MPI 等进行进程内通信。这不会影响大多数用户,但一些 Dask 部署在拥有极速网络能力的新型超级计算机上。我们有朝一日可能利用 Infiniband 并具备无需拷贝即可在本地管理数据的能力(Tornado 无法实现这一点),这对一些用户社区非常有吸引力。
经过初步基准测试,我们发现 ZeroMQ 提供了一定的速度提升,但在复杂工作负载下会导致集群缺乏稳定性(很可能是我们的问题,而不是 ZeroMQ 的问题,但事实如此)。ZeroMQ 支持严格来说是实验性的,并且很可能长期保持这种状态。读者不应对此感到兴奋。
Persist 和 Dask-GLM
我们与 Capital One 的研究人员合作,一直在开发一套用于一阶和二阶方法的并行求解器,这些方法广泛应用于各类统计和机器学习算法中。
在此过程中面临的一个挑战是构建同时对单机和分布式调度器都最优的算法。分布式调度器要求我们考虑数据的位置,是在客户端还是在集群上,而对于单机调度器来说,这问题较小。分布式调度器恰当地引入了一个新动词 persist
,它将数据保留为 Dask 集合,但会触发所有的内部计算
compute(dask array) -> numpy array
persist(dask array) -> dask array
我们现在已将此动词镜像到单机调度器中,参见 dask/dask #1927,并且现在在 dask-glm 的算法在这两种情况下都能获得很好的性能。
与 Capital One 的开发者合作非常有价值。我希望找到更多符合以下标准的机器学习团队:
- 关注性能
- 需要并行计算
- 致力于构建优秀的开源软件
- 在其领域足够专业以理解正确的算法
如果您认识这样的人或团队,无论是行业内的还是大学里的研究生,请鼓励他们在 http://github.com/dask/dask/issues/new 上提出问题。我近期可能会就此话题撰写一篇更长的博文。
博客评论由 Disqus 提供支持