Я пытаюсь ограничить количество ядер, используемых при вычислении вывода модели keras, при использовании TensorFlow в качестве бэкэнда.Решение этой проблемы, например, представлено здесь:
Предельное количество ядер, используемых в Keras
Однако в моем случае есть дополнительное осложнение.Мне нужно вычислить вывод модели в программе на С ++, для которой я сейчас использую boost :: python.Соответствующий код c ++ можно обобщить следующим образом:
Py_Initialize();
//set python path
PyObject* sysPath = PySys_GetObject("path");
PyList_Insert( sysPath, 0, PyString_FromString("./python"));
//import python module
pythonModule = python::import("kerasPredict");
kerasModel = pythonModule.attr("kerasModel")(modelName); //I pass the name of the model here
predictRoutine = kerasModel.attr("predict");
...
Py_Finalize();
Импортированный код Python выглядит следующим образом:
import numpy as np
from keras import models
from keras import backend as K
def tensorFlowSetNumThreads( num_threads ):
K.set_session(K.tf.Session(config=K.tf.ConfigProto(intra_op_parallelism_threads = num_threads, inter_op_parallelism_threads = num_threads ) ) )
class kerasModel():
def __init__(self, file_name):
self.model = models.load_model( file_name )
#return model prediction given a list of inputs
def predict( self, x ):
x = np.asarray(x, dtype=float)
x = x.reshape( (1, len(x)) )
return float( self.model.predict(x) )
Вызов predictRoutine
в c ++ прекрасно работает для вычисления вывода модели,но использует все ядра, доступные на данном компьютере.Я должен иметь возможность запускать этот код в кластере со многими многоядерными машинами, где мои задания могут использовать только одно ядро.Поэтому мне нужно ограничить число ядер, которые использует процесс, для которых я намеревался использовать функцию tensorFlowSetNumThreads
, которую я определил выше.При вызове этой функции в python она делает то, что ожидается, устанавливая количество ядер, которое используется при вычислении вывода модели на указанное число.Однако вызов его через boost :: python вызывает следующую общую ошибку:
boost :: python :: error_already_set
Это происходит при использовании функции в c ++ какследует:
python::object setNCores = pythonModule.attr("tensorFlowSetNumThreads");
try{
setNCores( 1 );
} catch(...){
PyErr_Print();
}
или просто добавив его в класс python в функции __init__
:
def __init__(self, file_name):
tensorFlowSetNumThreads(1)
self.model = models.load_model( file_name )
, и даже с блоком try-catch, показанным выше, он не справляетсяраспечатать любое другое сообщение об ошибке, отличное от «boost :: python :: error_already_set».
Кто-нибудь знает, как ограничить число потоков, используемых предсказанием модели в Keras при вызове его через boost :: python, либо с помощью подхода, аналогичного тому, который я пробовал выше, либо альтернативного?