Databricks生成AIクックブック - 3.1. データパイプライン

[3\.1\. Data pipeline — Databricks Generative AI Cookbook](https://ai-cookbook.io/nbs/3-deep-dive-data-pipeline.html) [2024/6/22時点]の翻訳です。

:::note warn
本書は著者が手動で翻訳したものであり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

> [Databricks生成AIクックブック](https://qiita.com/taka_yayoi/items/36c51bce8f33a70cf204)のコンテンツです。


# 3.1. データパイプライン

![](https://ai-cookbook.io/_images/1_img2.png)
非構造化データを用いるすべてのRAGアプリケーションの基盤はデータパイプラインです。このパイプラインは、RAGアプリケーションで効果的に活用されるフィーマットで非構造化データを準備することに責任を持ちます。このデータパイプラインの複雑性は多岐に渡りますが、ご自身のRAGアプリケーションを初めて構築する際に検討すべきキーコンポーネントは以下の通りとなります:

1. **コーパスの構成:** 特定のユースケースに基づき適切なデータソースとコンテンツを選択
1. **パーシング:** 適切なパーシング技術を用いて生データから適切な情報を抽出
1. **チャンキング:** 効率的な収集のために、パースしたデータを小規模かつ管理可能なチャンクに分割
1. **エンべディング:** チャンクテキストデータを意味をキャプチャする数値ベクトル表現に変換

[データパイプラインの変更の実装](https://qiita.com/taka_yayoi/items/fd2f3cd4119184e62ce5)では、これらのデータパイプラインにおけるすべての選択肢を実践的な観点から、どのように実験するのかを議論します。

## 3.1.1. コーパスの構成

言うまでもないことですが、適切なデータコーパスなしにはあなたのRAGアプリケーションはユーザーのクエリーで必要とされる情報を収集することができません。適切なデータとは、特定の要件やあなたのアプリケーションのゴールに全体的に依存し、利用可能なデータのニュアンスを理解するために十分な時間をかけることが重要となります(このガイドについては[requirements gathering section](https://ai-cookbook.io/nbs/5-hands-on-requirements.html)をご覧ください)。

例えば、カスタマーサポートbotを構築する際、以下のようなことを検討するかもしれません:

- ナレッジベースのドキュメント
- FAQ
- 製品マニュアルや仕様
- トラブルシューティングガイド

どのようなプロジェクトにおいても、最初に適切なコンテンツを特定、キュレーションする助けとなるドメイン専門家やステークホルダーと連携することで、あなたのデータコーパスの品質やカバレッジを改善することができます。彼らは、ユーザーが送信するであろうクエリーのタイプに対する洞察を提供し、含めるべき最も重要な情報の優先度付けの助けになります。

## 3.1.2. パーシング

あなたのRAGアプリケーションのデータそーすを特定したら、次のステップは、生のデータから必要な情報を抽出することになります。パーシングとして知られるこのプロセスには、非構造化データをRAGアプリケーションで効果的に利用できるようなフォーマットに変換する処理が含まれます。

仕様する固有のパーシング技術やツールは、取り扱うデータのタイプに依存します。例えば:

- **テキスト文書**(PDF、Word文書など): [unstructured](https://github.com/Unstructured-IO/unstructured)や[PyPDF2](https://pypdf2.readthedocs.io/en/3.x/)のようにすぐ利用できるライブラリは、さまざまなファイルフォーマットを取り扱うことができ、パーシング処理のカスタマイズのオプションを提供します。
- **HTML文書**: [BeautifulSoup](https://beautiful-soup-4.readthedocs.io/en/latest/)のようなHTMLパーシングライブラリは、Webページから適切なコンテンツを抽出するために活用されます。これらを用いることで、HTML構造をナビゲートし、特定の要素を選択し、必要なテキストや属性を抽出することができます。
- **画像やスキャンされた文書**: 画像からテキストを抽出するには、通常Optical Character Recognition (OCR)技術が必要となります。人気のあるOCRライブラリには、[Tesseract](https://github.com/tesseract-ocr/tesseract)、[Amazon Textract](https://aws.amazon.com/textract/ocr/)、[Azure AI Vision OCR](https://azure.microsoft.com/en-us/products/ai-services/ai-vision/)、[Google Cloud Vision API](https://cloud.google.com/vision)があります。

データをパーシングする際、以下のベストプラクティスを検討しましょう:

1. **データクリーニング:** ヘッダー、フッター、特殊文字のような不適切、ノイズとなる情報を除外するために抽出テキストを前処理します。あなたのRAGチェーンで処理が必要となるような不必要、壊れた情報の量を減らすことを認識しましょう。
1. **エラーと例外の対応:** パーシング処理で生じるいかなる問題を特定、解決するためのエラーハンドリングやロギングの機構を実装しましょう。これによって、問題をクイックに特定、修正できるようになります。これを行うことで、多くの場合、ソースデータの品質による上流の問題につながることになります。
1. **パーシングロジックのカスタマイズ:** あなたのデータの構造やフォーマットによっては、より適切な情報を抽出するために、パーシングロジックをカスタマイズ必要があるかもしれません。事前の追加工数を必要とするかもしれませんが、必要な際にこれを行うことに投資することで、下流の品質問題の多くを回避することができます。
1. **パーシング品質の評価:** アウトプットのサンプルを手動でレビューすることで、パースしたデータの品質を定期的に評価しましょう。これによって、パーシング処理におけるすべての問題や改善の余地を特定する助けになります。

## 3.1.3. チャンキング

![](https://ai-cookbook.io/_images/2_img1.png)

生データをより構造化されたフォーマットにパーシングした後の次のステップは、*チャンク*と呼ばれるより小さく管理可能な単位に分割することとなります。大規模なドキュメントを小規模かつ意味的に集約されたチャンクに分割することで、収集されたデータがLLMのコンテキストに収まるようになることに加え、邪魔で不適切な情報が含まれることを最小化できます。チャンキングにおける選択は、LLMに与えられる収集データに直接的な影響を与えるので、RAGアプリケーションにおける最適化の最初のレイヤーの一つとなります。

データをチャンキングする際、通常は以下のファクターを検討する必要があります:

1. **チャンキング戦略:** オリジナルのテキストをチャンクに分割するために用いる手法です。これには、文、段落、あるいは特定の文字/トークン数による分割のような基本的なテクニックから、より高度なドキュメント固有の分割戦略が含まれます。
1. **チャンクのサイズ:** より小さいチャンクは特定の詳細にフォーカスしますが、いくつかの周辺情報を失うことになります。より大きなチャンクはより多くのコンテキストを捕捉しますが、不適切な情報を含むことにもなります。
1. **チャンク間のオーバーラップ:** データをチャンクに分割する際に重要な情報が失われないようにするために、隣接するチャンク間である程度オーバーラップさせることを検討しましょう。オーバーラップによって、チャンク間の連続性やコンテキストの保持を可能にします。
1. **意味の一貫性:** 可能であれば、意味論的に一貫性のある、つまり関連する情報を含み、それ単体で意味のあるテキスト単位となるようなチャンクを作成することを狙いましょう。これは、段落、セクション、トピックの境界のようなオリジナルデータの構造を検討することで成し遂げることができます。
1. **メタデータ:** それぞれのチャンクに、ソースとなる文書名、セクションの見出し、製品名のような適切なメタデータを含めることで、収集プロセスを改善することができます。このチャンクの追加情報は、チャンクに収集クエリーをマッチさせる助けとなります。

適切なチャンク手法を特定することは、試行錯誤でコンテキスト依存の取り組みとなります。全てに通用するアプローチはありません。最適なチャンクサイズや手法は、特定のユースケースや処理されるデータの性質に依存します。広く言えば、チャンク戦略には以下のようなものがあります:

- **固定サイズのチャンキング:** 固定の文字数やトークンのように事前に定義したサイズでテキストを分割します([LangChain CharacterTextSplitter](https://python.langchain.com/v0.2/docs/how_to/character_text_splitter/)など)。任意の数の文字/トークンによる分割は、セットアップがクイックで簡単ですが、多くの場合、意味的に一貫性のあるチャンクにはなりません。
- **段落ベースのチャンキング:** チャンクを定義するためにテキスト本来の段落境界を使用します。この手法は、段落には多くの場合関連情報が含まれているのでチャンクの意味的な一貫性を保持する助けになります([LangChain RecursiveCharacterTextSplitter](https://python.langchain.com/v0.2/docs/how_to/recursive_text_splitter/)など)。
- **フォーマット固有のチャンキング:** マークダウンやHTMLのようなFOMAとには、チャンク境界の定義に使える構造が備わっています(マークダウンのヘッダーなど)。LangChainの[MarkdownHeaderTextSplitter](https://python.langchain.com/v0.2/docs/how_to/markdown_header_metadata_splitter/#how-to-return-markdown-lines-as-separate-documents)やHTMLの[ヘッダー](https://python.langchain.com/v0.2/docs/how_to/HTML_header_metadata_splitter/)/[セクション](https://python.langchain.com/v0.2/docs/how_to/HTML_section_aware_splitter/)ベースのスプリッターをこの目的で使用することができます。
- **セマンティックチャンキング:** テキスト内の意味的に一貫性のあるセクションを特定するために、トピックモデリングのようなテクニックを活用することができます。これらのアプローチでは、トピックの移り変わりに基づいて最も適切なチャンクの境界を特定するために、それぞれのドキュメントのコンテンツや構造を分析します。より基本的なアプローチよりも多くのことが必要となりますが、セマンティックチャンキングはテキストの自然な意味的な境界により則したチャンクを作成する助けとなります(このサンプルについては、[LangChain SemanticChunker](https://python.langchain.com/v0.2/docs/how_to/semantic-chunker/)をご覧ください)。

![](https://ai-cookbook.io/_images/3_img1.png)

**例:** LangChainの[RecursiveCharacterTextSplitter](https://python.langchain.com/docs/modules/data_connection/document_transformers/text_splitters/recursive_text_splitter)で`chunk_size=100`と`chunk_overlap=20`を指定した固定サイズのチャンキングの例。[ChunkViz](https://chunkviz.up.railway.app/)は、様々なチャンクサイズやチャンクのオーバーラップでLangchainの文字列スプリッターが結果のチャンクにどのように影響するのかを可視化するインタラクティブな手段を提供します。

## 3.1.4. エンべディングモデル

![](https://ai-cookbook.io/_images/4_img1.png)

データをチャンキングしたら、次のステップではエンべディングモデルを用いてテキストのチャンクをベクトル表現に変換します。えんべディングモデルは、それぞれのテキストチャンクを意味を捕捉するベクトル表現に変換するために使用されます。チャンクを密なベクトルとして表現することで、エンべディングは収集クエリーに対する意味的な類似性に基づき最も適切なチャンクを高速かつ正確に収集できるようにしてくれます。クエリー時には、データパイプラインでチャンクのエンべディングを作成するのに使用されたのと同じエンべディングモデルを用いて収集クエリーが変換されます。

エンべディングモデルを選択する際には以下のファクターを検討しましょう:

- **モデルの選択:** それぞれのエンべディングモデルにはニュアンスがあり、利用できるベンチマークではあなたのデータ固有の特性を捕捉できない場合があります。[MTEB](https://huggingface.co/spaces/mteb/leaderboard)のような標準的なリーダーボードでは順位が低かったとしても、すぐに利用できる様々なエンべディングモデルで実験しましょう。以下のようなものがあります:
    - [GTE\-Large\-v1\.5](https://huggingface.co/Alibaba-NLP/gte-large-en-v1.5)
    - [OpenAI’s text\-embedding\-ada\-002, text\-embedding\-large, and text\-embedding\-small](https://platform.openai.com/docs/guides/embeddings)
- **最大トークン数:** 選択したエンべディングモデルの最大トークン数の制限に注意しましょう。この制限を超えたチャンクを送信すると、超えた部分は切り捨てられて重要な情報を失うことになりかねません。例えば、[bge\-large\-en\-v1\.5](https://huggingface.co/BAAI/bge-large-en-v1.5)の最大トークン制限は512です。
- **モデルのサイズ:** より大きなエンべディングモデルは通常優れたパフォーマンスを提供しますが、より多くの計算リソースを必要とします。あなた固有のユースケースや利用可能なリソースに基づいて、パフォーマンスと効率性のバランスを見極めましょう。
- **ファインチューニング:** あなたのRAGアプリケーションがドメイン固有の言語(企業内部の略語や用語など)を取り扱う場合、ドメイン固有のデータによるエンべディングモデルのファインチューニングを検討しましょう。これによって、モデルがあなた固有のドメインのニュアンスや用語をキャプチャする助けとなり、多くの場合、より良い収集パフォーマンスにつながります。

<br>

- [目次](https://qiita.com/taka_yayoi/items/36c51bce8f33a70cf204#%E7%9B%AE%E6%AC%A1) 
- 前のセクション: [3\. RAG品質のノブ](https://qiita.com/taka_yayoi/items/c5d63ebe767ec9833464)
- 次のセクション: [3.2. 収集、拡張、生成(RAGチェーン)](https://qiita.com/taka_yayoi/items/7097a738ea8e014d86f2)

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)