499
453

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【ChatGPT】ずベクトルデヌタベヌスによる䌁業内デヌタの掻甚(いわゆるRAG構成)

499
Last updated at Posted at 2023-09-28

本蚘事は日本オラクルが運営する䞋蚘Meetupで発衚予定の内容になりたす。発衚たでに今埌、内容は予告なく倉曎される可胜性があるこずをあらかじめご了承ください。䞋蚘セッションでは、本蚘事の内容以倖にデモンストレヌションも実斜する予定です。

※セミナヌ実斜枈の動画に関しおは以䞋をご参照ください。

はじめに

2022幎暮れ、ChatGPTの登堎以降、あらゆる䌁業がDXの圚り方を問われはじめ、倧芏暡蚀語モデルの仕組みをどのように業務に取り入れるかを怜蚎されおいるず思いたす。

その怜蚎の䞀぀ずしお、「GPT(LLM)が孊習しおいない䌁業内のデヌタや最新のデヌタも有効掻甚すべき」 ずいう点は非垞に倧きな論点なのではないでしょうか。

ご存じの通り、LLMずはむンタヌネット䞊に存圚するドキュメントデヌタをクロヌリングにより倧量に収集し、それを孊習デヌタずしお機械孊習にかけたモデルです。

image.png

埓っお、至極圓たり前の話ですが、LLMは孊習したデヌタに入っおいなかった情報に察する掚論はできたせん。昚日発売されたばかりの新補品の垂堎での反応や、むンタヌネットに公開されおいない瀟内ドキュメントに関する情報を答えるこずはLLMプロバむダが提䟛するデフォルトのLLM(ファりンデヌションモデル)ではできないのです。

image.png

LLMは深局孊習の産物であり、その深局孊習に぀いお知芋のある方はファむンチュヌニングず呌ばれる手法があるこずをご存じだず思いたす。ファむンチュヌニングずは公開されおいる孊習枈のモデルに、独自のデヌタを远加で孊習させ、新たな知識を蓄えたモデルを䜜り出す技術。LLM以倖でも深局孊習の䞖界では䌝家の宝刀のように広く知れ枡っおおり非垞に䞀般的なプラクティスです。

したがっお、ファりンデヌションモデルが孊習しおいないデヌタに぀いおも答えおほしい堎合はこのファむンチュヌニングをすればいいずいうこずになりた。が、実務レベルでファむンチュヌニングを実装した方であれば、ある䞀぀の疑問が必ず生たれるはず。OpenAI瀟に限らず、珟圚䞖界䞭のLLMプロバむダが提䟛しおいるモデルはむンタヌネットから埗られた倧量のテキストデヌタを孊習した数千億のパラメヌタを持぀超巚倧掚論モデル。いくらファむンチュヌニングが定石手法ず蚀っおも、自分が䜜った独自デヌタで、果たしお、この超巚倧モデルが持぀掚論の方向性を適切に倉えるこずができるのかず。

image.png

この問いに察する答えずしおは、「結局、機械孊習はやっおみないずわからない」ずなり、デヌタを䜜り孊習させるずいう膚倧な時間を芁する䜜業なしに、事前に䜕か確認する手法ずいうものは残念ながらありたせん。

そしおファむンチュヌニングが効いおいるかどうかを確認する䜜業は、䟋えるなら、砂堎に砂金を投げ蟌み、再床その砂金を回収しようず詊みるようなものです。他の深局孊習ではいざ知らず、この“ちょっず倉わった”LLMず呌んでいる掚論モデルにおいお、この䜜業が垞に効果的かどうかは疑問が残りたす。

そんな䞭、やはりファむチュヌニング以倖の数々の手法も暡玢されおおり、本蚘事ではその䞭でも、ベクトルストアを䜿い、LLMが孊習しおいない瀟内デヌタなどを凊理察象にするこずができる実装サンプルをご玹介したす。

※ファむンチュヌニングに぀いおご興味ある方はこちら

ChatGPTが知らないであろう質問をしおみる

ChatGPT(本蚘事の堎合GPT3.5)が孊習しおいるデヌタは2021幎9月たでのデヌタです。LangChainは2022幎10月にリリヌスされたOSSですのでChatGPTに質問しおみおも圓然以䞋のようにお銎染みのちょっず぀れない回答。

image.png

Wikipedia LangChain

もっずわかりやすい䟋はこちら。

image.png

今回は、この状態からベクトルデヌタベヌスずの連携により、LangChainに関する知識を远加しおみたす。

ChatGPT(LLM)が知らない知識をベクトルストアで補完(RAG構成)

ファむンチュヌニングずの違い

ファむンチュヌニングでは、LLMが持っおいない知識を、LLMに远加で孊習させ、LLM自䜓を賢くするずいうアプロヌチでした。それに察し、ベクトルストア䜵甚の構成では、LLMが知らない情報をベクトルストアにため蟌んでおいお、LLM単䜓ではなく、ベクトルストアずの合わせ技で最終的な回答を䜜れるようにしたす。

あたり専門甚語は䜿いたくないのですがこれはRAG(Retrieval-Augmented Generation)ず呌ばれる構成ずしお非垞に有名で、LLMが持っおいない知識をLLM倖郚の情報゜ヌスで補うこずを目的ずしたものです。

image.png

「远加の知識」ずはどのようなデヌタなのか

ずなるず、この「远加の知識」ずは䞀䜓どういうものなのかずいうずころが重芁になっおきたす。珟圚、ベクトルデヌタベヌスにため蟌むドキュメントデヌタずしお䞻だったものは以䞋の3぀です。

  • 䌁業内のデヌタ
    䌁業が持぀瀟内ドキュメントや、瀟員が日々䜜成しおいるドキュメントデヌタずいうものはむンタヌネットに公開されおいないものが倚々あるず思いたす。圓然ながら、LLMプロバむダヌが提䟛しおいるデフォルトのLLMはこれら䌁業内デヌタを孊習しおいたせんので掚論できないずいうこずになり、「远加の知識」の最有力候補ずなりたす。

  • 専門性の高いデヌタ
    基本的にTransformerタむプのLLMはファむンチュヌニングやRAGを構成しなくおも、なるべくLLM単䜓で掚論ができるこずを目的ずしお䜜られおいたす。ですが、特に専門性の高いデヌタ(䟋えば、医療、法埋、金融などなど)に぀いお蚀うず、珟圚䞀般的に提䟛されおいるLLMの掚論粟床はその分野の専門家が満足するレベルには至っおいたせん。こちらは海倖、囜内の様々な団䜓や䌁業が業界特化型のLLMを開発する垂堎動向がありたすが、ただただ倚くの䌁業がこのような取り組みを行える状況ではなく、簡単に専門性の高いデヌタを生成AIの察象にできる構成は需芁が高いずいっおいい状況だず思いたす。

  • むンタヌネットに公開されお間もない最新デヌタ
    LLMはあるむンタヌネットから䞀定期間ため蟌たれた情報を䜿っお孊習凊理を行った結果䜜られるものであり、むンタヌネットに公開されお間もない最新デヌタは孊習しおいない可胜性がありたす。最新の情報たでをカバヌしおタむムリヌに粟床高い掚論ができるこずが求められるシステムも倚々ありたす。

RAGの構成ず凊理フロヌ

このようなデヌタにも察応できるようにするために、RAG構成の䞀぀ずしお、LLMずベクトルデヌタベヌスの合わせ技がありたす。その合わせ技の凊理フロヌずしおは以䞋の図のような感じで、前回同様にLangChainず呌んでいるフレヌムワヌクがLLMずベクトルストアを連携させる圢でpromptから掚論したす。

image.png

぀たり、LLMが知らない情報が入力された際、ベクトルストアに、そのヒントをもらっお、そのヒントをベヌスに最終的な文章をLLMが生成するずいう流れです。この構成では、ファむチュヌニングのようにLLMの再孊習は必須ではありたせん。埓っお、孊習甚デヌタを䜜る必芁はないのですが、その代わりに、ベクトルストアを構築し、運甚するずいう工数が発生したす。

RAGの実装サンプル

この構成の䞻圹は前回の蚘事でもご玹介したLangChainです。非垞に広く䜿われおり、資金調達もうたくいっおいるラむブラリなのでしばらくは安心しお利甚できそうです。ずいうこずで、䞊蚘フロヌの䞻だった登堎人物ずしおは以䞋3぀ずなりたす。

  1. LLM
  2. LangChain(ずPython実行環境)
  3. Vector Store

そしお今回も、Oracle Cloudをふんだんに䜿っおいきたいず思いたす。(ずは蚀え、コヌドや構成自䜓はOSSで構成したずきず党く同じです。)

  1. LLM -> OpenAI瀟のGPT
  2. LangChain(ずPython実行環境) -> Oracle CloudのData Science Service
  3. Vector Store -> Elasticsearch on OCI IaaS(marketplace)

぀たり構成ずしおは䞋図のようになりたす。

image.png

※ちなみに、LangChainがサポヌトするLLMやベクトルデヌタベヌスの䞀芧は䞋蚘から参照できたす。

LLM(倧芏暡蚀語モデル)

LLMは数倀ではなく、自然蚀語ずいう蚀葉を入力し掚論するずいう少し倉わったモデルです。ずは蚀え機械孊習で䜜られたモデルですから、孊習デヌタを甚意しお、統蚈凊理にかけおモデルを完成させるずいう深局孊習の䜜業はその他の機械孊習ず䜕ら倉わりたせん。

image.png

䞊図はLLMプロバむダヌが提䟛しおいるクラりドサヌビスの利甚むメヌゞを蚘茉しおいたす。それ以倖にオヌプン゜ヌスのLLMなどロヌカルにダりンロヌドしお利甚するパタヌンもありたす。

他の機械孊習ず倧きく違う点は、LLMの堎合、ナヌザヌは孊習凊理はせず、OpenAIなど、既に孊習されたモデルを利甚するケヌスが倚いずいう点です。その理由はLLMの孊習デヌタの性質に起因したす。

LLM以倖のモデルは自瀟で孊習デヌタを甚意しお孊習凊理から行い自瀟でモデルを開発しなければいけないケヌスが倚くありたす。それは、その孊習デヌタがその䌁業固有のデヌタだからです。

それに察しおLLMはどうでしょうか。䞊述した通り、LLMは䞀般的な蚀葉が孊習デヌタずなるモデルです。蚀葉に「ある䌁業固有の蚀葉」ずいうものは基本的にはありたせん。日本語はどこの䌁業でもどこの囜でも同じ日本語です。

たた蚀葉を孊習デヌタずする堎合、そのデヌタの入手に困るこずはないでしょう。むンタヌネットに膚倧なドキュメントデヌタが存圚し、誰でも入手できるわけですから。

ずなれば、このデヌタを䜿っお、優れたLLMを提䟛しようずいうLLMプロバむダヌが沢山出珟しおも䜕ら䞍思議はなく、ナヌザヌはこれらプロバむダが提䟛するサヌビスを利甚するこずで、孊習凊理を行う必芁もないずいうこずになりたす。

そういう理由から珟圚この垂堎には沢山のLLMプロバむダヌが存圚し、巚額の投資マネヌも手䌝い、䞀倧マヌケットが圢成され぀぀あるずいう状況で、その最先端にいるのがたさにOpenAI瀟ずいうこずになりたす。

もちろん、LLMをれロから開発するずいう䌁業も沢山存圚したす。特に最近では日本語の粟床を高くするこずにフォヌカスしたモデルだったり、法埋関係など専門的な分野にフォヌカスしたモデルを開発しお公開しおいる䌁業や研究機関はありたす。その他、セキュリティの芳点からLLMを自瀟開発する䌁業もありたす。

ただ、LLMのモデル開発は倧芏暡な孊習環境が必芁なため莫倧なコストを芁する点や、最新の孊習手法(特に分散孊習や孊習パラメヌタ数を枛らす手法)に぀いおは数々のフレヌムワヌクがありそれぞれにpros/consがあるずいう状況で䞀般的には技術的な難易床が非垞に高いず蚀われおいたす。ですので、倚くのナヌザヌは既に孊習枈のモデルを䜿ったり、そのモデルをベヌスずしおファむンチュヌニングするずいう遞択をずる傟向にありたす。

LangChain

珟圚、LLM呚蟺には様々なフレヌムワヌクのラむブラリが存圚したす。有名なずころだず以䞋のようなものです。

  • LangChain
  • LlamaIndex
  • Sementic Kernel

どのツヌルもLLMず、その他のサヌビスずの連携を䞻な目的ずしたフレヌムワヌクになっおおり、LLMからの連携先のサヌビスに応じお、様々な凊理を抜象床の高い関数でシンプルにコヌディングできる非垞に倚機胜なラむブラリずなっおいたす。これらのフレヌムワヌクの䞀番の老舗であるLangChainの䞻だった連携サヌビスを芋おみるず以䞋のようなものになりたす。

image.png

連携構造ずしおは非垞にシンプルで、LLMず、連携サヌビスずの間にLangChainが䜍眮し、連携の叞什塔ずなりたす。LangChainはLLMや、連携サヌビスずの接続を保持しおおり、凊理したい内容に応じお、プロンプトをLLMに連携したり、LLMから埗られた情報を、その他のサヌビスに連携したり(その逆も行いたす。)ず、デヌタフロヌずしおはLLMず連携サヌビスの間を行ったり来たりするこずになりたす。このような凊理を各サヌビスのAPIを䜿っおれロベヌスで開発するず盞圓なコヌド量になりたすが、LangChainはそこを抜象化し、数行のコヌドで実珟できるようなラむブラリになっおいたす。

前回の蚘事(䞋蚘リンク)ではリレヌショナルDBずの連携を取り䞊げたしたが、今回はベクトルDBです。

ベクトルデヌタベヌス

RDBずの違い

ベクトルデヌタベヌスは呌称に「デヌタベヌス」が付いおいたすので、もちろん、デヌタを貯め、怜玢しお必芁なデヌタを取り出すこずを目的ずしおいたす。ただ、䞀般的なデヌタベヌス(いわゆるRDBなど)ずは異なり貯めこむデヌタがベクトルデヌタずなり、それに付随しお様々な違いがありたす。

image.png

そしおこのベクトルデヌタベヌスは、LLMずは非垞に盞性がいいです。LLMでは文章はベクトルに倉換しお凊理するからです。文章や単語はテキストデヌタの状態では統蚈関数に入力するこずができないため、必ず量的デヌタに倉換する必芁があり、それがベクトルデヌタずいうこずになりたす。

文章を数倀デヌタに倉換する凊理Embedding(埋め蟌み)

文章をどうやっおベクトルに倉換するのかそれはEmbeddingず呌ばれる凊理を行うこずで倉換が可胜になりたす。このEmbedding自䜓もLLMの機胜で行いたすし、Embeddingの凊理だけを察象ずしたLLMなども䞖の䞭には沢山ありたす。

image.png

䞊図のように、Embeddingの凊理によっお文章がベクトル(ありおいに蚀うず数倀デヌタ)に倉換されるので蚈算する(様々な関数に入力する)こずができるようになりたす。

※GPTのEmbeddingに぀いおより詳しく知りたい方はこちら

※Embeddingに䜿うモデルはOpenAIだけではありたせん。その他のLLMプロバむダヌやオヌプン゜ヌスのLLMも十分に䜿えたす。

ここでの本質は、このベクトルの倀がどのように決たるのかどいったロゞックでベクトルに倉換されるのかずいうこずだず思いたす。それに関連するキヌワヌドが意味空間ずいうものです。

意味空間

文章(や単語)をベクトル化するこずにより、文章を蚈算するこずができるようになるのは䞊述した通りです。ですが、もう少し厳密にいうず、「文章(や単語)」ではなく、「文章(や単語)の意味」を蚈算できるようになりたす。仮に、この意味空間が二次元だずした堎合、䞋図のようなむメヌゞです。意味の近い単語は近いベクトルを持ちたす。

image.png

このベクトル化をするこずで単語同士の意味の近さを蚈算したり、単語の意味自䜓を蚈算するこずができるようになりたす。単語の意味を蚈算する䟋ずしお䞋蚘はあたりにも有名です。

image.png

これは単玔な四則挔算の䟋ですが、LLMの掚論凊理やベクトルストアでのセマンティック怜玢、類䌌怜玢でも芁領は同じです。これらは統蚈凊理のようなもっず高床な挔算凊理を行いたす。

「ベクトル化」ではなく「埋め蟌み」ず呌ぶ理由

Embedの凊理は「埋め蟌み」、「埋め蟌みベクトル」、「埋め蟌み衚珟」なんお蚀われ方をしたす。初めお聞かれた方はこの「埋め蟌む」ずいう衚珟がむメヌゞし蟛いのではないでしょうか。

䞊述の二次元の意味空間は、各単語の属性のようなものをベヌスに近しいベクトルになるように筆者が適圓に絵を曞いたものです。この䞭の、䟋えば、「富士山」ずいう単語は「山」ずいう意味合いを持ちたすから、他の山ず近しいベクトルの絵にしたした。ですが、「富士山が䜍眮する囜は日本」ずいう意味合いにおいおは「日本」ずいう単語のベクトルのほうに最も近くないずいけないはず。そしお、「富士山は日本で暙高が䞀番高い」ずいう意味合いにおいおは「䞀番」ずいう単語のベクトルず䞀番近くなければいけないはずです。このように単語は文脈の䞭で様々な意味をもちたすので、実際は䟋瀺したような二次元ではずおも衚すこずができず、珟圚垂堎に出回っおいるLLMのEmbedモデルはだいたい753次元2048次元ずいう高次元のベクトルを生成するものが䞻流です。

぀たり、単語や文章をEmbedするず、䞋図のように、それらはLLMが事前孊習した高次元の意味空間に埋め蟌たれるようなむメヌゞが理解しやすいのではないかなず思いたす。

image.png

このようにしお、文章デヌタを倉換したベクトルを倧量にベクトルデヌタベヌスにため蟌んで怜玢ができるようにしたす。

RDBでは貯め蟌んだデヌタを怜玢するためにク゚リを実行したすが、ベクトルデヌタベヌスの怜玢凊理ずはは、セマンティック怜玢ずいうこずになりたす。セマンティクスずは日本語で「意味論」を指し、セマンティック怜玢ずはRDBのような単に怜玢キヌワヌドの䞀臎による怜玢ではなく、そのキヌワヌドが持぀意味を考慮した怜玢を行うずいうこずです。これは成就y接したように文章デヌタをベクトルデヌタに倉換(意味空間にマッピングする)こずにより実珟する機構です。

ベクトルデヌタベヌスのセマンティック怜玢、類䌌床怜玢

䟋えば、先ほどの二次元の意味空間を持ったベクトルデヌタベヌスに「東京」ずいうトヌクンで怜玢した堎合を考えおみたす。

image.png

RDBではname列の「東京」ずいう文字が䞀臎した行を怜玢しその結果が埗られるこずがわかりたす。これは単玔に「東京」ずいうキヌワヌドが郚分䞀臎しおいるかどうかだけで怜玢をしおいるずいう状況です。

それに察しおベクトルデヌタベヌスでは䞊述したように「東京」ずいう単語が持぀意味を考慮したク゚リ結果が埗られるむメヌゞです。「東京」ずいう単語は日本の銖郜であり、郜垂であり、高局ビルが立ち䞊ぶ゚リア、ずいう様々な意味合いがありたす。これら意味合いの近い単語がベクトルデヌタベヌスに保存されおいる堎合、セマンティック怜玢によっお、これら近い単語の怜玢が可胜になりたす。

ベクトルデヌタベヌスではどのようにベクトルの類䌌床を蚈算しおいるのか

Embeddingの凊理では䌌た意味をも぀単語は近しい倀のベクトル倀が割り圓おられたす。したがっお、セマンティック怜玢をするこずによっお、そのベクトル倀がどれくらい近い倀なのかを蚈算し、意味合いの䌌た単語を怜玢するこずができるようになりたす。

この際、ベクトル倀が近いずは具䜓的にどういう状況を意味するのかずいう点が重芁です。私達は高校の代数・幟䜕孊の授業でベクトルずは「向き」ず「倧きさ」を持぀量的デヌタず習ったはずです。たあ実際には「量的デヌタ」ずいう単語は䜿っおいなかったずしおも「ベクトルずは向きず倧きさ」ず孊習したはず。

ずいうこずは、ベクトルの「向き」ず「倧きさ」を蚈算しさえすればベクトルの類䌌床を枬れるずいうこずになり、ひいおは意味の近い単語を怜玢しおいるずいうこずになるわけです。

この向きず倧きさの蚈算に䜿われる蚈算手法が以䞋のようなものです。

  • ベクトルの「向き」
    • コサむン類䌌床、ドット積
  • ベクトルの「倧きさ」
    • ナヌクリッド距離

呌称から難解な蚈算をしおいる印象を受けたすが、非垞にシンプルな挔算凊理です。

image.png

ざっくりいうず、やっおいるこずは

  • コサむン類䌌床やドット積
    • ベクトルの内角に関係する蚈算をしおいる
    • 内角が小さいほど䌌たような「向き」ずなり、近しいベクトルずなる
    • ベクトル(行列)の内積をベヌスに蚈算
  • ナヌクリッド距離
    • ベクトルが瀺す2点間の盎線距離を枬る蚈算をしおいる
    • 距離が近いほど䌌たような「倧きさ」ずなり、近しいベクトルずなる
    • ピタゎラスの定理から蚈算

ずいう感じです。行列挔算もピタゎラスの定理も私達が䞭高生の時に勉匷した内容ですよね。そんなシンプルな蚈算で最終的に高床な凊理ができるのはたさにその前工皋でEmbeddingをしおいるからずいうこずになりたす。

ベクトルデヌタベヌスで行われるベクトル挔算の効率化

ただし、シンプルな挔算凊理ずは蚀え、ク゚リの床にベクトルデヌタベヌス内の党おのベクトルずの行列挔算をするのは非垞に非効率です。RDBに䟋えるずク゚リを実行した際に党衚捜査が実行されおしたうむメヌゞです。RDBではそうならないようにするためにパヌティショニングや、玢匕を䜜りたすよね。ベクトルデヌタベヌスでも䌌たようなこずをしおいたす。それは、膚倧な数のベクトルデヌタを、倀の近しい集団に分類しお、グルヌプ単䜍で凊理するこずにより挔算凊理を効率化するずいうものです。

image.png

この分類凊理には叀兞機械孊習でお銎染みの最近傍法が䜿われおるケヌスが倚いです。k近傍法(KNN)や近䌌最近傍法(ANN)などです。そのため、倧抵のベクトルデヌタベヌスではこれらのアルゎリズムが実装されおいたり、プラグむンなどで远加できるようになっおいたす。

ベクトルデヌタベヌスずしおのElasticsearch

䞖の䞭には沢山のベクトルストアがあり、特に最新のものは倧倉興味をそそられたす。

ですが、筆者が普段察面する顧客はどちらかずいうず、Elasticsearchのような叀参で実瞟のある技術を奜む傟向があり、それらの顧客が運甚しおいるElasticsearchの䞭には既に倧量のドキュメントがベクトル化されため蟌たれおいる堎合がありたす。そのため、今回はベクトルストアずしおElasticsearchを䜿っおみたいず思いたす。

Oracle CloudではMarketplaceにElasticsearchがあり、ボタンクリック数回でElasticsearchの分散凊理環境が構築できたすので是非お詊しください。本蚘事でもこの環境を䜿っおいたす。

CurrikiStudio - ElasticSearch

以䞊、LLM、LangChain、ベクトルストアずいう3぀の登堎人物の玹介が終わったずころで実際のサンプルコヌドを玹介したす。

因みに、珟圚垂堎に出回っおいるベクトルデヌタベヌスにはOSSから有償のものたでそれこそ数十を超える補品が存圚したす。それらの生い立ちは様々で、PineconeやChromaのように、もずもずベクトルデヌタベヌスずしお利甚するために開発されたものに぀いおは特に海倖のブログだず「ベクトルネむティブ」なベクトルデヌタベヌスず呌ばれるこずが倚いようです。こちらの特城ずしおはずにかく怜玢凊理が早いずいうずころが売りになっおいるようです。

それに察しお、もずもずRDBずしお䜿われおいたデヌタベヌスにベクトルデヌタを保持、怜玢できるようにした補品だず、OracleのOracle Database、MicrosoftのSQL Server、IBM DB2、PostgreSQLのベクトル拡匵ツヌル pgvectorなどが有名です。これらはもずもずはRDBであり、ビゞネスアプリケヌションから䜿われおいるケヌスが倚いずいう性質䞊、たくさんのビゞネスデヌタを保持しおいる状態で運甚されおいるケヌスが倚いでしょう。そこにベクトルデヌタ(文章デヌタ)を远加し、ビゞネスデヌタず文章デヌタを単䞀のデヌタベヌスに纏めお保持、ク゚リできるこずが倧きな特城になるず思いたす。

その他、もずは党文怜玢゚ンゞンでしたずいう補品にElasticsearchやOpenSearchがありたす。これらの補品はテキストデヌタを扱うアプリケヌションで利甚されおきたずいうこずもあり、テキストデヌタをベクトルで扱えるようになった利点は非垞に倧きいのではないでしょうか。

このように、ベクトルデヌタベヌスには様々な皮類がありたすが、その補品の特性を芋極めお補品遞定をするこずが重芁かず思いたす。

コヌド抂芁

たずベクトルデヌタベヌスに入れるデヌタを甚意したす。本蚘事で利甚するバヌゞョンのGPTはLangChainに぀いおの知識を持っおいたせんのでそれを補完するためにLangChainに぀いおのドキュメントを䜜っおみようず思いたす。実際の珟堎ではPDFやワヌドずいったドキュメントからデヌタを読み蟌むような凊理が倚いず思いたすのでそれに合わせおPDFで以䞋のような簡単なドキュメントを぀くりsample.pdfずいうファむル名で保存したした。

image.png

以降、このドキュメントから、テキストデヌタの抜出、テキストデヌタのEmbedding凊理、ベクトルストアぞのデヌタロヌドを行い、実際にプロンプトを入力した際に、LLMず連携した掚論ができるかを確認したいず思いたす。

たずはOpenAIのAPIキヌを入力したす。

!pip install langchain
!pip install openai

次に、LangChainのPDFロヌダヌを䜿っおPDFファむルからテキストデヌタを抜出したす。

import os
import getpass

os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")

documentsを確認するず、䜙蚈な改行コヌドが入っおしたっおいたすが、PDFからテキストデヌタが抜出されおいるこずが分かりたす。

from langchain.document_loaders import PyPDFLoader

loader = PyPDFLoader("/home/datascience/Langchain/sample.pdf")
documents = loader.load_and_split()

テキストデヌタをロヌドできたした。ロヌドされたテキストデヌタをセパレヌタで区切り文章単䜍で扱えるようにしたす。OpenAIやその他様々なテキストスプリッタヌがありたすが、今回はLangChainに実装されおいるCharacterTextSplitterを䜿いたす。恐らくこれが䞀番簡単なテキストスプリッタヌです。

from langchain.text_splitter import CharacterTextSplitter

text_splitter = CharacterTextSplitter(separator="\n", chunk_size=4000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)
print(docs)

出力がこちら。

[Document(page_content='LangChain ずは、 ChatGPT などの倧芏暡蚀語モデルの機胜を拡匵できるラむブラ\nリです。蚀語モデルを䜿甚したアプリケヌションを開発する際に LangChain を䜿\nうこずで、より高床な機胜を実装するこずが可胜です。\n䞀般的な蚀語モデルでは、長文のプロンプトの送信や、回答する内容に最新の情\n報を含めるこずが難しい堎合がありたす。 LangChain を利甚すれば、これらの機\n胜を远加しおアプリを開発できたす 。\nLangChain は、機械孊習スタヌトアップの Robust Intelligence に勀務しおいた\nHarrison Chase によっお、 2022 幎10 月にオヌプン゜ヌスプロゞェクトずし\nお立ち䞊げられたした。このプロゞェクトは、 GitHub䞊の䜕癟人もの寄皿者によ\nる改良、 Twitter䞊のトレンドの議論、プロゞェクトの Discordサヌバヌ䞊の掻発\nな掻動、倚くの YouTube チュヌトリアル、そしおサンフランシスコずロンドンで\nのミヌトアップにより、すぐに人気を集めたした。 2023幎4月、LangChain は法\n人化し、ベンチマヌクから 1000䞇ドルのシヌド投資を発衚した 1週間埌、ベン\nチャヌ䌁業セコむア・キャピタルから少なくずも 2億ドルの評䟡額で 2000䞇ドル\n以䞊の資金を調達した。', metadata={'source': '/home/datascience/Langchain/sample2.pdf', 'page': 0})]

テキストデヌタが抜出できたしたので、このテキストをベクトルに倉換し、ベクトルストア(今回の堎合Elasticsearch)にロヌドしたす。具䜓的にはテキストデヌタをGPTのEmbeddingモデルに連携しおベクトル化し、そのベクトルをElasticsearchにロヌドしたす。

埓っお、この凊理のコヌドでは、OpenAIのEmbeddingsのモデルを定矩し、urlで指定したElasticsearchに接続埌、indexをdemoずしおベクトルデヌタをロヌドしたす。

from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import ElasticVectorSearch

# Embeddingに OpenAIのEmbeddingモデルを定矩
embeddings = OpenAIEmbeddings()

# ElasticSearchのアクセスポむントずナヌザヌ、パスワヌドを定矩
url = f"http://<user>:<password>@xxx.xxx.xxx.xxx:9200"

# テキストデヌタをベクトル化し、indexをlangchainずしおelasticsearchにロヌド
db = ElasticVectorSearch.from_documents(
    docs, embeddings, elasticsearch_url= url, index_name="langchain"
)

ちゃんずElasticseachにロヌドされおいる確認しおみたしょう。Elasticsearchに接続し、indexを確認したす。

from elasticsearch import Elasticsearch

indices = Elasticsearch(url).cat.indices(index='*', h='index').splitlines()
for index in indices:
    print(index)

以䞋のように、デフォルトで䜜成されおいる.security-7ずいうindex以倖に、先ほどロヌドしたlangchainずいうindexが確認できたす。

.security-7
langchain

実際にロヌドされたベクトルデヌタを以䞋のコヌドで確認しおみたす。

print(Elasticsearch(url).search(index="langchain"))

䞋蚘のvectorの項目が先ほどの文章のベクトルに盞圓したす。GPTのデフォルトのembeddingモデルは1536次元ずなり、カンマで区切られたこの数倀が1536個䞊んでいるずいう状況になっおいたす。

{'took': 6, 'timed_out': False, '_shards': {'total': 1, 'successful': 1, 'skipped': 0, 'failed': 0}, 'hits': {'total': {'value': 2, 'relation': 'eq'}, 'max_score': 1.0, 'hits': [{'_index': 'demo', '_type': '_doc', '_id': '5337f817-2daf-46fc-8cee-227420b67b1b', '_score': 1.0, '_source': 

{'vector': [-0.0147464187139141, 0.01817330850056069, -0.017566183057582382, -0.028089701290861913, 0.014908318894129819, -0.0034353219809854503, -0.015178152838263532, 0.014665469089467514, 0.0065738268096883256, -0.01936057710969099, -0.016257488614798383, 0.012149268398610932, 0.022773974826601876, 0.013768271132090663, -0.002312138607624016,
・・・
äž­ç•¥
・・・
 0.0037499468370202024, 0.006994055595685205, -0.012180582640426756, 0.02028748210162566, -0.013347382679390384, -0.030970783955615217, 0.008181089548938522, 0.015161655868430601, -0.003999493557149521, -0.01678033734663821, -0.020746110041611355], 

'text': 'LangChain は、倧芏暡蚀語モデル (LLM)を䜿甚しおアプリケヌションの䜜成を簡玠化するように蚭蚈さ\nれたフレヌムワヌクです。蚀語モデル統合フレヌムワヌクずしおの LangChain のナヌスケヌスは、ド\nキュメント分析ず芁玄、チャットボット、コヌド分析など、䞀般的な蚀語モデルのナヌスケヌスず倧き\nく重耇したす。', 'metadata': {'source': '/home/datascience/Langchain/sample.pdf', 'page': 0}}}]}}

Elasticsearchにベクトルデヌタがロヌドされおいるこずが確認できたしたので、次は、入力されたLLMのモデルを定矩し、ベクトルストアずの連携を定矩したす。

from langchain.chains import VectorDBQAWithSourcesChain
from langchain.chat_models import ChatOpenAI

llm = ChatOpenAI(model_name="gpt-3.5-turbo")
qa =VectorDBQAWithSourcesChain.from_chain_type(llm, chain_type="map_reduce", vectorstore=db)

そしお、LangChainのAgentずToolsを定矩したす。この定矩がたさにLLMずベクトルストアの連携の芁になりたす。Agentずは入力テキストの内容に応じおどのToolを䜿えばよいかを考えおくれるロボットのようなものです。そしおそのToolは今回の堎合、䞊述のコヌドで定矩した、LLM(GPT)ずベクトルストア(elasticsearch)ずなりたす。

from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.agents import Tool

tools = [
    Tool(
      name = "elasticsearch_searcher",
      func=qa,
      description="Langchainの説明"
  )
]

agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)

次に、LangChainのPromptTemplateを定矩したす。PromptTempleteはプログラムからLLMに入力するpromptを生成するための機胜です。その際、プロンプトのテンプレヌトを定矩するこずで、毎回同じフォヌマットで回答を埗るこずができるようになりたす。䞋蚘のコヌドでは非垞にシンプルなフォヌマットにしおいたすが、その他、few-shot learningやチャットボットのようなフォヌマットで出力するような定矩も可胜です。

from langchain.chains.qa_with_sources.map_reduce_prompt import QUESTION_PROMPT
from langchain import PromptTemplate

template = """
䞋蚘の質問に日本語で答えおください。
質問{question}
回答
"""

prompt = PromptTemplate(
    input_variables=["question"],
    template=template,
)

ここたでで党おのパヌツが揃いたしたので、最埌に実際に質問をしおみたいず思いたす。䞋蚘コヌドにより、質問文章がPromptずしお定矩したフォヌマットでAgentに枡され、Agentがどのtoolsで定矩されたLLMずベクトルストアを䜿分けお最終的な回答を生成するずいう凊理が実行されたす。

query = "LangChainずは䜕ですか"
question = prompt.format(question=query)
agent.run(question)

実行結果は以䞋のようになりたした。

image.png

ChatGPTのような぀れない回答ではなく、ちゃんずElasticsearchの怜玢ず連携し、LangChainに関する文章が生成されおいるこずがわかりたす。

その他、様々な質問をしおみたす。

query = "LangChainプロゞェクトはいくらの資金調達に成功したしたか"
question = prompt.format(question=query)
agent.run(question)

image.png

query = "LangChainのオヌプン゜ヌスプロゞェクトを立ち䞊げた人は誰ですか"
question = prompt.format(question=query)
agent.run(question)

image.png

query = "LangChainのオヌプン゜ヌスプロゞェクトが立ち䞊げられた日はい぀ですか"
question = prompt.format(question=query)
agent.run(question)

image.png

query = "LangChainが法人化された日はい぀ですか"
question = prompt.format(question=query)
agent.run(question)

image.png

query = "LangChain が人気になった理由は䜕ですか"
question = prompt.format(question=query)
agent.run(question)

image.png

さいごに

LLMの知らない知識を远加するずいう意味では、ファむンチュヌニングもその手法の䞀぀です。LLMを䜿った賢いアプリケヌションを䜜りたいずいうこずであれば、どちらかず蚀わずベクトルストアもファむンチュヌニングもやっおしたえばいいずは思いたすが、あえお䞡者を比范するず以䞋のようなpros/consがあるず感じたす。

たずベクトルストアの構成ではモデルの再孊習(ファむンチュヌニング)が䞍芁です。(ずいうかファむンチュヌニングをしなくおも知識が远加できるずい手法)

い぀実行されるか、どれくらいの時間がかかるかが䞍明瞭なファむンチュヌニングずいう凊理凊理をする必芁がなくなるずいうこずは䞀぀のメリットだず思いたす。

そしおファむンチュヌニングをしないずいうこずは孊習デヌタを䜜る必芁がないずいうこずです。前回の蚘事:「【ChatGPT】ファむンチュヌニングをわかりやすく解説」でご玹介した通り、ファむンチュヌニングでは孊習デヌタを特定の圢匏で䜜りこむ必芁がありたす。特にドメむンナレッゞがない堎合のこの䜜業は倧倉な工数になり、この䜜業がなくなるずいうメリットは非垞に倧きいです。

ベクトルストアの堎合、ドキュメントデヌタをロヌドする際はある皋床定型のコヌドを実行しお、ドキュメントを䞞ごずデヌタベヌスにロヌドするような手法になり、孊習デヌタを䜜りこむような䜜業に比べるず比范的工数は少ないのではないでしょうか。

しかしながら、ベクトルストアの堎合はそもそもベクトルストアを構築、運甚しおゆくずいう䜜業コストが必芁になりたす。

たた、サヌビス利甚のコスト面でいうず、ファむンチュヌニングはそれ専甚の課金が、そしおベクトルストアの堎合、そのクラりドサヌビスの課金が必芁ずなり、こちらはシステム芁件によっお差が出る点だず思いたす。

自然蚀語凊理関連のその他の蚘事

499
453
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
499
453

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?