百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

如何使用Llama-3.2–11B模型将非结构化数据转换为结构化格式

ztj100 2025-03-03 21:15 33 浏览 0 评论

了解大型视觉模型的概况

在深入研究之前,了解大型视觉模型是什么以及为什么它们胜过传统的光学字符识别 (OCR) 系统会有所帮助。与主要设计用于使用简单算法从图像中提取文本的传统 OCR 系统不同,大型视觉模型(如 GPT4o 或Pixtral-12B或 Llama 3.2–11B-Vision-Instruct)能够实现更多功能。

这些模型是多模式的,这意味着它们可以处理文本和图像,并且使用先进的深度学习算法构建,可以理解上下文、识别模式并从复杂的非结构化输入中提取结构化数据。传统的 OCR 可能难以处理质量较差的扫描、手写或混合格式,而大型视觉模型可以以模仿人类理解的方式智能地解释视觉信息。

过去几个月出现了几种视觉语言模型。但是,选择正确的模型取决于您的需求。例如,如果您的数据是这样的,当您与 4o 等 GPT 模型共享时无需担心,那么我们建议您采用这种方式以节省成本。另一方面,如果您有严格的数据合规性要求,那么最好在自己的基础设施上托管 Llama 3.2–11B-Vision 或 Pixtral-12B 等模型,这样您就不会与平台公司共享内部数据。

为简单起见,这里有一个比较表:

上表说明了这些大型视觉模型之间的关键区别,每个模型适用于不同的复杂程度、隐私需求和成本考虑。对于处理敏感排放数据和严格 ESG 报告要求的公司来说,Llama 3.2–11B-Vision-Instruct 或 Pixtral-12B 等模型具有显著优势,特别是因为它们可以托管在您自己的基础设施上,确保您的数据保持安全和私密。它们还允许高度定制,这意味着您可以微调这些模型,以更好地解释贵公司处理的特定类型的非结构化排放数据。

好的,现在我们看看使用这些模型将非结构化数据解析为结构化格式的步骤。

使用 Llama-3.2–11B-Vision-Instruct 的步骤

首先,您需要访问模型 — Llama-3.2–11B-Vision-Instruct。为此,请前往Hugging Face,创建一个帐户,并注册您访问该模型的意图。您需要填写一些基本信息,Meta 的模型维护者将根据这些信息授予您访问权限。

您还需要一个高端云 GPU。我们在本教程中使用了 NVIDIA Tensor Core A100 GPU。启动 GPU 和相应的 Jupyter 笔记本后,您可以检查 GPU 配置:

!nvidia-smi

此命令将显示 GPU 配置和内存使用情况。您还需要在 Hugging Face 上创建访问令牌,以便下载模型。创建访问令牌后,将其保存在环境变量中。

因此,在您的 .env 文件中,添加以下行:

HF_TOKEN = '你的访问令牌来自_hugging_face'

我们现在将安装所需的库。

pip install torch requests Pillow accelerate python-dotenv
pip install git+https://github.com/huggingface/transformers

接下来,让我们导入所需的库:

import requests
import torch
from PIL import Image
from transformers import MllamaForConditionalGeneration, AutoProcessor
from dotenv import load_dotenv
load_dotenv()

现在我们准备好了。

步骤 1:下载模型

如果您已将访问令牌保存在 .env 文件中,则无需使用 huggingface_hub 登录。您现在可以下载模型了。

model_id = "meta-llama/Llama-3.2-11B-Vision-Instruct"
model = MllamaForConditionalGeneration.from_pretrained(
   model_id,
   torch_dtype=torch.bfloat16,
   device_map="auto",
)
processor = AutoProcessor.from_pretrained(model_id)

由于模型相当大,因此这需要一些时间。

第 2 步:测试模型

下载模型后,您可以通过使用图像给出简单说明来测试它。操作方法如下:

image = Image.open("emissions_per_person.png")
messages = [
      {"role": "user", "content": [
          {"type": "image"},
          {"type": "text", "text": """
           Capture the emission per person by country in a table format with numbers.
           Provide approximate floating point numbers.
          """}
      ]}
  ]
input_text = processor.apply_chat_template(messages, add_generation_prompt=True)
inputs = processor(
   image,
   input_text,
   add_special_tokens=False,
   return_tensors="pt"
).to(model.device)
output = model.generate(**inputs, max_new_tokens=1000)
response = processor.decode(output[0])
print(response)

为了测试,我们使用了下图,该图显示了总排放量最大的 15 个国家的人均二氧化碳排放量。

这是我们得到的输出:

<|begin_of_text|><|start_header_id|>user<|end_header_id|>
<|image|>
            Capture the emission per person by country in a table format with numbers.
            Provide approximate floating point numbers.
           <|eot_id|><|start_header_id|>assistant<|end_header_id|>
The following table presents the carbon dioxide emissions per person, measured in tons of CO2e, for 15 countries with the highest total emissions. The data is displayed in a table format with approximate floating-point numbers.
| Country          | Emissions per Person (tCO2e) |
| :--------------- | :--------------------------: |
| Saudi Arabia     |             18.4             |
| USA              |             16.5             |
| Canada           |              14.4            |
| S. Korea         |              12.1            |
| Russia           |              10.4            |
| Japan            |               8.6            |
| China            |               7.2            |
| Germany          |               6.9            |
| Iran             |               5.4            |
| S. Africa        |               4.5            |
| Turkey           |               4.2            |
| Mexico           |               3.8            |
| Indonesia        |               3.4            |
| Brazil           |               3.3            |
| India            |               1.7            |
**Answer:** The table provides a concise overview of the carbon dioxide emissions per person for 15 countries with the highest total emissions.<|eot_id|>

如您所见,这些数字大致在范围内。

步骤 3:使用模型进行结构化输出

我们注意到的一个因素是,该模型更适合以 markdown 格式生成输出,而不是 JSON 或 YAML。因此,我们的方法是首先引导它生成 markdown,然后将 markdown 转换为 JSON。

看一下我们将要使用的图像文件:

这是一张相当复杂的账单,您的会计团队可能会收到数千张这样的账单。让我们在这张账单上测试一下 AI 模型。我们的提示这次将指导降价:

image = Image.open("water_bill.png")
messages = [
      {"role": "user", "content": [
          {"type": "image"},
          {"type": "text", "text": """
           Parse the bill image in markdown format. Capture all details, and fill up these values:           
           Account Number:
           Account Name:
           Address:
           Bill from:
           Bill to:
           Bill due date:
           Bill total:
           Due date:
           Amount after due date:
          """}
      ]}
  ]
input_text = processor.apply_chat_template(messages, add_generation_prompt=True)
inputs = processor(
   image,
   input_text,
   add_special_tokens=False,
   return_tensors="pt"
).to(model.device)
output = model.generate(**inputs, max_new_tokens=1000)
response = processor.decode(output[0])
print(response)

这将生成如下响应:

<|begin_of_text|><|start_header_id|>user<|end_header_id|>
<|image|>
            Parse the bill image in markdown format. Capture all details, and fill up these values:            
            Account Number:
            Account Name:
            Address:
            Bill from:
            Bill to:
            Bill due date:
            Bill total:
            Due date:
            Amount after due date:
           <|eot_id|><|start_header_id|>assistant<|end_header_id|>
**Water Bill Details**
* **Account Information**
	+ Account Number: 0441-12-022
	+ Account Name: Balingit Joe
	+ Address: Rizal
* **Billing Period**
	+ Bill From: 10/03/2022
	+ Bill To: 11/02/2022
* **Bill Due Date**: 11/17/2022
* **Bill Total**: 210.00
* **Due Date**: 11/17/2022
* **Amount After Due Date**: 220.50<|eot_id|>

如您所见,捕获的数据或多或少是准确的。但是,该模型有时会产生幻觉,因此需要人工监督。

步骤 4:生成结构化输出

使用 GPT 4o 模型,您可以轻松生成 JSON、Zod 或 Pydantic 结构的输出。但是,目前的开源视觉模型并非如此。

为了生成结构化的输出 markdown,您需要将 markdown 转换为 JSON 格式。首先,我们将删除 Llama-3.2 特定的标签和无关数据:

def parse_eot_content(input_string):
   # Step 1: Find the content between the <|eot_id|> tags
   eot_pattern = r"<\|eot_id\|>(.*?)<\|eot_id\|>"
   eot_match = re.search(eot_pattern, input_string, re.DOTALL)
  
   if eot_match:
       eot_content = eot_match.group(1)
   else:
       return None  # If no content between <|eot_id|> tags
  
   # Step 2: Remove the section within <|start_header_id|> and <|end_header_id|>
   header_pattern = r"<\|start_header_id\|>.*?<\|end_header_id\|>"
   cleaned_content = re.sub(header_pattern, '', eot_content, flags=re.DOTALL)
  
   # Step 3: Return the cleaned content
   return cleaned_content.strip()

我们还将编写一个简单的函数来将 markdown 数据解析为 JSON 格式,如下所示:

def markdown_to_json(markdown):
   data = {}
   current_section = None
   # 按行分割
   lines = markdown.splitlines()   对于行中的行:
       line = line.strip()       # 如果该行为空,则跳过它
       if not line: 
           continue 
      
       # 如果该行是新部分标题(粗体文本)
       section_match = re.match(r'\*\*(.+?)\*\*', line) 
       if section_match: 
           current_section = section_match.group(1).strip() 
           data[current_section] = {} 
           continue 
      
       # 如果行以“*”开头,则将其作为列表项或键值对处理
       if line.startswith("*"): 
           # 删除星号和周围的空格
           line = line.lstrip("*").strip() 
           key_value_match = re.split(r':\s+', line, maxsplit=1) 
          
           # 在根级别处理键值对
           if len(key_value_match) == 2: 
               key, value = key_value_match 
               data[current_section][key] = value 
           continue 
      
       # 如果行以“+”开头,则它就是部分内的键值对
       if line.startswith("+"): 
           line = line.lstrip("+").strip() 
           key_value_match = re.split(r':\s+', line, maxsplit=1)           # 将键值对添加到当前部分
           if len(key_value_match) == 2: 
               key, value = key_value_match 
               if current_section: 
                   data[current_section][key] = value 
               else: 
                   data[key] = value
    return json.dumps(data, indent=4)

我们现在可以使用这些函数转换 Llama-3.2 输出。

parsed_output = parse_eot_content(response)
output = markdown_to_json.jsonify(parsed_output)
print(output)

这将产生以下结果:

{
    "Water Bill Details": {
        "Account Number": "0441-12-022",
        "Account Name": "Balingit Joe",
        "Address": "Rizal",
        "From": "10/03/2022",
        "To": "11/02/2022",
        "Billing Due Date": "11/17/2022",
        "Current Bill Amount": "210.00",
        "Total Amount Due": "210.00",
        "Due Date": "11/22/2022"
    }
}

您现在可以将其插入数据库并进行查询。

相关推荐

Vue3非兼容变更——函数式组件(vue 兼容)

在Vue2.X中,函数式组件有两个主要应用场景:作为性能优化,因为它们的初始化速度比有状态组件快得多;返回多个根节点。然而在Vue3.X中,有状态组件的性能已经提高到可以忽略不计的程度。此外,有状态组...

利用vue.js进行组件化开发,一学就会(一)

组件原理/组成组件(Component)扩展HTML元素,封装可重用的代码,核心目标是为了可重用性高,减少重复性的开发。组件预先定义好行为的ViewModel类。代码按照template\styl...

Vue3 新趋势:10 个最强 X 操作!(vue.3)

Vue3为前端开发带来了诸多革新,它不仅提升了性能,还提供了...

总结 Vue3 组件管理 12 种高级写法,灵活使用才能提高效率

SFC单文件组件顾名思义,就是一个.vue文件只写一个组件...

前端流行框架Vue3教程:17. _组件数据传递

_组件数据传递我们之前讲解过了组件之间的数据传递,...

前端流行框架Vue3教程:14. 组件传递Props效验

组件传递Props效验Vue组件可以更细致地声明对传入的props的校验要求...

前端流行框架Vue3教程:25. 组件保持存活

25.组件保持存活当使用...

5 个被低估的 Vue3 实战技巧,让你的项目性能提升 300%?

前端圈最近都在卷性能优化和工程化,你还在用老一套的Vue3开发方法?作为摸爬滚打多年的老前端,今天就把私藏的几个Vue3实战技巧分享出来,帮你在开发效率、代码质量和项目性能上实现弯道超车!一、...

绝望!Vue3 组件频繁崩溃?7 个硬核技巧让性能暴涨 400%!

前端的兄弟姐妹们五一假期快乐,谁还没在Vue3项目上栽过跟头?满心欢喜写好的组件,一到实际场景就频频崩溃,页面加载慢得像蜗牛,操作卡顿到让人想砸电脑。用户疯狂吐槽,领导脸色难看,自己改代码改到怀疑...

前端流行框架Vue3教程:15. 组件事件

组件事件在组件的模板表达式中,可以直接使用...

Vue3,看这篇就够了(vue3 从入门到实战)

一、前言最近很多技术网站,讨论的最多的无非就是Vue3了,大多数都是CompositionAPI和基于Proxy的原理分析。但是今天想着跟大家聊聊,Vue3对于一个低代码平台的前端更深层次意味着什么...

前端流行框架Vue3教程:24.动态组件

24.动态组件有些场景会需要在两个组件间来回切换,比如Tab界面...

前端流行框架Vue3教程:12. 组件的注册方式

组件的注册方式一个Vue组件在使用前需要先被“注册”,这样Vue才能在渲染模板时找到其对应的实现。组件注册有两种方式:全局注册和局部注册...

焦虑!Vue3 组件频繁假死?6 个奇招让页面流畅度狂飙 500%!

前端圈的朋友们,谁还没在Vue3项目上踩过性能的坑?满心期待开发出的组件,一到高并发场景就频繁假死,用户反馈页面点不动,产品经理追着问进度,自己调试到心态炸裂!别以为这是个例,不少人在电商大促、数...

前端流行框架Vue3教程:26. 异步组件

根据上节课的代码,我们在切换到B组件的时候,发现并没有网络请求:异步组件:...

取消回复欢迎 发表评论: