2017-08-01 2 views
2

Ich habe einen Datensatz, der auf der CPU auf der Fliege generiert wird. Samples werden in Python durch eine Funktion make_sample berechnet, die ziemlich komplex ist und kann nicht in Tensorflow ops übersetzt werden. Da die Erstellung von Beispielen zeitraubend ist, möchte ich die Funktion aus mehreren Threads aufrufen, um eine Eingabewarteschlange zu füllen.Tensorflow langsamer bei Verwendung mehrerer Threads während der Vorverarbeitung auf der CPU

begann ich aus dem example given in the documentation und kam zu folgendem Spielzeug Beispiel:

import numpy as np 
import tensorflow as tf 
import time 

def make_sample(): 
    # something that takes time and needs to be on CPU w/o tf ops 
    p = 1 
    for n in range(1000000): 
    p = (p + np.random.random()) * np.random.random() 
    return np.float32(p) 

read_threads = 1 

with tf.device('/cpu:0'): 
    example_list = [tf.py_func(make_sample, [], [tf.float32]) for _ in range(read_threads)] 
    for ex in example_list: 
    ex[0].set_shape(()) 
    batch_size = 3 
    capacity = 30 
    batch = tf.train.batch_join(example_list, batch_size=batch_size, capacity=capacity) 

with tf.Session().as_default() as sess: 
    tf.global_variables_initializer().run() 
    coord = tf.train.Coordinator() 
    threads = tf.train.start_queue_runners(sess=sess, coord=coord) 
    try: 
    # dry run, left out of timing 
    sess.run(batch) 
    start_time = time.time() 
    for it in range(5): 
     print(sess.run(batch)) 
    finally: 
    duration = time.time() - start_time 
    print('duration: {0:4.2f}s'.format(duration)) 
    coord.request_stop() 
    coord.join(threads) 

Was mich wundert ist, dass, wenn read_threads zunimmt, nie die CPU-Auslastung von über 50% hinausgeht. Was noch schlimmer ist, die Rechenzeit sinkt: auf meinem Computer,

  • read_threads=1duration: 12s
  • read_threads=2duration: 46s
  • read_threads=4duration: 68s
  • read_threads=8duration: 112s

Gibt es eine Erklärung, und vor allem eine Lösung, um einen effizienten Multithr zu erhalten eaded Datengenerierung mit benutzerdefinierten Python-Funktion auf Tensorflow?

Antwort

2

tf.py_func wiederverwendet vorhandenen Python-Interpreter. Leider unterstützt Python Nebenläufigkeit, aber keine Parallelität. Mit anderen Worten, Sie können mehrere Python-Threads haben, aber nur einer kann Python-Code jederzeit ausführen. Standardlösungen bestehen darin, die Generierungspipeline in TensorFlow/C++ zu verschieben oder mehrere Python-Prozesse und eine zusätzliche Ebene zum Aggregieren ihrer Ergebnisse zu verwenden (dh die Ergebnisse mehrerer Python-Prozesse mithilfe von ZMQ zu aggregieren)

Verwandte Themen