コーディング支援AIツールContinueの紹介と構成例

Continueというコーディング支援AIツールの紹介です。

コーディング支援AIツール・サービスとしてはGitHub Copilotが有名で、次いでCursorやCodeiumあたりが話題性のあるところかと思います。Publickeyに2024年3月時点での情報がまとまっています。

https://www.publickey1.jp/blog/24/aigithub_copilotaws_codewhisperer1120243.html

Continueはそれらと比べて知名度は劣りますが以下のような特徴があり、うまく使いこなせば有力な選択肢になると考えています。

- ツール本体がオープンソースである
Visual Studio CodeとJetBrains IntelliJ IDEAの拡張機能がApache License, Version 2.0で提供されています

- 言語モデルは自分で選ぶ
Continueではコード補完用とチャット用で二つの言語モデルを利用しますが、そこでどの言語モデルを選ぶかは利用者側に任されています

Continueを開発しているのはシリコンバレーのスタートアップ企業[Continue社](https://continue.dev)です。Continue社はツール本体をオープンソースで普及させて、言語モデルを顧客ごとにカスタマイズしていくところをビジネスにしようとしているそうです。頑張ってほしいです。

# Continueの使用例

## コード補完

Visual Studio Codeでの使用例です。画像の赤枠部分でコード補完が行われています。すぐ上にある`restoreOptions`ファンクションの定義を参考にして、それに対応するコードを補完していることが分かりますね。

![Completion 1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/c660d8e9-f8a2-eb22-f990-b5b32c0a5b81.png)

この例ではTabキーを押していくだけでコードが完成しました。

![Completion 2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/269caef7-68a2-78cc-ca66-3774f4c949d9.png)

ちなみにGitHub Copilotでもまったく同じコードが補完されました。こちらは6行まとめて補完してくれるのでContinueより少し賢いです。

![Completion 3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/c91bcf03-d127-7f6c-946d-8b899af08a45.png)

## チャット

コードに関する質問をチャット形式で行うことができます。

![Chat 1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/b7dff85b-63c5-42b6-105e-dc28a7115c87.png)

これもGitHub Copilotとよく似ています。

![Chat 2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/d6af7c2b-d604-6f31-2118-bca3c5dcaf04.png)

これがオープンソースソフトウェアだというのですから驚きです。ただこのようにContinueを使える状態まで持っていくには少々手間がかかるため、本記事でみなさんの手間を減らしていければと思います。

# Continueの構成例

以下の前提条件で構成をまとめました。

- NVIDIAのGPUを搭載したWindows PCを用意します。これをPC01とします
- Visual Studio CodeをインストールしたPC/Macを用意します。これをPC02とします
- コード補完用の言語モデルはローカルに用意します
- チャット用の言語モデルはクラウドサービスを利用することにします

構成図を以下に示します。

![environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/5fedf70d-0654-0124-4f68-cb5bc157c9be.png)

## コード補完用の言語モデル

今回の構成ではコード補完用の言語モデルをローカルに用意します。Continueでコード補完を行うにはFill in the Middleというタスクを解く特殊な学習を施した言語モデルが必要なのですが、これをAPIで提供するクラウドサービスが存在しないためです。Fill in the MiddleについてはCodeiumの記事をご参照ください。

https://codeium.com/blog/why-code-completion-needs-fill-in-the-middle

幸い最近はFill in the Middleに対応したコンパクトで高性能なコード補完用の言語モデルがいくつかリリースされています。

- [DeepSeek Coder](https://deepseekcoder.github.io/) 1.3B/5.7B/6.7B/33B
- [StarCoder2](https://huggingface.co/blog/starcoder2) 3B/7B/15B
- [Stable Code](https://ja.stability.ai/blog/stable-code-3b) 3B

2024年2月に公開された[StarCoder2の論文](https://arxiv.org/html/2402.19173v1)によると、DeepSeek Coder 6.7Bがモデルサイズに対して優れた性能を示しているようです。70億パラメーターの言語モデルは4ビット量子化することでVRAM 8GB程度のGPUで動かすことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/1658cc0a-f27f-7629-3146-d90c5b243ca1.png)

DeepSeek CoderとStarCoder2は研究目的と商用利用のいずれも無料、Stable Codeは商用利用をする場合Stability AIメンバーシップの契約が必要です。ライセンスについては利用前に必ず確認してください。

## チャット用の言語モデル

チャット用の言語モデルはクラウドサービスを利用します。2024年4月時点では、一般消費者向けGPUのVRAMに収まる実用的な言語モデルはまだないという認識です。今後の技術革新に期待しましょう。

Continueにはあらかじめ[Model Provider](https://continue.dev/docs/model-setup/select-provider)が定義されていて有名どころのサービスは網羅されています。自由に選んでいただいてよいのですが、個人的には以下の二つをおすすめします。

- Google Gemini 1.0 Pro
そこそこのコンテキスト長があり、応答が早いです。最も大きな特長はAPIを無料で利用できるところです。当初無料プランは2024年初頭までの予定でしたが、2024年4月に無料/有料二つのプランで継続されるとの案内がありました。なお無料プランの場合は送信したデータが言語モデルの学習に利用されるので注意してください。

- Anthropic Claude 3
Haiku/Sonnet/Opusと性能・コストのバランスが異なる三つの言語モデルが提供されており、最上位のOpusはOpenAI GPT-4 Turboを上回るという高性能言語モデルです。まずHaikuに質問して、分からなければSonnetに、それでも分からなければOpusに、と使っていくとコストパフォーマンスが良いです。

# Continueの環境構築

詰まりそうなポイントに絞って解説します。

## CUDA on WSL2の導入

Windowsから直接CUDAを利用するのは何かと苦労が多いのでWSL2経由で利用します。導入にあたっては以下の公式サイトを見ながら作業することをおすすめします。古いブログ記事などを見てしまうとかえって混乱してしまいがちです。

https://docs.nvidia.com/cuda/wsl-user-guide/index.html

導入に成功するとWSL2で`nvidia-smi`コマンドが使えるようになります。

```
$ nvidia-smi
Thu Apr  4 14:59:29 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.65                 Driver Version: 551.86         CUDA Version: 12.4     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4070 ...    On  |   00000000:07:00.0 Off |                  N/A |
|  0%   30C    P8              1W /  220W |       0MiB /  12282MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+
```

## OllamaとDeepSeek Coderの導入

[Ollama](https://ollama.com/)とは各種言語モデルをローカルで実行するためのオープンソースソフトウェアです。インストールはコマンド一つ、言語モデルはOllamaコミュニティで最適化したものが[用意されている](https://ollama.com/library)ので選ぶだけ、[REST APIも利用可能](https://github.com/ollama/ollama/blob/main/docs/api.md)と至れり尽くせりです。Ollamaの導入は簡単なので説明は割愛します。

DeepSeek Coderの導入には一つ注意点があって、言語モデルとして`deepseek-coder:6.7b`ではなく`deepseek-coder:6.7b-base`を選ぶ必要があります。`6.7b`は`6.7b-instruct`のエイリアスとなっており、これは自然言語からコードを生成する指示学習済み言語モデルですので利用用途が異なります。

## ネットワークの設定

PC02からPC01内のWSL2で稼働するOllama APIサーバーへ接続するために、いくつかネットワークの設定が必要です。構成図を再掲します。

![environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/5fedf70d-0654-0124-4f68-cb5bc157c9be.png)

### Ollamaのネットワーク設定

Ollama APIサーバーは初期設定で`localhost`からの接続しか許可しません。これを変更するためsystemdユニットファイルのServiceセクションに`Environment="OLLAMA_HOST=0.0.0.0"`を追記してください。

```unit-file:/etc/systemd/system/ollama.service
[Unit]
Description=Ollama Service
After=network-online.target

[Service]
ExecStart=/usr/local/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=3
Environment="PATH=/home/taira/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib:/mnt/c/Program Files/WindowsApps/CanonicalGroupLimited.Ubuntu22.04LTS_2204.3.63.0_x64__79rhkp1fndgsc:/mnt/c/WINDOWS/system32:/mnt/c/WINDOWS:/mnt/c/WINDOWS/System32/Wbem:/mnt/c/WINDOWS/System32/WindowsPowerShell/v1.0/:/mnt/c/WINDOWS/System32/OpenSSH/:/mnt/c/Program Files/dotnet/:/mnt/c/Program Files (x86)/NVIDIA Corporation/PhysX/Common:/mnt/c/Users/taira/AppData/Local/Microsoft/WindowsApps:/mnt/c/Users/taira/AppData/Local/Programs/Microsoft VS Code/bin:/mnt/c/Users/taira/.dotnet/tools:/mnt/c/Users/taira/AppData/Local/Microsoft/WindowsApps:/snap/bin"
Environment="OLLAMA_HOST=0.0.0.0"

[Install]
WantedBy=default.target
```

サービスを再起動するとOllama APIサーバーの待ち受けアドレスが`127.0.0.1`から`*`に変わっていることが確認できます。

```bash
$ sudo ss -anpt
State     Recv-Q    Send-Q       Local Address:Port          Peer Address:Port    Process
LISTEN    0         4096             127.0.0.1:11434              0.0.0.0:*        users:(("ollama",pid=21603,fd=3))
$ sudo systemctl daemon-reload
$ sudo systemctl restart ollama
$ sudo ss -anpt
State    Recv-Q   Send-Q     Local Address:Port        Peer Address:Port   Process
LISTEN   0        4096                   *:11434                  *:*       users:(("ollama",pid=9282,fd=3))   
```

これでまずPC01からOllama APIサーバーへ接続できるようになりました。PC01でコマンドプロンプトを開きcurlコマンドを用いて実際に接続できることを確認してください。

```console
PC01> wsl --distribution Ubuntu-22.04 hostname --all-ip-addresses
172.21.215.8

PC01> curl http://172.21.215.8:11434
Ollama is running
```

なおLinux版のOllamaインストーラーは`ollama.service`を上書きしてしまうため、Ollamaをバージョンアップした際は再度この設定を行う必要がある点に注意してください。

### Windowsのネットワーク設定

PC01のWindows Defenderファイアウォールを開いて詳細設定から「受信の規則」を右クリック、「新しい規則」を選択してTCP 11434番への通信を許可します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/f4ed3fdf-e5c1-2914-b1c5-493c70fa10cd.png)

次に、以下のPowerShellスクリプトを作成します。

```powershell:ollama.ps1
$ip = (wsl --distribution Ubuntu-22.04 hostname --all-ip-addresses).trimend()
netsh interface portproxy delete v4tov4 listenport=11434
netsh interface portproxy add v4tov4 listenport=11434 connectaddress=$ip
netsh interface portproxy show all
```

このPowerShellスクリプトを管理者権限で実行すると、PC01のTCP 11434番への通信がWSL2のTCP 11434番へ転送されるようになります。

```
ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               11434       172.21.215.8    11434
```

これでPC02からもOllama APIサーバーへ接続できるようになりました。PC02でコマンドプロンプトを開きcurlコマンドを用いて実際に接続できることを確認してください。

```console
PC02> curl http://PC01:11434
Ollama is running
```

WSL2のIPアドレスはPCを再起動すると変化することがあります。PCの再起動後はこのスクリプトを改めて実行するようにしてください。

今回示した構成では、PC01と同じネットワークにいるコンピューターはOllama APIサーバーにアクセスし放題となる点に注意してください。現在Ollamaに認証機能を設けることが[議論](https://github.com/ollama/ollama/issues/1053)されています。

## Continueの設定

Visual Studio Codeを立ち上げてマーケットプレースからContinueをインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/bf676aac-182d-5db5-b438-6a8d4689ff5b.png)

アクティビティバーのContinueアイコンをクリックし、下部の言語モデル追加ボタンをクリック、チャット用として追加したい言語モデルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/e2f6918b-2623-5b4c-cf8b-94356d4d210a.png)

コード補完用の言語モデルはバージョン0.8.23時点で設定画面がないので、Configアイコンをクリックして`config.json`ファイルを開き、`tabAutocompleteModel`プロパティに設定を書き込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216196/3d7b6073-a6e6-887f-b08c-684cfb250271.png)

これで環境構築は完了です。

# 今後の展望

Continueはまだ発展途上であり不具合が数多く見受けられます。Continueの[Discord](https://discord.gg/vapESyrFmJ)で活発に情報交換が行われているので、気になるところがあればぜひ参加してみてください。

業務での利用に向けては、複数の開発者がOllama APIサーバーを共有できるようにユーザー認証やログ分析などの仕組みを整えていく必要がありそうです。

チャット用の言語モデルについて今回はクラウドサービスを利用しましたが、ここにきて[Command R+](https://docs.cohere.com/docs/command-r-plus)というローカルで実行可能な高性能言語モデルが出てきました。今後PCのCPUやGPUの性能が大きく向上すればローカルでの実行が一般的になるかもしれません。楽しみですね。