1.tf.embedding_lookup(sparse)详解
2.从源码build Tensorflow2.6.5的源码记录
3.探索TensorFlow核心组件系列之Session的运行源码分析
4.TF-TRT使用环境搭建
5.TFlite 源码分析(一) 转换与量化
6.ROS 源码学习 ---TF
tf.embedding_lookup(sparse)详解
嵌入查找是一种从矩阵中根据ID索引对应值的方法,适用于处理离散特征。编译
假设embw1为一个行5列的源码矩阵,即表示一个拥有个类别的编译单值离散特征(例如商品ID)的初始化权重嵌入矩阵,嵌入大小为5。源码如果feature1是编译linux音频源码一个序列多值稀疏特征,批量大小为4,源码序列特征长度为3,编译经过嵌入查找后,源码转换为(4,编译3,5)的张量。这种方法在DIN源码中有所应用。源码
如果feature2是编译单值稀疏特征,批量大小为4,源码经过嵌入查找后,编译转换为(4,源码5)的张量。这表示是从emb_w1的特定行进行行索引。
第二部分,嵌入查找稀疏主要参考博客,引入了从CSV文件中读取和解析数据的操作。需要注意在CSV解析时,确保每一行前有固定的索引值,否则可能会报错。假设CSV解析的index是固定的使用方法,若采用逐行解析的reader形式,则index是自带的。目前尚未实现使用reader形式解析的博客链接。
总体而言,嵌入查找和嵌入查找稀疏在处理稀疏数据时,paes算法源码提供了高效的方法来转换和处理特征,为模型训练提供了有力的支持。
从源码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。android tools 源码您可以使用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、delphi日历源码TF、python版本匹配
在配置过程中,发现numpy、TF、python版本需要匹配,否则会出现错误。
4 - 启示
从源码编译Tensorflow2.6.5的过程,虽然经历了多次失败,但最终还是成功。这个过程也让我对Tensorflow的编译流程有了更深入的了解,同时也提醒我在后续的工作中要注意版本匹配问题。
探索TensorFlow核心组件系列之Session的运行源码分析
TensorFlow作为一个前后端分离的计算框架,旨在实现前端在任何设备、任何位置上使用API构建模型,而不受硬件资源限制。那么,TensorFlow是如何建立前后端的连接呢?在这一过程中,Session起着关键桥梁作用,它连接前后端通道,并通过session.run()触发计算,将前端的计算图转化为graphdef pb格式发送至后端。后端接收此格式,将计算图重建、剪枝、分裂,并分配到设备上,最终在多个Executor上执行计算。xgboost源码安装
Session管理着计算图、变量、队列、锁、设备和内存等多种资源,确保资源安全、高效地使用。在Session生命周期中,包含创建、运行、关闭和销毁四个阶段,确保模型运行的正确性和效率。
在Session创建时,使用BaseSession初始化,通过调用TF_NewSessionRef创建实例。此过程涉及确定图实例、判断混合精度设置以及创建Session。在分布式框架中,Python通过swig自动生成的函数符号映射关系调用C++层实现。
Session运行主要通过session.run()触发,该方法在BaseSession的run()中实现,涉及创建fetch处理器、获取最终fetches和targets,调用_do_run方法启动计算,并输出结果。在本地模式下,Session初始化会生成DirectSession对象。
综上所述,Session在TensorFlow架构中扮演着核心角色,连接前后端,管理资源,并确保模型高效、安全地运行。
TF-TRT使用环境搭建
TF-TRT,即TensorFlow与TensorRT的集成,是NVIDIA为加速深度学习推理应用而设计的工具。它简化了TensorFlow用户在GPU上利用TensorRT进行模型推理的流程。本文主要介绍如何在服务器上搭建TF-TRT的使用环境和编写相关代码。
首先,NVIDIA推荐的TF-TRT环境配置基于TensorRT 5.0RC,需要确保NVIDIA驱动程序版本.0以上,CUDA .0以及TensorRT。安装过程建议在Anaconda的虚拟环境中进行,从Tensorflow GitHub上下载1.版本源码,并通过bazel build工具生成pip安装包。在编译时,由于GCC 5.0可能与新版本兼容性问题,需添加特定编译选项。
对于服务器上直接安装,你需按照官方教程安装CUDA、CUDNN、NVIDIA Driver和TensorRT。在Tensorflow的configure文件中,根据你的硬件配置进行相应的调整。然后,通过pip安装生成的.whl文件,安装时需要注意选择nvcc编译器,cudnn 7.3以上版本,以及兼容性的GCC编译选项。
另一种方式是利用Docker容器,Tensorflow .容器需要nvidia driver +版本,并需要获取Nvidia GPU cloud的API密钥。安装完成后,你可以通过Docker拉取tensorflow:.-py3镜像,验证TensorRT与Tensorflow的集成是否成功。
无论是直接安装还是容器化,都需注意选择合适的驱动和软件版本,以确保TF-TRT的稳定运行。安装过程中,还可以根据实际需求在container中安装其他软件,以满足个性化需求。
TFlite 源码分析(一) 转换与量化
TensorFlow Lite 是 Google 推出的用于设备端推断的开源深度学习框架,其主要目的是将 TensorFlow 模型部署到手机、嵌入式设备或物联网设备上。它由两部分构成:模型转换工具和模型推理引擎。
TFLite 的核心组成部分是转换(Converter)和解析(interpreter)。转换主要负责将模型转换成 TFLite 模型,并完成优化和量化的过程。解析则专注于高效执行推理,在端侧设备上进行计算。
转换部分,主要功能是通过 TFLiteConverter 接口实现。转换过程涉及确定输入数据类型,如是否为 float、int8 或 uint8。优化和转换过程主要通过 Toco 完成,包括导入模型、模型优化、转换以及输出模型。
在导入模型时,`ImportTensorFlowGraphDef` 函数负责确定输入输出节点,并检查所有算子是否支持,同时内联图的节点进行转换。量化过程则涉及计算网络中单层计算的量化公式,通常针对 UINT8(范围为 0-)或 INT8(范围为 -~)。量化功能主要通过 `CheckIsReadyForQuantization`、`Quantize` 等函数实现,确保输入输出节点的最大最小值存在。
输出模型时,根据指定的输出格式(如 TensorFlow 或 TFLite)进行。TFLite 输出主要分为数据保存和创建 TFLite 模型文件两部分。
量化过程分为选择量化参数和计算量化参数两部分。选择量化参数包括为输入和权重选择合适的量化参数,这些参数在 `MakeInitialDequantizeOperator` 中计算。计算参数则使用 `ChooseQuantizationParamsForArrayAndQuantizedDataType` 函数,该函数基于模板类模板实现。
TFLite 支持的量化操作包括 Post-training quantization 方法,实现相关功能的代码位于 `tools\optimize\quantize_model.cc`。
ROS 源码学习 ---TF
TF作为ROS的核心库之一,其主要功能是维护和传播所有frame之间的变换关系。它通过两个核心函数来实现:broadcast用于发布坐标变换,listener则负责监听并构建坐标变换树,便于用户调用。
初次接触时,我曾质疑为何每个节点都需要独立的listener来维护自己的tf树,是否可以共享全局变换信息以节省资源。在研究amcl包的源码时,我发现了TF的奇特用法,使用了tf2以及额外的tf_static主题,这让我深感困惑。
为了解开这些疑问,我深入阅读了TF的源码和ROS官方的TF2 Wiki。了解到TF2被设计用来替换TF,其中引入了/tf_static来存储静态变换,以及Action Based Query,允许通过action进行查询,避免了多个listener的资源消耗。
在ROS源码中,关键的包如geometry和geometry2提供了核心数据结构,如TransformStorage和TimeCache,它们负责存储和管理变换。BufferCore是整个架构的核心,它处理了tf数据的维护和查找,包括对/tf和/tf_static的订阅与处理。
在Transformer类和TransformListener中,我们看到buffer的使用,它结合了listener的功能,并提供底层的buffer访问。这种设计使得amcl包中的listener可以暴露更底层的功能,如将数据直接注入到listener中。
TF2的改进包括了更高效的存储和查询机制,以及/tf_static提供的静态变换服务。静态变换只保存最新的一个变换,且使用latched topics确保消息不会丢失,从而提供了“总是能查到变换”的特性。
Action Based Query的引入,如buffer_server提供的action服务,使得分布式查询变得更为灵活,支持超时查找,展示了TF2在查询效率上的提升。
总结来说,TF库的设计既体现了ROS框架的简洁,也展示了TF2带来的改进。虽然TF2在某些方面有所优化,但当前TF的实用性仍然很强,没有强制性地替换。通过理解TF的核心数据结构和框架,我们可以更好地利用这个工具。