Sponsored
GPUなしのVPS上に、Ollama と軽量なローカルLLMを構築した記録です。今回は「中国製モデルは避けたい」「日本語に強いものがよい」という条件で、ELYZA 系の日本語モデルを採用しました。
6 vCPU / 11 GiB RAM / GPUなし のVPSでも、短文用途なら十分実用になります。
一方で、長文生成はCPU推論なので重く、初回ロードは特に待ち時間が出ます。
今回の構成
| 項目 | 内容 |
|---|---|
| OS | Ubuntu系 Linux |
| サーバー | GPUなし VPS |
| CPU | 6 vCPU |
| メモリ | 11 GiB |
| ディスク | 約 99 GiB |
| ランタイム | Ollama 0.17.7 |
| モデル | elyza/Llama-3-ELYZA-JP-8B-GGUF の q4_k_m |
| Ollama上のモデル名 | elyza-jp-lite |
このモデルを選んだ理由はシンプルです。
- ELYZA は日本企業で、中国系モデルを避けたい条件に合う
- 日本語寄りの調整が入っていて、汎用軽量モデルより日本語用途に向く
q4_k_mのGGUFなら、CPU-onlyでも現実的に動かせるサイズだった
先に結論
この構成でできたことは次の通りです。
Ollamaをsystemd管理で常駐化127.0.0.1:11434のみにバインドしてローカル限定公開ELYZAのGGUFモデルを取り込みOLLAMA_KEEP_ALIVE=-1で常時ウォーム状態に変更- 短い日本語プロンプトで応答確認
常時ウォーム後は、X投稿程度の短文ならかなり使いやすくなります。
ただし「一瞬で返る」というより、「初回ロードの重さを避けられる」という理解が正確です。
正常系の構築手順
1. サーバー資源を確認する
まずは本当に載るかを確認します。
uname -a
free -h
df -h /
nproc
今回のサーバーでは、モデル常駐後でも1本なら十分回せる見込みでした。
ただし複数モデル常駐は厳しめです。
2. Ollama本体をインストールする
公式配布のLinuxバイナリを使います。
curl -fsSL https://ollama.com/download/ollama-linux-amd64.tar.zst | sudo tar —zstd -x -C /usr
インストール確認:
/usr/bin/ollama —version
3. 専用ユーザーを作る
root 直実行ではなく、専用の ollama ユーザーで管理した方が扱いやすいです。
sudo useradd —system —create-home —home-dir /usr/share/ollama —shell /usr/sbin/nologin ollama
4. systemdサービスを作る
今回は外部公開せず、127.0.0.1:11434 だけで待ち受ける構成にしました。
/etc/systemd/system/ollama.service
[Unit]
Description=Ollama Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=ollama
Group=ollama
Environment="HOME=/usr/share/ollama"
Environment="OLLAMA_HOST=127.0.0.1:11434"
Environment="OLLAMA_KEEP_ALIVE=-1"
ExecStart=/usr/bin/ollama serve
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
反映
sudo systemctl daemon-reload
sudo systemctl enable --now ollama.service
sudo systemctl status ollama.service --no-pager
5. モデルをダウンロードする
GGUFの保存先を作って、ollama ユーザーで取得します。
sudo install -d -o ollama -g ollama /usr/share/ollama/import
sudo -u ollama curl -L --fail --progress-bar \
-o /usr/share/ollama/import/Llama-3-ELYZA-JP-8B-q4_k_m.gguf \
https://huggingface.co/elyza/Llama-3-ELYZA-JP-8B-GGUF/resolve/main/Llama-3-ELYZA-JP-8B-q4_k_m.gguf
このファイルは約 4.9 GB あります。 回線が遅い環境だと、ここが一番時間のかかる工程です。
6. Modelfileを作る
モデル名を分かりやすくするため、Modelfile を作って Ollama に取り込みます。
FROM /usr/share/ollama/import/Llama-3-ELYZA-JP-8B-q4_k_m.gguf
PARAMETER num_ctx 4096 PARAMETER temperature 0.6
SYSTEM あなたは簡潔で実務的な日本語アシスタントです。特に指定がない限り日本語で回答し、根拠が弱い場合は推測だと明示してください。
例えば /usr/share/ollama/import/Modelfile.elyza-jp-lite に置きます。
7. Ollamaへモデル登録する
sudo -u ollama env OLLAMA_HOST=127.0.0.1:11434 \
/usr/bin/ollama create elyza-jp-lite \
-f /usr/share/ollama/import/Modelfile.elyza-jp-lite
登録確認
sudo -u ollama env OLLAMA_HOST=127.0.0.1:11434 /usr/bin/ollama list
期待する結果のイメージ
NAMEIDSIZE elyza-jp-lite:latestxxxxxxxxxxxx4.9 GB
8. 動作確認する
まずは短い日本語で疎通確認します。
sudo -u ollama env OLLAMA_HOST=127.0.0.1:11434 \
/usr/bin/ollama run elyza-jp-lite \
"ローカルLLMを127.0.0.1だけで待ち受ける利点を、日本語で一文で説明してください。"
ロード状態も確認できます。
sudo -u ollama env OLLAMA_HOST=127.0.0.1:11434 /usr/bin/ollama ps
セキュリティです、的な応答がありました。
運用上のポイント
localhost限定にした理由
今回は 127.0.0.1:11434 に限定しました。
理由は単純で、Ollama APIをそのまま外部公開するのは雑だからです。 外から使いたいなら、別途次のような層を挟む方が安全です。
- 認証付きのリバースプロキシ
- Cloudflare Tunnel
- Tailscale
- SSHトンネル
とりあえずローカル限定にしておけば、事故率はかなり下がります。
常時ウォーム化は有効
OLLAMA_KEEP_ALIVE=-1 を設定すると、一度ロードされたモデルが常駐します。 これで「最初だけ異様に遅い」問題がかなり緩和されます。
確認コマンド:
sudo -u ollama env OLLAMA_HOST=127.0.0.1:11434 /usr/bin/ollama ps
常駐していれば UNTIL が Forever になります。
実際に詰まったポイント
ここからが本題です。 正常系だけ書くと簡単そうに見えますが、実際にはいくつか引っかかりました。
1. tar で展開時に —zstd が必要だった
最初に次のように実行すると失敗しました。
curl -fsSL https://ollama.com/download/ollama-linux-amd64.tar.zst | sudo tar x -C /usr
エラー
tar: Archive is compressed. Use —zstd option
修正版はこちらです。
curl -fsSL https://ollama.com/download/ollama-linux-amd64.tar.zst | sudo tar —zstd -x -C /usr
.tar.zst なので当然ではあるのですが、つい -x だけで通ると思って詰まりました。
2. Modelfileを ollama ユーザーが読めなかった
最初は Modelfile をホーム配下に置いて、こんな感じで作ろうとしました。
sudo -u ollama env OLLAMA_HOST=127.0.0.1:11434
/usr/bin/ollama create elyza-jp-lite
-f /home/username/work/local-llm/Modelfile.elyza-jp-lite
すると権限エラーになりました。
Error: stat /home/username/work/local-llm/Modelfile.elyza-jp-lite: permission denied
原因は、sudo -u ollama で実行しているのに、ホーム配下の権限が閉じていたことです。 これは Modelfile を /usr/share/ollama/import に置き直して解決しました。
3. GGUF本体も「誰が読むか」を揃えた方が安全だった
モデル取り込み時は、クライアント実行ユーザーとファイル所有者がズレると面倒です。 今回のように最初から以下を統一しておくとトラブルが少ないです。
| 項目 | 内容 |
|---|---|
| 保存先 | /usr/share/ollama/... |
| 所有者 | ollama:ollama |
| 実行ユーザー | sudo -u ollama |
4. サービス再起動直後に叩くと、たまに早すぎる
systemctl restart ollama.service の直後にすぐ ollama run すると、起動直後のタイミングで失敗することがありました。
Sponsored
たとえばこういう系です。
Error: could not connect to ollama server, run ‘ollama serve’ to start it
実際にはサービスは立ち上がっていて、ほんの少し待てば問題ありません。 この手の処理は以下のようにすると安定します。
sudo systemctl restart ollama.service sleep 2 sudo -u ollama env OLLAMA_HOST=127.0.0.1:11434 /usr/bin/ollama ps
5. 「短文を作って」と言っても、モデルは長めに話しがち
これはエラーではないですが、運用上の詰まりポイントでした。
たとえば「X向け140字前後で」と投げても、モデルによっては必要以上に長く説明し始めます。 そのため、実運用では次のような工夫が必要です。
- 「140字以内」
- 「1文だけ」
- 「箇条書き禁止」
- num_predict を絞る
- 定型の短文プロンプトを用意する
つまり、モデルを入れただけで即SNS運用に使えるわけではなく、出力制御の設計は別途必要です。
性能感
このVPSでは、初回ロード込みの短文生成は約30秒かかりました。 一方、ロード済み状態では短い応答がかなり速くなります。
体感としてはこんな感じです。
| 条件 | 体感 |
|---|---|
| 初回ロード直後 | 重い |
| ウォーム状態の短文 | 十分実用 |
| X投稿サイズ | 下書き用途なら問題なし |
| 長文生成 | まだ重い |
重要なのは、「常時ウォームでコールドスタートを避ける」ことです。 CPU-only環境では、ここをやるだけで使い勝手がかなり変わります。
不要ファイルの整理
ollama create 後は、元のGGUFを必ずしも残す必要はありません。 ディスク節約のため、取り込み後に削除してもよいです。
sudo rm -f /usr/share/ollama/import/Llama-3-ELYZA-JP-8B-q4_k_m.gguf sudo rm -f /usr/share/ollama/import/Modelfile.elyza-jp-lite
Ollama内部ストア側に取り込み済みなら、通常利用には問題ありません。
まとめ
GPUなしVPSでも、Ollama + 軽量GGUFモデル で日本語ローカルLLMは十分構築できます。 今回の条件なら、ELYZA 系はかなり素直な選択でした。
ポイントをまとめると次の通りです。
- 日本語重視なら、日本語寄りモデルを選ぶ
- localhost 限定で始める
- systemd 管理にする
- モデル所有者と実行ユーザーを揃える
- OLLAMA_KEEP_ALIVE=-1 でウォーム状態を維持する
- 長文より、短文アシスト用途から始める
「VPSでローカルLLMを動かす」と聞くと大げさに見えますが、短文用途に割り切れば十分現実的です。 特に、下書き生成、要約、短文案出し、日本語の壁打ち用途にはかなり向いています。
次にやるなら、用途別にモデルやプロンプトを分けるのが良さそうです。
- X投稿用の短文プリセット
- 要約用プリセット
- サーバー内専用のAPIラッパー
- 認証付きの外部公開経路
ローカルLLMは「万能な本番AI」ではないですが、「自分のVPSで軽く使う道具」としてはかなり面白いです。