使用Mistral 7B进行开源LLM文档提取

2024年02月26日 由 alex 发表 535 0

简介

OCR是一门精通的科学,而且已经有一段时间了。如今的问题在于数据的提取和处理,而 LLM 在这部分大放异彩。摩根大通最近推出了 DocLLM,这是一种专门为此设计的 LLM。该模型尚未推出,而且在上下文窗口大小方面有一些限制。因此,我决定采取相反的做法,做一个窗口尺寸更大的完全开放源代码。


该项目分为两部分,即 OCR 层和 LLM 层。在生产就绪的项目中,这将是不同的微服务,甚至是不同的服务。但划分是明确的,首先是读取所有内容(OCR 层),然后是提取特定内容(LLM 层)。


OCR 层


2


将页面转换为图像

首先,必须将任何类型的文件转换为图像。这种方法可确保访问文件中的所有内容。通过将页面分割成图像,可以在后续步骤中对它们进行单独处理。


OCR 预处理图像

通常,图像质量较差,需要进行调整以提高可读性。增强措施包括改变对比度以及使用各种库和框架。


超立方 OCR

它是世界上最著名、最流行的开源 OCR。它的历史也相当悠久,但随着时间的推移,它已被调整为支持更多语言结构和表格。本示例通过用"|"分割来支持表格。


它使用 pytesseract 通过 Python 连接到tesseract。代码如下:


def extract_text_with_pytesseract(list_dict_final_images):
    
    image_list = [list(data.values())[0] for data in list_dict_final_images]
    image_content = []
    
    with concurrent.futures.ThreadPoolExecutor() as executor:
        futures = []
        for index, image_bytes in enumerate(image_list):
            future = executor.submit(process_image, index, image_bytes)
            futures.append(future)
        
        for future in concurrent.futures.as_completed(futures):
            try:
                raw_text = future.result()
                image_content.append(raw_text)
            except Exception as e:
                raise Exception(f"Error processing image: {e}")
    
    return image_content
# only this one matters, the rest is concurrency logic
def process_image(index, image_bytes):
    try:
        image = Image.open(BytesIO(image_bytes))
        raw_text = str(image_to_string(image))
        return raw_text
    except Exception as e:
        raise Exception(f"Error processing image {index}: {e}")


LLM 层


提取合同定义

从文档中获取内容后,我们需要以结构化的方式提取信息。下图显示了完整的提示:


3


协议部分可以用多种方式定义,但你应该使用与任何编程语言相似甚至相同的方式。这里的协议是一个伪代码,包括字段的名称、类型和描述。


你还可以询问文档的分类:


documentType:string => 只能是 "发票"、"销售单"、"有限责任公司创建文件"、"驱逐文件"


为什么选择 JSON 格式而不是 YAML 等其他格式,尤其是 YAML 通常会产生较小的有效载荷?答案在于训练数据的可用性。由于 JSON 是网络上的主要数据交换格式,因此它在用于训练的数据集中更为普遍。


正确提取 JSON

在 OpenAI 中,你已经可以使用 JSON 返回类型:


response = openai.Completion.create(
  model="text-davinci-003",
  prompt="Translate the following English text to French: 'Hello, how are you?'",
  response_format={ "type": "json_object" }
)


由于该功能不可用,你需要手动添加并修剪 JSON 结构。通常情况下,用于培训目的,结果会以这种格式返回:


```json
[Content]
```


有了这样的认识,我们就可以对输入内容进行如下处理:


{
  "model": "mistral-tiny",
  "messages": [
    {
      "role": "user",
      "content": "[Content]```json\n{"
    }
  ],
  ...
}


输出内容如下:


{
    ...
    "choices": [
        {
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "[Content]```[Content]"
            },
            "finish_reason": "stop"
        }
    ],
    ...
}


你可以使用该函数接收这两个内容,并给出提取的 JSON:


def extractJsonSubstring(str1, str2):
    # Concatenate the two strings
    combined_str = str1 + str2
    
    # Define the start and end markers
    start_marker = "```json"
    end_marker = "```"
    
    # Find the start and end positions of the substring
    start_pos = combined_str.find(start_marker)
    ### jump start_pos to the end of the start_marker
    start_pos = start_pos + len(start_marker)
    end_pos = combined_str.find(end_marker, start_pos)
    
    # Extract the substring
    json_substring = combined_str[start_pos:end_pos]
    return json_substring


本地运行 - OLLAMA

现在有几种在本地运行模型的方法,如 LLM studio 或 Ollama。在这种情况下,考虑到项目,你可以使用 LlamaIndex 和 Ollama。


查看代码并进行测试

在该 repo 中,你有一个带有一个端点的 FastAPI 应用程序,用于测试所有这些组件。但这只是一个简单的应用程序接口,你应特别针对你的用例进行扩展。


首先,你应指向适当的 Tessaract 可执行文件


4


如果你使用的是 docker,请使用第二个,并注释硬编码的路径。


此外,本示例使用直接请求 Mistral API 的方式。请确保更改了 config.py 文件中的密钥。


5


这是一个 FastAPI 项目,因此请确保安装了依赖项,并访问 localhost:8000/docs


到达后,带着文件和合同进入 /extract 端点。


6


提出要求,你就会得到适当的结果。请记住,这只是一个模板,有些事情可能与棘手的合同不符。


7


高级案例: 100万个tooken上下文


LLMLingua


8


LLM Lingua 是我最近看到的最喜欢的软件之一。它既聪明又简单,通过微调一个小得多的模型来压缩内容,这样就能将其传递到一个大得多的昂贵模型上。


根据论文所述,20 倍的压缩率大约会降低 1.5%,但这取决于数据的性质。


Mistral Yarn 128k 上下文窗口

YaRN(另一种 RoPE 扩展方法)使用旋转位置嵌入(RoPE)来增加窗口大小。


使用这两种技术,10x * 128k 上下文窗口压缩率将为你提供一个 1M 以上的窗口。你可以把整本圣经都放进去!


使用更大上下文的情况

有时一个页面并不包含要提取的全部值,有时会是多个页面。获取数据后再进行聚合可能会出现问题,因为他可能会提取错误的值而不是空值(如合同部分所述),因此一种解决方案是简单地增加上下文内容,这样就不会有任何内容遗漏。


结论

正如文档提取开源项目所展示的那样,OCR 和 LLM 技术的整合标志着在分析非结构化数据方面取得了重大进展。Tesseract 和 Mistral 等开源项目的结合是一种完美的实现方式,可用于内部使用案例。

文章来源:https://medium.com/gopenai/open-source-document-extraction-using-mistral-7b-llm-18bf437ca1d2
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
写评论取消
回复取消