Tensorflow:为什么在使用功能更强大的硬件时,我的TensorFlow模型不能更快地训练?

时间:2018-08-02 20:41:56

标签: tensorflow tensorflow-datasets tensorflow-estimator

我的Tensorflow模型遇到了一些性能问题。这些模型基于CSV,并具有多达500万行的数据集和6-8GB的数据。我试图整理一个小的例子来说明我的方法。我在这里做根本上不正确的事情吗?

我正在尝试使用Dataset API从TFRecord文件加载,然后使用Estimator API进行训练和评估。

我已经提供了示例代码,该示例代码可加载具有1个功能(projectedPoints)和标签(pickTier)的TFrecord文件。训练数据集有约80k记录,评估数据集有约18k记录。如果需要,我可以包含更多或更少的数据,但是该行为似乎与甚至更多的数据都保持一致。在我的示例中,我指定了内置的LinearClassifier Estimator类,但是我得到的任何结果(包括自定义结果)都得到相似的结果。

Here's a link to a GitHub repo具有实际的tfrecord文件(如果有帮助的话)。

我不确定我如何使用一些东西。这是从CSV文件加载表格数据的正确方法吗?我用这种数据来解决这个问题吗?我这样做的原因是,当我使用由熊猫函数而不是数据集API支持的输入函数时,我遇到了类似的性能问题。我现在有点想法,说它可能提供的不是很多,但是我从这里的其他帖子中意识到,它可能对更大的数据集有帮助。

很长一段时间以来,我一直在Macbook Pro上开发和运行这些模型。直到我到达需要一段时间的培训为止,这一直很好。然后我认为是时候向它扔更多的硬件了。

我用16核3.4 ghz AMD Threadripper,32GB RAM和1080 Ti建造了一台机器。所有模型运​​行都较慢。我不明白为什么。

我还弄弄了allow_soft_placement设置。主要的影响似乎是由于某些操作不受支持,因此您无法在GPU上完全运行这样的示例。那有意义吗?


示例1

CPU:2.5GHz四核Intel Core i7(2015 Macbook Pro)

Tensorflow:1.9.0点

设备:“ / cpu:0”

结果:〜300-320步/秒


示例2

CPU:16核3.4 ghz AMD Threadripper

Tensorflow:1.9.0点

设备:“ / cpu:0”

结果:〜275步/秒。现在可以在16核CPU上运行,而在4核CPU上运行。慢一点我不应该仅基于CPU功率就期望更高的数字吗?在任何给定时间,它似乎只使用总CPU功率的8-10%。这似乎也不正确。


示例3

CPU:16核3.4 ghz AMD Threadripper

Tensorflow:1.9.0由具有CUDA支持的源构建

设备:“ / cpu:0”

结果:〜240-250步/秒

我认为这仍然只在CPU上运行,但是仅启用GPU的速度已经慢了一点。包括显示GPU存在的日志。但是由于我指定显式使用CPU,所以我认为那会赢吗?也许不吧。在此期间,GPU使用率约为2-4%。 CPU保持以前的8-10%。

INFO:tensorflow:Graph已完成。 2018-07-31 09:00:55.444038:I tensorflow / core / common_runtime / gpu / gpu_device.cc:1392]找到具有属性的设备0: 名称:GeForce GTX 1080 Ti主要:6个次要:1 memoryClockRate(GHz):1.582 pciBusID:0000:07:00.0 totalMemory:10.91GiB空闲内存:10.30GiB 2018-07-31 09:00:55.444058:我tensorflow / core / common_runtime / gpu / gpu_device.cc:1471]添加可见的gpu设备:0 2018-07-31 09:00:55.607347:我tensorflow / core / common_runtime / gpu / gpu_device.cc:952]具有强度1边缘矩阵的设备互连StreamExecutor: 2018-07-31 09:00:55.607374:我tensorflow / core / common_runtime / gpu / gpu_device.cc:958] 0 2018-07-31 09:00:55.607379:I tensorflow / core / common_runtime / gpu / gpu_device.cc:971] 0:N 2018-07-31 09:00:55.607568:我tensorflow / core / common_runtime / gpu / gpu_device.cc:1084]创建了TensorFlow设备(/ job:localhost /副本:0 /任务:0 /设备:GPU:0与9965 MB内存)->物理GPU(设备:0,名称:GeForce GTX 1080 Ti,pci总线ID:0000:07:00.0,计算能力:6.1)


示例4

CPU:16核3.4 ghz AMD Threadripper

Tensorflow:1.9.0由具有CUDA支持的源构建

设备:“ / gpu:0”

结果:〜230-340步/秒

GPU现在已启用,并且速度甚至更慢。根据nvidia-smi的数据,GPU使用率大多数时候仍徘徊在2-4%左右。

这是实际的代码

import tensorflow as tf
from tensorflow.python.estimator import estimator
from tensorflow.python.estimator.canned.linear import LinearClassifier
from tensorflow.python.training.ftrl import FtrlOptimizer
from tensorflow.python.training.session_run_hook import SessionRunHook, SessionRunArgs
from tensorflow.python.training.basic_session_run_hooks import SecondOrStepTimer

device_name = "/cpu:0"

def train():

    tf.logging.set_verbosity(tf.logging.INFO)


    with tf.device(device_name):

        train_input_fn = create_train_input_function(
            train_tf_records_filename="train.tfrecords",
            batch_size=128,
            shuffle_while_training=True,
            shuffle_buffer_size=1000,
            train_epochs=10000,
            device_name=device_name
        )


        eval_input_fn = create_eval_input_function(
            eval_tf_records_filename="eval.tfrecords",
            device_name=device_name
        )

        estimator = LinearClassifier(

            config = tf.estimator.RunConfig(
                save_checkpoints_secs=360,
                model_dir="model",
                session_config=tf.ConfigProto(
                    log_device_placement=False,
                    allow_soft_placement=False,
                )
            ),
            optimizer=FtrlOptimizer(
                learning_rate= 0.001,
                l1_regularization_strength= 0.001,
                l2_regularization_strength= 0.001
            ),

            feature_columns=[
                tf.feature_column.numeric_column("projectedPoints")
            ]
        )


        train_spec = tf.estimator.TrainSpec(
            input_fn=train_input_fn,
            max_steps=100000000
        )

        eval_spec = tf.estimator.EvalSpec(
            input_fn=eval_input_fn,
            throttle_secs=1000,
            start_delay_secs=1000
        )

        tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)


def parser(serialized_example):
    features = {}

    features['pickTier'] = tf.FixedLenFeature([], tf.int64)
    features['projectedPoints'] = tf.FixedLenFeature([], tf.float32)


    parsed_example = tf.parse_single_example(
        serialized_example,
        features=features)


    label = parsed_example["pickTier"]

    # Remove label
    parsed_example.pop("pickTier", None)


    return parsed_example, label




def create_train_input_function(train_tf_records_filename=None, batch_size=None, shuffle_while_training=None, shuffle_buffer_size=None, train_epochs=None, device_name=None):

    def train_input_fn():

        # with tf.device("/cpu:0"):
        filenames = [train_tf_records_filename]

        dataset = tf.data.TFRecordDataset(filenames, compression_type='GZIP')

        def the_parser(serialized_example):
            return parser(serialized_example)

        # Map the parser over dataset, and batch results by up to batch_size
        dataset = dataset.map(the_parser)
        dataset = dataset.batch(batch_size)
        dataset = dataset.repeat(train_epochs)

        if shuffle_while_training:
            dataset = dataset.shuffle(buffer_size=shuffle_buffer_size)


        dataset = dataset.apply(
            tf.contrib.data.prefetch_to_device(
                device_name
            )
        )

        iterator = dataset.make_one_shot_iterator()

        features, labels = iterator.get_next()

        return features, labels

    return train_input_fn


def create_eval_input_function(eval_tf_records_filename, device_name):

    def eval_input_fn():

        # with tf.device("/cpu:0"):

        filenames = [eval_tf_records_filename]
        dataset = tf.data.TFRecordDataset(filenames, compression_type='GZIP')

        def the_parser(serialized_example):
            return parser(serialized_example)


        dataset = dataset.map(the_parser)
        dataset = dataset.batch(18814)

        iterator = dataset.make_one_shot_iterator()

        features, labels = iterator.get_next()

        return features, labels

    return eval_input_fn


train()

0 个答案:

没有答案