TPU медленнее GPU?

Я просто пробовал использовать TPU в Google Colab и хочу посмотреть, насколько TPU быстрее GPU. Я получил на удивление противоположный результат.

Ниже приводится NN.

  random_image = tf.random_normal((100, 100, 100, 3))
  result = tf.layers.conv2d(random_image, 32, 7)
  result = tf.reduce_sum(result)

Результаты работы:

CPU: 8s
GPU: 0.18s
TPU: 0.50s

Интересно, почему .... Полный код TPU выглядит следующим образом:

def calc():
  random_image = tf.random_normal((100, 100, 100, 3))
  result = tf.layers.conv2d(random_image, 32, 7)
  result = tf.reduce_sum(result)
  return result

tpu_ops = tf.contrib.tpu.batch_parallel(calc, [], num_shards=8)

session = tf.Session(tpu_address)
try:
  print('Initializing global variables...')
  session.run(tf.global_variables_initializer())
  print('Warming up...')
  session.run(tf.contrib.tpu.initialize_system())
  print('Profiling')
  start = time.time()
  session.run(tpu_ops)
  end = time.time()
  elapsed = end - start
  print(elapsed)
finally:
  session.run(tf.contrib.tpu.shutdown_system())
  session.close()

person fatdragon    schedule 30.09.2018    source источник
comment
Я подозреваю, что этого недостаточно для полноценного использования TPU. Вы можете попробовать настроить микробенчмарк в примере записной книжки: colab.research.google .com / notebooks /   -  person Bob Smith    schedule 30.09.2018
comment
Вот как я адаптировался к приведенному выше образцу кода ... хотя сначала я обнаружил проблему с примером MNIST (который занимает около 0,8 с / 100 шагов для графического процессора, но 2,2 с / 100 шагов для TPU). Я подозреваю, что для его использования необходимо написать некоторый код, специфичный для TPU ... github.com/tensorflow/tensorflow/tree/master/tensorflow/   -  person fatdragon    schedule 30.09.2018
comment
Да, вам нужно накачать 100 МБ и зациклить несколько раз, чтобы увидеть разницу. Но он намного быстрее и важнее, он масштабируется с помощью того же кода. вам просто нужно установить переход с 1 TPU на N TPU. С GPU после 8 вам нужно начать делать хоровд и кластер, изменить настройку и ...   -  person fabrizioM    schedule 28.05.2020


Ответы (1)


Трудно правильно провести сравнительный анализ устройств, поэтому, пожалуйста, относитесь ко всему, что вы узнаете из этих примеров, с недоверием. В общем, лучше сравнивать конкретные модели, которые вас интересуют (например, работающие в сети ImageNet), чтобы понять различия в производительности. Тем не менее, я понимаю, что это весело, так что ...

Более крупные модели лучше проиллюстрируют производительность TPU и GPU. Ваш пример также включает время компиляции в стоимость вызова TPU: каждый вызов после первого для данной программы и формы будет кэширован, поэтому вам нужно tpu_ops один раз перед запуском таймера, если вы не хотите фиксировать время компиляции .

В настоящее время каждый вызов функции TPU копирует веса в TPU, прежде чем он сможет начать работу, что более существенно влияет на небольшие операции. Вот пример, который запускает цикл на TPU перед возвратом к процессору со следующими выходными данными.

  • 1 0.010800600051879883
  • 10 0.09931182861328125
  • 100 0.5581905841827393
  • 500 2.7688047885894775

. Таким образом, вы можете запустить 100 итераций этой функции за 0,55 с.

import os
import time
import tensorflow as tf

def calc(n):
  img = tf.random_normal((128, 100, 100, 3))
  def body(_):
    result = tf.layers.conv2d(img, 32, 7)
    result = tf.reduce_sum(result)
    return result

  return tf.contrib.tpu.repeat(n[0], body, [0.0])


session = tf.Session('grpc://' + os.environ['COLAB_TPU_ADDR'])
try:
  print('Initializing TPU...')
  session.run(tf.contrib.tpu.initialize_system())

  for i in [1, 10, 100, 500]:
    tpu_ops = tf.contrib.tpu.batch_parallel(calc, [[i] * 8], num_shards=8)
    print('Warming up...')
    session.run(tf.global_variables_initializer())
    session.run(tpu_ops)
    print('Profiling')
    start = time.time()
    session.run(tpu_ops)
    end = time.time()
    elapsed = end - start
    print(i, elapsed)
finally:
  session.run(tf.contrib.tpu.shutdown_system())
  session.close()
person Russell Power    schedule 01.10.2018