对话机器人 rasa (四):生产环境部署,Ubuntu 服务器基于 docker

更新日期: 2023-05-31 阅读次数: 3968 字数: 1475 分类: AI

由于线上生产环境使用的是腾讯云的服务器,Ubuntu server 版本比较低,是 18.04。自带的 python 版本为 3.6,不满足对话机器人框架 rasa 对 python 版本的最低要求。

而升级 python 版本可能破坏系统的一些工具。至于 virtualenv, miniconda 的方案我都非常反感,因为手动操作也不少,增加了重复部署的复杂度,而且长时间不用,命令就忘了。(目前大部分服务端程序,我都采用了 golang,已经很少用 python)我觉得目前最佳的部署方案是 docker。

这也是我第一次线上生产环境尝试 docker 部署,所以记录一下流程。

如果有一定 docker 使用经验,并且要同时部署 rasa core 和 actions 两个服务,可以参考我整理的另外一篇文章:对话机器人 Rasa(九): docker compose 同时部署 rasa core 和 actions 服务

安装 docker

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

安装之后,docker 服务默认就被启动了,并不需要手动 systemctl enable / start 操作。

docker 用户组

出于懒惰,一开始我没有将当前用户加入 docker 用户组,所以后续的 docker 操作都使用了 sudo。

正确的做法是将当前用户加入到 docker 用户组。

sudo usermod -aG docker $USER

但是,加入组后,执行 docker 命令,还是报权限错误。

$ docker image ls
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/json": dial unix /var/run/docker.sock: connect: permission denied

需要退出当前用户,再次登录就可以了。

拉取 rasa 的 docker 镜像

为了跟开发机上的 rasa 版本保持一致,我选择拉取同样版本的 docker 镜像

docker pull rasa/rasa:3.4.6-full

这是一个基于 Ubuntu 20.04 构建的镜像,安装了默认的 python3 版本 3.10。

docker hub 上可以找到该镜像:

https://hub.docker.com/r/rasa/rasa

在 tags 页,通过搜索过滤 3.4.6,找到 3.4.6 full 的信息,及对应的 docker pull 命令。 重要的是,可以通过 Image Layers 看到这个镜像的构成,例如,系统版本,依赖版本等。

查看已有镜像列表

docker image ls
REPOSITORY    TAG          IMAGE ID       CREATED         SIZE
rasa/rasa     3.4.6-full   06d8ddbd8b17   3 weeks ago     3.21GB
hello-world   latest       feb5d9fea6a5   18 months ago   13.3kB

下载的压缩文件为 1.15G, 解压之后为 3.21G。

模型部署

由于我不太确定要部署哪些文件,所以干脆把所有文件都同步到了服务器上。 虽然我感觉只需要模型文件就可以了。

#!/bin/bash

rsync --verbose  --progress --stats --compress \
      --recursive --times --perms --links --delete \
      --exclude ".rasa/" --exclude "*~" --exclude "*.swp" --exclude='.git/' \
      ./ some_user@server_ip:/home/some_user/project

注意:将 models 下没有用的模型文件删除。实际测试发现,线上自动选择最新模型的机制有问题。

前提是已经训练好中文模型,可以参考 让 Rasa 支持中文模型

启动 shell 测试一下

验证模型是否好用的时刻到了,可以在项目目录下执行:

docker run -it -v $(pwd):/app rasa/rasa:3.4.6-full shell
  • 参数 v 就是将本地磁盘的目录映射到 docker 的指定目录下。镜像的 WORKDIR 是 /app
  • rasa docker 镜像的 ENTRYPOINT 是 rasa, 所以只需要加上 shell 参数即可。

可以看到完美运行。

直接启用镜像是不行的

例如

$ docker run -it rasa/rasa:3.4.6-full

$ docker container ls -a
CONTAINER ID   IMAGE                  COMMAND                CREATED         STATUS                     PORTS     NAMES
d8b8007ee32f   rasa/rasa:3.4.6-full   "rasa --help"          2 minutes ago   Exited (0) 2 minutes ago             exciting_volhard
44c7287678d6   rasa/rasa:3.4.6-full   "rasa /usr/bin/bash"   5 minutes ago   Exited (2) 5 minutes ago             compassionate_ganguly
54467a213d9f   rasa/rasa:3.4.6-full   "rasa /bin/bash"       7 minutes ago   Exited (2) 7 minutes ago             angry_mcclintock

由于镜像中的配置是:

ENTRYPOINT ["rasa"]
CMD ["--help"]

所以,也就是执行了个 rasa help,就结束并退出了。

启用 restful api 服务

并映射到本地端口:

docker run -it -p 9020:5005 -v $(pwd):/app -d rasa/rasa:3.4.6-full run --enable-api

注:

  • 参数 p 是指定端口:host_port:container_port,即第一个端口号是宿主的端口,第二个端口是 docker 镜像的端口
  • 参数 d 是为了后台运行

查看容器的运行状态:

$ docker container ls
CONTAINER ID   IMAGE                  COMMAND                  CREATED              STATUS              PORTS                                       NAMES
4d46f99cdcf5   rasa/rasa:3.4.6-full   "rasa run --enable-a…"   About a minute ago   Up About a minute   0.0.0.0:9020->5005/tcp, :::9020->5005/tcp   pensive_pascal

测试 restful 服务

解析测试:

$ curl -XPOST http://localhost:9020/model/parse -d '{"text":"hello"}'
{"text":"hello","intent":{"name":"greet","confidence":0.9999858140945435},"entities":[],"text_tokens":[[0,5]],"intent_ranking":[{"name":"greet","confidence":0.9999858140945435},{"name":"mood_unhappy","confidence":6.114856660133228e-6},{"name":"goodbye","confidence":2.1561531866609585e-6},{"name":"affirm","confidence":1.956613232323434e-6},{"name":"deny","confidence":1.6925729369177134e-6},{"name":"mood_great","confidence":1.3166808230380411e-6},{"name":"bot_challenge","confidence":7.097570460246061e-7},{"name":"oxygen_benefit","confidence":2.5109002876888553e-7},{"name":"praise","confidence":1.1407703226495869e-7}]}

对话测试:

$ curl -XPOST http://localhost:9020/webhooks/rest/webhook -d '{"sender": "user_id", "message": "你好"}'
[{"recipient_id":"user","text":"\u4f60\u597d\uff01\u5403\u4e86\u4e48\uff1f"}]

text 的那段 unicode 编码转换为中文就是 “你好!吃了么?”

至此,部署操作基本完成。

可以再做一个 Nginx 配置转发即可。

设置多 rasa worker

在默认情况下,Rasa 服务器只使用1个worker。只有将环境变量 SANIC_WORKERS 的值设置为1以上, 同时当 locker store 的设置不是 InMemoryLockStore 时才可以启用多个 worker。

docker 设置环境变量的方法:

docker run -e MY_ENV_VAR=value my-image

docker 如何中止一个容器

要中止一个运行的 Docker 容器,您可以使用以下命令:

docker stop <container-id>

其中 container-id 是要中止的容器的 ID 或名称。

如果想要立即停止(强制关闭)容器,可以使用以下命令:

docker kill <container-id>

注意,这将在不安全地终止容器进程,可能导致数据丢失或其他问题。建议首先尝试正常停止容器(使用 docker stop 命令)。

查看系统资源占用

> docker stats --all

CONTAINER ID   NAME                    CPU %     MEM USAGE / LIMIT    MEM %     NET I/O           BLOCK I/O     PIDS
4d46f99cdcf5   pensive_pascal          0.00%     2.75GiB / 15.51GiB   17.73%    99.7kB / 32.2kB   1.92GB / 0B   37
31f800006844   beautiful_hermann       0.00%     0B / 0B              0.00%     0B / 0B           0B / 0B       0
74f755e91338   hopeful_dhawan          0.00%     0B / 0B              0.00%     0B / 0B           0B / 0B       0
6776ea1934e2   beautiful_meitner       0.00%     0B / 0B              0.00%     0B / 0B           0B / 0B       0

参考

  • 安装:https://cloud.tencent.com/developer/article/1167995
  • 安装:https://yeasy.gitbook.io/docker_practice/install/ubuntu
  • rasa docker 的使用方式:https://rasa.com/docs/rasa/docker/building-in-docker/

查看合集

📖 对话机器人 Rasa 中文系列教程

tags: rasa docker

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式