美文网首页程序员
在 tensorrtserver 中使用 saved_model

在 tensorrtserver 中使用 saved_model

作者: 孟浪之言 | 来源:发表于2019-09-30 12:49 被阅读0次

    1. 部署 tensorrtserver

    建议使用 docker 部署 tensorrtserver。docker 相关的知识网上很多,自行参考。tensorrtserver 的官方建议的安装如下:

    docker pull nvcr.io/nvidia/tensorrtserver:19.08-py3
    

    镜像文件较大,且国内下载很慢,经常断线。所以建议使用阿里云的镜像源,阿里的镜像源是比较动态的,可以到注册账号后登录阿里云搜索 tensorrtserver ,找到合适的源,以下是两个示例:

    docker pull registry.cn-beijing.aliyuncs.com/cloudhjc/tensorrtserver:server19.08
    
    docker pull registry.cn-hangzhou.aliyuncs.com/bostenai/tensorrtserver:19.04-py3
    

    下载完镜像后,可以执行 docker images 看下,然后执行命令,启动该镜像的容器:

    docker run --rm --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p8000:8000 -p8001:8001 -p8002:8002 -v/model/repository:/models registry.cn-hangzhou.aliyuncs.com/bostenai/tensorrtserver:19.04-py3 trtserver --model-store=/models
    

    命令的格式如下:

    docker run --rm [环境配置] [端口号配置] -v[本地模型路径]:/models [镜像名称] trtserver --model-store=/models

    如上则启动了一个地址为本机地址,http 端口号为 8000,grpc 端口号为 8001 ,监控端口号为 8002

    2. 验证服务启动

    访问 http://ip:8001/api/status ,可以获得服务当前的运行状态,以及模型列表。
    访问 http://ip:8002/metrics,可以获得服务的运行日志。
    如果上述的 url 都访问正常,则表示服务正常启动了。

    3. 部署模型

    虽然,tensorrtserver 自带有模型示例,但是没有 saved_model 的示例,所以我们先自己生成一个 saved_model 模型,如下的 python 脚本可以生成一个矩阵相乘的 saved_model 的模型

    import tensorflow as tf
    import numpy as np
    
    input0 = tf.placeholder(tf.float32, [None, None], "input0")
    input1 = tf.placeholder(tf.float32, [None, None], "input1")
    
    b = tf.Variable(2.0,name='b')
    output = tf.matmul(input0, input1, name="matmul")
    
    with tf.compat.v1.Session() as sess:
        sess.run(tf.global_variables_initializer())
        v = sess.run([output], feed_dict={input0: np.ones([3, 2], np.float32), input1: np.ones([2, 3], np.float32)})
        
        print(v)
        print(b)
        
        inp0 = tf.saved_model.utils.build_tensor_info(input0)
        inp1 = tf.saved_model.utils.build_tensor_info(input1)
        out = tf.saved_model.utils.build_tensor_info(output)
    
        sign = tf.saved_model.signature_def_utils.build_signature_def(
            inputs={'input0': inp0, 'input1': inp1},
            outputs={'output': out},
            method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME)
    
        builder = tf.saved_model.builder.SavedModelBuilder("export")
        
        builder.add_meta_graph_and_variables(
            sess, [tf.saved_model.tag_constants.SERVING],
            signature_def_map={ tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY: sign },
          main_op=tf.tables_initializer(),
          strip_default_attrs=True)
    
        builder.save()
        print ("export end!!")
    

    执行脚本后在同目录下的 export 就会生成一个 saved_model.pb 的模型。
    将模型文件(saved_model.pb 和 variables 目录)拷贝到部署 tensorrtserver 的服务器。假设我们的模型路径为 /model/,模型名称为 matmul,那么经过拷贝和重命名后的路径目录结构期望如下:

    .
    └── matmul
        ├── 1
        │   └── model.savedmodel
        │       ├── saved_model.pb
        │       └── variables
        └── config.pbtxt
    

    即需要在模型路径下创建 matmul 文件夹,并在文件中创建名称为 1 的文件夹,在名称为 1 的文件夹在再创建一个名称为 model.savedmodel 的文件夹,模型文件 saved_model.pb 和 variables 目录保存在 model.savedmodel 文件夹下。这个目录结构中 1 实际上就是 tensorrtserver 定义的模型的版本号。在 matmul 目录下 config.pbtxt 是模型的配置文件,这个文件需要自己编写。

    4. 编写 config.pbtxt

    config.pbtxt 是模型访问的配置文件,需要正确编写,否则模型无法正确加载。上面矩阵相乘的 config.pbtxt 内容如下:

    name: "matmul"
    platform: "tensorflow_savedmodel"
    max_batch_size: 0
    input [
    {
    name: "input0"
    data_type: TYPE_FP32
    dims: [1, 10]
    },
    {
    name: "input1"
    data_type: TYPE_FP32
    dims: [10, 1]
    }
    ]
    output [
    {
    name: "output"
    data_type: TYPE_FP32
    dims: [1, 1]
    }
    ]
    
    4.1 基本配置
    1. name 要和模型的目录的名称保持一致,不一致则报错。
    2. saved_model 的 platform 写 tensorflow_savedmodel,其他模型可以参考(点击URL)。
    3. max_batch_size 可以参考模型是否支持批输入进行配置,如果模型不支持,启动的时候会报如下的错误,这时将 max_batch_size 改成 0 即可。

    Servable {name: matmul version: 1} cannot be loaded: Internal: unable to load model 'matmul', model configuration supports batching but first dimension of tensor 'input0' expected by framework is not a variable-size batch dimension: [10]

    4.2 input 和 ouput 的配置

    config.pbtxt 中的 input 和 output 时配置的重中之重,它们需要和模型的输入和输出严格保持一致。所以配置之前,我们需要先查看模型的输入输出信息。通过 saved_model_cli 命令可以查看该信息。saved_model_cli 在安装 tensorflow 之后即有,在系统命令行下执行。
    执行命令格式如下(参数是路径,不是名称):

    saved_model_cli show --all --dir [saved_model路径]
    

    得到的返回如下

    MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:
    
    signature_def['serving_default']:
      The given SavedModel SignatureDef contains the following input(s):
        inputs['input0'] tensor_info:
            dtype: DT_FLOAT
            shape: (-1, -1)
            name: input0:0
        inputs['input1'] tensor_info:
            dtype: DT_FLOAT
            shape: (-1, -1)
            name: input1:0
      The given SavedModel SignatureDef contains the following output(s):
        outputs['output'] tensor_info:
            dtype: DT_FLOAT
            shape: (-1, -1)
            name: matmul:0
      Method name is: tensorflow/serving/predict
    

    这里需要注意的是,如果执行 saved_model_cli 命令后返回的信息不包含 serve 和 serve 的签名,那么这个模型是不可以运行在 tensorrtserver 上。这点很重要,不是部署的问题,是模型的问题
    得到配置信息之后,我们就可以根据信息进行 input 和 output 的配置了。

    1. name 的配置:name 和 inputs 后单引号中的内容一致,比如示例中为 input0 和 input 1
    2. data_type 的配置:data_type 存在映射关系,即需要将 tensorflow 的类型映射成 tensorrtserver 的类型,如示例中的 DT_FLOAT 对应类型为 TYPE_FP32,详细的映射关系点击 URL
    3. dims 的配置:dims 和模型配置中的 shape 保持一致即可。dims 配置这边有一个坑是 shape 信息为 “ shape: unknown_rank ”,这时是没有对应的 dims 配置的,所以模型也是不可用的。unkown_rank 表示输入的 tensor 形状未定义,一般是如下的代码定义的输入,中间的 shape 定义为 None:
    nput0 = tf.placeholder(tf.float32, None, "input0")
    
    1. output 的配置和 input 配置相同

    5. 带模型的启动 tensorrtserver

    从 config.pbtxt 的配置,我们可以得到 tensorrtserver 不支持的 saved_model 如下:

    1. tag-set 中不包含 serve ,或者有 serve 标签,但是没有 server 的签名的
    2. shape 中包含 unkonwn_rank 的

    编辑完成 config.pbtxt 后,就可以启动服务了。
    执行命令:

    docker run --rm --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -p8000:8000 -p8001:8001 -p8002:8002 -v/model/:/models registry.cn-hangzhou.aliyuncs.com/bostenai/tensorrtserver:19.04-py3 trtserver --model-store=/models
    

    启动服务,访问 http://ip:8001/api/status/matmul 得到模型的信息如下:

    id: "inference:0"
    version: "1.1.0"
    uptime_ns: 2190253935560
    model_status {
      key: "matmul"
      value {
        config {
          name: "matmul"
          platform: "tensorflow_savedmodel"
          version_policy {
            latest {
              num_versions: 1
            }
          }
          input {
            name: "input0"
            data_type: TYPE_FP32
            dims: 1
            dims: 10
          }
          input {
            name: "input1"
            data_type: TYPE_FP32
            dims: 10
            dims: 1
          }
          output {
            name: "output"
            data_type: TYPE_FP32
            dims: 1
            dims: 1
          }
          instance_group {
            name: "matmul"
            count: 1
            kind: KIND_CPU
          }
          default_model_filename: "model.savedmodel"
        }
        version_status {
          key: 1
          value {
            ready_state: MODEL_READY
          }
        }
      }
    }
    ready_state: SERVER_READY
    

    看到模型的 ready_state 为 SERVER_READY 表示模型已经处于可以访问的状态了。这时候就可以调用客户端访问该模型了。

    相关文章

      网友评论

        本文标题:在 tensorrtserver 中使用 saved_model

        本文链接:https://www.haomeiwen.com/subject/qfucpctx.html