python - 删除操作图 tensorflow 以在CPU上运行

标签 python tensorflow gpu

我已经训练了一个网络(使用 GPU),现在我想在 CPU 上运行它(用于推理)。为此,我使用以下代码加载元图,然后加载网络参数。

config = tf.ConfigProto(
        device_count = {'GPU': 0}
    )
sess = tf.Session(config=config)
meta_graph=".../graph-0207-190023.meta"
model=".../model.data-00000-of-00001"

new_saver = tf.train.import_meta_graph(meta_graph)
new_saver.restore(sess, model)

问题是,由于图是为训练而定义的,所以我使用了一些不在 CPU 上运行的特定操作。例如“MaxBytesInUse”https://www.tensorflow.org/api_docs/python/tf/contrib/memory_stats/MaxBytesInUse它记录 GPU 事件。

这就是为什么当我尝试运行此代码时,出现以下错误:

InvalidArgumentError: No OpKernel was registered to support Op 'MaxBytesInUse' with these attrs.  Registered devices: [CPU], Registered kernels:
  device='GPU'

     [[Node: PeakMemoryTracker/MaxBytesInUse = MaxBytesInUse[_device="/device:GPU:0"]()]]

有没有一种简单的方法可以删除特定的 GPU 相关操作并在 CPU 上运行图形?

最佳答案

我认为这样的事情应该可以解决你的问题

import tensorflow as tf

def remove_no_cpu_ops(graph_def):
    # Remove all ops that cannot run on the CPU
    removed = set()
    nodes = list(graph_def.node)
    for node in nodes:
        if not can_run_on_cpu(node):
            graph_def.node.remove(node)
            removed.add(node.name)
    # Recursively remove ops depending on removed ops
    while removed:
        removed, prev_removed = set(), removed
        nodes = list(graph_def.node)
        for node in graph_def.node:
            if any(inp in prev_removed for inp in node.input):
                graph_def.node.remove(node)
                removed.add(node.name)

def can_run_on_cpu(node):
    # Check if there is a CPU kernel for the node operation
    from tensorflow.python.framework import kernels
    for kernel in kernels.get_registered_kernels_for_op(node.op).kernel:
        if kernel.device_type == 'CPU':
            return True
    return False

config = tf.ConfigProto(
        device_count = {'GPU': 0}
    )
sess = tf.Session(config=config)
meta_graph = ".../graph-0207-190023.meta"
model = ".../model.data-00000-of-00001"
# Load metagraph definition
meta_graph_def = tf.MetaGraphDef()
with open(meta_graph, 'rb') as f:
    meta_graph_def.MergeFromString(f.read())
# Remove GPU ops
remove_no_cpu_ops(meta_graph_def.graph_def)
# Make saver from modified metagraph definition
new_saver = tf.train.import_meta_graph(meta_graph_def, clear_devices=True)
new_saver.restore(sess, model)

这个想法是迭代图形定义中的所有节点并删除那些没有 CPU 内核的节点。实际上,您可以通过检查是否存在适用于节点操作和输入类型的 CPU 内核、检查内核定义的 constraint 字段来使 can_run_on_cpu 更加准确,但这可能足以满足您的情况。我还在 tf.train.import_meta_graph 中添加了一个 clear_devices=True ,它会清除操作中的设备指令,强制它们在特定设备上运行(如果您有任何图表中的那些)。

关于python - 删除操作图 tensorflow 以在CPU上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54590442/

相关文章:

python - 使用 TensorFlow 重新规范化权重矩阵

python - Keras:使用 model.train_on_batch() 和 model.fit() 获得不同的精度。可能是什么原因以及如何解决?

python - Tensorflow:可以释放 GPU 资源的模型包装器

cuda - 计算 Cuda 内核中的寄存器/线程

python - 如何使用 Spacy 解析动词

python - 我如何线性搜索和比较两个 .text 文件以查看它们之间缺少什么?

python - 在循环的每次迭代中将函数作为 python 中的新进程运行

c++ - 通过对数组、OpenCL、交错寻址求和得出无效结果

F#/"Accelerator v2"DFT 算法实现可能不正确

python - subprocess.run : Is it safe to combine check=True with stdout=PIPE?