我使用TensorFlow创建了一个统计估算器。我遵循了sklearn的估算器,因此我有一个可以打包所有内容的类,包括导入Tensorflow和启动TF的会话(如果我在该类之外导入TF,则根本无法并行工作)。
我需要对随机数据多次运行该估计器以查看经验分布,因此我正在使用joblib并行化创建数据,创建估计器对象和对数据运行估计的代码。
我正在使用具有64核(和足够的内存)的linux服务器,在其中运行的工作要比此还要大得多,同时也使用joblib。但是,当我尝试运行基于TF的代码时,我只能运行8个进程。如果我尝试使用9,则top
中仅显示8,当完成8后,joblib将永远不会再发送8,也永远不会返回,否则会返回以下错误消息
“ BrokenProcessPool:执行程序中的进程突然终止 当未来正在运行或等待时。”
如果我将进程限制为8,则一切正常。 我尝试将joblib的后端更改为dask.parallel,并且我有相同的行为。我从后端获得了更多信息,不断出现消息
“ distributed.nanny-警告-工作者进程7602被杀死 未知信号”
我希望能够运行8个以上的进程。 问题是:这是一个硬限制,还是可以通过TF参数更改它?我能以任何方式解决这个问题吗?我认为局限性是与Tensorflow相关的,因为一旦运行了8个进程(它们需要几个小时),我就无法在该计算机上运行Tensorflow上的其他任何东西。
感谢您的帮助!
以下代码重现该错误:
from sklearn.base import TransformerMixin
import numpy as np
from joblib import Parallel, delayed
class MyEstimator(TransformerMixin):
def __init__(self):
import tensorflow as tf
self._tf = tf
self._graph = tf.Graph()
with self._graph.as_default():
self.session = self._tf.Session()
A0 = np.eye(10, 2)
self.a_var = a_var = tf.Variable(A0, name='a_var', dtype=tf.float64)
self._x = x = tf.placeholder(dtype=tf.float64)
self._y = y= tf.placeholder(dtype=tf.float64)
w = tf.tensordot(a_var, x, axes=0)
self.f = tf.reduce_mean((y-w)**2)
def fit(self, x, y):
#self.session.run(
# self._tf.global_variables_initializer())
self._f = self.session.run(self.f, feed_dict={self._x:x, self._y: y, self.a_var:np.eye(10, 2)})
return self
def run_estimator():
my_est = MyEstimator()
x = np.random.normal(0,1,10)
y = np.random.normal(0,1,10)
my_est.fit(x,y)
Parallel(n_jobs=16)(delayed(run_estimator)() for _ in range(16))
我正在使用Linux,Python 3.6.3,TensorFlow 1.7.0,joblib 0.12。
答案 0 :(得分:0)
几个月后,我找到了一个TensorFlow服务器https://www.tensorflow.org/deploy/distributed
的解决方案from sklearn.base import TransformerMixin
import numpy as np
from joblib import Parallel, delayed
class MyEstimator(TransformerMixin):
def __init__(self, target):
import tensorflow as tf
self._tf = tf
self._graph = tf.Graph()
with self._graph.as_default():
config = self._tf.ConfigProto(
intra_op_parallelism_threads=1,
inter_op_parallelism_threads=1,
device_count={"CPU":4},
use_per_session_threads=True)
config.graph_options.optimizer_options.global_jit_level = tf.OptimizerOptions.ON_1
pool = config.session_inter_op_thread_pool.add()
pool.num_threads = 1
self.session = self._tf.Session(target)
A0 = np.eye(10, 2)
self.a_var = a_var = tf.Variable(A0, name='a_var', dtype=tf.float64)
self._x = x = tf.placeholder(dtype=tf.float64)
self._y = y= tf.placeholder(dtype=tf.float64)
w = tf.tensordot(a_var, x, axes=0)
self.f = tf.reduce_mean((y-w)**2)
def fit(self, x, y):
#self.session.run(
# self._tf.global_variables_initializer())
self._f = self.session.run(self.f, feed_dict={self._x:x, self._y: y, self.a_var:np.eye(10, 2)})
return self
def run_estimator(target):
my_est = MyEstimator(target)
x = np.random.normal(0,1,10)
y = np.random.normal(0,1,10)
my_est.fit(x,y)
return 1
import tensorflow as tf
server = tf.train.Server.create_local_server()
Parallel(n_jobs=16)(delayed(run_estimator)(server.target) for _ in range(16))