自分のハードウェアでのコード理解

'Understanding code on your own hardware'

LangChainとローカルハードウェアを使用して、コードについて話すLLMのセットアップ

お約束します、あなたのコードはローカルハードウェアを離れません。写真提供:Clément Hélardot氏(Unsplash)

現在、大規模言語モデル(LLM)が実行できるさまざまなタスクの中で、ソースコードの理解は、ソフトウェア開発者やデータサイエンティストとしてソースコードと取り組んでいる場合に特に興味深いかもしれません。コードに関する質問をすることができるチャットボットを持つことは素晴らしいことではないでしょうか?データの前処理はどこに実装されていますか?ユーザーの認証を検証するための関数はすでに存在しますか?calculate_vector_dim関数とcalculate_vector_dimension関数の違いは何ですか?正しいファイルを自分で検索する代わりに、ボットに質問をして、回答と関連するコード断片が含まれているファイルへのポインタを受け取ることができます。このメカニズムはセマンティックサーチと呼ばれ、その有用性を想像できるでしょう。

このチュートリアルでは、まさにそれを行うLangChainボットの実装方法を紹介します。さらに、コードを手渡しで提供しないという具体的なデータプライバシーの問題に焦点を当てます。作成したコードは私有財産であり、機密情報や貴重な知識を含んでいる可能性があります。他社がホストするLLMに送信することを望まないかもしれませんし、会社のポリシーによっては外国にあるかもしれない他社のLLMに送信することが許可されないかもしれません。そのため、このチュートリアルでは、ローカルハードウェア上で実行されるコード理解ボットのセットアップ方法を紹介します。つまり、あなたのコードは常にインフラストラクチャから出ることはありません。

さあ、早速始めましょう!まず、セマンティックサーチの一般的なプロセスの簡単な紹介を行います。その後、コード理解のためのボットを実装します。

セマンティックサーチでは、関連するドキュメントを見つけることが重要です。写真提供:Markus Spiske氏(Unsplash)

まず、セマンティックサーチの一般的なアイデアを簡単に説明します。このアプローチは、リトリーバルとLLM自体による回答生成という2つの主要なステップで構成されています。リトリーバルのステップでは、関連情報を含むドキュメントが選択され、それらがLLMにフィードされて自然言語の回答が生成されます。たとえば、transform_vectorsという関数についての質問をする場合、リトリーバルはその質問に答えるために関連するファイルを選択します。それには、transform_vectors関数が実装されているファイルだけでなく、それを使用しているファイルやそれに言及しているドキュメントの一部も含まれる場合があります。第2ステップでは、それらのファイルの内容が次のようなプロンプトでLLMに与えられます:

"""以下の文脈を考慮して質問に答えてください。 <document 1><document 2>...<document n>質問: <ユーザーの質問>回答:"""

LLMは、与えられたドキュメントの情報を使用して、質問に対する自然言語の回答を作成します。

それがセマンティックサーチの主なアイデアです。さあ、実装を始めましょう!まず、必要なライブラリをインストールし、データを読み込む必要があります。

必要なライブラリのインストール

開始する前に、Pythonが実行される環境をセットアップし、次のパッケージをインストールしていることを確認してください:

pip install langchain==0.0.191pip install transformers

ドキュメントの読み込み

次に、データを読み込んでLangChainが使用できる形式に変換する必要があります。このデモでは、LangChain自体のコードをダウンロードしますが、もちろん独自のコードベースを使用することもできます:

import osfolder_name = "sample_code"os.system(f"git clone https://github.com/hwchase17/langchain {folder_name}")

すべてのファイルを読み込み、それぞれを1つのファイルに変換します。つまり、各Documentにはコードベースの1つのファイルが含まれます。

from langchain.docstore.document import Document
documents = []
for root, dirs, files in os.walk(folder_name):
    for file in files:
        try:
            with open(os.path.join(root, file), "r", encoding="utf-8") as o:
                code = o.readlines()
                d = Document(page_content="\n".join(code), metadata={"source": os.path.join(root, file)})
                documents.append(d)
        except UnicodeDecodeError:
            # いくつかのファイルはutf-8でエンコードされていません。今のところ無視します。
            pass

検索

これらのうち、質問に回答するのに関連するのはどれですか?それを決定するのは検索の役割です。写真:Ed Robertson氏によるUnsplash

Documentsを作成したので、これを検索可能にするためにインデックス化する必要があります。ドキュメントをインデックス化するとは、ドキュメントの最も関連性の高い情報を捉える数値ベクトルを計算することを意味します。プレーンテキスト自体とは異なり、数値のベクトルは数値計算を実行するために使用できます。これにより、類似性を簡単に計算することができ、それを使用して、特定の質問に回答するために関連するドキュメントを決定することができます。

技術的なレベルで、このインデックスは埋め込みを使用して作成し、VectorStoreに保存します。VectorStoreはサービスとして利用できます(例:DeepLake)。これにはいくつかの便利な利点がありますが、このシナリオでは、コードを手放すことは避けたいため、ローカルマシンでVectorStoreを作成します。これを行う最も簡単な方法は、Chromaを使用することです。これにより、メモリ内にVectorStoreが作成され、永続化することができます。

from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
hfemb = HuggingFaceEmbeddings(model_name="krlvi/sentence-t5-base-nlpl-code-x-glue")
persist_directory = "db"
db = Chroma.from_documents(documents, hfemb, persist_directory=persist_directory)
db.persist()

from_documents関数内で、インデックスが計算され、Chromaデータベースに保存されます。次回から、from_documents関数を再度呼び出す代わりに、永続化されたChromaデータベースをロードすることができます:

db = Chroma(persist_directory=persist_directory, embedding_function=hfemb)

上記のように、埋め込みとしてkrlvi/sentence-t5-base-nlpl-code-x-glueを使用しました。これは、オープンソースのGitHubライブラリのコードで訓練された埋め込みです。埋め込みを使用する際には、コードで訓練されていることが重要です。自然言語のみで訓練された埋め込みは、おそらく性能が低くなります。

VectorStoreと埋め込みが準備できたので、Chromaデータベースから直接リトリーバを作成できます:

retriever = db.as_retriever()

LLM

LLMは、ドキュメント上で推論を行い、ユーザーの質問に回答する必要があります。写真:Tingey Injury Law Firm氏によるUnsplash

最後に必要なコンポーネントはLLMです。最も簡単な解決策は、ホストされているLLMを使用することです(例:OpenAIインターフェイスを使用)。しかし、私たちはコードをそのようなホストされたサービスに送信したくありません。代わりに、独自のハードウェア上でLLMを実行します。これには、HuggingFacePipelineを使用します。これにより、LangChainフレームワークでHuggingFaceのモデルを使用することができます。

from langchain import HuggingFacePipeline
import transformers
model_id = "mosaicml/mpt-7b-instruct"
config = transformers.AutoConfig.from_pretrained(model_id,trust_remote_code=True)
tokenizer = transformers.AutoTokenizer.from_pretrained(model_id)
model = transformers.AutoModelForCausalLM.from_pretrained(model_id, config=config, trust_remote_code=True)
pipe = transformers.pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=100)
llm = HuggingFacePipeline(pipeline=pipe)

以下の通り、私はモザイクmpt-7bモデルを使用しました。これはGPU上で約16GBのメモリしか必要としません。私はAutoModelForCausalLMを作成し、それをtransformers.pipelineに渡し、最終的にHuggingFacePipelineに変換しています。HuggingFacePipelineはLangChainの通常のLLMオブジェクトと同じインターフェースを実装しています。つまり、例えばOpenAI LLMインターフェースと同じように使用することができます。

マシンに複数のGPUがある場合、使用するGPUを指定する必要があります。この場合、インデックス0のGPUを使用したいと思います:

config.init_device="cuda:0"model.to(device='cuda:0')pipe = transformers.pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=100, device=0)

上記で設定したいくつかの追加パラメータは次のように説明できます:

  • trust_remote_code:LangChain外部からのモデルを実行するためには、これをtrueに設定する必要があります。
  • max_new_tokens:モデルが回答で生成することができるトークンの最大数を定義します。この値が低すぎる場合、モデルの応答は質問に回答する前に切り捨てられる可能性があります。

すべてを結びつける

We have all the components we need. We just have to plug it all together. Photo by John Barkiple on Unsplash

今、必要なすべてのコンポーネントを持っており、それらをConversationalRetrievalChainで組み合わせることができます。

from langchain.chains import ConversationalRetrievalChainqa_chain = ConversationalRetrievalChain.from_llm(llm=llm, retriever=retriever, return_source_documents=True)

最終的に、チェーンにクエリを投げて質問に答えることができます。結果オブジェクトには、自然言語の回答とその回答に到達するために参照されたソースドキュメントのリストが含まれています。

result = qa_chain({"question":"KNNRetrieverのcreate_index関数の戻り値の型は何ですか?", "chat_history":[]})print(f"回答: {result['answer']}")print(f"ソース: {[x.metadata['source'] for x in result['source_documents']]}")

以下は回答です:

回答: KNNRetrieverのcreate_index関数の戻り値の型はnp.ndarrayです。ソース: ['sample_code/langchain/retrievers/knn.py', 'sample_code/langchain/vectorstores/elastic_vector_search.py', 'sample_code/langchain/vectorstores/elastic_vector_search.py', 'sample_code/langchain/vectorstores/opensearch_vector_search.py']

サマリー

以上です!まあ、ある程度ですが。上記のコードで、ソースコードに関する質問をすることができるようになりました。ただし、次のように必要に応じていくつかのステップを変更することがあります。

  • LangChainのコードではなく、独自のソースコードをドキュメントとして使用します。
  • 異なる埋め込みを試してみてください。埋め込みが適さない場合、リトリーバは適切なドキュメントを見つけることができず、最終的には正確な回答ができません。
  • 異なるモデルを試してみてください。より大きくパワフルなモデルが存在しますが、一部はハードウェア上で実行するには大きすぎる場合があります。性能がまずまずで、モデルを満足のいく方法で実行できる最適なポイントを見つける必要があります。
  • リトリーバステップを容易にするために、ドキュメントの前処理の異なる方法を試してみてください。一般的な例として、等しい長さのチャンクに分割することが挙げられます。

より良いパフォーマンスを得るために試すべきことはまだまだあります。自由に試して、ボットを自分のニーズに適応させてください。

さらなる読み物

LangChainによるコード理解のさらなる例については、こちらのドキュメントをご覧ください:

  • https://python.langchain.com/docs/use_cases/code/

HuggingFaceでは、LangChainで簡単に使用できるモデルや埋め込みを見つけることができます:

  • https://huggingface.co/models

この記事がお気に入りでしたか? 私の将来の投稿の通知を受けるためにフォローしてください。

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

人工知能

Diginiのスマートセンスの社長、ガイ・イエヒアブによるインタビューシリーズ

ガイ・イハイアヴ氏は、ビジネスの成功に最も重要な資産を保護するためにインターネット・オブ・シングス(IoT)の力を活用す...

人工知能

「スノーケルAIのCEO兼共同創設者、アレックス・ラットナー - インタビューシリーズ」

アレックス・ラトナーは、スタンフォードAIラボを母体とする会社、Snorkel AIのCEO兼共同創設者ですSnorkel AIは、手作業のAI...

人工知能

「マーク・A・レムリー教授による生成AIと法律について」

データサイエンス内で新しい分野が現れ、研究内容が理解しにくい場合は、専門家やパイオニアと話すことが最善です最近、私た...

人工知能

「aiOlaのCEO兼共同創設者、アミール・ハラマティによるインタビューシリーズ」

アミール・ハラマティは、aiOlaのCEO兼共同創業者であり、スピーチを作業可能にし、どこでも完全な正確さで業界固有のプロセ...

機械学習

「Prolificの機械学習エンジニア兼AIコンサルタント、ノラ・ペトロヴァ – インタビューシリーズ」

『Nora Petrovaは、Prolificの機械学習エンジニア兼AIコンサルタントですProlificは2014年に設立され、既にGoogle、スタンフ...

データサイエンス

「Adam Ross Nelsonによる自信のあるデータサイエンスについて」

データサイエンスの中で新たな分野が現れ、研究内容が理解しにくい場合は、専門家や先駆者と話すのが最善です最近、私たちは...