「2GBのVPSでローカルLLMは動くのか」。動きます。ただし0.5Bまでです。

0.5Bから1Bに上げた瞬間、生成速度が 15.36 tokens/秒 → 0.07 tokens/秒 に落ちました。219分の1です。段階的に遅くなるのではなく、崖から落ちます。

3Bはサービスごと落ちました。

結論

モデルファイルディスク増メモリピーク生成速度結果
qwen2.5:0.5b397MB+380MB930MB15.36 tok/s動く
llama3.2:1b1.3GB+1,260MB1,201MB(上限)0.07 tok/s実用不可
qwen2.5:3b1.9GB+1,840MB落ちた

必要メモリの目安は「モデルファイルの約2.4倍」。 0.5B(380MB)で930MBでした。

測定条件

  • サーバー:さくらのVPS 2Gプラン / Ubuntu 24.04 LTS(GPUなし・CPUのみ
  • Ollama:0.33.3
  • :systemdの MemoryMax=1200M / MemorySwapMax=1024M でOllamaを隔離
  • 同居:定期的にデータを取得して予測を回すバッチ処理と、静的サイト1本が動いている実運用サーバー
  • プロンプト:「日本の首都はどこですか。一文で答えてください。」

同居しているものがあるので、free の全体値は他の処理の影響を受けます。そのため、Ollama単体の数字はすべてcgroup(memory.current)から取っています。

Ollama本体だけで、ディスク2.1GB・メモリ36MB

モデルを1つも入れていない状態です。

ディスク+2,160MB
常駐メモリ(cgroup)36MB
待ち受け127.0.0.1:11434

メモリは驚くほど軽い。 比較すると位置づけが分かります。

常駐メモリ
Ollama本体36MB
Docker(dockerd + containerd)約49MB
n8n402MB
Dify(16コンテナ)2,076MB

「AIツールは重い」わけではありません。重いのはモデルです。

ただしディスクは2.1GB持っていきます。CPUしかないVPSでも、GPU用のライブラリを含めて配布されるためです。

インストールで2時間失った話

ここが実用上いちばん引っかかる場所です。

公式の手順はこれです。

curl -fsSL https://ollama.com/install.sh | sh

これを実行したところ、89分かけて55.6%で切れました。

curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now

やり直しです。 インストールスクリプトは curl | zstd -d | tar -x と直結していて、ダウンロードしながら展開しています。 そのため途中で切れても再開できません。

配布物は 1,433,825,108バイト(1.34GB)。一発勝負で落とし切る必要があります。

落としてから展開すれば2分

同じファイルが GitHubのリリースにあります。wget -c で落としました。

wget -c --tries=0 --waitretry=15 --timeout=60 \
  https://github.com/ollama/ollama/releases/download/v0.33.3/ollama-linux-amd64.tar.zst
2026-09-07 20:55:24 (11.3 MB/s) - saved [1433825108/1433825108]

2分1秒で完了しました。

wget -c を使う理由は2つあります。

  • -c は途中から再開できる。 切れても最初からになりません
  • wgetはHTTP/1.1しか使わない。 今回の HTTP/2 PROTOCOL_ERROR は起きません

落としたら、壊れていないか確認してから展開します。

zstd -t ollama-linux-amd64.tar.zst          # 圧縮ファイルの検証
sudo install -o0 -g0 -m755 -d /usr/local/bin /usr/local/lib/ollama
sudo tar --zstd -xf ollama-linux-amd64.tar.zst -C /usr/local

展開は10.9秒でした。

原因は特定できていません。 失敗の直後(20:52)に同じ ollama.com のURLへ curl を投げたら 10.8 MB/s 出ました。つまり配布元が常に遅いわけではありません。あの時間帯だけ経路が細かった可能性が高いですが、確証はありません。

ただし対処法は原因に関係なく有効です。1.34GBを一発勝負で落とす構造そのものが弱い。 落としてから展開してください。

サービス化は自分で書きます。

sudo useradd -r -s /bin/false -U -m -d /usr/share/ollama ollama
sudo tee /etc/systemd/system/ollama.service > /dev/null <<'EOF'
[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=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Environment="OLLAMA_HOST=127.0.0.1:11434"

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable --now ollama

OLLAMA_HOST=127.0.0.1:11434 を明示しています。 Ollamaに認証はありません。外に開くと誰でもモデルを叩けます。既定値も同じですが、意図として書き残します。

0.5B:動く。ただし日本語は怪しい

ollama pull qwen2.5:0.5b     # 38.6秒
モデル表示サイズ397MB
ディスク実増+380MB
メモリピーク(cgroup)930MB
ロード時間3.18秒
プロンプト処理59.67 tok/s
生成速度15.36 tok/s
枠に当たった回数0

15 tokens/秒。 短い応答なら待てる速度です。1,200MBの枠にも当たっていません。

ただし出力がこれでした。

日本の首都は东京です。

「東京」が簡体字の「东京」になっています。 中国語圏で作られた小型モデルなので、日本語の中に簡体字が混ざります。動くことと使えることは別という、分かりやすい実例です。

ollama list の「397MB」と df の「380MB」がずれるのは、Ollamaが10進のMB、du/df が2進のMiBで表示しているためです。同じ値です。)

1B:ここが崖

ollama pull llama3.2:1b      # 2分4秒
ディスク実増+1,260MB
メモリピーク1,201MB(上限に張り付き)
枠に当たった回数50,879回
ロード時間43.6秒
プロンプト処理2.60 tok/s
生成速度0.07 tok/s
全体の所要時間3分0.7秒

9トークンの返事に3分かかりました。

そのときのサーバーの状態です。

空きメモリ    25MB
スワップ      1,304MB
I/O待ち       最大86%
ロード        3.8

Difyを2GBに載せたときとまったく同じ形です。枠の中でページを出し入れし続けるスラッシングが起きています。

答え自体は正しく出ました。

日本の首都は東京です。

0.5Bの簡体字混入がなく、日本語として正しい。品質は上がっています。速度が実用の範囲外なだけです。

3B:落ちる

ollama pull qwen2.5:3b       # 2分56秒、ディスク +1,840MB
ollama run qwen2.5:3b "..."
Error: Post "http://127.0.0.1:11434/api/generate": EOF

サービスが死にました。 10秒刻みの記録に、その瞬間が残っています。

21:38:42  cgroup 1,200MB  スワップ 861MB   ← 限界
21:38:46  cgroup     0MB  スワップ   0MB   ← 消滅
21:38:50  cgroup    37MB                  ← 再起動後

systemctl show ollama -p NRestartsNRestarts=1。systemdが1回再起動しています。

死因は特定できませんでした。 カーネルのOOM記録(journalctl -k)には何も残っておらず、cgroup内の oom_kill カウンタはサービス再起動時に作り直されてリセットされています。枠の中でOOMになった可能性が高いと考えていますが、証拠はありません。

実用上の結論は変わりません。動きませんでした。

メモリの目安:モデルファイルの約2.4倍

0.5Bの実測から出た倍率です。

モデルファイル 380MB → 実際のピーク 930MB(2.4倍)

この倍率で逆算すると、1Bのモデル(1,260MB)には約3,000MB必要になります。1,200MBの枠に入るはずがありません。 実測と一致します。

つまり、使えるモデルの上限はこう決まります。

載せられるモデルファイル ≒ 空きメモリ ÷ 2.4

空きが1.4GBなら 約580MB以下のモデルまで。0.5Bクラスだけです。

(cgroupの memory.current にはモデルファイルのページキャッシュも含まれるため、この2.4倍にはキャッシュ分が乗っています。「アプリが確保した量」より大きめの数字である点は割り引いて読んでください。)

2GBのVPSで、ローカルLLMをやるべきか

やれること

  • 0.5Bクラスのモデルが15 tok/sで動く。分類・要約・単純な抽出なら実用範囲
  • Ollama本体は36MBしか常駐しない。使わないときのコストはほぼゼロ
  • モデルを止めればメモリはすぐ戻る

やれないこと

  • 1B以上は無理。 0.07 tok/sは待てる速度ではありません
  • 日本語の品質を求めるなら0.5Bでは足りない(簡体字が混ざる)
  • ディスクは本体2.1GB+モデル。 3つ入れたら3.4GBでした

実際にやるなら

必要なのは「メモリ ÷ 2.4」の計算だけです。

空きメモリ載せられるモデル現実的な用途
1.4GB(2GBプラン)〜580MB(0.5Bクラス)分類・抽出。日本語の生成は厳しい
3GB前後(4GBプラン)〜1.2GB(1Bクラス)未検証
7GB前後(8GBプラン)〜2.9GB(3Bクラス)未検証

下2行は測っていません。 上の倍率からの計算です。実測したら追記します。

そして忘れてはいけないのは、GPUがないことです。上の速度はすべてCPUでの推論です。GPU付きの環境とは桁が違います。

まとめ

  • Ollama本体:メモリ36MB / ディスク2.1GB。デーモンはDockerより軽い
  • 0.5B(380MB):15.36 tok/s で動く。 ただし日本語に簡体字が混ざる
  • 1B(1.3GB):0.07 tok/s。 219分の1に落ちる。9トークンに3分
  • 3B(1.9GB):サービスが落ちる(死因はログに残らず)
  • 必要メモリ ≒ モデルファイル × 2.4
  • 公式インストールスクリプトはレジュームできない。 1.34GBを一発勝負。wget -c で落としてから展開すれば2分
  • 2GBのVPSでローカルLLMをやるなら、0.5Bクラスが上限

「動くか動かないか」ではなく、どこで崖が来るかが分かりました。0.5Bと1Bの間です。

VPSのプラン選びについては、実測から積み上げた選び方にまとめています。