【问题标题】:Periodic overhead when using tensorflow dataset for model training on GPU使用 TensorFlow 数据集在 GPU 上进行模型训练时的周期性开销
【发布时间】:2018-09-29 20:27:38
【问题描述】:

正如您在下面的代码中看到的那样,我正在尝试使用 Tensorflow 数据集在 Tensorflow 上训练一个简单的模型。数据集非常庞大,我对其进行混洗、重复和批处理,以便进行随机梯度下降来训练我的模型。

但我可以观察到优化步骤的一段时间开销(在我的代码中是 sess.run(train))。

正如您在此处看到的,每 5 步进行优化需要 3 秒而不是 0.5 秒。

步骤 105 持续时间:3.5233473777770996

步骤 106 持续时间:0.5653283596038818

步骤 107 持续时间:0.5391891002655029

第 108 步持续时间:0.5480048656463623

步骤 109 持续时间:0.0415492057800293

步骤 110 持续时间:3.032115936279297

步骤 111 持续时间:0.5407207012176514

步骤 112 持续时间:0.5276811122894287

步骤 113 持续时间:0.5448746681213379

步骤 114 持续时间:0.04253268241882324

第 115 步持续时间:3.1273345947265625

此外,我的 GPU 几乎一直处于 0% 的利用率,大约 90% 的内存已使用。

似乎这个开销是在迭代器完成查看所有数据集时出现的。

我在 Ubuntu 16.04 上使用 Python 3.6 和 Tensorflow 1.4。

您知道如何加快训练速度吗?

最好的,

import tensorflow as tf
import numpy as np
import os, time, multiprocessing
import matplotlib.pyplot as plt

def _floats_feature(value):
    return tf.train.Feature(float_list=tf.train.FloatList(value=value.reshape(-1)))


def parser(record):
    num_features = 2000
    size_group = 300
    num_classes= 10
    class_indice = 0
    keys_to_features={
                'X': tf.FixedLenFeature([size_group*num_features],tf.float32),
                'label' : tf.FixedLenFeature([num_classes],tf.float32)}
    parsed = tf.parse_single_example(record, keys_to_features)

    label = parsed['label']
    label = tf.slice(label,[class_indice],[1])
    label = tf.squeeze(label) # To get a vector one dimension
    X = parsed['X']
    X= tf.reshape(X, [size_group,num_features])
    return X, label


def test_train_w_dataset():

    # Definition of the size 
    num_features = 2000
    num_ex = 2000
    size_group = 300
    num_classes = 10
    batch_size= 480
    max_iters = 300
    buffer_size = 10000

# Creation of the Dataset 
filename_tfrecords = 'tmp.tfrecords'
if not(os.path.isfile(filename_tfrecords)): # If the file doesn't exist we will create it
    print("Start creating the Dataset")
    writer = tf.python_io.TFRecordWriter(filename_tfrecords)

    for i in range(num_ex):
        if i % 1000 == 0: print("Step :",i)
        X = np.random.normal(size=(size_group,num_features))
        vectors =  2*np.random.randint(0,2,(num_classes,1))-1
        features=tf.train.Features(feature={
                    'X': _floats_feature(X),
                    'label' : _floats_feature(vectors)})
        example = tf.train.Example(features=features)       
        writer.write(example.SerializeToString())
    writer.close()
else:
    print("The dataset tfrecords already exist")

train_dataset = tf.data.TFRecordDataset(filename_tfrecords)
num_proc = multiprocessing.cpu_count()
train_dataset = train_dataset.map(parser,
                                    num_parallel_calls=num_proc)
dataset_shuffle = train_dataset.shuffle(buffer_size=buffer_size,
                                             reshuffle_each_iteration=True) 
dataset_shuffle = dataset_shuffle.batch(batch_size)
dataset_shuffle = dataset_shuffle.repeat() 
dataset_shuffle = dataset_shuffle.prefetch(batch_size) 
shuffle_iterator = dataset_shuffle.make_initializable_iterator()
X_, y_ = shuffle_iterator.get_next()

W=tf.Variable(tf.random_normal([num_features], stddev=1.),name="weights")
W=tf.reshape(W,(1,1,num_features))
Prod=tf.reduce_sum(tf.multiply(W,X_),axis=2)
Max=tf.reduce_max(Prod,axis=1)
Tan= tf.reduce_sum(tf.multiply(tf.tanh(Max),y_))
loss= tf.add(Tan,tf.reduce_sum(tf.multiply(W,W)))

LR = 0.01
restarts = 1
optimizer = tf.train.GradientDescentOptimizer(LR) 
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
train = optimizer.minimize(loss)  
print("The graph is defined")
sess = tf.Session(config=config)

durationTab = []

for essai in range(restarts+1):
    # To do need to reinitialiszed
    t0 = time.time()
    sess.run(tf.global_variables_initializer())
    sess.run(tf.local_variables_initializer())
    sess.run(shuffle_iterator.initializer)
    t1 = time.time()
    duration = t1 - t0
    print('Duration of initialization : ',duration)
    for step in range(max_iters):
        t0 = time.time()
        sess.run(train)
        t1 = time.time()
        duration = t1 - t0
        print("Step ",str(step),' duration : ',duration)
        durationTab += [duration]


plt.plot(durationTab)
plt.ylabel('Duration')
plt.xlabel('Iteration')
plt.show()

if __name__ == '__main__':

    test_train_w_dataset()

【问题讨论】:

    标签: python tensorflow tensorflow-datasets overhead


    【解决方案1】:

    对于 GPU 利用率,请确保您使用经过 gpu 优化的二进制文件。检查操作位置(例如在 tensorboard 中)。强制将操作放置在 gpu 上(参见 tf.device)。

    对于周期性尖峰,可能有几个原因:

    • 其他进程阻止访问 CPU/GPU/RAM/磁盘,您需要等待它通过。您可以尝试终止系统上可能正在运行的其他多余任务。
    • 您的内存用完了。检查使用了多少交换空间。如果它在您运行时增长,那么峰值可能只是系统抖动,尽管它看起来表现得很好。
    • 磁盘访问。您提到这与循环数据有关。可能是系统只需要再次读取数据,因此您需要等待磁盘,尽管通常这不可见。您可以通过确保数据在硬盘驱动器上连续、将其移动到 SSD 或 RAM 来加快速度。

    由于很多原因都与 RAM 有关,您可能应该尝试使用更小的模型(更小的批次、更少的层、更少的节点/层),看看它是否会消失。如果是这样,那么您需要出去购买更多 RAM。

    【讨论】:

    • 感谢您的回答。我正在使用 Tensorflow GPU 优化的二进制文件。此外,我尝试将我的 TFrecords 数据集从 HDD 移动到 SSD,它没有任何改变。RAM 未满,GPU 内存也未满。该模型非常简单,只有一层。问题似乎来自 Tensorflow Dataset 的使用,这很奇怪,因为它似乎是 Dataset 的角色,可以有效地处理 GPU 的馈送。
    【解决方案2】:

    似乎在批处理和重复函数之间添加 dataset_shuffle = dataset_shuffle.cache() 可以消除这些周期性开销。不过,我不确定使用此命令是否已完全读取数据集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-27
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      • 2021-10-16
      • 1970-01-01
      • 1970-01-01
      • 2018-01-14
      相关资源
      最近更新 更多