Raspberry Pi 5上で軽量LLM、TinyLlamaを動かしてみる

先日、日本で発売されたRaspberry Pi 5 (メモリ4GB)が届いたので、流行りのLLMを動かしてみました。動作の様子は次のツイートに掲載しています。

https://x.com/kazuhitoyokoi/status/1759064706516754797

ニューヨークにあるエンパイアステートビルの説明をしてくれています。

用いたOSは、2023-12-05にリリースされたRaspberry Pi OS (64-bit) with Desktopです。
Raspberry Pi Imagerを用いてSDカードにイメージを書き込み起動しました。



# TinyLlamaの環境準備
まずターミナル上で以下のコマンドを実行して、Hugging FaceのサイトからTinyLlamaのモデルをダウンロードしてきます。操作は/home/pi/直下で行っています。
```
wget https://huggingface.co/TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF/resolve/main/tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf
```
次にPythonのプログラムで必要となるllama-cpp-pythonをインストールします。
```
python -m venv llama2
llama2/bin/pip install llama-cpp-python
```
次にviなどのテキストエディタで以下のPythonプログラム、llama2.pyを作成します。
```:llama2.py
import sys
from llama_cpp import Llama
llm = Llama(model_path="tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf", verbose=False)
output = llm("<user>\n" + sys.argv[1] + "\n<assistant>\n", max_tokens=40)
print(output['choices'][0]["text"] + "...")
```
本Pythonプログラムではllama-cpp-pythonをインストールすることで利用できるようになったllama_cppライブラリを用いて、TinyLlamaのモデルを読み込み、llm()関数を用いてプロンプトを渡しています。プロンプトはコマンドライン引数から生成しています。また、max_tokens=40で出力する回答の長さを最大40文字に制限しています。

Pythonプログラムの動作確認のため、以下のコマンドを実行してみます。
```
llama2/bin/python llama2.py "What is Empire State Building?"
```
実行ログが出力され、最後に以下の回答が出力されました。
```
The Empire State Building is a famous landmark and iconic building located in Midtown Manhattan, New York City. It was designed by the architects R. M. Schindler and...
```
それらしい回答が返ってきましたね。実行時間も5秒程で実用的な応答時間です。

# チャットUIのプログラムを読み込み
コマンド操作では見栄えが良くないため、チャットUIも開発してみました。ここではローコードで素早くフロントエンド画面を開発できるNode-REDという開発ツールに開発済のプログラム(フロー)を読み込みます。Node-REDインストールスクリプトが用意されているため、Raspberry Piのターミナル上で次のコマンドを実行します。
```
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
```
設定ウィサードの中で聞かれる「Do you want to enable the Project feature?」ではYesを選択し、GitHubリポジトリからプログラムを取得できるようにします。

最後にNode-REDを自動起動するように設定してRaspberry Piを再起動します。
```
sudo systemctl enable nodered.service
sudo reboot
```

再起動した後はRaspberry Pi上にポート1880番でHTTPサーバが立ち上がります。ブラウザから[http://localhost:1880](http://localhost:1880)にアクセスするとNode-REDの開発環境であるフローエディタが表示されます。

最初のウィザード画面ではGitHubリポジトリからフローを取得するため「プロジェクトのクローン」を選択します。

![Screenshot 2024-02-18 at 12.10.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/589ddf49-2976-cfd6-bca2-2e8550a51c85.png)

次にユーザ情報を設定した後「GitHubリポジトリのURL」の入力欄に「[https://github.com/kazuhitoyokoi/tinyllama](https://github.com/kazuhitoyokoi/tinyllama)」を貼り付けます。

![Screenshot 2024-02-18 at 12.11.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/ed3901d7-b244-9ccc-ddd2-e032200bbddf.png)

これでフローが読み込まれますが、いくつか必要なノード部品がインストールされていない状態です。そのため、右上のメニューからプロジェクト->設定を選択して、プロジェクトの設定画面を開きます。

![Screenshot 2024-02-18 at 12.12.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/9eb524eb-a5fe-d3d8-0701-93456b8ae861.png)

依存関係のタブの中に、必要なノード部品が表示されるため、インストールボタンを押して追加します。

![Screenshot 2024-02-18 at 12.12.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/cbec1d4b-6fb2-35b0-f6e4-5edf4c046646.png)

これでフローが動くようになりました。チャットUIの画面を開くため、右側のサイドバーにあるダッシュボード2.0タブを選択し、ダッシュボードを開くためのボタンをクリックします。

![Screenshot 2024-02-18 at 12.12.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/9cccee77-f4e2-80db-70dd-18e37162cba2.png)

すると、デモ動画と同じチャットUIの画面が表示されます。

![Screenshot 2024-02-18 at 12.14.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287766/8bd412ec-8b6b-f4fb-8ea4-8e4013ee6bcf.png)

下の入力欄に英語で質問文を入力してみましょう。ChapGPTの様に賢い回答をしてくれることでしょう。

# 最後に
半年ほど前までは、LLMの推論処理だけでも高性能なハードウェアが必要でした。現在はLLMの軽量化も進み、Raspberry Piの性能も上がったことで1万円程度の安価なハードウェアでもChatGPTライクなアプリを手元で動かせるようになりました。
最小限のコーディングで本格的なアプリを開発できるローコード開発ツールを用いることで、たった24行のソースコードだけでチャットアプリを作れることにも驚きです。
2024年もどんどん技術が進化してゆくでしょう。楽しみです。