在 XDL 开源前夕,机器之心采访了其团队的四位主要负责人:
靖世,研究员,阿里妈妈定向广告技术团队负责人兼阿里妈妈算法平台负责人
见独,资深技术专家,阿里妈妈工程平台技术负责人
怀人,资深算法专家,阿里妈妈算法平台深度学习方向负责人兼定向广告排序算法团队负责人
乐迪,资深技术专家,阿里妈妈大数据计算与机器学习平台的工程架构负责人
「高维稀疏数据的数据处理、模型计算以及在线服务一直是深度学习应用于业界的一个核心挑战区。作为一个真实在广告业务下解决过大量技术问题的团队,我们为了解决这些问题提出了大量的方法。阿里妈妈第一代的 基于深度学习的 CTR 模型研制与大规模线上部署都是 XDL 支撑的,我们将其中对业界有贡献的部分提供给用户,希望做出对大家有增量的东西。」靖世这样描述 XDL 开源的初衷。
而现有框架在处理高维稀疏数据的「痛点」究竟在哪里?使用的模型有什么不同?更加具体的,XDL 框架如何使用?如何与现有框架及模型结合?XDL 团队为机器之心的读者做了详细的解答。
XDL 项目地址:https://github.com/alibaba/x-deeplearning
高维稀疏数据怎么搞?
其实最早的时候,阿里巴巴深度模型的研发也是在尝试已有的框架,例如 Caffe、TensorFlow 和 MXNet 等。但当时阿里巴巴发现已有框架在生产化方面有很多局限,首先第一个是大规模稀疏数据的处理能力,其次是如何实现结构化数据。
大规模稀疏数据体现在搜索、推荐和广告等任务上,例如某系统一共有 10 亿的商品量,那么用户是不是访问过每一个商品就是一维特征。因此,表征用户的特征维度就可能有 10 亿维,而只有访问过的商品才有值「1」,未访问过的商品全为「0」,这也就是高维稀疏的意义。这样的结构和传统机器学习一个特征矩阵加一列标注很不一样,因此也就需要特定的框架高效处理。
除了用户的稀疏表征,商品同样也是稀疏的,它们可能有各种各样的特征,例如颜色、形状、图像和名称等。在一般的推荐系统中,样本都是平铺的,例如一个用户点击了商品 1 和商品 2。那么样本 1 为(用户,商品 1)、样本 2 为(用户,商品 2),这种平铺的数据是非常低效的,因此 XDL 对于大规模稀疏数据有一个结构化的过程。这种结构化会将实体与实体之间的复杂关系进行关联化,并继续投入到计算中,因此 XDL 整体就是一个结构化的计算流。
其实 XDL 团队在处理大规模高维数据后,发现整个计算模式可以进一步提升,以前的张量计算流也许可以使用结构化的计算流代替。可能读者对数据结构化还是缺少了一种直观感受,如下图所示为简单的数据结构化。其中左边的样本是传统平铺的训练数据,而右边的树型结构化会大大降低存储需求。
图示:如上图所示左边为平铺的数据,其一个用户配一个商品(Item)就为一个样本,用于表征用户的高维特征需要重复使用。而箭头右边树型结构化的数据会节约很大的存储成本,它同样表示三个独立的样本。
XDL 团队表示在淘宝原来的信息流广告里,他们需要 300 台以上的机器才能支持模型训练一次。但是这种结构化数据大大简化了数据的表示,因此整个数据集减少了一百倍以上的硬盘存储,计算速度也提升了十多倍。因此最后本来需要几百台机器的模型训练,可以精简到十台机器左右就能完成训练。
最后,除了数据结构化,模型同样也可以结构化。因为当阿里巴巴开始探索将图像、文本和语音等信息加到推荐等系统时,他们会发现这些信息和其它信息又是一个复杂的结构化关系,因此他们开始将模型的分布也结构化。首先数据根据结构关系可以分布在不同的机器上,而这些结构同样可以将计算分配到不同的机器上。所以将模型的计算与数据的结构耦合在一起,它们间的计算量和通讯传输量都能有效降低。
所以以上几点是 XDL 整个的脉络,XDL 团队表示它主要在三个层面上对通用框架有比较大的提升:
首先是对大规模稀疏性数据的建设;
其次是结构化的计算流;
最后在结构化的计算流基础上,模型的分布也需要结构化。
当然,这些都是 XDL 团队在实践中的探索,它们也并没有完美处理各种高维稀疏的情况。但是经过阿里巴巴业务上的检验,整个框架和配套开源的推荐/广告/搜索算法都被被证明非常有效。也许通过开源社区的共同参与,高维稀疏数据的处理能更高效。
用于解决不完全信息下的开放问题的模型
「图像、语音、文本,都是在完全信息下定义的封闭问题。而互联网领域里的机器学习是不完全信息下的开放问题。」靖世概括道。「图像像素已经表征了所有信息,模型能力如果达到极限,就应该能够判定图像中有什么东西,获取目标信息。而在互联网领域,可选数据非常多。以电商为例,除了 item 级别的表征之外,商品图像、详情页信息、评论……都是可以引入的相关数据,但即使囊括所有可得的相关数据,其合集仍然不是完全信息。」
而模型的意义,就是能够从数据中找到特定的规律,既能够拟合现有数据,又能够有一定的推广性。从业务的角度出发,找规律的过程中用到的「数据」,应该是平台能够充分利用所有可得的信息,无论它是以何种形式呈现的。而如何将尽可能多的、类别各不相同的信息引入到模型中,就是 XDL 着重解决的一个问题。
用于广告、推荐、搜索这样任务中的模型,可能乍一看很「简单」:它们不会像单纯的视觉模型一样有数以百计的层数,也不会像纯粹的 NLP 模型一样用模型结构跨越漫长的时间步,几层的模块、全连接的模块在系统里都会很常见。然广告等领域模型的其复杂性正是体现在其「复合」这一特点上。
当模型的输入数据异构特性非常明显的时候,稀疏数据需要做嵌入、时序的数据需要过 LSTM 模块捕捉时序关系、图像数据需要逐层卷积抽象不同粒度的特征,串联多种特征转化为其他网络可接受的输入后,还要进行统一的稠密的计算。不同网络的联动,乃至进一步到系统层面,样本的 I/O 问题,数据流水线的优化工作、训练阶段机器之间频繁的大量的参数交换等等问题,都是没有相应框架就做不了的。
因此,任务与数据形态的不同,看起来是带来了一个算法问题,其实是导致最大的变动出现在框架。乐迪举了个例子,「模型结构复杂了之后,其内部的前向与后向计算的迭代就很难用标准化的方式去做了,批规模的安排、超参的设计与反馈速率,都会极大影响迭代过程。TensorFlow 划分了 ps(parameter server)和 worker,但是 worker 不会再切分。我们的模式可以把模型任意地切分,每一部分都可以选择不同的迭代速率等参数,从而让整个复杂网络的训练变得非常高效。」
「像八爪鱼套八爪鱼。」靖世打了个比方。这样的模型的体量通常十分惊人,见独表示,阿里的场景下,模型的参数规模通常会到达几十亿甚至上百亿,内部应用的模型已经有千亿规模出现。
和 XDL 一起开源的就有一些阿里妈妈实际在用的、验证过有用的「八爪鱼」模型,在 xdl-algorithm-solution 文件夹里,首批就公开了六个模型,其中包括利用图像信息帮助点击率预估的 DICM 以及以预估 CTR 为约束刻画用户兴趣的 DIEN。
CrossMedia Network (论文中具体指 Deep Image CTR Model,DICM),旨在帮助精准展示广告系统为每次投放请求选择收益最大化的广告。CrossMedia Network 主要利用图像信息,包括用于展示和点击的广告图像(Ad image)和用户点击过的商品组成的用户行为图像(User behavior images)。利用这两类信息,结合原有 ID 特征,DICM 模型对于每个广告展示样本的点击或未点击的二元判别,进而转化为点击率预估。
Deep Interest Evolution Network(DIEN) 模型主要用于定向广告排序中的 CTR(点击率)预估阶段,应用于阿里妈妈定向广告各大产品中。传统的点击率预测算法通常直接将用户历史行为表示用户兴趣,DIEN 提出了兴趣抽取和和兴趣演化两个模块,在兴趣提取模块用 auxiliary loss 约束模型找到能够推测出后续的行为的隐层表达,在兴趣演化模块用 GRU 模块根据不同的预估目标商品构建不同的兴趣演化路径。
除了框架、模型之外,XDL 也有提供数据和服务的打算:
「很多测试用户反映模型跑不起来,那我们内部也整理了一些觉得对业界比较有用的数据,在保护用户隐私的前提下,打算以公开数据集的形式发布出来。这个体量对于阿里的业务本身来说可能已经很小了,但是相信对于研究者使用框架跑一些算法验证还是很有帮助的。但是真实数据的规模是非常庞大的,比如我们在某个场景只抽出了 1% 的数据出来,大小仍然有 50 G 的规模。」
而怀人也提到,当结构复杂后,在线预估也会遇到瓶颈:「我们也正在探索根据数据前向计算所需算力的分布,用不同的硬件来做对应的计算,最终做到全局最优化。」在未来,XDL 也计划在训练框架之外,进一步开源高性能在线推理服务引擎,将超大规模模型参数的分布式存储、分布式计算问题也一并解决。
XDL 的 使用姿态
对于开发者而言,最关心的可能是 XDL 如何使用,以及它能帮助我们获得怎样的提升。想象一下,如果我们已经费了九牛二虎之力构建出一个 TensorFlow 深度模型,然而最终发现它在高维稀疏数据下效率很低。那么我们该如何将这个模型迁移到 XDL,并利用其数据结构化与模型结构化的优势进行高效训练?
XDL 团队表示他们在文档上会有一个完整的示例,如果我们写了一个完整的 TensorFlow 模型,那么基本上模型定义部分就不需要修改了,我们只需要在外围写大概十来行的分布式驱动代码就行。增加了 XDL 的分布式驱动后,单机的 TensorFlow 模型就能分布式运行,并具备 XDL 面向高维稀疏数据的大规模并行能力。
靖世表示,其实我们可以认为 XDL 构建了一个大型高维分布式计算图,我们可以将 TensorFlow 构建的静态计算图嵌入到 XDL 分布式计算图中。然后在大型计算图中,TensorFlow 构建的子图可以调用对应的框架,并完成计算。所以说如果模型已经进入到密集的运算及架构设计上,那么其实我们可以将这个子图包装一下并嵌入到 XDL 中。
此外,值得注意的是数据格式,XDL 团队表示输入数据流是根据框架定义的规范和格式,我们需要根据这些格式来准备数据。但是当数据流进入到单机上的稠密网络时,所有数据结构会自动转化为 TensorFlow 内部的数据格式,我们可以按照 TensorFlow 那样的格式定义后面各种各样的网络。虽然 XDL 定义了新的数据结构,用户必须按照经优化的模板定义数据结构,但这样统一的格式可以避免保存、部署和迁移等遇到的大量问题,也能获得更多的性能提升。
总的而言,在使用 XDL 构建大型分布式计算图后,分布式数据流也需要按照格式定义才能传入该计算图。随后我们可以将自己用 TensorFlow 构建的计算图嵌入到 XDL 计算图中,且当 XDL 数据流传输到该独立的子计算图时,它会转化成对应深度学习框架的数据格式,并调用对应的后端完成计算。
TensorFlow 嵌入实例
在 XDL 的使用示例中,其展示了如何结合密集型特征和稀疏性特征,并完成联合训练。其中密集型特征可能是图像或语音等数据,而稀疏性特征可能是用户和商品之间的访问关系。这就相当于将 TensorFlow 模型嵌入到 XDL 中,并承担密集型特征运算,而 XDL 本身会处理稀疏性特征。
在这个示例中,模型包含一路密集型特征 (deep0) 以及两路稀疏性特征 (sparse[0-1]),稀疏性特征通过 Embedding 计算生成两个 8 维密集型向量,并与本来的密集型特征拼接后执行 4 层全连接层运算,并最后得出模型损失。
代码地址:https://github.com/alibaba/x-deeplearning/wiki/%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B
首先是读取数据,我们可以定义读取器,并配置线程数和批量数等读取等设定。因为数据格式是有规范的,所以我们可以像使用 Pandas 读取 CSV 那样简单地抽取不同类型的数据,包括稀疏的访问记录和密集的图像数据等。
随后我们需要定义模型,这里可以分为两路,即稀疏和稠密。其中稀疏数据可以借助 XDL 构建稠密的特征向量,这有点类似于构建 NLP 中的词嵌入向量,它在保留用户和商品等信息的情况下尽可能为密集计算提供便利。
在构建嵌入向量后,它就应该与前面密集型特征拼接在一起并完成第二路的稠密计算。这里仅使用三层全连接网络作为示例,但是我们可以根据需要完成各种复杂的神经网络。此外,由于已有的框架在这些计算上非常有优势,因此我们可以直接导入 TensorFlow 等框架,并将密集型计算分配给它们,这正相当于将子计算图嵌入到了 XDL 分布式计算图中。
最后,我们只要定义最优化器与对应的训练过程就行了,当然损失函数等训练信息也需要在这一部分定义。如下所示,值得注意的是,这里是直接运行 XDL 定义的计算图,并不用管嵌入的 TensorFlow 计算图是什么样的。此外由 TrainSession 可见,XDL 采用的也是一种静态计算图。
当然,这可能只是最简单的一种用法,模型的计算主要集中在单机后面的密集型网络中。但是 XDL 其实还是构建了一个分布式计算图的,它可以理解为多个不同的单机节点构成的复杂网络。其中不同表示我们可以构建很多子网络,这些子网络可以使用 XDL 构建一个更庞大的深度学习网络。这种高级应用其实在业务中很常见,因为搜索、推荐和广告等场景需要的系统通常都非常大。当然如果只需要 XDL 高性能的分布式训练,我们可以仅简单地嵌入单个计算图。