利用 TensorFlow Profiler:在 AMD GPU 上优化 TensorFlow 模型

TensorFlow Profiler in practice: Optimizing TensorFlow models on AMD GPUs — ROCm Blogs

简介

TensorFlow Profiler 是一组旨在衡量 TensorFlow 模型执行期间资源利用率和性能的工具。它提供了关于模型如何与硬件资源交互的深入见解,包括执行时间和内存使用情况。TensorFlow Profiler 有助于定位性能瓶颈,使我们能够微调模型的执行,以提高效率并加快结果,这在需要接近实时预测的场景中尤为重要。

机器学习算法,特别是深度神经网络,具有很高的计算需求。评估机器学习应用程序的性能,以确保执行的是经过最优化的模型版本,这一点至关重要。这篇博客演示了如何在 AMD 硬件上使用 TensorFlow Profiler 工具,通过训练自编码器模型、收集设备跟踪数据、并根据分析结果修改自编码器的结构来优化模型性能。有关 TensorFlow Profiler 的更多信息,请参见 使用 Profiler 优化 TensorFlow。

在 GitHub 文件夹 中可以找到与本篇博客相关的资源。

前提条件

以下是跟随本博客所需的要求和说明:

操作系统和硬件

以下描述了支持的操作系统和硬件环境,推荐用于运行本博客文章中的示例。

  • AMD 加速器或 GPU:请参阅 ROCm 文档中有关支持的操作系统和硬件的列表,网址为 系统要求(Linux)。

  • ROCm 6.0: 请参阅 ROCm 安装说明。

  • Docker: 使用 适用于 Ubuntu 的 Docker 引擎。

  • TensorFlow 和 TensorBoard:使用官方的 ROCm Docker 镜像 rocm/tensorflow:rocm6.0-tf2.12-runtime,支持 TensorFlow 2.12。

运行此博客

使用 Docker 是搭建所需环境的最简单和最可靠的方法。

  • 确保已安装 Docker。如果没有,请参阅 安装说明。

  • 确保在主机上已安装 amdgpu-dkms(随 ROCm 一起提供),以便从 Docker 内部访问 GPU。有关详细信息,请参阅 ROCm Docker 说明。

  • 克隆库,并进入博客目录:

    git clone https://github.com/ROCm/rocm-blogs.git
    cd rocm-blogs/blogs/software-tools-optimization/tf_profiler
    
  • 构建并启动容器。有关构建过程的详细信息,请参阅 dockerfile。这将启动一个 Jupyter Lab 服务器。

    cd docker
    docker compose build
    docker compose up
    
  • 在浏览器中导航到 http://localhost:8888/lab/tree/src/tf_profiler_ae_example.ipynb 并打开 tf_profiler_ae_example.ipynb 笔记本。

现在,请使用 Jupyter 笔记本来跟随此博客进行学习。

使用 TensorFlow Profiler 记录分析数据

在接下来的部分中,我们将设计并训练一个在 MNIST 数据集上的简单自编码器模型,同时使用 TensorFlow Profiler 收集分析数据。通过在 TensorBoard 中分析这些分析数据,我们将识别性能瓶颈,并做出明智的决策,以优化模型在 AMD 加速器上的性能。

设计一个简单的自动编码器

自动编码器是一种用于无监督学习的神经网络,旨在学习输入数据的高效表示。自动编码器通常用于降维或特征学习等任务。它们包括两个主要部分:*编码器*,将输入压缩为潜在空间表示;*解码器*,从潜在表示中重构输入数据。目标是最小化原始输入与其重建之间的差异,从而使模型能够在没有监督的情况下学习数据的显着特征。

我们将使用 MNIST 数据集来训练这个自动编码器。`MNIST` 数据集是一个大量的手写数字数据集,常用于训练各种图像处理系统。`MNIST` 是 tensorflow_datasets 模块的一部分,并随 TensorFlow 一起安装。对于自动编码器,其目标是让它学习 MNIST 数据集中手写数字的紧凑表示。

为了展示 TensorFlow Profiler 的优势,让我们设计如下的自动编码器神经网络:

首先导入以下模块:

import os
import tensorflow as tf
import tensorflow_datasets as tfds
from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D
from tensorflow.keras.models import Model
from tensorflow.keras.callbacks import TensorBoardfrom datetime import datetime

接下来,加载数据集并进行预处理操作:将每个图像规范化到 [0,1] 范围。

# 加载数据集def preprocess_image(features):image = tf.cast(features['image'], tf.float32) / 255.0image = tf.image.resize(image, [28,28])image = tf.expand_dims(image[:, :, 0], -1)return image, image # Returns input and output the same for the autoencoder# 创建 mnist 训练和测试拆分
ds_train = tfds.load('mnist', split='train', as_supervised=False)
ds_train = ds_train.map(preprocess_image, num_parallel_calls = tf.data.AUTOTUNE).batch(64)ds_test = tfds.load('mnist', split='test', as_supervised=False)
ds_test = ds_test.map(preprocess_image, num_parallel_calls = tf.data.AUTOTUNE).batch(64)

让我们定义以下自动编码器架构:

# 定义架构
input_img = Input(shape = (28,28,1))# 编码器部分
x = Conv2D(512,(3,3), activation = 'relu', padding = 'same')(input_img)
x = MaxPooling2D((2,2), padding = 'same')(x)
x = Conv2D(128, (3,3), activation = 'relu', padding = 'same')(x)
encoded = MaxPooling2D((2,2), padding='same')(x)# 解码器部分
x = Conv2D(128,(3,3), activation = 'relu', padding = 'same')(encoded)
x = UpSampling2D((2,2))(x)
x = Conv2D(512,(3,3), activation = 'relu', padding = 'same')(x)
x = UpSampling2D((2,2))(x)
decoded = Conv2D(1,(3,3), activation='sigmoid', padding='same')(x)autoencoder = Model(input_img, decoded)

最后,设置 profiling 回调函数以在模型训练时收集 profiling 数据。

# 定义优化器和损失函数
autoencoder.compile(optimizer = 'adam', loss = 'binary_crossentropy')# 设置 profiling。将 profiling 日志存储在相应的文件夹中
tensorboard_callback = TensorBoard(log_dir = './logs/' + datetime.now().strftime("%Y%m%d-%H%M%S"),histogram_freq=1, profile_batch='500,520')# 训练模型10轮
autoencoder.fit(ds_train,epochs = 10,validation_data = ds_test,callbacks = [tensorboard_callback], # callback needed for use of tensorboard tools)# 复制文件 "events.out.tfevents.1583461681.localhost.profile-empty" 到每个记录的日志中以显示数据
source_path = "./events.out.tfevents.1583461681.localhost.profile-empty"
destination_path = log_dir
shutil.copy(source_path, destination_path)

注意:
在上面的代码中,shutil.copy被用来将文件 events.out.tfevents.1583461681.localhost.profile-empty 复制到对应训练运行的 logs 文件夹中。这是 TensorBoard 的一个限制;它需要手动放置此文件才能正确显示 profiling 数据,并使 PROFILE 菜单可用。

为了探索 TensorFlow Profiler 的使用和功能,我们特意将自动编码器的训练限制为 10 轮。让我们运行以下代码来可视化自动编码器的输出。

# 显示图像import matplotlib.pyplot as plt
import numpy as np
import tensorflow_datasets as tfds# 提取一个测试图像
for test_images, _ in ds_test.take(30): # get image with index 30test_image = test_images[0:1]reconstructed_image = autoencoder.predict(test_image)# 绘制原始图像
fig, axes = plt.subplots(1,2)
axes[0].imshow(test_image[0,:,:,0], cmap='gray')
axes[0].set_title('Original Image')
axes[0].axis('off')# 绘制重建图像
axes[1].imshow(reconstructed_image[0,:,:,0], cmap='gray')
axes[1].set_title('Reconstructed Image')
axes[1].axis('off')plt.show()

我们可以比较自动编码器的输入(原始图像)和它的输出(重建图像):

Figure1

探索使用 TensorBoard 的 TensorFlow Profiler 数据

我们将使用 TensorBoard 来探索收集到的性能分析数据。TensorBoard 是一个用于机器学习实验的可视化工具。它可以帮助可视化训练指标和模型权重,使我们可以更深入地了解模型的训练过程。

TensorBoard 的一个有用特性是 TensorBoard 回调 API。这个功能可以集成到模型的训练循环中,自动记录诸如训练和验证指标之类的数据。TensorBoard 包括一个 Profile 选项,可以用于分析 TensorFlow 操作的时间和内存性能。这对于识别训练或推理过程中的瓶颈情况非常有用。启用性能分析设置 profile_batch 在 TensorBoard 回调中。

在我们的案例中,我们创建了一个 TensorBoard 回调实例 (tensorboard_callback = TensorBoard()) 并配置了以下参数:

  • log_dir: 对应于日志数据存储的位置。在这种情况下,文件夹还附加了当前时间戳: './logs/' + datetime.now().strftime("%Y%m%d-%H%M%S")

  • histogram_freq: 对应于记录日志的频率(以周期数表示)。值 histogram_freq=1 表示每个周期都记录数据。

  • profile_batch: 配置需要分析的批次。在这种情况下,我们定义`profile_batch='500,520'`。这将在批次 500 到批次 520 内分析操作。由于我们使用的批次大小为 64(`batch(64)`),并且训练集的大小为 60,000,
    我们有 60000 / 64 = 938 批次,因此 profile_batch='500,520' 的范围在我们可分析的批次范围内。

让我们通过在 TensorBoard 上可视化分析结果来探索我们的 profiler 结果。

首先加载 Jupyter notebook 上的 TensorBoard 扩展:

%load_ext tensorboard

接下来,在 notebook 内启动 TensorBoard(可能需要几秒钟才能显示出来):

%tensorboard --logdir='./logs' --bind_all --port 6006

显示如下屏幕:

Figure2

要可视化分析数据,请转到`PROFILE` 标签。在这里,我们会看到以下选项:

  • 当前的 Run,对应选中的日志文件夹。

  • Tools 部分,选择 overview_page

  • Hosts 列表,显示当前执行 TensorFlow 代码时的 CPU 或主机。

Figure3

性能摘要包含若干性能指标。它还显示了一个 Step-time 图表,其中 x 轴对应于之前选择的批次(`profile_batch='500,520'`)。另外,TensorFlow Profiler 给了我们一些可以为更好性能实施的潜在建议。

TensorBoard 提供了几种工具来更好地理解我们的 TensorFlow 代码的执行。让我们专注于在同一次训练运行中收集的跟踪数据。在 Tools 菜单下选择 trace_viewer

Figure4

trace_viewer 选项允许我们观察每批次(`profile_batch='500,520'`)收集的跟踪数据。在跟踪视图内,x 轴表示时间,y 轴列出在可用设备上收集的每个跟踪。使用 A D W 和 S 键分别向左移动,向右移动,放大和缩小。

我们还可以查看任何 TensorFlow 操作的运行时间并可视化其跟踪。让我们重点关注批次 500。就我们的情况,我们观察到 GPU:1 上的 Conv2D 操作的持续时间约为 475,680 纳秒(ns)。根据这张图表,这个操作消耗了大部分处理时间。我们还可以观察其他 GPU 操作的运行时间以及在 CPU 上记录的跟踪。

Figure5

比较不同 Profiler 运行的数据

到目前为止,我们已经展示了如何在 TensorFlow 中分析和可视化自动编码器实现的跟踪数据。我们还展示了 TensorFlow Profiler 如何创建训练过程中计算操作的性能摘要,甚至为我们提供潜在的改进性能的建议。让我们看看在按照 TensorFlow Profiler 提供的建议对代码进行一些更改后,性能摘要如何变化。

首先,通过左侧的 Tools 菜单探索 op_profile 选项。这次我们观察到 Conv2DBackpropFilter 和 Conv2D 在训练阶段占用了大部分处理时间。如果我们考虑在 Conv2D 操作中减少滤波器的数量来减少计算时间,同时在自动编码器的输出(重构)的质量之间进行权衡会怎么样呢?

Figure6

让我们在对应的部分修改编码器和解码器中的滤波器数量如下:

# Encoder
x = Conv2D(16,(3,3), activation = 'relu', padding = 'same')(input_img)
x = MaxPooling2D((2,2), padding = 'same')(x)
x = Conv2D(8, (3,3), activation = 'relu', padding = 'same')(x)

同样地,对于解码器:

# Decoder
x = Conv2D(8,(3,3), activation = 'relu', padding = 'same')(encoded)
x = UpSampling2D((2,2))(x)
x = Conv2D(16,(3,3), activation = 'relu', padding = 'same')(x)

我们已经将编码器中的滤波器数量从原来的 512 修改为 16 ,并且在相应的 Conv2D 卷积层中从 128 修改为 8 。由于解码器的架构与编码器的架构是镜像对称的,因此在解码器部分也做了相应的修改。让我们比较输入、我们之前的自动编码器的输出和新更新后的自动编码器的输出:

Figure7

在未优化和优化的重构中,我们没有看到两个自动编码器的重构之间有很大的视觉差异。

检查此更新运行记录的 TensorFlow Profiler 数据。

Figure8

让我们也检查一下 Conv2D 计算中所占用的时间百分比。

Figure9

太好了!Profiler 工具帮助我们识别了模型中的潜在瓶颈,源于 Conv2D 操作。如果我们考虑在输出质量有所损失与减少计算时间之间进行一些权衡,我们可以在训练流程中实现更好的性能。

总结

TensorFlow Profiler 是一个优化深度神经网络计算的关键工具。它提供了详细的洞察力以优化 TensorFlow 模型,特别是展示了利用 AMD GPU 功能的显著优势。此设置确保了更快的机器学习计算,使得 AMD GPU 成为高级 TensorFlow 应用程序的绝佳选择。

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

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

相关文章

游戏引擎学习第15天

视频参考:https://www.bilibili.com/video/BV1mbUBY7E24 关于游戏中文件输入输出(IO)操作的讨论。主要分为两类: 只读资产的加载 这部分主要涉及游戏中用于展示和运行的只读资源,例如音乐、音效、美术资源(如 3D 模型和…

(二)Ubuntu22.04+Stable-Diffusion-webui AI绘画 中英双语插件安装

一、说明 看情况添加 二、双语安装 双语插件 https://github.com/journey-ad/sd-webui-bilingual-localization 中文语言包 https://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN 先装中文语言包 错误:AssertionError: extension access disable…

UE5 DownloadImage加载jpg失败的解决方法

DownloadImage加载jpg失败的解决方法 现象解决方案具体方法 现象 用UE自带的 DownloadImage 无法下载成功,从 failure 引脚出来。 接入一个由监控器自动保存起的图像,有些可以正常加载成功,有些无法加载成功。 经调查问题出现在,…

Elasticsearch 中的热点以及如何使用 AutoOps 解决它们

作者:来自 Elastic Sachin Frayne 探索 Elasticsearch 中的热点以及如何使用 AutoOps 解决它。 Elasticsearch 集群中出现热点的方式有很多种。有些我们可以控制,比如吵闹的邻居,有些我们控制得较差,比如 Elasticsearch 中的分片分…

Statsmodels之OLS回归

目录 Statsmodels基本介绍OLS 回归实战实战1:实战2: Statsmodels基本介绍 Statsmodels 是 Python 中一个强大的统计分析包,包含了回归分析、时间序列分析、假设检验等等的功能。Statsmodels 在计量的简便性上是远远不及 Stata 等软件的&…

【接口封装】—— 1、加载样式表

函数定义 static void loadStyleSheet(QWidget* widget, const QString &fileName,const QString& otherStyleQString());&#xff08;头文件&#xff09;&#xff1a; #include <qfile.h> #include <QWidget> 源文件: void CommonUtils::loadStyleSheet(…

AI、VR与空间计算:教育和文旅领域的数字转型力量

在这个数字技术高速发展的时代&#xff0c;AI、VR技术及大空间计算技术&#xff0c;已成为推动多个行业革新的强劲动力。近日&#xff0c;世优科技推出了最新研发的VR大空间产品《山海经》&#xff0c;这一全新的沉浸式体验项目不仅重新定义了观展方式&#xff0c;还为文化旅游…

AWTK 最新动态:支持鸿蒙系统(HarmonyOS Next)

HarmonyOS是全球第三大移动操作系统&#xff0c;有巨大的市场潜力&#xff0c;在国产替代的背景下&#xff0c;机会多多&#xff0c;AWTK支持HarmonyOS&#xff0c;让AWTK开发者也能享受HarmonyOS生态的红利。 AWTK全称为Toolkit AnyWhere&#xff0c;是ZLG倾心打造的一套基于C…

数据库、数据仓库、数据湖、数据中台、湖仓一体的概念和区别

数据库、数据仓库、数据湖、数据中台和湖仓一体是数据管理和分析领域的不同概念&#xff0c;各自有不同的特点和应用场景。以下是它们的主要区别&#xff1a; 1. 数据库&#xff08;Database&#xff09; 定义&#xff1a;结构化的数据存储系统&#xff0c;用于高效地存储、检…

Linux运维篇-iscsi存储搭建

目录 概念实验介绍环境准备存储端软件安装使用targetcli来管理iSCSI共享存储 客户端软件安装连接存储 概念 iSCSI是一种在Internet协议上&#xff0c;特别是以太网上进行数据块传输的标准&#xff0c;它是一种基于IP Storage理论的存储技术&#xff0c;该技术是将存储行业广泛…

Django一分钟:django中收集关联对象关联数据的方法

场景&#xff1a;我有一个模型&#xff0c;被其它多个模型关联&#xff0c;我配置了CASCADE级联删除&#xff0c;我想要告知用户删除该实例之后&#xff0c;哪些关联数据将会被一同删除。 假设我们当前有这样一组模型&#xff1a; class Warehouse(models.Model):""…

iPhone 17 Air看点汇总:薄至6mm 刷新苹果轻薄纪录

我们姑且将这款iPhone 17序列的超薄SKU称为“iPhone 17 Air”&#xff0c;Jeff Pu在报告中提到&#xff0c;我同意最近关于 iPhone 17超薄机型采用6 毫米厚度超薄设计的传言。 如果这一测量结果被证明是准确的&#xff0c;那么将有几个值得注意的方面。 首先&#xff0c;iPhone…

Tcp协议Socket编程

&#x1f30e; Tcp协议Socket编程 本次socket编程需要使用到 日志文件&#xff0c;此为具体日志编写过程。以及 线程池&#xff0c;线程池原理比较简单&#xff0c;看注释即可。 文章目录&#xff1a; Tcp协议Socket编程 TCP Socket API简介 构建Tcp_echo_server      …

嵌入式系统中QT实现网络通信方法

大家好,今天主要给大家分享一下,如何使用QT中的网络编程实现。 第一:QT网络编程基本简介 QT中网络模块为提供了可以使用TCP/IP客户端与服务器的类。它提供了较低级别的类,例如代表低级网络概念的 QTcpSocket, QTcpServer 和 QUdpSocket,以及诸如 QNetworkRequest, QNetw…

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现&#xff08;Kalman Filter&#xff09; 更新以gitee为准&#xff1a; 文章目录 数据预测概念和适用方式线性系统的适用性 数据预测算法和卡尔曼滤波公式推导状态空间方程和观测器先验估计后验估计…

大模型时代的具身智能系列专题(十三)

迪士尼研究中心 瑞士苏黎世迪斯尼研究中心致力于不同领域的业务活动&#xff0c;其中包括电影、电视、公园和度假村以及消费产品。我们针对所有这些领域进行科研工作。我们开发能使我们将后道生产元素整合到前级生产中的技术。由此可节省许多昂贵的效果&#xff0c;这些效果最…

IDEA2023设置控制台日志输出到本地文件

1、Run->Edit Configurations 2、选择要输出日志的日志&#xff0c;右侧&#xff0c;IDEA2023的Logs在 Modify option 里 选中就会展示Logs栏。注意一定要先把这个日志文件创建出来&#xff0c;不然不会自动创建日志文件的 IDEA以前版本的Logs会直接展示出来 3、但是…

o1的风又吹到多模态,直接吹翻了GPT-4o-mini

开源LLaVA-o1&#xff1a;一个设计用于进行自主多阶段推理的新型VLM。与思维链提示不同&#xff0c;LLaVA-o1独立地参与到总结、视觉解释、逻辑推理和结论生成的顺序阶段。 LLaVA-o1超过了一些更大甚至是闭源模型的性能&#xff0c;例如Gemini-1.5-pro、GPT-4o-mini和Llama-3.…

AJAX的基本使用

AJAX的基本使用 &#x1f389;&#x1f389;&#x1f389;欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!&#x1f64f;&#x1f64f;&#x…

DDei在线设计器V1.2.43版发布

2024-11-21-----V1.2.43 一、bug 修复 1. 修复只读情况下&#xff0c;连线依然可以通过特殊点调整的 bug 2. 修复了同一页面多个实例时&#xff0c;部分方法只会引用最后一个实例的问题 3. 修复了组合控件和容器控件改变容器后没有清理的问题&#xff0c;优化了容器的实现 4. …