斯坦福cs329p——实用机器学习

目录:

  1. Data collection
  2. Data Preprocessing
  3. ML model recap
  4. Model Validation
  5. Model Combination
  6. Covariate and Concept Shift
  7. Label Shift and Drift Detection
  8. Data beyond IID
  9. Model Tuning
  10. Deep Network Tuning
  11. Transfer Learning
  12. Distillation
  13. Multimodal data
  14. Model Deployment
  15. Fairness (Criteria)
  16. Fairness (Fixes) and Explainability
  17. Guest Lecture
  18. Guest Lecture

主页:https://c.d2l.ai/stanford-cs329p/

李沐的中文版: https://space.bilibili.com/1567748478/video

独立开发变现周刊

独立开发变现周刊

目录:

  1. 独立开发变现周刊(第 1 期):Notion也能做博客?
  2. 独立开发变现周刊(第 2 期):挑战100天获取100个付费用户
  3. 独立开发变现周刊(第 3 期):100个CSS加载动画
  4. 独立开发变现周刊(第 4 期):Friendly月收入1万美金学到10件重要的事
  5. 独立开发变现周刊(第 5 期):Notion Api 终于开放公测啦
  6. 独立开发变现周刊(第 6 期):一个Telegram机器人卖了32万美金
  7. 独立开发变现周刊(第 7 期):让创作者的支付更简单
  8. 独立开发变现周刊(第 8 期):实操从$0开始通过Notion模板一个月内赚到$1000
  9. 独立开发变现周刊(第 9 期):创造者领域融资13亿美元,开发者有机会吗?
  10. 独立开发变现周刊(第 10 期):uTools, 一款极简、插件化效率工具
  11. 独立开发变现周刊(第 11 期):独立开发者管理一千万用户的感受
  12. 独立开发变现周刊(第 12 期):VS Code插件可以赚到钱吗?
  13. 独立开发变现周刊(第 13 期):No Code实现从一个群到一个网站月收入3千美金
  14. 独立开发变现周刊(第 14 期):获取前1000个用户的3个策略
  15. 独立开发变现周刊(第 15 期):独立开发者做小产品,要善用平台价值
  16. 独立开发变现周刊(第 16 期):让你的网站养只可爱的宠物吧
  17. 独立开发变现周刊(第 17 期):为了活下去,如何获取前200个付费用户?
  18. 独立开发变现周刊(第 18 期):一个通过短信进行购物的网站平台
  19. 独立开发变现周刊(第 19 期):基于Gmail的CRM浏览器插件,年收入1000万美金
  20. 独立开发变现周刊(第 20 期):和2个朋友做的产品以8位数美金的价格卖给了微软

【转载】机器学习编译器和优化器的友好介绍

我有一个忏悔。我在大学编译器课上哭了。我成为了一名机器学习工程师,这样我就不必担心编译器了。

然而,随着我更多地了解将 ML 模型投入生产,编译器的话题不断出现。在许多用例中,尤其是在边缘运行 ML 模型时,模型的成功仍然取决于其运行的硬件,这使得在生产中使用 ML 模型的人员了解他们的模型如何编译和优化以运行非常重要在不同的硬件加速器上。

理想情况下,编译器是不可见的,一切都会“正常工作”。然而,我们距离这一点还有很多年。随着越来越多的公司希望将 ML 带到边缘,并且越来越多的硬件正在为 ML 模型开发,越来越多的编译器正在开发以弥合 ML 模型和硬件加速器之间的差距——MLIR 方言、TVM、XLA、 PyTorch Glow、cuDNN 等。 根据 PyTorch 的创建者 Soumith Chintala 的说法,随着 ML 采用的成熟,公司将竞争谁可以更好地编译和优化他们的模型

了解编译器的工作原理可以帮助您选择正确的编译器,将您的模型带到您选择的硬件上,以及诊断性能问题并加速您的模型。

ML编译器大战


ML 的下一个竞赛是编译器(Soumith Chintala,Venture Beat 2020)

这篇文章(希望如此)是对 ML 编译器的友好、无泪的介绍。它始于边缘计算的兴起,我相信这将编译器从系统工程师的领域带入了普通 ML 从业者的领域。如果您已经对 ML 的优势深信不疑,请随时跳过这一部分。

下一部分是关于在边缘部署 ML 模型的两个主要问题:兼容性和性能、编译器如何解决这些问题以及编译器如何工作。最后提供了一些关于如何使用几行代码显着加快 ML 模型的资源。


目录

……
1. 云计算与边缘计算

……
2.编译:兼容性

….
3. 优化:性能

……
4. 如何优化您的 ML 模型

……
5. 手工设计与基于机器学习的编译器

……
6. 不同类型的编译器

……
7. 编译器的下一步是什么


1. 云计算与边缘计算

想象一下,您已经训练了一个令人难以置信的 ML 模型,其准确性超出了您最疯狂的期望。您很高兴能够部署此模型,以便用户可以访问它。

最简单的方法是将您的模型打包并通过托管云服务(例如 AWS 或 GCP)进行部署,这是有多少公司在开始使用 ML 时部署的。云服务在使公司轻松将 ML 模型投入生产方面做得非常出色。

但是,云部署有很多缺点。首先是成本。ML 模型可能是计算密集型的,并且计算成本很高。甚至在 2018 年,像 Pinterest、Infor、Intuit 等大公司每年已经在云账单上花费数亿美元 [ 1 , 2 ]。对于中小型公司来说,这个数字每年可能在5 万200 万美元之间处理云服务的错误可能导致初创公司破产 [ 1 , 2 ]。

云账单


随着 AWS 使用量的激增,公司对云账单感到惊讶。
图片来自 The Information (2018)。

随着云计算费用的攀升,越来越多的公司正在寻找将其计算推向消费设备(边缘设备)的方法。在边缘完成的计算越多,对云的需求就越少,他们为服务器支付的费用也就越少。

除了有助于控制成本外,还有许多特性使边缘计算具有吸引力。首先是它允许您的应用程序在云计算无法运行的地方运行。当您的模型位于公共云上时,它们依赖稳定的 Internet 连接将数据发送到云并返回。边缘计算允许您的模型在没有 Internet 连接或连接不可靠的情况下工作,例如在农村地区或发展中国家。

其次,当您的模型已经在消费者的设备上时,您可以少担心网络延迟。需要通过网络传输数据(将数据发送到云上的模型进行预测,然后将预测发送回用户)可能会使某些用例变得不可能。在许多情况下,网络延迟是比推理延迟更大的瓶颈。例如,您可能能够将 ResNet50 的推理延迟从 30 毫秒减少到 20 毫秒,但网络延迟可能高达数秒,具体取决于您所在的位置。下图显示了从佛蒙特州(我正在访问的地方)到世界上各个服务器中心的网络延迟。

来自佛蒙特州的网络延迟


Ping 结果从佛蒙特州到世界各地的服务器。
ping.psa.fun 的结果

在处理敏感的用户数据时,将模型置于边缘也很有吸引力。云上的机器学习意味着您的系统可能必须通过网络发送用户数据,使其容易被拦截。云计算通常还意味着将多个用户的数据存储在同一个地方,这意味着数据泄露会影响到很多人。据《安全》杂志 2020 年报道,近 80% 的公司在过去 18 个月中经历了云数据泄露。边缘计算使遵守有关如何传输或存储用户数据的法规(例如 GDPR)变得更加容易。

2.编译:兼容性

由于边缘计算相对于云计算具有许多优势,因此公司正在竞相开发针对不同 ML 用例进行优化的边缘设备。谷歌、苹果、特斯拉等老牌公司都宣布了自己制造芯片的计划。与此同时,机器学习硬件初创公司已经筹集了数十亿美元来开发更好的人工智能芯片。

2020 年筹集资金的 MLOps 硬件初创公司


人工智能硬件初创公司的一个子集(CrunchBase 的融资信息)

有了这么多用于运行 ML 模型的硬件新产品,一个问题就出现了:我们如何使使用任意框架构建的模型在任意硬件上运行?

对于在硬件上运行的框架,它必须得到硬件供应商的支持。例如,尽管 TPU 于 2018 年 2 月公开发布,但直到 2020 年 9 月,TPU 才支持 PyTorch。在此之前,如果您想使用 TPU,则必须使用 TensorFlow 或 JAX。

在某种类型的硬件(平台)上为框架提供支持是耗时且工程密集的。从 ML 工作负载映射到硬件需要了解并能够利用硬件的基础设施。然而,一个基本的挑战是不同的硬件类型具有不同的内存布局和计算原语,如下面的Chen 等人的插图所示.

例如,CPU 的计算原语曾经是一个数字(标量),GPU 的计算原语曾经是一个一维向量,而 TPU 的计算原语是一个二维向量(张量)。然而,如今许多 CPU 具有向量指令,而一些 GPU 具有二维张量核心。与二维向量相比,一维向量对一批 256 张图像 x 3 通道 x 224 W x 224 H 执行卷积算子将有很大不同。同样,您需要考虑不同的 L1、L2 和 L3 布局和缓冲区大小以有效地使用它们。

不同硬件后端的计算原语和内存布局


计算不同硬件后端的原语和内存布局。
图片由 Chen 等人提供,2018 年。

正因如此,框架开发者往往只专注于为少数服务器级硬件(例如 GPU)提供支持,而硬件供应商则倾向于为范围狭窄的框架提供自己的内核库(例如 Intel 的 OpenVino 只支持Caffe、TensorFlow、MXNet、Kaldi 和 ONNX。NVIDIA 有 CUDA 和 cuDNN)。将 ML 模型部署到新硬件(例如手机、嵌入式设备、FPGA 和 ASIC)需要大量的手动工作。

框架-硬件兼容性


如何在任意硬件后端运行使用任意框架构建的模型。

代替 ?
带有编译器名称。

中间代表 (IR)

如果我们创建一个中间人来桥接框架和平台,而不是针对每种新的硬件类型和设备都针对新的编译器和库呢?框架开发者将不再需要支持每一种类型的硬件,只需要将他们的框架代码翻译成这个中间人。那么硬件供应商可以支持一个中间框架而不是支持多个吗?

中间人代表 (IR) 作为中间人


中间人代表 (IR) 作为中间人

这种类型的“中间人”称为中间表示(IR)。IR 是编译器工作方式的核心。根据模型的原始代码,编译器在生成硬件原生代码以在特定平台上运行模型之前生成一系列高级和低级中间表示。

为了从 IR 生成机器原生代码,编译器通常利用代码生成器,也称为代码生成器。ML 编译器使用的最流行的代码生成器是LLVM,由 Vikram Adve 和 Chris Lattner(他们通过创建 LLVM 改变了我们对系统工程的概念)开发。TensorFlow XLA、NVIDIA CUDA 编译器 (NVCC)、MLIR(用于构建其他编译器的元编译器)和 TVM 都使用 LLVM。

此过程也称为“降低”,因为您将高级框架代码“降低”为低级硬件本机代码。这不是“翻译”,因为它们之间没有一对一的映射。

高级 IR 通常是 ML 模型的计算图。对于熟悉 TensorFlow 的人来说,这里的计算图类似于您在 TensorFlow 1.0 中遇到的计算图,之前 TensorFlow 切换到 Eager Execution。在 TensorFlow 1.0 中,TensorFlow 在运行模型之前首先构建了模型的计算图。此计算图允许 TensorFlow 了解您的模型以优化其运行时。

高级 IR 通常与硬件无关(不关心它将在什么硬件上运行),而低级 IR 通常与框架无关(不关心模型是用什么框架构建的)。

IR


高级 IR 和低级 IR。

我们将在下一节中讨论 Tuned IR。

3.优化:性能

在您“降低”代码以将模型运行到您选择的硬件中后,您可能会遇到的一个问题是性能。Codegen 非常擅长将 IR 降低为机器代码,但根据目标硬件后端,生成的机器代码可能无法正常执行。生成的代码可能不会利用数据局部性和硬件缓存,或者可能不会利用可以加速代码的高级功能,例如向量或并行操作。

典型的 ML 工作流由许多框架和库组成。例如,您可以使用 pandas/dask/ray 从数据中提取特征。您可以使用 NumPy 来执行矢量化。您可以使用 LightGBM 之类的树模型来生成特征,然后使用使用各种框架(如 sklearn、TensorFlow 或 Transformer)构建的模型集合进行预测。

尽管这些框架中的个别功能可能会被优化,但跨框架几乎没有优化。在这些函数之间移动数据以进行计算的幼稚方式可能会导致整个工作流程的速度下降一个数量级。斯坦福 DAWN 实验室的研究人员进行的一项研究发现,与手动优化的代码相比,使用 NumPy、Pandas 和 TensorFlow 的典型机器学习工作负载在一个线程中的运行速度要慢 23 倍Palkar 等人,’18)。

在生产中通常发生的是数据科学家/机器学习工程师 pip 安装他们工作所需的包。事情似乎在开发环境中运行良好,因此他们将模型部署到生产环境中。当他们在生产中遇到性能问题时,他们的公司通常会聘请优化工程师来为他们运行的硬件优化他们的模型。

2020 年筹集资金的 MLOps 初创公司


Cruise 优化工程师的工作描述

2020 年筹集资金的 MLOps 初创公司


Mythic 优化工程师的职位描述

优化工程师很难找到,而且招聘成本很高,因为他们需要了解机器学习和硬件架构。

为了帮助降低聘请优化专家的成本,我们可以求助于同时适用于机器学习模型和硬件的优化编译器。在将 ML 模型代码降级为机器代码的过程中,编译器可以查看您的 ML 模型的计算图及其包含的运算符(卷积、循环、交叉熵等),并找到一种方法来加速它。也优化您的代码的编译器称为优化编译器。我们将在下一节详细介绍如何优化您的 ML 模型。


总结一下您到目前为止所涵盖的内容,编译器桥接了 ML 模型和它们运行的​​硬件。优化编译器由两个组件组成:降低和优化。这两个组件不一定是分开的。优化可以发生在从高级 IR 到低级 IR 的所有阶段。

  • 降低:编译器为您的模型生成硬件本机代码,以便您的模型可以在某些硬件上运行。
  • 优化:编译器优化您的模型以在该硬件上运行。

4. 如何优化您的 ML 模型

有两种方法可以优化您的 ML 模型:本地和全局。本地是当您优化模型的一个运算符或一组运算符时。全局是当您端到端地优化整个计算图时。

已知有标准的局部优化技术可以加速您的模型,其中大多数技术使事物并行运行或减少芯片上的内存访问。以下是三种常用的技术。

  • 向量化:给定一个循环或嵌套循环,而不是一次执行一项,而是使用硬件原语对内存中连续的多个元素进行操作。
  • 并行化:给定一个输入数组(或 n 维数组),将其划分为不同的、独立的工作块,并分别对每个块进行操作。
  • 循环平铺:更改循环中的数据访问顺序以利用硬件的内存布局和缓存。这种优化依赖于硬件。CPU 上的良好访问模式不是 GPU 上的良好访问模式。请参阅下面由Colfax Research 提供的可视化
  • 运算符融合:将多个运算符融合为一个以避免冗余内存访问。例如,对同一个数组的两个操作需要对该数组进行两次循环;在融合的情况下——它只是一个循环。请参阅下面Matthias Boehm的示例
循环平铺


Colfax Research 的循环平铺可视化。

算子融合


Matthias Boehm 的算子融合示例。

根据 Weld(另一个编译器)的创建者 Shoumik Palkar 的说法,这些标准的局部优化技术有望提高约 3 倍的速度当然,这个估计是高度依赖于上下文的。

要获得更大的加速,您需要利用计算图的更高级别结构。例如,给定一个卷积神经网络,计算图可以垂直或水平融合,以减少内存访问并加速模型。请参阅下面由 NVIDIA 的TensorRT 团队制作的可视化

图优化


卷积神经网络计算图的纵向和横向融合。

TensorRT 的插图。

5. 手工设计与基于机器学习的编译器

手工设计的规则

正如上一节通过卷积神经网络的垂直和水平融合所暗示的那样,有许多可能的方法来执行给定的计算图。例如,给定 3 个运算符 A、B 和 C,您可以将 A 与 B 融合,将 B 与 C 融合,或者将 A、B 和 C 融合在一起。

传统上,框架和硬件供应商会聘请优化工程师,他们根据自己的经验提出如何最好地执行模型计算图的启发式方法。例如,NVIDIA 可能有一个工程师或一个工程师团队专门专注于如何让 ResNet-50 在他们的 DGX A100 服务器上真正快速运行。(这也是为什么你不应该过多地阅读MLPerf 的结果。在某种硬件上运行得非常快的流行模型并不意味着任意模型在该硬件上运行得非常快。可能只是这个模型是过度优化)。

手工设计的规则有几个缺点。首先是它们不是最佳的。不能保证工程师提出的启发式方法是最好的解决方案。

其次,它们是非自适应的。在新框架或新硬件架构上重复这个过程需要大量的努力。

由于模型优化取决于构成其计算图的一组运算符,因此这很复杂。优化卷积神经网络不同于优化循环神经网络,也不同于优化变压器。NVIDIA 和 Google 专注于在其硬件上优化 ResNet 和 BERT 等流行模型。但是,作为 ML 研究人员,如果您想出一个新的模型架构呢?在被硬件供应商采用和优化之前,您可能需要自己对其进行优化以证明它的速度很快。

使用机器学习加速机器学习模型

目标是在所有可能的方法中找到执行计算图的最快方法。如果我们尝试所有可能的方法,记录他们需要运行的时间,然后选择最好的方法会怎样?

问题是有太多可能的方法(路径)来探索(组合!),并且尝试所有方法都被证明是不可行的。如果我们使用 ML 来:

  • 缩小搜索空间,因此我们不必尝试那么多路径。
  • 预测一条路径需要多长时间,这样我们就不必等待整个计算图完成执行。

估计通过整个计算图的路径运行所需的时间非常困难,因为它需要对该图进行大量假设。目前的技术可能只关注图表的一小部分。

如果您在 GPU 上使用 PyTorch,您可能已经看到torch.backends.cudnn.benchmark=True. 当此设置为 True 时,将启用cuDNN 自动调谐cuDNN 自动调谐搜索一组预先确定的选项以执行卷积算子,然后选择最快的方式。如果每次迭代都运行相同的 convnet 形状,cuDNN 自动调整会很有帮助。第一次运行卷积算子时会很慢,因为 cuDNN 自动调谐需要时间来运行搜索。但是在后续运行中,cuDNN 将使用自动调整的缓存结果来选择最快的配置。

cuDNN autotune尽管有效,但仅适用于卷积算子,而且 AFAIK 仅适用于 PyTorch 和 MXNet。一个更通用的解决方案是autoTVM,它是开源编译器堆栈 TVM 的一部分。autoTVM使用子图而不仅仅是运算符,因此它使用的搜索空间要复杂得多。autoTVM 的工作方式非常复杂,但要点如下:

  1. 它首先将您的计算图分解为子图。
  2. 它预测每个子图有多大。
  3. 它分配时间为每个子图搜索最佳路径。
  4. 它缝合了将每个子图运行在一起以执行整个图的最佳方式。

autoTVM 测量运行每条路径所需的实际时间,这为其提供了地面实况数据以训练成本模型以预测未来路径将花费多长时间。这种方法的优点在于,因为模型是使用运行时生成的数据进行训练的,所以它可以适应它运行的任何类型的硬件。缺点是成本模型需要更多时间才能开始改进。

autoTVM 加速


与 cuDNN 在 NVIDIA TITAN X 上的 ResNet-50 相比,

基于 ML 的 TVM 提供的加速。基于 ML 的 TVM 需要约 70 次试验才能胜过 cuDNN。

Chen 等人的实验。


autotvm 成本模型


TVM 的成本模型如何运作

像 TVM 这样的编译器是自适应的、灵活的,当您想尝试新硬件时尤其有用。一个例子是苹果在 2020 年 11 月发布了他们的 M1 芯片M1是基于ARM的片上系统,ARM架构或多或少都比较好理解。但是,M1 的 ARM 实现仍然有很多新颖的组件,需要进行大量优化才能使各种 ML 模型在其上快速运行。发布一个月后,OctoML 的人们表明,autoTVM 所做的优化比 Apple 的 Core ML 团队手工设计的优化快了近 30%. 当然,随着 M1 的成熟和手工优化变得密集,自动优化将很难击败手工优化。但系统工程师可以利用 autoTVM 等工具来加速优化。

虽然自动调整的结果令人印象深刻,但它们有一个问题:TVM 可能很慢。您遍历所有可能的路径并找到最优化的路径。对于复杂的 ML 模型,此过程可能需要数小时甚至数天。但是,这是一次性操作,您的优化搜索结果可以缓存并用于优化现有模型并为未来的调整会话提供一个起点。您为一个硬件后端优化一次模型,然后在同一后端的多个设备上运行它。当您有一个准备好用于生产的模型并且目标硬件可以运行推理时,这种优化是理想的。

6. 不同类型的编译器

最广泛使用的编译器类型是由主要框架和硬件供应商开发的针对特定框架和硬件组合的特定领域编译器。不出所料,最受欢迎的产品是由最大的供应商开发的。

  • NVCC(NVIDIA CUDA 编译器):仅适用于 CUDA。闭源。
  • XLA(Accelerated Linear Algebra,Google):最初是为了加速 TensorFlow 模型,但已被 JAX 采用。作为 TensorFlow 存储库的一部分开源
  • PyTorch Glow (Facebook):PyTorch 已经采用 XLA 在 TPU 上启用 PyTorch,但对于其他硬件,它依赖于 PyTorch Glow。作为 PyTorch 存储库的一部分开源

一般而言,第三方编译器非常雄心勃勃(例如,您必须非常自信地认为您可以比 NVIDIA 更好地针对 GPU 进行优化)。但是第三方编译器很重要,因为它们有助于降低新框架、新一代硬件、新模型的性能开销,让小玩家有机会与拥有自己的编译器针对现有产品进行大量调整的老牌玩家竞争。

我看到的最好的第三方编译器是 Apache TVM,它适用于各种框架(包括 TensorFlow、MXNet、PyTorch、Keras、CNTK)和各种硬件后端(包括 CPU、服务器 GPU、ARM、 x86、移动 GPU 和基于 FPGA 的加速器)。

另一个我觉得令人兴奋的项目是MLIR,它最初也是由 Chris Lattner(LLVM 的创建者)在 Google发起的但是,它现在属于 LLVM 组织。MLIR 并不是一个真正的编译器,而是一个元编译器,允许您构建自己的编译器的基础设施。MLIR 可以运行多个 IR,包括 TVM 的 IR,以及 LLVM IR 和 TensorFlow 图。

WebAssembly (WASM)

这是我非常兴奋的事情,我需要为此创建一个部分。WASM 是我在过去几年中看到的最令人兴奋的技术趋势之一。它性能卓越、易于使用,并且拥有一个像野火一样不断发展的生态系统 [ 1 , 2 ]。截至 2021 年 9 月,全球 93% 的设备都支持它

我们一直在讨论编译器如何帮助我们为我们的模型生成机器原生代码以在某些硬件后端上运行。如果我们想生成一些可以在任何硬件后端上运行的代码怎么办?

进入了很好的旧浏览器。如果您可以在浏览器中运行您的模型,您就可以在任何支持浏览器的设备上运行您的模型:Macbook、Chromebook、iPhone、Android 手机等。您无需关心这些设备使用什么芯片。如果苹果决定从英特尔芯片转向 ARM 芯片,那不是你的问题!

WebAssembly 是一个开放标准,允许您在浏览器中运行可执行程序。在 sklearn、PyTorch、TensorFlow 或您使用的任何框架中构建模型后,您可以将模型编译为 WASM,而不是编译模型以在特定硬件上运行。你会得到一个可执行文件,你可以只用 JavaScript 来使用它。

WASM 的主要缺点是因为 WASM 在浏览器中运行,所以速度很慢。尽管 WASM 已经比 JavaScript 快得多,但与在设备(例如 iOS 或 Android 应用程序)上本地运行代码相比,它仍然很慢。Jangda 等人的一项研究显示编译为 WASM 的应用程序运行速度比原生应用程序平均慢 45%(在 Firefox 上)到 55%(在 Chrome 上)。

有许多编译器可以帮助您编译为 WASM 运行时。最流行的可能是 Emscripten(它也使用 LLVM 代码生成器),但它只能从 C 和 C++ 编译成 WASM。scailable应该从 scikit-learn 模型转换为 WASM,但它在 GitHub 上只有 13 颗星,并且在过去 3 个月内没有更新(它甚至还在维护吗?)。TVM 是我所知道的唯一一个从ML 模型编译为 WASM 的活动编译器如果您知道任何其他编译器,请告诉我,我很乐意在此处添加它们!

提示:如果您决定试用 TVM,请使用他们的非官方 conda/pip 命令进行快速安装,而不是使用 Apache 站点上的说明。如果您需要帮助,他们只有一个 Discord 服务器

7. 编译器的下一步是什么

考虑您的模型如何在不同的硬件后端上运行会很有帮助,这样您就可以提高它们的性能。Austin Huang在我们的MLOps Discord发帖称,他经常通过使用简单的现成工具(量化工具、Torchscript、ONNX、TVM)而无需太多努力就可以看到 2倍的加速。

这里有一个很棒的技巧列表,可以帮助您在 GPU 上加速 PyTorch 模型,甚至无需使用编译器。

当您的模型准备好部署时,有必要尝试不同的编译器,看看哪一个能给您带来最佳的性能提升。您可以并行运行这些实验。一个推理请求的小幅提升可以累积成数百万或数十亿推理请求的大回报。

尽管用于机器学习的编译器已经取得了巨大的进步,但在我们完全从一般 ML 从业者那里抽象出编译器之前,还有很多工作要做。想想像 GCC 这样的传统编译器。您使用 C 或 C++ 编写代码,GCC 会自动将您的代码降低为机器代码。大多数 C 程序员甚至不关心 GCC 生成什么中间表示。

未来,机器学习编译器可以采用同样的方式。您使用框架以计算图的形式创建 ML 模型,您的 ML 编译器可以为您运行的任何硬件生成机器原生代码。您甚至无需担心中间表示。

TVM 之类的工具是使未来成为可能的步骤。

致谢

我要感谢 Luke Metz、Chris Hoge、Denise Kutnick、Parimarjan Negi、Ben Schreiber、Tom Gall、Nikhil Thorat、Daniel Smilkov、Jason Knight 和 Luis Ceze,他们耐心地回答了我的数百个问题并使这篇文章成为可能。

【转载】【漏洞分析】Facebook email disclosure and account takeover

I have a preference for apps over web when it comes to hunting, so in January I decided to dive deep into apk endpoints hoping to find something juicy.

比起网络,我更喜欢应用程序,所以在一月份我决定深入 apk endpoints,希望能找到一些有趣的东西。

I downloaded bunch of FB and messenger apks of different versions, grepped all the endpoints, sorted them and was going through them

我下载了很多不同版本的 FB 和 messenger 应用程序,润滑了所有端点,对它们进行了排序,并正在浏览它们

During the process, I came across another an interesting endpoint named:

在这个过程中,我遇到了另一个有趣的端点,名为:

POST auth/flashcall_account_recovery

POST auth/flashcall _ account _ recovery

The endpoint required 3 parameters:
cuid, encrypted_phone_numbers & cli

端点需要3个参数: cuid,encrypted _ phone number & cli

The CUID basically meant encrypted email/phone and can be easily found.

Just supply victim’s email in

CUID 基本上意味着加密的电子邮件/电话,可以很容易地被找到。只要提供受害者的电子邮件在

POST /recover_accounts

POST/recover_accounts

And in response you’d get the CUID.

作为回应,你会得到 CUID。

Secondly, while going through the Facebook’s password recovery flow.

其次,在浏览 Facebook 的密码恢复流程时。

I noticed that in the endpoint responsible for sending the FB OTP code, there was a parameter named:

我注意到,在负责发送 FB OTP 代码的端点上,有一个参数名为:

should_use_flash_call=false

应该使用 flash call = false

If its false, you’d receive an OTP SMS in your phone and if set true, you receive a phone call instead of OTP for account recovery.

如果是假的,你会收到一个 OTP 短信在你的手机,如果设置为真,你会收到一个电话,而不是 OTP 的帐户恢复。

And in the response it contained the required encrypted phone numbers.

在回复中,它包含了所需的加密电话号码。

Now, I could not figure out what cli was.
The only thing coming to my mind was “cli~command line interface

现在,我不知道 cli 是什么,我脑子里唯一想到的是“ cli ~ 命令行界面”

Unable to figure out, I supplied null value instead.

由于无法确定,我改为提供了空值。

When made the request,
I received the userID belonging to the user, whose email value I supplied as the CUID.

当发出请求时,我收到了属于该用户的 userID,我提供了其电子邮件值作为 CUID。

Meaning an attacker could supply anyone’s email/phone as CUID and in response he would be exactly able to determine who that email belonged to.

这意味着攻击者可以提供任何人的电子邮件/电话作为 CUID,作为回应,他可以准确地确定这封电子邮件属于谁。

I quickly submitted the report and it was triaged and fixed within a day.

我迅速提交了报告,并在一天之内进行了分类和修复。

I was veryyyyy curious about this endpoint as I had never used a “phone call recovery” to reset my password.

我对这个端点非常好奇,因为我从来没有用“电话恢复”来重置我的密码。

Neither it was present in my UI, nor was there much info available regarding this account recovery flow in Google as well as Youtube.

在我的用户界面中没有,也没有很多关于 Google 和 Youtube 账户恢复流程的信息。

So I started to analyze how this recovery flow works by reading the smali files.

因此,我开始通过读取 smali 文件来分析这个恢复流是如何工作的。

The endpoint worked in following manner.

端点以下列方式工作。

  1. I enter my email/phone. 我输入我的电子邮件/电话
  2. Choose phone call recovery option. 选择电话恢复选项
  3. I receive a phone call. 我接到一个电话
  4. That phone number will be automatically supplied to the endpoint as: 该电话号码将自动提供给端点,如下:

POST /flash_call_recovery

POST/flash _ call _ recovery

cuid=x&enc_phone=x&cli=+1xxxxx

2.1.1.2.2.2.2.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3

Turns out in cli parameter we are basically supposed to supply the phone number from which we received the phone call in Step3.

结果在 cli 参数中,我们基本上应该提供我们在 Step3接到电话的电话号码。

Now it all made sense why it was called phone call recovery🤦‍♂️

现在一切都说得通了,为什么它被称为“复苏电话”(phone call recovery)

I guess the cli means something like caller identification.

我猜 cli 的意思是来电显示之类的。

In an ideal scenario when supplied all valid values, we would then receive this following response:

在理想的情况下,当提供所有有效值时,我们将收到以下响应:

{“id”:”UserID”,”nonce”:”XXXX”,"skip_logout_pw_reset":""}

{“ id”: “ UserID”,“ nonce”: “ XXXX”,“ skip _ logout _ pw _ reset”: “”}

This nonce value acts as an OTP code and then will be supplied to the OTP verification endpoint.

此 nonce 值充当 OTP 代码,然后将提供给 OTP 验证端点。

The OTP verification endpoint is then responsible for validating the nonce and setting the new password.

OTP 验证端点负责验证 nonce 并设置新密码。

In POST /flash_call_recovery , I initially tested if supplying another user’s valid cli with victim’s cuid would work, but it didn’t.

在 POST/flash _ call _ recovery 中,我最初测试了将受害者的 cuid 提供给另一个用户的有效 cli 是否可行,但没有成功。

I tried flipping every parameters here and there but non of them worked.

我试着翻转每一个参数,但是没有一个有效。

Now, the only option I was left with was bruteforcing the cli.

现在,我唯一的选择就是强迫他们。

Considering how strict FB is with rate limiting since it even has rate limit implemented on non authentication endpoints I had little to no hope.

考虑到 FB 在速率限制方面有多么严格,因为它甚至在非身份验证端点上实现了速率限制,我几乎没有希望。

But to my absolute surprise, it had no rate limit implemented in this endpoint.

但令我惊讶的是,在这个端点没有实施速率限制。

Hence the attack would work like this:

因此,攻击的工作原理如下:

  1. User supplies victim’s 用户提供受害者的cuid and enc_phone_number in flashcall recovery endpoint 在闪点恢复终端
  2. Bruteforces the 粗暴的强迫cli
  3. Receives the 接收nonce from the response 从反应
  4. Supplies the 供应nonce in OTP verification endpoint and sets a new password for victim’s account. 在 OTP 验证端点,并设置一个新的密码为受害者的帐户

Here’s video demonstrating how a default phone call account recovery process works:

下面的视频演示了一个默认的手机通话账户恢复过程的工作原理:

Timeline of Email Disclosure

邮件泄露时间表

Submitted: April 25, 2021
Triaged: April 27,2021
Fixed:
April 27,2021

提交: 2021年4月25日分诊: 2021年4月27日修复: 2021年4月27日

Timeline of Account Takeover

接管帐户时间表

Submitted: April 29, 2021
Triaged : April 30, 2021 at 3:32 PM
Fixed: April 30, 2021 at 3:49 PM

提交: 2021年4月29日分流: 2021年4月30日下午3:32固定: 2021年4月30日下午3:49

It took me more time to verify the fix then FB took to release the fix, lol🤣

我花了更多的时间来验证修复然后 FB 采取释放修复,哈哈

After thorough investigation, Facebook found no evidence of abuse and the issue was finally closed in September 2.

经过彻底的调查,Facebook 没有发现虐待的证据,这个问题最终在9月2日结束。