
Ankush k Singal • 2023-11-20
掌握文档提取技能
引言
在文档处理领域,从图像中准确提取关键信息一直是一个持久的障碍。尽管光学字符识别 (OCR) 在将图像转换为可编辑文本方面取得了进展,但面对不同的文档格式和质量,它仍然面临许多复杂性。Zephyr 7b LLM 在此应运而生,它是一个开创性的解决方案,与 LlamaIndex 相结合,直接解决了这些难题,预示着基于图像的文档提取进入了一个变革时代。

OCR 的困境:障碍与限制 光学字符
识别 (OCR) 虽然强大,但也面临着诸如
- 多样化的文档格式:文档呈现出复杂的布局、字体和结构,给传统 OCR 精准解释和提取信息带来挑战。
- 质量与清晰度:低分辨率、模糊或倾斜角度的图像会影响 OCR 识别文本的准确性。
- 手写体和草书内容:OCR 常常难以处理手写体或草书字体,导致错误或提取不完整。
- 多语言复杂性:处理多种语言的文档对缺乏识别和提取不同语言内容能力的 OCR 系统构成挑战。

Zephyr 7b LLM:弥合差距
Zephyr 7b LLM 通过解决 OCR 技术固有的这些限制来革新格局
- 先进的机器学习算法
Zephyr 7b LLM 采用最先进的机器学习算法,经过各种文档格式和语言的广泛训练。这使其能够适应并学习各种文档结构,从而显著提高准确性并增强提取能力。
2. 上下文理解
与传统 OCR 不同,Zephyr 7b LLM 不仅识别单个字符,还能理解这些字符所处的上下文。这种上下文理解能力显著减少了错误,即使从复杂的文档布局中也能确保精确提取。
3. 自适应图像处理
与 LlamaIndex 的结合增强了 Zephyr 7b LLM 处理不同分辨率或质量图像的能力。它利用自适应图像处理技术,纠正失真、增强清晰度,并优化图像以进行细致的 OCR 分析。
4. 多语言能力
Zephyr 7b LLM 跨越了语言障碍。其多语言能力有助于从各种语言的文档中无缝提取内容,为处理多语言文档的企业提供了全球可访问性。

代码实现
Zephyr 7b LLM 与 LlamaIndex 的协作标志着文档提取领域的重大转型。通过融合 Zephyr 先进的 OCR 能力与 LlamaIndex 的图像增强和数据组织功能,这种集成提供了一个全面的解决方案
- 增强的精度:Zephyr 的机器学习专业知识与 LlamaIndex 的图像增强功能相结合,显著提高了提取数据的准确性,减少了错误,并提升了整体效率。
- 高效的工作流程:用户体验到优化的工作流程,能够快速提取基于图像的文档并将其转换为结构化、可操作的数据,从而加快决策过程。
- 对各种文档的适应性:这种集成使用户能够轻松处理各种文档格式和语言,从而可以提取和分析以前难以处理的文档类型。

步骤 1:安装并导入库
!pip install llama-index transformers accelerate sentencepiece bitsandbytes -q
步骤 2:加载模型
import torch
from transformers import BitsAndBytesConfig
from llama_index.prompts import PromptTemplate
from llama_index.llms import HuggingFaceLLM
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_quant_type="nf4",
bnb_4bit_use_double_quant=True,
)
def messages_to_prompt(messages):
prompt = ""
for message in messages:
if message.role == 'system':
prompt += f"<|system|>\n{message.content}</s>\n"
elif message.role == 'user':
prompt += f"<|user|>\n{message.content}</s>\n"
elif message.role == 'assistant':
prompt += f"<|assistant|>\n{message.content}</s>\n"
# ensure we start with a system prompt, insert blank if needed
if not prompt.startswith("<|system|>\n"):
prompt = "<|system|>\n</s>\n" + prompt
# add final assistant prompt
prompt = prompt + "<|assistant|>\n"
return prompt
llm = HuggingFaceLLM(
model_name="HuggingFaceH4/zephyr-7b-alpha",
tokenizer_name="HuggingFaceH4/zephyr-7b-alpha",
query_wrapper_prompt=PromptTemplate("<|system|>\n</s>\n<|user|>\n{query_str}</s>\n<|assistant|>\n"),
context_window=3900,
max_new_tokens=2000,
model_kwargs={"quantization_config": quantization_config},
# tokenizer_kwargs={},
generate_kwargs={"temperature": 0.7, "top_k": 50, "top_p": 0.95},
messages_to_prompt=messages_to_prompt,
device_map="auto",
)
from llama_index import ServiceContext, set_global_service_context
service_context = ServiceContext.from_defaults(llm=llm, embed_model="local:BAAI/bge-small-en-v1.5")
set_global_service_context(service_context)
步骤 3:存储索引
from llama_index import SimpleDirectoryReader, VectorStoreIndex
from llama_index.readers.file.base import (
DEFAULT_FILE_READER_CLS,
ImageReader,
)
from llama_index.response.notebook_utils import (
display_response,
display_image,
)
from llama_index.indices.query.query_transform.base import (
ImageOutputQueryTransform,
)
filename_fn = lambda filename: {"file_name": filename}
llama_reader = SimpleDirectoryReader(
input_dir="/content/llama",
file_metadata=filename_fn,
)
llama_documents = llama_reader.load_data()
llama_index = VectorStoreIndex.from_documents(llama_documents)
步骤 4:查询 转换
from llama_index.query_engine import TransformQueryEngine
query_engine = llama_index.as_query_engine(similarity_top_k=2)
query_engine = TransformQueryEngine(
query_engine, query_transform=ImageOutputQueryTransform(width=400)
)
llama_response = query_engine.query(
"Show an image to illustrate how tree index works and explain briefly",
)
display_response(llama_response)
#Output
Final Response: I am not capable of displaying images. however, i can provide you with an explanation of how tree index works.
tree index is a data structure that organizes data in a hierarchical manner, similar to a tree. it is commonly used in databases to improve query performance.
when querying a tree index, the process involves traversing from the root node down to the leaf nodes. the number of child nodes chosen per parent node is determined by the child_branch_factor parameter.
for example, if child_branch_factor=1, a query will choose one child node given a parent node. if child_branch_factor=2, a query will choose two child nodes per parent.
the following image illustrates how a tree index works:
! Tree Index Example
in this example, the tree index is built from a set of nodes (which become leaf nodes in this tree). when querying this index, the process involves traversing from the root node down to the leaf nodes. for instance, if we want to find a specific node with the value "x", we would start at the root node and follow the left branch (since "x" is less than "a") to the next level. we would then follow the left branch again to reach the leaf node with the value "x".
i hope this helps clarify how tree index works!
步骤 5:让我们读取 收据
from llama_index.readers.file.base import DEFAULT_FILE_READER_CLS
from llama_index.readers.file.image_reader import ImageReader
image_parser =ImageReader(
keep_image=True,
parse_text=True
)
file_extractor = DEFAULT_FILE_READER_CLS
file_extractor.update({
".jpg": image_parser,
".png": image_parser,
".jpeg": image_parser,
})
receipt_reader = SimpleDirectoryReader(
input_dir="/content/data",
file_metadata=filename_fn,
file_extractor=file_extractor,
)
receipt_documents = receipt_reader.load_data()
print(len(receipt_documents))
#Output
3
receipts_index = VectorStoreIndex.from_documents(receipt_documents)
from llama_index.query_engine import TransformQueryEngine
query_engine = receipts_index.as_query_engine()
receipts_response = query_engine.query(
"When was the last time I went to RESTAURANT and how much did I spend? this data is in your latest vector index.",
)
display_response(receipts_response)
# Output
Final Response: Based on the given context information, the last time the querying individual went to RESTAURANT was on July 5, 2019, and they spent $164.00.
结论
总之,Zephyr 7b LLM 与 LlamaIndex 的融合开启了基于图像的文档提取的新篇章。它不仅解决了 OCR 固有的挑战,还提高了从图像中提取数据的精度和效率,从而在以文档为中心的工作流程中提升了生产力和决策能力。
“通过各种平台保持联系并支持我的工作
- GitHub:我的所有开源项目和 Notebook 都可以在我的 GitHub 个人主页 https://github.com/andysingal 上找到。如果您觉得我的内容有价值,请不要吝啬您的 star。
- Patreon:如果您想提供额外支持,可以考虑成为我的 Patreon 页面 https://www.patreon.com/AndyShanu 的赞助人。
- Medium:您可以在 Medium 上阅读我的最新文章和见解:https://medium.com/@andysingal。
- Kaggle:查看我的 Kaggle 个人主页,了解数据科学和机器学习项目:https://www.kaggle.com/alphasingal。
- Hugging Face:对于自然语言处理和人工智能相关项目,您可以访问我的 Huggingface 个人主页:https://hugging-face.cn/Andyrasika。
- YouTube:要观看我的视频内容,请访问我的 YouTube 频道:https://www.youtube.com/@andy111007。
- LinkedIn:要及时了解我的最新项目和帖子,您可以在 LinkedIn 上关注我。这是我的个人主页链接:https://www.linkedin.com/in/ankushsingal/."
请求与问题:如果您有想让我参与的项目,或者对我解释的概念有任何疑问,请随时告诉我。我一直在寻找未来 Notebook 的新想法,并且乐于帮助解决您可能有的任何疑虑。
请记住,每一个“赞”、“分享”和“星标”都极大地支持了我的工作,并激励我继续创作更多高质量内容。感谢您的支持!
如果您喜欢这个故事,欢迎订阅 Medium,这样您将在我的新文章发表时收到通知,同时也能完全访问其他作者的数千个故事。
资源