kWatanabe 記事一覧へ

kWatanabe の 技術帖

某企業でOSや仮想化の研究をやっているインフラ系エンジニア。オンプレとクラウドのコラボレーションなど、興味ある技術を綴る。

LAN内にLLMサーバを立ててAIコーディングを行う

  • LinuxサーバにローカルLLMを導入し、WindowsマシンからGithub Copilotのように使ってみた
  • RTX 3080Ti のLLMサーバで1行の補完に数秒程度かかる。これが一般的なのかは不明

ローカルLLMでAIコーディングをしたいが、端末では動かしたくない

Github Copilot や Claude Code など、AIコーディングのプロダクトが流行している。調べてみると、ローカルLLMでもAIコーディングができるものがあるらしい。

しかし、全ての端末に GPU を積むことは現実的でないので、できればローカルLLMを動かすマシンを1台用意して、それを端末から使えるようにしておきたい。

そこで、ローカルLLMを提供するLLMサーバを構築することにした。

検証環境

LLMサーバ

クライアント

手順

ollama のインストールとサービス化

ローカルLLMネタとしては、10000番煎じくらいなのだが、ollama を導入する。

ollama.com

Webページには、よくある curlシェルスクリプトをダウンロードして、パイプで sh に流す手順が書いてあるが、導入先を自分で調整したいのでマニュアルでインストールする。

$ sudo mkdir -p /opt/ollama
$ cd /opt/ollama
$ wget https://ollama.com/download/ollama-linux-amd64.tgz
$ tar xf ollama-linux-amd64.tgz

次にサービス化するために、専用の実行ユーザを作成したうえで、systemd の unit ファイルを作成する。

$ sudo useradd -s /bin/false -d /opt/ollama -r ollama
$ sudo chown -R ollama:ollama /opt/ollama
$ sudo systemctl edit --full --force ollama.service
[Unit]
Description=Ollama LLM Service
After=network-online.target

[Service]
ExecStart=/opt/ollama/bin/ollama serve
User=ollama
Group=ollama
Restart=always
RestartSec=5
Environment="PATH=$PATH"
Environment="OLLAMA_HOST=0.0.0.0"
Environment="OLLAMA_ORIGINS=192.168.1.*"

[Install]
WantedBy=multi-user.target
  • 複数の NIC を搭載しているマシンで、 bind する NIC を限定したいならば OLLAMA_HOST にそのIPアドレスを設定する。
  • OLLAMA_ORIGINS には、LLMサーバに接続するマシンのIPアドレスを設定する。

サービスを起動し、クライアントから接続できることを確認する。

$ sudo systemctl daemon-reload
$ sudo systemctl start ollama
$ sudo systemctl status ollama
● ollama.service - Ollama LLM Service
     Loaded: loaded (/etc/systemd/system/ollama.service; disabled; preset: enabled)
     Active: active (running) since Sat 2025-07-12 08:47:46 JST; 3s ago
...
$ /opt/ollama/bin/ollama -v
ollama version is 0.9.0

更に、接続する予定のクライアントから、ollama に疎通できることを一緒に確認しておく。疎通できない場合は、 OLLAMA_HOSTOLLAMA_ORIGINS の設定に誤りが無いか、確認する。

C:\>curl http://<LLMサーバのIPアドレス>:11434/
Ollama is running

モデルの選定

クライアントには、Visual Studio Code で外部のコード生成AIを利用できるようにする Continue を用いる。

marketplace.visualstudio.com

Continue では、6種類のRoleごとにモデルを使い分ける。

Role 概要 Continue の中の人の推奨
Chat チャットのウィンドウから、人間がプロンプトを与えて利用するモデル - Llama 3.1 8B
- DeepSeek Coder 2 16B
Autocomplete エディタでコードを記述する際に、自動補完に利用するモデル 特になし
(Qwen 2.5 Coder 1.5B から初めてみてはとのこと)
Edit コードの編集画面に記載したコメント行から、ソースコードのベースを生成するモデル 特になし
Apply Editが生成したソースコードのベースを、実際にコードに反映する際に利用されるモデル - Morph Fast Apply
- Relace's Instant Apply
(共にクラウドサービス)
Embeddeding コード内での類似性検索を行う際に利用されるモデル - nomic-embed-text
Rerank ドキュメントやコメントと、実際のコードの関連性を評価する際に利用されるモデル - rerank-2
(クラウドサービス)

今回は、モデルのサイズと GPU の VRAM の容量から、以下のモデルを選定した。

Role 選定したモデル
Chat Llama 3.2 11B Vision
Autocomplete Qwen 2.5 Coder 14B
Edit 未指定 (未指定だと、Chatと同じモデルが利用される)
Apply 未指定 (未指定だと、Chatと同じモデルが利用される)
Embedded nomic-embed-text
Remarks 未指定 (未指定だと、無効になる)

モデルの導入

選定したモデルは、全て ollama のリポジトリに登録されているので、 ollama コマンドで導入できる。

$ /opt/ollama/bin/ollama pull llama3.2-vision:11b
$ /opt/ollama/bin/ollama pull qwen2.5-coder:14b
$ /opt/ollama/bin/ollama pull nomic-embed-text

クライアントの設定

まず、Visual Studio Code の Extensions から Continue - open-source AI code assistant をインストールする。

Continue拡張機能

次に、拡張機能の歯車アイコンから拡張機能の設定を起動し、Telemetry Enabled のチェックを外す。

Continueのテレメトリ設定

左側のアイコンリストに追加されている Continue のアイコンを押下して、Continue を起動し、Select modelModels と辿り、右側に小さく表示されている歯車アイコンを押下する。

モデルの設定ファイルを開く歯車アイコン

モデルの定義ファイルが開かれるため、Role ごとに利用するモデル名と、ollama の API エンドポイントを指定する。

name: Local Assistant
version: 1.0.0
schema: v1
models:
  - name: Llama 3.2 11B Vision
    provider: ollama
    model: llama3.2-vision:11b
    apiBase: http://<LLMサーバのIPアドレス>:11434/
  - name: Qwen 2.5 14b
    provider: ollama
    model: qwen2.5-coder:14b
    apiBase: http://<LLMサーバのIPアドレス>:11434/
    roles:
      - autocomplete
  - name: Nomic Embed Text
    provider: ollama
    model: nomic-embed-text
    apiBase: http://<LLMサーバのIPアドレス>:11434/
    roles:
      - embed
context:
  - provider: code
  - provider: docs
  - provider: diff
  - provider: terminal
  - provider: problems
  - provider: folder
  - provider: codebase

定義ファイルのより具体的な記述方法は以下を参照。

docs.continue.dev

試使用

チャット

Chat のプロンプトに自分が設定した Chat モデルの名称が表示されていることを確認する。

ContinueのChatウィンドウ

手始めに、 C 言語で、ユーザが入力した回数だけメッセージを表示する変則 Hello, World! を作らせてみる。

Chatから変則Hello,Worldの生成を依頼した結果

エラー処理もするようプロンプトに書いたので、 scanf() は最低限の保護はされているが、よく見ると入力した回数よりメッセージが 1 回多く表示される気がする。

また、解説文で scanf() の戻り値で数値であるかを判定するとあるものの、その解釈は誤っている。動作としては期待するものではあるのだが。

コード補完

右下の Continue ボタンを押下して、自分が設定した Autocomplete モデルが表示されることと、Autocomplete が有効になっていることを確認する。

Autocompleteの状態

適当にコードを入力したり、コメントを入力したりすると、数秒後に候補が半透明のフォントで表示されるため、そこで Tab を押下するとそれが入力される。

試しに、1行目に実装したい機能をコメントで記載して、Tab を連打すると以下のようになった。

// コンソールから数値を入力し、その数値の回数分だけ Hello, AI World! という文字列を出力するプログラム
#include <stdio.h>
int main() {
    int count;
    printf("Enter a number: ");
    scanf("%d", &count);
    for (int i = 0; i < count; i++) {
        printf("Hello, AI World!\n");
    }
    return 0;
}

入力のバリデーションがされていないので、コメントを追加して誘導する。

// コンソールから数値を入力し、その数値の回数分だけ Hello, AI World! という文字列を出力するプログラム
#include <stdio.h>
int main() {
    int count;

    // ユーザから数値を入力する. 値が間違っている場合はエラーとしてプログラムを終了する.
    printf("Enter a number: ");
    if (scanf("%d", &count) != 1 || count <= 0) {
        fprintf(stderr, "Invalid input. Please enter a positive integer \n");
        return 1;
    }

    // 入力された数値の回数分だけ "Hello, AI World!" を出力する
    for (int i = 0; i < count; i++) {
        printf("Hello, AI World!\n");
    }
    return 0;
}

それっぽい結果が得られた。

所感

実行中にサーバで nvidia-smi を実行していると、VRAM の消費量は 10GB 程度だった。Chat も Autocomplete も、 Continue が推奨するモデルより大型のものを使用しているので、もっと非力な GPU でもなんとかなるかもしれない。

ただ、RTX 3080Ti でも入力からコード補完まで数秒待たされるので、あまり非力な GPU だと使い物にならないかもしれない。

まとめ

  • RTX 3080Ti を搭載した Linux マシンを LLM サーバとして構築し、LAN 内から AI コーディングに使えるようにした。
  • VRAM の観点からはもう少し小型の GPU でも問題なさそうだが、応答速度の観点からはもっと強力な GPU だと幸せかもしれない。
  • 自分にAIコーディングの経験がないので、クラウドベースのAIコーディングと比べた際の品質はよく分からない。

 

*1:CPUがモバイル向けなのに eGPUが RTX 3080Ti なのは、MINISFORUM MS-A2に、PCIe-OCuLink変換アダプタを介して RTX 3080Ti を搭載しているため