bat*_*uzz 7 python performance keras tensorflow
我正在使用tensorflow,我想通过同时使用CPU和一个GPU 来加速预训练的Keras模型的预测阶段(我对训练阶段不感兴趣).
我尝试创建2个不同的线程,这些线程提供两个不同的tensorflow会话(一个在CPU上运行,另一个在GPU上运行).每个线程提供固定数量的批次(例如,如果我们总共有100个批次,我想在一个循环中为CPU分配20个批次,在GPU上分配80个,或者两者中任何可能的组合)并合并结果.如果拆分是自动完成的话会更好.
然而,即使在这种情况下,似乎批处理是以同步方式进行的,因为即使向CPU发送少量批次并计算GPU中的所有其他批次(以GPU作为瓶颈),我观察到整体预测时间是相对于仅使用GPU进行的测试,总是更高.
我希望它更快,因为当只有GPU工作时,CPU使用率约为20-30%,因此有一些CPU可用于加速计算.
我阅读了很多讨论,但它们都涉及多个GPU的并行性,而不是GPU和CPU之间的并行性.
以下是我编写的代码示例:以这种方式从同一个Keras模型加载tensor_cpu和tensor_gpu对象:
with tf.device('/gpu:0'):
model_gpu = load_model('model1.h5')
tensor_gpu = model_gpu(x)
with tf.device('/cpu:0'):
model_cpu = load_model('model1.h5')
tensor_cpu = model_cpu(x)
Run Code Online (Sandbox Code Playgroud)
然后预测完成如下:
def predict_on_device(session, predict_tensor, batches):
for batch in batches:
session.run(predict_tensor, feed_dict={x: batch})
def split_cpu_gpu(batches, num_batches_cpu, tensor_cpu, tensor_gpu):
session1 = tf.Session(config=tf.ConfigProto(log_device_placement=True))
session1.run(tf.global_variables_initializer())
session2 = tf.Session(config=tf.ConfigProto(log_device_placement=True))
session2.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
t_cpu = Thread(target=predict_on_device, args=(session1, tensor_cpu, batches[:num_batches_cpu]))
t_gpu = Thread(target=predict_on_device, args=(session2, tensor_gpu, batches[num_batches_cpu:]))
t_cpu.start()
t_gpu.start()
coord.join([t_cpu, t_gpu])
session1.close()
session2.close()
Run Code Online (Sandbox Code Playgroud)
如何实现CPU/GPU并行化?我想我错过了什么.
任何形式的帮助将非常感谢!
下面是我的代码,演示了如何并行执行 CPU 和 GPU:
import tensorflow as tf
import numpy as np
from time import time
from threading import Thread
n = 1024 * 8
data_cpu = np.random.uniform(size=[n//16, n]).astype(np.float32)
data_gpu = np.random.uniform(size=[n , n]).astype(np.float32)
with tf.device('/cpu:0'):
x = tf.placeholder(name='x', dtype=tf.float32)
def get_var(name):
return tf.get_variable(name, shape=[n, n])
def op(name):
w = get_var(name)
y = x
for _ in range(8):
y = tf.matmul(y, w)
return y
with tf.device('/cpu:0'):
cpu = op('w_cpu')
with tf.device('/gpu:0'):
gpu = op('w_gpu')
def f(session, y, data):
return session.run(y, feed_dict={x : data})
with tf.Session(config=tf.ConfigProto(log_device_placement=True, intra_op_parallelism_threads=8)) as sess:
sess.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
threads = []
# comment out 0 or 1 of the following 2 lines:
threads += [Thread(target=f, args=(sess, cpu, data_cpu))]
threads += [Thread(target=f, args=(sess, gpu, data_gpu))]
t0 = time()
for t in threads:
t.start()
coord.join(threads)
t1 = time()
print t1 - t0
Run Code Online (Sandbox Code Playgroud)
计时结果为:
CPU线程:4-5秒(当然,会因机器而异)。
GPU 线程:5 秒(工作量是原来的 16 倍)。
两者同时进行:5s
请注意,没有必要进行两次会议(但这对我也有用)。
您看到不同结果的原因可能是
对系统资源的一些争用(GPU 执行确实会消耗一些主机系统资源,如果运行 CPU 线程使其拥挤,可能会降低性能)
时间不正确
你的模型的一部分只能在 GPU/CPU 上运行
其他地方的瓶颈
其他一些问题
| 归档时间: |
|
| 查看次数: |
4809 次 |
| 最近记录: |