SSブログ

今週もホタル [相鉄沿線]

こども自然公園 
土曜日には、ホタルも人も、沢山増えていました。





都心まで乗り入れた相鉄線を利用して、遠くから見に来た人もいたようです。



今週のチョットGPT

最近、日本語のLLM (Large Language Models)がいくつか発表されるようになってきた中で、 rinna/japanese-gpt-neox-3.6b-instruction-ppoというのが、わりと自然な日本語文を作ってくれるようなので、LangChainのUse CasesにあるQuestion Answering over Docsのように使ってみようと思ったのですが、調べてみたけど、まだRinnaのLLMは、対応していないみたいでした。
それなら、自分でRinnaのEmbeddings機能を直接呼び出して作ちゃえ、ということで、やってみました。Rinnaのモデルは、パラメータ数も学習済みデーターも海外のものと比べたら一桁ぐらい小さくて、Rinnaだけでは、ちゃんとしたQAができませんが、外からヒントを与えてあげれば、ちゃんと使えますね。富岳が来年以降に大きなモデルを発表するようですが、それよりは、こんなLLMが早く出てくるのを待っていました。

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

# rinna/japanese-gpt-neox-3.6b-instruction-ppoの
# tokenaizerとmodelの作成
tokenizer = AutoTokenizer.from_pretrained(
    "rinna/japanese-gpt-neox-3.6b-instruction-ppo", 
    use_fast=False)
model = AutoModelForCausalLM.from_pretrained(
    "rinna/japanese-gpt-neox-3.6b-instruction-ppo")

# LLMを入れるデバイス(cpu かgpuか)
device = 'cpu'
if torch.cuda.is_available():
    device = 'cuda'
    model = model.to(device)

###
# LLMモデルからembeddings(lookup table)を取得します。
input_embeddings = model.get_input_embeddings()


###
# Rinnnaのtokenizerとembeddingsを利用し
# ドキュメントを読んで、質問の際に使うヒント作成用の
# ベクトル化したデータを作ります。
import numpy as np
import faiss

filename = 'data/kodomosizenkouen.txt'

###
# テキストの読み込み
data = []
maxlen = 512
n = 0

with open(filename) as f:
    for s_line in f:
        if len(s_line) > 30:
            data.append((s_line.strip())[:maxlen])
            n += 1

###
# テキストを埋込み表現にする(ベクトル化)関数
def embedding(text):
    input_ids = (tokenizer(text)).input_ids
    t = torch.LongTensor([input_ids]).to(device)
    embeddings = input_embeddings(t)
    return(torch.mean(embeddings[0], 0).detach())


# 埋込み表現(ベクトル)化
vect = []
for d in data:
    vect.append(embedding(d).to('cpu').detach().numpy().copy())

### FAISSのindexを作る
# 参照: https://github.com/facebookresearch/faiss ,
# https://github.com/facebookresearch/faiss/blob/main/tutorial/python/1-Flat.py

# Rinnaのembeddingsのサイズに合わせてFAISSのindexを用意する
nd = 2816 # dimension
index = faiss.IndexFlatL2(nd)   # build the index

xb = np.array(vect)
index.add(xb)                  # add vectors to the index


### FAISSのindexを使った検索
# (質問をする際に使うヒントの作成) 
def get_some_hint(text, n = 5):
    emb = embedding(text)
    xq = np.array([emb.to('cpu').detach().numpy().copy()])
    D, I = index.search(xq, n)
    hint = ''
    for i in range(len(I[0])):
        hint += data[I[0][i]]
    return hint

###
# 質問文
text = 'こども自然公園でホタルを見ることはできますか'

prompt = [
    {
        "speaker": "ユーザー",
        "text": text
    }
]
prompt = [
    f"{uttr['speaker']}: {uttr['text']}"
    for uttr in prompt
]
prompt = "".join(prompt)
prompt = (
    prompt
    + ""
    + "システム: "
)

token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")

with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        do_sample=True,
        max_new_tokens=512,
        temperature=0.7,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):])
output = output.replace("", "\n")
print(output)

# ヒント無しの場合の答え
ああ、もちろんです。こども自然公園は、ホタルの生息地の1つで、ホタルの鑑賞に最適な場所です。 ホタルは、6月から7月にかけて、自然公園内の小川や池で見られます。ホタル鑑賞のベストシーズンは、6月下旬から7月中旬です。

# FAISSに格納されている情報をヒントに使う
hint = get_some_hint(text)
prompt = [
    {
        "speaker": "hint",
        "text": hint
    },
    {
        "speaker": "ユーザー",
        "text": text
    }
]
prompt = [
    f"{uttr['speaker']}: {uttr['text']}"
    for uttr in prompt
]
prompt = "".join(prompt)
prompt = (
    prompt
    + ""
    + "システム: "
)

token_ids = tokenizer.encode(prompt, add_special_tokens=False,
    return_tensors="pt")

with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        do_sample=True,
        max_new_tokens=512,
        temperature=0.7,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):])
output = output.replace("", "\n")
print(output)

# ヒントを与えたときの答え
はい、こども自然公園では、ホタル鑑賞ができます。ホタルは、ゲンジボタルとも呼ばれ、神奈川県内の多くの地域で見ることができます。ホタル観賞は、5月下旬から6月下旬にかけて、主にゲンジボタルが生息する地域で行われます。こども自然公園は、自然豊かな公園で、ホタル鑑賞以外にも、バーベキュー場や動物との触れ合いなどの自然体験を楽しむことができます。



nice!(16)  コメント(0)