LLMのある噂を検証する
知人のエンジニアからある噂を聞きました。
「LLMの単語ベクトルは偏っていて、全く関係ない文章が高い類似度を算出されることがある」
上記の噂が本当なのか、1つのLLMだけですが、検証してみました。
環境構築
Google Colabratryを使用してるので、環境構築は不要です。
LLMベースのモデル(重い)
下記のLLMベースモデルが人気だったが、無料版のColabではRAMをすべて消費してしまうので別の軽いモデルを使用する。
LLMベースのモデル(軽い)
下記のモデルでは無料版のColabでも使えました。
ライブラリのインストール
!pip install peft
!pip install sentence_transformers
!git clone https:
%cd FlagEmbedding
!pip install -e .
FlagEmbeddingをインストールした後は、Colabのランタイムを再起動する。
データセットの準備(流用)
モデルによっては、全く違う文章でも類似度の最大値が1として0.8を超える数値を算出するものもあります。
全く違う文章の類似度は低く、似た文章の類似度は高く判定するように、数値を差をつけて推定してくれるモデルを選定する必要があります。
よって、文章の類似度算出を検証するにあたって、類似度が異なる文章を用意する必要があります。
本記事では、Yahoo! JAPAN研究所の日本語言語理解ベンチマークJGLUEを用います。
2つの文章の類似度を5段階評価した、ラベル付きのデータです。
下記のサイトを参考に、0.0~1.0で0.1刻みで文章のサンプル抽出します。
import pandas as pd
df_json = pd.read_json('https://raw.githubusercontent.com/yahoojapan/JGLUE/main/datasets/jsts-v1.1/valid-v1.1.json', lines=True)
df_json.head()
import numpy as np
"""
サンプルを抽出
今回は、label を 1.0 刻みで分割してその中から1件ずつデータを取ります。
後で比較しやすいように label は 0.0 ~ 1.0 の範囲に変換します。
"""
seed = 42
offset = 1.0
df_sample = df_json[df_json['label']==0.0].sample(random_state=seed)
for i in np.arange(0.0, 5.0, offset):
if i==0.0:
df_sample = pd.concat([df_sample, df_json.query(f'{i} < label < {i+offset}').sample(random_state=seed)])
else:
df_sample = pd.concat([df_sample, df_json.query(f'{i} <= label < {i+offset}').sample(random_state=seed)])
df_sample = pd.concat([df_sample, df_json[df_json['label']==5.0].sample(random_state=seed)])
df_sample = pd.concat([df_sample, df_json[(df_json['sentence1']==df_json['sentence2']) & (df_json['label']==5.0)].sample(random_state=seed)])
df_sample.drop(['sentence_pair_id', 'yjcaptions_id'], axis=1, inplace=True)
df_sample.reset_index(drop=True, inplace=True)
df_sample['label'] = df_sample['label'].apply(lambda x: x/5.0)
df_sample = df_sample[1:-1].reset_index(drop=True)
df_sample
類似度判定
from FlagEmbedding import FlagLLMModel
from sentence_transformers import util
model_name = 'BAAI/bge-reranker-v2-m3'
model = FlagLLMModel(model_name,
query_instruction_for_retrieval="Given a web search query, retrieve relevant passages that answer the query.",
use_fp16=True)
cosine_score_list = []
for i in range(len(df_sample)):
sentence1 = df_sample["sentence1"][i]
sentence2 = df_sample["sentence2"][i]
embeddings1 = model.encode_queries(sentence1)
embeddings2 = model.encode_queries(sentence2)
cosine_score = util.pytorch_cos_sim(embeddings1, embeddings2)[0][0]
cosine_score = round(float(cosine_score), 4)
cosine_score_list.append(cosine_score)
df_sample[model_name] = cosine_score_list
display(df_sample.style.background_gradient(axis=None))
マジで全然差でんばい。
色んな文章を生成するためには、単語ベクトルが一領域に寄っている必要があるのかな。
別の軽いLLMも試してみよう。
なんj論文レビュー
AgentScope での大規模マルチエージェントシミュレーション
SOTA:https://paperswithcode.com/paper/very-large-scale-multi-agent-simulation-in
Depth Anything V2(単眼深度推定)
SOTA:https://paperswithcode.com/paper/depth-anything-v2
ACEGEN: 創薬のための生成化学物質の強化学習
SOTA:https://paperswithcode.com/paper/acegen-reinforcement-learning-of-generative