ローカルLLMのフレームワークの選び方

　本記事はプライバシー・セキュリティやOpenAI_APIの課金回避等の理由で、できればローカルでLLMを使いたいが、高価なGPUマシンが無い人向けのローカルLLMフレームワークの選び方についての記事になります。特に企業や個人の非公開の内部データやドキュメントを生成AIに入力することは、心配になりますよね。最近ではローカルLLMの利用に関する情報が増えてきましたが、安心して使えるオープンソースのツールとしては、元祖llama.cppを筆頭にOllama、LM Studioなどがあり、どれが良いか迷うことも多いのではないでしょうか。
　結論から言うと現時点ではOllamaが一押しです。理由は各種設定の自由度が高く、手軽に様々なプラットフォーム上で使えて、GPU依存度が低くメモリ消費も少ないからです。具体的に実際の使用経験から各プラットフォームをご紹介し、合わせて使い方のヒントにも触れて行きたいと思います。但しこの分野はアップデートが早くかつ頻繁な為、内容の陳腐化も早いので、あくまでも2024年3月上旬時点での参考情報として下さい。

・検証環境は下記の通りです
　ローカル：M1 MacBookAir メモリ8GB GPU7コアCPU8コア


１．選択肢
　候補は結構多いのですが、冒頭に記載した通りの目的なので下記の候補に絞ります。
 　・llama.cpp : 元祖ローカルLLMフレームワークで、名前の通りC++で書かれたオープンソース。
  　・Ollama：インストールが簡単で設定の自由度が高く、使い勝手も良いオープンソース。
　・LM Studio：デスクトップ向けのローカルLLMフレームワークでGUIなので扱い易い。
 　・その他：llamafile、gpt4all、h2ogpt
　上記以外の候補についても興味がある方は、下記リンクが役に立つかもしれません。

  [　リンク：5 easy ways to run an LLM locally　](https://www.infoworld.com/article/3705035/5-easy-ways-to-run-an-llm-locally.html)
   [　リンク：Run LLMs locally By LangChain　](https://python.langchain.com/docs/guides/local_llms)
   
　ちなみに、その他に列挙したツール群は全てllama.cppをバックエンドとして使っているので、性能は各ツールのチューニングにもよりますが、基本はllama.cppと同等かと推測されます（LM Studioもllama.cppに依存しているようですが、処理速度はかなり改善されているようです）。llama.cppは強力なツールですが、インストールが環境によって多少複雑になったり、各種便利機能等は殆ど備えていないので、今後もllama.cppをバックエンドに利用した便利ツールは出てきそうですね。

２．検証方法
　最初はOpenAIからスタートしたのですが、この時に作成したPythonコードの主要部分は下記のようになります。PDFを読み込んで埋め込みによりLLMが質問に回答するプログラムです。今回はこのコードをローカルLLM用に書き換えて評価しました。本コードの詳細は別途記事にする予定なので、興味のある方は是非ご覧下さい。

 ```test.py
　...
from langchain_community.chat_models import ChatOpenAI
　...
class QAResponseGenerator:
    def __init__(self):
        self.llm=ChatOpenAI(openai_api_base="http://localhost:8000/v1", openai_api_key="******")
　...

 ```
 　上記コードの上から1行目と最終行のChatOpenAIの部分を入れ替えて検証しました。llama.cppの場合はChatOpenAI -> LlamaCpp、Ollamaの場合はChatOpenAI -> ChatOllamaとなります（どちらもLangChainからのimportが必要）。LM Studioだけは単独アプリでローカルサーバーを起動する形なので、指定のローカルポートをLlamaCppかChatOpenAI内にurlとして設定しました。
　各フレームワークのインストール／ビルド方法は下記リンクで詳しく案内されていますので、必要に応じて参照して下さい。
   [　リンク：llama.cpp　](https://github.com/ggerganov/llama.cpp/tree/master)
   [　リンク：Ollama　](https://ollama.com/)
   [　リンク：LM Studio　](https://lmstudio.ai/)

　インストールが完了したら、test.pyを書き換えていきます。
　まずllama.cppを直接読み込む場合は、下記のコマンドでLLMモデルのインターフェースを起動します。
 ```
 ./main -m ./models/{your_llm_modelfile}.gguf -n 128
 ```
 
　次にpython側のLlamaCppでこのモデルを読み込みます。
 
  ```test.py
   (llama.cpp用1)
　...
- from langchain_community.chat_models import ChatOpenAI
+ from langchain_community.llms import LlamaCpp
　...
class QAResponseGenerator:
    def __init__(self):
-        self.llm=ChatOpenAI(openai_api_base="http://localhost:8000/v1", openai_api_key="******")
+        self.llm = LlamaCpp(
            verbose=True,
            model_path=f"./models/your_local_llm_file",
            temperature=0, 
            n_ctx=2048,  
            n_threads=6,
        )
　...
 ```
　llama.cppはWebサーバー機能もあるので、API経由でアクセスする場合はまずサーバーを起動します。
```
 ./server -m models//{your_llm_modelfile}.gguf -c 2048
```
　次にChatOpenAIをそのまま使ってAPI経由で接続します。
 
  ```test.py
   (llama.cpp用2)
　...
 from langchain_community.chat_models import ChatOpenAI
　...
class QAResponseGenerator:
    def __init__(self):
        self.llm=ChatOpenAI(openai_api_base="http://localhost:8000/v1", openai_api_key="******")
　...
 ```
 　Ollamaの場合は、最初に自分のダウンロードしたLLMファイル用のModelfileに設定情報を保存して(詳細は下のOllamaのパラメータのリンク参照)、これを使って下記のコマンドでビルドしておくと、次からはollama run xxx(任意の名前) のみで起動します。
```
ollama create xxx -f ./Modelfile
ollama run xxx
```
  あとはPython側でChatOllamaを使ってAPI接続します。
 ```test.py
  (Ollama用)
　...
- from langchain_community.chat_models import ChatOpenAI
+ from langchain_community.chat_models import ChatOllama
　...
class QAResponseGenerator:
    def __init__(self):
       - self.llm=ChatOpenAI(openai_api_base="http://localhost:8000/v1", openai_api_key="******")
       +  self.llm=ChatOllam(base_url="http://localhost:11434")
　...
 ```
 　LM StudioはChatOpenAIをそのまま使いますがポートを変更してAPI接続します。
 ```test.py
  (LM Studio用)
　...
 from langchain_community.chat_models import ChatOpenAI
　...
class QAResponseGenerator:
    def __init__(self):
       - self.llm=ChatOpenAI(openai_api_base="http://localhost:8000/v1", openai_api_key="******")
       +  self.llm=ChatOpenAI(openai_api_base="http://localhost:1234/v1)
　...
 ```
　自分で各LLMの設定を試してみたい方は、下記のリンクに設定可能なパラメータのリストと説明がありますので、参考にして下さい。
    [　リンク：llama.cpp(LangChainのLlamaCpp)のパラメータ　](https://python.langchain.com/docs/integrations/llms/llamacpp)
   [　リンク：Ollama(LangChainのChatOllama)のパラメータ　](https://github.com/ollama/ollama/blob/main/docs/modelfile.md#system)
   [　リンク：LM Studioのパラメータ　](https://github.com/lmstudio-ai/configs)

　なお、ChatOpenAIをダミーのKeyで利用することも可能なようですが、Pythonのコードの内容によってAPI_Keyの認証エラーが発生する場合もあるので（詳細不明）、LlamaCppやChatOllamaを使った方が無難なようです。
　
３．検証結果
　上記のコード（test.py）で簡単なPDFの説明書を読み込ませ、質問に回答してもらいました。処理時間は質問を受けてから回答が終了するまでのトータルの秒数になります。今回は各プラットフォームを同じ条件で比較しましたが、質問内容やプロンプトの設定等により当然結果の数字は異なってきます。
　・llama.cpp： 　54sec
　・Ollama：　　22sec
　・LM Studio：　29sec

４.　まとめ
　今回はローカルLLMを動作させる3つのフレームワークである、llama.cpp、Ollama、LM Studioの3つを処理速度の観点で比較してみました。それぞれに一長一短があるのですが、llama.cppとOllamaはリモート環境でサーバーのみ起動してAPI経由で利用することも可能です。自分に合った環境を構築できるのは嬉しい限りですね。