2024.01.12

ローカル環境でコード生成を使いたい 〜Continue+Llama.cpp+ELYZA-japanese-CodeLlamaを試してみた〜

ご覧頂きありがとうございます。グループ研究開発本部 AI 研究開発室の N.M.と申します。
ChatGPTをはじめAIに関する大きなムーブメントの起きた激動の2023年が終わり、2024年が始まりました。我々AI研究開発室も日々AI技術を追いかけています。昨年から話題になることの多いGitHub Copilotもその一つであり、特にコードの補完は非常に使い勝手もよく開発や解析のサポートに使うことができます。今回はなるべくローカルに閉じた状態で近しい環境が作れないか試してみたことを紹介します。最後までご覧いただければ幸いです。

TL;DR

  • VSCodeのExtensionであるContinueとELYZA-japanese-CodeLlama-7b(+llama.cpp)を使って自然言語によるコード生成を試す
  • ある程度のスペックを持つPC、かつ初歩的なコードであればそこまでストレスなく自然言語よりコードを生成可能
  • ただEditは少し挙動が不安定で今ひとつ、コード補完がないためそこがネック、今後に大きく期待

動機

前述の通り、GitHub Copilotは非常に有用なツールであり、開発・解析の能率を大きく上げることができます。御多分に洩れず我々の部署でも導入が検討されましたがいくつかネックとなることがありました。

  1. タダではない
    当たり前ですが業務で使う場合は無料ではありません。1ユーザー当たり19USD/月(2024/1/12時点)の料金を払うからにはそれ相応のアウトプットが求められる訳で、規模の大きい会社だと割と渋られることも多いかと思います。

  2. 機密情報が混入する恐れがある
    まさかデータをそのまま突っ込むようなことはないと思いますが、金融系プロジェクトなどかなり高いセキュリティレベルを要求されるものではそもそもソースコード自体に機密情報が存在する可能性もあり、導入のハードルは高いです。

コードを書くのがそこまで得意ではないデータサイエンティストとしてはコードを書いている時間を短縮できればとても嬉しいのですが、上記などの理由から業務では利用できず、情報がマスクされているか気をつけながらChat GPTに聞いてブラウザとエディタをうろうろするような形でコーディングしています。

そのため、他サーバとの通信せずにローカルマシン上でGitHub Copilotのようなコード生成機能を実現することができれば情報漏洩のリスクが下がる(かもしれない)上にタダです(もちろん手元のPCのパワーに左右されますが…)。今回のブログでは、上述のようにいちいちブラウザとエディタを右往左往しなくても済み、あわよくば開発・解析能率を上げるような形を実現できないか考えます。

今回利用するもの

上記のようなニーズを解決できる方法をリサーチしたところ、ContinueというIDE向け拡張機能を見つけました。このContinueはオープンソースで開発されており、現状は無料で利用することができます。この拡張機能は多くのLLM Providerに対応していて、OpenAI APIはもちろんLocal上でLLMを動かすことができるOllamaなどにも対応しています。今回のブログではこの拡張機能を試していきます。バージョンはv0.8.1です。

Continueの裏側で動かすProviderはLlama.cppを利用します。Llama.cppは、FacebookのLLaMAモデル(Large Language Model)をC/C++に移植したもので、GGUF形式と呼ばれるファイルに変換し量子化することでGPUを使用することなく実行することが可能にしたものです。もともとはただCPUのみで実行できるように作られたライブラリだったようですが、現在は開発が進み簡単なAPIサーバーとして利用することができるようになっています。このLlama.cppはContinueでもサポートされており、これがLocalでモデルを動かせる肝になっています。バージョンは

またLlama.cppのサーバーモードで動かすモデルに関してはELYZA-japanese-CodeLlama-7b-instructを利用しました。これは特に強い理由はないです(強いていうのであれば日本語でプロンプトを入力してコーディングしたいからです)。公式的にはContinueもLlama.cppもサポートしているとは書かれていないですが、もともとLlama.cppでサポートされていたGGML形式と比べより汎用的に利用・変換できるGGUF形式に変換することで問題なく使用することができました。

以上のライブラリを利用して試していきます。実行するのは会社で使っているMacbook Pro(M2 Pro, 32GB)です。

準備する

まずはLlama.cppの準備をします。
GitHubからcloneしてきたものをmakeして変換に必要なPythonのライブラリをinstallします。

git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp make python3 -m venv venv . venv/bin/activate pip install -r requirements.txt

Llama.cpp周りの準備が終わったあと、ELYZAのモデルをダウンロードし、Llama.cppで実行できるように変換します。

cd models git clone https://huggingface.co/elyza/ELYZA-japanese-CodeLlama-7b-instruct python3 convert.py --outfile models/elyza-codellama.gguf models/ELYZA-japanese-CodeLlama-7b-instruct ./quantize models/elyza-codellama.gguf models/elyza-codellama_Q4_K_M.gguf Q4_K_M

ここまで完了したらVSCode側の設定に入ります。マーケットプレイスからContinueをinstallします。インストール後、設定の変更を行います。設定変更のためのファイルは~/.continueにあります。

(venv) user .continue % tree . ├── config.js ├── config.json ├── config.node.js ├── config.ts ├── dev_data ├── diffs ├── node_modules ├── sessions └── tsconfig.json

過去のバージョンではconfig.pyというPythonファイルがあり、ここに設定を書いていく形式を採用したようでしたが、現在は設定をなるべくconfig.jsonにまとめる動きがあるようです。config.jsonの中身はデフォルトで以下のようになっています。

{ "models": [ { "title": "GPT-4", "provider": "openai-free-trial", "model": "gpt-4" }, { "title": "GPT-3.5-Turbo", "provider": "openai-free-trial", "model": "gpt-3.5-turbo" } ], "slashCommands": [ { "name": "edit", "description": "Edit highlighted code" }, { "name": "comment", "description": "Write comments for the highlighted code" }, { "name": "share", "description": "Download and share this session" }, { "name": "cmd", "description": "Generate a shell command" } ], "customCommands": [ { "name": "test", "prompt": "Write a comprehensive set of unit tests for the selected code. It should setup, run tests that check for correctness including important edge cases, and teardown. Ensure that the tests are complete and sophisticated. Give the tests just as chat output, don't edit any file.", "description": "Write unit tests for highlighted code" } ], "contextProviders": [ { "name": "diff", "params": {} }, { "name": "open", "params": {} }, { "name": "terminal", "params": {} } ] }

models はproviderを設定する部分で、デフォルトではOpenAI APIになっています。今回はここに下記のような記述を追加します。titleは任意、providerは"llama.cpp"、modelは値によってプロンプトのテンプレートが決定され、変な値や実装の分岐に含まれないような文字列を指定するとプロンプトのフォーマットが変になってしまうため、今回はllamaとしておきます。apiBaseはlocalhostを指定して完了です。

"models": [ { "title": "Llama CPP", "provider": "llama.cpp", "model": "llama", "apiBase": "http://localhost:8080" }, ... ],

slashCommandsはハイライトしたコードの修正やコメントの追加特定の操作を表すコマンドです。config.tsを編集することでよりカスタマイズすることができるようですが、今回は割愛します。また、customCommandsで上記のslashCommandsで実装しなくてもプロンプトに入力する感覚でカスタムコマンドを実装することができます。

contextProvidersはファイルやissueなど前提知識となるものをContextとして含めることができます。これにより、空のファイルを指定して/editして新しいファイルを作成することができます。Pluginとして扱っているようでデフォルトではgitのdiff、ファイル、terminalの3つが指定されています。必要であれば以下のように追加していきます(urlを追加しています)。

"contextProviders": [ { "name": "diff" }, { "name": "open" }, { "name": "terminal" }, { "name": "url"} ]

また、continueではライブラリの改善のために使用状況を収集しているようです。これを止めたい場合は以下のようにconfig.jsonに記述します

"allowAnonymousTelemetry": false

以上を踏まえた上でllama.cppの簡易APIサーバーを立てて準備は完了です。

./server -m models/elyza-codellama_Q4_K_M.gguf -c 2048

実際に動かす

それでは実際に動かしていきます。
(もちろんLLMなので、この結果に辿り着くまでに何度か試しているのは事実ですが、それはご愛嬌ということで…)

ソースコードを自然言語で聞く

まずはChatGPTの代替になるような、自然言語でソースコードの書き方を聞いてみます。

この使い方であれば、生成スピードに関してはストレスにならない程度にはスムーズで十分実用に耐えると思っています。

コードの一部を選択して修正する

次にハイライトしたコードの修正を行います。

それっぽい形で書いてはくれていますが、おそらくレスポンスのコードブロックの言語の部分(python)も一緒に生成されてしまっている他、構文エラーもあります。試してみるとeditに関しては結構構文エラーが多く、相当簡単なロジックでないと対応することは厳しそうです。

テストコードを書く

次に関数を選択してテストコードを生成してもらいます。

今回のケースは非常に単純なものではあるのですが、サクッとコードを生成してもらえるのは面倒ごとが省けて助かります。customCommandsを工夫すれば実際にコードを直接書いてもらえるかもしれません。

0からコードを生成する

最後に、空のファイルを指定して0からコードを生成してもらいます。

(面白いかは別として)それっぽいコードは生成されました。やはりeditコマンドによるものなので挙動が不安定ではあります。

まとめ

今回はVSCodeの拡張機能であるContinueをLlama.cppとELYZA-japanese-CodeLlama-7bを裏側として試してみました。生成速度に関しては7Bの量子化モデルであればそれほど気になるものではなく、十分に実用に耐えうると感じました。生成されたコードを完全には信用せずに、continueのdocsにもある通り、あくまで開発・解析の補助として利用する分には問題ないかと思います。

一方で、コード修正に関してはまだまだ精度は悪く、改善の余地がありました。コードの入力補完に該当する機能もなく、GitHub Copilotほどの有用性は現時点ではなさそうです。特に入力補完に関しては今後に大きく期待したいです。

またtelemetryに関しても懸念があり、ローカルに完結させる動機の一つである機密情報の漏えいリスクに関しては把握しておく必要があります。ただ、オープンソースであるためどこにtelemetryに関するコードがありどのように取得しているのかは確認できるため対策のしようはあるかもしれません。最後までご覧いただきありがとうございました。

最後に

グループ研究開発本部 AI 研究開発室では、データサイエンティスト/機械学習エンジニアを募集しています。ビッグデータの解析業務など AI 研究開発室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集職種一覧からご応募をお願いします。皆さんのご応募をお待ちしています。

  • Twitter
  • Facebook
  • はてなブックマークに追加

グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。

 
  • AI研究開発室
  • 大阪研究開発グループ

関連記事