Тензор потока данных параллелизм |Multi-GPU только один имеет ненулевое использование - PullRequest
0 голосов
/ 27 июня 2019

Я выполнил версию word2vec для нескольких графических процессоров, и я применил log_device_placement в коде, который показывает, что некоторые операции были применены к множественному графическому процессору:

2019-06-27 00: 32: 34.536178: I tensorflow / ядро ​​/ common_runtime / placer.cc: 874] optimizer_7 / градиенты / loss_7 / sampled_losses / Log1p_grad / добавить / х: (Const) / работа: локальный / реплика: 0 / задача: 0 / Устройство: ГПУ: 7 оптимизатор_6 / градиенты / потери_6 / sampled_losses / Log1p_grad / add / x: (Const): / job: localhost / реплика: 0 / task: 0 / device: GPU: 6 2019-06-27 00: 32: 34.536188: I tenorflow / core / common_runtime / placer.cc: 874] optimizer_6 / градиенты / loss_6 / sampled_losses / Log1p_grad / добавить / х: (Const) / работа: локальный / реплика: 0 / задача: 0 / Устройство: ГПУ: 6 оптимизатор_5 / градиенты / потери_5 / выборки_losses / Log1p_grad / add / x: (Const): / job: localhost / реплика: 0 / task: 0 / device: GPU: 5 2019-06-27 00: 32: 34.536202: I tenorflow / core / common_runtime / placer.cc: 874] optimizer_5 / градиенты / loss_5 / sampled_losses / Log1p_grad / добавить / х: (Const) / работа: локальный / реплика: 0 / задача: 0 / Устройство: ГПУ: 5 оптимизатор_4 / градиенты / потери_4 / sampled_losses / Log1p_grad / add / x: (Const): / job: localhost / реплика: 0 / task: 0 / device: GPU: 4 2019-06-27 00: 32: 34.536216: I tenorflow / core / common_runtime / placer.cc: 874] optimizer_4 / градиенты / loss_4 / sampled_losses / Log1p_grad / добавить / х: (Const) / работа: локальный / реплика: 0 / задача: 0 / Устройство: ГПУ: 4 оптимизатор_3 / градиенты / потери_3 / sampled_losses / Log1p_grad / add / x: (Const): / job: localhost / реплика: 0 / task: 0 / device: GPU: 3 2019-06-27 00: 32: 34.536231: I tenorflow / core / common_runtime / placer.cc: 874] optimizer_3 / градиенты / loss_3 / sampled_losses / Log1p_grad / добавить / х: (Const) / работа: локальный / реплика: 0 / задача: 0 / Устройство: ГПУ: 3 оптимизатор_2 / градиенты / потери_2 / сэмплированные_лосы / Log1p_grad / add / x: (Const): / job: localhost / реплика: 0 / task: 0 / device: GPU: 2 2019-06-27 00: 32: 34.536246: I tenorflow / core / common_runtime / placer.cc: 874] optimizer_2 / градиенты / loss_2 / sampled_losses / Log1p_grad / добавить / х: (Const) / работа: локальный / реплика: 0 / задача: 0 / Устройство: ГПУ: 2 оптимизатор_1 / градиенты / потери_1 / sampled_losses / Log1p_grad / add / x: (Const): / job: localhost / реплика: 0 / task: 0 / device: GPU: 1 2019-06-27 00: 32: 34.536273: I tenorflow / core / common_runtime / placer.cc: 874] optimizer_1 / градиенты / loss_1 / sampled_losses / Log1p_grad / добавить / х: (Const) / работа: локальный / реплика: 0 / задача: 0 / Устройство: ГПУ: 1 оптимизатор / градиенты / потери / sampled_losses / Log1p_grad / add / x: (Const): / job: localhost / реплика: 0 / task: 0 / device: GPU: 0 2019-06-27 00: 32: 34.536288: I tenorflow / core / common_runtime / placer.cc: 874] Оптимизатор / градиенты / потеря / sampled_losses / Log1p_grad / добавить / х: (Const) / job: localhost / replica: 0 / task: 0 / device: GPU: 0 ......

Но nvidia-smi показывает только одну работу графического процессора в то время:

+ ---------------------------------------------- ------------------------------- + | NVIDIA-SMI 396.44 Версия драйвера: 396.44 | | ------------------------------- + ----------------- ----- + ---------------------- + | Название графического процессора Персистент-М | Bus-Id Disp.A | Летучий Uncorr. ECC | | Поклонник Temp Perf Pwr: Использование / Cap | Использование памяти | GPU-Util Compute M. | | =============================== + ================= ===== + ====================== | | 0 GeForce GTX 108 ... Off | 00000000: 04: 00.0 Выкл. | N / A | | 36% 49C P2 80 Вт / 250 Вт | 10882MiB / 11178MiB | 26% по умолчанию | + ------------------------------- + ----------------- ----- + ---------------------- + | 1 GeForce GTX 108 ... Off | 00000000: 06: 00.0 выкл. | N / A | | 29% 39C P2 56 Вт / 250 Вт | 10631MiB / 11178MiB | 0% по умолчанию | + ------------------------------- + ----------------- ----- + ---------------------- + | 2 GeForce GTX 108 ... Off | 00000000: 07: 00.0 выкл. | N / A | | 29% 36C P2 54 Вт / 250 Вт | 10631MiB / 11178MiB | 0% по умолчанию | + ------------------------------- + ----------------- ----- + ---------------------- + | 3 GeForce GTX 108 ... Off | 00000000: 08: 00.0 Выкл. | N / A | | 29% 38C P2 55 Вт / 250 Вт | 10631MiB / 11178MiB | 0% по умолчанию |+ ------------------------------- + ---------------------- + ---------------------- + |4 GeForce GTX 108 ... Off |00000000: 0C: 00.0 Выкл. |N / A ||29% 38C P2 55 Вт / 250 Вт |10631MiB / 11178MiB |0% по умолчанию |+ ------------------------------- + ---------------------- + ---------------------- + |5 GeForce GTX 108 ... Off |00000000: 0D: 00.0 Выкл. |N / A ||29% 33C P2 55 Вт / 250 Вт |10631MiB / 11178MiB |0% по умолчанию |+ ------------------------------- + ---------------------- + ---------------------- + |6 GeForce GTX 108 ... Off |00000000: 0E: 00.0 Выкл. |N / A ||29% 37C P2 55 Вт / 250 Вт |10631MiB / 11178MiB |0% по умолчанию |+ ------------------------------- + ---------------------- + ---------------------- + |7 GeForce GTX 108 ... Off |00000000: 0F: 00.0 Выкл. |N / A ||29% 36C P2 54 Вт / 250 Вт |10663MiB / 11178MiB |6% по умолчанию |+ ------------------------------- + ---------------------- + ---------------------- +

+ ----------------------------------------------------------------------------- + |Процессы: Память GPU ||GPU PID Тип Имя процесса Использование || ============================================================================= ||0 38130 C python 8987MiB ||1 38130 C python 10621MiB ||2 38130 C python 10621MiB ||3 38130 C python 10621MiB ||4 38130 C python 10621MiB ||5 38130 C python 10621MiB ||6 38130 C python 10621MiB ||7 38130 C python 10653MiB |+ ----------------------------------------------------------------------------- + `

Я прилагаю свой исходный код здесь:

...
with tf.name_scope('inputs'):
train_inputs = tf.placeholder(tf.int32, shape=[batch_size])
train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])

    upper = 4
    for i in range(0,upper):
        with tf.device(tf.DeviceSpec(device_type="GPU", device_index=i)):
            data_size = batch_size / upper
            data_size = int(data_size)
            print(data_size)
            _train_inputs = train_inputs[i * data_size : (i + 1) * data_size]
            _train_labels = train_labels[i * data_size : (i + 1) * data_size]


            with tf.name_scope('embeddings'):
                if prev_emb_model == '0': 
                    embeddings = tf.Variable(
                        tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
                else:
                    add_on_emb = tf.random_uniform([vocabulary_size - len(emb), embedding_size], -1.0, 1.0)
                    embeddings = tf.concat([emb, add_on_emb], 0)
                embed = tf.nn.embedding_lookup(embeddings, _train_inputs)

            # Construct the variables for the NCE loss
            with tf.name_scope('weights'):
                nce_weights = tf.Variable(
                    tf.truncated_normal([vocabulary_size, embedding_size],
                                        stddev=1.0 / math.sqrt(embedding_size)))
            with tf.name_scope('biases'):
                nce_biases = tf.Variable(tf.zeros([vocabulary_size]))

                # Compute the average NCE loss for the batch.
            # tf.nce_loss automatically draws a new sample of the negative labels each
            # time we evaluate the loss.
            # Explanation of the meaning of NCE loss:
            #   http://mccormickml.com/2016/04/19/waord2vec-tutorial-the-skip-gram-model/

            # with tf.device(tf.DeviceSpec(device_type="GPU", device_index=0)):
            with tf.name_scope('loss'):
                loss = tf.reduce_mean(
                    tf.nn.nce_loss(
                        weights=nce_weights,
                        biases=nce_biases,
                        labels=_train_labels,
                        inputs=embed,
                        num_sampled=num_sampled,
                        num_classes=vocabulary_size))


            # Construct the SGD optimizer using a learning rate of 1.0.
            with tf.name_scope('optimizer'):
                optimizer = tf.train.GradientDescentOptimizer(
                    1.0).minimize(loss, colocate_gradients_with_ops=True)


    # Compute the cosine similarity between minibatch examples and all
    # embeddings.
    norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keepdims=True))
    normalized_embeddings = embeddings / norm

    # Add variable initializer.
    init = tf.global_variables_initializer()


config = tf.ConfigProto(allow_soft_placement=True,log_device_placement=True)
# config.gpu_options.allow_growth = True
with tf.Session(graph=graph, config=config) as session:

    #  We must initialize all variables before we use them.
    init.run()
    print('Initialized')
    average_loss = 0

    walks_data = []
    for w in walks:
        for n in w: 
            walks_data.append(n)

    for step in range(args.iter):
        print(step)

        batch_inputs, batch_labels = generate_batch(batch_size, 1,
                                                    window_size, walks_data)

        feed_dict = {train_inputs: batch_inputs, train_labels: batch_labels}


        _, loss_val = session.run([optimizer, loss],
                                            feed_dict=feed_dict,
                                            run_metadata=run_metadata)
        average_loss += loss_val

        if step % 2000 == 0:
        ...

    final_embeddings = normalized_embeddings.eval()
...