现在有很多个电子发票PDF文件, 使用自动化工具帮我们批量自动从发票PDF提取出格式化信息。如从发票
提取出DICT_DATA
DICT_DATA={
"开票日期":"2023年01月06日",
"应税货物(或服务)名称":"*信息技术服务*技术服务费",
"价税合计(大写)":"",
"税率":"6%",
"备注":"230106163474406331"
}
点击前往网站 https://ollama.com/ ,下载ollama软件,支持win、Mac、linux
ollama软件目前支持多种大模型, 如阿里的(qwen、qwen2)、meta的(llama3),
以llama3为例,根据自己电脑显存性能, 选择适宜的版本。如果不知道选什么,那就试着安装,不合适不能用再删除即可。
打开电脑命令行cmd(mac是terminal), 网络是连网状态,执行模型下载(安装)命令
ollamarunllama3
等待 llama3:8b 下载完成。
在python中调用ollama服务,需要ollama包。
打开电脑命令行cmd(mac是terminal), 网络是连网状态,执行安装命令
pip3installollama
在Python中调用本地ollama服务,需要先启动本地ollama服务, 打开电脑命令行cmd(mac是terminal), 执行
ollamaserve
Run
2024/06/1414:52:24routes.go:1011:INFOserverconfigenv="map[OLLAMA_DEBUG:falseOLLAMA_FLASH_ATTENTION:falseOLLAMA_HOST:http://127.0.0.1:11434OLLAMA_KEEP_ALIVE:OLLAMA_LLM_LIBRARY:OLLAMA_MAX_LOADED_MODELS:1OLLAMA_MAX_QUEUE:512OLLAMA_MAX_VRAM:0OLLAMA_MODELS:/Users/deng/.ollama/modelsOLLAMA_NOHISTORY:falseOLLAMA_NOPRUNE:falseOLLAMA_NUM_PARALLEL:1OLLAMA_ORIGINS:[http://localhosthttps://localhosthttp://localhost:*https://localhost:*http://127.0.0.1https://127.0.0.1http://127.0.0.1:*https://127.0.0.1:*http://0.0.0.0https://0.0.0.0http://0.0.0.0:*https://0.0.0.0:*app://*file://*tauri://*]OLLAMA_RUNNERS_DIR:OLLAMA_TMPDIR:]"
time=2024-06-14T14:52:24.742+08:00level=INFOsource=images.go:725msg="totalblobs:18"
time=2024-06-14T14:52:24.742+08:00level=INFOsource=images.go:732msg="totalunusedblobsremoved:0"
time=2024-06-14T14:52:24.743+08:00level=INFOsource=routes.go:1057msg="Listeningon127.0.0.1:11434(version0.1.44)"
time=2024-06-14T14:52:24.744+08:00level=INFOsource=payload.go:30msg="extractingembeddedfiles"dir=/var/folders/y0/4gqxky0s2t94x1c1qhlwr6100000gn/T/ollama4239159529/runners
time=2024-06-14T14:52:24.772+08:00level=INFOsource=payload.go:44msg="DynamicLLMlibraries[metal]"
time=2024-06-14T14:52:24.796+08:00level=INFOsource=types.go:71msg="inferencecompute"id=0library=metalcompute=""driver=0.0name=""total="72.0GiB"available="72.0GiB"
cmd(mac是terminal)看到如上的信息,说明本地ollama服务已开启。
importcntextasct
text=ct.read_pdf('data/1.pdf')
print(ct.__version__)
text
Run
2.1.2
'机器编号:北京增值税电子普通发票发票代码:\n发票号码:\n开票日期:2023年01月06日\n校验码:\n购\n买\n方名称:哈尔滨所以然信息技术有限公司\n密\n码\n区030898/5<32>*/0*440/63+79*08\n纳税人识别号:91230109MABT7KBC4M /<54<1*6+49<-*+*>7<-8*04<+01\n地址、电话:68+160026-45904*2<+3+15503>2\n开户行及账号:98*2/*-*480145+-19*0917-1*61\n货物或应税劳务、服务名称规格型号单位数量单价金额税率税额\n*信息技术服务*技术服务费 1248.113208 248.11 6% 14.89\n合计¥248.11 ¥14.89\n价税合计(大写)\n 贰佰陆拾叁元整(小写)¥263.00\n销\n售\n方名称:北京\n备\n注230106163474406331\n纳税人识别号:\n地址、电话:\n开户行及账号:\n销售方:(章)'
使用ollama服务中的大模型 llama3:8b , 需要大模型提示信息及数据。这是我实验里设计的提示信息prompt
提取TEXT中的关键信息,返回DICT_DATA,DICT_DATA为dict数据格式,所含关键词依次为"开票日期","应税货物(或服务)名称","价税合计(大写)","税率","备注";结果只显示DICT_DATA。TEXT:{text}
importollama
response=ollama.chat(model='llama3:8b',messages=[
{
'role':'user',
'content':f'提取TEXT中的关键信息,返回DICT_DATA, DICT_DATA为dict数据格式,所含关键词依次为"开票日期", "应税货物(或服务)名称", "价税合计(大写)", "税率", "备注";结果只显示DICT_DATA。TEXT:{text1}',
},
])
result=response['message']['content']
result
Run
'DICT_DATA={\n"开票日期":"2023年01月06日",\n"应税货物(或服务)名称":"*信息技术服务*技术服务费",\n"价税合计(大写)":"",\n"税率":"6%",\n"备注":"230106163474406331"\n}'
从运行结果看出, 大模型从发票PDF中准确提取到我们需要的信息,耗时大概10s。需要注意,有时候大模型还会返回
'Hereistheextractedkeyinformationindictionaryformat:\n\n```\n{\n"开票日期":"2023年01月06日",\n"应税货物(或服务)名称":"*信息技术服务*技术服务费",\n"价税合计(大写)":"贰佰陆拾叁元整",\n"税率":"6%",\n"备注":"230106163474406331"\n}\n```\n\nLetmeknowifyouhaveanyfurtherrequests!?'
现在我们需要将 DICT_DATA 变为真正的字典数据
importre
result=response['message']['content']
result=[rforrinre.split('```|DICT_DATA=',result)if'{'inr][0]
print(type(eval(result)))
print(eval(result))
Run
<class'dict'>
{'开票日期':'2023年01月06日',
'应税货物(或服务)名称':'*信息技术服务*技术服务费',
'价税合计(大写)':'贰佰陆拾叁元整',
'税率':'6%',
'备注':'230106163474406331'}
实验成功,我们将其封装为函数extract_info
importollama
importre
defextract_info(text):
response=ollama.chat(model='llama3:8b',stream=False,messages=[
{
'role':'user',
'content':f'提取TEXT中的关键信息,返回DICT_DATA, DICT_DATA为dict数据格式,所含关键词依次为"开票日期", "应税货物(或服务)名称", "价税合计(大写)", "税率", "备注";结果只显示DICT_DATA。TEXT:{text}',
},
])
result=response['message']['content']
result=[rforrinre.split('```|DICT_DATA=',result)if'{'inr][0]
returneval(result)
result=extract_info(text)
result
Run
{'开票日期':'20230214',
'应税货物(或服务)名称':'*家用厨房电器具*米家小米电热水MJDSH03YM',
'价税合计(大写)':'壹佰贰拾叁圆玖角玖分',
'税率':'13%',
'备注':None}
假设data文件夹内有成百上千的发票(实际上只有一张发票), 对data文件夹进行批量信息提取,结果存储为csv。
%%time
importos
#cntext版本为2.1.2,非开源,
#需联系大邓372335839获取
importcntextasct
importpandasaspd
#当前代码所在的代码文件与data文件夹处于同一个文件夹内
#获取data内所有pdf的路径
pdf_files=[f'data/{file}'forfileinos.listdir('data')if'.pdf'infile]
dict_datas=[]
forpdf_fileinpdf_files:
pdf_text=ct.read_pdf(pdf_file)
dict_data=extract_info(pdf_text)
dict_datas.append(dict_data)
df=pd.DataFrame(dict_datas)
df
Run
CPUtimes:user32ms,sys:2.17ms,total:15.2ms
Walltime:3.8s
本文只使用了一张发票进行实验, 实际上准确率没有这么高, 识别错误字段集中在销售方纳税识别号(案例没有展示销售方纳税识别号的识别)。原因主要是ct.read_pdf读入pdf时,文本比较杂乱。对大模型的语义理解有一定的挑战。目前大模型已经支持文本、图片、音频、视频、网址, 所以各位看官,不用等太久,就可克服此问题。
大模型会对每个输入,给出正确概率最大的回答,因此大模型提取数据时存在一定的错误识别风险。为降低该风险,尽量选择特别特殊、显眼,例如三张发票的价税合计(大写), 因为信息是特殊的中文大写数字, 在所有文本中是最醒目最特别的文本信息,这样大模型处理这类信息时会给这类信息尽可能高的权重,增大回答的准确率。
| 欢迎光临 链载Ai (https://www.lianzai.com/) | Powered by Discuz! X3.5 |