gpt4 book ai didi

python - 使用 tf.Estimator 创建的 tensorflow 服务的图形优化

转载 作者:太空狗 更新时间:2023-10-29 17:51:33 31 4
gpt4 key购买 nike

语境 :

我有一个基于 tf.estimator.DNNClassifier 的简单分类器它通过意图标签获取文本和输出概率。我能够使用 tensorflow serving 训练将模型导出到可服务对象以及服务可服务对象.问题是这个 servable 太大(大约 1GB),所以我想尝试一些 tensorflow graph transforms尝试减小所提供文件的大小。

问题 :

我明白怎么拿saved_model.pb并使用 freeze_model.py新建.pb可用于调用转换的文件。这些转换的结果(也是 .pb 文件)不是可服务的,不能与 tensorflow 服务一起使用。

开发人员如何从:

saved model -> graph transforms -> back to a servable

documentation这表明这当然是可能的,但从文档来看如何做到这一点一点也不直观。

我试过的 :
import tensorflow as tf

from tensorflow.saved_model import simple_save
from tensorflow.saved_model import signature_constants
from tensorflow.saved_model import tag_constants
from tensorflow.tools.graph_transforms import TransformGraph


with tf.Session(graph=tf.Graph()) as sess_meta:
meta_graph_def = tf.saved_model.loader.load(
sess_meta,
[tag_constants.SERVING],
"/model/path")

graph_def = meta_graph_def.graph_def

other_graph_def = TransformGraph(
graph_def,
["Placeholder"],
["dnn/head/predictions/probabilities"],
["quantize_weights"])


with tf.Graph().as_default():
graph = tf.get_default_graph()
tf.import_graph_def(other_graph_def)
in_tensor = graph.get_tensor_by_name(
"import/Placeholder:0")
out_tensor = graph.get_tensor_by_name(
"import/dnn/head/predictions/probabilities:0")

inputs = {"inputs": in_tensor}
outputs = {"outputs": out_tensor}

simple_save(sess_meta, "./new", inputs, outputs)

我的想法是加载 servable,从 meta_graph_def 中提取 graph_def,转换 graph_def,然后尝试重新创建 servable。这似乎是不正确的方法。

有没有办法从导出的 servable 对图形成功执行转换(以减少推理时的文件大小),然后使用转换后的图形重新创建 servable?

谢谢。

更新 (2018-08-28) :

找到 contrib.meta_graph_transform()这看起来很有希望。

更新 (2018-12-03) :

一个相关的 github issue我打开了似乎在票证末尾列出的详细博客文章中解决的问题。

最佳答案

我们可以使用以下提到的方法优化或减小 Tensorflow 模型的大小:

  • 卡住:将保存在 SavedModel 的检查点文件中的变量转换为直接保存在模型图中的常量。这减小了模型的整体尺寸。
  • 修剪:去除预测路径中未使用的节点和图的输出,合并重复节点,以及清理其他节点操作,如摘要、身份等。
  • 常量折叠:在模型中查找总是计算为常量表达式的任何子图,并将它们替换为这些常量。折叠批规范:将批归一化中引入的乘法折叠到前一层的权重乘法中。
  • 量化:将权重从浮点数转换为较低的精度,例如 16 位或 8 位。

  • 下面提到了卡住图形的代码:
    from tensorflow.python.tools import freeze_graph

    output_graph_filename = os.path.join(saved_model_dir, output_filename)
    initializer_nodes = ''

    freeze_graph.freeze_graph(input_saved_model_dir=saved_model_dir,
    output_graph=output_graph_filename,
    saved_model_tags = tag_constants.SERVING,
    output_node_names=output_node_names,initializer_nodes=initializer_nodes,
    input_graph=None, input_saver=False, input_binary=False,
    input_checkpoint=None, restore_op_name=None, filename_tensor_name=None,
    clear_devices=False, input_meta_graph=False)

    下面提到了修剪和恒定折叠的代码:
    from tensorflow.tools.graph_transforms import TransformGraph

    def get_graph_def_from_file(graph_filepath):
    with ops.Graph().as_default():
    with tf.gfile.GFile(graph_filepath, 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
    return graph_def

    def optimize_graph(model_dir, graph_filename, transforms, output_node):
    input_names = []
    output_names = [output_node]
    if graph_filename is None:
    graph_def = get_graph_def_from_saved_model(model_dir)
    else:
    graph_def = get_graph_def_from_file(os.path.join(model_dir,
    graph_filename))
    optimized_graph_def = TransformGraph(graph_def, input_names,
    output_names, transforms)
    tf.train.write_graph(optimized_graph_def, logdir=model_dir, as_text=False,
    name='optimized_model.pb')
    print('Graph optimized!')

    我们通过传递所需优化的列表来调用模型上的代码,如下所示:
    transforms = ['remove_nodes(op=Identity)', 'merge_duplicate_nodes',
    'strip_unused_nodes','fold_constants(ignore_errors=true)',
    'fold_batch_norms']

    optimize_graph(saved_model_dir, "frozen_model.pb" , transforms, 'head/predictions/class_ids')

    量化代码如下:
    transforms = ['quantize_nodes', 'quantize_weights',]
    optimize_graph(saved_model_dir, None, transforms, 'head/predictions/class_ids')

    应用优化后,我们需要将优化图转换回 GraphDef。代码如下所示:
    def convert_graph_def_to_saved_model(export_dir, graph_filepath):
    if tf.gfile.Exists(export_dir):
    tf.gfile.DeleteRecursively(export_dir)
    graph_def = get_graph_def_from_file(graph_filepath)
    with tf.Session(graph=tf.Graph()) as session:
    tf.import_graph_def(graph_def, name='')
    tf.saved_model.simple_save(
    session,
    export_dir,
    inputs={
    node.name: session.graph.get_tensor_by_name(
    '{}:0'.format(node.name))
    for node in graph_def.node if node.op=='Placeholder'},
    outputs={'class_ids': session.graph.get_tensor_by_name(
    'head/predictions/class_ids:0')}
    )
    print('Optimized graph converted to SavedModel!')

    示例代码如下所示:
    optimized_export_dir = os.path.join(export_dir, 'optimized')
    optimized_filepath = os.path.join(saved_model_dir, 'optimized_model.pb')
    convert_graph_def_to_saved_model(optimized_export_dir, optimized_filepath)

    有关更多信息,请参阅@gobrewers14 提到的以下链接:

    https://medium.com/google-cloud/optimizing-tensorflow-models-for-serving-959080e9ddbf

    关于python - 使用 tf.Estimator 创建的 tensorflow 服务的图形优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51971050/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com