PaddlePaddle介绍
PaddlePaddle(飞桨)以百度多年的深度学习技术研究和业务应用为基础,是中国首个自主研发、功能完备、开源的产业级深度学习平台,集深度学习核心训练和推理框架、基础模型库、端到端开发套件和丰富的工具组件于一体。PaddlePaddle的标志如下所示。
PaddlePaddle标志
PaddlePaddle深度学习框架采用基于编程逻辑的组网范式,对于普通开发者而言更容易上手,同时支持声明式和命令式编程,兼具开发的灵活性和高性能。另外,PaddlePaddle不仅广泛兼容第三方开源框架训练的模型,并且为不同场景的生产环境提供了完备的推理引擎,包括适用于高性能服务器及云端推理的原生推理库Paddle Inference,面向分布式、流水线生产环境的自动上云、A/B测试等高阶功能的服务化推理框架Paddle Serving,针对于移动端、物联网场景的轻量化推理引擎Paddle Lite,以及在浏览器、小程序等环境下使用的前端推理引擎Paddle.js。同时,透过与不同场景下主流硬件高度适配及异构计算的支持,PaddlePaddle的推理性能领先绝大部分的主流实现。
PaddlePaddle可以被认为是一个Python的依赖库,官方提供了pip、conda、源码编译等多种安装方法。以pip安装方法为例,PaddlePaddle提供了基于CPU和GPU两个版本的安装方法:
基于CPU版本的安装方法:
pip install paddlepaddle
基于GPU版本的安装方法:
pip install paddlepaddle-gpu
PaddlePaddle实践:手写数字识别任务
MNIST是非常有名的手写体数字识别数据集。无论TensorFlow还是PaddlePaddle的新手入门,都是通过它做实战讲解。它由手写体数字图像和相对应标签组成,如下所示。
MNIST手写体数字识别数据集
MNIST数据集分为训练图像和测试图像。训练图像60 000张,测试图像10 000张,每一张图像代表0~9中的某一个数字,且图像大小均为28×28的矩阵。这一节将以PaddlePaddle官方提供的MNIST手写数字识别任务为例,进行PaddlePaddle框架的基本学习。与其他深度学习任务一样,PaddlePaddle同样要通过以下4个步骤完成一个相对完整的深度学习任务。
·数据集的准备和加载;
·模型构建;
·模型训练;
·模型评估。
1.数据集的准备和加载
PaddlePaddle框架内置了一些常见的数据集。在这个示例中,开发者可以加载Paddle-Paddle框架的内置数据集,例如本案例所涉及的MNIST数据集。这里加载两个数据集:一个用来训练模型,一个用来评估模型。
import paddle.vision.transforms as T transform = T.Normalize(mean=[127.5], std=[127.5], data_format='CHW') # 下载数据集 train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform) val_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform)
2.模型构建
通过Sequential将一层一层网络结构组建起来。注意,需要先对数据进行Flatten操作,将[1, 28, 28]形状的图像数据改变为[1, 784]形状。
mnist = paddle.nn.Sequential( paddle.nn.Flatten(), paddle.nn.Linear(784, 512), paddle.nn.ReLU(), paddle.nn.Dropout(0.2), paddle.nn.Linear(512, 10) )
3.模型训练
在训练模型前,需要配置训练模型时损失的计算方法与优化方法。开发者可以使用PaddlePaddle框架提供的prepare完成,之后使用fit接口开始训练模型:
model = paddle.Model(mnist) # 模型训练相关配置,准备损失计算方法、优化器和精度计算方法 model.prepare(paddle.optimizer.Adam(parameters=model.parameters()), paddle.nn.CrossEntropyLoss(), paddle.metric.Accuracy()) # 开始模型训练 model.fit(train_dataset, epochs=5, batch_size=64, verbose=1)
训练结果:
The loss value printed in the log is the current step, and the metric is the average value of previous steps. Epoch 1/5 step 938/938 [==============================]
- loss: 0.1801 - acc: 0.9032 - 8ms/step Epoch 2/5 step 938/938 [==============================]
- loss: 0.0544 - acc: 0.9502 - 8ms/step Epoch 3/5 step 938/938 [==============================]
- loss: 0.0069 - acc: 0.9595 - 7ms/step Epoch 4/5 step 938/938 [==============================]
- loss: 0.0094 - acc: 0.9638 - 7ms/step Epoch 5/5 step 938/938 [==============================]
- loss: 0.1414 - acc: 0.9670 - 8ms/step
4.模型评估
开发者可以使用预先定义的测试数据集评估前一步训练得到的模型的精度。
model.evaluate(val_dataset, verbose=0)
结果如下:
{'loss': [2.145765e-06], 'acc': 0.9751}
可以看出,初步训练得到的模型精度在97.5%附近。在逐渐了解PaddlePaddle后,开发者可以通过调整其中的训练参数来提升模型的精度。
与Serverless架构结合:PaddleOCR项目开发与部署
PaddlePaddle团队首次开源文字识别模型套件PaddleOCR,目标是打造丰富、领先、实用的文本识别模型(或工具库)。该模型套件是一个实用的超轻量OCR系统,主要由文本检测、检测框矫正和文本识别3部分组成。该系统从骨干网络的选择和调整、预测头部的设计、数据增强、学习率变换策略、正则化参数选择、预训练模型使用以及模型自动裁剪量化几个方面,采用19个有效策略,对各个模块的模型进行效果调优和瘦身,最终得到整体大小为3.5MB的超轻量中英文字符识别和2.8MB的英文数字字符识别。
1.本地开发
根据PaddleOCR的项目案例,采用轻量级Python Web框架Bottle框架进行项目开发:
# index.py
import base64
import bottle
import random
from paddleocr import PaddleOCR
ocr = PaddleOCR(use_gpu=False)
@bottle.route('/ocr', method='POST')
def ocr():
filePath = './temp/' + (''.join(random.sample('zyxwvutsrqponmlkjihgfedcba', 5)))
with open(filePath, 'wb') as f:
f.write(base64.b64decode(bottle.request.body.read().decode("utf-8").split(',')[1]))
ocrResult = ocr.ocr(filePath, cls=False)
return {'result': [[line[1][0], float(line[1][1])] for line in ocrResult]}
bottle.run(host='0.0.0.0', port=8080)
开发完成之后,运行该项目:
python index.py
服务启动之后,日志如下所示。
服务成功启动后的日志
通过将图像转换为Base64编码,并以POST方法请求刚刚启动的Web服务。可以看到PaddleOCR的执行结果如下所示。
OCR模型测试执行结果
2.部署到Serverless架构
由于项目所依赖的库众多,且体积相对来说比较大,我们很难直接通过原生项目简单地部署,所以为了降低项目的部署难度,会通过Serverless Devs开发者工具,将项目打包成镜像,并通过镜像模式部署到Serverless架构。在开始部署之前,我们需要准备好Doc-kerfile文件以及符合Serverless Devs开发规范的资源描述文件。
参考PaddleOCR项目,可以对Dockerfile文件进行简单的定义和编写:
FROM python:3.7-slim
RUN apt update && apt install gcc libglib2.0-dev libgl1-mesa-glx libsm6 libxrender1 -y && pip install paddlepaddle bottle scikit-build paddleocr
# Create app directory
WORKDIR /usr/src/app
# Bundleapp source
COPY . .
接下来需要对部署项目进行预期的描述,即确定项目的地区、服务配置、函数配置、触发器配置以及自定义域名配置等:
edition: 1.0.0
name: paddle-ocr
access: default
services:
paddle-ocr:
component: fc
props:
region: cn-shanghai
service:
name: paddle-ocr
description: paddle-ocr service
function:
name: paddle-ocr-function
runtime: custom-container
caPort: 8080
codeUri: ./
timeout: 60
customContainerConfig:
image: 'registry.cn-shanghai.aliyuncs.com/custom-container/paddle-ocr:0.0.1'
command: '["python"]'
args: '["index.py"]'
triggers:
- name: httpTrigger
type: http
config:
authType: anonymous
methods:
- GET
- POST
customDomains:
- domainName: auto
protocol: HTTP
routeConfigs:
- path: /*
完成相关准备工作之后,需要通过Serverless Devs开发者工具进行项目的构建,即将业务代码等打包成容器镜像(结果如下所示):
s build --use-docker
构建完成之后,可以通过Serverless Devs开发者工具直接进行部署:
s deploy --use-local -y
部署完成后,日志如下所示。可以看到,系统返回测试地址。
此时,可以通过该测试地址进行测试,同样得到了预期效果,如下所示。
镜像构建日志
部署完成后的日志
项目测试结果
3.项目优化
通过对部署在Serverless架构上的项目进行请求,我们可以看到冷启动和热启动的时间消耗,如下所示。
冷启动和热启动的时间消耗
通过冷启动与热启动的对比可以发现,在热启动时,整个系统的性能是相对高的。但是遇到冷启动时整个系统的响应时长是不可控的,此时可以考虑以下途径进行优化。
·缩减容器镜像的体积,减少不必要的依赖、文件等,清理安装依赖时留下的缓存等,因为函数计算的冷启动时间包括镜像拉取时间。
·部分流程优化,例如PaddleOCR项目中明确说明:“PaddleOCR会自动下载ppocr轻量级模型作为默认模型”,这就意味着该项目在Serverless架构的冷启动相比热启动还增加了一个模型下载和解压的流程。这一部分在必要时可以拉入容器镜像,进而减少冷启动带来的影响。
·开启镜像加速,可以有效降低容器镜像冷启动带来的影响。阿里云函数计算官方文档中有相关镜像加速的性能测试描述:“开启函数计算的镜像加速后,可提速2~5倍,将分钟级的镜像拉取缩短至秒级”。
·实例预留,可以最大限度降低冷启动率。通过实例预留,我们可以利用多种算法(策略)进行实例的预热和预启动,最大限度降低Serverless架构冷启动带来的影响。
上述项目优化点更多是在对抗冷启动,降低冷启动给项目带来的影响。而在真实的生产过程中,除上述优化方法外,还可以考虑将项目部署在Serverless架构的GPU实例上,以获得更高的预测性能。
标签:Serverless,架构,模型,PaddlePaddle,paddle,冷启动,ocr From: https://blog.51cto.com/muzinan110/6025458