はじめに
LLMの進化が著しく、ついていくのもやっとです。
最近、ローカルLLMデビューをしたので、さっそくStreamlitでチャットアプリを作って遊んでみようと思います。
必要なパッケージ
- streamlit
- llama_cpp
なければインストールしましょう
pip install streamlit llama_cpp
llama_cppはcmakeなどのC++フレームワークが入っていないと動かないので、適宜インストールしましょう。
Streamlitについて
Streamlitは簡単にWebアプリが作れるPythonのフレームワークです。
以前にチャットエレメントを使った時の記事はこちら↓
llamaモデルについて
LLaMA(Large Language Model Meta AI)は、Meta AI が2023年2月に発表した大規模言語モデル[1][2]。70億パラメータから650億パラメータまで、さまざまなサイズのモデルが学習された。
(引用:https://ja.wikipedia.org/wiki/LLaMA)
Metaの開発した大規模言語モデルで、いろんなところでオープンソースとして使われていますね。
今回は以下の記事を参考にして構築していきます。
コードの構造
- ユーザ入力の受付 -
input_prompt
ユーザからの入力を受け付けます - チャット履歴の表示 -
write_chats
関数で渡したチャット履歴を画面に表示 - Llamaモデルを使用した返答の生成 -
LlamaAdapter
クラスを通じて、ユーザの入力に対するボットの返答を生成する。
実装
実際のコードを紹介していきます。
input_prompt
def input_prompt(chats):
"""ユーザからの入力を受け取る
Args:
chats ([dict]): 元チャット履歴
Returns:
[dict]: 更新後のチャット履歴
"""
# ユーザーからの入力を受け取る
prompt = st.chat_input("Say something")
# ユーザーからの入力があれば、チャット履歴に追加
if prompt:
chats.append({"role": "user", "message": prompt})
return chats
ユーザからのinputを受け取り、chatsに記録していきます。
write_chats
def write_chats(chats):
"""チャット履歴を表示する
Args:
chats ([dict]): チャット履歴
"""
# チャット履歴を表示
for chat in chats:
# ユーザーの発言
if chat["role"] == "user":
with st.chat_message("user"):
st.write(f"{chat['message']}")
# ボットの発言
else:
with st.chat_message("ai"):
st.write(f"{chat['message']}")
chatsの内容を表示します。少し無駄のある実装かもしれませんw
LlamaAdapter
class LlamaAdapter:
def __init__(self):
# モデルを初期化
self.llm = Llama(model_path='./japanese-stablelm-3b-4e1t-instruct-q4_K_M.gguf')
def infer(self, prompt):
"""返答を生成する
Args:
prompt (str): ユーザーの入力
Returns:
str: ボットの返答
"""
# ボットの返答を生成
output = self.llm(
prompt,
max_tokens=64,
)["choices"][0]["text"]
return output
こちらは参考サイトのコードを少しいじって、好きなプロンプトを入力できるようにしました。
メイン部分
動作する部分を書いていきます。
# モデルを初期化
if "model" not in st.session_state:
st.session_state["model"] = LlamaAdapter()
# 使いやすい形にする
model = st.session_state["model"]
# チャット履歴を初期化
if "chat_history" not in st.session_state:
st.session_state["chat_history"] = []
# 使いやすい形にする
chats = st.session_state["chat_history"]
# promptの入力を受け付ける
chats = input_prompt(chats)
# チャット履歴を出力
if len(chats)!=0:
write_chats(chats)
if len(chats)!=0 and chats[-1]["role"] == "user":
# ボットの返答を予測
with st.spinner("Thinking..."):
output = model.infer(chats[-1]["message"])
chats.append({"role": "bot",
"message": f"{output}"})
# ボットのチャットを出力
if len(chats)!=0 and chats[-1]["role"] == "bot":
write_chats([chats[-1]])
実行
以下のコマンドで実行することができます。
streamlit run app.py
実際の使用例
入力すると、こんな感じで考え始めます。
すると、以下のように返答が表示されます。
また、以下のようにちゃんと下に続いていきます。
まとめ
Streamlitとllama_cppパッケージを使用して、簡単にローカルで動作するチャットアプリを作成する方法を紹介しました。これができるといろんなアイデアが湧いてきますね。