深入浅出 tvm – (2) 搭建开发环境

本文面向 tvm 开发者,粗略介绍一下 tvm 的安装过程

1. 开发环境

系统:ubuntu 20.04,由于中文生态兼容的比较好,比如输入法,有道云笔记,所以这个系统本身也是我的主力开发系统
tvm 版本:v0.10.0,如果你的不是这个版本,记得 checkout 一下,否则下面的依赖可能不全,对于学习 tvm 来说,v0.10.0 版本其实够了

2. 依赖安装

以我的 dockerfile 为例,可以参考
另外,大家也可以跳过这一步,直接用我弄好的镜像:docker pull pipul/tvm_ci_cpu
FROM ubuntu:20.04

ENV TZ=Europe/Kiev
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY ./apt /etc/apt
COPY ./etc/sudoers.d/90-nopasswd-sudo /etc/sudoers.d/90-nopasswd-sudo
COPY ./.bashrc /etc/bashrc

RUN apt-get update
RUN apt-get install -y vim sudo git g++ pip llvm
RUN apt-get install -y python3 python3-dev python3-setuptools gcc libtinfo-dev zlib1g-dev build-essential cmake libedit-dev libxml2-dev
RUN pip install onnx numpy attrs decorator Pillow psutil scipy relpath typing-extensions tornado 'xgboost>=1.1.0' cloudpickle
有几个不是必须的:
  1. COPY ./apt 主要是替换了163的源,不然软件安装太慢
  2. /etc/sudoers.d/90-nopasswd-sudo 是 tvm 编译的时候必须依赖的,但是 docker 镜像 ubuntu:20.04 是默认没有的,所以需要搞下
  3. COPY ./.bashrc 可以忽略
假设构建好的镜像为:${tvm-docker-image}
一旦镜像构建好了之后,后续编译和开发 tvm,都在镜像内完成


深入浅出 tvm – (1) 简介

深度学习分为2个过程:
  1. 训练:从数据得到模型
  2. 推理:从模型得到答案
为解决训练而设计的系统叫训练框架:比如 paddlepaddle,tensorflow,pytorch
为解决推理而设计的系统叫推理引擎:比如 paddle inference,tensorflow,pytorch-trt 等等
训练得到的模型,其实就是一个计算图,这个计算图接收输入,通过一系列的运算,得到一个结果,后面这个过程就叫推理

1. 编译器在什么位置?

如果只从系统的输入和输出看的话:编译器 ≈ 推理引擎
因为现在几乎所有的AI编译器,它的输入都是模型(计算图)+数据,输出就是一个推理结果,这个和推理引擎所干的事情几乎一模一样
以 tvm 为例,如下:
0
其中 nnvm + graph optimizations + tvm + tvm primitives 就是 TVM 干的事情
tvm 的输入就是 CoreML 或者 ONNX 模型(一种计算图的格式)


Efficient Memory Disaggregation with Infiniswap

1. 概要

infiniswap 可以实现把一个机器的内存 swap 到另外多个机器上(1对多)
和其他实现相比,infiniswap 可以把开销做到很小,并且故障容错能力更强
  1. A transparent remote paging model for virtual machines @2008
  2. Swapping to remote memory over Infiniband: An approach using a high performance network block device @2005
  3. 还有一堆20+年前的论文(参考意义不大)

2. 架构设计

infiniswap 的组件其实就2个,非常简单:
  1. infiniswap-bd:一个虚拟的 swap 设备,其后端是远程内存
  2. infiniswap-daemon:管理本机对外提供的 remote memory(包括内存到虚拟地址的映射,等等)
这2个组件每个机器都会部署,类似于 daemonset
而且有个比较有意思的地方是,infiniswap 是去中心化的,它并没有一个中心式的管理组件(你看zombieland,中心式的管控组件就挺多的)
如下:
0


Carbink – Fault-Tolerant Far Memory

论文:https://www.usenix.org/system/files/osdi22-zhou-yang.pdf

ppt:https://www.usenix.org/sites/default/files/conference/protected-files/osdi22_slides_zhou_yang.pdf

Hydra 论文:https://arxiv.org/pdf/1910.09727.pdf

远内存系统允许应用程序透明地访问本地内存以及属于远程机器的内存。容错是任何针对远端内存的实用方法的关键属性,因为机器故障(计划故障和计划外故障)是数据中心特有的。然而,设计一个对计算和存储都有效的容错方案是困难的。在本文中,我们介绍了Carbink,一个远内存系统,它使用纠删码、远程内存压缩、单边RMA和可卸载的奇偶校验计算来实现快速、存储高效的容错。与最先进的远内存容错系统Hydra相比,Carbink的尾部延迟降低了29%,应用性能提高了48%,内存使用最多提高了35%。


Zombieland: Practical and Energy-efficientmemory disaggregation in a datacenter

Zombieland: Practical and Energy-efficientmemory disaggregation in a datacenter

1. 概要

zombieland 从硬件视角,实现了CPU&内存的池化
和传统的专门做内存池化的系统不太一样,zombieland 做到了把cpu和内存彻底的分离,甚至连供电都是分开的,它可以做到把cpu的电源关掉的情况下仍然可以让内存提供远程访问服务
(有点牛逼,这不得把主板设计都改了?)
通过这个设计,zombieland 实现了 86% 的能效提升

2. 设计实现

zombieland 的思路是实现服务器的 ”半关机“,增加了一个新的 ACPI 状态,叫 Sz,处于这种状态的服务器叫 zombie
这种 Sz 服务器,它的内存是可以被远程访问的,但是功耗只比 S3 状态增加了 15%,而且这种设计对硬件的改动很小
然后 zombieland 给 hypervisor 实现了2种远程内存扩展:RAM ext 和 Explicit swap device,允许 hypervisor 把虚机的冷内存卸载到远程内存上,或者用户可以显式的把内存swap到远端

2.1. 理论收益

和其他方案对比:
1)Server-centric architecture
0
能效:Total Energy Consumed = 2.1 × Emax.


AIFM – High-Performance, Application-Integrated Far Memory

AIFM 提出一种在用户态完成 swap 的方案,相比传统的内核态(虚拟内存)的方案,实现了:
  1. 更低的延迟:相比 fastswap,有6倍吞吐的提升
  2. 更高的灵活性:用户可以显式指定一块内存是local还是far(指向 remote memory)
0

1. 一些背景

1) OS swapping and far memory
之前对 swap 以及 far memory 相关的研究,大多都是在内核态的,由于内核态的 swap 都是 4k 粒度的,对于一些随机大量的小object场景,会带来很多性能问题
另一方面,如果你要依赖一些应用的信息(比如访存的行为、访存策略、内存热点)去做性能优化,这也是做不到的(madvise有一些近似的功能,但是不够)
为此,AIFM 提出了一种object级别的,可以访问远端内存的,类似于c++弱指针的一种新型指针
2)Disaggregated and distributed shared memory
当前大多数 Disaggregated memory 相关的实现,都要求数据中心具备高速互联的能力(但是现在很多数据中心其实还不具备这个能力),AFIM 提供了一种软件级的解决方案
另外一个问题是,传统的 far memory 系统里面,一份数据需要被多个 host 共享,这就要解决很复杂的数据一致性问题(同时带来了很大的性能开销)
AIFM 简化了这个问题, far memory 中的数据只属于一个 host


Distributed Shared Persistent Memory

NVM:Next-generation non-volatile memories,一种非易失性,按字节寻址,低延迟(接近DRAM的读写性能),新型设备
Hotpot 应该是第一个支持 PM 的 DSM 系统,传统的 DSM 都没有为 PM 做过真正意义上的支持。17年的Octopus也算是一个支持 PM 的 DSM 系统,但是它只有文件系统接口
Octopus: an RDMA-enabled DistributedPersistent Memory File System
因此,作者实现了一个支持 PM 的(所以叫DSPM区别于传统的DSM),内核态的DSM 系统,然后把一个 NoSQL 数据库部署到了 Hotpot 上,性能提升了3倍

1. 场景

作者发现 Tensorflow 和 PowerGraph 这类应用程序,在多个线程之间有大量的共享数据。
但是这个地方我没太理解,DSM 系统对同机多线程之间的数据共享是没有价值的,因为多线程本来就共享一个地址空间,数据只有一份
唯一的解析可能是,dsm 可以让这类系统,实现跨node级别的线性扩展

2. DSPM 的挑战

First)应该提供什么样的接口来同时支持直接内存访问,以及数据持久化?同时如果支持直接内存访问,会带来一个新的问题,怎么保证“指针”在不同机器上的一致性?
Second) 如何有效地组织DSPM中的数据以提供良好的应用程序性能?
Finally) 分布式缓存的数据一致性和可靠性怎么解决?


Mix Precision Training 混合精度训练

这是一篇百度和 nvidia 合作的论文
实际上在 MPT 之前,已经有一些论文在做减少精度训练相关的工作了,比如:
  1. Binaryconnect: Training deep neural networks withbinary weights during propagations @2015
  2. Binarized neural networks. InAdvances in Neural Information Processing Systems @2016

1. 背景

随着现在深度神经网络模型越来越大,万亿参数,百万亿参数,深度学习训练所需要的GPU内存越来越多,内存优化迫在眉睫
Year
Name
Param
From
2018
110M
OpenAI
2018
349M
Google
2020
175B
OpenAI
2022
540B
Google
传统的神经网络训练里面,都是用FP32来保存权重、梯度等数据。但是FP32在大模型场景下(万亿参数)内存开销太大了
为了解决这个问题,MPT 论文提出了一种使用 FP16 精度来训练神经网络,同时基本不影响训练效果的方法

2. 实现

使用FP16会有很多好处:
  1. 大幅减少内存消耗:50%?
  2. 运算加速,FP16肯定要比FP32要快
但是随之带来的问题是:精度损失
IEEE标准中的FP16格式如下:
0
取值范围是5.96× 10−8 ~ 65504,而FP32则是1.4×10-45 ~ 3.4×1038
精度损失在神经网络训练里面可是比较致命的,可能会训练出截然相反的结果
为了解决这个问题,论文提出了3种方法


Singularity:Planet-Scale, Preemptive and Elastic Scheduling of AI Workloads

摘要

原文:https://arxiv.org/pdf/2202.07848.pdf

Singularity,微软的全局分布式调度服务,用于高效可靠地执行深度学习训练和推理工作负载。Singularity 的核心是一种新颖的、负载感知的调度器,它可以透明地抢占深度学习工作负载以及进行弹性伸缩,在不影响AI加速器(如 GPU、FPGA)的正确性和性能的前提下,提高利用率。

Singularity中的所有作业默认都是可抢占、可迁移、可动态调整(弹性)大小的:一个运行的作业可以动态透明地:

(a) 被抢占并迁移到不同的节点、集群、数据中心或区域,并从执行被抢占的位置恢复;

(b) 在给定类型的不同加速器上弹性伸缩resize;

我们的机制是透明的,因为它们不需要用户对代码做任何更改,也不需要使用任何可能限制灵活性的自定义库。此外,我们的方法显著提高了深度学习工作负载的可靠性。

结果表明,Singularity 提高了系统的效率和可靠性,对稳态性能的影响可以忽略不计。而且,Singularity 的设计与 DNN 架构无关,可以处理各种并行策略(例如,数据/管道/模型并行)。

 

1. 简介

Singularity 核心实现了 AI 任务的可抢占、可迁移、可动态调整,并且该实现与模型架构无关、与模型训练的并行策略无关,可以认为做到了用户无感

1.1. 设计目标

Singularity 为了最大化整个集群的吞吐量,采用以下设计原则:

  1. 不闲置资源:Singularity 将整个加速器集群视为单个逻辑共享集群,并避免任何资源碎片化或静态容量预留。Singularity 适时调度使用全球范围内的任何空闲资源,跨集群、AZ和工作负载边界(训练与推理)。
  2. 提供作业级别的 SLA:在适时使用空闲容量的同时,Singularity 通过遵守作业级别的 SLA 来提供隔离。例如,当推理作业的负载增加时,Singularity 通过弹性缩小或抢占训练作业来释放容量。
  3. 故障弹性恢复:DNN 训练作业运行时间长达数小时、数天甚至数周,因此从头开始成本损失巨大。在 Singularity 中,作业从它们被抢占的地方恢复,从而将故障重启成本最小化。

1.2. 关健机制

为实现上面的目标,整个 Singularity 系统的底层由两大重要的机制来支撑。它们分别是:

1) 抢占和迁移机制:Singularity 可以透明地设置检查点、抢占和迁移节点间甚至跨集群和区域的所有 DNN 作业。检查点是通过高效的的同步屏障 (synchronization barrier) 来实现分布式作业的所有参与者之间分布式状态的 一致性切分 (consistent cut)。

2) 伸缩和弹性机制:Singularity 使所有工作能够使用可变数量的 AI 加速器,以透明的方式 动态地、弹性地 伸缩资源。

Singularity 系统架构

  1. 这里涵盖了所有的 AI 算力,包括 GPU、FPGA、CPU、ASIC 等不同的硬件形态。
  2. 所有的算力资源都被容器化了
  3. 硬件抽象层(HAL)竟然 在一层基础软件之上,这层基础软件包括 NVML、NCCL、CUDA,也就是设备管理、设备通信、设备计算这三类功能。
  4. 硬件抽象层这里的 CUDA 指的是 CUDA Driver API f. 核心调度原语。高层原语包括:Failover、Suspend、Resume、Migrate、Scale Up/Down ,底层原语包括:Checkpoint、Restore、Distributed Barrier 。


vm template 原理浅析

vm template 是一种加速虚机创建、节省vm内存的技术。

1. 背景

我们之所以说虚机是强隔离的,主要是因为虚机有独立的内核。不同vm之间的进程是完全运行在自己的内核空间里面的,相互不可见
引起虚机的启动,需要引导一个完整的内核,以及完整的os
这在传统的虚机场景下,问题不大,一个物理机上启动的vm数量可能就十几个
但是容器场景下,kata-containers,容器粒度要远小于虚机,一个物理机可能启动上百个kata容器,每个kata容器都有自己独立的内核,这样算来,开销就不小了
由于每个kata容器的内核,操作系统镜像,都是相同的。如果虚机之间的内核、操作系统镜像所占用的内存能够共享,这样就能省掉不少内存。
于是,vm template 技术出现了

2. vm template 原理

主要是利用了linux内核fork系统的cow原理(copy on write)
cow:fork一个新的进程,会把原进程的内存空间全部copy一份,但这个copy只是一个引用。只有新进程在写这块内存区域的时候,才会发生真正的copy操作
所以 vm template 的核心思路是:通过一个事先创建好的最小 factory-vm,包含公共的内核、操作系统镜像、以及kata-agent。创建kata容器的时候,从factory-vm fork一个vm出来,然后再通过热插拔的方式,调整vm的规格以符合kata容器的要求
但是这里有一个问题是,template vm 的规格是固定的,但是 Pod 的规格不是固定的,所以必须通过 Pod vm 的热插拔 & resize 能力来实现 vm 规格的调整