[LLM] PDF ドキュメントを解析して概要を生成 | スマート ドキュメントの概要

1. 全体的な考え方

  • 非常にシンプルな v1 バージョン
    • langchain と pdfminer を使用して pdf ドキュメントを k ブロックに分割し、オーバーラップやその他のパラメーターを設定します
    • 最初にプロンプ​​ト 1 を使用して各チャンク テキスト ブロックの概要を生成し、次にプロンプ​​ト 2 を使用して複数の概要を一貫して結合/追加および削除します。
    • モデルはchatglm2-6bまたは他の大きなモデルを使用できます
  • 評価基準: 情報が PDF の主要なトピックをカバーしているかどうか、サブポイントが PDF の第 1 レベルと第 2 レベルのタイトル比率と概ね一致しているかどうか、要約が一貫性があり滑らかであるかどうか。

ここに画像の説明を挿入します
プロンプト 1: セグメント化された概要

prompt1 = '''你是一个摘要生成器。请根据下文进行分段总结,请注意:
            1.输入数据为从pdf读入的文本,一句话可能存在跨越多行;
            2.要求每段内容不丢失主要信息, 每段的字数在50字左右;
            3.每段生成的摘要开头一定不要含有'第几段'的前缀文字;
            4.对下文进行分段总结:'''

プロンプト 2: コンテンツの統合

prompt2 = '''你是一个文章内容整合器,请注意:
            1.输入数据中含有多个已经总结好的段落;
            2.有的段落开头有这是第几段或者摘要的字样;
            2.请将每段信息进行优化,使得每段之间显得更加连贯,且保留每段的大部分信息;
            4.输入的的文章如下:'''

2. コード

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Author : andy
@Date   : 2023/8/23 10:09
@Contact: [email protected]
@File   : chunk_summary.py
"""
import json
from langchain.text_splitter import CharacterTextSplitter
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams, LTTextBoxHorizontal
from pdfminer.pdfpage import PDFPage
import os
import pandas as pd

def split_document_by_page(pdf_path):
    resource_manager = PDFResourceManager()
    codec = 'utf-8'
    laparams = LAParams()
    device = PDFPageAggregator(resource_manager, laparams=laparams)
    interpreter = PDFPageInterpreter(resource_manager, device)

    split_pages = []
    with open(pdf_path, 'rb') as file:
        for page in PDFPage.get_pages(file):
            interpreter.process_page(page)
            layout = device.get_result()
            text_blocks = []
            for element in layout:
                if isinstance(element, LTTextBoxHorizontal):
                    text = element.get_text().strip()
                    text_blocks.append(text)
            page_text = '\n'.join(text_blocks)
            split_pages.append(page_text)

    return split_pages

def callChatGLM6B(prompt):
    pass

def summary(pdf_path, num):
    # 使用示例
    # pdf_path = "/Users/guomiansheng/Desktop/LLM/LangChain-ChatLLM/pdf_test.pdf"
    # pdf_path = 'example.pdf'  # 替换为你的 PDF 文件路径
    one_dict = {
    
    }
    pages = split_document_by_page(pdf_path)
    add_page_data = ''
    page_ans = ""
    print(f"=============这是第{
      
      num}个pdf\n")
    for i, page_text in enumerate(pages):
        # page_ans = page_ans + f"这是第{i}页pdf:\n" + page_text
        page_ans = page_ans + page_text
        print(f"Page {
      
      i + 1}:", "当前page的字数:", len(page_text))
        print(page_text)
        print("--------------------")

    # 文本分片
    text_splitter = CharacterTextSplitter(
        separator="\n",
        chunk_size=1500,
        chunk_overlap=150,
        length_function=len
    )
    chunks = text_splitter.split_text(page_ans)
    # chunks
    prompt0 = '''请根据下文进行分段总结, 要求每段内容不丢失主要信息, 每段的字数在50字左右:'''
    prompt = '''你是一个摘要生成器。请根据下文进行分段总结,请注意:
                1.输入数据为从pdf读入的文本,一句话可能存在跨越多行;
                2.要求每段内容不丢失主要信息, 每段的字数在50字左右;
                3.每段生成的摘要开头一定不要含有'第几段'的前缀文字;
                4.对下文进行分段总结:'''

    prompt3 = '''你是一个文章内容整合器,请注意:
                1.输入数据中含有多个已经总结好的段落;
                2.有的段落开头有这是第几段或者摘要的字样;
                2.请将每段信息进行优化,使得每段之间显得更加连贯,且保留每段的大部分信息;
                4.输入的的文章如下:'''
    ans = ""
    for i in range(len(chunks)):
        # response = callChatGLM66B(prompt + chunks[i])
        response = callChatGLM6B(prompt + chunks[i])
        if 'data' not in response.keys():
            print(response.keys(), "\n")
            print("========this chunk has problem=======\n")
            continue
        temp_ans = response['data']['choices'][0]['content'] + "\n"
        ans += temp_ans

    ans = ans.replace("\\n", '\n')
    # save txt
    # save_path = "/Users/guomiansheng/Desktop/LLM/LangChain-ChatLLM/save_6b_ans3_all"
    save_path = "/Users/guomiansheng/Desktop/LLM/LangChain-ChatLLM/gpt_diction"
    with open(save_path + '/ans' + str(num) + '.txt', 'w', encoding='utf-8') as file:
        file.write(ans)
    print("======ans========:\n", ans)
    one_dict = {
    
    'input': page_ans, "output": ans}
    return ans, one_dict


def main():
    # find 10 file
    def find_files_with_prefix(folder_path, prefix):
        matching_files = []
        for root, dirs, files in os.walk(folder_path):
            for file in files:
                if file.startswith(prefix) and file.endswith('.pdf'):
                    matching_files.append(os.path.join(root, file))
        return matching_files

    # 示例用法
    folder_path = '/Users/guomiansheng/Desktop/LLM/LangChain-ChatLLM/pdf_data_all'  # 替换为你的大文件夹路径
    # prefixes = ['pdf_0', 'pdf_1', 'pdf_2']  # 替换为你想要匹配的前缀列表
    prefixes = []
    for i in range(10):
        prefixes.append('pdf_' + str(i))
    matching_files = []
    for prefix in prefixes:
        matching_files.extend(find_files_with_prefix(folder_path, prefix))
    # del matching_files[0]
    # del matching_files[0]

    ans_lst = []
    for i in range(len(matching_files)):
        one_ans, one_dict = summary(matching_files[i], i)
        ans_lst.append(one_dict)
    # pdf_path = "/Users/guomiansheng/Desktop/LLM/LangChain-ChatLLM/pdf_test.pdf"
    # summary(pdf_path)
    return ans_lst


def preprocess_data(ans_lst):
    json_path = "/Users/guomiansheng/Desktop/LLM/LangChain-ChatLLM/summary_ft_data.json"
    with open(json_path, "w", encoding='utf-8') as fout:
        for dct in ans_lst:
            line = json.dumps(dct, ensure_ascii=False)
            fout.write(line)
            fout.write("\n")


def read_data():
    json_path = "/Users/guomiansheng/Desktop/LLM/LangChain-ChatLLM/summary_ft_data.json"
    with open(json_path, "r", encodings='utf-8') as f:
        lst = [json.loads(line) for line in f]
        df = pd.json_normalize(lst)


if __name__ == '__main__':
    ans_lst = main()
    preprocess_data(ans_lst)

とある講座の内容を紹介するPDFを偶然見つけたところ、以下のように3日間の講座のテーマ内容がまとめられており、さらにデータレイクの概念などもポイントごとにPDFにまとめられていました。

" 教育即将推出名为“数据湖,大数据的下一场变革!”的超强干货课程。该课程分为三天,

第一天的主题是“数据湖如何助力企业大数据中台架构的升级”,内容包括数据处理流程和大数据平台架构,以及数据湖和数据仓库的理念对比和应用;

第二天的主题是“基于 Apache Hudi 构建企业级数据湖”,将介绍三个开源数据湖技术框架比较,Apache Hudi 的核心概念和功能,以及基于 Hudi 构建企业级数据湖的方法;

第三天的主题是“基于 Apache Iceberg 打造新一代数据湖”,将深入探讨 Apache Iceberg 的核心思想、特性和实现细节,以及如何基于 Iceberg 构建数据湖分析系统。该课程由前凤凰金融大数据部门负责人王端阳主讲,他具有多年的大数据架构经验,擅长 Hadoop、Spark、Storm、Flink 等大数据生态技术,授课特点为拟物化编程 + 强案例支撑,旨在帮助学生快速建立完备的大数据生态知识体系。课程将在今晚 20:00 准时开课。"

" 
1.开放性:Lakehouse 使用开放式和标准化的存储格式,提供 API 供各类工具和引擎直接访问数据。  
2.数据类型支持:Lakehouse 支持从非结构化数据到结构化数据的多种数据类型。  
3.BI 支持:Lakehouse 可直接在源数据上使用 BI 工具。  
4.工作负载支持:Lakehouse 支持数据科学、机器学习以及 SQL 和分析等多种工作负载。  
5.模式实施和治理:Lakehouse 有 Schema enforcement and governance 功能,未来能更好的管理元数据,schema 管理和治理。  
6.事务支持:Lakehouse 支持 ACID 事务,确保了多方并发读写数据时的一致性问题。  
7.端到端流:Lakehouse 需要一个增量数据处理框架,例如 Apache Hudi。  
8.数据湖和数据仓库对比:数据湖采用读时模式,满足上层业务的高效分析需求,且无成本修改 schema。  
9.数据湖落地方案:包括基于 Hadoop 生态的大数据方案,基于云平台数据湖方案,基于商业产品的数据湖方案。  
10.数据湖助力数仓解决痛点:数据湖可以解决离线数仓和实时数仓的痛点问题,提高数据处理效率。  
11.数据湖帮助企业大数据中台升级:数据湖可以实现底层存储标准统一化,构建实时化标准层,提高数据存储的安全性、全面性和可回溯性。  
12.大数据中台实时数据建设要求:开源数据湖架构 Day02 基于 Apache Hudi 构建企业级数据湖。"

3. まとめと改善点

1. 概要

  1. 以前に存在した問題: 重複の生成、イベント内の時間の捏造、切り捨て、各チャンク テキスト ブロック間の要約が一貫性がないなど。
  2. 最適化ポイント: pdfminer と Langchain を使用してチャンク テキスト ブロックを分割し、テキスト ブロックの要約を生成し、チャンク化された要約をプロンプト 2 と組み合わせてコンテンツを統合し、文章に一貫性を持たせ、単語数を制御します。top_p=0​​.5 温度=0.8 、など。

2. 今後さらに最適化できる点

  • streamlist を使用して PDF 内のテーブル オブジェクトのコンテンツを抽出します。
  • 談話解析を使用して文書をより詳細に分割するなど。
  • ドキュメントのレイアウト分析が最も重要です。一般的なプロセスは、まずレイアウト分析モデルを使用して、スキャンされた画像内の特定のテキスト部分 (テキスト)、特定の数式 (方程式) などの各部分の意味を検出します。など; その後、他のモデルを使用して、各ブロックのコンテンツを個別に識別します。
    • 参考:数式の識別に使用できるオープンソースプロジェクト:Nougat: https:
      //facebookresearch.github.io/nougat/
      数式や表はマークダウンのプレーンテキストとして表現できるため、入力は単一ページになりますpdf 変換 結果の画像、出力は、この pdf ページに対応するマークダウン (MMD、Mathpix MD) 形式のプレーン テキスト シーケンスです。

4. インテリジェントなドキュメント

ここに画像の説明を挿入します

アリババの業界の事前トレーニング済みモデル LegalBert:

  • 長い文書/長いテキストのためのより使いやすい Transformer 構造 - Longformer は、長いシーケンスをモデル化する機能を向上させます。
  • レイアウト情報 (Layout) と画像情報の導入は、段階的な反復プロセスです。この考え方は、2020年にMicrosoftが提案したlayoutLMの考え方を今でも受け継いでいます。
  • マルチモーダル文書理解事前トレーニング モデルの最初のバージョンは、テキスト + レイアウトという 2 つのモダリティの統合コーディングに基づいており、モデル入力層にはテキスト埋め込みとレイアウト埋め込みが含まれます。2-D Position Embedding は、文書内の空間相対位置関係をモデル化するために使用され、文書上で OCR ツールを使用することで、各トークンの境界ボックスを取得できます。事前トレーニング段階には、マスクされた視覚言語モデルとマルチラベル文書分類という 2 つの目標があります。

ここに画像の説明を挿入します

参照

[1] LLM+ ベクトル ライブラリに基づいて対話の問題点と解決策を文書化
[2] LangChain - 独自の GPT を作成 (2) simple-chatpdf
[3] LangChain を使用して素手で ChatGPT PDF ナレッジ ベースを構築
[4] LangChain+ChatGPT 3 分で実装 PDF およびその他のドキュメントに基づく Q&A アプリケーション
[5] pdfminer: https://euske.github.io/pdfminer/
[6]ナレッジ グラフと CEVAL リストからのインスピレーションを使用して大規模モデルの Q&A を強化するいくつかのソリューションもご覧ください評価
[7] Python+Streamlit Web ページから PDF 中国語文字とテーブル オブジェクトを抽出
[8]アリババのドキュメント インテリジェンス テクノロジとエンタープライズ デジタル化向けアプリケーション アリババ シニア アルゴリズム エキスパート、Wang Mengjia
[9] SMP 2023 ChatGLM Financial Large Model Challenge 60 ポイント ベースラインアイデア

おすすめ

転載: blog.csdn.net/qq_35812205/article/details/132524651