💥

ローカルLLMでzoltraakを動かせるか検証してみた

2024/07/15に公開

はじめに

どんな人向けの記事?

  • ローカルLLMに興味のある人
  • zoltraakに興味のある方
  • LLMを用いて要件定義書を作りたい方
環境
Mac Studio(M2 Ultra 128GB)

内容

今回は元木さんのZoltraakを使って、自然言語から要件定義書を作ってみようと思います。

ただし、リリースされてから2ヶ月以上経ったzoltraakを普通に動かすだけでは面白くないので、この記事ではローカルLLMを使った場合にどの程度の品質のアウトプットが得られるか、そもそもまともに使えるのかを検証してみたいと思います。

結論

結論から述べると、下記の通りになりました。

  • 現状のローカルLLMだけでzoltraakを完全に動作させるのは難しそう

    • 要件定義書は問題なく作成できる。
    • その後の工程の、ディレクトリ・ファイル構成を作成するための実行可能なpythonコードを作ることができなかった。
    • grimoiresの記載を工夫することで、ある程度は改善できるかもしれない。
  • 絶対にオンプレミス環境で実行しなければならない特段の理由がない限りは、デフォルトで設定されているClaude APIを使うのが良さそう。(品質、速度、成功率の観点で)

  • gemma2:27b-instructやqwen2:72b-instructも捨てたものではない。

Zoltraakとは

Zoltraakについてはまだ一部しか理解できていませんが、現時点での理解を下記に述べます。

  • LLMを用いて、自然言語から要件定義書を作ることができる。
  • 要件定義書に基づいたソースコードを執筆してくれる。
  • 使い方次第で、新規事業提言書のたたき台も作れる。

イメージとしては、下記のテツメモさんのポストが参考になるかと思います。

https://x.com/tetumemo/status/1783227393978859853

ただし、アウトプットの品質は用いたLLM性能に強く依存するため、
執筆時点ではClaude 3.5 Sonnetあたりが一番高品質のものができるという認識です。

ローカルLLMモデルの選定

品質だけ考えればClaude 3.5 Sonnetが一番というのは理解しているのですが、
最近はGoogle Gemma2の登場もあって、オープンLLMの性能も飛躍的に向上してきました。

特に前回の記事で紹介したEZO-Common/Humanities-9B-gemma-2-itモデルは、shaberi3ベンチマークにおいて、zoltraakのデフォルト設定で用いられているClaude 3 haikuやgemini-1.5-flashに匹敵する日本語性能を誇ることがわかりました。

https://zenn.dev/robustonian/articles/ezo_9b_gemma_2_it

そこで、本記事ではEZO-Common-9B-gemma-2-itを使って検証したいと思います。

zoltraakの導入

Githubのページに従って導入していきます。

https://github.com/dai-motoki/zoltraak

  • zoltraakのインストール
$ git clone https://github.com/dai-motoki/zoltraak.git
$ cd zoltraak
$ python -m venv zoltraak-dev
$ source zoltraak-dev/bin/activate  # Linuxの場合←Macも同じ
$ pip install setuptools wheel
$ pip install -e .

これで導入は完了です。

Claude APIを使う場合(デフォルト)

Claude APIを使う場合、あとはAnthropic API キーの設定を行えば動かせると思います。

  • プロジェクトのルートディレクトリに.envファイルを作成。
  • 以下の行を.envファイルに追加し、YOUR_API_KEYを実際の Anthropic の API キーに置き換える:
.env
ANTHROPIC_API_KEY=YOUR_API_KEY

実行

あとは下記のようなコマンドを打つことで、zoltraakを実行できるようになっているはずです。

$ zoltraak "今月中に教育用の拡張現実(AR)アプリケーションを開発する" -c general_def

ローカルLLMで使ってみる

そこまで大層な作業ではないのですが、ブログ記事に書くには細かすぎる内容だと思ったのでローカルLLMで使えるようにするための改修手順については割愛します。

ただし参考までに、私がどのように改修をしていったのか、大まかな流れだけ書き留めておきます。

  • Step 1: Claudeの代わりにGemini-1.5-flashを用いて実行できるように修正
    • zoltraak/zoltraak/llms/gemini.pyにGemini用のgenerate_response関数が用意されていたので、こちらを使うように修正しました。
    • それと、ANTHROPIC_API_KEYの代わりにGEMINI_API_KEYを設定しておく必要があります。
  • Step 2: 同様の作業をOpenAIのAPIで実行できるように修正
    • llama.cppのllama-serverやollamaはOpenAI APIとの互換性があります。
    • Shaberi3ベンチと同様に、api_baseのURLとモデル名を設定すればローカルLLMを使ってzoltraakを実行できるようになります。

検証

ここでは、gemini-1.5-flashとEZO-Common/Humanities-9B-gemma-2-it-f16に同じプロンプトを与えたときの出力を比較します。

かなりざっくりとしてますが、下記のプロンプトで実行してみました。

$ zoltraak "web APIとLLMを用いたAI投資アドバイザーの開発" -c general_def

すると、端末に下記のような文字列が出力され、まずは要件定義書が生成されます。

==============================================================
起動術式 (プロンプトコンパイラ)   : general_def.md
魔法術式 (要件定義書)             : def_ai_investment_advisor_web_api_llm.md
錬成術式 (プロンプトフォーマッタ) : md_comment_lang.md
言霊   (LLMベンダー・モデル 名)   : gemini/gemini-1.5-flash
ファイルを開く                    : False
==============================================================
ステップ1. 起動術式を用いて魔法術式を構築中... 🪄 ━━━━━━━━━━━━━━━━━━━━━━☆゚.*・。゚

しばらくすると、魔法術式から領域術式を実行しますか? (y/n): と問われるので、'y'を打ち込んでEnterすると、アウトプットが複数生成されます。アウトプットの内容や数はプロンプトに依存します。

ステップ2. 魔法式から領域を構築中...
  0%|                                                                                                                                                          | 0/7 [00:00<?, ?files/s] 
 14%|████████████████████▊                                                                                                                             | 1/7 [00:08<00:48,  8.01s/files] 
 29%█████████████████████████████████████████▋                                                                                                        | 2/7 [00:15<00:39,  7.85s/files] 
 43%|██████████████████████████████████████████████████████████████▌                                                                                   | 3/7 [00:23<00:31,  7.87s/files] 
 57%|███████████████████████████████████████████████████████████████████████████████████▍                                                              | 4/7 [00:32<00:24,  8.33s/files] 
 71%|████████████████████████████████████████████████████████████████████████████████████████████████████████▎                                         | 5/7 [00:40<00:16,  8.30s/files] 
 86%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏                    | 6/7 [00:49<00:08,  8.31s/files]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7/7 [00:57<00:00,  8.19s/files]

途中でエラーが発生せずに最後まで進んだら、すべてのアウトプットが生成完了となります。

エラーについて

Step 2.ではわりとエラーで止まることが多かったです。

  • 以前無料枠でClaude 3 haikuを使っていたときは、レートリミットでエラーになりました。
    • これは素直に従量課金すれば解決します。
  • geminiは、エラーが出るときと出ないときがありました。
    • エラーが出るときはたいてい、実行不可能なpythonファイルが生成されて、それを実行しようとした場合です。
  • EZO-Common/Humanities-9B-gemma-2-it-f16では10回ぐらい挑戦しましたが、すべてStep 2.でエラーが出て、Step 1.の要件定義書を出力するところまでしか進めませんでした。
    • 出力されたpythonファイルdef_ai_investment_advisor_llm_api_v1.pyには、下記のような記載がありました。
    • 本来ここには、README.mdやら詳細な説明文を生成するためのpythonスクリプトが記載されるべきはずなのに、その代わりにpythonスクリプトの説明が記載されているようです。
def_ai_investment_advisor_llm_api_v1の冒頭
このスクリプトは、要件定義書の内容に基づいて README.md ファイルを作成し、
さらに LLM を利用して各セクションに対して詳細な説明文を生成することを
目的としています。

本質的な課題

レートリミットは本質的なエラーではないため無視すると、現状のローカルLLMの課題としては、下記のような複雑なタスクを正確にこなせていないことが原因のようです。

https://github.com/dai-motoki/zoltraak/blob/main/zoltraak/grimoires/architect/architect_claude.md

この指示は、人間でも指示通りにこなすのがなかなか難しいタスクと言えると思います。これくらい複雑なタスクの場合、少なくとも現状のローカルLLMだけで正確に処理するのはまだ難しそうです。

対策としては、上述したarchitect_claude.mdを利用するモデルの理解しやすい表現に書き直すことなどが考えられますが、色々と試行錯誤をしても結局解決には至りませんでした。

ちなみにgemma2:27b-instruct-fp16やqwen2:72b-instruct-q4_K_Mでも試しましたが、下記のような感じでした。

モデル context window 結果 備考
Claude 3 haiku,sonnetなど 200k わりと成功率が高い
gemini-1.5-flash 1.0M たまに成功
qwen2:72b-instruct-q4_K_M 128k まれに成功
gemma2:27b-instruct-fp16 8k すべて失敗 たまにpythonコードが作れても、モデルがgpt-3.5-turboなどに書き換えられて実行できず
EZO-Common-9B-gemma-2-it-f16 8k すべて失敗 そもそもpythonコードが出力されなかった

shaberi3ベンチではEZO-Common-9B-gemma-2-it-f16のスコアが高かったですが、複雑な処理をさせたいときはgemma2:27b-instruct-fp16やqwen2:72b-instruct-q4_K_Mも役に立つ場面がありそうです。qwen2:72b-instruct-q4_K_Mクラスになると、処理がかなり遅くなってしまうのが難点ですが。。。

他に課題になりそうなこととして、gemma2系のモデルはcontext windowが8kと短めなのも影響しているかもしれません。

出力結果:要件定義書の一部抜粋

ということで、ここではStep 1.で出力された要件定義書の出力結果だけ確認したいと思います。結果は下記のとおりです。

  • Gemini-1.5-flashの出力(一部抜粋)
    Alt text

  • EZO-Common-9B-gemma-2-it-f16の出力(一部抜粋)
    Alt text

いずれも要件やステークホルダーはかなり似通ったものが出力されています。
個人的に注目したのは、LLMの活用法でしょうか。

両者とも投資家の情報を元に投資戦略の立案をするFP的な役割をさせているようですが、EZO-Common-9B-gemma-2-it-f16ではさらにLLMの学習に利用し、アップデートさせて品質を高めるというのも戦略に盛り込まれているところが素晴らしいと思いました。

まとめ

本記事では、ローカルLLMを用いてzoltraakを動かせるかの検証をしてみました。

これだけ性能が上がったんだからローカルLLMで動かせそうだ!と思って検証を始めたのですが、残念ながらローカルLLMだけでzoltraakを最後まで実行することはできませんでした。

絶対にオンプレミス環境で実行しなければならない、という特段の理由がない限りは、デフォルトで設定されているClaude APIを使うのが良さそう(品質、速度、成功率の観点で)だという結論です。

それと今回色々と試して、gemma2:27b-instruct-fp16やqwen2:72b-instruct-q4_K_Mも捨てたものではないというのがわかったことも価値があったと思います。

ここまで見ていただきありがとうございました。次回もぜひ、よろしくお願いします。

Discussion