计算图
计算图是深度学习中表示网络模型计算逻辑和状态的关键工具。它由张量(Tensor)和算子(Operator)构成,通过节点表示算子,有向线段表示张量状态,揭示计算之间的依赖关系。例如,MIGraphX框架中的模型计算图可表示为:
input -> convolution->silce->contiguous->flatten
在MIGraphX中,可以通过以下代码查看计算图的文本形式:
migraphx::program net;
std::cout<<net<<std::endl;
MIGraphX中的计算图类型
MIGraphX支持打印两种类型的计算图:未编译和编译后的计算图。
未编译的计算图示例
module: "main"
[...]
main:@2 = convolution[...](input, main:@0) -> float_type, {...}
[...]
第一行moudle:"main"
表示计算图,下面每一行表示该主计算图中的一条指令,例如main:@2 = convolution[...]
,其中:
main:@2
:指令ID,main表示主计算图,@2表示指令序号。convolution
:算子名称。[...]
:算子属性。(input, main:@0)
:指令输入参数。float_type, {...}
:输出shape和类型。
特殊指令以@
开头,如@literal
表示常量,@param
表示模型输入,@return
表示模型结束指令。
编译后的计算图示例
module: "main"
main:@0 = check_context::migraphx::version_1::gpu::context -> float_type, {}, {}
[...]
编译后的计算图包括内存分配(hip::hip_allocate_memory
,提前统一分配,后面直接使用)、当设置offload_copy=true
,能看到数据拷贝到GPU(hip::copy_to_gpu
,)指令、常量拷贝GPU(hip::hip_copy_literal
)、数据拷贝主机端(hip::copy_from_gpu
)、hip::sync_stream
用于流同步。
性能分析工具migraphx-driver
migraphx提供了性能分析工具migraphx-driver,可在安装目录下的bin文件找到。使用方法如下:
/opt/dtk/bin/migraphx-driver perf [--enable-offload-copy] [-h] [--batch] [--input-dim] [-n] [--fp16] [--gpu/--cpu] --onnx
参数说明:
--enable-offload-copy
:启用offload_copy模式,必填-h
:显示帮助文档--batch
:可选,设置batchsize,但如果程序中的使用的onnx模型没有batchsize参数,就要设置一下,不如就会报错了。--input-dim
:自定义模型输入shape。使用方法:--input-dim @input 64 3 224 224
,@input表示onnx的输入节点名,后面的64 3 224 224表示输入shape,格式为NCHW-n
:迭代次数,默认100次,工具以此计算平均耗时--fp16
:使用FP16模式,默认使用FP32--gpu/--cpu
:默认gpu--onnx
:指定onnx模型文件路径
性能分析
运行分析工具之后,输出的结果中首先是模型的编译的计算图,然后在计算图后面会显示计算图中每一条指令执行的时间:
Allocating params ...
Running performance report ...
main:@0 = check_context::migraphx::version_1::gpu::context -> float_type,{},{}:0.00269076ms,0.00632856%
main:@1 = hip::hip_allocate_memory[shape=float_type,{38535168},{1},id=main:scratch]->float_type,{38535168},{1}:0.00169618ms, 0.00395935%
...
会列出模型中每个算子的执行时间及其在总时间中的占比。
最后会输出总体性能指标:
性能分析的最后部分会总结模型的整体性能指标,如总耗时、每秒处理的数据量(Rate)、额外开销(Overhead)等。例如:
Summary:
gpu::convolution: 22.6576ms / 49 = 0.4624ms,53.2898%
...
Batch size: 32
Rate: 975.796/sec
Total time: 32.7937ms
Total instructions time: 37.1238ms
Overhead time: 0.189906ms, -4.33002ms
Overhead: 1%, -13%
- Summary后面表示:所有相同算子的耗时/模型中的调用次数=平均耗时,占比
- Total time:n次平均后的模型总耗时。
- Rate:每秒处理的数据量,
Rate=1000.0/total time*batchsize
- Total instructions time:所有算子耗时总和。(包含同步时间)
- Overhead time:额外开销,正常开销是算子执行的耗时,但实际上还有遍历计算图的耗时,这里数值的意义是第一个表示实际测试出来的额外开销,第二个表示
total time-total instruction time
的差值。 - overhead:表示额外的开销占据total time的比例。
通常使用total time或者rate来表示模型的实际推理性能
通过这些数据,用户可以精确地了解模型中哪些算子是性能瓶颈,从而对模型进行优化。
调试MIGraphX
输出每个节点结果
要查看每个指令的输出,设置环境变量:export MIGRAPHX_TRACE_EVAL=2
运行程序之后可以得到类似下面格式的输出:
Run instruction: main:@151 = gpu::add(main:@147,main:@150,main:@149) ->
float_type, {8, 6, 4, 96}, {2304, 384, 96, 1}
Time: 0.008117ms, 0.160552ms
Output has normal
Output: 0.932655, 0.78008, 0.455646, 0.490867, 0.500787, ..., -1.57317, -1.5806,
-1.59469, -1.48618, -1.80712
第一行Run instruction:后面表示指令,最后一行Output:后面的数值就是该指令的输出结果,为了方便查看,只显示结果中的最前面5个数值和最后面5个数值
查看MIGraphX版本
不同版本间可能存在差异,通过以下命令查看版本:/opt/dtk/bin/migraphx-driver --version