LoginSignup
0
1

ローカルLLMで簡単にチャットアプリを作る

Last updated at Posted at 2024-04-10

はじめに

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の開発した大規模言語モデルで、いろんなところでオープンソースとして使われていますね。
今回は以下の記事を参考にして構築していきます。

コードの構造

  1. ユーザ入力の受付 - input_promptユーザからの入力を受け付けます
  2. チャット履歴の表示 - write_chats関数で渡したチャット履歴を画面に表示
  3. 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

実際の使用例

入力すると、こんな感じで考え始めます。

image.png

すると、以下のように返答が表示されます。

image.png

また、以下のようにちゃんと下に続いていきます。

image.png

image.png

まとめ

Streamlitとllama_cppパッケージを使用して、簡単にローカルで動作するチャットアプリを作成する方法を紹介しました。これができるといろんなアイデアが湧いてきますね。

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