文档简介:
一、资源规划
资源规划文档旨在系统资源使用层对真实交付场景做产品层面的通用指导
文档涵盖了构建百度OCR算子服务所需要的服务器主机、 CPU、内存、 GPU、网络等内容方面的规划。 本文档所列出的所有数量数字方面的值均需针对实际场景需求和限制做针对性调整。
名词定义
名称 | 含义 |
---|---|
鉴权服务 | 鉴权服务包含百度发布的服务授权证书,如果不安装鉴权服务,后续的应用服务也将无法启动,目前支持加密狗(硬件)和提取机器指纹(软件)两种鉴权方式 |
应用服务 | 包含Docker等基础环境以及相关技术方向的算法模型,是私有化产品的的核心。部署应用服务的前提是部署鉴权服务,应用服务在运行时会实时请求鉴权服务,需要保障两个服务之间能够顺利通信 |
单机一键部署 | 适用于鉴权服务、应用服务部署在一台物理机上的场景。即执行一条命令将鉴权服务、应用服务安装完成。 |
多机分离部署 | 适用于鉴权服务、应用服务不在一台机器上部署的场景。首先部署鉴权服务、然后部署应用服务 |
测试环境 | 客户方提供的进行产品、场景测试的环境,一般与生产环境隔离,开发、测试能够方便接触到的环境,对部署的可用性要求较低 |
生产环境 | 客户的生产环境,一般的业务系统真实提供服务的环境,具备较高的可用性要求,包括异地多活的灾备要求。一般只有运维人员有该环境的超管权限 |
物理架构拓扑图
文字识别私有化部署产品包含鉴权服务和应用服务,其中
- 鉴权服务通过客户网关系统连接到应用服务器为应用服务提供鉴权认证
- 应用服务部分直接或通过生产级网关被客户业务场景直接使用
鉴权应用
规划原则:
鉴权服务是运行百度文字识别应用服务的基础,如果鉴权异常,将直接导致模型的API接口不可用。鉴权服务的高可用通过Raft算法实现。 鉴于Raft算法的特性,我们建议您选择“奇数”个节点来部署鉴权集群。
鉴权集群不同节点的容错能力如下。
集群节点数量 | 最大容错 |
---|---|
1 | 0 |
2 | 0 |
3 | 1 |
4 | 1 |
5 | 2 |
6 | 2 |
规划流程:
一般建议鉴权节点数量为1或3个。
模型算子应用
规划原则:
- 单模型应用实例承担流量,根据业务逻辑复杂度(请求报文)、机器节点硬件条件(CPU、内存、网络、显存)强相关
- 单模型应用实例的内存分配依赖模型的大小
- 单模型应用实例的CPU资源与请求报文相关
- 单模型应用实例占用网路IO与请求报文和返回结果相关
- 单模型应用实例占用磁盘空间大小与请求报文、日志输出量等特性相关
- 场景需要的模型应用服务资源与整体业务QPS、单模型实例性能、高可用方案相关
规划流程:
根据实际场景进行性能测试,得出单模型实例性能指标(QPS、响应延时、内存占用、显存占用),结合场景高峰流量预估和高可用要求,以及服务器实际显卡数量等计算需要模型应用实例数,根据机器节点硬件资源指标,最终确定硬件节点数。
资源规划示例
模块清单
模块名 | 模块角色说明 |
---|---|
openresty | 基础依赖服务,提供负载均衡能力 |
docker | 基础依赖服务 |
nvidia | 基础依赖服务 |
redis | 基础依赖服务 |
…… | 基础依赖服务 |
c-offline-security-server | 鉴权服务 |
auth-manage-service | 鉴权服务,用于鉴权管理,提供web页面查看鉴权信息。 |
ocr-x x x x x | 模型应用服务 |
…… | 模型应用服务 |
以上模块清单针对不同的模型部署包稍有差异,可以通过下面的命令查询当前部署包内详细的模块清单。
# se :表示search,根据模块名称查询安装包里是否包括某个模块,不区分大小写,
如果没有指定名称则输出安装包里所有模块信息 cd origin/package/Install && python install.py se
您可以根据模型的数量适当调整cpu,内存,显存,存储等资源,下面以在单台服务器部署1个模型为例说明:
资源需求 |
节点 |
部署模块 |
单节点CPU |
单节点内存 |
单节点显卡数 |
单节点存储 |
单节点网络 |
测试环境 |
节点A |
基础依赖服务 |
4核 |
8G |
视模型情况而定 |
50G |
>1000Mbps |
鉴权服务和鉴权管理服务 |
|||||||
模型应用服务 |
|||||||
生产环境 |
节点A |
基础依赖服务
|
8核 |
16G |
视模型情况而定 |
500G |
>1000Mbps |
模型应用服务 |
|||||||
节点B |
鉴权服务 |
1核 |
2G |
不需要 |
10G |
>1000Mbps |
|
生产环境 |
节点A |
鉴权服务 |
8核 |
16G |
视模型情况而定 |
500G |
>1000Mbps |
基础依赖服务 |
|||||||
模型应用服务 |
|||||||
节点B |
基础依赖服务 |
8核 |
16G |
视模型情况而定 |
500G |
>1000Mbps |
|
模型应用服务 |
如果您有多个服务器节点,可以参考以上示例,选择每台服务器节点需要部署的服务。
二、场景与名词
场景说明
- (无环境)全新部署:服务器环境为第一次部署,该服务器之前没有部署过百度文字识别产品的任何模型。
- (有环境)升级模型:是指用户之前部署过老版本的百度文字识别产品模型,需要对模型进行升级操作。
- (有环境)新增模型:是指用户当前服务器或者其他服务器已经部署过百度文字识别产品部分模型,需要新增其他模型
- 回滚:回滚到最近一次升级前的版本
- 卸载: 删除已经安装的模块
名词解释
名词 | 说明 | 示例 |
---|---|---|
package_dir | 存放部署包、升级包的路径,包体积较大,尽量不要放在/下 | 如 /mnt/disk0/baidu_ocr_install_20111009 |
work_dir | 应用程序文件存储地址,默认为/home/baidu/work | 如 /home/baidu/work |
三 、准备工作
环境检查
部署之前请务必参考此文档部署前环境检查必看进行硬件、网络、及软件环境检查,以避免在安装部署过程中出现问题。
获取部署包
1、申请正式模型部署包安装文件下载链接,下载模型部署包并重名名。
# 示例如下,-O --output-document=FILE 对文件重名名,O为大写英文字母 #
请将示例中的9C20XXXXXXXX.tar.gz替换为真实的文件名 wget -O 9C20XXXXXXXX.
tar.gz https://bj.bcebos.com/v1/private-ai-online/9C20XXXXXXX.tar.gz?authorization=bce-authXXXXXXX132187fcf81
2、将9C20XXXXXXXX.tar.gz上传到待部署的服务器,为方便区分不同的部署包,建议以【baidu_ocr_install + 日期】命名,如 baidu_ocr_install_20111009,该目录我们将其命名为package_dir
3、进入package_dir 执行以下命令解压部署包
# baidu_ocr_install_20111009 部署包的根目录,次处仅为示例,实际操作时换成您上一步命令的路径
cd baidu_ocr_install_20111009 && tar zxvf 9C20XXXXXXXX.tar.gz
4、解压后进入original目录执行bash download.sh命令获取全部安装文件,执行脚本后会自动下载以下安装文件:数据库服务安装包、鉴权服务安装包、应用服务安装包以及docker安装包等基础依赖环境。如果已经提前在办公网络下载完毕,请忽略该步骤。
cd original && bash download.sh
执行结束后,会在download.sh同级目录下生成download.log日志记录下载详情。
若您在此过程出现问题,请提交工单联系百度的工作人员
接下来您可以根据实际使用场景和前文的资源规划,从下文选择一种部署方式来部署。
四、全新部署
指服务器环境为第一次部署,该服务器之前没有部署过任何百度文字识别产品的任何模型。
您可以进入模型部署包的存储路径,执行下面的命令查看程序help信息:
cd original/package/Install
python install.py
返回结果如下:
install.py usage:
inall: 安装所有的产品以及鉴权服务和基础服务,适用于在单台物理机上安装所有模块的场景
in, install: 安装一个模块,名称不区分大小写,适用于产品模块和鉴权服务分机器部署的场景
se, search: 根据模块名称查询安装包里是否包括某个模块,不区分大小写,如果没有指定名称则输出安装包里所有模块信息
li, list: 根据模块名称查询某个模块是否已经安装,如果没有指定名称则输出所有已经安装的模块
rm, remove: 根据模块名称删除某个已经安装的模块;如果有其他模块依赖这个模块,则不允许删除
rmall: 删除所有已经安装的模块
lu, licenseupdate: 更新license文件,适用于授权延期、实例数扩容、增加产品授权
up, upgrade: 升级指定模块,不区分大小写,不指定参数时输出所有可升级模块信息
rb, rollback: 回滚指定模块,不区分大小写,回滚到最近一次升级前的版本
du, safestoredataupdate: 安全存储数据更新,包括敏感数据、模型解密密钥等相关文件的更新
请根据前文的资源规划和实际的使用场景从【单机一键部署】和【多机分离部署】选择一种方式部署。
单机一键部署
如果您只有一台服务器,可以使用inall参数来部署,inall 表示install all,安装所有的产品以及鉴权服务和基础服务,适用于在单台服务器上安装所有模块的场景,容易和 install 混淆,在使用时请注意。
1、使用root权限启动一键部署脚本进行安装:
# inall: 安装所有的产品以及鉴权服务和基础服务,适用于在单台物理机上安装所有模块的场景 python install.py inall
执行安装后,首先进行环境检查
未通过的检查项详情如下:
+---------------------------+-------------+--------------+----------+--------------------+
| 模块 | 检查项 | 含义 | 指标要求 | 实际参数或报错信息 |
+---------------------------+-------------+--------------+----------+--------------------+
| default | * disk_home | HOME磁盘空间 | >=512 GB | 201 GB |
| c-offline-security-server | machine | 宿主机环境 | | 当前环境为虚拟机 |
+---------------------------+-------------+--------------+----------+--------------------+
带*的检查项非强制,可以选择跳过
2021-08-27 21:44:37,414 - 2712 - install - ERROR - 环境检查失败!请修复未通过的检查项后重新安装,如有问题请联系技术支持。
按任意键结束。输入continue后回车可跳过环境检查,跳过后不保证安装成功。
其中带 * 项 (如 disk_home等)非强制要求,可以忽略。确认无误后请输入 continue 英文字符,继续下一步
之后会要求手动输入IP地址和选用的显卡编号,示例如下:
请输入鉴权集群的IP列表,逗号分隔,列入:192.168.1.101 # 参考上文资源规划,如鉴权节点唯一,只需要输入真实机器IP即可,
如106.12.141.217 # 如果鉴权节点有多个,请以英文逗号分隔,如106.12.141.217,106.12.141.218,106.12.141.219 106.12.141.217
# 输入您要使用的显卡编号,仅输入1个。可通过nvidia-smi查看显卡编号 enter value for gpu index numbers used by this
application,separated by comma, e.g. 0,1,2:
2、确认本次安装模块是否完整:
执行docker ps -a |grep baidu查看相关容器是否包含以下且状态均正常
以【通用文字识别模型(CPU)版本】为例:
[root@instance-wch0lkwp Install]# docker ps -a|grep baidu CONTAINER ID IMAGE
COMMAND CREATED STATUS
PORTS NAMES c1643ee21c44 registry.baidu.com/aipe/openresty:1.11.2.3-trusty "/usr/local/openre..." 40 seconds ago
Restarting (1) 6 seconds ago nginx-1 c766cdbbdb73 iregistry.baidu-int.com/aipe/public/centos:cuda10.0-cudnn7-c7-gcc8-ocr
"sh start.sh" 40 seconds ago Up 3 seconds 0.0.0.0:8138->8256/tcp ocr-finance-gpu-1
如果只有一个模型应用实例,则不需要部署负载均衡服务,可以执行以下命令移除nginx容器
docker rm -f nginx-1
多机分离部署
如果您有多台服务器需要部署服务,可以参考第一章节的资源规划示例,尝试规划每台服务器需要部署的服务类型
1、查询当前部署包内包含的模块清单
# se :表示search,根据模块名称查询安装包里是否包括某个模块,不区分大小写,如果没有指定名称则输出安装包里所有模块信息
python install.py se
2、选择您要安装的模块部署
# in :install, 安装某个模块,名称不区分大小写 python install.py in 模型名
接下来请直接进入【九、验证服务可用性】章节。
五、升级模型
升级模型部署,是指您之前部署过老版本的百度文字识别产品模型,需要对模型进行升级操作。
方法一:
1、首先查询新的部署包内包含的模块清单
# se :表示search,根据模块名称查询安装包里是否包括某个模块,不区分大小写,如果没有指定名称则输出安装包里所有模块信息
python install.py se
2、选择您要升级的模型模块并更新授权证书
# up, upgrade: 升级指定模块,不区分大小写,不指定参数时输出所有可升级模块信息 python install.py up
模块名(这里指模型) # lu, licenseupdate: 更新license文件,适用于授权延期、实例数扩容、增加产品授权 python install.py lu
方法二:
进入旧模型部署包(可以参考上文约束的命令规范:baidu_ocr_install_日期找到历史部署包)卸载当前版本的模型,
之后进入新申请的部署包选择要升级的模型安装。
示例:
ll ### 返回结果如下: # drwxr-xr-x 2 root root 4096 10月 26 16:56 baidu_ocr_install_20211025 #
drwxr-xr-x 2 root root 4096 10月 26 16:56 baidu_ocr_install_20211026 # 进入旧部署包
cd baidu_ocr_install_20211025/original/package/Install # 查看当前部署包内置的模块 python install.py se #
卸载指定模型 python install.py rm 模型模块名 # 进入新申请的部署包 cd baidu_ocr_install_20211026/original/package/Install
# 查看当前部署包内置的模块,找到该模型的模块 python install.py se # 安装同名模型 python install.py in 该模型的模块名
接下来请直接进入【九、验证服务可用性】章节。
六、新增模型
1、查询新的部署包内包含的模块清单,依次部署所需要的依赖
# 进入新申请的部署包 cd original/package/Install # se :表示search,根据模块名称查询安装包里是否包括某个模块,
不区分大小写,如果没有指定名称则输出安装包里所有模块信息 python install.py se # in :install, 安装某个模块,
名称不区分大小写 python install.py in docker
如果有其他依赖需要安装的话(如您需要使用GPU等,需要额外安装nvidia模块),步骤同上。此处不再提供示例。
2、部署指定模型模块并更新授权证书
# in :install, 安装某个模块,名称不区分大小写 python install.py in 模型名(模型模块) # lu, licenseupdate:
更新license文件,适用于授权延期、实例数扩容、增加产品授权 python install.py lu
接下来请直接进入【九、验证服务可用性】章节。
七、回滚
license回滚
在新申请获取的部署包内执行license更新操作后,如果发现证书异常可以通过下面的方法回滚,
找到旧部署包(可以参考上文约束的命令规范:baidu_ocr_install_日期),执行license update操作
# 进入旧的部署安装包,执行如下命令替换当前的license文件 # lu,表示 license update cd original/package/Install &&
python install.py lu
应用回滚
1、查询部署包内包含的模块清单
# se :表示search,根据模块名称查询安装包里是否包括某个模块,不区分大小写,如果没有指定名称则输出安装包里所有模块信息
python install.py se
2、选择您要回滚的模块
# rb, rollback: 回滚指定模块,不区分大小写,回滚到最近一次升级前的版本 python install.py rb 模块名
若您在此过程出现问题,请提交工单联系百度的工作人员
八、 销毁
支持一键卸载所有模块
cd original/package/Install # rmall: 删除所有已经安装的模块 python install.py rmall
或者卸载指定模块
# rm, remove: 根据模块名称删除某个已经安装的模块;如果有其他模块依赖这个模块,则不允许删除 python install.py rm 模块名
九、验证服务可用性
健康检查
百度OCR产品为您提供了私有化应用健康检查(或故障排查)脚本:trouble_shooting.tar,保障您在局域网内部署完毕后进行服务可用性检查或者在遇到突发故障时进行故障排查,方便又快捷,祝您使用愉快!
使用方法: 将脚本上传至服务器任意目录(或在服务器直接下载),并解压后运行。
# 解压 tar vxf trouble_shooting.tar # 执行 bash trouble_shooting.sh
接口测试
请根据接口说明文档中的接口路径(GeneralClassifyService/classify 或 GeneralClassifyService/process)来选择对应的代码示例。
GeneralClassifyService/classify
如果接口路径为“/GeneralClassifyService/classify”,请参考如下代码示例:
#!/usr/bin/python2 #-*- coding:UTF-8 -*- import SimpleHTTPServer import SocketServer import sys import urllib2,urllib
import base64 import hashlib import json url = "http://127.0.0.1:8017/GeneralClassifyService/classify" #此处ip需填写部署ocr的机器ip,端口填写ocr服务端口
with open('./test.jpg', "rb") as f: #此处需填写请求图片的地址 img = f.read() base64Data = base64.b64encode(img)
# 第一层base64转换 request_str = 'type=st_ocrapi&detecttype=LocateRecognize&languagetype=CHN
_ENG&imgDirection=setImgDirFlag&recg_type=seq&locate_type=v2&caps_original=true'
#此处需按照接口文档中的参数填写 data = request_str + "&image=" + base64Data postData = {'data':base64.b64encode(data)} # 第二层base64转换 req_json = json.dumps(postData)
#转json格式 req = urllib2.Request(url) req.add_header('Content-Type', 'application/json')
response = urllib2.urlopen(req, req_json, 1000).read() res = json.loads(response)
#print res res1 = res['result'] res2 = base64.decodestring(res1) print res2
GeneralClassifyService/process
如果接口路径为“/GeneralClassifyService/process”,请参考如下代码示例:
#!/usr/bin/python2 #-*- coding:UTF-8 -*- import SimpleHTTPServer import SocketServer
import sys import urllib2,urllib import base64 import hashlib import json url = "http://127.0.0.1:8127/GeneralClassifyService/process" #此处ip需填写部署ocr的机器ip,
端口填写ocr服务端口 with open('./test.jpg', "rb") as f: #此处需填写请求图片的地址
img = f.read() base64Data = base64.b64encode(img) #base64转换 input={ 'logid':'test_9527',
#无实际意义,可不传 'format':'json', 'object_type': 'general_v5',#识别对象类型,根据接口文档调整
'type': 'st_ocrapi', 'image': base64Data } postData = { 'provider':'default', #默认值 'input':
json.dumps(input) } req_json = json.dumps(postData) req = urllib2.Request(url) req.add_header('Content-Type',
'application/json') response = urllib2.urlopen(req, req_json, 1000).read() res = json.loads(response)
#将结果的json数据格式转化为字典类型 print res
十、运维
您可以前往「私有化部署服务」/「常见问题」查找常见问题排查思路
您可以前往 「私有化部署服务」/「运维手册」查看常用运维文档