OneFlow源码解析:Eager模式下Tensor的存储管理

dcde8982a7d8db1204f28e2f26bc8cbb.jpeg

作者|郑建华

不同Tensor类型的存储管理方式

Lazy Tensor 的存储是由 Runtime 和 Actor 等对象管理的。静态图完成编译后,需要多少个对象、多少存储空间都是确定的,Runtime 等在初始化时会分配存储,在退出时回收资源。

Eager 模式下,Global Tensor 可以视为对 Local Tensor 的分布式封装,EagerGlobalTensorImpl 在本地的数据是一个

EagerLocalTensorImpl 对象。可以通过考察 EagerLocalTensorImpl 来理解 eager 模式下 tensor 的存储管理。

参考的示例代码如下:

 
import numpy as npimport oneflow as flowa = np.random.randn(1, 4)flow.tensor(a, device=flow.device("cpu"), dtype=flow.float)

Tensor 存储相关类的关系

EagerLocalTensorImpl 的存储相关的类关系如下。

后续会顺着示例代码的执行过程,看看图中的对象都是在何时、如何构造的,存储被谁持有、如何分配并释放。

15c2bd31384ec829680f6bcaa6efe0f2.png

3 

通过虚拟机指令为 Tensor 分配存储

tensor 的构造函数通过 Python C API 注册为 PyTensorObject_init,由 functional::_legacy_tensor_ctor 

根据签名进行转发。

示例代码对应的是 TensorWithDataFunctor

,调用 MakeLocalTensorFromData 构造 tensor,在这个函数中通过调用 functional::Empty以及 EmptyFunctor分配存储。在 EmptyFunctor 中把相关属性都存到 attrs,然后调用 OpInterpUtil::Dispatch在 vm 指令的执行准备过程中分配存储。

EmptyFunctor 返回的 tensor 是一个只有存储空间、不含数据的对象。数据拷贝在后面由 CopyLocalTensorFromUntypedArray

完成。

3.1 存储相关对象的构造

因为是 eager 模式下的 local tensor,OpInterpUtil::Dispatch 会被转发到 NaiveInterpret执行。对于示例代码,这个函数的输入参数如下:

  • inputs 是一个空数组

  • outputs 只有一个元素、且是空指针

因为 outputs 中的 tensor 指针都是空的,所以需要创建一个 EagerLocalTensorImpl 对象,其 one::TensorStorage 成员变量是空指针。

因为 output_eager_blob_objects 中的元素尚未初始化,会调用 tensor_impl->InitEagerBlobObject 

进行初始化。因为 tensor_storage_ 还是空的,这个过程会执行如下操作:

  • 创建 vm::TensorStorage 对象

  • 创建 EagerBlobObject 对象

  • set_eager_blob_object

    • UpdateTensorStorage

      • 创建 one::TensorStorage 对象

      • 设置 tensor 存储释放的回调函数

上述对象的创建,都只是记录相关信息,还不涉及 tensor 的存储分配。

需要注意的是,注册到 one::TensorStorage 的回调函数被赋值给了成员变量 releaser_hook_,这个函数会通过虚拟机指令释放 tensor。

3.2 在指令执行过程中分配 tensor 存储

分配 tensor 存储的过程如下:

  • vm::Instruction::Compute

  • vm::InstructionPolicy::ComputeIf

  • vm::OpCallInstructionPolicy::Compute

  • OpCallInstructionUtil::Compute

  • 获取内存分配器

  • OpCallInstructionUtil::AllocateOutputBlobsMemory

  • blob_object->TryAllocateBlobBodyMemory

  • allocator->Allocate

在 EagerBlobObject::TryAllocateBlobBodyMemory 中,allocator 分配的存储地址会赋值给 dptr,存储地址 dptr 和 Free 函数一起构造一个智能指针,并赋值给 vm::TensorStorage 的 blob_dptr_ 变量。

通过虚拟机指令释放 Tensor 存储

在前面的 3.1 节提到,EagerLocalTensorImpl 在初始化 EagerBlobObject、创建 one::TensorStorage 的同时,会设置一个释放 tensor 的回调函数,回调函数保存在变量 releaser_hook_ 中

,one::TensorStorage 析构时调用这个回调函数。把这些信息综合整理一下,one::TensorStorage 析构时会执行如下操作:

 
vm::InstructionList instruction_list;InstructionsBuilder instructions_builder(&instruction_list);// JUST(Build(&instructions_builder));if (eager_blob_object->producer_stream().has_value()) {JUST(instructions_builder->ReleaseTensor(eager_blob_object));}JUST(vm::Run(instructions_builder.mut_instruction_list()));

在 InstructionsBuilder::ReleaseTensor 中,如果有其它 stream 最近使用了 eager_blob_object,会通过 SoftSyncStreamBetween 进行同步。通过这种方式解决存储的依赖问题。

一般情况下,通过 tensor 的 producer_stream 释放存储,根据这个对象获取对应的 vm::Stream 对象,并据此构造指令 instruction(包含 eager_blob_object 和 vm_stream),示例代码对应的指令类型是 FastReleaseTensorInstructionPolicy,其 Compute 方法执行具体的存储释放逻辑,过程如下:

  • ReleaseTensorInstructionPolicy::Release()

  • eager_blob_object->DeallocateBlobDataPtr()

  • tensor_storage_->Release()

  • tensor_storage_->_Release()

  • blob_dptr_.reset()

    • 智能指针重置,调用分配存储时指定的 Free 方法

5 

reshape 等场景的存储管理

在 reshape、slice、transpose 等场景中,调用的 EagerLocalTensorImpl 构造函数的参数包括 input 的 tensor_storage,所以这个 tensor 的 tensor_storage_ 变量不是空的,在执行 InitEagerBlobObject 时,只创建 EagerBlobObject以提供 shape、stride等信息;但不会再创建 one::TensorStorage,而是复用 input 的存储。

两个 TensorStorage 类型可以合并吗?

为什么在 one::TensorStorage 析构时、由它保存的回调函数来触发释放 vm::TensorStorage 中的存储呢?

one::TensorStorage 只多了一个 releaser,这两个 Storage 类型是否可以合并呢?

在当前的设计下,这两个类型不能合并。因为 one::TensorStorage::releaser_hook_ 中持有 EagerBlobObject 的智能指针,EagerBlobObject 中也持有 vm::TensorStorage 的智能指针。如果两个 Storage 类型合并为一个,就会出现循环引用、对象无法析构而导致内存泄漏。

所以,vm::TensorStorage 只是单纯的存储,可以在多个 tensor 之间共享。EagerBlobObject 既包括存储、也包括 shape、stride、data_type 等独特的对象信息。而 one::TensorStorage 是为了避免循环引用而引入的、专门负责释放存储的角色。

7 

附录

GDB 断点示例

 
break oneflow::one::MakeLocalTensorFromDatabreak oneflow::one::NaiveInterpretbreak oneflow::vm::VirtualMachineEngine::DispatchInstructionbreak oneflow::vm::OpCallInstructionUtil::Computebreak oneflow::vm::OpCallInstructionUtil::AllocateOutputBlobsMemorybreak oneflow::vm::EagerBlobObject::TryAllocateBlobBodyMemorybreak oneflow::vm::ReleaseTensorInstructionPolicy::Releasebreak oneflow/core/eager/eager_blob_object.cpp:107

参考资料

  • OneFlow(https://github.com/Oneflow-Inc/oneflow/tree/b51cb72430619f6088e47bbb8b8226f37299573a

  • OneFlow源码解析:Tensor类型体系与Local Tensor

其他人都在看

  • “ChatGPT们”的淘金时代

  • 推演语言模型的大小与计算开销

  • 狂追ChatGPT:开源社区的“平替”热潮

  • 谷歌科学家:ChatGPT秘密武器的演进与局限

  • 比快更快,开源Stable Diffusion刷新作图速度

  • OneEmbedding:单卡训练TB级推荐模型不是梦

  • GLM训练加速:性能最高提升3倍,显存节省1/3

欢迎Star、试用OneFlow: github.com/Oneflow-Inc/oneflow/icon-default.png?t=N3I4http://github.com/Oneflow-Inc/oneflow/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/33334.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hadoop3.2.4+Hive3.1.2+sqoop1.4.7安装部署

目录 一、软件包 二、JDK部署 1.JDK解压 2.设置环境变量 3.环境验证 4.分发JDK相关文件至Node_02、Node_03 5.环境生效 三、Zookeeper部署 1.Zookeeper解压 2.Zookeeper配置 3.创建myid文件 4.设置环境变量并添加映射 5.分发ZooKeeper 相关文件至Node_02、Node_0…

JVM(运行时数据区)

内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行。JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。 1、线程私有:程序计数器、虚拟机栈、本…

手把手教你如何使用Docker

手把手教会你如何使用Docker!!! 一、Docker介绍 我们在公司开发中,会有开发环境,测试环境,上线环境, 比如我们开发人员开发好了一个项目,在开发环境中运行正常,但测试人…

在Linux系统中实现一个可加载的内核模块

Intro 坐标成都电讯大专, 某操作系统课老师在PPT上草草写下3个内核线程API后就要求编程, 感受一下: include/linux/kthread.h,你就看到了它全部的API,一共三个函数。 这里是代码声明,略 kthread_run()负责内核线程的创建, kthre…

eclipse安装MAT内存分析工具插件

(一)默认已安装eclipse IDE 打开eclipse选择如下操作: 插件地址:http://download.eclipse.org/mat/1.5/update-site/ 安装插件。 安装完成后重启即可。 (二)获取Heap Dump文件 新建一个java项目&#xff0c…

【深度学习·实践篇】CodeT5模型学习与基于CodeT5进行新的模型训练

文章目录 写在前面一. 一些名词二. 基于Codet5训练自己的模型理论步骤:1. 安装依赖2. 下载CodeT5代码库3. 准备数据集4. 修改训练脚本5. 启动训练6. 进行预测 具体实践1. 准备数据集2. 配置运行环境3. 修改脚本参数4. 为实现分布式训练,修改脚本如何实现…

虚拟机安装Ubuntu18.04

一、下载VMware VMware下载地址:https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html 安装这个太久了,可以网上搜一下安装流程不难,只有一个建议,安装路径不要有中文 可以参考下面教程&#xff0c…

智能PID软件-AVEVA Diagrams创建图纸模板【图瓦软件出品】

AVEVA Diagrams可以针对不同的项目,定义公司级和项目级的图纸模板,包括图纸图框和角图章。不仅大大节约设计人员的时间,而且能够确保成品图纸的一致性和规范性。下面我们介绍一下如何在Diagrams中定制图纸模板,初步了解一下Diagra…

5 款必备的免费在线画图工具!超级好用

大家好,我是宝哥! zen flowchart 虽然是英文,但其实也并没有多么复杂的内容,而且浏览器现在都带有页面翻译的功能,所以还是蛮方便的!初次使用需要注册,也并不难,随便自己的一个邮箱注…

最新ChatGPT开源平替模型骆马(Vicuna) 单个GPU就能跑!UC伯克利领头,130亿参数「小羊驼」权重公布

转载:单个GPU就能跑!UC伯克利领头,130亿参数「小羊驼」权重公布 【导读】刚刚,UC伯克利、CMU、斯坦福等,联手发布了最新开源模型骆马(Vicuna)的权重。 3月31日,UC伯克利联手CMU、斯…

试用国内及国外AI绘图软件后的总结

最近AI很火,所以这几天抱着试试看的角度试用了多款AI绘图软件,大概测试了市面上的3款工具吧,3款国外的,1款国内的。 因为有对比,波哥也不是专业的评测机构出身,所以这些比对无论是从角度,还是从…

这家付费图库巨头率先拥抱AI绘画,还掏钱补偿原创画师

詹士 发自 凹非寺量子位 | 公众号 QbitAI 画师与AI生成图片争议不断,有平台给出了解决方案。 而且是掏真金白银补偿创作者那种。 美东时间10月25日,付费图库Shutterstock宣布:将通过出售AI生成图片,向创作者提供补偿费&#xff0c…

OpenAI 发布GPT-4——全网抢先体验

OpenAI 发布GPT-4 最近 OpenAI 犹如开挂一般,上周才刚刚推出GPT-3.5-Turbo API,今天凌晨再次祭出GPT-4这个目前最先进的多模态预训练大模型。与上一代GPT3.5相比,GPT-4最大的飞跃是增加了识图能力,并且回答准确性也得到显著提高。…

GPT-4正式发布!如何访问 怎么免费使用GPT-4?

美国人工智能研究实验室OpenAI,周二为其爆红聊天机器人ChatGPT发布了最新GPT-4语言模型,这距离ChatGPT的上线仅仅过去了4个月时间。 和ChatGPT最初使用的GPT-3.5模型相比,GPT-4实现了几个方面的飞跃式提升:强大的识图能力&#x…

谷歌Bard最新更新:支持中文,还升级了ChatGPT都没有的识图功能

夕小瑶科技说 原创 作者 | 智商掉了一地、ZenMoore 两个月前咱们刚盘点完 Bard 的大更新,在那两周中,谷歌将全家桶和 Bard 联动不久,还推出了十大新功能,当时他们就在博客更新中提到,会在今年夏天新增对中文等另外 40…

GPT-4来炸场:10秒输出一个网站,识图知意 so easy,为何如此丝滑

比被卷更可怕的莫过于自己卷自己,这点还得是OpenAI更胜一筹。 四个月前,ChatGPT 刚刚推出,并成为历史上增长最快的消费者应用程序。在ChatGpt大杀四方时,万众瞩目的大型多模态模型GPT-4也在今天凌晨正式发布。 据OpenAI官方介绍&…

使用GPT-4生成QT代码

一、概述 最近ChatGPT火爆起来了,ChatGPT是一种基于GPT的自然语言处理模型,可以用于生成自然语言文本,例如对话、文章等。最近又发现了一个优秀且免费的代码生成工具Cursor ,Cursor集成了 GPT-4 ,可以帮助你快速编写、…

chatgpt赋能python:Python如何查看图片

Python如何查看图片 在SEO优化中,图片也是至关重要的一部分。而在Python中,我们可以使用一些代码来查看图片。下面就来介绍一下Python如何查看图片的方法。 1. 安装Python相关库 要使用Python查看图片,需要先安装一些相关的库。常用的库包…

ChatGPT之后,垂直大模型兴起

由ChatGPT掀起的这一波大模型浪潮中, 百度、阿里等大厂相继下场,王慧文、王小川、李开复等大佬也纷纷入场。年初,比尔盖茨高呼“人工智能时代已经开始”,给大模型定下了宏伟的基调。随着竞争的展开,大模型已不是“是否”问题&…

大佬下场AI2.0,我们帮“王慧文们”指条明路

划重点: 1、如果将开发大模型比做是“造房子”,那AI Infra 就是“工具箱”,而中国缺少的正是工具和原材料制造工厂。 2、根据国外市场的情况,可以将整个AI Infra大致分为数据准备、模型构建、模型产品三个层面,在这三…