范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

对比PyTorchTensorFlowJAXTheano,我发现都在关注两大问题

  作者 王益
  OneFlow社区编译
  翻译 杨婷
  最近,我在处理 PyTorch 分布式和 TorchRec 相关的工作,为此,我开始学习 PyTorch 2.0。在业余时间,我也在跟着Alpa作者学习JAX和XLA。如今回顾这些技术,我发现它们的关注点似乎都是如下两个问题:
  包含自动求导和并行在内的函数转换,例如 vmap, pmap 和 pjit 等; 异构计算,CPU 负责控制流,GPU/TPU 负责张量计算和集合通信。
  本文档中的所有例子都支持在 Colab 中运行:
  1函数转换
  "函数转换"意为将一个程序转变成另一个程序,最常见的例子是自动求导(autograd)。自动求导采用用户编写的前向过程并创建后向过程,对于用户来说,编写自动求导通常都太过复杂。函数转换的主要难点在于:在编写函数转换算法时以何种方式表示输入和输出过程。
  Theano:显式地构建 IR
  Theano是最早的深度学习工具之一,也就是如今为人们所熟知的Aesara项目。Theano有一个允许用户在内存中将IR构建为数据结构的API,因此Theano可实现自动求导,并将结果输出为 Python 函数。
  import aesara from aesara import tensor as at  a = at.dscalar("a") # Define placeholders, which have no values. b = at.dscalar("b")  c = a * b              # c now contains the IR of an expression.TT dc = aesara.grad(c, a) # Convert the IR in c into another one, dc  f_dc = aesara.function([a, b], dc) # Convert the IR into a Python function, assert f_dc(1.5, 2.5) == 2.5       # so we can call it.
  TensorFlow 1.x:用于运行 IR 的虚拟机
  TensorFlow 1.x明确保留了构建IR的想法。若在TensorFlow中运行上述示例,结果不会有什么差别;但倘若在TensorFlow 1.x中来运行,最大的差别在于:我们不会将后向 IR 转换为 Python 函数,并使用 Python 解释器来运行。相反,我们会在TensorFlow runtime中来运行。
  import tensorflow.compat.v1 as tf # TensorFlow 1.x API import numpy as np tf.disable_eager_execution()  a = tf.placeholder(tf.float32, shape=()) b = tf.placeholder(tf.float32, shape=())  c = a * b dc = tf.gradients(c, [a], stop_gradients=[a, b])  with tf.compat.v1.Session() as sess:  # TensorFlow has a runtime to execute the IR,    x = np.single(2)                    # so, no converting it into Python code.    y = np.single(3)        print(sess.run(dc, feed_dict={a:x, b:y}))
  PyTorch 1.x:没有前向IR
  PyTorch不会像Theano或TensorFlow那样将前向传播转换为IR。反之,PyTorch 使用 Python 解释器来运行前向传播。这样做的弊端在于会在运行期间生成表示后向传播的 IR,我们称之为Eager模式(动态图模式)。
  import torch  a = torch.tensor(1.0, requires_grad=True) # These are not placeholders, but values. b = torch.tensor(2.0)  c = a * b    # Evaluates c and derives the IR of the backward in c.grad_fn_. c.backward() # Executes c.grad_fn_. print(c.grad)
  TensorFlow 2.x: 梯度带
  TensorFlow 2.x增加了一个像PyTorch API的Eager模式API。此 API 追踪前向传播如何运行名为梯度带(GradientTape)的 IR 。TensorFlow 2.x可以从这个跟踪中找出后向传播。
  import tensorflow as tf  a = tf.Variable(1.0) # Like PyTorch, these are values, not placehodlers.  b = tf.Variable(2.0)  with tf.GradientTape() as tape:   c = a * b dcda = tape.gradient(c, a) print(dcda)
  JAX
  JAX 不会向用户公开诸如梯度带等方面的低级别细节。简单说来,JAX的思维方式为:将输入和输出都用Python函数来表示。
  import jax   a = 2.0 b = 3.0 jax.grad(jax.lax.mul)(a, b)  # Compute c = a * b w.r.t. a.  The result is b=3.   jax.jit(jax.grad(jax.lax.mul))(a,b)  jax.experimental.pjit(jax.grad(jax.lax.mul),                        device_mesh(ntpus))(a,b)
  对于想要自己编写的函数转换的高级用户,他们可以调用make_jaxpr 等低级 API 来访问 IR,称为 JAXPR。
  jax.make_jaxpr(jax.lax.mul)(2.0, 3.0)  # Returns the IR representing jax.lax.mul(2,3) jax.make_jaxpr(jax.grad(jax.lax.mul))(2.0, 3.0)  # Returns the IR of grad(mul)(2,3)
  FuncTorch
  FuncTorch和JAX类似,都是基于PyTorch的函数转换。
  import torch, functorch  a = torch.tensor([2.0]) b = torch.tensor([3.0]) functorch.grad(torch.dot)(a, b)
  JAX的make_jaxpr 类似于functorch的make_fx 。
  def f(a, b):   return torch.dot(a, b) # Have to wrap the builtin function dot into f. # 必须将内置函数dot转换成f.    print(functorch.make_fx(f)(a, b).code) print(functorch.make_fx(functorch.grad(f))(a, b).code)
  TensorFlow 2.x、JAX 和 functorch 都为前向传递构建了一个 IR,但 PyTorch Eager模式没有。IR 不仅可用于自动求导,还可用于其他类型的函数转换。在下列例子中,functorch.compile.aot_function 调用了回调函数print_compile_fn 两次,分别用于前向和后向传播。
  from functorch.compile import aot_function import torch.fx as fx  def print_compile_fn(fx_module, args):     print(fx_module)     return fx_module aot_fn = aot_function(torch.dot, print_compile_fn) aot_fn(a, b)
  2高阶导数
  PyTorch
  import torch from torch import autograd  x = torch.tensor(1., requires_grad = True) y = 2*x**3 + 8  first_derivative = autograd.grad(y, x, create_graph=True) print(first_derivative)  second_derivative = autograd.grad(first_derivative, x) print(second_derivative)
  TensorFlow 2.x
  import tensorflow as tf  x = tf.Variable(1.0)  with tf.GradientTape() as outer_tape:     with tf.GradientTape() as tape:         y = 2*x**3 + 8         dy_dx = tape.gradient(y, x)         print(dy_dx)     d2y_dx2 = outer_tape.gradient(dy_dx, x)     print(d2y_dx2)
  JAX
  def f(a):   return 2*a**3 + 8  print(jax.grad(f)(1.0)) print(jax.grad(jax.grad(f))(1.0))
  3动态控制流
  动态控制流(dynamic control flows)有两个层级:在 CPU 上运行的粗粒度级别和在 GPU /TPU 上运行的细粒度级别。本部分主要介绍在 CPU 上运行的粗粒度级别的动态控制流。下面我们将用(if/else)条件语句作为例子检验深度学习工具。
  TensorFlow 1.x
  在 TensorFlow 1.x 中,我们需要将条件语句显式构建到 IR 中。此时条件语句是一个特殊的运算符 tf.cond 。
  def f1(): return tf.multiply(a, 17) def f2(): return tf.add(b, 23) r = tf.cond(tf.less(a, b), f1, f2)  with tf.compat.v1.Session() as sess:  # TensorFlow has a runtime to execute the IR,   print(sess.run(r, feed_dict={a:x, b:y}))
  TensorFlow 2.x
  TensorFlow 2.x 支持使用 tf.cond  和 tf.while_loop  显式构建控制流。此外,实验项目google/tangent中有AutoGraph功能,它可以将Python控制流转换为tf.cond 或tf.while_loop 。此功能利用了 Python 解释器支持的函数和函数源代码。例如下面的g函数调用了 Python 的标准库将源代码解析为 AST,然后调用 SSA 表单来理解控制流。
  def g(x, y):     if tf.reduce_any(x < y):         return tf.multiply(x, 17)     return tf.add(y, 23)      converted_g = tf.autograph.to_graph(g)  import inspect print(inspect.getsource(converted_g))
  JAX
  由于部分Python语法很复杂,所以通过解析源代码来理解控制流就显得很困难,这就导致AutoGraph经常出错。但如果这种方法很简单,那么Python开发者社区也不会在构建Python编译器时失败这么多次了。正是由于有这种挑战的存在,必须要明确地将控制流构建到 IR 中。为此,JAX 提供了 jax.lax.cond  和 jax.lax.for_loop 函数。
  jax.lax.cond(a < b, lambda : a*17, lambda: b+23)
  考虑到这一点,你可能会觉得我们可以使用递归算法。但是下面用于计算阶乘的递归无法用JAX跟踪。
  def factorial(r, x):   return jax.lax.cond(x <= 1.0, lambda: r, lambda: factorial(r*x, x-1)) factorial(1.0, 3.0)
  可能你还想调用factorial 来计算 3!=6 。但这会让递归深度超过最大值,因为递归不仅依赖于条件,还依赖于函数定义和调用。
  PyTorch
  PyTorch最初是Python-native。正如前文所说,由于多功能调度机制,grad  和 vamp 的函数转换都是即时的。值得注意的是:
  相比Theano 和 TensorFlow构建IR后的函数转换,即时函数转换效率更高。  在进行 grad  和 vmap   时,JAX也是即时函数转换。然而像 pamp  和 pjit  等更复杂的函数转换需要对整个计算过程进行概述,在这个过程中IR是必不可少的。
  由于IR在pmap  和 pjit 中的必要性,PyTorch社区最近添加了torch.cond pytorch/pytorch#83154
  4分布式计算
  根据执行代码或 IR 的不同方式,在使用 Python 解释器或runtime时,有两种分布式计算方法。
  Python-Native
  Theano和PyTorch采用了Python-native分布式计算方式。这种分布式训练工作包含多个Python解释器进程。这导致出现了以下结果。
  打包和运行(Pack and run)。由于这些 Python 进程在不同的host上运行,因此我们需要打包用户程序和依赖项,并将它们发送到这些host上去运行。一直以来TorchX负责了这个打包过程。它支持例如Docker和torch.package等各种打包格式,并且可以与各种集群管理器配合使用,如Kubernetes和SLURM。  单程序多数据(SPMD)。由于将用户程序发送到各种host上要依赖于打包,与其他权重较轻的方式(如通过 RPC 发送代码)相比,这种方式不太灵活,因此,我们通常只发送一个程序。当所有这些进程运行同一程序时,这个作业就变成了单程序多数据(SPMD)作业。
  Python-native SPMD
  下面是一个简单的SPMD PyTorch程序,我们可以在相同或不同的host上使用进程运行这个程序。在这个过程中,我们只需要调用all_gather 。真正的分布式训练程序会调用更高级别的API,例如torch.nn.parallel.DistributedDataParallel  和 torchrec.DistributedModelParallel , 然后再调用低级 API,例如 all_gather  和 all_reduce 。
  import os import torch from torch import distributed as dist  def main():     use_gpu = torch.cuda.is_available()     local_rank = int(os.environ.get("LOCAL_RANK", "0"))     local_world_size = int(os.environ.get("LOCAL_WORLD_SIZE", "0"))     device = torch.device(f"cuda:{local_rank}" if use_gpu else "cpu")     dist.init_distributed(backend="nccl")      lst = torch.tensor([local_rank + 100]).to(device)      # placeholder      rlt_lst = [torch.zeros_like(lst) for _ in range(local_world_size)]     dist.all_gather(rlt_lst, lst, async_op=False)     print("After broadcasting:", rlt_lst)
  Python-native Non-SPMD
  PyTorch 不仅限于 SPMD 式的分布式训练。它还通过torch.distributed.pipeline.sync.Pipe 和PiPPy project提供流水并行,其中流水并行的各个阶段在不同的设备上运行不同的程序。这些阶段常通过 torch.rpc  包来沟通。
  分布式运行时机制
  分布式 TensorFlow 作业由运行 TensorFlow runtime 程序的进程组成,而不是由 Python 解释器组成。此分布式运行时作业执行 TensorFlow graph (IR),它是由执行用户程序的 Python 解释器生成。
  用户程序可以使用低级API(如 tf.device )去指定作业要运行什么操作、在哪台设备和主机上运行等等。因为API有runtime,所以可以做到这一点。
  with tf.device("/job:bar/task:0/device:gpu:2"):     # ops created here have the fully specified device above
  与PyTorch一样,TensorFlow也为分布式训练提供了高级API tf.distributed.strategy ,Keras和DTensor。
  strategy = tf.distribute.MirroredStrategy()             if tf.config.list_physical_devices("GPU")             else tf.distribute.get_strategy()  with strategy.scope():   model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])  model.compile(loss="mse", optimizer="sgd")
  分布式运行时极大地方便了训练服务的维护,因为我们不再将用户程序打包到集群上运行。相反,我们打包运行时程序,因为相比用户程序,运行时程序更加统一。
  混合理念
  JAX 支持 Python-native 和分布式运行时。
  JAX 提供例如vmap 、pmap  和 pjit 的函数转换,这可以将 Python 函数转换为分布式程序。
  (本文经授权后由OneFlow社区编译,译文转载请联系获得授权。原文:https://quip.com/Y8qtAyV4EXRg)
  欢迎 Star、试用 OneFlow 最新版本: https://github.com/Oneflow-Inc/oneflow/

张伦硕因钟丽缇一句话在直播中发飙,他被骂了6年冤不冤?内娱的尽头是直播带货。之前,张恒(老还珠的塞娅公主)在某音上发了条怀旧动态,cos了一回当年的塞娅公主。本以为可以收割一波还珠回忆杀,结果网友愣是看出了端倪这是要带货了吧??然后就港娱四大天王,终究成为了一场历史在文字中证道。唐泪四大天王可谓传奇。这趟从1992年绵延至今的旅程,可谓腥风血雨。明枪暗箭,癫狂怨气,不一而足。甚至四人之中,拥趸争首踩尾之举,也可书写一部极厚的恩怨史书。原因很简这部恋爱综,捕捉到了人性的亲密与疏离这两年恋爱综艺又卷土重来,特别是网飞打造的韩国真人恋爱综艺单身即地狱,五对高颜值又高学历,青春靓丽的年轻男女被安排在豪华又与世隔绝的度假岛屿上,肉体的互相吸引荷尔蒙的作用,精神与外歌手演唱会混时长,观众大呼太坑人!北京日报客户端记者韩轩兴冲冲去看演唱会,买了价格不菲的票,到场却发现歌手本人只唱了几首歌,生气不生气?近日,周杰伦曾轶可线下演唱会接连被网友吐槽,说好的个人演唱会,要么不是歌手个人等来了,国片这波回春复苏,是新年的主题。所有事情都需要复苏,电影也不例外。国产电影尤其需要回暖。有多久,我们没在影院看到一部令人心潮澎湃的国产新片?影院等着复苏的契机,影迷也等着被真正有吸引力的好片带剧版悬崖演员阵容不输悬崖之上,陈道明和孙红雷倾情出演如果将电影改拍成电视剧,这个挑战性绝对不小,除去观众熟悉的剧情之外,演员塑造的人物形象,已经在观众心中固化,因此很少有这样的尝试,但是对于电影悬崖之上而言,这是个例外,网传它将被拍歌手杨坤华语歌坛至少倒退十年,23年跨年演唱会说明了一切歌手杨坤华语歌坛至少倒退十年,23年跨年演唱会证实了答案对此,网友们表示网友1现在的年轻歌手女生邓紫棋张靓颖这俩的唱功还不错,男的年轻歌手唱的都是阴阳怪气的,都不怎么样。网友2千里国内三地已监测到XBB毒株,症状有什么不同?会二次感染吗?解读来了美东时间2022年12月30日美国疾控中心公布数据显示估计当周美国有40。5新冠病毒感染病例是高传染性的奥密克戎亚型毒株XBB。1。5毒株引起的XBB免疫逃逸能力有所增强已登陆我国中国联通的云时代范本从基础联接到万物智联作者丨斗斗编辑丨裴一多出品丨数字化报日新月异的技术创新,为电信运营商带来了持续不断的行业变革。短短几年光景,随着移动互联网的迅速发展,电信行业的边界彻底模糊化,竞争的主体更加多元和阿里都没能拯救苏宁,何况王兴的美团?企业家创建伟大公司,要有大志向大情怀大操守大智慧!创建伟大公司,需要卓越的领导人,但不要苛责于个人。一个人的能力再强,在时代潮流面前,也总是显得那么渺小!就拿张近东创立的苏宁公司来京东方引领柔性OLED质量升级爱集微点评京东方的柔性OLED专利,通过保护层对面板结构的侧面周边进行保护,使得撕除承载膜的步骤不会对面板结构的边框位置产生影响,面板结构上相应的阴极区域等不会产生剥落的情况,以确
一个男人有多爱你,性最清楚生活很现实,感情更现实。为什么隔着屏幕的爱恋,哪怕再美好,也不会有好的结果。不过就是因为,情书情话再美好,但真实生活并不会陪你演戏。隔着一段距离的时候,你觉得自己可能接受对方的一切我好想你的深夜emo文案1。失望吗?示爱的越界者。Disappointed?Atransgressorofaffection。2。送我一支玫瑰吧,在谎言的映衬下。Sendmearose,againstal温柔的野兽头条创作挑战赛(一)勇敢的童年他们说,童年是一段妙不可言的七彩时光。然,于我而言,童年却是摆设在我人生中的一座假山,徒有山的名号,却带着僵死般的灰黑。1991年10月初六凌晨12点14年前的语文课上,90分钟我写出了这篇几乎满分的作文绿水青山烟雨绿林赋序属深秋,吾与好友会于绿林之下,景色旖旎,水声汩汨,涓涓流淌,日光融融,映日荷花,红叶接天,清风徐来,杨柳摇曳,水波荡漾,涟漪阵阵,惊走鱼虾,浮动水面鸟声悦耳,其以欢喜之心慢度日常我永远爱傍晚轻抚着的微风和落日黄昏日落尤其温柔,人间皆是浪漫爱世间温暖万物,沿途为晚霞停留!晒出我拍到的日落朝朝暮暮烟火气,杯盏温柔漫人间炊烟里品人生,美食中再相逢如果快乐有开关,别让生命之花轻易凋零你有好好注重过自己的身体吗?我相信很多人和我一样也没有做到好好维护自身身体健康,身体上的小毛病我们也不曾关注过。我们总是在想,我们还年轻穿少一些没有事儿的,我们还年轻吃少一些没事儿如果有一天你变得非常有钱,你最想做的是什么,要实现童年的梦如果有一天你变得非常有钱,你最想做什么很多人在年轻的时候,觉得自己没有什么特别的意义。有的人觉得活着没意思!然而一旦有一天你变得非常有钱,你会想做什么呢?是成为一个有钱人,还是像以爱在深秋秋日生活打卡季文王民官从落叶知秋,到枫红菊黄,绿瘦蟹肥,不知不觉中,秋竟也就在这么快地过去了。秋是美丽的,那一树的果实代表聚,那飞舞的落叶表示散。聚时轰轰烈烈,春华秋实。散时飘飘洒封城记五从秋天到冬天我一直不怎么喜欢秋天。在我看来,虽然很多时候秋意味着收获,意味着成熟,秋的多姿多彩五色斑斓确也令人向往,但是,我对秋的感觉好像总是停留在秋的荒疏萧瑟秋的衰败冷落上,黯然似乎是我对秋贵州这个地方,层林尽染枫叶红,释放万种枫情又是一年赏秋景的最美季节,枫叶火红,犹如被天空染红的晚霞一般,美不胜收,这样的美景让人无比愉悦和浪漫。在贵州,要赏阅这样层林尽染枫叶红,一定要去这个地方,释放万种枫情。阳光明媚,秋中国拥有秋天最长的城市,多达80天,夏天还是爽爽的20多度Hello,大家好,这里是xiang浩看世界。秋季,是处在热与凉交替的季节,也是诸多小伙伴最为热爱的季节对于它,古人们先后用绝妙佳句记录当年景色,有金井梧桐秋叶黄珠帘不卷夜来霜,也