前不久正在做某平台上城市规划项目相关数据的抓取,发现此类数据不满足传统爬虫所需的格式化要求,批量爬取的难度较大。于是转换思路,先通过截取所有项目页面的图片,并保存到本地。然后利用百度的开源模型Paddlenlp对图片内容进行识别。由于数据量大,而且我的RTX2060显卡跑这种大型推理模型稍显吃力,还是把数据和代码部署到云GPU服务器慢慢跑吧。
PaddleNLP Taskflow API
PaddleNLP是一款简单易用且功能强大的自然语言处理开发库。聚合业界优质预训练模型并提供开箱即用的开发体验,覆盖NLP多场景的模型库,搭配产业实践范例,提供极致的训练与推理性能,可满足灵活定制的开发需求。
PaddleNLP Taskflow API 提供丰富的开箱即用的产业级NLP预置模型,覆盖自然语言理解与自然语言生成两大经典场景,以及AIGC等多模态场景。包括分词、词法分析、句法分析、信息抽取、知识挖掘、文本纠错、文本匹配、文本摘要、闲聊、知识问答、文生图等十余项经典任务,提供产业级的效果与极致的推理性能。
根据我需要完成的任务,调用Taskflow中的document_intelligence,即文档智能,以多语言跨模态布局增强文档预训练模型ERNIE-Layout为核心底座。
输入格式
[ {"doc": "./invoice.jpg", "prompt": ["发票号码是多少?", "校验码是多少?"]}, {"doc": "./resume.png", "prompt": ["五百丁本次想要担任的是什么职位?", "五百丁是在哪里上的大学?", "大学学的是什么专业?"]} ]
默认使用PaddleOCR进行OCR识别,同时支持用户通过word_boxes传入自己的OCR结果,格式为List[str, List[float, float, float, float]]。
[ {"doc": doc_path, "prompt": prompt, "word_boxes": word_boxes} ]
可配置参数说明
batch_size
:批处理大小,请结合机器情况进行调整,默认为1。lang
:选择PaddleOCR的语言,ch在中英混合的图片中使用,en在英文图片上的效果更好,默认为ch。topn
: 如果模型识别出多个结果,将返回前n个概率值最高的结果,默认为1。
示例代码说明
paddlenlp的Github仓库地址:https://github.com/PaddlePaddle/PaddleNLP
from paddlenlp import Taskflow docprompt = Taskflow("document_intelligence") pprint(docprompt([{"doc": "./resume.png", "prompt": ["五百丁本次想要担任的是什么职位?", "五百丁是在哪里上的大学?", "大学学的是什么专业?"]}]))
运行结果:
[{'prompt': '五百丁本次想要担任的是什么职位?', 'result': [{'end': 7, 'prob': 1.0, 'start': 4, 'value': '客户经理'}]}, {'prompt': '五百丁是在哪里上的大学?', 'result': [{'end': 37, 'prob': 1.0, 'start': 31, 'value': '广州五百丁学院'}]}, {'prompt': '大学学的是什么专业?', 'result': [{'end': 44, 'prob': 0.82, 'start': 38, 'value': '金融学(本科)'}]}]
调用模型代码
在调用此模型之前,需要先用pip下载paddlenlp和paddleocr,二者缺一不可。
然后,导入相关模块和库:
from paddlenlp import Taskflow from tqdm import tqdm import os import glob import time import csv
利用os和glob两个模块,获取文件夹中的图片路径,tqdm库是用来可视化处理进程的,csv模块则是用来读取和写入数据的(当然也可以用pandas,我的新环境中没有下载就没用)。
with open("planning_5.csv","a+",newline='') as f: docprompt = Taskflow("document_intelligence") pic_lst = [] d_path = 'G5' #图片位置autodl-tmp/G5 os.chdir('G5') pic_lst.extend(glob.glob(f'*.png')) writer = csv.writer(f) t1 = time.time() os.chdir('/root/autodl-tmp/') # 记得返回原路径 print(os.getcwd()) for i in tqdm(pic_lst): try: pic_path = d_path + '/' + i res = docprompt([{"doc":pic_path,"prompt":["项目名称是什么?", ..."日期是什么"]}]) #提取信息对应的问题 project_name = res[0]['result'][0]['value'] server_name = res[1]['result'][0]['value'] price = res[2]['result'][0]['value'] buyer_name = res[3]['result'][0]['value'] date = res[4]['result'][0]['value'] t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) line = [i,project_name,server_name,price,buyer_name,date,t] #行数据 if '' not in line: writer.writerow(line) #写入csv except: t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) writer.writerow([0,0,0,0,0,0,t]) print("error!") pass t2 = time.time() print("cost:",t2-t1,"s")
好,到这一步其实模型已经可以跑通了,接下来就可以部署到服务器。
云GPU服务器部署
我是在AutoDL平台上租GPU的,主要是价格便宜,也比较好用。AutoDL官网:https://www.autodl.com/。先租一个按时计费的RTX 3090,然后进入控制台,就可以看到以下界面:
AutoDL平台的主机上都是以Jupyter作为编译器的,点击JupyterLab可以进入实例的控制界面,点击AutoPanel可以进入管理面板。先说JupyterLab,点进去可以看到以下界面,一般是在根目录下的autodl-tmp中操作和上传数据。可以看到我的代码已经在jupyternotenook中运行了。要注意的是,在创建实例的时候,一定要选好镜像,即算法运行环境,包括深度学习框架版本、python版本、cuda的版本等等。
为了充分利用GPU的性能,我同时运行了四个脚本。那为什么不运行5个或者更多呢?这就需要点进AutoPanel监测GPU性能了,在监测面板中,可以看到实时的GPU利用率。当我同时开启四个进程的时候,GPU的利用率峰值接近80%。为了保证我的程序能稳定的运行,开四个我感觉是比较合适的。
关于如何上传\下载数据、租赁服务器等具体内容,可以参见AutoDL官网的帮助文档:https://www.autodl.com/docs/。