8

高阶干货|如何用gperftools分析深度学习框架的内存泄漏问题

 3 years ago
source link: https://my.oschina.net/u/4067628/blog/4767198
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

高阶干货|如何用gperftools分析深度学习框架的内存泄漏问题 - 飞桨PaddlePaddle的个人空间 - OSCHINA - 中文开源技术交流社区

本系列为高阶干货,面向深度学习从业者,栏目会定期分享PaddlePaddle研发工程师和产品经理的行业经验。本篇和内存泄漏分析相关,适合中高阶深度学习工程师仔细阅读,预计阅读时间5分钟

乔龙飞:PaddlePaddle开源社区成员,百度资深研发工程师,目前负责PaddlePaddle相关技术工作

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

什么是内存泄漏

计算机程序都可能有内存泄漏的风险。内存泄漏一般是由于程序在堆(heap)上分配了内存而没有释放,随着程序的运行占用的内存越来越大,一方面会影响程序的稳定性,可能让运行速度越来越慢,或者造成oom,甚至会影响程序所运行的机器的稳定性,造成宕机。

内存泄漏的分析工具

目前有很多内存泄漏分析工具,比较经典的有valgrind, gperftools

主流的深度学习框架,例如Google Tensorflow,Mxnet,PaddlePaddle等,都是用Python驱动C++ core来执行训练或者预测任务。对于这种类型的程序:

1.valgrind直接分析非常困难,需要自己编译debug版本的、带valgrind支持的专用Python版本,而且输出的信息中大部分是Python自己的符号和调用信息,很难看出有用的信息,另外使用valgrind会让程序运行速度变得非常慢,所以不建议使用。

2.而gperftools使用简单,无需重新编译代码即可运行,对运行速度的影响也比较小。

下面基于PaddlePaddle的一次内存泄漏问题的分析过程,介绍如何使用gperftools来分析和调试深度学习框架内存分配问题。

功能支持

gperftool主要支持以下四个功能:

1.thread-caching malloc

2.heap-checking using tcmalloc

3.heap-profiling using tcmalloc

4.CPU profiler

对于堆内存的分析,主要用到thread-caching malloc和heap-profiling using tcmalloc

使用流程

本教程基于paddle提供的Docker开发环境paddlepaddle/paddle:latest-dev,基于Ubuntu 16.04.4 LTS环境,基本上只要支持google-perftools就可以了。

步骤

1. 安装google-perftools

apt-get install libunwind-dev
apt-get install google-perftools

2. 安装pprof

go get -u github.com/google/pprof

3. 设置运行环境

# 如果是以root运行的话,其他用户可能需要相应的修改

export PPROF_PATH=/root/gopath/bin/pprof
export PPROF_BINARY_PATH=/root/gopath/bin/pprof
export LD_PRELOAD=/usr/lib/libtcmalloc.so.4

4. 使用heap profile来运行python程序。本质上是周期性的对堆的分配情况做一次快照。

# HEAPPROFILE 设置生成的堆分析文件的目录和文件前缀

# HEAP_PROFILE_ALLOCATION_INTERVAL 设置每分配多少存储dump一次dump,默认1GB

随着程序的运行,会在perf_log这个文件夹下生成很多文件,如下

-rw-r--r-- 1 root root 1.0M Jun 1 15:00 test.log.0001.heap
-rw-r--r-- 1 root root 1.0M Jun 1 15:00 test.log.0002.heap
-rw-r--r-- 1 root root 1.0M Jun 1 15:00 test.log.0003.heap
-rw-r--r-- 1 root root 1.0M Jun 1 15:00 test.log.0004.heap
-rw-r--r-- 1 root root 1.0M Jun 1 15:00 test.log.0005.heap
-rw-r--r-- 1 root root 1.0M Jun 1 15:00 test.log.0006.heap

5. 使用pprof对heap文件进行分析。分析分为两种模式

→完整模式。会对当前heap做一个分析,显示目前分配内存一些调用路径。

pprof --pdf python test.log.0012.heap

上述命令会生成一个profile00x.pdf的文件,可以直接打开。从下面的截图可以看出,在CPU版本fluid的运行过程中,分配存储最多的模块是CPUAllocator(memory pool),而别的模块相对而言分配内存较少,所以被忽略了,这对于分析内存泄漏是很不方便的,因为泄漏是一个缓慢的过程,相对于memory pool这种一开始就分配大片内存的模块,泄漏的地方内存占用相对较少,在这种图中是无法看到的。

memory allocator

→Diff模式。可以对两个时刻的heap做diff,把一些内存分配没有发生变化的模块去掉,而把增量部分显示出来。

pprof --pdf --base test.log.0010.heap python test.log.1045.heap

上述命令也会生成一个profile00x.pdf的文件,从pdf可以看出:ProgramDesc这个结构,在两个版本之间增长了200MB+,所以这里有很大的内存泄漏的可能性,最终结果也确实证明是这里造成了泄漏。

result

result

下载安装命令

## CPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/cpu paddlepaddle

## GPU版本安装命令
pip install -f https://paddlepaddle.org.cn/pip/oschina/gpu paddlepaddle-gpu

*为了方便大家使用PaddlePaddle,遇到问题可在中文社区提问,值班同学将在24小时内响应!更有精品案例、课程提供,让大家学习使用框架,轻松无忧!直达链接:

https://ai.baidu.com/forum/topic/list/168

本文分享 CSDN - 飞桨PaddlePaddle
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK