tensroflow-serving部署自己模型

经过一系列测试,tensorlfow-serving确实要比直接利用flask部署快非常多,虽然网上也有很多有关怎么把自己的训练好的模型部署到tensorlfow-serving上。但是为了有一个自己完整的记录,还是写了这样的经验供大家参考。

(1)训练自己的tensorflow模型或者直接使用预训练的bert模型,这里我采用的tensorflow1.15.0版本。最终生成的是如下结构的模型文件:

如果利用预训练模型,在重加在参数的时候我是使用的

加载模型所以在预训练模型里边添加一个checkpoint文件内容如下:

  model_checkpoint_path: "bert_model.ckpt"

所以文件结构如下:

(2)构造模型图以及生成pb文件

有了如上文件,然后我们就需要构造tensorflow-serving服务的infer函数,也就是推断函数,由于以上文件不包含图模型,所以我们需要重新构建模型图。具体代码也比较简单,我们以输出bert最后一层为例,具体代码如下:

import json

import os

import tensorflow as tf

import argparse

import modeling

def create_model(bert_config, is_training, input_ids):

    # 通过传入的训练数据,进行representation

    model = modeling.BertModel(config=bert_config, is_training=is_training, input_ids=input_ids)

    # output = model.get_pooled_output()

    output = model.get_sequence_output()

    return output,model

# encoding=utf-8

import tensorflow as tf

import sys

import pdb

import os

def build_and_saved_model(args):

    bert_config = modeling.BertConfig.from_json_file(

        os.path.join(args.model_path, 'bert_config.json'))

    input_ids = tf.placeholder(tf.int32, [1, args.max_seq_len], name="input_ids")

    output,model=create_model(bert_config=bert_config,is_training=False,input_ids=input_ids)

    session = tf.Session()

    session.run(tf.global_variables_initializer())

    saver = tf.train.Saver()

    model_file = tf.train.latest_checkpoint(args.model_path)

    saver.restore(sess = session, save_path = model_file)

    trans_model_save_path = './export_models/v1'

    builder = tf.saved_model.builder.SavedModelBuilder(trans_model_save_path)

    # 将输入张量与名称挂钩

    inputs = {

        'input_ids': tf.saved_model.utils.build_tensor_info(model.input_ids),

    }

    outputs = {

        'output': tf.saved_model.utils.build_tensor_info(model.sequence_output),

    }

    #签名定义

    ner_signature_def = tf.saved_model.signature_def_utils.build_signature_def(

        inputs=inputs,

        outputs=outputs,

        method_name = tf.saved_model.signature_constants.PREDICT_METHOD_NAME

    )

    builder.add_meta_graph_and_variables(

        session,

        [tf.saved_model.tag_constants.SERVING],

        signature_def_map={

            'ner_def':ner_signature_def

        }

    )

    builder.save()

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='Trans ckpt file to .pb file')

 parser.add_argument('-model_path',type=str,default='./chinese_roberta_wwm_ext_L-12_H-768_A-12', help='dir of a pretrained BERT model')

    parser.add_argument('-export_path', type=str, default='./export_models', help='export model path')

    parser.add_argument('-max_seq_len', type=int, default=64, help='maximum length of a sequence')

    args = parser.parse_args()

    build_and_saved_model(args)

  经过以上代码基本上构成了pb文件。具体的模型就在create_model函数中编写,另外注意一点就是输入输出一定要写清楚。ner_signature_def签名可以包括,如果不包括的话,tensorflow-serving会有一个默认的签名。最后生成的文件结构如下:

注意:生成的模型一定要在数字文件夹(例如:我的是1命名的文件夹)

(3)利用docker tensorflow-serving启动自己的服务

     有了pd的模型文件,接下来就可以利用官方的docker镜像开启自己的服务,具体命令如下:

  nvidia-docker run --runtime=nvidia -p 18501:8501 -p 18500:8500 --mount type=bind,source=$(pwd)/export_models,target=/models/model --name bert_out -t  b247542eae94 --per_process_gpu_memory_fraction=0.3

这里需要解释几点1.http请求默认使用8501和8500,两个端口,所以建议开启docker容器内部的端口最好是这两个,外边的映射端口可以随意(例如我用的是18501和18500).

Source就是pd文件保存的本地具体路径。target就是容器映射的路径。其他参数可以参考官网github进行对比。

  1. 请求,这里举例两个方法

        

Curl -d '{"signature_name":"ner_def","instances": [{"input_ids": [345,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}]}' -X POST http://localhost:18501/v1/models/model:predict

第二种是python http请求如下代码:

import json

import requests

import numpy as np

maxlen = 64

import tokenization

tokenizer = tokenization.FullTokenizer(

    vocab_file="./vocab.txt", do_lower_case=True)

while True:

  print("请输入")

  text=input()

  x1 = tokenizer.tokenize(text)

  x1=tokenizer.convert_tokens_to_ids(x1)

  x_masks= [1] * len(x1)

  X1 = x1 + [0] * (maxlen-len(x1)) if len(x1) < maxlen else x1

  X_mask = x_masks + [0] * (maxlen-len(x1)) if len(x1) < maxlen else x1

  #request_data = {"signature_name": "serving_default", "inputs": {'input_1': inputs[0], 'input_2': inputs[1]}}

  request_data = {"signature_name": "ner_def", "instances": [{"input_ids":X1,"input_mask":X_mask}]}

  SERVER_URL =  'http://locahosts:18501/v1/models/model:predict'

  response = requests.post(SERVER_URL, data=json.dumps(request_data))

  print(response.text)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值