记一次tensorflow debug过程
本周有个TF问题困扰一周,周末闲着无聊,debug一天,本着更加无聊的思路,写下本文。。。
起因
在用单机4卡跑TF模型时,遇到了如下错误:
38430 Aborted (core dumped) $@
一脸懵逼,之前看过TF的core文件,由于是多线程异步的,几十个线程又非常相似,如果不是对底层API非常了解,还是建议先别看了。。。
分布式环境到本地mac环境
由于线上的单机多卡环境是在集群上提交的,为了模拟线上环境,在mac本地搭建了本地计算图计算模型。 本地跑完了整个流程,完全没发现错误,只能得到一个结论:计算图本身并没有问题。
排除数据错误
既然计算图并没有问题,那么可能是数据异常造成的错误了。
本地数据检查
由于读取的数据是spark来生成tfrecord的,首先用spark统计各个数据指标,并未发现不符合要求的。接着在本地mac环境跑计算图,使用较小的valid数据集时并不能复现问题。而且将tfrecord的数据解析,也并未发现错误。
远程数据检查
小数据集上并不能复现该问题,然而在线上大数据集上仍然出现了该问题。考虑是大数据集上某些数据造成了问题,采用了人肉二分法。发现part-r-00210、part-r-00215等数据上能复现该问题。
本地分布式环境
考虑到可能是本地并没有复现分布式的环境,于是将本地mac也改成单机多卡方式,同时
allow_soft_placement = True
将有问题数据集下载到本地,终于完整复现了问题,同时得到了提示:
tensorflow/core/framework/tensor.cc:746] Check failed: 0 <= start (0 vs. -2147483648)
同时也发现个有趣的问题,不同的batch_size下,有时候能复现,有时候不能复现。。。
Tensorflow源码查看
根据提示查看git http:// v1.4.0tensor.cc 746行代码如下:
Tensor Tensor::Slice(int64 start, int64 limit) const {
CHECK_GE(dims(), 1);
CHECK_LE(0, start);
CHECK_LE(start, limit);
int64 dim0_size = shape_.dim_size(0);
CHECK_LE(limit, dim0_size);
if ((start == 0) && (limit == dim0_size)) {
return *this;
Tensor ret;
ret.shape_ = shape_;
ret.set_dtype(dtype());
ret.buf_ = nullptr;
if (dim0_size > 0) {
const int64 elems_per_dim0 = NumElements() / dim0_size;
const int64 delta = start * elems_per_dim0;
dim0_size = limit - start;
ret.shape_.set_dim(0, dim0_size);
const int64 num_elems = dim0_size * elems_per_dim0;
if (buf_) {