本文描述如何基于 ServiceBoot微服务引擎 开发支持“服务原生”、“云原生”和“算力原生”的AI模型推理服务程序。
CubeAI模型示范库 中的所有模型都是使用这种方式进行开发的。
操作系统
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
# 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 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
从 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 目录下放置两个文件:
本地开发测试
适用于模型开发过程中验证模型推理程序的正确性。
面向对象开发模式
在 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模型推理服务时,需要搭建流媒体服务器来提供流媒体视频源,具体步骤可参见:
Dear OpenI User
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.
For more agreement content, please refer to the《Openl Qizhi Community AI Collaboration Platform Usage Agreement》