サイト内検索

今回の内容

第2話では具体的に必要なソフトウェアやハードウェア、デプロイ方法について解説しました。
第3話では、各コンテナを使用したサンプルコードを元にRAGのパイプラインの構築を解説します。
 
[NVIDIA NIMを活用したRAGのChatbotの開発]
第1話 マイクロサービスを利用したRAGシステム開発
第2話 RAGシステムで必要なソフトウェア/ハードウェアの構成とは?
第3話 RAGシステムのサンプルコード

RAGシステムのサンプルコード

マイクロサービスベースで開発する際のそれぞれのコンテナの使い方や簡単なアプリケーションの作成方法を説明します。
今回の環境ではH100×2枚にLLM、A100×1枚に埋め込みモデルをデプロイしています。
 
まず完成後のサンプルのアプリケーションの動画は下記になります。
DGX B200に関してRAGを使用していないllama3.1-70bに質問した際には情報を持っていないため正しい回答を生成することはできませんでした。
一方で、RAGを活用することでDGX B200についての回答を得ることができています。

それでは最後に本デモアプリケーションのセットアップに関して解説します。

1. ライブラリのインストール

下記コマンドでrequirements.txtを作成します。

cat > requirements.txt << "EOF" 
fastapi==0.104.1
langchain==0.3.4
langchain-community==0.3.3
langchain-core==0.3.13
langchain-nvidia-ai-endpoints==0.3.3
numpy==1.26.4
sentence-transformers==2.2.2
unstructured==0.11.8
langchain_milvus==0.1.6
gradio==5.1.0
EOF

必要なライブラリのインストールに関して解説します。
上記コマンドを実行し作成されたrequirements.txtを用いて下記コマンドでライブラリをインストールします。

pip install -r requirements.txt

問題なくライブラリがインストールできたことを確認して次のステップに移行します。

2. importするライブラリ

from langchain_nvidia_ai_endpoints import ChatNVIDIA
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_nvidia_ai_endpoints import NVIDIAEmbeddings
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
import os
from langchain_milvus import Milvus
import gradio as gr

importするライブラリに関して解説します。
今回は1.ライブラリのインストールでインストールしたライブラリをインポートします。
ここでは、langchainと呼ばれるLLMを使用したアプリケーションを構築するためのオープンソースのフレームワークを使用します。
また、ベクターデータベースは2話でセットアップしたMilvusを使用します。
インターフェースはgradioを用いて作成します。

3. LLMの設定関連

#llmの設定
llm = ChatNVIDIA(
  base_url="YOUR_LOCAL_ENDPOINT_URL",
  api_key = "not-used",
  model="model_name",#冒頭の動画ではmeta/llama-3.1-70b-instructを使用しています。
  temperature=0.2,
  top_p=0.7,
  max_tokens=1024,
)
#embedding modelの設定
embedding_model = NVIDIAEmbeddings(
  base_url="YOUR_LOCAL_ENDPOINT_URL",
  api_key = "not-used",
  model="model_name",
  truncate="NONE", 
  )
#MilvusのURL
URI="YOUR_DB_URL:19530"
#promptのテンプレートの設定
prompt = ChatPromptTemplate.from_messages([
    ("system", 
        "You are a helpful and friendly AI!"
        "Your responses should be concise and no longer than two sentences."
        "Do not hallucinate. Say you don't know if you don't have this information."
        # "Answer the question using only the context"
        "

Question:{question}

Context:{context}" ), ("user", "{question}") ])

LLMや埋め込みモデルの設定に関して解説します。
今回は1話で説明した下記構成でサンプルアプリケーションを作成します。そのため、LLMのNIMコンテナやベクトルデータベース、埋め込みモデルのNIMコンテナ、プロンプトを設定します。NIMコンテナのURL等は適宜ご自身の環境をご確認いただき変更してご使用ください。
また、Milvusはデフォルトではport:19530で起動しますが変更することも可能です。
ここではSystem promptを"You are a helpful and friendly AI!"~としていますが、System promptを変更することでLLMの出力が変化しますので、より良い回答が得られるように工夫することも可能です。

4. ベクトルデータベースに格納する関数

# VectorDBに格納する関数
def process_pdf_to_milvus(pdf_file):
    # PDFを読み込む
    loader = PyPDFLoader(pdf_file)
    document = loader.load()
    # テキストをチャンクに分割
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=500,
        chunk_overlap=100,
        separators=["

", "
", ".", ";", ",", " ", ""], ) document_chunks = text_splitter.split_documents(document) # ベクトルデータベースの設定 vector_store = Milvus.from_documents( document_chunks, embedding=embedding_model, connection_args={"uri": URI}, drop_old=True ) return "PDFが処理され、Milvusに保存されました!"

ベクトルデータベースに格納する関数に関して解説します。
今回はpdfを対象としていますので、PyPDFLoaderでPDFを読み込みます。その後チャンクサイズを500、重複トークン数を100とし、separatorsで指定した文字で分割します。その後ベクトルデータベース(Milvus)に保存します。

5. 回答を生成する関数

def answer_question(question):
    vector_store_loaded = Milvus(
    embedding_function=embedding_model,
    connection_args={"uri": URI}
    )
    #chainの作成
    chain = (
    {
        "context": vector_store_loaded.as_retriever(),
        "question": RunnablePassthrough()
    }
    | prompt
    | llm
    | StrOutputParser()
    )
    answer=chain.invoke(question)
    return answer

回答を生成する関数に関して解説します。
まず、あらかじめMilvusに格納されたデータベースをよみこみます。
その後LangchainのChainを作成し、Milvusのデータベースの情報を使用して回答を生成します。

6. Gradioのインターフェースの起動

with gr.Blocks() as demo:
        gr.Markdown("# PDFからベクトルデータベースへ & 質問応答システム")
        with gr.Tab("質問応答"):
            question_input = gr.Textbox(label="質問を入力")
            answer_button = gr.Button("質問する")
            answer_output = gr.Textbox(label="回答")
            answer_button.click(answer_question, inputs=[question_input], outputs=answer_output)
        with gr.Tab("PDFをアップロードしてMilvusに保存"):
            pdf_input = gr.File(label="PDFファイルを選択",type="filepath")
            save_button = gr.Button("PDFをMilvusに保存")
            save_output = gr.Textbox(label="結果")
            save_button.click(process_pdf_to_milvus, inputs=[pdf_input], outputs=save_output)
demo.launch()

最後にgradioを使用して簡単なチャットボットの形式にします。
ここでは、with gr.Tabで質問を入力する画面とPDFをアップロードする画面を分けています。
demo.launchでChatbotのUIを作成しています。

まとめ

本連載ではNIMを活用したマイクロサービスベースの開発に関して解説し、サンプルコードを用いてアプリケーションの作成方法を解説しました。
今回は必要最低限の機能のみを実装しましたが、ベクターデータベースの管理機能や、リランキングモデルの活用、複数のLLMを使用したパイプラインの構築など様々な応用が考えられます。
本記事が皆様のLLMアプリケーションの開発の一歩目になれば幸いです。

AI導入をご検討の方は、ぜひお問い合わせください

AI導入に向けて、弊社ではハードウェアのNVIDIA GPUカードやGPUワークステーションの選定やサポート、また顔認証、導線分析、骨格検知のアルゴリズム、さらに学習環境構築サービスなどを取り揃えています。お困りの際はぜひお問い合わせください。