能書き
前回まではForgejoをおうちサーバーで運用できる体制の構築と学習に向かっていた訳ですが。そしてそれはまだ道半ばではありますが。
ここらでちょっと方向転換して、私もAIコーディングを目指して勉強する事にしました。
とは言え、私の小遣いはショボいのです。LLMへの課金は避けたい所。そういうコスト的な事情からローカルLLMとOpenCodeの組合せでやってみる事にしました。
しかし私のマシンは、ローカルLLMで頑張るにはかなり非力です。メインメモリは何とか32GBですが、そもそもグラボを積んでいませんし。
GPUを使わずCPUのみだとスピードが十分の一以下になってしまうという話もありました。しかしスピードが十分の一なら時間を十倍掛ければ何とかなる!たぶん!おそらく!きっと!趣味ならそれも許されるでしょう!
と言う訳で、十倍の時間を動かし続けられる環境を作る事にしました。具体的には:
- 普段使いのノートパソコンではなくて、24時間電源入れっ放しにしているマシン(NUC13ANHI5000)にllama.cppを入れる
- AIエージェントもそのマシン上で動かして、人間が寝ている間も動かし続けられるようにする
そんな感じ。
Ollamaではなくてllama.cppを選択した理由は、少しでもメモリを有効活用する為です。Ollamaにしても実は単なるllama.cppのラッパーだという記事を見まして。llama.cppのインストールは多少大変なようですが、これも限られたリソースを最大活用する為です。頑張りました。とか言いつつ、手間を省く為にビルド済のものを利用してしまいましたが。
今回はまず、llama.cppを入れてLLMを選択しダウンロードする所までやってみます。実際には我が家のサーバーマシンはProxmoxVE(9.1.5)を入れてありまして、この上にコンテナを作ってそこへ放り込む事になります。
前提
- ハードウェアスペック:
- NUC13ANHI5000
- SSD: 2TB、HDD無し
- CPU: 13th Gen Intel(R) Core(TM) i5-1340P
- メインメモリ: 32GB
- グラボ無し(GPU無し、VRAM無し)
- 上記ハードウェアにProxmoxVE(9.1.5)をインストールしてあり、既に幾つかのサーバーを立てている(私の過去記事を参照)
- 私のAIコーディングの知識はまだまだ入門にも至っていなくて、只今絶賛学習中
目標
- ProxmoxVE上にコンテナを作成してビルド済のllama.cppのバイナリをインストール
- コンテナのOSはUbuntu24.04
参考文献
公式はGitHubのようですね。今回はここのREADME.mdの、ビルド済バイナリを利用する方法に従ってインストールしてみます。
モデル選択はこの記事を参考にしました。
モデルに関する基礎知識。
そして、llama.cppには依存関係のあるパッケージが1つだけあります。ちゃんとビルドすれば問題にならないのかも知れませんが。
systemdのサービスで自動起動する設定は下記を参考にさせていただきました。
その他の細々した設定など。
- ProxmoxVEのswap設定 - Qiita
- 我が家のIPアドレス体系(再掲) - 私的サーバー構築日誌:dhcpサーバー冗長化・Ubuntu 24.04 LTS in MicroServer N54L - Qiita
- おうちサーバー構築報告:AnsibleでProxmoxVEのゲストマシン4台それぞれ/etcをSubversion管理 - Qiita
準備
コンテナを用意します。私の流儀で、手順がちょっと長いです。
踏み台
我が家のProxmoxサーバーでは、コンテナへの接続は172.16.1.100を踏み台としています。ユーザーはansibleです。
ssh ansible@172.16.1.100
これの公開鍵を表示しておきます。
cd
cat .ssh/id_ed25519.pub
コンテナ作成
下記スペックでProxmox上にコンテナを用意します。なおコンテナIDが106になる事から、我が家のIPアドレス体系に従って、IPアドレスは172.16.1.106/16にします。
- ホスト名: ai
- SSH公開鍵: 上述の、踏み台ユーザー
ansibleの公開鍵 - 非特権コンテナ: チェック
- ネスト: チェック
- テンプレート: ubuntu-24.04-standard_24.04-2_amd64.tar.zst
- ディスクサイズ: 128GiB
- CPUコア: 4
- メモリ: 20,480MiB(=20GiB)
- スワップ: 0MiB(SSD対策でスワップ無しとする)
- ネットワーク:
172.16.1.106/16 - ゲートウェイ:
172.16.2.1(我が家のゲートウェイのIPアドレス) - DNSドメイン: 空欄(ホスト設定を使用)
- DNSサーバ: 空欄(ホスト設定を使用)
コンテナを構築して開始したら、踏み台172.16.1.100からsshログインを試みます。同時に踏み台の.ssh/known_hostsへ登録します。
ssh root@172.16.1.106
SSD対策で、私のProxmoxホストマシンはswapinessを10にしています。それを確認。
sysctl vm.swappiness
下記のように、60ではなくて10と表示されます。
# sysctl vm.swappiness
vm.swappiness = 10
確認できたらコンテナ172.16.1.106から抜けましょう。
exit
Ansibleで基本設定
私の流儀で、Ansibleを利用して/etcをSubversion管理するように設定します。/etcのSubversion管理をしないなら、このAnsible実行は省略して大丈夫です。次のユーザー作成へどうぞ。
なおetckeeperを使わないのはSubversion好きの私の我儘です。
インベントリについて。ここで動かすプレイブックには冪等性が無いので、今回のコンテナのIPアドレス(172.16.1.106)だけを記したインベントリを作る必要があります。
cd
cd svn_etc
cat <<___ >inventory_106.ini
[servers]
172.16.1.106
[servers:vars]
ansible_user=root
___
インベントリの確認の為にpingしてみましょう。
ansible all -m ping -i inventory_106.ini
確認できたらAnsibleを実行します。
ansible-playbook -i inventory_106.ini playbook.yaml
ユーザー作成
準備したコンテナ(IPアドレス172.16.1.106)に踏み台(172.16.1.100)から入ります。
ssh root@172.16.1.106
llama.cpp実行用の一般ユーザーを作成します。
useradd -m -s /bin/bash llama
そしてパスワードを設定。
passwd llama
sudoは、今回は不要でしょうかね。必要ならばrootでログインし直す事にしましょう。
ユーザーを作成したら、私の流儀で、/etcをSubversionにコミットします。
cd /etc
svn st | grep "^?" | cut -b9- | xargs -rt svn add
svn ci -m"added user 'llama'"
svn up
以上でコンテナを用意できました。
exit
llama.cppインストール
公式というかプログラムソースのREADME.mdの Quick start を読むと、ビルド済バイナリに関しては、リリースページからダウンロードしろと書いてあります。ので、その通りにします。
実際にリリースページを開いてバージョンなどを確認します。今日の最新版はb9957らしいですな。そして Linux Ubuntu x64 (CPU) を選択してダウンロード。これはGUIで操作してからコンテナにアップロードする手順の方が楽そうな気がしますが、まぁいいか。
踏み台172.16.1.100から上述の新規コンテナ172.16.1.106にユーザーrootでsshログインします。後で実行ファイルを/usr/local/binに移動したりするので、ユーザーはllamaではなくてrootにしましょう。
ssh root@172.16.1.106
そして先程確認したビルド済バイナリをダウンロード。今回のURLはhttps://github.com/ggml-org/llama.cpp/releases/download/b9957/llama-b9957-bin-ubuntu-x64.tar.gzになります。
ダウンロードのコマンドはcurlでもwgetでもどちらでもいいんですが、このコンテナだとcurlはインストールされていないようです。ここはwgetを使いましょう。
wget https://github.com/ggml-org/llama.cpp/releases/download/b9957/llama-b9957-bin-ubuntu-x64.tar.gz
README.md には「ダウンロード」としか書いてないので、ここから先は実践あるのみ。以下はその実践の記録となります。
解凍。
tar xvf *.tar.gz
解凍できたらダウンロードファイルは不要です。
rm *.tar.gz
解凍結果を見ると、コマンドと思しき実行ファイルとライブラリ*.soが一緒くたになってますね。うーん、*.soは/usr/local/libに移動した方がいいのかなぁ……でもそれが原因で動かなくなるのも嫌ですな。ここは一つ、全部まとめて/usr/local/binへ移動する事にします。どうせコレしかインストール予定はありませんし。
cd llama-*
mv * /usr/local/bin
cd ..
rmdir llama-*
そして、ビルド済llama.cppをProxmoxVEのコンテナに入れた場合、別途インストールしなければならないパッケージが1つだけあるようです。どこかの記事に書いてあった訳ではなくて、とにかく実行してみたらエラーが発生したので。
apt install libgomp1
軽く確認。ユーザーllamaでllama-cli --versionしてみます。
su - llama
llama-cli --version
ヨシ!
$ llama-cli --version
version: 9957 (c4ae9a88f)
built with GNU 11.4.0 for Linux x86_64
そうしたら、私の流儀で、/etcをSubversion登録します。
exit
cd /etc
svn st | grep "^?" | cut -b9- | xargs -rt svn add
svn ci -m"installed libgomp1"
svn up
モデルダウンロードと動作確認
モデルについては参考文献その他ネット上の噂を勘案した結果、UnslothのQwen3.5-9B-UD-Q4_K_XL.ggufを選択しました。
それにしても Hugging Face というサイトは操作がわかりにくいですな。検索はぐーぐる先生を頼ってしまいました。
cd
wget https://huggingface.co/unsloth/Qwen3.5-9B-GGUF/resolve/main/Qwen3.5-9B-UD-Q4_K_XL.gguf
実行してみます。
llama-server -m Qwen3.5-9B-UD-Q4_K_XL.gguf --host 0.0.0.0
普段使いのマシンからブラウザでアクセス。
とりあえず「Not now」ボタンをクリックしましょう。
ちょっとだけ会話してみました。
なるほど速度が超遅い。これは体感十倍ですわ。とは言えこれは私だけのLLM……むふふ。
とりあえず終了。Ctrl+Cでllama-serverを止めてからexitします。
exit
自動起動
モデルは/var/libにサブフォルダを作って置くのが良さそうです。/home/llamaにダウンロードしてしまったので、移動してファイルの権限を調整します。
ssh root@172.16.1.106
mkdir /var/lib/llama
mv /home/llama/Qwen3.5-9B-UD-Q4_K_XL.gguf /var/lib/llama
chown root: /var/lib/llama/*.gguf
それからsystemdのサービスファイルを作成します。
EDITOR=vi systemctl edit --force --full llama-server.service
systemctl cat llama-server
作成内容は下記。各パラメータはとりあえずデフォルト。Restartについてはnoにしました。OOMなどで突然終了される状況なども把握したいので、自動起動は無しの方向です。
# systemctl cat llama-server
# /etc/systemd/system/llama-server.service
[Unit]
Description=llama-server (llama.cpp)
After=network.target
[Service]
Type=simple
User=llama
Group=llama
WorkingDirectory=/var/lib/llama
ExecStart=/usr/local/bin/llama-server -m /var/lib/llama/Qwen3.5-9B-UD-Q4_K_XL.gguf --host 0.0.0.0
Restart=no
[Install]
WantedBy=multi-user.target
コンテナ再起動時の自動起動を設定し、開始します。
systemctl enable llama-server
systemctl start llama-server
systemctl status llama-server
ブラウザでアクセスし、サーバー起動を確認します。
仕舞い
llama.cppをインストールし、モデルをダウンロードして、動かしました。これで私だけのローカルLLMが手に入りました。
使い物になるかどうかはこれからですが。次回は別コンテナにOpenCodeをインストールして接続してみます。



