1.Python语言学习(三):Tensorflow_gpu搭建及convlstm核心源码解读
2.BERT(Transformer Encoder)详解和TensorFlow实现(附源码)
3.极简入门TensorFlow C++源码
4.[推理部署]👉Mac源码编译TensorFlow C++指北
5.TensorFlow 源码大坑(2) Session
6.从源码build Tensorflow2.6.5的架构记录
Python语言学习(三):Tensorflow_gpu搭建及convlstm核心源码解读
在探索深度学习领域,使用Python语言进行编程无疑是源码源码一条高效且灵活的途径。尤其在科研工作或项目实施中,详解Python以其丰富的架构库资源和简单易用的特性,成为了许多专业人士的源码源码首选。本文旨在分享在Windows系统下使用Anaconda搭建TensorFlow_gpu环境及解读ConvLSTM核心源码的详解录屏录音+源码过程。在提供具体步骤的架构同时,也期待读者的源码源码反馈,以持续改进内容。详解
为了在Windows系统下搭建适合研究或项目的架构TensorFlow_gpu环境,首先需要确认TensorFlow_gpu版本及其对应的源码源码cuDNN和CUDA版本。访问相关网站,详解以获取适合自身硬件配置的架构版本信息。以TensorFlow_gpu2.为例,源码源码进行环境搭建。详解
在Anaconda环境下,通过命令行操作来创建并激活特定环境,如`tensorflow-gpu`环境,选择Python3.版本。接着,安装cuDNN8.1和CUDA.2。推荐使用特定命令确保安装过程顺利,亲测有效。随后,使用清华镜像源安装TensorFlow_gpu=2..0。激活虚拟环境后,使用Python环境验证安装成功,通常通过特定命令检查GPU版本是否正确。
为了在Jupyter Notebook中利用该环境,需要安装ipykernel,并将环境写入notebook的kernel中。激活虚拟环境并打开Jupyter Notebook,通过命令确保内核安装成功。
对于ConvLSTM核心源码的解读,重点在于理解模型的构建与参数设置。模型核心代码通常包括输入数据维度、模型结构、超参数配置等。以官方样例为例,构建模型时需关注样本整理、标签设置、卷积核数量等关键参数。例如,输入数据维度为(None,,,1),输出数据维度为(None,None,,,)。通过返回序列设置,可以控制模型输出的形态,是spring电影源码返回单个时间步的输出还是整个输出序列。
在模型改造中,将彩色图像预测作为目标,需要调整模型的最后层参数,如将`return_sequence`参数更改为`False`,同时将`Conv3D`层修改为`Conv2D`层以适应预测彩色图像的需求。此外,选择合适的损失函数(如MAE)、优化器(如Adam)以及设置Metrics(如MAE)以便在训练过程中监控模型性能。
通过上述步骤,不仅能够搭建出适合特定研究或项目需求的TensorFlow_gpu环境,还能够深入理解并灵活应用ConvLSTM模型。希望本文内容能够为读者提供有价值的指导,并期待在后续过程中持续改进和完善。
BERT(Transformer Encoder)详解和TensorFlow实现(附源码)
BERT,全称Bidirectional Encoder Representation from Transformers,源自Transformer的Encoder部分。其核心结构通过双向注意力机制,使得每个token能同时关注其前后文内容,形成双向上下文融合。相较于单向语言模型,BERT在复杂语言理解任务中展现出更强大的性能,如完形填空、问答系统、情感分析、目标导向搜索和辅助导航等。
BERT的训练机制包含两种创新的预训练策略:Masked Language Model(MLM)和Next Sentence Prediction(NSP)。MLM通过在句子中随机遮蔽部分词汇,促使模型基于上下文进行预测,增强词汇理解和错误纠正能力。NSP则判断两句话在语料中的连续性,强化句子级别的语言表征能力。
在BERT的架构中,每个输入token生成一个输出表示,对于任务不同,输出会用到额外的输出层进行预测。例如,对于完型填空或问答任务,使用每个token对应的输出;对于情感分类任务,则使用“[CLS]”对应的输出。
微调阶段,BERT在大量语料上训练后,可用于NLP的各个任务中。对于语义分析任务,构建模型时将BERT输出中的“[CLS]”符号输入到Dense层进行分类处理。通过加载BERT模型、预处理模型以及进行微调,最终完成任务的训练和推理。
极简入门TensorFlow C++源码
前一段时间,我专注在框架开发上,并偶尔协助业务同学优化使用TensorFlow的代码。在观看dmlc/relay、nnvm的代码时,我发现了它们的有趣之处。我也对TensorFlow的必应导航源码Graph IR、PaddlePaddle的Graph IR产生了兴趣,上周五在阅读代码时,无意间听到了一个数据竞赛群讨论框架的底层实现。几位算法大佬提到了看底层源码可能较为繁琐,因为这类代码通常相对容易理解。在与群内伙伴的交流后,我萌生了撰写一篇关于如何阅读TensorFlow或其他框架底层源码的文章。
选择合适版本的bazel,对于阅读TensorFlow源码至关重要。应使用版本为0..0的bazel来拉取TF2.0代码,因为太高的版本或太低的版本可能影响阅读体验。在安装了合适的bazel版本后,使用clion上的bazel插件进行导入,然后配置编译,导入项目,等待clion编译整个项目。完成编译后,就能愉快地阅读代码,甚至于protobuf生成的文件也能轻松跳转。
使用c++编译模型是TensorFlow的另一面。尝试使用c++编写模型代码,可以深入理解TensorFlow的底层机制。主要函数包括CreateGraphDef、ConcurrentSteps、ConcurrentSessions等。通过这些函数,可以构建计算图,定义节点、常量变量、操作符等。这为理解TensorFlow的逻辑提供了直观的视角。
深入分析代码后,可以了解到TensorFlow的GraphDef机制、Square类的实现、注册到特定op的过程、functor的使用以及最终的实现逻辑。这有助于理解TensorFlow的核心原理,并在阅读源码时进行更深入的思考。
除了阅读源码,还可以通过编写测试用例来增强理解。TensorFlow提供了丰富的测试用例,如在client_session_test.cc中运行测试程序,可以验证代码的正确性。这不仅有助于理解代码,还能提高对TensorFlow框架的掌握程度。
阅读源码只是理解TensorFlow原理的开始,深入行业论文和请教行业专家是进一步深入学习的关键。网络上关于机器学习系统的资料丰富多样,但缺少系统性的课程。希望官方能够分享更多框架的干货,并期待在学习过程中总结和分享更多资源。阅读源码虽然复杂,但其背后蕴含的原理和逻辑十分有趣。
[推理部署]👉Mac源码编译TensorFlow C++指北
在Mac环境下编译TensorFlow C++源码,考资源码需要完成以下步骤,以避免可能的编译问题,确保顺利构建。
首先,确认系统环境满足要求。需有Xcode和Command Line Tools,JDK 1.8.0版本以支持编译过程中所需的Java环境,以及Bazel工具,TensorFlow依赖此工具进行编译。特别注意Bazel版本需与TensorFlow对应,如TensorFlow 1.对应Bazel 0..1。
接下里,安装依赖,包括JDK和Bazel。JDK安装时需检查电脑中是否已安装,并确保正确安装。使用HomeBrew安装Bazel,通过命令行接受协议,并使用`--user`指令确保安装在个人目录的`bin`文件夹下,同时设置`.bazelrc`路径为`$HOME/.bazelrc`。
安装自动化工具`automake`和使用Python3.7.5在虚拟环境中构建TensorFlow C++源码。推荐使用清华镜像源加速`pip`的安装过程。通过`git clone`方式下载TensorFlow源码,确保checkout至r1.分支。调整域名映射以提升`git clone`速度。
进行编译选项配置,通常在TensorFlow文件夹内运行命令,根据提示选择默认选项。
开始编译TensorFlow,此过程可能需要较长时间,完成后,应在`bazel-bin/tensorflow`目录下找到编译好的`libtensorflow_cc.so`和`libtensorflow_framework.1.dylib`文件。
若遇到`Undefined symbols for architecture x_: “_CFRelease”`错误,这通常与创建软连接有关,无需特别处理。若需要手动安装额外依赖库,如Eigen3,可参考相关指南。
编译完成后,可对C++接口进行测试,验证编译过程的正确性。通常情况下,Mac下的TensorFlow 1. C++源码编译完成。
最后,编译TFLite,生成的动态链接库将保存在指定目录下。在`CMakelists.txt`文件中增加对应配置项,以完成TFLite的构建。
总结而言,Mac下TensorFlow 1. C++源码编译及TFLite的构建,需要遵循上述步骤,并确保环境与工具版本的兼容性,以顺利进行编译过程。Linux系统下的主力埋伏源码编译方式相似,但具体细节可能有所不同。
TensorFlow 源码大坑(2) Session
深入探讨TensorFlow源码中的Session机制,揭示其运行机制和复杂性。从Python和C++两端的Session API入手,解析其调用栈,解析内部工作流程。Python端的tf.Session().run()方法,通过初始化调用栈,实现计算图的执行。C++端的ClientSession.run()同样展示了Session运行机制,揭示了底层实现细节。对比之下,DirectSession作为Session的基类,展示了如何构建Executor并具体运行计算图,为理解TensorFlow的高效计算逻辑提供了深入视角。
深入解析Python端tf.Session().run()方法的调用栈,揭示了其如何通过初始化调用栈来执行计算图的全过程。从创建Session到调用run方法,每一次调用都紧锣密鼓地执行一系列操作,确保计算图能够正确运行,这使得理解TensorFlow的执行流程变得清晰。
同时,C++端的ClientSession.run()方法提供了另一种视角,展示了Session运行机制在底层语言中的实现。通过对比Python和C++端的实现,可以更深入地理解TensorFlow在不同环境下的兼容性和性能优化。
DirectSession作为Session的基类,展示了如何构建Executor并具体运行计算图。通过分析DirectSession的run方法和构建过程,可以理解TensorFlow在执行计算图时的灵活性和高效性,以及如何通过Executor优化计算流程。
总之,深入研究TensorFlow源码中的Session机制,不仅能够揭示其复杂性,还能为开发者提供优化计算图执行流程、提升模型训练效率的策略,是理解TensorFlow内核机制的关键。
从源码build Tensorflow2.6.5的记录
.从源码编译Tensorflow2.6.5踩坑记录,笔者经过一天的努力,失败四次后终于成功。Tensorflow2.6.5是截至.时,能够从源码编译的最新版本。
0 - 前期准备
为了对Tensorflow进行大规模修改并完成科研工作,笔者有从源码编译Tensorflow的需求。平时更常用的做法是在conda环境中pip install tensorflow,有时为了环境隔离方便打包,会用docker先套住,再上conda + pip安装。
1 - 资料汇总
教程参考:
另注:bazel的编译可以使用换源清华镜像(不是必要)。整体配置流程的根本依据还是官方的教程,但它的教程有些点和坑没有涉及到,所以多方材料了解。
2 - 整体流程
2.1 确定配置目标
官网上给到了配置目标,和对应的版本匹配关系(这张表里缺少了对numpy的版本要求)。笔者最后(在docker中)配置成功的版本为tensorflow2.6.5 numpy1..5 Python3.7. GCC7.5.0 CUDA.3 Bazel3.7.2。
2.2 开始配置
为了打包方便和编译环境隔离,在docker中进行了以下配置:
2. 安装TensorFlow pip软件包依赖项,其编译过程依赖于这些包。
3. Git Tensorflow源代码包。
4. 安装编译工具Bazel。
官网的介绍:(1)您需要安装Bazel,才能构建TensorFlow。您可以使用Bazelisk轻松安装Bazel,并且Bazelisk可以自动为TensorFlow下载合适的Bazel版本。为便于使用,请在PATH中将Bazelisk添加为bazel可执行文件。(2)如果没有Bazelisk,您可以手动安装Bazel。请务必安装受支持的Bazel版本,可以是tensorflow/configure.py中指定的介于_TF_MIN_BAZEL_VERSION和_TF_MAX_BAZEL_VERSION之间的任意版本。
但笔者尝试最快的安装方式是,到Github - bazelbuild/build/releases上下载对应的版本,然后使用sh脚本手动安装。比如依据刚才的配置目标,笔者需要的是Bazel3.7.2,所以下载的文件为bazel-3.7.2-installer-linux-x_.sh。
5. 配置编译build选项
官网介绍:通过运行TensorFlow源代码树根目录下的./configure配置系统build。此脚本会提示您指定TensorFlow依赖项的位置,并要求指定其他构建配置选项(例如,编译器标记)。
这一步就是选择y/N基本没啥问题,其他参考里都有贴实例。笔者需要GPU的支持,故在CUDA那一栏选择了y,其他部分如Rocm部分就是N(直接按enter也可以)。
6.开始编译
编译完成应输出
7.检查TF是否能用
3 - 踩坑记录
3.1 cuda.0在编译时不支持sm_
笔者最初选择的docker是cuda.0的,在bazel build --config=cuda //tensorflow/tools/pip_package:build_pip_package过程中出现了错误。所以之后选择了上面提到的cuda.3的docker。
3.2 问题2: numpy、TF、python版本匹配
在配置过程中,发现numpy、TF、python版本需要匹配,否则会出现错误。
4 - 启示
从源码编译Tensorflow2.6.5的过程,虽然经历了多次失败,但最终还是成功。这个过程也让我对Tensorflow的编译流程有了更深入的了解,同时也提醒我在后续的工作中要注意版本匹配问题。
探索TensorFlow核心组件系列之Session的运行源码分析
TensorFlow作为一个前后端分离的计算框架,旨在实现前端在任何设备、任何位置上使用API构建模型,而不受硬件资源限制。那么,TensorFlow是如何建立前后端的连接呢?在这一过程中,Session起着关键桥梁作用,它连接前后端通道,并通过session.run()触发计算,将前端的计算图转化为graphdef pb格式发送至后端。后端接收此格式,将计算图重建、剪枝、分裂,并分配到设备上,最终在多个Executor上执行计算。
Session管理着计算图、变量、队列、锁、设备和内存等多种资源,确保资源安全、高效地使用。在Session生命周期中,包含创建、运行、关闭和销毁四个阶段,确保模型运行的正确性和效率。
在Session创建时,使用BaseSession初始化,通过调用TF_NewSessionRef创建实例。此过程涉及确定图实例、判断混合精度设置以及创建Session。在分布式框架中,Python通过swig自动生成的函数符号映射关系调用C++层实现。
Session运行主要通过session.run()触发,该方法在BaseSession的run()中实现,涉及创建fetch处理器、获取最终fetches和targets,调用_do_run方法启动计算,并输出结果。在本地模式下,Session初始化会生成DirectSession对象。
综上所述,Session在TensorFlow架构中扮演着核心角色,连接前后端,管理资源,并确保模型高效、安全地运行。
TensorFlow XLA优化原理与示例
TensorFlow XLA优化原理与示例 一、XLA概述 XLA,加速线性代数,是一个专注于优化TensorFlow计算的领域特定编译器。旨在提升服务器和移动设备的性能、内存使用效率和代码移植性。初期,大部分用户可能不会立即感受到显著的优化效果,但通过尝试XLA的即时编译(JIT)或预编译(AOT)模式,探索针对新硬件加速器的XLA应用,可以显著提升性能。 二、构建XLA XLA与TensorFlow合作以实现以下目标:提高执行速度:编译子图以减少短暂操作的执行时间,消除TensorFlow运行时的开销,融合流水线操作以减少内存开销,针对已知张量形状优化,允许更积极的恒定传播。
改善内存使用:分析和规划内存使用情况,理论上消除许多中间存储缓冲区。
减少自定义操作依赖:通过改进自动融合低级操作的性能,减少对大量自定义操作的需求,匹配手工融合操作的性能。
移动足迹减少:通过提前编译子图,生成可以直接链接到另一个应用程序的对象/头文件,从而消除TensorFlow运行时的占用空间,结果可以大幅减少移动推断的占用空间。
提高可移植性:为新硬件编写新的后端程序相对容易,大多数TensorFlow程序将在该硬件上无修改地运行,与针对新硬件的个体单片操作方法形成对比,后者需要重写TensorFlow程序以利用这些操作。
三、XLA如何工作? 输入语言为“HLO IR”(高级优化程序),XLA将HLO中的图形(计算)编译成各种体系结构的机器指令。XLA模块化设计,易于插入替代后端以定位新颖硬件架构。支持x和ARM CPU后端,以及NVIDIA GPU后端。 编译过程包含多个与目标无关的优化和分析,如循环节省、独立于目标的操作融合,以及为计算分配运行时,内存的缓冲区分析。在独立于目标的步骤后,XLA将HLO计算发送到后端。后端执行进一步的HLO级别分析和优化,针对具体目标信息和需求。例如,XLA GPU后端可以执行专用于GPU编程模型的算子融合,并确定如何将计算划分为流。此时,后端也可以模式匹配某些操作或其组合来优化库调用。下一步是目标特定的代码生成,XLA附带的CPU和GPU后端使用 LLVM进行低级IR优化和代码生成。 四、XLA开发后端 XLA提供了一个抽象接口,新体系结构或加速器可以实现创建后端,运行TensorFlow图形。重新定位XLA通常比实现每个现有TensorFlow Op针对新硬件更简单和可扩展。实现可分为以下几种情况:现有CPU架构,尚未正式由XLA支持。通过使用LLVM,XLA可以轻松将TensorFlow重定向到不同的CPU,因为主要区别在于LLVM生成的代码。
具有现有LLVM后端的非CPU类硬件。可以基于现有CPU或GPU实现创建新的实现,共享大量代码。
没有现有LLVM后端的非CPU类硬件。需要实施StreamExecutor、xla::Compiler、xla::Executable和xla::TransferManager等关键类。
五、使用JIT编译 TensorFlow必须从源代码编译为包含XLA。使用即时(JIT)编译可以将多个算子(内核融合),融合到少量的编译内核中,减少内存带宽要求并提高性能。通过XLA运行TensorFlow图表有多种方法,包括通过JIT编译算子放置在CPU或GPU设备上,或通过将算子在XLA_CPU或XLA_GPU设备上运行。 六、打开JIT编译 可以在会话级别或手动打开JIT编译。手动方法涉及标记算子以使用属性进行编译完成。在会话级别打开JIT编译,会导致所有可能的算子贪婪地编译成XLA计算。受限于一些限制,如果图中有两个相邻的算子都具有XLA实现,编译为单个XLA计算。 七、使用示例 以MNIST softmax为例,在开启JIT的情况下进行训练。当前仅支持在GPU上进行。 确保LD_LIBRARY环境变量或ldconfig包含$CUDA_ROOT/extras/CUPTI/lib,其中包含CUDA分析工具界面(CUPTI)的库。TensorFlow使用CUPTI从GPU中提取跟踪信息。 八、代码流程 实现流程包括图优化Pass(MarkForCompilation)、EncapsulateSubgraphs和BuildXlaOps,将子图转化成XLA HLO Computation、XLA Function子图、Xla节点和最终的GPU可执行代码或PTX。 九、总结 通过使用XLA,TensorFlow的性能、内存使用效率和代码移植性得到了显著提升。实现XLA后端相对简单,支持从现有CPU架构到非CPU类硬件的各种优化,同时提供JIT编译和手动控制的灵活性。通过实例和代码示例,可以深入理解XLA在TensorFlow中的应用和优化策略。Tensorflow 编译加速器 XLA 源码深入解读
XLA是Tensorflow内置的编译器,用于加速计算过程。然而,不熟悉其工作机制的开发者在实践中可能无法获得预期的加速效果,甚至有时会导致性能下降。本文旨在通过深入解读XLA的源码,帮助读者理解其内部机制,以便更好地利用XLA的性能优化功能。
XLA的源码主要分布在github.com/tensorflow/tensorflow的多个目录下,对应不同的模块。使用XLA时,可以采用JIT(Just-In-Time)或AOT( Ahead-Of-Time)两种编译方式。JIT方式更为普遍,对用户负担较小,只需开启一个开关即可享受到加速效果。本文将专注于JIT的实现与理解。
JIT通过在Tensorflow运行时,从Graph中选择特定子图进行XLA编译与运行,实现了对计算图的加速。Tensorflow提供了一种名为JIT的使用方式,它通过向Tensorflow注册多个优化PASS来实现这一功能。这些优化PASS的执行顺序决定了加速效果。
核心的优化PASS包括但不限于EncapsulateXlaComputationsPass、MarkForCompilationPass、EncapsulateSubgraphsPass、BuildXlaOpsPass等。EncapsulateXlaComputationsPass负责将具有相同_xla_compile_id属性的算子融合为一个XlaLaunch,而XlaLaunch在运行时将子图编译并执行。
AutoClustering则自动寻找适合编译的子图,将其作为Cluster进行优化。XlaCompileOp承载了Cluster的所有输入和子图信息,在运行时通过编译得到XlaExecutableClosure,最终由XlaRunOp执行。
在JIT部分,关键在于理解和实现XlaCompilationCache::CompileStrict中的编译逻辑。此过程包括两步,最终结果封装在XlaCompilationResult和LocalExecutable中,供后续使用。
tf2xla模块负责将Tensorflow Graph转化为XlaCompilationResult(HloModuleProto),实现从Tensorflow到XLA的转换。在tf2xla中定义的XlaOpKernel用于封装计算过程,并在GraphCompiler::Compile中实现每个Kernel的计算,即执行每个XlaOpKernel的Compile。
xla/client模块提供了核心接口,用于构建计算图并将其转换为HloModuleProto。XlaBuilder构建计算图的结构,而XlaOpKernel通过使用这些基本原语描述计算过程,最终通过xla_builder的Build方法生成HloComputationProto。
xla/service模块负责将HloModuleProto编译为可执行的Executable。该过程涉及多个步骤,包括LLVMCompiler的编译和优化,最终生成适合特定目标架构的可执行代码。此模块通过一系列的优化pass,如RunHloPasses和RunBackend,对HloModule进行优化和转换,最终编译为目标代码。
本文旨在提供XLA源码的深度解读,帮助开发者理解其工作机制和实现细节。如有问题或疑问,欢迎指正与交流,共同探讨和学习。期待与您在下一篇文章中再次相遇。