技术动态

01-26
2018
Facebook如何运用机器学习进行亿级用户数据处理
2017年末,Facebook应用机器学习组发布最新论文,对整个Facebook的机器学习软硬件架构进行了介绍。纵览全文,我们也可以从中对Facebook各产品的机器学习策略一窥究竟。论文中涉及到机器学习在全球规模(上亿级数据处理)上的全新挑战,并给出了Facebook的应对策略和解决思路,对相关行业和研究极其有意义。摘要机器学习在Facebook的众多产品和服务中都有着举足轻重的地位。 本文将详细介绍Facebook在机器学习方面的软硬件基础架构,如何来满足其全球规模的运算需求。Facebook的机器学习需求极其繁杂:需要运行大量不同的机器学习模型。这种复杂性已经深深刻在Facebook系统堆栈的所有层面上。此外,Facebook存储的所有数据,有相当大一部分会流经机器学习管道,这样的数据载荷为Facebook的分布式高性能训练流带来巨大的压力。计算需求也非常紧张,在保持用于训练的GPU/CPU平台的同时平衡出大量CPU容量用于实时推理,也带来了异常紧张的。这些问题及其他难题的解决,仍有待我们在跨越机器学习算法、软件和硬件设计上持久而不懈的努力。引言Facebook的使命是“为人类构建社交关系赋能,让世界联系更加紧密”。截至2017年12月,Facebook已经连接了全球超过20亿的人口。同时,过去几年来,机器学习同样在这样一种全球尺度的实际问题上进行着一场革命,包括在机器学习算法创新方面的良性循环,用于模型训练的海量数据以及高性能计算机体系结构的进步。在Facebook上,机器学习几乎在提升用户体验的所有层面都发挥着关键作用,包括诸如新闻推送语音和文本翻译以及照片和实时视频分类的排名等服务。Facebook在这些服务中用到了各种各样的机器学习算法,包括支持向量机,梯度boosted决策树和许多类型的神经网络。本文将介绍Facebook的数据中心架构支持机器学习需求的几个重要层面。其架构包括了内部的“ML-as-a-Service”流,开源机器学习框架,和分布式训练算法。从硬件角度来看,Facebook利用了大量的CPU和GPU平台来训练模型,以便在所需的服务延迟时间内支持模型的训练频率。对于机器学习推理过程,Facebook主要依靠CPU来处理所有主要的服务,而其中神经网络排名服务(比如新闻推送)占据着所有计算负载的大头。Facebook所存储的海量数据中,有一大部分要流经机器学习管道,并且为了提高模型质量,这一部分的数据量还在随着时间推移不断增加。提供机器学习服务所需的大量数据成为了Facebook的数据中心将要在全球规模上面临的挑战。目前已有的可被用来向模型高效地提供数据的技术有,数据反馈和训练的解耦操作,数据/计算协同定位和网络优化。与此同时,Facebook公司这样大的计算和数据规模自身还带来了一个独特的机会。在每天的负载周期内,非高峰期都会空闲出大量可以用来进行分布式训练算法的CPU。Facebook的计算集群(fleet)涉及到数十个数据中心,这样大的规模还提供了一种容灾能力。及时交付新的机器学习模型对于Facebook业务的运营是非常重要的,为了保证这一点,容灾规划也至关重要。展望未来,Facebook希望看到其现有的和新的服务中的机器学习使用频率快速增长。当然,这种增长也将为负责这些服务架构的团队在全球规模的拓展性上带来更加严峻的挑战。尽管在现有平台上优化基础架构对公司是一个重大的机遇,但我们仍然在积极评估和摸索新的硬件解决方案,同时保持对于算法创新的关注。本文(Facebook对机器学习的看法)的主要内容包括:机器学习正在被广泛应用在Facebook几乎所有的服务,而计算机视觉只占资源需求的一小部分。Facebook所需的大量机器学习算法极其繁杂,包括但不限于神经网络我们的机器学习管道正在处理海量的数据,而这会带来计算节点之外的工程和效率方面的挑战。Facebook目前的推理过程主要依靠CPU,训练过程则是同时依靠CPU和GPU。但是从性能功耗比的角度来看,应当不断对新的硬件解决方案进行摸索和评估。全球用户用来使用Facebook的设备每天都可达数亿台,而这会就会提供大量可以用于机器学习任务的机器,例如用来进行大规模的分布式训练。Facebook的机器学习机器学习(ML)是指利用一系列输入来建立一个可调模型,并利用该模型创建一种表示,预测或其他形式的有用信号的应用实例。图1. Facebook的机器学习流程和架构示例图1所示的流程由以下步骤组成,交替执行:建立模型的训练阶段。这个阶段通常离线运行。在应用中运行训练模型的推理阶段,并进行(一组)实时预测。这个阶段是在线执行的。模型进行训练的频率要比推理少得多——推理的时间规模虽然在不断变化,但一般在几天左右。训练也需要相当长的时间来完成,通常是几个小时或几天。同时,根据产品实际需求不同,在线推理阶段每天可能运行达数十万次,而且一般需要实时进行。在某些情况下,特别是对于推荐系统,还需要以这样连续的方式在线进行额外的训练。在Facebook,机器学习的一个显著特征就是有可用于模型训练的海量数据。这个数据的规模会带来很多涉及到整个机器学习架构的影响。使用机器学习的主要服务消息推送消息推送排名算法能够使用户在每次访问Facebook时,最先看到对他们来讲最重要的事情。一般模型会通过训练来确定影响内容排序的各种用户和环境因素。之后,当用户访问Facebook时,该模型会从数千个候选中生成一个最佳推送,它是一个图像和其他内容的个性化集合,以及所选内容的最佳排序。广告广告系统利用机器学习来确定向特定用户显示什么样的广告。通过对广告模型进行训练,我们可以了解用户特征,用户上下文,以前的互动和广告属性,进而学习预测用户在网站上最可能点击的广告。之后,当用户访问Facebook时,我们将输入传递进训练好的模型运行,就能立马确定要显示哪些广告。搜索搜索会针对各种垂直类型(例如,视频,照片,人物,活动等)启动一系列特定的子搜索进程。分类器层在各类垂直类型的搜索之前运行,以预测要搜索的是垂直类型中的哪一个,否则这样的垂直类型搜索将是无效的。分类器本身和各种垂直搜索都包含一个训练的离线阶段,和一个运行模型并执行分类和搜索功能的在线阶段。SigmaSigma是一个分类和异常检测通用框架,用于监测各种内部应用,包括站点的完整性,垃圾邮件检测,支付,注册,未经授权的员工访问以及事件推荐。Sigma包含了在生产中每天都要运行的数百个不同的模型,并且每个模型都会被训练来检测异常或更一般地分类内容。LumosLumos能够从图像及其内容中提取出高级属性和映射关系,使算法能够自动理解它们。这些数据可以用作其他产品和服务的输入,比如通过文本的形式。FacerFacer是Facebook的人脸检测和识别框架。给定一张图像,它首先会寻找该图像中所有的人脸。然后通过运行针对特定用户的人脸识别算法,来确定图中的人脸是否是该用户的好友。Facebook通过该服务为用户推荐想要在照片中标记的好友。语言翻译语言翻译是涉及Facebook内容的国际化交流的服务。Facebook支持超过45种语言之间的源语言或目标语言翻译,这意味着Facebook支持2000多个翻译方向,比如英语到西班牙语,阿拉伯语到英语。通过这2000多个翻译通道,Facebook每天提供4.5B字的翻译服务,通过翻译用户的消息推送,Facebook每天可为全球6亿人减轻语言障碍。目前,每种语言对方向都有其自己的模型,但是我们也正在考虑多语言模型[6]。语音识别语音识别是将音频流转换成文本的服务。它可以为视频自动填补字幕。目前,大部分流媒体都是英文的,但在未来其他语言的识别也将得到支持。另外,非语言的音频文件也可以用类似的系统(更简单的模型)来检测。除了上面提到的主要产品之外,还有更多的长尾服务也利用了各种形式的机器学习。 Facebook产品和服务的长尾数量达数百个。机器学习模型所有基于机器学习的服务都使用“特征”(或输入)来产生量化的输出。Facebook使用的机器学习算法包括Logistic回归(LR),支持向量机(SVM),梯度提升决策树(GBDT)和深度神经网络(DNN)。LR和SVM在训练和预测方面非常有效。GBDT可以通过增加计算资源来提高准确性。DNN是最具表达力的,能够提供最高的准确性,但利用的资源也是最多的(在计算量上,至少比LR和SVM等线性模型高出一个数量级)。这三种模型的自由参数都在变得越来越多,必须通过使用带标签的输入示例来优化预测的准确性。在深度神经网络中,有三类经常使用的网络:多层感知器(MLP),卷积神经网络(CNN)和递归神经网络(RNN / LSTM)。MLP网络通常运行在结构化输入特征(通常是排名)上,RNN / LSTM网络一般用来处理时域的数据,即用作序列处理器(通常是语言处理),相对的CNNs则是一种处理用来空间数据的工具(通常是图像处理)。表I显示了这些机器学习模型类型和产品/服务之间的映射关系。表1 利用机器学习算法的产品或服务Facebook中的ML-as-a-Service为了简化在产品中应用机器学习的任务,我们构建了一些内部平台和工具包,包括FBLearner,Caffe2和PyTorch。FBLearner是三种工具(FBLearner Feature Store,FBLearner Flow,FBLearner Predictor)的套装,其中每种工具分别负责机器学习管道上不同的部分。正如前面图1显示的那样,它利用了一种内部作业调度程序在GPU和CPU的共享资源池上分配资源和调度作业。Facebook大多数机器学习模型的训练过程都是在FBLearner平台上进行的。这些工具和平台被设计来帮助机器学习工程师提高效率,从而能够专注于算法创新。FBLearner Feature Store。任何机器学习建模任务的起点是收集和生成特征。 FBLearner Feature Store本质上是一系列特征生成器的目录,其特征生成器可以用于训练和实时预测,当然它也可以作为多个团队可以用来共享和寻找特征的公共空间(market place)。这样以个特征列表对于刚开始使用机器学习的团队来说是一个很好的平台,同时也有助于在现有模型中应用新特征。FBLearner Flow是Facebook用于训练模型的机器学习平台。Flow是一个管道管理系统,它会执行一个可以描述模型训练和/或评估所需步骤及其所需资源的工作流程(workflow)。这个工作流程由离散单元或操作符(operators)构成,每个单元都有输入和输出。操作符之间的连接会通过跟踪一个操作符到下一个操作符的数据流自动推理,Flow则通过处理调度和资源管理来执行工作流程。Flow还拥有一个可以用于实验管理的工具和一个简单的用户界面,这个界面可以跟踪每个workflow或实验生成的所有构件和指标,从而方便对比和管理这些实验。FBLearner Predictor是Facebook内部的推理引擎,它可以使用在Flow中训练的模型来提供实时的预测。Predictor可以用作多租户服务,也可以用作集成在特定产品的后端服务中的库。Facebook的很多产品团队都在使用Predictor,而其中许多团队都需要低延迟解决方案。Flow和Predictor之间的直接集成还有助于运行在线的实验以及在生产中管理多个版本的模型。深度学习框架我们在Facebook上利用了两种截然不同的协同框架来进行深度学习:针对研究优化的PyTorch和针对生产优化的Caffe2。Caffe2是Facebook的内部生产框架,它用于训练和部署大规模的机器学习模型。Caffe2专注于产品所需的几个关键特性:性能,跨平台支持和基本的机器学习算法,如卷积神经网络(CNN),递归神经网络(RNN)和多层感知器(MLP)。这些网络都具有稀疏或密集的连接以及高达数百亿的参数。该框架的设计采用模块化方法,在所有后端实现(CPU,GPU和加速器)之间共享统一的图表示。为了在不同平台上实现最佳的运行时间,Caffe2还抽象了包括cuDNN,MKL和Meta在内的第三方库。PyTorch是Facebook在AI研究领域的首选框架。它的前端注重灵活性、调试以及动态神经网络,能够快速进行实验。由于依赖于Python来执行,它并没有针对生产和移动端部署进行优化。当研究项目产生了有价值的结果时,模型就需要转移到生产上。过去,在生产环境中,我们通过使用其他框架重写产品环境的训练管道来完成模型转移。最近Facebook开始构建ONNX工具链来简化这个转移过程。比如,动态神经网络虽然被用于尖端的人工智能研究,但这些模型需要更长的时间才能被应用于产品中。通过解耦框架,我们避免了的为满足性能而设计更复杂的执行引擎(比如Caffe2)的需求。此外,相比模型速度,研究人员在进行研究时更看重其灵活性。举个栗子,在模型探索阶段,性能下降30%是可以容忍的,尤其是在它具有易测验和模型可视化的优点时。但是相同的方法并不适合于生产。这种取舍原则在PyTorch和Caffe2的框架设计中也可以看到,PyTorch提供了良好的默认参数和合理的性能,而Caffe2可以选择使用异步图执行,量化权重和多个专用后端等特性来达到最佳性能。虽然FBLearner平台本身不限制使用什么框架,无论是Caffe2,TensorFlow,PyTorch还是其他的框架都可以,但我们的AI软件平台(AI Software Platform)团队为了让FBLearner能够很好地与Caffe2集成还是进行了特定优化。总的来说,分离研究和生产框架(分别是PyTorch和Caffe2)使我们能够在两边灵活运作,减少约束数量的同时还能增加新特性。ONNX. 深度学习工具生态系统在整个行业还处于初级阶段。 对于不同的问题子集,不同的工具有着不同的优势,并且在灵活性,性能和支持平台方面有着不同的折衷,这就跟我们之前对PyTorch和Caffe2所描述的权衡一样。 因此,在不同的框架或平台之间交换训练模型的需求很大。 为了弥补这个缺陷,2017年末,Facebook与几个合作伙伴共同推出了开放式神经网络交换(Open Neural Network Exchange , ONNX)。ONNX是一种以标准方式表示深度学习模型的格式,以便在不同的框架和供应商优化库之间实现互操作。同时,它能满足在不同的框架或平台之间交换训练好的模型的需求。ONNX被设计为一种开放的规范,允许框架作者和硬件供应商为其做出贡献,并拥有框架和库之间的各种转换器。Facebook正在努力使ONNX成为所有这些工具之间的协作伙伴,而不是一种具有排他性的官方标准。在Facebook内部,ONNX是我们将研究模型从PyTorch环境转移到Caffe2中的高性能生产环境的主要手段,它可以实现对模型的自动捕捉和固定部分的转换。在Facebook内部,ONNX是我们将研究模型从PyTorch环境转移到Caffe2中的高性能生产环境的主要手段。 ONNX提供了自动捕捉和转换模型的静态部分的能力。 我们有一个额外的工具链,通过将它们映射到Caffe2中的控制流原函数或者以C ++作为自定义操作符重新实现它们,会有助于将模型从Python转移到动态图。机器学习的资源需求鉴于机器学习在训练和推理(inference)的阶段的资源要求、频率和持续时长不同,我们将分别讨论这两个阶段的细节和资源应用。Facebook硬件资源概况Facebook的基础架构部门(Facebook Infrastructure)很早之前就开始为主要软件服务构建的高效平台,包括针对每种主要工作负载的资源要求定制的服务器、存储以及网络支持。图2 基于CPU的计算服务器。单插槽服务器底座上有4个Monolake服务器卡,双插槽服务器底座还一个双插槽服务器,因此在2U机箱中共有三个双插槽服务器。所以在2U形式的组合中共有12个服务器。当前Facebook提供约八种主要的计算和存储架构,对应八种主要服务。这些主要架构类型足以满足Facebook主要服务的资源要求。例如,图2中展示了一个可以容纳三个计算Sleds模块的2U机架,这些模块可支持两种服务器类型。其中一种Sled模块是单插槽CPU服务器(1xCPU),多用于Web层——一种主要看重吞吐量的无状态服务,因此可以使用能效更高的CPU(Broadwell-D处理器);它的DRAM(32GB)以及主板硬盘或闪存较少。另一种Sled模块是较大的双插槽CPU服务器(2x高功率Broadwell-EP或Skylake SP CPU),它配有大量的DRAM ,常用于涉及大量计算和存储的服务。图3. 搭载8个GPU的Big Basin GPU服务器(3U机架)由于我们训练的神经网络越来越大,并且越来越深,我们开发出了Big Basin GPU服务器(如图3所示),这是我们2017年最新的GPU服务器。最初的Big Basin GPU服务器配置了八个互相连接的NVIDIA Tesla P100 GPU加速器,它使用NVIDIA NVLink形成了一个八CPU混合立方网格,后来,这种设计经过改进之后又应用到了V100 GPU上。Big Basin是早前的Big Sur GPU的继承者,后者是Facebook数据中心首个广泛应用的高性能AI计算平台,用于支持于2015年开发并通过开放计算项目(Open Compute Project)发布的NVIDIA M40 GPU。与Big Sur相比,V100 Big Basin每瓦电可实现的性能更高,这得益于单精度浮点运算单元——每个GPU的运算速度从7 teraflops(每秒万亿次浮点运算)增加到了15.7 teraflops,以及可提供900GB/s的带宽的高带宽显存(HBM2)。这种新的架构还使得半精度运算的速度快了一倍,进一步提高了运算吞吐量。由于Big Basin的运算吞吐量更大,而且显存也从12 GB增加到了16 GB,因此它可以用来训练比先前模型大30%的模型。高带宽NVLink互连GPU通信还强化了分布式训练。在使用ResNet-50图像分类模型进行的测试中,Big Basin的运算吞吐量比Big Sur要高出300%,借助它我们可以以更快的速度训练比以往更复杂的模型。Facebook通过开放计算项目(Open Compute Project)公布了所有这些计算服务器的设计以及几种存储平台。离线训练的资源需求当前,不同的产品会使用不同的计算资源来完成各自的离线训练步骤。有些产品(例如Lumos)在GPU上完成所有的训练。其他产品(例如Sigama)则在双插槽 CPU计算服务器完成所有的训练。诸如Facer这样的产品采用双阶段训练流程,先在GPU上以很小的频率(几个月一次)队通用的面部检测和识别模型进行训练,然后在数千个1xCPU服务器上以很高的频率对每个用户的模型进行特定训练。在本部分,我们将围绕机器学习训练平台、训练频率和持续时长,具体介绍多种服务的细节,并在表II中进行了总结。另外,我们还讨论了数据集的趋势以及这些趋势对计算、内存、存储和网络架构的意义。计算类型和相对数据来源的位置。离线训练既可以在CPU上完成,也可以在GPU上完成,这取决于服务本身。虽然在多数情况下,在GPU上训练出的模型在性能上要比在CPU上训练的模型好,但是CPU强大的现成运算能力使得它成为了一个非常有用的平台。这一点在每天的非高峰期中尤为明显,因为在这期间CPU资源本来就无法得到利用,后面的图4会对此进行说明。下面我们给出了服务和计算资源训练模型的对应关系:在GPU上训练模型的服务: Lumos、语音识别、语言翻译在CPU上训练模型的服务:News Feed、Sigma在GPU和CPU上训练模型的服务:Facer (在GPU上每几年训练一次的通用模型,此类模型较为稳定;在1xCPU上训练的用户特定的模型,此类模型可以用于处理新图像数据)、搜索(利用多个独立的垂直搜索引擎,使用可以进行预测的分类器启动最合适的垂直搜索引擎)。目前,GPU主要被用于离线训练,而不是向用户提供实时数据。因为大多数GPU架构都针对运算吞吐量进行了优化,以克服延迟劣势。同时由于训练过程严重依赖从大型数据生成库中获取的数据,考虑到性能和带宽方面的原因,GPU必须靠近数据来源。由于训练模型所使用的数据量增长的相当快,GPU是否靠近数据来源变得越来越重要。内存、存储和网络:从内存储器容量的角度看,CPU和GPU平台都能为训练提供充足的存储容量。即使对于Facer这样的应用,也可以在1xCPU上用32GB RAM训练用户特定的SVM模型。如果可以尽可能地利用高效平台以及多余的存储容量,则平台的总体训练效率会非常优秀。表II 不同服务的离线训练的频率、持续时长和资源机器学习系统依赖于使用实例数据的训练。Facebook 使用了机器学习数据管道中的大量数据。这使得计算资源趋向于靠近数据库。随着时间的推移,大多数服务会显示出利用累积的用户数据的趋势,这将导致这些服务更加依赖Facebook的其他服务,并且需要更大的网络带宽来获取数据。因此,只有在数据源所在地或附近部署巨大的存储,以便从偏远的区域大规模转移数据,从而避免为了等待获取更多样本数据而关停训练管道。在部署训练机器的位置时,我们也可以使用这种方法来避免训练机群给附近的存储资源造成过大的压力。不同的服务在离线训练期间使用的数据量有很大的差别。几乎所有服务的训练数据集都呈现出持续增长甚至大幅增长的趋势。例如,有些服务在ROI降低之前会使用数百万行数据,其他服务则使用数百亿行数据(100多TB),并且只受到资源的限制。 扩展(Scaling)考虑和分布式训练:训练神经网络的过程包含使用随机梯度下降法(SGD)对参数权重进行优化。这种方法用于拟合神经网络,通过评价标记实例的小子集(即“batch” 或“mini-batch”)来迭代更新权重。在数据并行中,网络会生成多个模型副本(并行实例),以并行的处理多批数据。当使用一台机器训练模型时,模型越大或更深都会带来更好的训练效果,准确度也会更高,但是训练此类模型往往需要处理更多的样本。当使用一台机器进行训练时,我们可以通过增加模型副本的数量并在多个GPU上执行数据并行,来最大化训练效果。当训练所需的数据量随时间增加,硬件限制会导致总体训练延迟和收敛时间增加。不过,我们可以使用分布式训练来克服这些硬件限制,减少延迟。这个研究领域在Facebook和整个AI研究界相当热门。一种普遍的假设是,在不同机器上实现数据并行需要使用一种专门的互连机制。但是,在我们对分布式训练的研究中,我们发现基于以太网(Ethernet)的网络就可以提供近似线性的扩展能力。能否实现近似线性的扩展,与模型的大小和网络带宽有密切的关系。如果网络带宽太小,执行参数同步所花的时间比执行梯度计算所花的时间还多,在不同机器上进行数据并行所带来的优势也会大打折扣。使用50G的以太网NIC,我们可以用Big Basin服务器扩展视觉模型的训练,而且机器间的同步完全不会造成问题。在所有情况下,更新都需要使用同步(每个副本都看到相同状态),一致性(每个副本生成正确更新)和性能(子线性缩放)的技术来与其他副本共享,这可能会影响训练质量。 例如,翻译服务目前就不能在不降低模型质量的情况下进行大批量的小批量(mini-batches)训练。相反,如果使用特定的超参数设置,我们就可以在非常大的mini-batch数据集上训练图像分类模型,并且可以扩展到256个以上的GPU上。实验证明,在Facebook的某个大型服务中,在5倍的机器上执行数据并行可以实现4倍的训练效率(例如:训练一组训练时间超过4天的模型,以前总共可以训练100个不同模型的机器集群现在每天只能训练同样的20个模型,训练效率降低了20%,但是潜在的工程进度等待时间从4天减少到了1天)。如果模型变得超级大,这时候就可以使用并行训练,对模型的层进行分组和分布,以优化训练效率,各机器间可以传递激活单元。优化可能与网络带宽、延迟或平衡内部机器限制有关。这会增加模型的端对端延迟,因此,每一时步(time step)内原始性能的增强通常与步长(step)质量的下降有关。这可能会进一步降低模型在每个步长的准确度。各步长准确度的下降最终会累积起来,这样我们就可以得出并行处理的最佳步长数量。DNN模型本身的设计使得它只能在一台机器上运行,在推理阶段,在机器间分割模型图通常会导致机器与机器进行大量的沟通。但是Facebook的主要服务会不断地权衡扩展模型的利与弊。这些考虑可以决定网络容量需求的变化。表 III 在线推理服务的资源要求在线推理的资源需求在完成离线训练之后的线推理步骤中,我们需要将模型载入到机器中,使用实时输入运行模型来生成网站流量的实时结果。接下来我们将讨论,一种实际应用中的在线推理模型——广告排名模型。这种模型可以筛选成千上万条广告,在消息推送中显示排在1至5名的广告。这个过程是通过对依次减小的广告子集进行逐步复杂的排名运算循环(passes)来实现的。每一轮运算都会用到类似于多层感知模型(MLP)的模型,这种模型包含稀疏嵌入层,每一轮运算都会缩小广告的数量。稀疏嵌入层需要大量的内存,因此当进行到靠后的运算时,模型的超参数数量更多,它将在独立于MLP运算轮的一个服务器上运行。从计算的角度上看,绝大多数在线推理都是在大量1xCPU(单插槽)或2xCPU(双插槽)上运行的。由于1xCPU对Facebook的服务而言性能更高,而且性价比更高,因此Facebook提倡尽可能使用1xCPU服务器训练模型。随着高性能移动硬件的诞生,Facebook甚至可以在用户的移动设备上直接运行某些模型,来改进延迟和降低通信成本。但是,某些需要大量计算和内存资源的服务仍然需要使用2xCPU才能实现最佳性能。不同的产品在得出在线推理的结果时拥有不同的延迟要求。在某些情况下,得出的数据可能“十分优秀” ,也可能会在向用户返回初步快速评估后被重新输入到模型中。例如,在某些情况中将某个内容分类为合格是可以接受的,但是当运行更加复杂的模型时这个初步的分类结果就会被推翻。广告排名和消息推送之类的模型配置有稳定的SLA,可以向用户推送合适的内容。这些SLA决定着模型的复杂性和依赖性,因此如果拥有更加强大的计算能力,我们就可以训练出更加先进的模型。机器学习数据计算除了资源需求外,在数据中心部署机器学习时还需要考虑一些重要的因素,包括对重要数据的需求以及面对自然灾害的可靠性。从获取数据到模型Facebook公司的许多机器学习模型,成功的主要因素就是广泛而高质量的可用数据。快速处理并将这些数据提供给机器学习模型的能力能够确保我们部署快速有效的离线训练。对于复杂的机器学习应用程序,如广告和排名,每个训练任务所需的数据量都超过数百TB大小。此外,复杂的预处理逻辑的使用能确保数据被清理并归一化,以便高效地迁移和更轻松地学习。这些操作对资源的要求非常高,特别对存储量,网络和CPU的需求。作为一个通用的解决方案,我们尝试对训练工作量中的数据进行解耦。这两个工作量都有非常显著的特点。一方面,它非常复杂,具有临时的,依赖业务性的,且变化快等特点。另一方面,训练工作量通常是固定的(例如GEMM),稳定的(核心业务相对较少),高度优化,且更偏爱于“干净”的环境下工作(例如,独占高速缓存使用和最小线程争夺)。为了优化这两者,我们在物理上对不同的机器的不同工作负载进行隔离。数据处理机器,又名“readers”,从存储器中读取数据,处理和压缩它们,然后将结果反馈给一个叫做“trainers”的训练机器。另一方面,trainers只专注于快速有效地执行任务。readers和trainers可以分布以便提供更灵活性和可扩展性的应用。此外,我们还优化了不同工作负荷的机器配置。另一个重要的优化指标是网络使用。训练过程产生的数据流量非常重要的,并且有时候会突然产生。如果没有智能化处理的话,这很容易就会导致网络设备的饱和,甚至干扰到其他服务。为了解决这些问题,我们采用压缩优化,调度算法,数据/计算布局等等操作。利用规模作为一家为用户提供服务的全球性公司,Facebook必须保持大量服务器的设计能够满足在任何时间段内的峰值工作负载。如图所示,由于用户活动的变化取决于日常负荷以及特殊事件(例如地区节假日)期间的峰值,因此大量的服务器在特定的时间段内通常是闲置的。这就释放了非高峰时段内大量可用的计算资源。利用这些可能的异构资源,以弹性方式合理分配给各种任务。这是Facebook目前正努力探索的一大机会。对于机器学习应用程序,这提供了将可扩展的分布式训练机制的优势应用到大量的异构资源(例如具有不同RAM分配的CPU和GPU平台)的机会。但是,这也会带来一些挑战。在这些低利用率的时期,大量可用的计算资源将从根本上导致分布式训练方法的不同。调度程序首先必须正确地平衡跨越异构硬件的负载,这样主机就不必为了同步性而等待其他进程的执行。当训练跨越多个主机时,调度程序还必须要考虑网络拓扑结构和同步所需的成本。如果处理不当,机架内或机架间同步所产生的流量可能会很大,这将极大地降低训练的速度和质量。
01-19
2018
Java 领域的五大发展预测,新的发布计划将推动创新
IBM 杰出工程师兼 Java 首席技术官 John Duimovich 近日对 2018 年 Java 领域做了五大预测,预测内容如下:预测 1:Eclipse 将变得更加重要随着 EE4J 和 MicroProfile 等关键项目的开展,Eclipse 基金会将在 2018 年变得更加重要。随着开放社区越来越多地参与这些重要项目和其他与 Java 相关的项目,寻求快速创新。 今年,开发人员将更加关注 Eclipse 基金会。预测 2:加速与容器的融合作为简化开发和管理的工作的一部分,容器和运行时将更加紧密耦合,共同优化,以实现 Java 应用程序的无缝管理和配置。Java 结构和容器之间的一致的内存管理和更容易的连接将被保留下来,以便开发人员可以利用容器和 Java 运行时的优点,本质上,这是另一种形式的容器。预测 3:Kotlin 将成为热门编程语言Kotlin 有望成为编程界的一支主力军。 Kotlin的 简洁的语法和与 Java 的互操作性使它广受开发者的欢迎。 现在,它在 Android 上有了一流的支持,必将推动其在手机上的使用。 在 2018 年它将获得更大的发展空间。预测 4:新的版本发布计划将推动创新Java 新的发布计划意味着,今年将发布 Java 10 和 Java 11 两个版本。频繁的更新意味着,可以更快引入新的功能,更好地解决问题。大型组织可能会等待长期支持版的发布,现在他们有了清晰的线路图。社区支持可以围绕临时版的流行趋势展开。预测 5:无服务器将带来重大的 Java 重构无服务器平台的需求正在增长 - 最初是作为消费模型来驱动的,但现在正在从简单的事件编程模型扩展到基于复合流的系统。 随着云开发人员将重点转移到应用程序,而不必担心服务器,这种创新将继续下去。 这意味着 Java 运行时将需要进行优化和重构,以适应无服务器的世界。
01-16
2018
今天是Windows 10免费升级的最后一天0101
1月16日消息:今天是Windows 7/8.1免费升级Windows 10的最后一天了,虽然这个“最后一天”已经不是第一次了。  微软将在明天正式关闭Windows 10免费升级通道,之后拥有正版Windows 7和Windows 8.1的用户想要升级到Windows 10,只能花钱了。Windows 10  事实上,微软在2016年7月29日就结束了正常的Windows 10免费升级通道,但为了视听障碍人士,微软的辅助技术免费升级通道一直都没有关闭。  所以,在2016年7月29日之后,人们仍然可以通过辅助技术通道免费将Windows 7和Windows 8.1升级到Windows 10。  就在上个月,微软宣布这个通道会在12月31日关闭,结果还是没能关闭成功,延期到了现在。这一次应该是真要关闭了吧?Windows 7/8.1免费升级Windows 10系统的最后一个“后门”即将于明天正式封闭。这意味着用户在今天之后将不再免费升级,今后想要升级至少需要支付119.99美元(Windows 10家庭版本)的费用。Windows 10上线之初,微软提供了长达1年的免费升级计划,无论是正版还是盗版用户在这个时间段内都可以免费升级至Windows 10。2016年7月29日免费通道关闭之后,用户发现通过“辅助技术”依然能够免费升级。辅助技术更新是Windows 10在2016年7月一年免费升级期结束后的一个“小小漏洞”。因为微软对辅助技术的定义相当宽泛,包括使用键盘快捷方式、放大镜的Win7/8.1客户都算,所以实质上几乎适用于任何人。微软最初曾表示将于2017年12月31日关闭这个漏洞,不过本月微软宣布做出调整,延长至1月16日。
01-17
2018
谷歌出来走两步:Home Max可致无线路由器崩溃0101
1月17日消息,谷歌Home Max智能音箱已经正式发售,价格是399美元。没想到上市没有多长时间,就有该产品的用户在谷歌论坛上反馈该音响问题频频。谷歌Home Max可致无线路由器崩溃(图片来自TheVerge)       谷歌产品论坛上有了一份初步报告,称用户在使用Home Max播放音乐时,无线网络可能会产生崩溃停止工作的情况。 目前谷歌方面要求用户将含有关键字“GHT3 -无法设置最大的网络”的截图和路由器日志的情况保留,以便他们对此问题进行诊断。       对于出现的问题, 谷歌公司的发言人对此作出回应,谷歌Home Max用户反映的问题描述显示,当该用户的Home Max连接无线网络时,无线路由器就会崩溃,只能通过重启无线路由器来解决这个问题。       不过一部分用户认为,路由器的硬件配置不同可能是导致这个问题出现的原因。但自最初的用户反映该情况以后,有人证实,他们在不同的无线路由器上都遇到了同样的问题。      据了解,谷歌Home Max是一款尺寸较大的音箱。这款音箱配备了双4.5英寸低音单元和0.7英寸的高音单元。谷歌在10月份的发布会上表示,谷歌Home Max的音量要比谷歌Home大20倍,而用户可以通过Cast、蓝牙或3.5毫米接口去连接音箱。       Home Max还支持Smart Sound功能,它将会让扬声器自动适应房间尺寸,消除一些杂音。如果将音响放置在墙边或者架子上,它们会听起来不同。Smart Sound功能就能够让这些差别消除。       Home Max能够支持许多主流音乐在线平台,比如YouTube Muisc Spotify以及Google Play Muisc、Pandora等。
01-17
2018
Python语言,如何在人工智能和大数据时代中占绝对的优势0101
本文探讨了Python语言在AI领域的优势与运用。谁会成为AI 和大数据时代的第一开发语言?这本已是一个不需要争论的问题。如果说三年前,Matlab、Scala、R、Java 和  Python还各有机会,局面尚且不清楚,那么三年之后,趋势已经非常明确了,特别是前两天 Facebook 开源了 PyTorch  之后,Python 作为 AI 时代头牌语言的位置基本确立,未来的悬念仅仅是谁能坐稳第二把交椅。不过声音市场上还有一些杂音。最近一个有意学习数据科学的姑娘跟我说,她的一个朋友建议她从 Java 入手,因为 Hadoop 等大数据基础设施是用 Java 写的。无独有偶,上个月 IBM developerWorks  发表的一篇个人博客(https://www.ibm.com/developerworks/community/blogs/jfp/entry/What_Language_Is_Best_For_Machine_Learning_And_Data_Science?lang=en),用职位招聘网站indeed  上的数据做了一个统计。这篇文章本身算得上是客观公正,实事求是,但传到国内来,就被一些评论者曲解了本意,说 Python 的优势地位尚未确立,鹿死谁手尚未可知,各位学习者不可盲目跟风啊,千万要多方押宝,继续撒胡椒面不要停。在这里我要明确表个态,对于希望加入到 AI 和大数据行业的开发人员来说,把鸡蛋放在 Python 这个篮子里不但是安全的,而且是必须的。或者换个方式说,如果你将来想在这个行业混,什么都不用想,先闭着眼睛把 Python 学会了。当然,Python不是没有它的问题和短处,你可以也应该有另外一种甚至几种语言与 Python 形成搭配,但是Python 将坐稳数据分析和 AI 第一语言的位置,这一点毫无疑问。我甚至认为,由于 Python 坐稳了这个位置,由于这个行业未来需要大批的从业者,更由于Python正在迅速成为全球大中小学编程入门课程的首选教学语言,这种开源动态脚本语言非常有机会在不久的将来成为第一种真正意义上的编程世界语。讨论编程语言的优劣兴衰一直被认为是一个口水战话题,被资深人士所不屑。但是我认为这次 Python 的上位是一件大事。请设想一下,如果十五年之后,所有40岁以下的知识工作者,无分中外,从医生到建筑工程师,从办公室秘书到电影导演,从作曲家到销售,都能使用同一种编程语言进行基本的数据处理,调用云上的人工智能  API,操纵智能机器人,进而相互沟通想法,那么这一普遍编程的协作网络,其意义将远远超越任何编程语言之争。目前看来,Python  最有希望担任这个角色。Python 的胜出令人意外,因为它缺点很明显。替换高清大图它语法上自成一派,让很多老手感到不习惯;“裸” Python 的速度很慢,在不同的任务上比C  语言大约慢数十倍到数千倍不等;由于全局解释器锁(GIL) 的限制,单个Python 程序无法在多核上并发执行;Python 2 和 Python  3  两个版本长期并行,很多模块需要同时维护两个不同的版本,给开发者选择带来了很多不必要的混乱和麻烦;由于不受任何一家公司的控制,一直以来也没有一个技  术巨头肯死挺 Python 。所以,相对于 Python 的应用之广泛,其核心基础设施所得到的投入和支持其实是非常薄弱的。直到今天,26岁的Python 都还没有一个官方标配的 JIT 编译器,相比之下, Java 语言在其发布之后头三年内就获得了标配 JIT 。另一个事情更能够说明问题。Python 的 GIL 核心代码 1992 年由该语言创造者 Guido van Rossum 编写,此后十八年时间没有一个人对这段至关重要的代码改动过一个字节。十八年!直到2010年,Antoine Pitrou才对 GIL 进行了近二十年来的第一次改进,而且还仅在 Python 3.x  版本中使用。这也就是说,今天使用 Python 2.7 的大多数开发者,他们所写的每一段程序仍然被26年前的一段代码牢牢制约着。说到 Python 的不足,我就想起发生在自己身上的一段小小的轶事。我多年前曾经在一篇文章里声明自己看好 Python,而不看好 Ruby。大概两年多以前,有一个网友在微博里找到我,对我大加责备,说因为当年读了我这篇文章,误听谗言,鬼迷心窍,一直专攻 Python,而始终对 Ruby 敬而远之。结果他Python 固然精通,但最近一学 Ruby,如此美好,如此甜蜜,喜不自胜,反过来愤然意识到,当年完全被我误导了,在最美的年华错过了最美的编程语言。我当时没有更多的与他争辩,也不知道他今天是否已经从Python后端、大数据分析、机器学习和 AI 工程师成功转型为Rails快速开发高手。我只是觉得,想要真正认识一件事物的价值,确实也不是一件容易的事情。Python 就是这样一个带着各种毛病冲到第一方阵的赛车手,但即便到了几年前,也没有多少人相信它有机会摘取桂冠,很多人认为 Java 的位置不可动摇,还有人说一切程序都将用 JavaScript重写。但今天我们再看,Python 已经是数据分析和 AI的第一语言,网络攻防的第一黑客语言,正在成为编程入门教学的第一语言,云计算系统管理第一语言。Python 也早就成为Web 开发、游戏脚本、计算机视觉、物联网管理和机器人开发的主流语言之一,随着 Python 用户可以预期的增长,它还有机会在多个领域里登顶。而且不要忘了,未来绝大多数的 Python 用户并不是专业的程序员,而是今天还在使用 Excel、PowePoint、SAS、Matlab和视频编辑器的那些人。就拿 AI 来说,我们首先要问一下,AI 的主力人群在哪里?如果我们今天静态的来谈这个话题,你可能会认为 AI 的主力是研究机构里的 AI 科学家、拥有博士学位的机器学习专家和算法专家。但上次我提到李开复的 “AI红利三段论”明确告诉我们,只要稍微把眼光放长远一点,往后看三至五年,你会看到整个 AI  产业的从业人口将逐渐形成一个巨大的金字塔结构,上述的 AI 科学家仅仅是顶端的那么一点点,95% 甚至更多的 AI 技术人员,都将是AI  工程师、应用工程师和AI 工具用户。我相信这些人几乎都将被Python 一网打尽,成为 Python 阵营的庞大后备军。这些潜在的 Python 用户至今仍然在技术圈子之外,但随着 AI  应用的发展,数百万之众的教师、公司职员、工程师、翻译、编辑、医生、销售、管理者和公务员将裹挟着各自领域中的行业知识和数据资源,涌入 Python  和 AI 大潮之中,深刻的改变整个 IT,或者说 DT (数据科技)产业的整体格局和面貌。为什么 Python 能够后来居上呢?如果泛泛而论,我很可以列举 Python 的一些优点,比如语言设计简洁优雅,对程序员友好,开发效率高。但我认为这不是根本原因,因为其他一些语言在这方面表现得并不差。还有人认为 Python 的优势在于资源丰富,拥有坚实的数值算法、图标和数据处理基础设施,建立了非常良好的生态环境,吸引了大批科学家以及各领域的专家使用,从而把雪球越滚越大。但我觉得这是倒因为果。为什么偏偏是 Python 能够吸引人们使用,建立起这么好的基础设施呢?为什么世界上最好的语言 PHP 里头就没有  numpy 、NLTK、sk-learn、pandas 和 PyTorch 这样级别的库呢?为什么 JavaScript  极度繁荣之后就搞得各种程序库层次不齐,一地鸡毛,而 Python 的各种程序库既繁荣又有序,能够保持较高水准呢?我认为最根本的原因只有一点:Python 是众多主流语言中唯一一个战略定位明确,而且始终坚持原有战略定位不动摇的语言。相比之下,太多的语言不断的用战术上无原则的勤奋去侵蚀和模糊自己的战略定位,最终只能等而下之。Python 的战略定位是什么?其实很简单,就是要做一种简单、易用但专业、严谨的通用组合语言,或者叫胶水语言,让普通人也能够很容易的入门,把各种基本程序元件拼装在一起,协调运作。正是因为坚持这个定位,Python 始终把语言本身的优美一致放在奇技妙招前面,始终把开发者效率放在CPU效率前面,始终把横向扩张能力放在纵向深潜能力之前。长期坚持这些战略选择,为 Python 带来了其他语言望尘莫及的丰富生态。比如说,任何一个人,只要愿意学习,可以在几天的时间里学会Python基础部分,然后干很多很多事情,这种投入产出比可能是其他任何语言都无法相比的。再比如说,正是由于 Python 语言本身慢,所以大家在开发被频繁使用的核心程序库时,大量使用 C 语言跟它配合,结果用 Python 开发的真实程序跑起来非常快,因为很有可能超过 80% 的时间系统执行的代码是 C 写的。相反,如果 Python 不服气,非要在速度上较劲,那么结果很可能是裸速提高个几倍,但这样就没人有动力为它开发 C 模块了,最后的速度远不如混合模式,而且很可能语言因此会变得更复杂,结果是一个又慢又丑陋的语言。更重要的是,Python 的包装能力、可组合性、可嵌入性都很好,可以把各种复杂性包装在 Python 模块里,暴露出漂亮的接口。很 多时候,一个程序库本身是用 C/C++ 写的,但你会发现,直接使用 C 或者 C++  去调用那个程序库,从环境配置到接口调用,都非常麻烦,反而隔着一层,用其python 包装库更加清爽整洁,又快又漂亮。这些特点到了 AI  领域中,就成了 Python 的强大优势。Python 也借助 AI 和数据科学,攀爬到了编程语言生态链的顶级位置。Python 与 AI绑在一起,对它们来说,无论是电子商务、搜索引擎、社交网络还是智能硬件,未来都只是生态链下游的数据奶牛、电子神经和执行工具,都将听命于自己。替换高清大图对编程语言发展历史缺乏了解的人可能会觉得,Python 的战略定位是犬儒主义和缺乏进取心的。但事实证明,能同时做到简单而严谨、易用而专业,是很难的,而能够坚守胶水语言的定位,更是难上加难。有的语言,从一开始就是出于学术而非实用的目的,学习曲线过于陡峭,一般人很难接近。有的语言,过于依赖背后金主的商业支持,好的时候风光无限,一旦被打入冷宫,连生存下去都成问题。有的语言,设计的时候有明确的假想场景,要么是为了解决大规模并发,要么是为了解决矩阵运算,要么是为了做网页渲染模板,一旦离开这个场景,就各种不爽。更多的语言,刚刚取得一点成功,就迫不及待的想成为全能冠军,在各个方向上拼命的伸展触角,特别是在增强表达能力和提升性能方面经常过分积极,不惜将核心语言改得面目全非,最后变成谁都无法掌控的庞然大物。相比之下,Python 是现代编程语言设计和演化当中的一个成功典范。Python 之所以在战略定位上如此清晰,战略坚持上如此坚定,归根结底是因为其社区构建了一个堪称典范的决策和治理机制。这个机制以 Guido van Rossum (BDFL,Pythoners 都知道这是什么意思), DavidBeazley,  Raymond Hettinger 等人为核心,以 PEP 为组织平台,民主而有序,集中而开明。只要这个机制本身得以维系,Python  在可见的未来里仍将一路平稳上行。最有可能向 Python 发起挑战的,当然是Java。Java 的用户存量大,它本身也是一种战略定位清晰而且非常坚定的语言。但我并不认为 Java 有很大的机会,因为它本质上是为构造大型复杂系统而设计的。什么是大型复杂系统?就是由人清清楚楚描述和构造出来的系统,其规模和复杂性是外生的,或者说外界赋予的。而 AI 的本质是一个自学习、自组织的系统,其规模和复杂性是一个数学模型在数据的喂养下自己长出来的,是内生的。因此,Java大多数的语言结构对于大数据的处理和 AI 系统的开发显得使不上劲,你强的东西这里用不上,这里需要的东西你做起来又别扭。而 Python 在数据处理方面的简洁强悍早就尽人皆知。对比两个功能相同的 Java 和 Python 机器学习程序,正常人只要看两眼就能做出判断,一定是 Python 程序更加清爽痛快。大概在 2003 或者 2004 年的时候,我买过一本 Python 的书,作者是一位巴西人。他说自己之所以坚定的选择 Python,是因为他小时候经常梦到未来世界将由一条大蟒蛇(蟒蛇的英文为python)统治。我当时觉得这哥们好可怜,做个梦都能梦到这么恐怖的场景。但今天来看,也许他只是像黑客帝国里的程序员安德森一样,不小心穿越到未来,并且窥探到了世界的真相。Python 现已逐步在网络爬虫、数据剖析、AI、机器学习、Web  开发、金融、运维、检验等多个领域扎根强大。随着它的被认可程度逐步提高,学习并把握这门言语的人群份额越来越大,许多公司也将为抢占该领域高精尖人才做着殊死搏斗!能够说,未来谁具有人工智能领域的技术权威,谁将会具有新年代互联网最高话语权。那么,在此之中,学好Python,必将让你在编程生计中大刀阔斧,勇闯天边!Python无疑将会成为AI年代下的新宠儿,
01-17
2018
修修补补又一年,微信小程序的困局在哪里?0101
微信小程序上线了游戏,而一年前,微信团队还信誓旦旦的宣称小程序不做游戏。张小龙说,现在跳一跳小程序日活已经1.7亿。也就是说,上线小游戏,微信才有公开数据的勇气。当然,食言这事谁都干过,比如马云也说过绝不做游戏。不过,当小程序打开了游戏界面之后,也就意味着小程序走到头了,有人说是毕业了,或者是肄业了,不管怎样,小程序已经背离了初心。这一年,微信小程序一直都在折腾,提供的功能无所不有了,不断的调整能力,上线新应用,但依然只是宣传上火爆而已。如果说小程序还有救,那只能是因为腾讯而已。对于大多数互联网应用,上市即决定成败,即便腾讯用了所有力量力推,也很难。腾讯为什么要做小程序?基本上看,有几个主要原因。第一,腾讯的业务以游戏为主,虽然也做了很多努力,但始终效果不佳,如果无法摆脱这种发展模式,面对中国游戏产业3000亿左右的产值,天花板将是腾讯难以逾越的障碍,也是未来被阿里巴巴拉下的必然。所以,腾讯希望用小程序连接一切,最重要的是开发其他的业务出来,拓展生存空间。第二,腾讯的能力主要体现在线上,只要是纯线上的业务发展就会很好,反之就会折戟。要想改变这个状态,就需要新的抓手,基于微信和二维码,小程序有可能成为线上线下的连接器,这对腾讯是最重要的。第三,虽然本身叫“小程序”,但其实是腾讯在把应用做重。微信本身是以轻应用起家并占领手机客户端的,所以,过重始终是微信管理团队的担忧。不过,随着流量富裕时代到来,重应用不再是问题,而且,这几年移动互联网发展证明,靠拉规模做范围然后寻找商业模式的互联网方式在移动端都不成功,只有把应用做重,在应用中设计付费才是出路,微信也必须走这条路。所以,小程序的本来设计是,用完即走,简单明快,这样才能更多的涉及全社会,而不是沉湎于个别热点之上。从本质上说,小程序承载的是腾讯的线下梦想。如今,本来要给微信引流的小程序现在变成靠微信引流,这可不是腾讯的初衷,如今连初心都改了,只是维持一个公众预期和资本故事而已。我们看到,承载着为微信连接线上线下连接使命的小程序,最终火的反倒是一些线上的功能,如腾讯自家的“王者荣耀小程序”、“腾讯投票”、“群里有事”,以及一些基于社交的爆款小程序,如“匿名聊聊”和同样基于好友分享的电商类小程序,如“拼多多”等。如果非要拿出一个线上线下的,恐怕也只有摩拜,而摩拜至今还陷入死战,多项指标落后,生死未卜。从通信视角看,微信这种应用轻、用户端重就是管道化,微信让运营商管道化了,然后微信自己也管道化了,这是腾讯最不愿意看到的。微信既不敢也没有能力让客户端变轻,自己主动加重又怕成为最后一根稻草,所以,小程序采取了很多主动轻量级的措施,这是在试错,如果可以承受,小程序会逐步变重,否则就会淡化退出。小程序并非是利用微信流量,只是利用微信的装机量,还要承担为微信拉流量的任务。很多人都只是看到了微信流量大,却忽视了微信流量垃圾流量占多数,微信的单位流量变现价值极低,从微信电话本开始,微信一直在找提高流量价值的出路,有成功也有失败,总体看,不理想。最近一段,微信开始主动试探网络电话,这其实就是在管道化无奈的情况下的只得去争抢运营商的蛋糕。那么,为什么小程序即便得到了全腾讯资源的竭尽全力的推动依然效果不好呢?因为,小程序从本质上违背了腾讯之所以成功的理念,不再注重用户的产品体验,而是以自我商业目的为中心的提供漫天功能,需要具备阿里巴巴的强运营思维才可以但这却是腾讯最缺乏的。此前,腾讯所有成功的业务都是讲产品做到极致,然后利用其强大的社交媒体流量吸引用户进来,但是,小程序是个例外,一直在拉用户进来,然后再看大家的反应而改动产品特性和功能。有专业人士指出,尽管争议不断,但微信强推小程序的决心丝毫未见动摇:开放“搜一搜”入口、马化腾亲自站台乘车码、拉拢星巴克等大品牌、推出信用分等动作,都是为了推广小程序,上一次微信在一个产品上如此下力气,大概还要追溯到微信支付上线之时。如此用心,小程序却依旧低迷。一句话,“小程序不好玩”,这对以游戏起家的腾讯产品就是致命的。由此,什么添加音视频、加上游戏等等,都没有必要分析,下一步添加Vr添加AI也是如此,只是在强行用呼吸机维持小程序生命而已。好吧,既然不好玩就没有找到出路,那么,现在直接上了游戏,这不就好玩了吗?可是,微信或者微信小程序直接上了游戏,这不就等于将微信给QQ化,让腾讯在游戏化的道路上更加坚持,所为大连接变成了游戏链接,与曾经的设计是南辕北辙。
02-08
2018
E01
div css布局中对于图片列表或图片排版时,图片不是固定宽度高度大小,但图片占位是固定宽度高度,这个时候如果使用CSS固定死图片大小(宽度 高度),这个时候如果图片相对于这个位置不是等比例大小,那么这张图片就会变形,让图片变的不清晰,这个时候想让图片不变形又按比例缩放,如何解决?CSS图片缩小不变形,图片自动缩小,图片按比例等比例缩小不变形解决。解决方法有两种:第一种,让图片和布局宽度高度成等比例,这样CSS设置死宽度和高度,图片也是等比例缩小,图片也不会变形。比如淘宝,要求店铺主上传产品封面图片是正方形的,为什么,因为图片宝贝展示列表都是正方形的排版布局,这样要求上传合适正方形宝贝封面图片,也是让图片不变形。所以有条件的情况下,大家将首页、图片列表页的布局宽度高度保持一致,上传图片时候将图片先进行处理为布局宽度高度时等比例放大尺寸的。第二种,使用CSS max-width和max-height实现图片自动等比例缩小很简单我们要使用到max-width和max-height,这样即可设置对象图片最大宽度和最大高度,这样图片就会等比例缩放图片,然图片相对不变形清晰。以下通过实例对比方法让大家掌握CSS控制图片缩小不变形技巧。一、原始描述 这里有个div,CSS宽度和CSS高度方便为300px和100px同时设置1px黑色边框,里面放了一张图片(图片原始宽度650px为高度为406px)。并通过CSS固定死图片宽度高度。1、HTML源代码:<!DOCTYPE html>  <html>  <head>  <meta charset="utf-8" />  <title>图片缩小不变形实例  我改了下 </title>  <style>  .divcss{ border:1px solid #000; width:300px; height:100px}  .divcss img{width:300px; height:100px}  </style>  </head>    <body>  <div class="divcss">  <img src="img.jpg" />  </div>  </body>  </html>2、CSS固定死图片宽度高度实例截图原始图片展示:原始图片截图css固定宽度高度后变形的图片截图3、小结,通过CSS固定对象内图片高度宽度,这样图片如果不是等比例缩小,那么图片就变形了。二、CSS解决图片缩小不变形实例使用max-width:300px或max-height:100px,即可解决图片比例缩小。但这样存在一个问题,如果按照宽度缩放,但图片过高会超出溢出盒子,这个时候需要对父级使用overflow:hidden隐藏超出图片内容。但是使用max-width或max-height,IE6不支持,我们需要设置个width:expression(this.width > 300 ? "300px" : this.width);或者height:e­xpression(this.height>100?"100px":this.height);。解决IE6支持max-heightdiv css解决IE6支持max-width一般情况下只需要设置好宽度限制,比如这里只设置最大宽度为300px(max-width:300px),然后对父级使用overflow:hidden隐藏溢出图片,同时为了兼容IE6我们设置个width:expression(this.width > 300 ? "300px" : this.width);解决即可。1、具体解决DIV+CSS实例代码如下:<!DOCTYPE html>  <html>  <head>  <meta charset="utf-8" />  <title>图片缩小不变形实例 www.divcss.com</title>  <style>  .divcss{ border:1px solid #000; width:300px; height:100px;overflow:hidden}  .divcss img{max-width:300px;_width:expression(this.width > 300 ? "300px" : this.width);}  </style>  </head>    <body>  <div class="divcss">  <img src="img.jpg" />  </div>  </body>  </html>2、浏览器测试效果截图css图片缩小等比例缩小后不变形截图3、缺点介绍,如果使用此方法,兼容各大浏览器不变形,但图片不是完整显示的。
01-31
2018
c++01
// Updates history of min bitrates. // After this method returns min_bitrate_history_.front().second contains the // min bitrate used during last kBweIncreaseIntervalMs. // 主要结合这个函数解释下变量min_bitrate_history_ // 这个变量的两个维度,front记录的是离当前最远的时间, // 每个速率都是按照时间先后顺序逐渐push到尾部。 // 因此更新的时候,需要先将超时的元素从列表头剔除。 // 后一个维度是最小速率值, // 在相同的时间区间内,保留最小的速率值。 // |-------Interval 1---------|----------Interval 2------| // |                          |                          | // |--t1 < t2 < t3 < t4 < t5--|--t1 < t2 < t3 < t4 < t5--| // 这样的操作较为简单,不用在每次插入元素时去判断对应的时间区域,再找到对应时间区间的最小值,用部分冗余的内存换取操作的快捷。 void SendSideBandwidthEstimation::UpdateMinHistory(int64_t now_ms) {   // Remove old data points from history.   // Since history precision is in ms, add one so it is able to increase   // bitrate if it is off by as little as 0.5ms.   while (!min_bitrate_history_.empty() &&          now_ms - min_bitrate_history_.front().first + 1 >              kBweIncreaseIntervalMs) {     min_bitrate_history_.pop_front();   }   // Typical minimum sliding-window algorithm: Pop values higher than current   // bitrate before pushing it.   while (!min_bitrate_history_.empty() &&          bitrate_ <= min_bitrate_history_.back().second) {     min_bitrate_history_.pop_back();   }   min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); }