paddlepaddle 的 CPU 和 GPU

想记录一下一个 bug 改了一上午改到最后发现并没有 bug 的 bug。

总结:

  • 因为下午要跑很久,为了省 GPU 算力,我想上午先用 CPU 把数据处理部分跑出来(感觉数据处理部分不像网络训练那样涉及太多计算,所以感觉用 CPU 就可以了)。
  • 结果因为没用 GPU 导致计算量太大程序阻塞没有输出,用了一上午改了一个不是 bug 的 bug。

故事拉开序幕

当我运行:

# generate train data 
!python3.7 generate_feature.py -m train 
# generate validation data 
!python3.7 generate_feature.py -m valid

输出是这样的:

!!!! mode_type: train !!!!
idx_path:./index/fold0_train_idx.npy
fold_name: _fold0

!!!! mode_type: valid !!!!
idx_path:./index/fold0_valid_idx.npy
fold_name: _fold0
=========>>mode:valid    JA finished!!! <<=========
=========>>mode:valid    J finished!!! <<=========
=========>>mode:valid    BA finished!!! <<=========
=========>>mode:valid    B finished!!! <<=========
=========>>mode:valid    JB finished!!! <<=========
=========>>mode:valid    JMj finished!!! <<=========
=========>>mode:valid    Mb finished!!! <<=========
  • 可以看到输出,只生成了 valid 的数据 JA,J,BA 等,没有生成 train 的数据?
  • 这两个 mode (train or valid)都是调用下面的这个 gen_train_valid 函数,是同一个函数呀,这是为什么呢?
def gen_train_valid(mode):
    data_path = '/home/aistudio/data/data118104/train_data.npy'
    labels_path = '/home/aistudio/data/data118104/train_label.npy'
    data = np.load(data_path)[:, 0:2, :, :, :].astype('float32')
    labels = np.load(labels_path)
    for idx in range(5):
        idx_path = './index/fold{}_{}_idx.npy'.format(idx, mode)
        print('idx_path:{}'.format(idx_path))  # 打印路径看看 mode 对不对
        fold_idx = np.load(idx_path)
        data_fold = data[fold_idx]
        labels_fold = labels[fold_idx]
        fold_name = '_fold{}'.format(idx)
        print('fold_name: {}'.format(fold_name))  # 打印 fold_name
        JA = get_JA(data_fold, labels_fold, fold_name, mode)
        get_J(JA, fold_name, mode)
        get_BA(JA, fold_name, mode)
        B = get_B(JA, fold_name, mode)
        get_JB(JA, B, fold_name, mode)
        get_JMj(JA, fold_name, mode)
        get_Mb(B, fold_name, mode)

分析没有看到 train 相关的输出信息,可能的原因包括:

  • 输出信息被隐藏了;
  • 程序跑出了异常:检查程序是否报错,如果有错误信息请提供相关的报错信息以便进一步分析问题所在。
  • 训练集中没有数据:请您检查训练集中是否有数据,如果没有数据则会导致训练集特征无法生成。

可是再排查:

  • 输出信息没有被隐藏,因为 train文件夹中没有生成一个文件。
  • 于是我打印了 work/dataset/index/fold0_train_idx.npy 里的值,证明数据集中有数据;
  • 可是既然 valid 能正常输出,不是说明了程序没有问题吗?

没办法,我又检查了 generate_feature.py 脚本的源代码,然后把问题原因定位到 get_JA 函数,因为从这个函数开始 train 就没有输出了。

def get_JA(J, labels, fold_name, mode):
    N, C, T, V, M = J.shape
    save_data_path = './{}/JA{}.npy'.format(mode, fold_name)
    if mode != 'test':
        save_label_path = './{}/fold{}_label.npy'.format(mode, fold_name[-1])
    l = [pairs_local, pairs_center1, pairs_center2, pairs_hands, pairs_elbows, pairs_knees, pairs_feet]
    res = np.zeros((N, len(l), T, V, M), dtype='float32')
    for i, pairs in enumerate(l):
        ans = get_single_angle(pairs, J)
        res[:, i, :, :, :] = ans.squeeze(1)
    JA = np.concatenate((J , res), axis=1).astype('float32')
    if mode == 'train':
        JA, labels = upsampling(JA, labels)

然后我在这个函数里添加了很多 print 语句,发现问题出现在这3行:

    for i, pairs in enumerate(l):
        ans = get_single_angle(pairs, J)
        res[:, i, :, :, :] = ans.squeeze(1)

我又把 get_single_angle 函数单独调出来运行发现是可以正常输出的,输出的结果通过打印形状,也是符合预期的,不过我还是给这个函数加上了异常捕获;

加入异常捕获代码之后,程序不会直接退出,而是会在遇到异常时输出错误信息并返回 None。

为了检查输出是否被遗漏,我在循环结束后再添加一行 print(‘i: {}’.format(i)) 进行检查:

 for i, pairs in enumerate(l):
        print('i_start: {}'.format(i))
        ans = get_single_angle(pairs, J)
        print(ans.shape) # (2337, 1, 2500, 25, 1)
        res[:, i, :, :, :] = ans.squeeze(1)
        print(res.shape) # (2337, 7, 2500, 25, 1)
        print('i_end: {}'.format(i)) i_start: 0

发现没有 i_end 的输出。

结合问题:在 valid 模式下可以正常输出,但在 train 模式下没有输出。

可能是因为训练集数据量较大,在执行 get_JA 函数时需要处理的数据量很大,导致在输出语句之前程序被阻塞,无法顺利输出。

解决办法

解决办法:增加硬件资源。如果计算机性能较低,可以尝试增加硬件资源,例如更换更高配置的 CPU 或 GPU,以提高计算速度。

果然用了 GPU V100 32GB,输出就正常了。

i_end 正常输出了:

i_start: 0
(2337, 1, 2500, 25, 1)
(2337, 7, 2500, 25, 1)
i_end: 0

paddlepaddle 的 CPU 和 GPU_第1张图片

终于 train 也输出文件了:

paddlepaddle 的 CPU 和 GPU_第2张图片

你可能感兴趣的:(飞桨深度学习,paddlepaddle,GPU,CPU)