admin管理员组

文章数量:1567920

文章目录

  • 🎀1. 安装依赖
    • 2.1 确认基础镜像
    • 2.2 安装其他包
  • 🤓2. layout-parser库
  • 😊3. 基础使用
    • 3.0 运行结果
    • 3.1 可能的错误原因——docker的GPU分配和容量问题
    • 3.2 错误解决——释放GPU容量
    • 3.3 GPU显存占满而利用率为0
    • 3.4 ✅错误解决
  • ✅ 4. streamlit显示PP-structure结果

主链接:

  • github上的readme文档——PP-Structure

🎀1. 安装依赖

由于后续这些都是基于docker进行的,所以这里直接记录dockerfile文件内容:

2.1 确认基础镜像

基础镜像就是paddlepaddle的镜像了,

  • 根据:开始使用可知,镜像的名称应该类似于:registry.baidubce/paddlepaddle/paddle:2.1.2-gpu-cuda11.2-cudnn8
  • 根据:paddlepaddle-docker主页仓库
    docker pull paddlepaddle/paddle:2.1.2-gpu-cuda11.2-cudnn8

先看一下当前服务器环境中是否有这个镜像,没有的话,还需要自己下载。

docker image ls|grep paddle


可以看到,都是很老的镜像,没有新的,哈哈。

docker pull paddlepaddle/paddle:2.1.2-gpu-cuda11.2-cudnn8

那就直接使用这个下载就好了,等着

关于镜像源的修改,可以参考另一篇文章:三)使用docker来进行paddleocr的安装使用,这里面记录的比较详细。

docker run -it -d --gpus "device=3" --ipc=host -p 10036:22 -v  /ws/huangshan:/paddle21 --name "paddle2.1" paddlepaddle/paddle:2.1.2-gpu-cuda11.2-cudnn8 bash -c "/etc/rc.local; /bin/bash"

使用上述代码运行运行容器,遇到了非常弱智的错误

先是因为端口已经被分配过,所以重新run,run的时候提示之前的名字已经某个容器使用了。。。所以上面那个容器其实还是生成成功了,所以需要先停止并删除刚刚那个容器

docker ps -a|grep paddle
docker stop 容器ID
docker rm 容器ID


继续报错,驱动版本太新了,

docker: Error response from daemon: OCI runtime create failed:
container_linux.go:367: starting container process caused: 
process_linux.go:495: container init caused: 
Running hook #0:: error running hook: exit status 1, 
stdout: , stderr: 
nvidia-container-cli: requirement error: 
unsatisfied condition: cuda>=11.2, 
please update your driver to a newer version, or use an earlier cuda container: unknown.

要么就是更新GPU驱动,要么就是把容器换成一个早一点的,换镜像。
docker pull paddlepaddle/paddle:2.1.2-gpu-cuda10.2-cudnn7
其他同上

# 使用上面的镜像运行一个使用了GPU的容器
> docker run -it -d --gpus "device=4" --ipc=host -p 10036:22 -v  /ws/huangshan/paddle21:/paddle21 --name "paddle2.1" paddlepaddle/paddle:2.1.2-gpu-cuda10.2-cudnn7 bash -c "/etc/rc.local; /bin/bash"
# 查看是否启动
> docker ps -a|grep paddle


可以看到,已经OK了。然后进入容器的CLI:

 docker container exec -it paddle2.1 /bin/bash

2.2 安装其他包

# 先查看一下python版本
python --version
> Python 2.7.0

主要包括:Layout-ParserPaddleOCR

注意,直接pip安装使用的是2.7的版本,所以安装时候注意修改环境,pip3默认是python3.5的环境,建议pip3.7安装

# 安装Layout-Parser,这个安装会下载opencv依赖包
pip3.7 install -U https://paddleocr.bj.bcebos/whl/layoutparser-0.0.0-py3-none-any.whl  -i https://pypi.tuna.tsinghua.edu/simple
# 直接使用上面这个语句 安装会很慢,所以最好加上清华源
# -i https://pypi.tuna.tsinghua.edu/simple

# 安装PaddleOCR
pip3.7 install "paddleocr>=2.2" # 推荐使用2.2+版本

# 建议使用下面这个确定的版本安装,
pip3.7 install "paddleocr==2.2"  -i https://pypi.tuna.tsinghua.edu/simple# 推荐使用2.2+版本
# 因为暂时不需要进行训练,所以不需要安装完整的git上的paddleocr版本
# 这个在安装完paddleocr之后,也会安装一些别的包, opencv_contrib_python这个包安装会很慢,所以可以直接终止,然后加上清华源, -i https://pypi.tuna.tsinghua.edu/simple

pip3.7 install streamlit  -i https://pypi.tuna.tsinghua.edu/simple

如果不打算自己训练一个模型,其实安装完paddleocr的whl包就可以停下了,如果是有自己训练的打算的,可以去

git clone https://github/PaddlePaddle/PaddleOCR

不过这个很慢,应该要等一会的。

🤓2. layout-parser库

这个库其实是用于版面分析的一个开源库,参见:github: Layout-Parser/layout-parser

工具介绍就只有一句话:

A unified toolkit for Deep Learning Based Document Image Analysis
一个基于深度学习的文档图像分析工具包

Layout-Parser会进行版面分析,在版面分析中,会对图片里的区域进行分类,包括文字、标题、图片、列表和表格5类

😊3. 基础使用

如果安装了paddleocr的git项目,下面这个代码就可以直接运行了,如果没有安装的话,需要稍微改改路径啥的。

import os
import cv2
from paddleocr import PPStructure,draw_structure_result,save_structure_res

table_engine = PPStructure(show_log=True)

save_folder = './output/table'
img_path = '../doc/table/1.png'
img = cv2.imread(img_path)
result = table_engine(img)
save_structure_res(result, save_folder,os.path.basename(img_path).split('.')[0])

for line in result:
    line.pop('img')
    print(line)

from PIL import Image

font_path = '../doc/fonts/simfang.ttf' # PaddleOCR下提供字体包
image = Image.open(img_path).convert('RGB')
im_show = draw_structure_result(image, result,font_path=font_path)
im_show = Image.fromarray(im_show)
im_show.save('result.jpg')

运行脚本,从输出的log信息中可以看到,IR相关的字眼,猜测使用了OpenVino,同时看到从cpu加载到gpu相关的字眼。

另外,中途卡在这步卡了很久,但是GPU的内存确实多占用了一些,所以确实还是在运行中的,继续等待。
同时,仔细观察,发现GPU内存的占用还在一点点上涨,可能就是cpu到gpu的传输非常慢导致的吧。


同时,持续观察这个4号GPU,可以看到,这个电压功率都在发生变化,而且一直在缓慢,但是GPU容量一直是不断的增长。

等待的过程中计算了一下下载的模型,主要包含以下内容:

  • 轻量的检测模型,ch_ppocr_mobile_v2.0_det_infer.tar 3.16MB
  • 轻量的识别模型,ch_ppocr_mobile_v2.0_rec_infer.tar 3.9MB
  • 稍微不那么轻量的表格结构化识别模型,en_ppocr_mobile_v2.0_table_structure_infer.tar 19.7MB

    另外还有:
  • ppyolov2_r50vd_dcn_365e_publaynet_infer/ppyolov2_r50vd_dcn_365e_publaynet.tar 221MB
    • 关于publaynet,其实是个大型的版面分析数据集,参考:PubLayNet:36万文档图像版面分析数据集

解决完GPU的问题,运行出结果如下:

3.0 运行结果

大概当GPU占用到800多MB的时候,出结果了,生成了结果图像和识别出的文本结果,但是图像完全是原图,txt文件里也什么都没有。重新运行,观察,

其实GPU利用率偶尔会变成1%然后很快闪回0%。最终,大约在1000MB占用内存大小后,开始快速释放内存,但是没有其他提示了,查看输出结果的文件,依然为空。。

3.1 可能的错误原因——docker的GPU分配和容量问题

很不幸,当我配置好环境,运行上面的脚本时,第一遍,下载了好几个模型之类的文件,包括一个ppyolov2_r50vd_dcn_365e_publaynet的预训练模型吧,然后就卡主了,终止命令,重新运行脚本,报错:

OSError: (External)  Cublas error, `CUBLAS_STATUS_ALLOC_FAILED`. 
Resource allocation failed inside the cuBLAS library.  
(at /paddle/paddle/fluid/platform/cuda_helper.h:98)

大致检索了一下,参考:

  • CSDN博客:CUBLAS_STATUS_ALLOC_FAILED 解决办法
  • 博客园:failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED 错误解决方法

可以确定原因出在GPU的分配上,之前这个容器启动的时候绑定的GPU是3号,好像之前有个容器也绑定的是3号,查看了一下,那个容器还处于运行状态,关闭该容器。

关闭后,GPU确实可以使用了,但是容量不够了???

RuntimeError: ResourceExhaustedError: 
Out of memory error on GPU 0. Cannot allocate 4.000244MB memory on GPU 0, 
23.694092GB memory has been allocated and available memory is only 5.562500MB.

Please check whether there is any other process using GPU 0.
1. If yes, please stop them, or start PaddlePaddle on another GPU.
2. If no, please decrease the batch size of your model. 
 (at /paddle/paddle/fluid/memory/allocation/cuda_allocator:79)

搜索linux gpu显存占用不够,找到的解决方案,大部分都是找到占用的进程,杀死!

先看看docker绑定的这个gpu的情况,在容器的CLI中输入:

所以对于当前这个GPU,一共显存是24268MB,被占用的量达到了23813MB。。。

关于nvidia-smi这个输出结果的说明,可以参考:

  • Nvidia-smi简介及常用指令及其参数说明
  • nvidia-smi 命令解读
  • 官方文档-NVIDIA System Management Interface
  • https://developer.download.nvidia/compute/cuda/6_0/rel/gdk/nvidia-smi.331.38.pdf 或者直接输入nvidia-sim -h查看参数说明

3.2 错误解决——释放GPU容量

感谢:Linux下释放GPU显存

sudo fuser -v /dev/nvidia*
# 查看当前系统中GPU占用的线程

注意,上述命令要在宿主机环境下输入,不能在docker里看,返回结果类似:

然后直接kill 对应的PID即可

kill -9 226829

杀了之后再去看docker中gpu的情况,就好多了

如果还是不够的话,那就重新启动一个容器,绑定另一个GPU好了

3.3 GPU显存占满而利用率为0

这个问题记录在另一个博客中,参见:GPU显存占满利用率GPU-util为0

3.4 ✅错误解决

后来在使用另一个镜像,不使用以下
docker pull paddlepaddle/paddle:2.1.2-gpu-cuda11.2-cudnn8
而是使用我这边服务器可以接受的,cpu版本,不用gpu了
docker pull paddlepaddle/paddle:2.1.2
然后就可以跑出来结果了,哈哈哈


文字部分会直接显示出来,其他分割的部分都默认显示在output/tabel/1文件夹中,类似

✅ 4. streamlit显示PP-structure结果

首先要解析输出内容,主要的函数是:

def save_structure_res(res, save_folder, img_name):
    excel_save_folder = os.path.join(save_folder, img_name)
    os.makedirs(excel_save_folder, exist_ok=True)
    # save res
    with open(os.path.join(excel_save_folder, 'res.txt'), 'w', encoding='utf8') as f:
        for region in res:
            if region['type'] == 'Table':
                excel_path = os.path.join(excel_save_folder, '{}.xlsx'.format(region['bbox']))
                to_excel(region['res'], excel_path)
            if region['type'] == 'Figure':
                roi_img = region['img']
                img_path = os.path.join(excel_save_folder, '{}.jpg'.format(region['bbox']))
                cv2.imwrite(img_path, roi_img)
            else:
                for box, rec_res in zip(region['res'][0], region['res'][1]):
                    f.write('{}\t{}\n'.format(np.array(box).reshape(-1).tolist(), rec_res))

关于返回结果的说明:

[
  {   'type': 'Text',
      'bbox': [34, 432, 345, 462],
      'res': ([[36.0, 437.0, 341.0, 437.0, 341.0, 446.0, 36.0, 447.0], [41.0, 454.0, 125.0, 453.0, 125.0, 459.0, 41.0, 460.0]],
                [('Tigure-6. The performance of CNN and IPT models using difforen', 0.90060663), ('Tent  ', 0.465441)])
  }
]

自己仿照着搞一个。最后全都呈现在页面中的效果是:

参考:

  • python使用Streamlit库制作Web可视化页面

本文标签: 简单PPPaddleOCRdockerfileStructure