RAGからマルチモーダル検索まで、OpenAIの技術進化

RAGからマルチモーダル検索まで、OpenAIの技術進化

著者 | 崔昊

レビュー | Chonglou

まとめ

この記事では、情報検索とテキスト生成の最新の進歩について探り、特に OpenAI の RAG モデルとそのテキスト コンテンツ検索への応用に焦点を当てます。この記事では、構造化検索から非構造化検索への大きな転換を示し、画像、表、テキストなどのマルチモーダル情報を効果的に処理および解釈できる GPT-4-vision-preview モデルについて詳しく説明します。この記事では、実際のケース分析を通じて、これらのテクノロジーをエンタープライズ ドキュメント管理、学術研究、メディア コンテンツ分析に使用する方法を示し、これらの高度なテクノロジーをマルチモーダル データ処理に適用する方法について読者に詳細な情報を提供します。

導入

人工知能の分野では、情報検索とテキスト生成は常に 2 つの重要な研究方向でした。 OpenAI の RAG (Retrieval-Augmented Generation) モデルは、この分野における画期的な成果として、ニューラル ネットワークのテキスト生成能力と大規模データ セットの検索機能をうまく組み合わせています。この革新により、テキスト生成モデルの精度と情報の豊富さが向上するだけでなく、複雑なクエリを処理する際の従来のモデルの限界も解消されます。

RAG モデルの主流のアプリケーションは、エンタープライズ ナレッジ ベースの検索など、テキスト コンテンツの検索に反映されます。テキストの読み込み、切り取り、埋め込み、インデックス作成などの方法を通じて入力とターゲットの相関関係が確立され、最終的に検索結果がユーザーに表示されます。しかし、情報の種類が多様化するにつれ、従来のテキスト検索ではすべてのニーズを満たすことができなくなりました。

当時、OpenAI は gpt-4-vision-preview モデルを発表しました。これは大きな技術的飛躍であっただけでなく、構造化検索から非構造化検索への重要な転換を示しました。このモデルは、画像、表、テキストなど、マルチモーダル情報を処理および解釈する機能を備えており、効果的に要約および検索できます。この進歩により、RAG 機能の範囲が大幅に拡大し、マルチモーダル データ処理の新たな道が開かれました。

たとえば、エンタープライズ ドキュメント管理の観点では、gpt-4-vision-preview は契約書やレポートなどのグラフやテキストを含む PDF ドキュメントを分析して、正確な要約を提供し、重要な情報を抽出できます。学術研究の分野では、この技術により学術論文内のデータや画像を自動的に整理・分析することができ、研究効率が大幅に向上します。メディア コンテンツ分析では、ニュース レポート内の画像とテキスト コンテンツを統合して分析し、メディア従事者にさらに深い洞察を提供します。

今日は、この記事を通じて、マルチモーダル PDF を分析および検索する方法を段階的に説明します。

シナリオ分析

さて、本日の主役が登場します。下図に示すように、この PDF ファイルは、リッチテキスト、チャート、データを含む典型的な金融市場分析レポートです。

金融市場分析レポート

このレポートには、市場動向の分析や予測などの詳細なテキスト説明だけでなく、株式市場指数、債券商品の利回り、主要金利などの多数のチャートとデータも含まれています。これらのチャートとデータは、市場全体のシナリオを理解する上で重要な役割を果たします。

ただし、このようなマルチモーダル PDF ファイルを手動で処理すると、時間がかかり、労力もかかります。アナリストは、テキストを注意深く読み、チャートとデータを解釈し、この情報を統合して完全な市場見解を形成する必要があります。このプロセスは時間がかかるだけでなく、特に大量の複雑なデータを扱う場合にはエラーが発生しやすくなります。

従来の RAG モデルでは、このようなマルチモーダル PDF ファイルに対応できません。 RAG はテキストベースの情報の処理と生成には優れていますが、主にテキスト コンテンツの検索と生成を行い、グラフやデータなどの非テキスト要素の処理機能は限られています。つまり、情報検索に RAG モデルを使用する場合、テキスト以外の要素を含む複雑な PDF ファイルでは、ファイル内のすべての情報を完全に理解して利用できない可能性があります。

したがって、このようなビジネス シナリオでは、OpenAI が開始したマルチモーダル処理方法を使用し、GPT -4-Vision-Previewモデルを使用してテキスト、グラフ、データを処理し、より包括的で正確な分析を提供する必要があります。これにより、分析の効率が向上し、手動処理によるエラーによるリスクが軽減されます。

テクニカル分析

マルチモーダル PDF ドキュメント処理における主な課題は、画像、表、テキストなど、ドキュメント内の非構造化情報を識別することです。ここでは、PDF、HTML、Word 文書などの画像やテキスト文書を取り込んで前処理するためのオープンソース コンポーネントを提供する非構造化ライブラリを使用する必要がありますその主な目的は、大規模言語モデル (LLM) のデータ処理ワークフローを簡素化し、最適化することです。 Unstructured のモジュール機能とコネクタは、データの取り込みと前処理を簡素化し、さまざまなプラットフォームに適応させ、非構造化データを構造化出力に効果的に変換する一貫したシステムを形成します

さらに、PDF ドキュメントをより適切に処理するために、画像とテキストを抽出するために使用される poppler-utils ツールも導入しました。特に、pdfimages ツールと pdftotext ツールは、それぞれ PDF に埋め込まれた画像とすべてのテキストを抽出するために使用され、マルチモーダル PDF の分析に不可欠です。

注: Poppler は、レンダリングに Cairo と Splash という 2 つのバックエンドを使用できる PDF ドキュメント レンダリング ライブラリです。 2 つのバックエンドには異なる特性があり、Poppler の機能も使用するバックエンドによって異なる場合があります。 Qt4 ベースの描画フレームワーク「Arthur」のバックエンドもありますが、このバックエンドは不完全であり、廃止されています。 Poppler は、Poppler バックエンドへのインターフェイスを提供する Glib および Qt5 のバインディングを提供しますが、Qt5 バインディングは Splash および Arthur バックエンドのみをサポートします。 Cairo バックエンドは、ベクター グラフィックスのアンチエイリアシングと透明オブジェクトをサポートしていますが、スキャンされたドキュメントなどのビットマップ イメージのスムージングは​​サポートしておらず、X ウィンドウ システムに依存しないため、Poppler は Wayland、Windows、macOS などのプラットフォームで実行できます。 Splash バックエンドはビットマップの縮小フィルタリングをサポートしています。 Poppler には、コマンドライン ツール pdftotext 経由で呼び出すことができるテキスト レンダリング バックエンドも付属しており、たとえば grep ツールを使用して、コマンドラインから PDF 内の文字列を検索できます。

画像、表、質問の抽出の問題を解決した後、Tesseract-OCR ツールは、画像と表のコンテンツを分析可能なテキスト形式に変換する上で重要な役割を果たしました。 Tesseract は PDF ファイルを直接処理することはできませんが、.tiff 形式に変換された PDF ファイル内の画像をテキストに変換できます。このプロセスは、マルチモーダル PDF を処理する際の重要なステップであり、これにより、元々画像や表の形式であった情報をテキスト形式に変換してさらに分析できるようになります。

もちろん、PDF 要素を識別して分離するための上記のテクニックに加えて、ベクター ストレージやベクター インデクサーなどのテクニックも使用されます。 でよく使われるので、ここでは詳しくは説明しません。

コードの実装

シナリオと技術分析を行った後、PDF に対してマルチモーダル分析とクエリを実行する必要がある場合は、まず PDF 内の画像、表、テキストを識別する必要があることに気付きました。ここでは、非構造化、Poppler ライブラリ、Tesseract-OCR ツールを紹介します。これらのツールのサポートにより、コーディング プロセスはさらに強力になります。

ライブラリとツールのインストール

!pip install langchain unstructured[all-docs] pydantic lxml openai chromadb tiktoken -q -U !apt-get install poppler-utils tesseract-ocr

上記にはこれまで触れられていないライブラリがいくつかあるので、ここで説明しておきます。

  • pydantic: データの検証と設定の管理に使用します。
  • lxml: XML および HTML 処理ライブラリ。
  • openai: OpenAI の API と対話します。
  • chromadb:ベクターデータベースの管理またはデータストレージに使用されます

PDF情報を抽出する

ツールの準備ができたので、次のステップはPDFを処理することです。 コードの内容は次のとおりです。

 from typing import Any from pydantic import BaseModel from unstructured.partition.pdf import partition_pdf # 设置存放图像的路径images_path = "./images" # 调用partition_pdf 函数处理PDF文件,提取其中的元素raw_pdf_elements = partition_pdf( filename="weekly-market-recap.pdf", # 指定要处理的PDF文件名extract_images_in_pdf=True, # 设置为True以从PDF中提取图像infer_table_structure=True, # 设置为True以推断PDF中的表格结构chunking_strategy="by_title", # 设置文档切分策略为按标题切分max_characters=4000, # 设置每个块的最大字符数为4000 new_after_n_chars=3800, # 在达到3800字符后开始新的块combine_text_under_n_chars=2000, # 将少于2000字符的文本组合在一起image_output_dir_path=images_path, # 指定输出图像的目录路径)

この Python コードは、pydantic ライブラリと unstructured ライブラリを使用して PDF ファイルを処理します。以下にコードの行ごとの説明を示します。

images_path = "./images": PDF から抽出した画像を保存するための変数 images_path を設定します。

次に、PDF ファイルを処理し、そこから要素を抽出するために使用されるpartition_pdf関数を呼び出します。

  • filename="weekly-market-recap.pdf": 処理する PDF ファイル名を指定します。
  • extract_images_in_pdf=True: PDF から画像を抽出するには True に設定します。
  • infer_table_structure=True: PDF 内の表構造を推測するには True に設定します。
  • chunking_strategy="by_title": ドキュメントのチャンク化戦略をタイトルごとにチャンク化するように設定します。
  • max_characters=4000: ブロックあたりの最大文字数を 4000 に設定します。
  • new_after_n_chars=3800: 3800 文字に達した後に新しいチャンクを開始します。
  • combine_text_under_n_chars=2000: 2000文字未満のテキストを結合します。
  • image_output_dir_path=images_path: 出力画像のディレクトリ パスを指定します。

コマンドを通じて PDF 画像の情報を取得できます。上記のコードを通じて画像は images ディレクトリに保存されるため、次のコードを通じて画像が表示されます。

 from IPython.display import Image Image('images/figure-1-1.jpg')

PDFから抽出した画像情報

画像情報の要約を生成する

次のコードは、画像コンテンツの概要情報を生成するために使用される ImageSummarizer というクラスを定義します

 # 引入所需的库import base64 import os # 从langchain包导入ChatOpenAI类和HumanMessage模块from langchain.chat_models import ChatOpenAI from langchain.schema.messages import HumanMessage # 定义图像摘要类class ImageSummarizer: # 初始化函数,设置图像路径def __init__(self, image_path) -> None: self.image_path = image_path self.prompt = """你的任务是将图像内容生成摘要信息,以便检索。这些摘要将被嵌入并用于检索原始图像。请给出一个简洁的图像摘要,以便于检索优化。 """ # 定义函数将图像转换为base64编码def base64_encode_image(self): with open(self.image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode("utf-8") # 定义摘要函数def summarize(self, prompt = None): # 获取图像的base64编码数据base64_image_data = self.base64_encode_image() # 创建ChatOpenAI对象,使用gpt-4-vision预览模型,最大token数为1000 chat = ChatOpenAI(model="gpt-4-vision-preview", max_tokens=1000) # 调用chat对象的invoke方法,发送包含文本和图像的消息response = chat.invoke( [ #人类提示语的输入HumanMessage( content=[ { "type": "text", "text": prompt if prompt else self.prompt }, { "type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image_data}"}, }, ] ) ] ) # 返回base64编码的图像数据和响应内容return base64_image_data, response.content

コードの詳細な説明は次のとおりです。

1. ライブラリをインポートする

イメージエンコードとオペレーティング システム関連の機能用の base64 および os ライブラリをインポートします。

Langchain パッケージから ChatOpenAI クラスと HumanMessage モジュールをインポートします。これらは、OpenAI のチャット モデルと対話するために使用されます。

2. 画像要約クラスImageSummarizerを定義する

__init__ メソッドは、画像パスとサマリー生成のプロンプトを初期化します。

base64_encode_image メソッドは、画像ファイルを読み取り、base64 エンコードに変換します。このエンコード形式は、ネットワーク上で画像を送信するのに適しており、画像情報と GPT モデル間のやり取りを容易にします。

3. 要約関数を定義する

base64_encode_image メソッドを使用して、画像の base64 エンコードされたデータを取得します。

ChatOpenAI オブジェクトを作成し、gpt-4-vision-preview モデルの使用を指定し、画像要約タスクのトークンの最大数を 1000 に設定します。

chat.invoke メソッドを使用して、テキスト プロンプトと画像データを含むメッセージをモデルに送信します。テキストプロンプトは、モデルが画像の概要を生成するようにガイドするために使用されます。

要約関数を作成する目的は、画像の概要を生成することであり、次のステップは関数を呼び出すことです。次のコードは、画像データと画像の概要のリストを作成し、指定されたパス内のすべてのファイルを反復処理してこの情報を生成します。

 # 创建图像数据和图像摘要的列表image_data_list = [] image_summary_list = [] # 遍历指定路径下的所有文件for img_file in sorted(os.listdir(images_path)): # 检查文件扩展名是否为.jpg if img_file.endswith(".jpg"): # 创建ImageSummarizer对象summarizer = ImageSummarizer(os.path.join(images_path, img_file)) # 调用summarize方法生成摘要data, summary = summarizer.summarize() # 将base64编码的图像数据添加到列表image_data_list.append(data) # 将图像摘要添加到列表image_summary_list.append(summary)

コードの説明:

1. 初期化リスト

イメージの base64 でエンコードされたデータと対応するイメージの概要を格納するために、image_data_list と image_summary_list の 2 つのリストが作成されます。

2. 指定されたパスの下にあるすべてのファイルを走査する

os.listdir(images_path) を使用して、指定されたパス (images_path) の下にあるすべてのファイルを一覧表示し、sorted 関数を使用してファイル名を並べ替えます。

3. 各ファイルを確認して処理する

img_file.endswith(".jpg") かどうかをチェックして、ファイル拡張子が .jpg であることを確認し、画像ファイルのみが処理されるようにします。

各 .jpg ファイルに対して、イメージへの完全なパスを渡して ImageSummarizer オブジェクトを作成します。

画像の要約を生成するには、summary メソッドを呼び出します。

返された base64 でエンコードされた画像データを image_data_list リストに追加します。

返された画像の概要を image_summary_list リストに追加します。

最後に、2 つのリストが生成されます。1 つには画像ファイルの base64 エンコードされたデータが含まれ、もう 1 つには対応する画像ダイジェストが含まれます。この情報は、画像の取得やその他の処理に使用できます。

画像の概要情報を表示するには次のコードを使用します

image_summary_list

出力は次のようになります。

[このグラフには、各業界のホリデーシーズンの売上成長、前週比、および年初来(YTD)のパフォーマンス比較に関するデータを示す 3 つの異なるグラフが含まれています。 \n\n最初のグラフは、「ホリデーシーズンの売上成長はパンデミック前のペースに戻る見込み」というタイトルの棒グラフで、2010年から2023年までの11月と12月の前年比売上成長の実績と予測を示しています。青い列は実際のデータ、縞模様の列は予測データ、青い点線は 2010 年から 2019 年までの平均成長率、緑の点線は 2020 年から 2022 年までの平均成長率を表しています。 \n\n2 番目のグラフは、2 つの部分に分かれたカラー ブロック グラフで、「V」、「B」、「G」の 1 週間および年初来 (YTD) のパフォーマンスをさまざまなスケール (大、中、小) で表示します。数値はカラーブロック内に白いテキストで表示されます。 \n\n3 番目のグラフは、1 週間と年初来 (YTD) のさまざまなセクターのパフォーマンスをそれぞれ示す 2 つの横並びの棒グラフです。左側の青いバーは週ごとの変化を示し、右側の緑のバーは年初からの現在までの変化を示しています。グラフの Y 軸はパーセンテージの変化を表し、X 軸にはさまざまな業界がリストされます。 \n\n概要: パンデミック前のレベルに戻ると予想されるホリデーシーズンの売上成長率、さまざまな市場規模 (大規模、中規模、小規模) の 1 週間および年初来のパフォーマンス、さまざまな業界の 1 週間および年初来のパフォーマンス データを示す 3 つのグラフ。 ']

結果から、GPT -4- Vision - Preview このモデルは画像を認識し、いくつかの詳細を制御することができます。

表とテキスト情報を認識する

PDF のコンテンツ全体は、画像、表、テキスト情報で構成されています。画像情報を識別した後、表とテキスト情報から始める必要があります。

次のコードは、PDF ドキュメント要素を処理するプロセスを定義します。

 # 定义一个基本模型Element,用于存储文档元素的类型和文本内容class Element(BaseModel): type: str text: Any # 创建表格元素和文本元素的空列表#表格信息table_elements = [] #文本信息text_elements = [] # 遍历从PDF中分割出的所有元素for element in raw_pdf_elements: # 判断元素是否为表格:非结构化-文档-元素-表格if "unstructured.documents.elements.Table" in str(type(element)): # 如果是表格,将其添加到表格元素列表table_elements.append(Element(type="table", text=str(element))) # 判断元素是否为复合元素elif "unstructured.documents.elements.CompositeElement" in str(type(element)): # 如果是复合元素,将其添加到文本元素列表text_elements.append(Element(type="text", text=str(element)))

コードの説明は次のとおりです。

1. 要素の基本モデルを定義する

pydantic の BaseModel を使用して、ドキュメント要素のタイプ (テーブルやテキストなど) とテキスト コンテンツを格納するための Element というクラスが定義されます。このクラスは、型注釈 str と Any を使用して、type (要素型) と text (要素コンテンツ) の 2 つのプロパティを定義します。

2. テーブルとテキスト要素を格納するための空のリストを作成する

table_elements と text_elements は、それぞれテーブル情報とテキスト情報を格納するために使用されます。

3. PDF内の要素を走査する

PDF ファイルから分割された各要素 (raw_pdf_elements 内) について、コードは要素のタイプを判別して分類します。

要素がテーブル ( unstructured.documents.elements.Table ) の場合は、タイプを「table」に設定し、テキスト コンテンツを要素の文字列表現に設定した Element オブジェクトを作成し、このオブジェクトを table_elements リストに追加します。

要素が複合要素 (unstructured.documents.elements.CompositeElement) である場合、同様に処理され、そのタイプは「text」に設定され、text_elements リストに追加されます。

PDF ドキュメント内のさまざまな要素を分類して保存した後、次のステップでは、それらを処理し、表とテキストを要約します。コードは次のとおりです。

 # 导入所需模块from langchain.chat_models import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain.schema.output_parser import StrOutputParser # 定义用于生成总结的提示文本prompt_text = """您负责简洁地总结表格或文本块,中文输出。: {element} """ # 从模板创建提示prompt = ChatPromptTemplate.from_template(prompt_text) # 创建总结链,结合提示和GPT-3.5模型summarize_chain = {"element": lambda x: x} | prompt | ChatOpenAI(temperature=0, model="gpt-3.5-turbo") | StrOutputParser() # 从表格元素中提取文本tables = [i.text for i in table_elements] # 使用总结链批量处理表格文本,设置最大并发数为5 table_summaries = summarize_chain.batch(tables, {"max_concurrency": 5}) # 从文本元素中提取文本texts = [i.text for i in text_elements] # 使用总结链批量处理文本,设置最大并发数为5 text_summaries = summarize_chain.batch(texts, {"max_concurrency": 5})

このコードは、LangChain と GPT-3.5 モデルを使用して、テーブルとテキスト ブロックの要約を生成するために使用されます。

1. モジュールをインポートする

LangChain の ChatOpenAI、ChatPromptTemplate、および StrOutputParser モジュールをインポートします。

2. 要約を生成するためのプロンプトテキストを定義する

モデルの概要テーブルまたはテキスト ブロックをガイドするために使用されるプロンプト テキスト テンプレートを定義します。

3. プロンプトと要約の連鎖を作成する

ChatPromptTemplate.from_template を使用して、定義されたプロンプト テキストに基づいてプロンプトを作成します。

プロンプト、GPT-3.5 モデル (サマリーを生成する機能には GPT -4 は必要ないため、トークンを保存するには GPT -3.5が使用されます)、および文字列出力パーサー (StrOutputParser) を組み合わせた、summary_chain という名前のサマリー チェーンを作成します。

4. 表とテキスト要素の処理

table_elements からテーブル テキストを抽出し、summary_chain.batch メソッドを使用してテキストをバッチ処理します。同時ユーザーの最大数は 5 に設定されています。

最大同時実行数を 5 に設定して、バッチ処理に summary_chain.batch も使用して、text_elements からテキスト ブロックのテキストを抽出します。

要約を次のように出力します。

表とテキストの要約情報

インデクサーを作成する

さて、ここまでで、PDF 内の画像、表、テキスト情報を一つずつ抽出しその後の検索を容易にするためにこれらの情報の要約を生成しました。この一連の準備ができたら、インデクサーを配置する必要があります名前が示すように、インデクサーは検索を容易にするために検索対象の情報にインデックスを追加します

次のコードは、テキスト、テーブル、および画像データを保存および取得するためのマルチベクトル リトリーバーを作成します。

 import uuid # 导入uuid库,用于生成唯一标识符# 导入所需的langchain模块from langchain.embeddings import OpenAIEmbeddings from langchain.retrievers.multi_vector import MultiVectorRetriever from langchain.schema.document import Document from langchain.storage import InMemoryStore from langchain.vectorstores import Chroma id_key = "doc_id" # 设置文档的唯一标识键# 初始化多向量检索器,初始为空,文字,图片,表格retriever = MultiVectorRetriever( vectorstore=Chroma(collection_name="summaries", embedding_function=OpenAIEmbeddings()), # 使用OpenAI的嵌入方法docstore=InMemoryStore(), # 使用内存存储文档id_key=id_key, # 设置文档的唯一标识键) # 为文本添加唯一标识doc_ids = [str(uuid.uuid4()) for _ in texts] # 为每个文本生成一个唯一的UUID # 创建文本的文档对象并添加到检索器summary_texts = [ Document(page_content=s, metadata={id_key: doc_ids[i]}) # 将文本封装为文档对象for i, s in enumerate(text_summaries) ] retriever.vectorstore.add_documents(summary_texts) # 将文本文档添加到向量存储中retriever.docstore.mset(list(zip(doc_ids, texts))) # 将文本文档的ID和内容存储在内存存储中# 为表格添加唯一标识table_ids = [str(uuid.uuid4()) for _ in tables] # 为每个表格生成一个唯一的UUID # 创建表格的文档对象并添加到检索器summary_tables = [ Document(page_content=s, metadata={id_key: table_ids[i]}) # 将表格封装为文档对象for i, s in enumerate(table_summaries) ] retriever.vectorstore.add_documents(summary_tables) # 将表格文档添加到向量存储中retriever.docstore.mset(list(zip(table_ids, tables))) # 将表格文档的ID和内容存储在内存存储中# 为图像添加唯一标识doc_ids = [str(uuid.uuid4()) for _ in image_data_list] # 为每个图像生成一个唯一的UUID # 创建图像的文档对象并添加到检索器summary_images = [ Document(page_content=s, metadata={id_key: doc_ids[i]}) # 将图像封装为文档对象for i, s in enumerate(image_summary_list) ] retriever.vectorstore.add_documents(summary_images) # 将图像文档添加到向量存储中retriever.docstore.mset(list(zip(doc_ids, image_data_list))) # 将图像文档的ID和内容存储在内存存储中

コードの説明:

1. マルチベクトルサーチャーを初期化する

Chroma をベクター ストレージとして使用し、OpenAI 埋め込み方式を利用してドキュメントをベクター形式に変換します。

ドキュメントをメモリに保存する方法である InMemoryStore をドキュメント ストレージとして使用します。

id_key をドキュメントの一意の識別子に設定します。

2. テキストデータの処理

各テキストに一意の識別子 (UUID) を作成します。

テキスト サマリーを Document オブジェクトとしてカプセル化し、ベクター ストレージとドキュメント ストレージに追加します。

3. 表形式データの処理

同様に、各テーブルの UUID を作成します。

テーブル サマリーを Document オブジェクトとしてカプセル化し、ベクター ストレージとドキュメント ストレージに追加します。

4. 画像データの処理

各イメージの UUID を作成します。

画像サマリーを Document オブジェクトとしてカプセル化し、ベクター ストレージとドキュメント ストレージに追加します。

このコードは、各ドキュメントを管理するために一意の識別子を使用して、テキスト、表、画像など、複数の種類のドキュメント データを保存および取得できるシステムを構築します。これは、大量の複雑なデータを処理および整理するのに非常に役立ちます。

マルチモーダルクエリプロンプトを生成する

次のコードには、画像とテキスト データを処理および表示するためのいくつかの関数が含まれています。

 from PIL import Image from IPython.display import HTML, display import io import re # 显示基于base64编码的图片def plt_img_base64(img_base64): display(HTML(f'')) # 检查base64数据是否为图片def is_image_data(b64data): """通过查看数据开头来检查base64数据是否为图片""" image_signatures = { b"\xFF\xD8\xFF": "jpg", b"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A": "png", b"\x47\x49\x46\x38": "gif", b"\x52\x49\x46\x46": "webp", } try: header = base64.b64decode(b64data)[:8] # 解码并获取前8个字节for sig, format in image_signatures.items(): if header.startswith(sig): return True return False except Exception: return False # 分离base64编码的图片和文本def split_image_text_types(docs): """分离base64编码的图片和文本""" b64_images = [] texts = [] for doc in docs: # 检查文档是否为Document类型并提取page_content if isinstance(doc, Document): doc = doc.page_content #是图片if is_image_data(doc): b64_images.append(doc) else: texts.append(doc) return {"images": b64_images, "texts": texts} # 根据数据生成提示信息def img_prompt_func(data_dict): messages = [] # 如果存在图片,则添加到消息中#图片的信息单独拿出来, 需要和提示语一起传给大模型的。 if data_dict["context"]["images"]: for image in data_dict["context"]["images"]: image_message = { "type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{image}"}, } messages.append(image_message) # 添加文本到消息formatted_texts = "\n".join(data_dict["context"]["texts"]) text_message = { "type": "text", "text": ( "You are financial analyst.\n" "You will be given a mixed of text, tables, and image(s) usually of charts or graphs.\n" "Use this information to answer the user question in the finance. \n" f"Question: {data_dict['question']}\n\n" "Text and / or tables:\n" f"{formatted_texts}" ), } messages.append(text_message) print(messages) return [HumanMessage(content=messages)]

コードの説明:

1. base64でエンコードされた画像を表示する(plt_img_base64)

この関数の目的は、base64 でエンコードされた画像を表示することです。

2. base64データが画像であるかどうかを確認する (is_image_data)

base64 でエンコードされたデータの先頭が一般的な画像形式 (JPEG、PNG、GIF、WEBP など) の署名と一致するかどうかを確認して、データが画像かどうかを判断します。

3. base64でエンコードされた画像とテキストを分離する(split_image_text_types)

この関数はドキュメント コレクションを反復処理し、is_image_data 関数を使用してどれが画像データでどれがテキストかを区別し、それぞれ 2 つのリストに格納します。

4. データに基づいてプロンプト情報を生成する (img_prompt_func)

この関数は、LangChain ビッグモデルに渡すメッセージを生成します。各画像に対して、画像の URL を含むメッセージを作成します。テキスト データの場合は、プロンプト テキストと質問を含むメッセージを作成します。

「テキスト」は特別に説明する必要があります。これはメッセージの特定のテキスト コンテンツを定義します。

まず、ユーザーの役割が次のように示されます:「あなたは財務アナリストです。」

次に、タスクの種類とデータ形式について説明します。「通常はチャートやグラフなどのテキスト、表、画像が混在して提供されます。」

ヒント: この情報を使用して、財務に関するユーザーの質問に回答します。

{data_dict['question']}: {} 内の部分は Python 文字列形式のプレースホルダーで、変数 data_dict の 'question' キーに対応する値、つまりユーザーが尋ねた質問を挿入するために使用されます。

「テキストおよび/または表:\n」: 後続のコンテンツがテキストおよび/または表であることを示すプロンプト テキスト。

f"{formatted_texts}": 文字列フォーマットを再度使用して、変数 formatted_texts (フォーマットされたテキスト データ) をメッセージに挿入します。

財務分析クエリの実装

これで準備が整いましたので、GPT -4- Vision - Preview モデルを使用して推論を開始できます。インデクサーに質問して、結果を確認してみましょう。

次のコードは、RAG (Retrieval Augmented Generation) モデルに基づくクエリ処理パイプラインを実装します。

 from langchain.schema.runnable import RunnableLambda, RunnablePassthrough # 创建ChatOpenAI模型实例model = ChatOpenAI(temperature=0, model="gpt-4-vision-preview", max_tokens=1024) # 构建RAG(Retrieval Augmented Generation)管道chain = ( { "context": retriever | RunnableLambda(split_image_text_types), # 使用检索器获取内容并分离图片和文本"question": RunnablePassthrough(), # 传递问题} | RunnableLambda(img_prompt_func) # 根据图片和文本生成提示信息| model # 使用ChatOpenAI模型生成回答| StrOutputParser() # 解析模型的字符串输出) # 定义查询问题query = "Which year had the highest holiday sales growth?" # 调用chain的invoke方法执行查询chain.invoke(query)

コードの説明:

1. ChatOpenAIモデルインスタンスを作成する

ChatOpenAI クラスを使用してモデル インスタンスを作成し、温度パラメータを 0 に設定し、gpt-4-vision-preview モデルを使用して、トークンの最大数を 1024 に設定します。

2. RAGパイプライン(チェーン)を構築する

リトリーバー | RunnableLambda(split_image_text_types): まずリトリーバーを使用してコンテンツを取得し、次に RunnableLambda を通じて split_image_text_types 関数を呼び出して画像とテキストを分離します。

RunnablePassthrough(): クエリの質問を直接渡すために使用されます。

RunnableLambda(img_prompt_func): 取得した画像とテキストに基づいてプロンプト情報を生成します。

モデル: 構成された ChatOpenAI モデルを使用して、生成されたプロンプト情報に基づいて回答を生成します。

StrOutputParser(): モデルによって出力された文字列を解析します。

3. クエリを定義する

文字列クエリをクエリの質問として定義します。例: 「休日の売上成長率が最も高かったのはどの年ですか?」

4. クエリを実行する (chain.invoke(query))

チェーンの呼び出しメソッドを呼び出すと、クエリが実行され、質問と取得された情報に基づいて回答が生成されます。

全体として、このコード スニペットは、コンテンツの取得、データの分離、プロンプトの生成、モデル回答を組み合わせて、テキストと画像データに基づいて複雑な質問を処理して回答する、洗練されたクエリ処理パイプラインを構築します。

出力を表示するには:

提供されたグラフによると、ホリデーシーズンの売上成長率が最も高かったのは 2021 年で、成長率は 12.7% でした。これは、「実際」セクションの棒グラフで最も高いバーで示されており、11 月と 12 月の売上の実際の前年比成長率を表しています。

これを中国語に翻訳すると次のようになります。

提供されたグラフによると、2021年のホリデーシーズンの売上高は12.7%と過去最高の伸びを記録しました。これは、棒グラフの「実線」部分の最も高い棒からわかります。これは、11 月と 12 月の前年比成長率を表しています。

PDFのチャート部分と大規模モデル応答の比較

大規模なモデルの応答を通じて、ホリデーセールスの成長率を説明するPDFのバーチャートと比較することで、 2021年の成長率が12.7 で最も高く、「ソリッド」カラムの説明も正しいことが明確にわかります。 Openaiが提供するマルチモーダル機能は機能したようです。

要約する

分析と例のデモンストレーションを通じて、この記事は、Multimodalデータ処理におけるOpenaiの最新技術の潜在的およびアプリケーションの見通しを明確に示しています。構造化されていないライブラリ、ポップラーツール、およびTesseract-OCCツールの詳細な紹介とコードの実装を通じて、この記事は読者に理論的知識を提供するだけでなく、これらのツールを実際に操作および適用する方法をガイドします。この記事の結論は、分析の効率を改善し、人的エラーを減らす際のGPT-4-Vision-Previewモデルの価値を強調しています。

著者について

51CTO コミュニティ エディター兼シニア アーキテクトの Cui Hao 氏は、ソフトウェア開発とアーキテクチャで 18 年の経験があり、分散アーキテクチャでは 10 年の経験があります。

<<: 

>>:  年末ですね!ファーウェイクラウド開発者デーと2023イノベーションサミットが成功裏に開催されました

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

...

...

...

...

AIが人間社会に与える影響

今後 25 年間は、既存の制御可能かつプログラム可能ないわゆる「人工知能」を活用して、人類が生物学の...

絶対確実な協働ロボット

人間とロボットが協力して協働ロボットを作る[[321860]]協働ロボットは人間と対話し、協働するよ...

...

知恵くんの“いいとこ”が明らかに!初のユニバーサルな具現化ベースモデル、ロボットは「理解はできるができない」状態に別れを告げる

先週金曜日、知会君は微博で「来週は良いものがリリースされる」と発表した。 「来週」になって間もなく、...

...

WeChat、サードパーティのエコシステムに統合するインテリジェント会話システム「Xiaowei」を発表

2019年WeChatオープンクラスPROで、WeChat AIチームが開発したインテリジェント対話...

...

疫病流行中に物流の円滑化に全力を尽くし、無人配送市場が活況を呈している

最近、国務院は貨物物流の円滑な流れを確保するために関連業務を展開するよう通知し、各地域と関連部門に主...

.NET8 究極のパフォーマンス最適化 プリミティブ - DateTime

序文前回の記事では列挙型の最適化について説明しました。今回は時刻形式である DateTime の最適...

MLOps 向け機械学習設計パターン

著者 | Pier Paolo Ippolito、データ サイエンティスト翻訳者 | 陸新王校正 |...

...