У меня есть модель тензорного потока с несколькими входами и несколькими слоями, а также последний слой Softmax. Модель обучается на Python (с использованием фреймворка Keras), затем сохраняется и вывод осуществляется с помощью программы на C ++, которая облегчает сборку CMake TensorFlow (следуя в основном этим инструкциям: https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/cmake).
В python (tenorflow-gpu) все операторы используют графический процессор (используя log_device_placement
):
out/MatMul: (MatMul): /job:localhost/replica:0/task:0/gpu:0
2017-12-04 14:07:38.005837: I C:\tf_jenkins\home\workspace\rel-in\M\windows-gpu\PY\35\tensorflow\core\common_runtime\simple_placer.cc:872] out/MatMul: (MatMul)/job:localhost/replica:0/task:0/gpu:0
out/BiasAdd: (BiasAdd): /job:localhost/replica:0/task:0/gpu:0
2017-12-04 14:07:38.006201: I C:\tf_jenkins\home\workspace\rel-win\M\windows-gpu\PY\35\tensorflow\core\common_runtime\simple_placer.cc:872]
out/BiasAdd: (BiasAdd)/job:localhost/replica:0/task:0/gpu:0
out/Softmax: (Softmax): /job:localhost/replica:0/task:0/gpu:0
2017-12-04 14:07:38.006535: I C:\tf_jenkins\home\workspace\rel-win\M\windows-gpu\PY\35\tensorflow\core\common_runtime\simple_placer.cc:872] out/Softmax: (Softmax)/job:localhost/replica:0/task:0/gpu:0
Чтобы сохранить график, freeze_graph
используется скрипт (скрипт, создающий журнал выше, загружает снова замороженный граф в формате .pb).
Когда я использую программу C ++ и загружаю замороженный граф (внимательно следя за LoadGraph()
функция в https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/label_image/main.cc — ReadBinaryProto()
а также session->Create()
), и снова регистрирую размещение устройств, я обнаружил, что Softmax размещен на CPU (все остальные операции на GPU):
dense_6/MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0
dense_6/BiasAdd: (BiasAdd): /job:localhost/replica:0/task:0/device:GPU:0
dense_6/Relu: (Relu): /job:localhost/replica:0/task:0/device:GPU:0
out/MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0
out/BiasAdd: (BiasAdd): /job:localhost/replica:0/task:0/device:GPU:0
out/Softmax: (Softmax): /job:localhost/replica:0/task:0/device:CPU:0
Такое размещение также подтверждается высокой загрузкой ЦП и низкой частотой графического процессора, а также очевидным при профилировании приложения. Тип данных out
слой float32
(out/Softmax -> (<tf.Tensor 'out/Softmax:0' shape=(?, 1418) dtype=float32>,)
).
Дальнейшее расследование выявило:
Cannot assign a device for operation 'tsoftmax': Could not satisfy explicit device specification '/device:GPU:0' because no supported kernel for GPU devices is available.
Вызов tensorflow::LogAllRegisteredKernels()
показал также, что Softmax доступен только для процессора!
Каталог сборки содержит много файлов, связанных с «softmax» (например, `tf_core_gpu_kernels_generated_softmax_op_gpu.cu.cc.obj.Release.cmake). Не знаю, как проверить каждый шаг компиляции.
когда я заглядываю в «tf_core_gpu_kernels.lib» (можно открыть .lib с помощью 7Z;)), появляются файлы типа «tf_core_gpu_kernels_generated_softmax_op_gpu.cu.cc.lib
«- так что я считаю, что нет ничего плохого в том, чтобы собрать сами ядра
Но: проверка «tenorflow.dll» (Dependency Walker) показывает, что включены только ядра ЦП для Softmax (есть такие функции, как const tensorflow::SoftmaxOp<struct Eigen::ThreadPoolDevice,double>
, но нет функций с графическим процессором, таких как const tensorflow::SoftplusGradOp<struct Eigen::GpuDevice,float>
).
Настройка: Tensorflow 1.3.0, Windows 10, GPU: NVidia GTX 1070 (8 ГБ ОЗУ, использование памяти также очень низкое).
Я нашел обходной путь — обходной путь должен включать tf_core_gpu_kernels.lib
в некоторых шагах (create_def_file.py
). Подробнее здесь: GitHub Issue 15254
Других решений пока нет …