利用TensorFlow serving在docker上部署深度学习模型

官方的文档https://www.tensorflow.org/tfx/serving/docker

目录

官方例程

部署自己的模型


官方例程

首先拉取官方TensorFlow serving的镜像

docker pull tensorflow/serving

 建立本地的repo

mkdir -p /tmp/tfserving
cd /tmp/tfserving
git clone https://github.com/tensorflow/serving

 运行镜像

docker run -p 8501:8501 \
  --mount type=bind,\
source=/tmp/tfserving/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu,\
target=/models/half_plus_two \
  -e MODEL_NAME=half_plus_two -t tensorflow/serving &

 命令的解释如下

--mount:   表示要进行挂载
source:    指定要运行部署的模型地址, 也就是挂载的源,这个是在宿主机上的模型目录
target:     这个是要挂载的目标位置,也就是挂载到docker容器中的哪个位置,这是docker容器中的目录
-t:         指定的是挂载到哪个容器
-p:         指定主机到docker容器的端口映射,这里的8501端口是镜像里REST的端口
docker run: 启动这个容器并启动模型服务
 
综合解释:
         将source目录中的例子模型,挂载到-t指定的镜像启动的容器下的target目录,并启动

这时出现错误,提示&要加双引号 

所在位置 行:1 字符: 208
+ ... s/half_plus_three -e MODEL_NAME=half_plus_two -t tensorflow/serving &
+                                                                         ~
不允许使用与号(&)。& 运算符是为将来使用而保留的;请用双引号将与号引起来("&"),以将其作为字符串的一部分传递。
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : AmpersandNotAllowed

用双引号把&扩起来

 docker run -p 8501:8501 --name="half_plus_two" --mount type=bind,source=E:/tmp/tfserving/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu,target=/models/half_plus_two -e MODEL_NAME=half_plus_two -t tensorflow/serving "&"

然后出现了-X的问题,可能是指令的格式不对

Invoke-WebRequest : 找不到与参数名称“X”匹配的参数。
所在位置 行:1 字符: 42
+ curl -d '{"instances": [1.0, 2.0, 5.0]}' -X POST http://localhost:850 ...
+                                          ~~
    + CategoryInfo          : InvalidArgument: (:) [Invoke-WebRequest],ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

参考了https://www.shuijingwanwq.com/2018/12/28/3077/,改成如下

curl -Body '{"instances": [1.0, 2.0, 5.0]}' -Uri http://localhost:8501/v1/models/half_plus_two:predict -Method 'POST'

或者使用requests.post方法

uri=http://localhost:8501/v1/models/half_plus_two:predict
query_data = '{"instances": [[1.0, 2.0, 3.0]}'
requests.post(url, query_data)

 这样就能work了,结果如下

StatusCode        : 200
StatusDescription : OK
Content           : {
                        "predictions": [2.5, 3.0, 4.5
                        ]
                    }
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 43
                    Content-Type: application/json
                    Date: Mon, 22 Jun 2020 07:58:23 GMT

                    {
                        "predictions": [2.5, 3.0, 4.5
                        ]
                    }
Forms             : {}
Headers           : {[Content-Length, 43], [Content-Type, application/json], [Date, Mon, 22 Jun 2020 07:58:23 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 43

部署自己的模型

只需要把自己的模型存成例程那样的格式就行,例程的文件结构是

model下有一个00000123的文件夹,里面有assets,variables,saved_model.pb三个文件,结构如下

E:.
└─00000123
    │  saved_model.pb
    │
    ├─assets
    │      foo.txt
    │
    └─variables
            variables.data-00000-of-00001
            variables.index

assets下只有一个foo.txt,里面内容是

asset-file-contents

因为我用的Keras训练网络,所以先需要转换成TensorFlow的.pb模型文件,代码如下

def model_h52pb():
    model_path = r'D:\work\model\my_model.h5'

    K.set_learning_phase(0)
    model = load_model(model_path, custom_objects={'my_acc': my_acc})  # 加载h5模型
    export_path = r'D:\work\model\tf_model'

    with K.get_session() as sess:
        tf.saved_model.simple_save(
            sess,
            export_path,
            inputs={'input': model.input},
            outputs={t.name: t for t in model.outputs})

这样可以得到和例程文件格式完全一样的variables和pb文件 ,那个assets文件夹直接拷贝过来。这样文件格式就搞定了。

官方例程的写法是

 docker run -p 8501:8501 --mount type=bind,source=E:/tmp/tfserving/serving/tensorflow_serving/servables/tensorflow/testdata/saved_model_half_plus_two_cpu,target=/models/half_plus_two -e MODEL_NAME=half_plus_two -t tensorflow/serving "&"

source里面是本地模型的路径,只需要换成我们模型的路径就行了。target里面放模型在容器里的路径,MODEL_NAME在query的时候要用到。这里模型名字设置为my_model。

 docker run -p 8501:8501 --name="my_model" --mount type=bind,source=E:/tmp/tfserving/my_model,target=/models/my -e MODEL_NAME=my -t tensorflow/serving "&"

 query可以这样写

curl -Body '{"instances": [[1.0, 2.0, 5.0]]}' -Uri http://localhost:8501/v1/models/my:predict -Method 'POST'

注意instances的格式要跟代码能正确处理的数据格式一样,才能进行预测,我这里是输入一个1*3的矩阵,与[1,2,3]点乘,然后+1。 

收到的response如下

StatusCode        : 200
StatusDescription : OK
Content           : {
                        "predictions": [[20.8982468]
                        ]
                    }
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 42
                    Content-Type: application/json
                    Date: Tue, 23 Jun 2020 01:31:10 GMT

                    {
                        "predictions": [[20.8982468]
                        ]
                    }
Forms             : {}
Headers           : {[Content-Length, 42], [Content-Type, application/json], [Date, Tue, 23 Jun 2020 01:31:10 GMT]}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 42

可以看到结果是符合预期的,大功告成!

 

参考:

http://dockone.io/article/9209

https://www.shuijingwanwq.com/2018/12/28/3077/

https://blog.csdn.net/weixin_34343000/article/details/88118667?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-6

https://blog.csdn.net/u011734144/article/details/82107610?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

https://blog.csdn.net/m0_38088298/article/details/85796658

你可能感兴趣的:(深度学习,docker)