avant-propos
Récemment, j'ai utilisé le service OCR dans un projet d'entreprise. Au début, j'ai utilisé l'interface de reconnaissance de texte universelle sur Baidu Cloud. Plus tard, j'ai appris par hasard que le module PaddleOCR de la plate-forme fly-pulse open source de Baidu avait un modèle prêt à l'emploi qui peut être utilisé directement, j'ai donc configuré une version CPU du service de reconnaissance OCR sur le serveur de l'entreprise. En raison des performances du serveur de l'entreprise et du problème de la version CPU, les performances ne répondaient pas aux exigences, j'ai donc acheté le serveur GPU de Huawei Cloud pour déployer la version GPU du service OCR.
Comment construire la version GPU de l'environnement PaddlePaddle sur le serveur cloud Huawei, veuillez vous référer à l'article suivant : https://blog.csdn.net/loutengyuan/article/details/126527326
Installer Paddle OCR
PaddleOCR est le service de reconnaissance de texte OCR open source de Baidu basé sur PaddlePaddle. Adresse Github : https://github.com/PaddlePaddle/PaddleOCR/Install
, entrez la commande suivante, après l'installation, vous pouvez découvrir le service de reconnaissance OCR sur la ligne de commande
pip install "paddleocr>=2.0." -i https://mirror.baidu.com/pypi/simple
Téléchargez un pack d'expérience d'images de test :
wget https://paddleocr.bj.bcebos.com/dygraph_v2.1/ppocr_img.zip #下载
unzip ppocr_img.zip #解压
Entrez dans le répertoire que vous venez de décompresser et commencez à faire l'expérience de la reconnaissance OCR
cd ppocr_img #进入刚才下载解压的图片目录
Effectuer la reconnaissance OCR
paddleocr --image_dir ./imgs/11.jpg --use_angle_cls true --use_gpu true
L'exécution peut signaler une erreur, ici vous devez installer deux libs libX11 et libXext
yum install -y libX11
yum install -y libXext
C'est la reconnaissance, utilisez le serveur GPU pour identifier l'ultra-rapide
Déployer le service API de reconnaissance OCR
Pour le déploiement, Paddle fournit deux méthodes, PaddleHub et Paddle Serving. L'utilisation de PaddleHub est la plus pratique et vous pouvez l'exécuter directement à partir de la ligne de commande. Paddle Serving est plus stable lorsqu'il est déployé et prend en charge la compilation et le déploiement c++.
Parlons du déploiement de PaddleHub et Paddle Serving python (déploiement recommandé ou Paddle Serving)
PaddleHub déploie l'API de reconnaissance OCR
Installer PaddleHub
pip install --upgrade paddlehub -i https://mirror.baidu.com/pypi/simple
Démarrer le service API
# 前台启动
hub serving start -m ch_pp-ocrv3 --use_gpu #会自动下载OCR模型
# 后台启动
nohup hub serving start -m ch_pp-ocrv3 --use_gpu > log.log 2>&1 &
Cela démarre un service de reconnaissance OCR
La taille de mémoire GPU maximale par défaut est de 8 000 Mo. Si vous devez modifier la méthode que vous pouvez trouver
/root/.paddlehub/modules/ch_pp_ocrv3/module.py
,_set_config
remplacez 8 000 par la valeur souhaitée.
def _set_config(self, pretrained_model_path):
"""
predictor config path
"""
model_file_path = pretrained_model_path + '.pdmodel'
params_file_path = pretrained_model_path + '.pdiparams'
config = paddle_infer.Config(model_file_path, params_file_path)
try:
_places = os.environ["CUDA_VISIBLE_DEVICES"]
int(_places[0])
use_gpu = True
except:
use_gpu = False
if use_gpu:
# 原本最大显存是8000M,这里改成2000M。
config.enable_use_gpu(2000, 0)
# config.enable_use_gpu(8000, 0)
else:
config.disable_gpu()
if self.enable_mkldnn:
# cache 10 different shapes for mkldnn to avoid memory leak
config.set_mkldnn_cache_capacity(10)
config.enable_mkldnn()
config.disable_glog_info()
config.delete_pass("conv_transpose_eltwiseadd_bn_fuse_pass")
config.switch_use_feed_fetch_ops(False)
predictor = paddle_infer.create_predictor(config)
input_names = predictor.get_input_names()
input_handle = predictor.get_input_handle(input_names[0])
output_names = predictor.get_output_names()
output_handles = []
for output_name in output_names:
output_handle = predictor.get_output_handle(output_name)
output_handles.append(output_handle)
return predictor, input_handle, output_handles
afficher le processus
ps -ef|grep python
fermer le processus
kill -9 19913
afficher le journal
tail -f 1000 log.log
Comment vérifier l'occupation du port
$: netstat -anp | grep 8888
tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN 13404/python3
tcp 0 1 172.17.0.10:34036 115.42.35.84:8888 SYN_SENT 14586/python3
Tuez le processus de force : par pid
$: kill -9 13404
$: kill -9 14586
$: netstat -anp | grep 8888
$:
- Demande de test du facteur
Lors de l'identification, vous devez convertir l'image en base64, puis soumettre les paramètres dans la requête json
Adresse de la requête : http://127.0.0.1:8866/predict/ch_pp-ocrv3
Méthode de la requête : json
Paramètres de la requête : {"images": ["Le contenu base64 de l'image, pas besoin du logo base64 précédent"]}
- Script de test Python
import requests
import json
import cv2
import base64
def cv2_to_base64(image):
data = cv2.imencode('.jpg', image)[1]
return base64.b64encode(data.tostring()).decode('utf8')
# 发送HTTP请求
data = {
'images':[cv2_to_base64(cv2.imread("你的图片地址"))]}
headers = {
"Content-type": "application/json"}
url = "http://127.0.0.1:8866/predict/ch_pp-ocrv3"
r = requests.post(url=url, headers=headers, data=json.dumps(data))
# 打印预测结果
print(r.json())
- demande de test de boucle
curl --location --request POST 'http://127.0.0.1:8866/predict/ch_pp-ocrv3' \
--header 'Content-Type: application/json' \
--data-raw '{"images":["图片的base64内容,不需前面的base64标识"]}'
Le résultat renvoie :
{
"msg":[{
"data":[{
"confidence":0.9314630627632141,"text":"(paddle env][root@M-1-2-centos","text_box_position":[[6,10],[231,10],[231,23],[6,23]]},{
"confidence":0.9092367887496948,"text":"ppocr imgl# hub serving start -m chpp-ocrv3 --use_gpu","text_box_position":[[227,10],[612,12],[612,25],[227,23]]},{
"confidence":0.939938485622406,"text":"[2022-05-30 19:49:34 +0800]","text_box_position":[[5,25],[191,25],[191,38],[5,38]]},{
"confidence":0.8236835598945618,"text":"[28320]","text_box_position":[[200,26],[246,26],[246,37],[200,37]]},{
"confidence":0.6653339862823486,"text":"LINFO]","text_box_position":[[256,26],[295,26],[295,37],[256,37]]},{
"confidence":0.842379093170166,"text":"starting gunicorn 2o.1.0","text_box_position":[[301,26],[474,26],[474,38],[301,38]]},{
"confidence":0.939938485622406,"text":"[2022-05-30 19:49:34 +0800]","text_box_position":[[5,40],[191,40],[191,53],[5,53]]},{
"confidence":0.8367705345153809,"text":"[28320]","text_box_position":[[200,41],[247,41],[247,52],[200,52]]},{
"confidence":0.86468505859375,"text":"[INFO]","text_box_position":[[257,41],[297,41],[297,52],[257,52]]},{
"confidence":0.9211856722831726,"text":"Listening at: http://0.0.0.0:8866 (28320)","text_box_position":[[302,40],[589,40],[589,53],[302,53]]},{
"confidence":0.9346868395805359,"text":"[2022-05-3019:49:34+0800]","text_box_position":[[4,55],[191,54],[191,67],[4,68]]},{
"confidence":0.9421297311782837,"text":"[28320]","text_box_position":[[199,55],[247,55],[247,68],[199,68]]},{
"confidence":0.9394086003303528,"text":"[INFO]","text_box_position":[[256,55],[298,55],[298,68],[256,68]]},{
"confidence":0.9321832656860352,"text":"Using worker: sync","text_box_position":[[302,56],[430,56],[430,68],[302,68]]},{
"confidence":0.9334865808486938,"text":"[2022-05-30 19:49:34 +0800]","text_box_position":[[4,70],[191,70],[191,83],[4,83]]},{
"confidence":0.8994974493980408,"text":"[INFO] ","text_box_position":[[256,70],[305,70],[305,84],[256,84]]},{
"confidence":0.8855429887771606,"text":"[28324]","text_box_position":[[200,71],[246,71],[246,82],[200,82]]},{
"confidence":0.9438435435295105,"text":"Booting worker with pid: 28324","text_box_position":[[300,70],[515,69],[515,83],[300,84]]}],"save_path":""}],"results":"","status":"000"}
De cette façon, il peut être utilisé normalement.La vitesse de reconnaissance est d'environ 100 à 300 ms, ce qui est très rapide.
Tutoriel de déploiement officiel : https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.5/deploy/hubserving/readme.md
Déployer le service de reconnaissance OCR via Paddle Serving
Par rapport au déploiement hubserving, PaddleServing présente les avantages suivants :
- Prise en charge d'une concurrence élevée et d'une communication efficace entre le client et le serveur
- Prend en charge les capacités de service de qualité industrielle telles que la gestion des modèles, le chargement en ligne, les tests A/B en ligne, etc.
- Prend en charge plusieurs langages de programmation pour développer des clients, tels que C++, Python et Java
Préparez d'abord l'environnement PaddleOCR, il sera très lent d'extraire le code github ici, vous pouvez d'abord le télécharger scientifiquement, puis le télécharger sur le serveur
git clone https://github.com/PaddlePaddle/PaddleOCR --depth=1
dans le répertoire de travail
cd PaddleOCR/deploy/pdserving/
Installez l'environnement d'exploitation de PaddleServing, les étapes sont les suivantes
# 安装serving,用于启动服务
wget https://paddle-serving.bj.bcebos.com/test-dev/whl/paddle_serving_server_gpu-0.8.3.post102-py3-none-any.whl
pip3 install paddle_serving_server_gpu-0.8.3.post102-py3-none-any.whl
# 安装client,用于向服务发送请求
wget https://paddle-serving.bj.bcebos.com/test-dev/whl/paddle_serving_client-0.8.3-cp38-none-any.whl
pip3 install paddle_serving_client-0.8.3-cp38-none-any.whl
# 安装serving-app
wget https://paddle-serving.bj.bcebos.com/test-dev/whl/paddle_serving_app-0.8.3-py3-none-any.whl
pip3 install paddle_serving_app-0.8.3-py3-none-any.whl
- conversion de modèle
Lors de l'utilisation de PaddleServing pour le déploiement de services, il est nécessaire de convertir le modèle d'inférence enregistré en un modèle facile à déployer pour servir.
Tout d'abord, téléchargez le modèle d'inférence de PP-OCR
# 下载并解压 OCR 文本检测模型
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_det_infer.tar -O ch_PP-OCRv3_det_infer.tar && tar -xf ch_PP-OCRv3_det_infer.tar
# 下载并解压 OCR 文本识别模型
wget https://paddleocr.bj.bcebos.com/PP-OCRv3/chinese/ch_PP-OCRv3_rec_infer.tar -O ch_PP-OCRv3_rec_infer.tar && tar -xf ch_PP-OCRv3_rec_infer.tar
Ensuite, utilisez le client paddle_serving_client installé pour convertir le modèle d'inférence téléchargé en un format de modèle facile à déployer sur le serveur.
# 转换检测模型
python3 -m paddle_serving_client.convert --dirname ./ch_PP-OCRv3_det_infer/ \
--model_filename inference.pdmodel \
--params_filename inference.pdiparams \
--serving_server ./ppocr_det_v3_serving/ \
--serving_client ./ppocr_det_v3_client/
# 转换识别模型
python3 -m paddle_serving_client.convert --dirname ./ch_PP-OCRv3_rec_infer/ \
--model_filename inference.pdmodel \
--params_filename inference.pdiparams \
--serving_server ./ppocr_rec_v3_serving/ \
--serving_client ./ppocr_rec_v3_client/
Une fois la conversion du modèle de détection terminée, il y aura des dossiers supplémentaires de ppocr_det_v3_serving et ppocr_det_v3_client dans le dossier actuel, avec le format suivant :
|- ppocr_det_v3_serving/
|- __model__
|- __params__
|- serving_server_conf.prototxt
|- serving_server_conf.stream.prototxt
|- ppocr_det_v3_client
|- serving_client_conf.prototxt
|- serving_client_conf.stream.prototxt
- Déploiement du pipeline Paddle Serving
# 启动服务,运行日志保存在log.txt
nohup python3 -u web_service.py > log.log 2>&1 &
S'il n'y a pas d'erreur dans le journal d'exécution, le démarrage est réussi.Ensuite,
vous pouvez utiliser le code client fourni par lui pour demander un test afin de
visualiser la progression
ps -ef|grep python
fermer le processus
kill -9 19913
afficher le journal
tail -f 1000 log.log
Comment vérifier l'occupation du port
$: netstat -anp | grep 8888
tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN 13404/python3
tcp 0 1 172.17.0.10:34036 115.42.35.84:8888 SYN_SENT 14586/python3
Tuez le processus de force : par pid
$: kill -9 13404
$: kill -9 14586
$: netstat -anp | grep 8888
$:
- Test de requête HTTP
Adresse de la requête : http://127.0.0.1:9998/ocr/prediction
Méthode de la requête : json
Paramètres de la requête : {"clé": "image", "valeur": "base64 de l'image"}
- test de requête curl
curl --location --request POST 'http://127.0.0.1:9998/ocr/prediction' \
--header 'Content-Type: application/json' \
--data-raw '{"key":"image","value":"图片的base64"}'
Format des données renvoyées :
{
"err_no": 0,
"err_msg": "",
"key": [
"result"
],
"value": [
"[[('(padde env)[root@M-1-2-centoppocrimghub servingstart -m chpp-ocrv3--usegpu', 0.84638405), [[5.0, 10.0], [611.0, 12.0], [611.0, 24.0], [5.0, 22.0]]], [('[2022-05-3019:49:34+0800][28320】[INF0]Startingqunicorm20.1.', 0.81580645), [[5.0, 25.0], [472.0, 25.0], [472.0, 38.0], [5.0, 37.0]]], [('[2022-05-3019:49:34+0800][28320][INF0]Listeningat:http://0.0.0.0:8866(28320)', 0.84695405), [[5.0, 40.0], [589.0, 40.0], [589.0, 54.0], [5.0, 54.0]]], [('[2022-05-319:49:34+0800][28320】[INF0]Usingworker:sync', 0.7949861), [[5.0, 54.0], [430.0, 56.0], [430.0, 68.0], [5.0, 66.0]]], [('[2022-05-319:49:34+080】[28324】[INFO】Bootingworkerwith pid:28324', 0.85473406), [[4.0, 70.0], [515.0, 70.0], [515.0, 84.0], [4.0, 84.0]]]]"
],
"tensors": []
}
Ceci est complet et peut être utilisé normalement. Si vous fournissez d'autres appels linguistiques, vous pouvez consulter leurs documents officiels.
Tutoriel de déploiement officiel : https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.5/deploy/pdserving/README_CN.md
épilogue
Le déploiement est relativement simple et la documentation officielle de Paddle est assez complète, mais certaines reconnaissances de texte spéciales doivent encore être personnalisées et entraînées par vous-même.