CubeAI模型开发指南
本文描述如何基于 ServiceBoot微服务引擎 开发支持“服务原生”、“云原生”和“算力原生”的AI模型推理服务程序。
CubeAI模型示范库 中的所有模型都是使用这种方式进行开发的。
开发环境准备
-
操作系统
- Linux Ubuntu 16.04 LTS以上,建议Ubuntu 20.04 LTS
-
Python
-
Docker
-
安装Docker引擎,方法和步骤参见: https://docs.docker.com/engine/install/ubuntu/ ,或直接运行以下命令:
$ sudo apt install docker.io
-
使非root用户具有操作docker的权限:
$ sudo usermod -aG docker $USER
$ newgrp docker
-
Node.js
- 以root身份登录,从 https://nodejs.org/en/download/ 下载node(建议版本号:v15.1.0),拷贝至 /opt 目录。
# cd /opt
# wget https://nodejs.org/download/release/v15.1.0/node-v15.1.0-linux-x64.tar.xz
- 解压,创建符号连接以便可以调用:
# tar -xvf node-v15.1.0-linux-x64.tar.xz
# ln -s node-v15.1.0-linux-x64 nodejs
# ln -s /opt/nodejs/bin/node /usr/bin/node
# ln -s /opt/nodejs/bin/npm /usr/bin/npm
# ln -s /opt/nodejs/bin/npx /usr/bin/npx
# node -v
# npm -v
- 配置npm源国内镜像:
# npm config set registry https://registry.npm.taobao.org
# npm config get registry
-
Angular CLI
- 安装
# npm install -g @angular/cli@10.1.1
- 创建符号链接以便可以调用
# ln -s /opt/nodejs/bin/ng /usr/bin/ng
# ng --version
-
集成开发环境
建议使用PyCharm作为Python的IDE集成开发环境。
建议在PyCharm中为每一个模型项目都新建一个Python虚拟环境(venv)。执行以下操作进入界面,然后选择添加相应的Python版本。
File | Settings | Project <项目名> | Project Interpreter
开发AI模型推理服务
-
从 CubeAI模型示范库 中选择一个模型作为开发模板,复制到新的目录并重命名。在PyCharm中打开该新目录,创建新的Python虚拟环境。
-
安装Python依赖包
-
在requirements.txt文件中列出模型运行所需要的所有依赖包信息。 其中必须包含 ServiceBoot ,用以作为模型服务化的基础引擎。
-
在Python虚拟环境terminal窗口当前目录下,执行如下命令来安装所有依赖包:
$ sh pip-install-reqs
-
依赖包安装完成后,可在terminal窗口中执行如下命令来查看 serviceboot 的所有命令行格式:
$ serviceboot
-
配置模型服务化参数
编辑application.yml文件,修改模型服务化相关配置参数。各参数含义解释如下:
-
serviceboot.python_version: Python版本号,应与当前开发环境Python版本号保持一致。
-
serviceboot.cname: 模型中文名称,必填。建议用中文短语,不要太长。
-
serviceboot.ename: 模型英文名称,必填。必须为ASCII编码,英文字母必须为小写字母。
-
serviceboot.version: 模型版本号,例如v1.0.0,可选。
-
serviceboot.port.dev: 开发环境模型服务端口号。可选,缺省为:3330。
-
serviceboot.port.prod: 容器运行环境模型服务端口号。可选,缺省为:80。
-
serviceboot.has_web: 是否包含前端 web 界面。可选,缺省为no。如有前端界面应填为:yes。
-
serviceboot.compile_python: 构建模型Docker镜像时是否将Python代码编译成二进制代码。可选,缺省为no。
-
serviceboot.process_num: ServiceBoot微服务启动时创建的Web服务进程数。可选,缺省为1。如为0,表示使用与运行时服务器CPU核数相同的进程数。
-
选择基础Docker镜像
编辑Dockerflie文件,修改第一行 “FROM” 后边的内容,改为本模型对应的基础镜像。
-
开发模型推理程序
-
模型程序位置
指定在 app 目录下开发模型推理程序。
模型主程序可采用面向对象和非面向对象(串行脚本式)两种模式来进行开发。
-
面向对象开发模式(推荐)
在面向对象开发模式中,将模型主程序放置于 app_core.py 文件中。其中必须定义一个名为 AppCore 的类,作为模型运行和调用的主入口。
-
非面向对象开发模式
在非面向对象(串行脚本式)开发模式中,将模型主程序放置于 app_main.py 文件中。
如果 app 目录下存在 app_main.py 文件,则采用非面向对象开发模式(此时即使存在 app_core.py 文件也不起作用);否则采用面向对象开发模式。
推荐使用面向对象开发模式。
-
模型API接口定义和开发
可通过在模型主程序中定义函数或方法来对外提供API接口服务。
-
面向对象开发模式
在模型主程序 app_core.py 的 AppCore 类中定义的所有方法(构造方法__init__除外),都可作为模型方法对外提供API接口服务。
可在 AppCore 中定义一个类变量 public_actions ,用于声明可对外提供API接口服务的方法名。不在该列表中的方法不能通过API接口方式访问。如果public_actions类变量不存在或值为None,则 AppCore 中定义的所有方法都对外开放。
-
非面向对象开发模式
在模型主程序 app_main.py 中定义的所有函数,都可作为模型函数对外提供API接口服务。
可在 app_main.py 文件中定义一个全局变量 public_actions ,用于声明可对外提供API接口服务的函数名。不在该列表中的函数不能通过API接口方式访问。如果public_actions变量不存在或值为None,则 app_main.py 文件中定义的所有函数都对外开放。
-
模型API输入参数
在 app_core.py 的 AppCore 类中定义的模型方法(面向对象模式),或者在 app_main.py 文件中定义的模型函数(非面向对象模式),可定义0至多个输入参数。
如果某个模型方法/函数只定义了一个输入参数且约定该输入参数类型为 bytes(二进制字节流),则在模型部署后,该模型方法/函数需要通过端点为 /api/stream/<method|function-name> 或 /api/file/<method|function-name> 的 HTTP API 接口来进行访问。如果通过 /api/stream 接口访问,则在 HTTP POST 请求体中直接携带bytes类型的二进制字节流;如果通过 /api/file 接口访问,则在 HTTP POST 请求体中携带用于HTTP文件上传的 XHR 格式请求体。
在所有其他情况下(模型方法/函数中定义了0至多个输入参数,且约定每一个输入参数类型都不为bytes),模型部署后该模型方法/函数通过端点为 /api/data 的 HTTP API 接口进行访问。访问时在 HTTP POST 请求体中携带 JSON 格式数据,形式如下:
{
"action": <与app_core.py的AppCore类中定义模型方法 或者 app_main.py中定义的模型函数同名的字符串>
"args": {
<参数名1>: <参数值1>,
<参数名2>: <参数值2>,
...
}
}
其中 args 为键值对形式的参数列表, 各参数名必须与模型主程序中定义的相应模型方法/函数的参数名保持一致。
-
模型API返回值
在 app_core.py 的 AppCore 类中定义的模型方法(面向对象模式),或者在 app_main.py 文件中定义的模型函数(非面向对象模式),其返回值可以是bytes类型的二进制字节流,也可以是其他任意Python类型的数据。如果是后者,则该返回值必须能够使用 json.dumps() 函数序列化为JSON字符串,也就是说其中不能嵌套无法被序列化的特殊类型数据。
模型部署后通过 HTTP API 访问时,如果模型主程序中定义的相应模型方法/函数的返回值为 bytes 类型,则 HTTP 响应体中直接包含该 bytes 类型的字节流;否则 HTTP 响应体中将包含一个序列化后的 JSON 对象字符串,其格式如下:
{
"status": "ok"|"err",
"value": <模型方法/函数返回结果>
}
其中 "status" 指示模型调用状态,为 "ok" 表示正常, "err" 表示模型调用或运行过程中发生异常。
当 "status" 的值 "ok" 时, "value" 的值为模型方法/函数的返回结果;当 "status" 的值 "err" 时, "value" 的值为错误或异常描述字符串。
当自主开发的模型推理程序(被自定义的模型方法/函数调用执行)在运行过程中抛出异常时,ServiceBoot后自动将HTTP响应体中的"status"赋值为"err",将"value"赋值为抛出异常的异常描述字符串。
-
模型初始化和模型数据加载
-
面向对象开发模式
在 app_core.py 的 AppCore类中定义构造方法 init() ,用于执行模型初始化和模型数据加载等相关操作。
-
非面向对象开发模式
直接在在模型主程序 app_main.py 文件中添加脚本程序来执行模型初始化和模型数据加载等相关操作。通常应放在模型函数定义之后。
-
开发前端Web界面(可选)
在 webapp 目录下开发可视化交互式前端 Web 界面。
模板程序中使用 Angular 框架来编写前端,编程语言采用 TypeScript 和 HTML。所有 Angular 代码放置于 webapp/src 目录之下。
前端Web界面程序的典型开发过程如下:
-
第一次拷贝样例程序后,应先安装Web开发所需要的前端依赖包:
$ cd webapp
$ npm install
-
在terminal窗口中执行 serviceboot start 命令,于本地启动基于ServiceBoot微服务引擎的AI模型服务:
$ serviceboot start
或者在PyCharm中直接运行 run_model_server.py 程序亦可。
-
在 webapp/src 目录下开发前端代码。普通开发者基于样例程序开发,只需要修改 webapp/arc/app/home 目录下的 home.component.ts 和 home.component.html 两个程序文件即可。高级开发者也可在此基础上进行扩展。
在开发过程中,当 Angular 代码修改之后,在terminal命令行窗口中 cd 至 webapp 目录之下,然后执行 ng build 命令来编译代码:
$ cd webapp
$ ng build
注意: 前端web代码编译后,存放在 webapp/www 目录之下。本系统并不限制前端web开发一定使用 Angular,使用其他任何前端框架都可以,只要保证最终编译生成的生产代码存放在 webapp/www 目录之下就行。
-
在浏览器中打开并刷新网页 http://127.0.0.1:3330/web/ , 查看并调试模型Web界面。
-
如需继续调试,转至第3步。
-
开发结束后,执行如下命令编译生产环境代码:
$ cd webapp
$ ng build --prod
-
模型文档
模型开发完成后,应在 README.md 文件中编写模型文档。
如需部署至CubeAI智立方平台,还可在 docs 目录下放置两个文件:
- docs/avatar.jpg: 模型头像图片,尺寸为200*200像素。
- docs/api-example.txt: 模型API接口测试文件,内容为JSON格式的HTTP POST消息体。
模型测试
-
本地开发测试
适用于模型开发过程中验证模型推理程序的正确性。
-
面向对象开发模式
在 app_core.py 文件末尾编写测试脚本,然后直接运行该Python文件进行测试。参见相关模型样例程序。
注意,在本测试模式下,需要将文件末尾的测试脚本置于 “if name == 'main':” 条件判断之下,并在初始化AppCore对象之前插入代码“os.chdir('..')” ,用于设置当前工作目录。。
-
非面向对象开发模式
在 app_main.py 文件末尾编写测试脚本,然后直接运行该Python文件进行测试。参见相关模型样例程序。
注意,在本测试模式下,需要将文件末尾的测试脚本置于 “if name == 'main':” 条件判断之下。
同时,还需要在初始化加载模型数据的脚本之前插入代码: “if name == 'main': os.chdir('..')” ,用于设置当前工作目录。
-
本地服务化测试
适用于模型开发完成、部署之前对模型的可用性进行测试。
-
首先运行程序:run_model_server.py,或者直接在terminal中执行命令:serviceboot start,在本地启动AI模型服务。
-
访问Web界面: http://127.0.0.1:3330/#/
-
本地部署测试
适用于对自己开发的模型推理服务在本地进行部署测试。
-
查看、编辑 Dockerfile 文件,确保使用了正确的基础镜像。
-
构建本地docker镜像:
$ serviceboot build_docker
或
$ sh build_docker.sh
-
查看本地docker镜像:
$ docker image ls
-
运行本地docker镜像,启动基于 ServiceBoot 引擎的AI模型服务:
$ docker run -p 3330:80 <docker_image_id>
-
模型服务可视化测试,例如:
http://localhost:3330/web/
在测试和验证视频流媒体类AI模型推理服务时,需要搭建流媒体服务器来提供流媒体视频源,具体步骤可参见: