热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Alluxio&大厂】你最想知道的微软实践案例来啦!

使用Alluxio加速大规模

点击蓝字 关注我们

使用Alluxio加速大规模ML/DL离线推理作业

Alluxio & Microsoft

活动回顾

Alluxio & Microsoft

  在2021年Alluxio Day 第三期社区活动日中,来自微软的STCA软件工程师 李镔洋,以及微软亚洲研究院高级研究工程师 张虔熙,为我们分享了如何使用Alluxio加速大规模ML/DL离线推理作业的内容。

以下为此次活动的演讲实录 ↓

本次分享主要分为以下部分:

离线推理作业的特点

运行大规模推理作业的挑战

系统实现框架与优化

性能评估

未来工作

李镔洋

  微软STCA软件工程师。负责Bing内部机器学习训练和推理平台的开发与优化。参与开发和维护微软开源机器学习平台。

张虔熙

  微软亚洲研究院高级研究工程师,负责数据库和存储系统的研究和开发工作。拥有多年大数据开发经验,曾负责超万节点大数据平台的架构优化和演进。负责Cache as a Service在公司内的落地。

离线推理作业的特点

  这个部分我将介绍离线推理作业的特点。

  首先介绍一下离线推理作业的规模。我们使用的离线推理作业中,每个作业都包含超过400个任务。每个任务都读取不同的数据集并且生成对应的输出结果,并且任务之间没有任何交互。每个任务都会读取约2-3GB的数据,生成约7-8GB的数据,所以整个作业读取和输出的数据是很大的,约读入1TB的数据,产生3.5TB的数据。完成一个任务需要花费约2-4个小时,这是一个长时间运行的作业。


  离线推理作业的数据获取模式是十分简单的,这类作业仅仅需要顺序读入一次输入数据,并且在作业运行时就可以写输出数据到Azure Blob。这与训练作业不相同,训练作业是在每个回合都将所有的输入数据读取一轮,而离线推理作业仅仅只读取一次。


  最后我介绍下我们使用的基础架构。我们使用Azure Blob作为存储系统,使用开源项目OpenPAI作为AI训练的平台,使用开源项目Hived作为调度组件,将每个作业调度到对应的节点上。

运行大规模推理作业的挑战

● 处理大量的输入和输出数据容易造成IO故障。

● 像blob-fuse这样的工具会在运行任务之前下载数据,并且在作业结束后会将结果进行上传到Azure Block云存储中。在我们的例子中,每个作业都包括接近400个任务,这些任务几乎是同时开始运行的,这也就表示几乎同时开始下载数据,这就容易造成较高的IOPS并且容易到达Azure  Blob的带宽限制。由于任务的相似性,他们几乎是在同一时间结束,所以他们会在同一时间将输出结果上传到Azure 存储系统中,这也容易到达Azure blob的带宽限制。如果到达了Azure blob的限制,那么这个任务就会失效,此时就需要重新执行作业中的任务,这是非常耗时的。

● 当使用像blob-fuse的工具时,在作业开始时会开始下载数据,当作业完成时会开始上传数据。在下载或上传数据的时候,GPU是处于空闲状态的,这不仅耗时而且还浪费资源。

Prod bed环境

● 使用约200个Azure低优先级虚拟机,每个虚拟机有4个GPU。这里需要注意的是虚拟机是采用的可抢占式的策略,随时会被回收,这也就使得环境不太稳定,我们需要通过一些措施使得训练平台变得更加稳定。

● 使用 Alluxio 2.3.0

● 使用 Kubernetes 1.15.x

● 使用Alluxio运行超过6个月,运行情况良好。

带有Alluxio的系统组织架构

  当用户提交一个作业时首先会进入到作业调度器组件中。在作业开始运行之前它会向Alluxio发送一条命令将部分数据预取放到缓存中。当预取好数据之后,作业调度器会将作业调度到对应的节点上。作业可以直接与Alluxio进行读取或者是写入数据而不需要与数据存储组件进行交互。另外,在Alluxio组件中,我们还希望实现自定义数据替换策略使得作业运行更加有效。

优化-基于deployment的CSI

  我们从Alluxio社区发现Alluxio有多种部署方式。最基本的部署方式是在每个节点上都部署一个fuse守护进程。所有的作业都与部署在这些节点上的fuse守护进程进行交互,来读取或写入数据。但这种部署方式并不能很好的满足推理任务对读和写的不同需求。

  对于推理任务来说,在进行任务读取的时候,所有的任务都需要读取模型文件。我们可以将模型文件缓存在Alluxio中,同时为了使得其运行更加有效,我们需要将模型文件的元数据也进行缓存。所以我们需要打开元数据缓存,设置开启内核缓存,设置比较长的超时时间。而对于输出数据而言,我们需要将数据输出到对应的目录中,因此需要关闭缓存元数据,还需要自定义Alluxio配置文件来确保数据不会丢失。针对读和写的不同需求,我们采用了基于CSI的部署方式。

  这是一个如何使用CSI的一个例子,对每个CSI的挂载点都可以提供一个配置文件,可以自定义挂载操作并且自定义Alluxio配置,例如设置挂载在Alluxio中的挂载目录。这对于我们是十分方便的。同时还可以设置一些自定义的挂载选项。

  对于每个推理任务而言,我们提供了两个挂载点,一个用于进行读取数据,一个用于进行写入数据。每个挂载点都有一个守护进程与之对应。


基于CSI的部署方式具有以下优势:

● 系统可针对不同的读写场景进行分别配置从而使得任务更加有效。

● 对于每个pod而言都会有属于单独的fuse守护进程,如果一个fuse守护进程失效后,只会影响到与之对应的工作负载,对于其他在相同节点运行的工作负载都不会产生影响,这提高了系统的鲁棒性。

● 每个作业都可以挂载到不同的路径,并且每个路径可以被管理员控制,所以管理员可以提供一些设置配置,给CSI持久卷。对每个作业都选择其中的一个卷。如果管理员不提供对应路径的配置,调度到该节点的作业就不能够使用该路径并修改对应的文件,从而可以确保系统的安全性以及访问控制权限。

优化-Fuse 客户端优化

  我们的系统对于fuse客户端也进行了优化。


  在我们的例子中主要处理的是离线推理作业,这类作业会产生大量的输出数据,并且这些数据是对于我们和数据科学家都是至关重要的。为了使得输出结果更加安全可靠,我们在fuse 客户端中进行优化。


  第一个是flush函数优化。平台用户反馈当作业结束之后产生的输出结果却丢失了。我们对此进行了调研,最后通过在fuse 守护进程中实现flush 函数来避免了这个问题。当一个作业完成之后,系统会自动调用flush函数。通过对flush函数优化,可以确保不丢失输出数据。


  第二个是release函数优化。有些用户想要对输出数据进行进一步处理以便进行其他的实验,但是他们进行后续实验时发现输出数据文件不能够被打开,并且在Alluxio日志中发现之前的作业并没有完成。我们对此进行了调查后发现Alluxio中的release 函数是异步的,我们会误以为任务已经完成,但是实际上由于release函数是异步的,所以可能关闭文件的函数是没有完成的。此时由于客户端认为作业已经完成,所以客户端关闭了,由于客户端与服务端的grpc通信无法继续,这使得服务端的关闭操作无法执行完成。优化后在release函数和unmount函数中添加一些逻辑使得在进行解挂载之前确保所有的客户端请求的操作都被Alluxio 服务端处理。


  通过解决了这两个问题,我们的系统更加稳定可靠。

预取功能

  这一部分介绍预取功能。


  我们在作业真正开始运行之前将数据通过Alluxio提前缓存在缓存系统中。通过这种操作,作业不需要等待数据进行获取而是可以直接进行执行。


  首先当用户提交一个作业到OpenPAI中,然后作业调度器会进行调度。如果在集群中存在一些任务正在运行,此时就需要进行等待一段时间。但是此时OpenPAI可以向Alluxio master发送预取命令,然后数据就会被进行缓存。所以在作业真正运行时,工作负载已经被进行缓存,此时OpenPAI会将作业调度到对应的节点上直接进行运行。

性能评估

  这一部分展示一些实验结果。


  从实验结果可以得知,使用了Alluxio进行优化后提升了作业运行速度。上图中左侧是没有使用Alluxio进行加速时GPU利用率变化情况,而右侧则是使用Alluxio的。

如果没有使用Alluxio,可以发现作业需要首先下载数据,然后当任务结束之后需要一段时间将数据进行上传到Azure Blob中。


  在使用Alluxio时,我们仍然需要一段时间来下载数据,但由于并不需要把数据全部下载下来,所以这个时间并不需要很长。在作业结束的时候不需要进行等待,这是因为推理作业会在作业运行的过程中输出数据并进行上传。由于作业需要超过两个小时的时间完成,所以这种方式缓解了作业对I/O系统的压力。这使得IO请求更加平滑。

  Alluxio还带来其他的一些优势,例如读重试。如果读取失败会自动进行重新读取,从而降低了作业运行的失败率。

通过引入Alluxio,我们优化了推理作业,使得其性能提升了大约18%。

未来工作

  1. 写操作失败重试。Alluxio中只对读操作有重试逻辑但是对写操作没有。客户端想要进行写数据时,会首先发送请求给worker节点,然后worker会进行处理相关数据。如果worker节点出错,那么写操作就会失效,进而导致作业的失败。我们使用的环境是Azure Low Priority VM,所以worker节点可能在任何时候被Azure 回收。如果worker节点发生了问题,那么我们的任务就会失败。我们希望添加写重试使得我们的系统更加可靠。


  2. 将Alluxio使用在训练作业中。训练作业有着特殊的数据访问模式,每个回合都会读取一次相同的输入数据。我们需要提供新的数据替换策略来使得训练作业更加有效。

引用

●OpenPAI:microsoft/pai:Resource scheduling and cluster management for AI (github.com)

Hived:microsoft/hivedscheduler:Kubernetes Scheduler for Deep Learning (github.com)

●Alluxio-CSI: Alluxio/alluxio-csi (github.com)

了解更多内容

点击“阅读原文”

新浪微博

Alluxio2021 

微信公众号

Alluxio




推荐阅读
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 数字账号安全与数据资产问题的研究及解决方案
    本文研究了数字账号安全与数据资产问题,并提出了解决方案。近期,大量QQ账号被盗事件引起了广泛关注。欺诈者对数字账号的价值认识超过了账号主人,因此他们不断攻击和盗用账号。然而,平台和账号主人对账号安全问题的态度不正确,只有用户自身意识到问题的严重性并采取行动,才能推动平台优先解决这些问题。本文旨在提醒用户关注账号安全,并呼吁平台承担起更多的责任。令牌云团队对此进行了长期深入的研究,并提出了相应的解决方案。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了在Oracle数据库中创建序列时如何选择cache或nocache参数。cache参数可以提高序列的存取速度,但可能会导致序列丢失;nocache参数可以避免序列丢失,但在高并发访问时可能导致性能问题。文章详细解释了两者的区别和使用场景。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 本文介绍了Redis中RDB文件和AOF文件的保存和还原机制。RDB文件用于保存和还原Redis服务器所有数据库中的键值对数据,SAVE命令和BGSAVE命令分别用于阻塞服务器和由子进程执行保存操作。同时执行SAVE命令和BGSAVE命令,以及同时执行两个BGSAVE命令都会产生竞争条件。服务器会保存所有用save选项设置的保存条件,当满足任意一个保存条件时,服务器会自动执行BGSAVE命令。此外,还介绍了RDB文件和AOF文件在操作方面的冲突以及同时执行大量磁盘写入操作的不良影响。 ... [详细]
  • 微软宣布从今年5月开始停止向PC制造商提供32位Windows 10,意味着64位版本将成为主流。尽管Windows 10系统存在一些bug,但全球已有超过10亿台活跃设备在使用。微软表示,从Windows 10 2004版本开始,所有新的Windows 10系统都将要求使用64位版本,不再发布32位版本。这一变化不会影响使用较早版本Windows 10中的32位客户系统。微软仍然致力于在这些设备上提供支持。 ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • 解决Sharepoint 2013运行状况分析出现的“一个或多个服务器未响应”问题的方法
    本文介绍了解决Sharepoint 2013运行状况分析中出现的“一个或多个服务器未响应”问题的方法。对于有高要求的客户来说,系统检测问题的存在是不可接受的。文章详细描述了解决该问题的步骤,包括删除服务器、处理分布式缓存留下的记录以及使用代码等方法。同时还提供了相关关键词和错误提示信息,以帮助读者更好地理解和解决该问题。 ... [详细]
  • php缓存ri,浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
    thinkPHP的F方法只能用于缓存简单数据类型,不支持有效期和缓存对象。S()缓存方法支持有效期,又称动态缓存方法。本文是小编日常整理有关thinkp ... [详细]
author-avatar
政庆雅竹8
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有