BLOG

Record, summarize, and improve.

AI Profiling

NVIDIA (英伟达)

GPU架构演进:Fermi、Kepler、Maxwell、Pascal、Volta、Turing、Ampere

Volta架构及之前使用NVIDIA Visual Profiler,Turing和Ampere使用NVIDIA Nsight SystemsNVIDIA Nsight Compute

Nsight Systems负责GPU和CPU的采样和跟踪

Nsight Compute负责GPU内核性能分析

nvidia-smi / nvidia-smi dmon:

此命令会显示出与GPU 有关的实用统计资料,例如内存用量、功耗以及在GPU 上执行的程序。目的是查看是否有充分利用GPU 执行模型。

  • 功耗(pwr)
  • GPU 温度(gtemp)
  • 内存芯片温度(mtemp)
  • 内存利用率(mem)
  • 编码器利用率(enc)
  • 解码器利用率(dec)
  • 内存时钟速率(mclk)
  • 处理器时钟速率(pclk)

NVIDIA Visual Profiler(NVVP):

NVVP是2008年推出的针对CUDA编程的性能分析器,包含在CUDA Toolkit的可视化性能分析器。用户使用nvprof命令由命令行直接收集和查看相关性能分析数据,也可以使用nvvp命令来使程序的性能分析可视化。

通过输出时间显示CPU和GPU运行轨迹,通过一个自动化分析引擎来判断程序的性能瓶颈,NVVP在使用过程中会生成一个主机端和设备端的时间轴,在其中设置时间断点来对各个阶段的程序运行状况进行数据统计。

Nsight Systems 是一款具有跟踪功能的统计采样分析器,可通过用户界面和命令行工具提供详细的性能指标和 API 调试。

三种不同的模式:

  • Profiling:收集任何性能数据的过程
  • Sampling(采样):通常是为了收集回溯(活动线程的调用堆栈)
  • Tracing:收集有关对象或系统中发生的各种活动的精确信息的过程

NVIDIA Nsight Systems:System-Level Profiling

  • CPU需要多少事件来控制GPU?
  • 数据从CPU移动到GPU需要多少时间?
  • 异步操作什么时候发生?

NVIDIA Nsight Compute:Kernel-Level Profiling

GPU执行model有多快?

Nsight Compute是针对CUDA程序内核的交互式性能分析工具,继承了NVVP的基本功能,用户同样可以选择命令行或用户界面获取CUDA内核的详细性能指标并进行API的调试。

CLI

命令格式:
nsys [global_option]

ncu [global_option]

Example:

nsys profile --ftrace=drm/drm_vblank_event -d 20

在默认位置生成报告#.nsys-rep

nsys stats命令可用于分析后生成特定或个性化的报告

Image in a image block


ncu -o profile CuVectorAddMulti.exe

生成#.ncu-rep

ncu-ui #.ncu-rep

图形化界面输出结果:

Image in a image block

选择nvprof命令开关后可用nsys nvprof [options]

Image in a image block

nsight-systems Available metrics:

  • GPC Clock Frequency - gpc__cycles_elapsed.avg.per_second
  • SYS Clock Frequency - sys__cycles_elapsed.avg.per_second
  • Async Compute in Flight - gr__dispatch_cycles_active_queue_async.avg.pct_of_peak_sustained_elapsed

Image in a image block

DLProf :是一款用于分析深度学习模型的工具,是对Nvidia Nsight的一个封装。

Stream(cudaStream_t):连续CUDA事件队列。

Event(cudaEvent_t):记录stream的状态

Image in a image block

Huawei Ascend (昇腾)

为了启用神经网络的性能分析,应将 MindSpore Profiler API 添加到脚本中。首先,需要在设置上下文之后、网络和 HCCL 初始化之前设置 MindSpore Profiler对象。然后,在训练结束时,应调用Profiler.analyse()来完成分析并生成性能分析结果。

profiler = Profiler(start_profile=False)
data_loader = ds.create_dict_iterator()

for i, data in enumerate(data_loader):
    train()
    if i==100:
        profiler.start()
    if i==200:
        profiler.stop()

profiler.analyse()

MindInsight启动命令可以参考MindInsight命令

从以下三个方面介绍MindSpore Profiler架构设计:

  • Profiler整体上下文交互关系;
  • Profiler的内部结构,包括模块结构和模块层数;
  • 模块之间的交互调用关系。

上下文关系:

Image in a image block
  1. 训练脚本中,调用MindSpore Profiler向MindSpore ada(Ascend设备)或CUPTI(GPU设备)模块发送命令,开始性能数据采集。最后,ada或CUPTI生成原始性能数据。
  2. MindSpore Profiler解析用户脚本中的原始数据,并在指定文件夹中生成中间数据结果。
  3. MindInsight Profiler连接中间数据,为用户提供可视化的Profiler功能。

Profiler模块分为以下几层:

Image in a image block
  1. ProfilerAPI是代码提供的调用入口,包括性能采集启动API和分析API。
  2. Controller是ProfilerAPI下一层的模块。由ProfilerAPI的启动API调用,用于启动或停止性能采集功能。原始数据由ada写入固定位置。
  3. Parser是用于解析设备上收集的、用户无法直接理解的原始性能数据的模块。解析器对数据进行解析、组合和转换,生成用户可以理解并可供上层分析的中间结果。
  4. Analyzer获取下层Parser解析的中间结果,对中间结果进行封装、过滤、排序,并将各种信息返回给上层Profiler API和RESTful。
  5. RESTful用于调用后端Analyzer提供的通用API来获取客观数据,并使用RESTful连接前端。

内部模块交互过程:

Image in a image block
  1. ProfilerAPI调用下层Controller的控制函数来控制下层采集模块采集性能信息。目前,采集模块(Ascend上的ada或GPU上的CUPTI)接收命令并独立收集性能信息。
  2. 训练完成后,用户调用ProfilerAPI的分析API。
  3. Profiler API分析API使用Parser模块解析性能数据,生成中间结果,调用Aalayser模块对结果进行分析,并将各种信息返回给用户。

生成的原始性能数据包括:

  • hwts.log.data.45.dev.profiler_default_tag file:存储算子执行信息,包括任务的开始和结束以及流ID。
  • DATA_PREPROCESS.dev.AICPU file:指定AI CPU算子在每个阶段的执行时间。
  • Framework.host.task_desc_info file:存储算子ID和算子名称的映射关系以及各个算子的输入输出信息
  • training_trace.46.dev.profiler_default_tag  file:存储每一步的起止时间以及步间隔时间、前向传播、后向传播时间、步尾时间。
Parser

解析器对数据进行解析、组合和转换,生成用户可以理解并可供上层分析的中间结果。

Image in a image block

每个模块解析一种原始数据,得到用户可以读取的中间文件。

Ascend:

  • HWTS解析器:解析 hwts.log.data.45.dev.profiler_default_tag 文件来获取设备基于任务的统计信息,例如每个任务的开始和结束以及流 ID,这些信息用于计算算子执行时间。
  • AI CPU Parser:解析DATA_PREPROCESS.dev.AICPU文件,获取AI CPU算子在各个阶段的执行时间。
  • Framework Parser:解析Framework.host.task_desc_info文件,获取AI Core算子与任务的映射关系,以及关键算子信息。
  • 训练跟踪解析器:解析 training_trace.46.dev.profiler_default_tag 文件来分析每个训练阶段的时间。

GPU:

  • Training Trace Parser:解析step_trace_profiling_0.txt文件以分析每个训练阶段的时间。
Analyser

Analyser用于对解析阶段产生的中间结果进行过滤、排序、查询和分页。

该模块解析Parser生成的中间文件,为上层数据分析提供通用API,并将分析后的数据返回给上层进行显示。各种中间文件都有一定的共同点,可以进行抽象。因此,下图展示了Analyzer类的设计。

Image in a image block

为了隐藏Analyzer的内部实现,方便调用,采用简单工厂模式,通过AnalyserFactory获取指定的Analyzer。

针对不同的查询内容,实现了多个Analyzer。可以为每个分析器定义过滤、排序和分页条件。每个分析器都知道合并、过滤和排序数据需要哪些中间文件。 Analyzer通过Parser生成的中间文件与Parser关联,不调用任何函数。这样Analyzer和Parser就解耦了。

目前,分析器的操作信息有两种类型:

  • 过滤算子类型的平均信息。
  • 在两个Analyser(Ascend的AicoreTypeAnalyser和AicoreDetailAnalyser,GPU的GpuOpTypeAnalyser和GpuOpInfoAnalyser)中过滤每个算子的详细平均信息。

Proposer模块

Proposer是Profiler的性能优化建议模块。 Proposer调用Analyzer模块获取性能数据,根据优化规则分析性能数据,并通过UI和API向用户展示优化建议。

Image in a image block
  • Proposer提供API用于调用API和RESTful来获取优化建议。
  • Proposer调用Analyzer API获取性能数据,并根据优化规则获取优化建议。
  • Proposer调用Analyzer工厂来获取Analyzer对象。

Proposer Class:

Image in a image block

Cambricon (寒武纪)

CNMon(Cambricon Neuware Monitor,寒武纪硬件监测器工具)是一款寒武纪硬件检测工具,通过调用CNDev接口获取底层硬件信息。CNMon不仅可以采集底层硬件信息,还可以实时获取上层软件对硬件资源的开销,为用户实时显示当前底层硬件的详细信息和状态。

Image in a image block

Cambricon Neuware Performance(CNPerf)

CNPerf(Cambricon Neuware Performance,寒武纪性能剖析工具)是一款针对用户层的性能剖析工具,它以性能事件为基础,可用于 MLU200 系列产品上程序性能瓶颈查找和热点函数定位。

CNPerf 支持的功能如下:

  • 精确获得用户程序及部分依赖库中每个函数的执行时间。
  • 获取函数调用栈信息。
  • 获取并展示 PMU 数据信息。
  • 获取并展示 VPU/JPU 利用率,以及 VPU 读写带宽等信息。
  • 获取函数调用、实时功耗、MLU 利用率等信息。
  • 命令行分析日志文件。
  • 可视化网络性能信息。

生成并查看性能数据的步骤如下所示:

  1. 使用 record 命令生成性能数据,并保存到指定文件中。若要执行 kernel 命令,则需要添加 ‑‑pmu 参数,数据文件默认保存到生成的 dltrace_data 文件夹下。
  2. 以 dltrace_data 文件夹下的数据文件为输入,执行 report 命令查看性能数据信息。
  3. 以 dltrace_data 文件夹下的数据文件为输入,执行 replay 命令显示函数调用信息。
  4. 以 dltrace_data 文件夹下的数据文件为输入,执行 kernel 命令显示所有监测到的 PMU 性能信息。
  5. 使用 show 命令生成性能数据,不记录日志,直接在终端显示设备相关的性能信息。
  6. 使用 layer 命令导出融合模式下每层的 PMU 性能数据,并生成 html 和 json 文件,用于可视化性能分析。
  7. 使用 monitor 命令查看 MLU 工作时的各种性能指标,如 VPU 读写带宽等信息。
  8. 使用 timechart 命令生成包含函数调用、实时功耗、MLU 利用率等信息的 json 文件,可使用
    chrome://tracing 查看。
CNPerf 跟踪的目标程序需要加‑pg 编译。

Example:

cnperf-cli record "caffe test -model conv.prototxt -mmode MLU -mcore MLU270”

执行完毕后该目录会生成 dltrace_data 文件夹。

cnperf-cli report

显示结果:

Image in a image block

kernel 命令在终端显示丰富的 PMU 数据,细化性能数据,使用方法和 report 命令类似

Image in a image block
Image in a image block

可视化

执行程序 cnperf‑cli timechart,生成 json 文件

cnperf‑cli timechart –detail,会细化到每个核上的输出数据,生成 json 文件

打开 Chrome 浏览器,输入链接:chrome://tracing,开启 Chrome 图形化工具,点击 Load,选择加载 timechart 生成的 json 数据文件即可。

Image in a image block

Intel Habana

Habana SynapseAI Profiler提供了两种分析方法:

Tensorboard:

import torch
import habana_frameworks.torch.core as htcore

activities = [torch.profiler.ProfilerActivity.CPU]

#CUDA:
#device = torch.device('cuda:0')
#activities.append(torch.profiler.ProfilerActivity.CUDA)

#HPU:
device = torch.device('hpu')
activities.append(torch.profiler.ProfilerActivity.HPU)

with torch.profiler.profile(
    schedule=torch.profiler.schedule(wait=0, warmup=20, active=5, repeat=1),
    activities=activities,
    on_trace_ready=torch.profiler.tensorboard_trace_handler('logs')) as profiler:
    for i in range(100):
        input = torch.tensor([[i]*10]*10, dtype=torch.float32, device=device)
        result = torch.matmul(input, input)
        result.to('cpu')
        htcore.mark_step()
        profiler.step()

在专用终端窗口中启动 TensorBoard 服务器。在下面的示例中,监听端口设置为5990:

$ tensorboard --logdir logs --bind_all --port=5990

在浏览器中打开一个新窗口选项卡并查看您的 TensorBoard 网站:

http://fq_domain_name:5990

TensorBoard 生成以下类型的信息:

  • 模型性能跟踪 - 在批量处理您的工作负载时,您可以通过监控模型的成本(损失)和准确性,在仪表板上实时跟踪训练过程的进度。
  • 分析 - 在最后一个请求的步骤完成后,TensorBoard 会分析收集到的分析数据,然后立即提交到您的浏览器,无需等待训练过程完成。

初始 TensorBoard 分析视图包括 Gaudi 的全面摘要,显示 Gaudi 设备执行信息以及主机 CPU 信息。您将能够在该部分的底部看到主机和设备的利用率以及调试指南,这些指南可以为性能优化提供一些指导。

Image in a image block

HPU 内核视图提供具体细节,显示张量处理核心 (TPC) 和矩阵乘法引擎 (MME) 中的 HPU 内核利用率

Image in a image block

要在训练期间监视 HPU 内存,请在torch.profiler.profile函数中将profile_memory参数设置为True 。下面显示了一个使用示例:

with torch.profiler.profile(
    schedule=torch.profiler.schedule(wait=0, warmup=20, active=5, repeat=1),
    activities=activities,
    on_trace_ready=torch.profiler.tensorboard_trace_handler('logs'),
    profile_memory=True) as profiler:

结果,TensorBoard 中将出现一个名为“Memory View”的附加视图。

Image in a image block

如果不想运行 TensorBoard UI,可以获取相同的 JSON 日志文件并使用habana_perf_tool 。该工具解析现有的 JSON 文件并提供相同的性能增强建议。

Intel Gaudi Profiling:

修改Intel Gaudi Profiling子系统中的配置文件:

$ hl-prof-config -e off -phase=multi-enq -g 1-20 -s my_profiling_session

命令配置为捕获从第一个图启动到第 20 个图启动的模型执行情况。

设置以下环境变量以启用 Intel Gaudi Profiling 子系统:

$ export HABANA_PROFILE=1

完成后,您应该能够在工作目录中找到带有my_profiling_session前缀和.hltv后缀的文件。

将文件上传到https://perfetto.habana.ai并查看 API 调用和硬件跟踪事件。

Image in a image block

使用命令:

$ hl-prof-config -e off --phase=device-acq -b 256

Graphcore

PopVision Graph Analyser

  • IPU 硬件、图形参数和主机配置的摘要报告
  • 洞察报告,让您快速概览 IPU 上模型的内存使用情况,显示使用内存最多的图块、顶点和交换。还显示改善内存使用的图形见解和指南,帮助您优化模型的内存使用。
  • 内存报告,对 IPU 系统中所有图块的内存使用情况进行详细分析,显示总内存和活动数据的图表,以及变量类型、位置和大小的详细信息。
  • Liveness Report ,它提供了程序中每个步骤的变量状态的详细分类。
  • 操作摘要,显示模型中软件层的所有操作的摘要,显示有关代码大小、执行周期、调试数据和 FLOP 测量的统计信息。
  • 执行跟踪,显示检测程序的每个步骤消耗了多少个周期。

这些文件可以使用POPLAR_ENGINE_OPTIONS环境变量或 Poplar API 创建。 PopVision® 图形分析器至少需要archive.aprofile.pop来呈现报告。

archive.a这是 ELF 可执行文件的存档,每个图块都有一个。这样您就可以在内存报告中看到每个图块的总内存使用情况。

profile.pop该文件包含有关 Poplar 图的编译时和执行信息。该文件用于显示内存活动性程序树视图以及执行跟踪视图。

总结

  1. 图形化,网页或IDE
  2. 用python脚本参数实现功能多样化配置命令行执行
  3. device profiler和host profiler分离