4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

watsonx.data Milvus + watsonx.ai RAGハンズオン Part1: Excelをベクトル化してベクトルDB Milvusに入れよう

Posted at

この内容は2024年11月27日(水)にホテル雅叙園東京で開催された「IBM TechXchange Japan 2024」で実施したwatsonxハンズオン「さわってみよう ベクトル・データベース watsonx.dataでRAG体験」の内容です。QiitaではPart1, Part2, Part3, Part4の四部構成で、 この投稿はPart1となります。

座学部分の資料はこちらです:

使用したハンズオン資料はこちらです:

0. ハンズオン内容 および 前提

0.1: ハンズオン内容

TechXchange JapanのWebサイトの内容のソースであるExcelファイルを使って、RAGを構成し、 TechXchange JapanについてQ&Aができるchatbotを作ります。

image.png

chatbotのイメージ:
image.png

  • このハンズオンでは watsonx.dataのベクトル・データベース Milvusへのアクセス、データの追加をし、watsonx.aiの生成AIを組み合わせてRAGを体験していただくのが目的です。
  • RAGのフレームワークとしてLangChainを使います。
  • chatbotのGUI構築にはpythonの機械学習モデルのデモを行うWebアプリケーションを簡単に作ることができるPythonのライブラリーgradioを使います。
  • RAGを体験していただくのが目的のため、Milvusのindex typeやmetricsなどの詳細、LangChainの使い方詳細、gradioの使い方詳細など Coding詳細はこのハンズオンでは扱いません。

0.2: ハンズオン前提

当ハンズオンを実施するには以下の環境が必要です:

  • watsonx.dataのMilvus または なんらかのMilvusが使える状況にあり、接続に必要なhostname, port, APIKEY情報が入手可能
  • watsonx.ai Studioでプロジェクト作成済み かつ Watson Machine Learning と関連付けされていて、APIKEY, Project Id情報が入手可能
  • pythonが実行できるjupyter notebook環境があること(Local環境でもOK)

1. Excelをベクトル化してベクトルDB Milvusに入れよう!

この内容はjupyter notebook https://github.com/IBM/japan-technology/blob/main/techxchange/2024-watsonx-handson-1/notebooks/techxchange_handson_01_vectordb.ipynb とほぼ同じです。Link先notebookはwatsonx.ai Studioでの実行を前提としていますが、当内容はLocalも含め一般的なpython実行環境が前提です。

image.png

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

pipにて以下のライブラリーを導入します:

pip install 'ibm-watsonx-ai>=1.1.15'
pip install 'langchain>=0.3.3'
pip install 'langchain-ibm>=0.3.1'
pip install 'langchain-milvus>=0.1.6'
pip install 'langchain-community>=0.3.2'
pip install 'pymilvus>=2.4.8'

2. apikeyの設定

apikey をセットしてください。
IBM Cloud環境でのAPIKEYの取得方法はこちらを参考にしてください。

またwatsonx.dataとwatsonx.ai Studioは同じAPIKEYである前提で同じ変数を使用していますので、もし違う場合は2つ変数を準備するようにしてください。

apikey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

3. Milvus接続情報の設定

Milvus接続情報の値をセットしてください。

  • Milvus Host名
  • Milvus Port番号

Milvus接続情報の詳細取得手順はこちら を参照してください。

またmy_connection_argsに設定するkeyの詳細はpymilvusのMilvusClientのパラメータを参照してください。

milvus_host="xxx.xxx.xxx.com"
milvus_port="YYYY"

# Milvus接続情報パラメータののセット
my_connection_args ={
 'uri': f'https://{milvus_host}:{milvus_port}', 
 'token': f'ibmlhapikey:{apikey}'
}

4. watsonx.ai Studio Project idの設定

watsonx.ai Studioで実行する場合は、このノートブックが実行されるプロジェクトからProject idを取得します。 watsonx.ai Studio以外で実行する場合は、Project idを入力してください。

Hint: project_id はプロジェクトを表示し、管理タブから project_id を取得可能です.

import os
try:
    project_id = os.environ["PROJECT_ID"]
except KeyError:
    project_id = "<ProjrctID>"

5.watsonx.aiのAuthentication用のエンドポイントのURLの設定

Waston Machine Learningのインスタンスを作成したリージョンで決まります。 https://ibm.github.io/watson-machine-learning-sdk/setup_cloud.html#authentication より

Dallas: https://us-south.ml.cloud.ibm.com
London: https://eu-gb.ml.cloud.ibm.com
Frankfurt: https://eu-de.ml.cloud.ibm.com
Tokyo: https://jp-tok.ml.cloud.ibm.com

watsonx_url = "https://us-south.ml.cloud.ibm.com" #ダラスの場合

6. Excelデータの取得

TechXchange Confrence Japan 2024の情報の入ったExcelを取得します。

尚ファイルはこちらにありますので、お手持ちのPCで見たい場合はダウンロードしてExcelで開いて見てみてください。

wget https://github.com/IBM/japan-technology/raw/refs/heads/main/techxchange/2024-watsonx-handson-1/data/TechXchangeJapan2024.xlsx -O TechXchangeJapan2024.xlsx

参考までにこんな感じの内容です:
image.png

7. 必要ライブラリーのImport

import pandas as pd
from langchain.schema.document import Document
import json
from langchain_milvus import Milvus
import os
from ibm_watsonx_ai.metanames import EmbedTextParamsMetaNames
from langchain_ibm import WatsonxEmbeddings
from ibm_watsonx_ai.foundation_models.utils.enums import EmbeddingTypes

8, 9, 10で以下を行います

image.png

8. Excelファイルの内容を pandas Daraframeに読み込む

path="./"
filename='TechXchangeJapan2024.xlsx'
excel_file = path+filename

df_list = []

# 全てのシートを読み込み、リストdf_listに格納
for sheet_name in pd.ExcelFile(excel_file).sheet_names:
    df = pd.read_excel(excel_file, sheet_name=sheet_name)
    df_list.append(df)
    print(f"\nExcelシート名: {sheet_name}")
    display(df.head()) #各シート最初の5 行 表示

出力として各シート最初の5行を表示するようにしてあります:
image.png
image.png

9. 行をJSON化し、metadataとしてCategory,IDを抜き出す

ベクトルDBにデータを入れる際、どの単位でどのようにベクトル化するかというのは、のちのちの類似検索の結果に関わってきますので重要です。

今回はやりませんが、PDFならページ単位に文字を抜き出して、1ページ分を1ベクトルににするとか、さらに細かく切っておおよそ1000文字単位でうまく文章の切れ目で切って1ベクトルにするとか、いろいろ考えられます。

今回はExcelファイルなので、シート単位で1シート1ベクトルとか、一行1ベクトルとかが考えられます。
今回は一行1ベクトルにしてみます。
さらに一行のベクトル化する元の文字列ですが、列名をいれたJSON形式の文字列にしてみます。

Milvusにはベクトルデータの他に、Keyとなる値を列として持つことができます。RDBのように列で検索も可能です。

LangChainを使って、ベクトルDBにインサートする際、列データはDocumentオブジェクトのmetadataとしてJSONで指定します。 こちらのmetadataのJSON文字列もここで作成します。

import numpy as np
json_doc_list=[]
json_meta_list=[]

for df in df_list:
    # 各シートのデータフレームに対する処理
    
    # 行をJSONフォーマットに変換
    json_doc_string = json.loads(df.to_json(orient='records', force_ascii=False))
   
    # metaデータとして'Category','ID'を抜き出し, JSONに変換
    json_meta_string =  json.loads(df[['Category','ID']].to_json(orient='records', force_ascii=False), parse_int=str)

    # 各シートのJSON Listを1つのListに結合
    json_doc_list.extend(json_doc_string)
    
    json_meta_list.extend( json_meta_string)

#中身確認 最初の5行
print("ベクトル化するデータ 最初の5行")
for index, item in enumerate(json_doc_list[0:5]):
    print(index + 1, item)

print("\nmetaデータ 最初の5行")
for index, item in enumerate(json_meta_list[0:5]):
    print(index + 1, item)

出力:
image.png

10. 1行の情報をlangchainのDocumentにし、Listを作成

  • page_contentはjson_doc_listの一行分のjson
    • ベクトル化されるデータ
  • metadataはjson_meta_listのの一行分のjson
    • ベクトルDBに列の項目として入るデータ
# DocumentのListをjson_doc_listとjson_meta_listから作成
# page_contentはjson_doc_listの一行分のjson
# metadataはjson_meta_listのの一行分のjson

# 以下と同じコード
# docs = []
# for doc_str, meta_str in zip(json_doc_list, json_meta_list):
#     docs.append(Document(page_content=json.dumps(doc_str, ensure_ascii=False), metadata=meta_str)) 
    
docs = [Document(page_content=json.dumps(doc_str, ensure_ascii=False), metadata=meta_str) 
        for doc_str, meta_str in zip(json_doc_list, json_meta_list)]

#中身確認 最初の二行
print(docs[0], "\n\n")

print(docs[1], "\n\n")

出力:
image.png

11, 12で以下を行います

image.png

11. Embeddingモデルを作成

ここではintfloat/multilingual-e5-largeを使います

LangChainで使用できるwatsonx.aiのEmbeddingモデルintfloat/multilingual-e5-largeがあるので、今回はこちらを使用します:

尚、intfloat/multilingual-e5-largeはオープンソースで公開されているので、watsonx.aiのEmbeddingモデルを使用しなくとも、ローカルにダウンロードすることで使用可能です。 その場合のコードはこちらです(今回は使用しません)

from langchain_huggingface import HuggingFaceEmbeddings
from tqdm.autonotebook import tqdm

embeddings = HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large")

下記は`apikey`はMilvusと同じものを使用しています。異なる場合は変数apikeyを変更してください。
# watsonx.aiのEmbeddingモデル取得
embed_params = {
    EmbedTextParamsMetaNames.TRUNCATE_INPUT_TOKENS: 512,
    EmbedTextParamsMetaNames.RETURN_OPTIONS: {"input_text": True},
}

embeddings = WatsonxEmbeddings(
    model_id="intfloat/multilingual-e5-large",
    url=watsonx_url,
    apikey=apikey,
    project_id=project_id
    )

12. ベクトルDB Milvusにデータの挿入

参考: LangChain ドキュメント: Vector stores

Milvus参考:

コレクション(Milvusのテーブル名のようなもの)の名前はtechxchange_line_dataとします。

# パラメータの設定 
index_params = {
    "metric_type": "COSINE", #コサイン類似度
    "index_type": "HNSW", 
    "params": { "M": 16,"efConstruction": 200,"efSearch": 16 }
}

# techxchange_line_data に データの挿入
vector_store = Milvus.from_documents(
    docs,
    embeddings,
    connection_args=my_connection_args,
    index_params = index_params,
    drop_old=True, #追加の場合はここをFalseに
    collection_name = 'techxchange_line_data' # コレクション名
)

上記はベクトル化+データの挿入を実施していますが、もし既にデータの入っているMilvusのCollectionに接続するのみの場合は以下のように接続してください:

# 既存データを使う場合はこちらを実行
from langchain_milvus import Milvus

vector_store = Milvus(
    embeddings,
    connection_args=my_connection_args,
    collection_name = 'techxchange_line_data'
)

13. 挿入データの確認

Milvus DBにロードした内容をDataFrameにダンプして表示させます。

AttuなどのGUIツールがあればそれを使用すれば見えますが、今回のハンズオンでは環境がないため、ダンプして表示してみます。

from pymilvus import MilvusClient
import pandas as pd

pk_list=vector_store.get_pks(expr="pk > 0")

client = MilvusClient(uri=my_connection_args['uri'], token=my_connection_args['token'])

res = client.get(
    collection_name="techxchange_line_data",
    ids=pk_list
)

for i, milvus_rec in enumerate(res):
    vecter_data = milvus_rec['vector']
    res[i]['vector']= "["+", ".join(map(str, vecter_data))+"]"
    res[i]['pk']= str(milvus_rec['pk'])

# DataFrame df_s にダンプしたデータが入ります
df_s = pd.DataFrame.from_dict(res).reindex(columns=['ID', 'Category', 'text', 'pk', 'vector'])

# notebookの場合は以下で表示してきます
df_s

notebookでの表示例:
image.png

以上で「Part1: Excelをベクトル化してベクトルDB Milvusに入れよう」は完了です。

次のPart2: ベクトルDB Milvusに入ったデータで類似検索してみよう!に進んでください。

4
0
0

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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?