CUDA层硬件debug之路

前记

众所周知,夕小瑶是个做NLP的小可爱。

虽然懂点DL框架层知识,懂点CUDA和底层,但是我是做算法的哎,平时debug很少会遇到深度学习框架层的bug(上一次还是三年前被pytorch坑),更从没遇到过CUDA层甚至硬件层的bug。直到有一天....

 

v2-bb5d59066d3e1dd5e0a35b2ab55ee4ab_b.jpg

这个bug彻底颠覆了我的debug思路,从这个bug开始,我再也不认为做算法的就做好算法就好了。

事故现场还原

当时的背景是这样的,我平时在一台8卡的GPU服务器上debug代码,这台服务器很少会把8卡全用满,毕竟这台机器只是用来debug代码而已,要跑那种好几天的8卡训练任务的话肯定就提交集群了,否则你如果占了全部8张卡,那自己和别人都没法debug了。

 

v2-e0c4d0041981113c74f5cf381ed6672f_b.jpg

当时恰逢deadline扎堆,0-5卡都被其他蹭机器的小伙伴占了,只有6、7卡能用。于是我就用这两张卡来debug代码,训练和预测都是多卡并行,于是debug的时候这两张是同时用的。

结果把新的idea实现后,跑了一下,发现一个step都没有跑完就挂掉了,而且全部的报错信息就两个单词:

        $ bash run.sh
segmentation fault

???我写的都是python代码呀,我不是在做NLP么,怎么跑出来段错误segmentation fault了??众所周知,段错误是写C++代码时非常让人头疼的错误

随手一搜

 

v2-78f4ae7734481cd84676f378b1d41624_b.jpg

果然,自己摊上大麻烦了╮(╯▽╰)╭

虽然,连挂掉时的代码出错位置都没有打印;虽然,炼丹以来第一次遇到这个报错。但!是!依然难不倒见过大风大浪的本宝宝的!

 

 

v2-d979300e0d3e56b491f49b6ed8294089_b.jpg

进一步加关键词限制来强行Google了一下,发现可能的错误原因依然太多了,各种类型的代码里都可能遇到。算了算了,这次就不Google oriented debug了,是时候展示真正的技术了!

首先,先看看是计算图compiled之前还是过程中还是runtime挂的。

【此处省略一顿怒插数十断点的操作】

于是一路debug发现计算图可以顺利建立,但是在深度学习框架完成计算图编译,开始runtime计算的时候,就挂了。emmmm,这说明。。。

果然是最糟糕的情况哇!!

基于静态图的DL框架就怕在runtime出问题,很多小伙伴可能不清楚runtime该怎么debug,于是纷纷觉得pytorch真香。其实对于绝大部分错误,静态图还是蛮好debug的,秘诀也很简单,那就是往图里插入debug op。

像tensorflow、paddlepaddle这种支持静态图的深度学习框架,都是有大量debug op的,最常用的就是print op(tensorflow中的tf.Print/tf.print,paddle中的layers.Print),它可以在计算图的任意位置打印出运行到此位置时的任意Variable/Tensor的runtime值,当然也可以搭配shape op(TF中的tf.shape,paddle中的layers.shape)打印出Tensor的runtime形状等信息。除了print op外,还有assert opis op等保证运行正确性、辅助debug的op,也就是说,python中常用来debug的一些关键字和函数调用,其实成熟的静态图框架里基本都能找到对应的op。熟悉了映射关系后,静态图debug起来也不会太费力。

 

v2-3c760bd8a1f91dd9aaeb06aa3d270e56_b.jpg

但!是!有两种情况依然比较头疼,一种是计算图已经完全建立了,但是第一个op还没有跑到的时候就挂了(这时候插入的debug op完全没被run到);还有一种是前向正确的跑完了,但是计算梯度的时候挂掉了(这时候错误可能发生在整张图的任意位置,甚至不在图里)。当它们再叠加上多机多卡问题时,就是最惨的情况。

不幸的是,我遇到了(。 ́︿ ̀。)

首先,如前所述,本宝宝很淡定的在计算图里插入了一堆Print结点,然后发现前向计算结果貌似非常正确,轻松的定位到错误发生在runtime计算反向梯度的时候,也就是

        optimizer.optimize()

算了算了,也不是第一次挂在这儿,报错信息似乎也提供不了太多指导(报错信息里有一些路径类信息,比较敏感就不贴出来了)。再多插入几个debug op来验证前向路径的正确性

【此处省略另一顿插op的操作】

结果,万万没想到,插入debug op之后,竟然第一个step跑完了,这次挂在了第二个step!

???

debug op还有强行续命的功效???

我!不!信!于是把debug op又都注释掉了,重新run!

结果,

又挂在了第一个step!!!

 

v2-19921318900985cc2963c451d85a7aed_b.jpg

我当时狠掐了自己一把,这特喵的一定是在做一个很荒唐的梦!

令我没想到的是,现实果然比梦境更荒唐。我又重复的run了好多好多次,发现没有插入debug op的时候确实永远是第一个step就会挂掉。于是我把这个震惊的现象告诉了大家,然后果然,大家都觉得我疯了。

小夕:”你们都过来!我来亲自演示一遍!“

小夕:”你们看!没有插入debug op的时候,第一个step就报了segment fault的错误叭~“

大家:”哦“

小夕:”然后看好哦,我把这里的debug op都插上,然后,run!“

诶诶诶???怎么还是第一个step就挂了,被疯狂打脸(´Д` )

大家:小夕你要是累了就先去睡会儿,别太累了,大家散了散了╮(╯▽╰)╭

嘤嘤嘤怎么会(。 ́︿ ̀。)

算了算了,不纠结这个了。回到debug本身,emmm,话说前向能正常跑完,永远都是挂在反向阶段,那么说明要么前向哪里埋了一个坑暂时被强行计算了,但是这个节点处的梯度其实是无法计算的;要么可能是优化器本身就有bug。

 

v2-f1f3c3767b06f362c0be7f570e0afafc_b.jpg

于是先扫了一遍代码,确实没有使用也没有cast很奇怪的数据类型,也没有使用一些很奇怪的op,基本可以排除前一种情况。那应该就是后一种了!而优化器用的其实就是adam,没什么改动,那问题就肯定出在自己新加的多卡梯度合并这块了!

于是果断的在6卡上跑了一下单卡的代码,果然正常训练!我真是福尔摩夕呀,马上就要揪出bug真凶了好激动。

继续!回去check了一下多卡逻辑,燃鹅似乎。。没问题鸭?天呐,难不成这回要去框架源码里插断点了?

看来,我只能祭出我的杀手锏了,那就是

滚!去!写!demo!

 

v2-990555818e1709a747d0cf4f0a74c14f_b.jpg

由于代码逻辑有点复杂,并且会在多卡梯度合并的时候要进行一些额外的处理,当时觉得应该还是代码哪里写的有问题,于是决定先开ipython写个多卡计算的小demo。

【此处省略一个demo】

嗯,前向计算顺利通过,符合预期。好,加大难度,引入梯度合并。

结果,

又又又segmentation fault 了!!!我还没引入我的idea呢,直接就挂了。

不对哇!!这不就是多卡训练的标准玩法么,难道最新版的框架有bug???天呐我发现了这么大的一个bug!于是卸掉重装了一个旧版的非常稳定的包,重新跑这个demo代码

结果,又又又又 segmentation fault 了!!!

 

v2-e0518154dd174382f183fdf2cdb45141_b.jpg

不会吧。。。又check了一下环境,确保CPU、内存、磁盘、GPU及其显存都是够用的,CUDA、CUDNN、NCCL也没问题(自带的tool都能check过)。难不成是python的锅?不至于吧,我也太多疑了。。。

这时我出现了一个大胆的想法。

难不成这两张显卡里,有一张是坏的??

前面测试CUDA时刚在GPU6上跑了一把,发现好好的。那么。。。GPU7!狼人肯定是你了!!

于是又去GPU7上跑,满心等着它挂掉,结果。。

训练一切正常

 

v2-e1638424af593f557a441d5f31a43071_b.jpg

强迫自己冷静了一下。我是不是太多疑了,竟然都怀疑到硬件身上了。但是,基本的运行环境都check过了鸭,如果不是硬件,也不是python和框架的问题,那难不成。。。是中间的glibc的问题???联想到segment fault这个报错信息,更加确信了!glibc就是狼人,这次跑不掉了!

然而众所周知,glibc这种级别的库,是非常底层的,一旦改坏了,会导致ls、cd这种级别的命令都挂掉。我看了一眼GPU0-5卡上跑的好好的别人的任务,再次陷入了迷茫。。。

【此处省略长达数十分钟的卡顿】

嗯,先低调一些,先把demo放到一个崭新的环境中跑下!于是把demo放到另一台机器上跑了一下,果然,多卡也是能正常跑的。莫非真是glibc?但是为什么别人的任务没问题呢。似乎一切现象都在导向最后一种可能

GPU6到GPU7的底层通信链路出故障了!

于是我耐心的等着其他小伙伴的任务跑完,重新测试!

GPU5+GPU6:训练正常

GPU5+GPU7:训练失败

GPU0+GPU1+GPU2+GPU3+GPU4+GPU5+GPU6:训练正常

GPU0+GPU1+GPU2+GPU3+GPU4+GPU5+GPU6+GPU7:训练失败

实锤!!!激动万分的跑去找管机器的小哥哥了,语无伦次的给解释了大半天。终于,小哥哥将信将疑的安排人去进一步测试了一下

焦急的等了若干天。。。

小哥哥:“是的,GPU7坏掉了,无法与其他卡通信,更换GPU7后测试正常“

听到这个消息后,小夕非常激动的重新测了一遍各种跟GPU7的排列组合,成功!!

后记

这时候我突然想起来之前那个见鬼的插debug op会导致多跑一个step的现象,而且仅出现了一次,于是跑去问小哥哥,小哥哥悠悠的说

“那大概就叫做回光返照吧,GPU7尽力了“

 

想看更多文(段)章(子),欢迎关注微信公众号「夕小瑶的卖萌屋」噢~

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

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

相关文章

研讨会 | 知识图谱大咖云集阿里,他们都说了啥

前言12月20日,由阿里巴巴联合中国中文信息学会语言与知识计算专委会(KG专委)举办的知识图谱研讨会在杭州召开。研讨会由阿里巴巴集团副总裁墙辉(玄难)主持,知识图谱领域国内知名专家参与了此次研讨。在阿里巴巴持续发力知识图谱这…

置信区间、P值那点事

在假设检验中,我们常常看到跟P值形影不离的一对区间值, 就是大名鼎鼎的置信区间了。 这置信区间和P值是怎么得来的,我想大多数盆友都不会有什么直观的概念,只会注意P值是否小于0.05或者0.01(根据显著性水平确定)。为了给大伙说清楚…

【JavaWeb】HTML+CSS

1 Web概念概述 JavaWeb是使用Java语言开发基于互联网的项目 软件架构 cs架构:优点【资源加载快、用户体验好】、缺点【安装、部署、维护麻烦】bs架构:优点【开发、安装、部署、维护简单】、缺点【应用过大,用户体验会受影响、对硬件有要求…

深度推荐系统2019年度阅读收藏清单

一只小狐狸带你解锁NLP/ML/DL秘籍正文来源:深度传送门今天是2020年新年工作第一天,祝大家开工大吉,新的一年一切顺利,诸事躺赢!深度传送门也跟很多号主一样,花了点时间分类整理了一下阅读清单(包…

手把手教你协方差分析的SPSS操作

手把手教你协方差分析的SPSS操作 2017-04-27 手把手教你协方差分析的SPSS操作 一、问题与数据 某研究将73例脑卒中患者随机分为现代理疗组(38例)和传统康复疗法组(35例)进行康复治疗,采用Fugl-Meyer运动功能评分法&a…

我对DevOps的理解

一、DevOps的意图 究竟什么是DevOps? 要想回答这个问题,首先要明确DevOps这个过程参与的人员是谁?即开发团队和IT运维团队!那么,DevOps的意图是什么呢?即在两个团队之间,建立良好的沟通和协作,…

【JavaWeb】JavaScript基础篇+高级篇

文章目录1 介绍2 ECMAScript2.1 基本语法2.2 基本对象3 BOM3.1 window窗口对象3.2 location地址栏对象3.3 history历史记录对象4 DOM4.1 概念4.2 核心DOM4.2.1 Document对象4.2.2 Element对象4.2.3 节点对象4.2.4 案例:动态表格4.2.5 内容切换4.2.6 样式设置5 事件5…

万万没想到,我的炼丹炉玩坏了

一只小狐狸带你解锁NLP/ML/DL秘籍作者:夕小瑶前记众所周知,夕小瑶是个做NLP的小可爱。虽然懂点DL框架层知识,懂点CUDA和底层,但是我是做算法的哎,平时debug很少会遇到深度学习框架层的bug(上一次还是三年前…

Reactor三种线程模型与Netty线程模型

一、Reactor三种线程模型 1.1、单线程模型 单个线程以非阻塞IO或事件IO处理所有IO事件,包括连接、读、写、异常、关闭等等。单线程Reactor模型基于同步事件分离器来分发事件,这个同步事件分离器,可以看做是一个单线程的while循环。下图描述了…

图解Transformer-一篇文章看懂transformer

原文标题:The Illustrated Transformer 原文链接:https://jalammar.github.io/illustrated-transformer/ 论文地址:https://arxiv.org/abs/1706.03762 前言 Attention这种机制最开始应用于机器翻译的任务中,并且取得了巨大的成就…

【JavaWeb】前端框架之Bootstrap

文章目录1 概念2 快速入门3 响应式布局4 CSS样式和JS插件1 概念 BootStrap是前端开发框架,基于HTML、CSS、JavaScript。 优点: 定义了很多CSS样式和JS插件,可以直接使用。响应式布局:同一套页面可以兼容不同分辨率的设备。 2 快…

号外号外,第一届沙雕项目竞赛,这些项目以数万Star惨获提名

一只小狐狸带你解锁NLP/ML/DL秘籍正文来源: Python空间 好看的皮囊千篇一律,有趣的灵魂没有底线。作为全球最大的同性交友网站,GayHub GitHub 上不止有鲜活的代码,秃头的算法,还有很多拥有有(sha&#…

尼克 | 从专家系统到知识图谱

本文节选自尼克老师的《人工智能简史》第 3 章:从专家系统到知识图谱。从第一个专家系统 DENDRAL 到语义网再到谷歌的开源知识图谱,对知识图谱的发展历程进行了全面回顾和深度点评。尼克,早年曾任职哈佛和惠普;后创业投资&#xf…

Google 资深软件工程师 LeetCode 刷题笔记首次公开

BAT 等国内的一线名企,在招聘工程师的过程中,对算法和数据结构都会重点考察。但算法易学难精,我的很多粉丝技术能力不错,但面试时总败在算法这一关,拿不到好 Offer。但说实话,数据结构和算法花点时间&#…

论文浅尝 | Learning with Noise: Supervised Relation Extraction

Luo B, Feng Y, Wang Z, et al. Learning withNoise: Enhance Distantly Supervised Relation Extraction with Dynamic TransitionMatrix[C]// Meeting of the Association for Computational Linguistics.2017:430-439.链接:http://www.aclweb.org/anthology/P/P1…

项目架构之传统三层架构和领域模型三层架构

一、架构之传统三层架构 传统三层架构是一种软件架构,是一种典型的、基于贫血模型的、面向过程的JavaWeb分层方式。该架构分为以下三个层次: 数据访问层(DAL - Data Access Layer)即对包括数据库在内的数据源进行操作的部分。业务…

限定域文本语料的短语挖掘(Phrase Mining)

一只小狐狸带你解锁NLP/ML/DL秘籍正文来源:丁香园大数据前言短语挖掘(Phrase Mining)的目的在于从大量的文本语料中提取出高质量的短语,是NLP领域中基础任务之一。短语挖掘主要解决专业领域(如医疗、科技等&#xff09…

论文浅尝 | Hike: A Hybrid Human-Machine Method for Entity Alignment

Zhuang Y,Li G, Zhong Z, et al. Hike: A Hybrid Human-Machine Method for Entity Alignmentin Large-Scale Knowledge Bases[C]// ACM, 2017:1917-1926. ( CIKM 2017 )论文链接:http://dbgroup.cs.tsinghua.edu.cn/ligl/crowdalign.pdfMotivation随着语义网络的迅…

TCC分布式实现原理及分布式应用如何保证高可用

一、业务场景介绍 咱们先来看看业务场景,假设你现在有一个电商系统,里面有一个支付订单的场景。 那对一个订单支付之后,我们需要做下面的步骤: 更改订单的状态为“已支付”扣减商品库存给会员增加积分创建销售出库单通知仓库发货…

IJCAI 2018:中科院计算所:增强对话生成一致性的序列到序列模型

IJCAI 2018:中科院计算所:增强对话生成一致性的序列到序列模型文章来源:企鹅号 - 读芯术你和“懂AI”之间,只差了一篇论文号外!又一拨顶会论文干货来袭!2018年6月9-10日,代表学术界和工业界的顶…