1、安装镜像构建工具
打开https://github.com/nuclio/nuclio/releases项目
下载1.11.20版本nuctl工具,并安装到电脑上
2、拉取运行时镜像
docker pull quay.io/nuclio/handler-builder-python-onbuild:1.11.20-amd64
3、构建镜像
3.1 在模型运行项目目录中新建镜像入口脚本,示例如下
vi workspace/main.py
import json #用于序列化输入和输出参数
import io, base64 #用于接受序列化图片
from PIL import Image #处理图片库
import init_model #导入模型初始化方法,如果改入口脚本与模型初始化模块不在一个目录下,可以通过修改PYTHONPATH,将初始化模块放到路径中
def init_context(context): #初始化函数,在这个函数中加载模型
context.logger.info("Init context... 0%")
model = init_model() #初始化模型
context.user_data.model = model #模型放置到context.user_data.model变量中
context.logger.info("Init context...100%")
def handler(context, event): #模型处理图片入口函数
data = event.body
# data中有一个key,image
# image表示图片文件使用base64编码成的字符串,编码方法为base64.b64encode(BytesIO(cv2_img.tobytes()).getvalue()).decode('utf-8')
image = Image.open(io.BytesIO(base64.b64decode(data["image"]))) #将图片字符串解码PIL的图片
# image = cv2.cvtColor(cv2.imdecode(np.fromstring(base64.b64decode(data["image"]),np.uint8),cv2.IMREAD_COLOR), cv2.COLOR_BGR2RGB) #解码为cv2图片
results = context.user_data.model.infer(image, threshold) #使用模型进行检测,检测结果list
return context.Response(body=json.dumps(results), headers={},content_type='application/json', status_code=200) #结果序列化为json,返回
3.2 物体检测模型返回结果示例说明
[
{
"confidence": "0.9", #检测结果的置信度
"label":"car", #检测结果的标签类别
"points":[x1,y1,x2,y2], #矩形框在原图片中的像素坐标,坐标系原点为图片左上角
"type":"rectangle" #检测结果类型,rectangle表示矩形
},{
"confidence": "0.9",
"label":"person",
"points":[x1,y1,x2,y2],
"type":"rectangle"
}
]
3.3 物体分割检测模型返回结果示例说明
[
{
"confidence": "0.9", #检测结果的置信度
"label":"car", #检测结果的标签类别
"points":[x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,....], #围成多边形的点坐标
"type":"polygon" #检测结果类型,polygon表示多边形
},{
"confidence": "0.9",
"label":"person",
"points":[x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,....],
"type":"polygon"
}
]
3.4 编写镜像构建声明文件,示例如下
vi build.yaml
metadata:
name: model-name #名称
spec:
description: 检测模型 #描述
runtime: 'python:3.7' #运行时,必须与模型的python版本一致
handler: main:handler #入口模块和入口函数
build:
baseImage: python:3.7 #基础镜像,包括模型以及模型运行时的镜像
directives: #可填写复制文件前的Docker指令
preCopy:
- kind: ENV #对应Dockerfile中的指令类型,如ENV、RUN、WORKDIR
value: PYTHONPATH=/workspace/test
3.5 构建镜像
运行命令构建
nuctl build -f build.yaml -p {workpath} --offline
构建时,会把workpath目录中的所有内容复制到镜像中,构建成功后输出镜像为nuclio/processor-{name}:latest
3.6 测试镜像
新建运行声明文件,示例如下
vi processor.yaml
spec:
runtime: 'python:3.7' #运行时
handler: main:handler #入口模块
eventTimeout: 30s #处理超时时间
triggers: #触发器配置
myHttpTrigger: #触发器名称
maxWorkers: 2 #工作进程个数
kind: 'http' #触发器类别
attributes:
maxRequestBodySize: 33554432 # 最大请求体32MB
启动接口服务,命令示例如下
docker run -it --rm -v `pwd`/processor.yaml:/etc/nuclio/config/processor/processor.yaml -p 8080:8080 nuclio/processor-{name}:latest
使用接口测试工具测试POST http://localhost/8080接口
或者使用下面命令测试
echo "{\"image\":\"$(base64 -w 0 img_path)\"}" | curl -X POST -H Content-type:application/json -d @- "http://localhost:8080"
镜像推送到harbor
3.7 编写服务声明文件
vi function.yaml,仅说明可修改部分
apiVersion: "nuclio.io/v1beta1"
kind: NuclioFunction
metadata:
name: yolo-v8-tf #模型名称,在平台中必须唯一
namespace: nuclio
annotations:
name: YOLO v8 #模型在平台页面中显示的名称
type: detector #检测模型,物体检测或者分割检测
framework: pytorch #模型框架,用于显示
spec: | #必须修改,设置模型检测支持的检测对象类别,必须与模型返回结果中的对象类别对应,且必须完整包括模型输出的所有对象类别
[
{ "id": 0, "name": "person" },
{ "id": 1, "name": "bicycle" },
{ "id": 2, "name": "car" },
{ "id": 3, "name": "motorbike" },
{ "id": 4, "name": "aeroplane" },
{ "id": 5, "name": "bus" },
{ "id": 6, "name": "train" },
{ "id": 7, "name": "truck" },
{ "id": 8, "name": "boat" },
{ "id": 9, "name": "traffic light" },
{ "id": 10, "name": "fire hydrant" },
{ "id": 11, "name": "stop sign" },
{ "id": 12, "name": "parking meter" },
{ "id": 13, "name": "bench" }
]
labels:
nuclio.io/project-name: cvat
spec:
image: images.registry/nuclio/processor-{name}:latest #前面步骤构建的镜像名称,镜像构建后必须将镜像推送到平台的镜像仓库中
description: YOLO v8图片物体检测模型 #模型描述,用于显示
runtime: 'python:3.7' #运行时
handler: main:handler #服务入口
eventTimeout: 30s
triggers:
myHttpTrigger:
maxWorkers: 3
kind: 'http'
workerAvailabilityTimeoutMilliseconds: 10000
attributes:
maxRequestBodySize: 33554432 # 32MB
platform:
attributes:
restartPolicy:
name: always
maximumRetryCount: 3
status:
state: waitingForResourceConfiguration
3.8 方法资源推送到k8s
kubectl apply -f function.yaml