「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>テキスト生成系(Transformer系)#j2f01d54]] > チューニング、拡張系 -[[戻る>テキスト生成系(Transformer系)#j2f01d54]] > [[チューニング、拡張系>テキスト生成系(Transformer系)#j2f01d54]] --[[LLMのPE]] --LLMのRAG --[[LLMのFT]] --[[LLMエージェント]] *目次 [#v3e6c832] #contents *概要 [#sd1c2529] RAG(Retrieval-Augmented Generation) -LLMと情報検索を組み合わせた技術。 -情報取得や質問応答の分野で強力。 **開発方法 [#f7e304f0] ***SaaSの活用 [#s206bcea] [[LangChain、LangFlow>LangChain]]など、複雑なRAGインフラをSaaSにオフロードする場合がある。 ***ローカルRAG [#h03251d8] -[[LlamaIndex]]などのライブラリや[[NoSQL]]を使用する。 -[[NoSQL]]には、古くは[[Elasticsearch]]などを使用していたが、 -ベクトル検索([[VDB>#jb21532e]])だけでなく、グラフ検索に対応した新しいものが出てきている。 **機能・コンポーネント [#b33f960a] ***チャンク(Chunk) [#cbbf5380] -Chunkは、大量のデータを小さなSegment(Chunk)に分割する。 -このプロセスにより、特定の情報を検索し易くなる。 -各Chunkは、独立して検索可能な単位となる。 ***埋め込み(Embedding) [#g25cf8bc] -Embeddingは、テキストデータを数値ベクトルに変換するプロセス。 -ベクトル化により、テキストデータの意味的な類似性を計算が容易になる。 -ベクトル検索のRAGでは、EmbeddingベースのRetrievalで、最も関連性の高い[[Chunk>#cbbf5380]]を特定する。 ***検索(Retrieval) [#z4398317] -Retrievalでは、Queryに対して関連性の高い情報をDBから取得する。 -具体的には、プロンプトに対して最も関連性の高い[[Chunk>#cbbf5380]]を検索で見つけ出す。 ***拡張(Augmented) [#kf1ec50b] ユーザ入力+取得した情報を統合して拡張。 ***生成(Generation) [#af8a2a61] 生成部分では、統合情報を入力し、LLMがユーザーに回答を提供する。 **プロセス [#ua88c3f1] ***知識情報の分割 [#m987e543] ユーザーが知識情報を入力 ***知識情報の埋め込み [#q1d7194a] [[Embedding>#g25cf8bc]]で知識情報を埋め込みベクトルに変換 ***質問の入力(Query Input) [#ke8dc9d5] ユーザーが質問を入力 ***質問の埋め込み(Query Embedding) [#a215a73b] [[Embedding>#g25cf8bc]]で質問を埋め込みベクトルに変換 ***情報の検索(Information Retrieval) [#l406cb00] 質問の埋め込みベクトルを使用して、DB内の関連[[Chunk>#cbbf5380]]を検索 ***情報の生成(Information Generation) [#n074a720] -検索された[[Chunk>#cbbf5380]]を基にプロンプトを生成 -LLMが生成されたプロンプトを元に回答を生成 ***回答の提供(Answer Delivery) [#n38a7441] 最終的にユーザーに回答を提供 **キーワード [#zf9ac7c8] ***埋め込みベクトル(Embedding Vector) [#a834b095] [[Embedding>#g25cf8bc]]で、テキストをベクトルに変換した表現方法。 ***類似性計算(Similarity Calculation) [#e5030f58] 埋め込みベクトル間の類似性を内積、距離などで計算するプロセス。 *詳細 [#u72d6203] RAGの拡張手法について **手法 [#ffeceb93] 代表的な手法 ***Chunk拡張 [#ff58b3b9] -非常に単純な手法で、検索でヒットしたChunkの前後のChunkもコンテキストに含めてLLMに渡すという方法 -Chunkサイズを大きくする場合と効果は似ているが、Chunkサイズを大きくすると、検索精度が落ちる問題があった。 ***Re-Rank [#peef05d6] -検索で得たChunkに対して、クエリとの類似度が高い順に並び変え再度ランク付けをする手法 -Chunkを得るための検索はベクトルの内積計算にして、Re-RankでTransformerやLLMを使用する。 -これにより、高コストの処理を減らし、消費するリソースを削減できる。 ***RAG-Fusion [#mca436c9] -入力クエリに類似したクエリをLLMにより幾つか生成し、それぞれのクエリの検索結果を統合する方法。 -類似クエリでも上位に来るChunkは重要なChunkだと言う仮定から、投票制で重要なChunkを取得する。 ***Hybrid-Query [#u7a9dad3] ハイブリッド・サーチ、ハイブリッド検索 -性質の異なる複数の検索方式(例えばベクトル検索とキーワード検索)を組み合わせて検索精度を向上させる手法 -キーワードベースの検索とベクトル検索を組み合わせたハイブリッド検索で精度が高く出るという結果が報告されている。 -検索技術 --キーワード検索~ 「文書の内容に沿った」キーワード検索を実現 ---[[TF-IDF>言語処理(AI)#hdbd22d6]] ---BM25(TF-IDFの進化系) --ベクトル検索~ 文の意味ベースの類似性によって検索する。 ---BERT ---Sentence-Transformers --その他の検索(従来型) ---非構造化データの全文検索 ---構造化データの検索(階層構造、テーブル構造) --その他の検索(新型) ---Graph検索(LLMを使用しネットワーク構造のインデックスを構築し検索) ---... ***Sub Query [#ua8eeae7] -入力クエリが複雑な場合や、複合的な意味を持っている場合に有効な手法 -入力クエリをSub Queryに分解し、それぞれのSub Queryでのレスポンスを最後に合成して回答する -例 --入力クエリ 「XとYの意味をそれぞれ教えて」 --LLMによって生成されたSub Query ---Sub Query1 Xの詳細な定義とその意味は何ですか? ---Sub Query2 Yの詳細な定義とその意味は何ですか? --最終レスポンス Sub Query1への回答+Sub Query2への回答 ***Multi Step Query [#q773e8b1] -クエリの分解と段階的な推進により、複数のChunkを取得して回答を洗練させる手法 -例 --データソース: 著者に関する質問に答える --入力クエリ: 著者が始めた事業共創プログラムの最初のメンバーには誰が参加しましたか? --クエリの分解1: ---Q:著者はどのような事業共創プログラムを開始しましたか? ---A:著者は、Y Combinator (YC) という事業共創プログラムを開始しました。 --クエリの分解2: ---Q:Y Combinator の事業共創プログラムの最初のメンバーは誰ですか? ---2005 年に開始された Y Combinator の事業共創プログラムの最初のバッチには、次のようなスタートアップ企業が含まれていました。 --クエリの分解3: ---Q:なし(これ以上の質問はありません)。 ---A: --最終的な回答:~ Y Combinator 事業共創プログラムの最初のバッチには、~ Reddit (Steve Huffman と Alexis Ohanian によって設立)、~ Loopt、Weebly、Twitch (Justin Kan によって設立) などのスタートアップが含まれていました。 ***HyDE [#oa40213d] -Hypothetical Document Embeddingsの略で、LLMに仮の回答を作らせて、その仮の回答をベクトル化して検索に使うという方法。 -本来はQ&AでQからA(が書かれているだろうChunk)を当てに行くが、QからLLMで生成したA'を使用してAを当てに行く。 -LLMが「A」についての基礎知識を有しており「A'」を肉付けしたものが「A」になるようなケースで利用できる可能性がある。 ***Stepback Prompt [#kc135197] -入力Promptを一段抽象化させたStepback Promptをクエリに用いてChunk検索した結果と合成する。 -Promptに対してピンポイントなChunkがないケースでもStepback Promptで推論が可能になるケースがある。 --Stepback Promptで定義、歴史、計算式などの「基礎的なChunk」を取得して回答を行う。 --入力PromptでChunk検索した結果の「派生のChunk」を使用すると不適切な回答が生成される事がある。 -例 --X氏は19XX年のY月~Z月まで何をしていたか?と言う質問があったとする。 --X氏に関して、19XX年と言う文字列に該当する経歴の情報が無い場合がある。 --ステップバック質問でX氏の経歴情報を取得する。ココに 19YY < 19XX < 19ZZ の情報が書かれていれば回答可能。 ***Pandas Dataframe [#b5f8cd21] -PandasのDFをChunkに分割せず、テーブル構造を保持したまま処理する。 -文字列としてではなくLLM を使用しプロンプトからPandas Pythonコードの回答を得てコレを実行した結果から回答を取得する。 -[[LlamaIndex]]では[[TextToSQL>#h2519cff]]と共に、構造化データを処理する機能の一部。 ***TextToSQL [#h2519cff] -[[Pandas Dataframe>#b5f8cd21]]のRDB + SQLバージョン。 -[[LlamaIndex]]では[[Pandas Dataframe>#b5f8cd21]]と共に、構造化データを処理する機能の一部。 **体系 [#j4b37e33] #ref(hoge.png,left,nowrap,hoge,50%) 以下は各種、手法の分類 -[[Query Translation>#x80d8fb1]] -[[Routing>#nd99a8f8]] -[[Query Construction>#v53bcf08]] -Indexing --[[Chunking>#obddc756]] --[[Embedding>#y0f380fb]] --[[Indexing>#sb976ac3]] -[[Retrieval>#d2e066e2]] -[[Generation>#z28d5463]] ***Query Translation [#x80d8fb1] -適切なChunkを取得できるようにクエリを適切な形式に変換するプロセス -手法例:Multi-query([[Hybrid-Query>#u7a9dad3]]、[[Sub Query(Decomposition)>#ua8eeae7]]、[[Multi Step Query>#q773e8b1]])、[[RAG-Fusion>#mca436c9]]、[[HyDE>#oa40213d]]、[[Stepback Prompt>#kc135197]] ***Routing [#nd99a8f8] -適切なChunkを取得できるようにデータストアやプロンプト(システム・プロンプト、プロンプト・テンプレート)を選択するプロセス -手法例:Logical Routing(データストア)、Semantic Routing(システム・プロンプト、プロンプト・テンプレート) ***Query Construction [#v53bcf08] -適切なChunkを取得できるように[[Routing>#nd99a8f8]]の結果でクエリをデータストアに適合した形式に変換するプロセス -手法例:[[TextToSQL>#h2519cff]]、[[TextToCypher>#l64216e6]]、Self-query Retriever ***Indexing - Chunking [#obddc756] 適切なChunkを取得できるようにIndexingプロセス「のChunkingを」工夫する。 -Fixed Size Chunking --難易度1 --文書を固定長でChunking -Recursive Chunking --難易度2 --設定サイズを下回るまで再帰的にChunking --分割は区切り文字的なモノを目安に行う。 -Document Based Chunking --難易度3 --文書ごと(MarkdownやPythonプログラムなど)にChunking -Semantic Chunking --難易度4 --文単位で分割・Embeddingをして、次の文との類似度が大きく「異なる」箇所でChunking --EmbeddingにはLLMを使用、コサイン類似度を計算し、ClusteringアルゴリズムでChunking -Agentic Chunking --難易度5 --LLMで文書から命題を作り、命題内容に応じたChunk作成(Dense Xと同じ) ***Indexing - Embedding [#y0f380fb] 適切なChunkを取得できるようにIndexingプロセス「のEmbeddingを」工夫する。 -Summary Embedding~ --LLMが元文書を要約し要約でIndexing --Index対象:元文書の要約(LLMが要約) --Retrireve対象:元文書 -Specialized Embeddings~ 特別なEmbedding方法 --Fine-tuning Indexing~ クエリと文書をEmbeddingするモデルをファインチューニング --ColBERT Indexing~ クエリと文書をToken単位でEmbeddingし、両者の最大類似度でスコアリング ***Indexing - Indexing [#sb976ac3] 適切なChunkを取得できるようにIndexingプロセス「のIndexingを」工夫する。 -Multi-representation Indexing~ 文書をRetrieveしやすい単位・複数形式に変換してIndexing -Parent Document Indexing~ --文書(Parent)を文書(Child)に分割 --Index対象:文書(Child) --Retrireve対象:文書(Parent) -Dense X Indexing~ LLMが元文書を複数の命題に変換し、これらの命題でIndexing --Index対象:元文書の命題(LLMが命題に変換) --Retrireve対象:元文書 --質問: ピサの斜塔の角度は何ですか?~ ---文章: 1990 年から 2001 年にかけて修復工事が行われる前は、塔は 5.5 度傾いていましたが、現在は[約 3.99 度傾いています。]~ これは、ピサの斜塔の頂上が中心から水平方向に 3.9 メートル (12 フィート 10 インチ) ずれていることを意味します。~ ---文 : 1990 年から 2001 年にかけて修復工事が行われる前は、塔は 5.5 度傾いていましたが、現在は[約 3.99 度傾いています。]~ ---命題: [ピサの斜塔は現在約 3.99 度傾いています。] -Hierarchical Indexing~ 再帰的抽象化処理による階層的なツリー構造のIndexing --RAPTOR Indexing~ 元文書をEmbedding、Clustering、要約を繰り返しルート要約Embeddingまで作成して検索 ---Index対象:要約文書の ---Retrireve対象:元文書のリーフ ***Retrieval [#d2e066e2] -Chunkを検索・取得するRetrievalプロセスを工夫する。 -手法例:Ranking([[Re-Rank>#peef05d6]], RankGPT, [[RAG-Fusion>#mca436c9]])、Refinement(CRAG)、[[Active Retrieval(Self-RAG、RRR)>#z28d5463]] ***Generation [#z28d5463] -RAG内で使用するLLMのGenerationプロセスを工夫する。 -手法例:Active Retrieval(Self-RAG、RRR) **Semantic Search [#p1f3120d] ***概要 [#la2664e1] 所謂、文書のEmbeddingによるベクトル化と内積による類似度の計算 -Sentence-Transformersなどを用いて文章をベクトル化する。 -文全体の意味を文脈に基づいてベクトル化するため、 --文章間の意味合い的な比較、類似文章検索やクラスタリングなどが可能になる。 --短く単純な文なら加法構成性が有効に働くケースもある。 ***実装 [#sfc2fe30] Sentence BERTの論文(+α)を実装したもの ***処理 [#bbd40501] ... **GraphRAG [#l64216e6] ***概要 [#sab79685] -Graphとは主にノードとエッジから構成されるデータモデル --グラフ作成はデータの構造化技術の一つ。 --ノードはモノ・概念を定義し、エッジはノード間の関係性を表す。 --SNSのアカウント同士の関係性を表すのに使用されているアレ --RDBと違い、複座なネットワーク構造を比較的容易に表現できる。 --次のような用途で使用される「因果関係をモデル化」「相互作用をモデル化」 -対象のテキストが因果関係、相互作用を含むナレッジの場合、効果が高くなる。 --ペルソナベースのレコメンデーション --ソーシャルネットワーク分析 --医療診断と治療提案 --法律文書の分析 --科学研究分野のデータ分析 -モデルの技法が複数あることに注意~ 目的やデータの性質に応じて最適なモデリング手法を選択することが重要 --RDF (Resource Description Framework) ---知識を「主語 - 述語 - 目的語」のトリプル形式で分解してグラフ化。 ---チャンクからトリプル形式をLLMを使用して抽出する。 --プロパティグラフ (Property Graph):SNSの友人関係など ---知識のノードとエッジにプロパティ(属性)を付与してグラフ化。 ---チャンクからノードとエッジにプロパティ(属性)をLLMを使用して抽出する。 --ERモデル (Entity-Relationship Model):人事データベース ---知識をERモデルでグラフ化するプロパティグラフ。 ---チャンクからエンティティ、リレーションをLLMを使用して抽出する。 --オブジェクトプロパティグラフ (Object Property Graph) ---知識をクラス図、オブジェクト図的にグラフ化するプロパティグラフ。 ---ノードやエッジにクラスやインスタンスの概念を導入。 --タキソノミー (Taxonomy):動物の分類など ---知識を階層的に分解して分類体系を階層構造でグラフ化。 ---... --フォークソノミー (Folksonomy):ユーザー生成のメタデータ。 ---知識をユーザーが付与したタグで非階層的にグラフ化。 ---... --トピックマップ (Topic Map):知識管理システム ---RDFよりも複雑なトピック間の関係性をグラフ化。 ---... ***実装 [#vc822586] -Graph検索ではGraphを使用して検索を行い、ストアにはGraphDBを使用する。 -Vector検索に加えGraph検索の結果を使用する[[Hybrid-Query>#u7a9dad3]]。 ***処理 [#i6ae32f1] -以下は、[[参考>#i26dfc50]]の内容からプロセス分解したもの。 -モデリング手法には[[プロパティグラフ (Property Graph)>#sab79685]]を使用している。 -必要なライブラリをインストール -Wikipediaから「サザエさん」についての情報を取得する。 -Splitterを使用してチャンク分割する。 -LLMでチャンクからグラフ構造(ノードとエッジ)を抽出・付加する。 -グラフ構造を抽出・付加したデータをGraphDBにロードする。 -グラフ構造は、ライブラリやGraphDBのUIでグラフィカル表示できる。 -[[Hybrid-Query>#u7a9dad3]]機能で全文検索のインデックスを作成する。 -質問文章から検索キーになるキーワードをLLMを用いて抽出するチェーンを定義 -上記チェーンで得たキーワードで全文検索した結果からCypherクエリで関連ノードを反復抽出する関数を定義 -上記で定義した関数を使用して質問「ワカメのお母さんは誰ですか?」を処理すると、~ 「波平 - PARENT -> 磯野ワカメ」「フネ - PARENT -> 磯野ワカメ」などの結果が得られる。 -上記の全文検索+グラフ検索にベクトル検索も追加しGraphRAGのパイプラインを構成して実行すると良い結果が得られる。 ※ 分析:3種のIndexを使用した検索でそれぞれ、どのようなチャンクが取得できているか?の情報が欲しかった。 *参考 [#y6b4e3f6] -深層学習についてのレポート(LLM編)~ https://www.osscons.jp/joho108j0-537/#_537 **理論 [#w96e3599] -RAGをはじめるならここから(仕組みを図解、超入門) #rag - Qiita~ https://qiita.com/Kahiro/items/56545a93bb99d8bdd8e3 -RAGの精度を上げるために参考にした文献や情報など #rag - Qiita~ https://qiita.com/oggata/items/0a21f63dbb5156d484de -RAGの秘密を解き明かす:LLMの能力を最大化する実践ガイド(1) #rag - Qiita~ https://qiita.com/dennis_wang/items/d40b848a21e4d8239472 -ゼロからはじめるRAG:クラウドに頼らない完全ローカル構築ガイド #AI - Qiita~ https://qiita.com/dennis_wang/items/04251529a2f4fe12aa31 -RAGの実装戦略まとめ #Python - Qiita~ https://qiita.com/jw-automation/items/045917be7b558509fdf2 -RAG精度向上のための6つのポイント #LLM - Qiita~ https://qiita.com/hmkc1220/items/01efb6a669ba262ee514 -RAG入門: 精度改善のための手法28選 #Python - Qiita~ https://qiita.com/FukuharaYohei/items/0949aaac17f7b0a4c807 ***Semantic Search [#i3263e52] -[[一般知識(単語を文脈予測アプローチでベクトル化の延長上)>言語処理(AI)#t6fb7c98]]でOK -詳しくは、未調査。 ***GraphRAG [#p2be127d] -GraphRAGをわかりやすく解説 #LLM - Qiita~ https://qiita.com/ksonoda/items/98a6607f31d0bbb237ef **実装 [#jf4633d9] -OpenAIのAssistants APIでRAG(検索拡張生成)を実装してみた #Python - Qiita~ https://qiita.com/nabata/items/db8890da03df1d81997a -【令和6年最新版】Azure OpenAI でRAG構築〜各種パラメータと機能についてまとめてみた〜~ https://zenn.dev/aidemy/articles/cd79fe964ebbff ***Semantic Search [#b0759f76] ... ***GraphRAG [#i26dfc50] -GraphRAGをわかりやすく解説 #LLM - Qiita~ https://qiita.com/ksonoda/items/98a6607f31d0bbb237ef -GraphRAGを使った生成AIチャットアプリを作ってみた #LLM - Qiita~ https://qiita.com/ssfujita/items/65a952f299190f4c1e6a -Local-LLM+Knowledge Graph+RAG, RAG series 2/n|Pes Cafe~ https://note.com/pescafe/n/n1759b5f4d41b **ライブラリ [#ude83345] ***[[LlamaIndex]] [#seceb564] ***[[NoSQL>#d22f5337]]クライアント [#o9eb362e] **NoSQL [#d22f5337] -Elasticsearch~ 言わずと知れた全文検索エンジン ***VDB [#jb21532e] Embeddingされたをベクトル化されたチャンクを格納&検索する。 -プロダクト --FAISS (Facebook AI Similarity Search)~ 効率的な近似最近傍検索(ANN)アルゴリズムを実装 --Chroma ---Redis上に構築されているため、ベクトルの格納とクエリが非常に高速 ---水平分散でき、データ量やクエリ量が増加しても処理能力を維持できる。 --Pinecone~ キーワード検索とベクトル検索を組み合わせたハイブリッド検索 --Weaviate~ 一部、[[LlamaIndex>#m319beb6]]の機能を担っているもよう。 --Milvus ---C++ で開発、ライセンス:Apache 2.0 ---ANN(近似最近傍探索)アルゴリズムに複数対応(HNSW, IVF, NSG, DiskANN など)。 ---スカラー値(数値・タグ)とのフィルタリング検索も可能。 ---分散アーキテクチャにより、スケールアウトが可能。 --Qdrant ---Rust で実装、ライセンス:Apache 2.0 ---HNSW ベースの ANN アルゴリズムに最適化されており、高速な検索が可能。 ---JSON フォーマットの payload(メタデータ)によるフィルタリング検索が得意。 ---オンメモリ + 永続ストレージのハイブリッド構成。 ***GDB [#p69f19cf] ノード(エンティティ)とエッジ(関係)が付与されたチャンクを格納&検索する。 -プロダクト --Neo4j ---世界で最も普及 ---Property Graph モデル ---独自のクエリ言語 Cypher を用いる。 ---大規模なグラフ分析や推論に強み。 --ArangoDB ---マルチモデル:Graph、Document(JSON)、Key-Value の全てを統合。 ---クエリ言語は独自の AQL(ArangoDB Query Language)。 ---グラフDBとしても使えるが、NoSQL文脈でDocument DBとしても強力。 --Amazon Neptune ---AWSが提供 ---RDFとProperty Graph 両方に対応。 ---クエリ言語は Gremlin(Property Graph) と SPARQL(RDF)。