当前位置:   article > 正文

部署paddleocr_paddleocr部署

paddleocr部署

最近接了 一个需求,客户想上传pdf,系统识别pdf内容并保存,用于后续内容检索。其实在我看来不如招一个打字员,服务器接收到文件直接让打字员识别,这样准确率又高,至于效率嘛那得看给别人开多少的工资了。
奈何我不是老板,所以只能苦哈哈的去找能够代替打字员工作的方案了。
目前市面上常用的tess4j、百度OCR、Tesseract-OCR、百度paddle。前三个要么收费,要么就是准确率要低一些。用现在的话来说,不是买不起,而是paddle更具性价比。
PaddleOCR主流的两种部署方式,一种是基于cpu部署,但是识别速度大概有此处省略1万字那么长,另外一种是基于gpu部署,将gpu参与计算,速度还是很客观的。这里主要讲的也是gpu部署。

Serving 服务化部署(Python/C++)

基于GPU PaddleHub Serving的部署

1.环境准备 Ubuntu、python3、显卡、 CUDA、CUDNN、conda3

1.1安装Nvidia基本驱动
查看可以安装的显卡驱动型号,后缀recommend是系统推荐安装的版本
ubuntu-drivers device

自动安装显卡驱动
ubuntu-drivers autoinstall  /  (apt install nvidia-driver-xxx 选择具体版本)

安装成功后输入reboot 重启机器命令nvidia-smi 即可验证是否安装成功,同时可以看到cuda最高支持的版本

1.2安装cuda
apt-get update
官网下载相关的安装包 https://developer.nvidia.com/cuda-11-7-0-download-archive
我这里选择的本地安装下载runfile包上传服务器并执行文件(具体版本根据显卡以及paddle官网支持的版本,目前最高支持11.7)
wget https://developer.download.nvidia.com/compute/cuda/11.7.0/local_installers/cuda_11.7.0_515.43.04_linux.run
sh cuda_11.7.0_515.43.04_linux.run

设置环境变量
sudo nano ~/.bashrc
打开文件写入环境变量
# 文本最后添加以下内容:
export CUDA_HOME=/usr/local/cuda
export PATH=${CUDA_HOME}/bin:${PATH}
export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:$LD_LIBRARY_PATH
使生效
source ~/.bashrc
检测是否成功
nvcc -V

1.3安装cudnn
官网下载相关tar包 https://developer.nvidia.com/rdp/cudnn-download
解压文件,对应版本要进行替换
tar -xvf cudnn-linux-x86_64-8.x.x.x_cudaX.Y-archive.tar.xz
将加压后的文件拷贝到cuda并修改权限
sudo cp cudnn-*-archive/include/cudnn*.h /usr/local/cuda/include 
sudo cp -P cudnn-*-archive/lib/libcudnn* /usr/local/cuda/lib64 
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
这里的路径要注意匹配上面的环境变量的路径

1.4安装python3
apt-get install zlib1g-dev libbz2-dev libssl-dev libncurses5-dev libsqlite3-dev libreadline-dev tk-dev libgdbm-dev libdb-dev libpcap-dev xz-utils libexpat1-dev liblzma-dev libffi-dev libc6-dev

下载python压缩包:
wget https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tgz
解压缩:
tar -vxzf Python-3.8.10.tgz

cd Python-3.8.10
编译安装:
./configure --prefix=/usr/local/python3 --with-ssl  #此处指定python安装目录
make
make install

建立软连接(相当于快捷方式),建立完后可以直接使用python3命令:
sudo ln -s /usr/local/python3/bin/python3 /usr/bin/python3
sudo ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3

没有软连接的话pip3和python3均要使用绝对路径, 如 /usr/local/python3/bin/python3

使用pip3安装模块时,若因网络原因安装失败 可尝试指定安装源 -i https://pypi.tuna.tsinghua.edu.cn/simple

1.5安装anconda
下载:
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-2021.11-Linux-x86_64.sh --no-check-certificate
注意conda相对应的系统内核版本,根据实际情况在https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive查找相应版本

sh Anaconda3-2021.11-Linux-x86_64.sh
之后一直输入yes
若最后一步直接回车,则默认输入了no
需要手动执行:
eval "$(/home/admin/anaconda3/bin/conda shell.bash hook)"
conda init
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

2.安装 Hub Serving

安装paddlehub模块
conda install paddlepaddle-gpu==2.5.2 cudatoolkit=11.7 -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/Paddle/ -c conda-forge
下载分类、检测、识别推理模型并解压
https://github.com/PaddlePaddle/PaddleOCR/blob/static/doc/doc_ch/quickstart.md

mkdir PaddleOCR
cd PaddleOCR
mkdir inference
cd inference
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

将下载的推理模型上传至服务器 inference文件下
在这里插入图片描述

下载PaddleOCR
https://codeload.github.com/PaddlePaddle/PaddleOCR/zip/refs/heads/release/2.7

上传至服务器并解压
unzip PaddleOCR-release-2.7.zip

移动至PaddleOCR-develop
mv PaddleOCR-release-2.7 PaddleOCR-develop

cd PaddleOCR-develop
# 安装检测服务模块,如果缺模块直接pip3 install 相关模块即可:  
hub install deploy/hubserving/ocr_det/

# 或,安装识别服务模块:  
hub install deploy/hubserving/ocr_rec/

# 或,安装检测+识别串联服务模块:  
hub install deploy/hubserving/ocr_system/

修改config.json文件
vi deploy/hubserving/ocr_system/config.json
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这里插入图片描述

修改deploy/hubserving/ocr_system文件夹下params.py文件
修改det_model_dir、rec_model_dir、rec_char_dict_path、cls_model_dir路径
在PaddleOCR文件夹下
为保证运行 修改成绝对路径
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述

3.启动服务

这里采用的是指定路径启动,需要切换到PaddleOCR-develop目录下通过命令
hub serving start -c deploy/hubserving/ocr_system/config.json


建议后台启动,采用screen新建窗口
screen -S OCR
export CUDA_VISIBLE_DEVICES=0
 /usr/local/python3/bin/hub serving start -c deploy/hubserving/ocr_system/config.json

crtl+a+d 窗口离线
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

4.java接口调试

不能直接识别pdf,这里采用pdf转图片并识别

package com.dqzh.construction.utils;


import com.dqzh.construction.custom.ResultData;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 2 * @Author: zxc
 * 3 * @Date: 2023-10-16 1:21
 * 4
 */
@RestController
@RequestMapping("/test")
public class OCRController {


    @Resource
    private RestTemplate restTemplate;

    @RequestMapping("/uploadV2")
    public ResultData upload(@RequestParam(value = "file", required = false) MultipartFile file) throws IOException {
        try {
            //创建请求头
            HttpHeaders headers = new HttpHeaders();
            //设置请求头格式
            headers.setContentType(MediaType.APPLICATION_JSON);
            //构建请求参数
            MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
            //读入静态资源文件
            StringBuilder builder = new StringBuilder();
            try (PDDocument document = PDDocument.load(file.getInputStream())
            ) {
                PDFRenderer pdfRenderer = new PDFRenderer(document);
                for (int page = 0; page < document.getNumberOfPages(); ++page) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300);
                    ImageIO.write(bim, "jpg", baos);
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
                    // 使用inputStream进行后续操作
                    map.put("images", Collections.singletonList(ImageToBase64(inputStream)));
                    //构建请求
                    HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
                    //发送请求
                    //Send the request
                    //根据服务器地址修改ip
                    Map json = restTemplate.postForEntity("http://127.0.0.1:8868/predict/ocr_system", request, Map.class).getBody();
                    //解析Json返回值
                    //Parse the Json return value
                    List<List<Map>> json1 = (List<List<Map>>) json.get("results");
                    List<Map> maps = json1.get(0);

                    for (Map map1 : maps) {
                        builder.append(map1.get("text"));
                    }
                    // 关闭流
                    inputStream.close();
                }
                return ResultData.success(builder);
            } catch (Exception e) {
                e.printStackTrace();
                return ResultData.success("读取失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
            return ResultData.success("读取失败");

        }

    }

    public static String ImageToBase64(InputStream imgPath) {
        byte[] data = null;
        // 读取图片字节数组
        //Read the image byte array
        try {
            data = new byte[imgPath.available()];
            imgPath.read(data);
            imgPath.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        //Base64 encoding of byte array
        Base64.Encoder encoder = Base64.getEncoder();
        // 返回Base64编码过的字节数组字符串
        //Returns a Base64 encoded byte array string
//        System.out.println(encoder.encodeToString(data));
        return encoder.encodeToString(data);
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/364267
推荐阅读
相关标签
  

闽ICP备14008679号