Proxmoxと中古PCでLLMを動かしてみる
ヤフオクで程度の良い中古PCを手に入れたので、最強のサーバー機にしてLLMを動かします。
結論から述べると、モデルにもよりますが、CPUのみで2~20トークン/sのLLMマシーンに仕上がりました。
ゴール
- proxmoxで仮想化したubuntuで動作するollamaを作る。モデルはGemma2。
- ついでにほかのPCからwebuiでいじれるようにする。
レシピ
ハードウェア
- PC Thinkvcentre Mq75 Tiny Gen2(Ryzen 5 5650GE メモリ8GB/Nvme 256GB)
- メモリ (SODIMM 32GBx2)
- ストレージ (1TB)
- CPUのpassmarkのスコアは15000以上、DDR4以上をお勧めします。
- LLMだけなら32GBで十分ですが、デュアルチャンネル化は必須です。
- 元のデータ(Windows)を使わないなら、SSDを買い直す必要はありません。
その他セットアップに必要なもの
- proxmoxのセットアップのために、8GB以上のUSBメモリが1本必要です。
- proxmoxに接続するためのPC、またはブラウザ搭載機が必要です。
ソフトウェア
- Gemma2はollamaの機能を使ってセットアップします。
セットアップ
セットアップの前に、proxmoxのセットアップUSBメモリを作成します。isoをダウンロードしてRufusなどでUSBメモリに書き込みます。詳しくは参考記事を見てください。
ハードウェア
作業を始める前に、(特に中古の場合は)1度電源が入るか確かめます。ジャンク品等でパーツが不足している場合はこのステップは飛ばして部品の取り付けを行ってください。
初期動作が確認出来たら、シャットダウンしてから電源を切り、コンセントを抜いて、トッピングの部品の取り付けをします。パカっと開けてメモリとSSDを取り付けましょう。
NvMeを換装する時は丁寧な作業を心がけましょう。SSDの裏側にサーマルパッドが張られている場合があるので、プラスチックのヘラでそっと丁寧に剥がします。雑に作業を行うとコンデンサがはじけたり基板パターンが剥がれたりろくなことがありません。
部品を取り付けたら、再度電源が入るか確かめます。電源が入ったら、ソフトウェアをセットアップします。
ソフトウェア(proxmox編)
proxmoxのセットアップ
まずはproxmoxのセットアップします。PCにキーボードとディスプレイ、それにインストールUSBメモリを取り付けて電源をONすればOKです。だいたいの場合はUSBメモリからインストーラが起動してうまくいきます。起動しないときはBIOS画面で起動デバイスの設定を行ってください。
BIOS画面を呼び出すときは、殆どの場合F1、ESC、DELのどれかなので、これらを連打しながら電源ボタンを入れればよいでしょう。
大事なのはネットワークの設定です。指定したIPアドレスを忘れると面倒なので、きちんと紙に書いて保管しておきましょう。
セットアップの詳細は沢山あるので記事を紹介して省略します。
proxmoxの初期設定
セットアップを完了したら、別のブラウザからIPアドレスを指定してproxmoxの管理画面に入ります。
エンタープライズリポジトリの設定をno-subscriptionに切り替えるとアップデートできるようになるので、proxmoxをアップデートします。
これらのページの内容と同一なので参考にしてください
コンテナの作成
ollamaを動かすためのubuntuを入れたLCXを作ります。
まずはテンプレートのダウンロード。
proxmoxの管理画面から、ストレージ→CTテンプレート→テンプレートボタンを押すとウインドウが開くので、そこからubuntuの新しいものをダウンロードします。
次に右上のマシン名→CTを作成ボタンを押して、LCXコンテナを作成します。
テンプレートには先ほどダウンロードしたものを選びましょう。
注意するのはホスト名、パスワード、ディスクサイズ、ネットワークです。これらは後から変更が面倒です。ディスクサイズは後で減らせませんので最低限の128GB。DHCPを使用する場合はネットワークの設定が必要です。
linuxのセットアップ
proxmoxの管理画面でコンテナを選択して、開始をクリックします。
さらにコンソールを開くとターミナルが開きます。
とりあえずrootでログインします。パスワードはコンテナを作成したときに入力したものを使います。
お約束セットでアップデートします。
#apt update
:
#apt upgrade
ついでにユーザーも作っておきましょう。sudoができないのでsudoを許可します。
#sudo adduser llm
:
#sudo gpasswd -a llm sudo
Adding user llm to group sudo
#
作業のためにllmに切り替えてhomeディレクトリに移動します。
#su llm
$cd ~/
$pwd
/home/llm
$
ollamaのセットアップ
curlが必要なので、apt-getでインストールします。
$apt-get install curl
作業用ユーザのホームディレクトリで、公式のLinux版を参考にセットアップを勧めます。
$curl -fsSL https://ollama.com/install.sh | sh
:
$ollama --version
ollama version is 0.5.7
次にモデルをダウンロードします。お勧めはGemma2:2bです。
$ollama pull gemma2:2b
: しばらくかかる
$
終わればollamaとお話しできる状況が整っているはずです。
$ ollama run gemma2:2b
>>> こんにちは
こんにちは! 😊
何かご用ですか? 😊
>>> Send a message (/? for help)
回答の中断はctrl+C、終了はctrl+Dです。
open-webuiから使えるようにする
ollamaのCUIを終了し、必要なモジュールを揃えます。
pythonが必要なので、バージョンをチェックし、pipをインストールして、仮想環境も整えます。
$python3 --version
Python 3.12.3 #python 3.11.1より新しければOK
$sudo apt install python3-pip
:
$python3 -m venv llmenv # "llmenv" は仮想環境の名前
:
$source llmenv/bin/activate #環境切替
open-webuiをセットアップします。少々時間がかかるので気長に待ちましょう。
(llmenv)llm@llm$sudo pip install open-webui
完了したら起動します。
$open-webui serve
他のPC等のブラウザから、http://[ipaddress]:8080
にアクセスするとwebuiを使うことができます。
ollamaのAPIをほかのPCから使えるようにする
初期状態のollamaは外部からのAPIを受け付けません。設定ファイルを編集して再起動する必要があります。
設定ファイルは/etc/systemd/system/ollama.servide
にありますので、以下のように追加設定をします。
先頭3行を書き加えてください。OLLAMA_ORIGIN
は自身のネットワークに合わせて設定してください。
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
OLLAMA_ORIGINS=192.168.128.*
[Unit]
Description=Ollama Service
After=network-online.target
[Service]
ExecStart=/usr/local/bin/ollama serve
User=ollama
Group=ollama
:
詳細な設定は以下のページが参考になります。
ollamaを再起動します。
$sudo systemctl restart ollama
ブラウザからhttp://[ipaddress]:11434
にアクセスして、Ollama is running
と表示されれば成功です。
open webuiの調整
さて、webuiからもAIさんを使えるようになったけども、CUIと比べると無応答になったり初期応答が遅くなったりどうにも調子が良くありません。
詳しくは分からなかったので、直観で設定を弄って解決したつもりになりましょう。
左下か右上のアイコンをクリックして、管理者パネルを開きます。
- 設定→EvaluationsからArena ModelsをOFFにする。
- 設定→ドキュメントからRAG テンプレートを空にして保存ボタンを押す
- 設定→モデルから不要なモデルをOFFにする
1と2の設定は早くなったような気分がします。2の設定を行うときは元のテンプレートを保存しておきましょう。うっかり消してしまったら↓からコピーしてください。
RAG テンプレート
Task:
Respond to the user query using the provided context, incorporating inline citations in the format [source_id] only when the <source_id> tag is explicitly provided in the context.
Guidelines:
- If you don't know the answer, clearly state that.
- If uncertain, ask the user for clarification.
- Respond in the same language as the user's query.
- If the context is unreadable or of poor quality, inform the user and provide the best possible answer.
- If the answer isn't present in the context but you possess the knowledge, explain this to the user and provide the answer using your own understanding.
- Only include inline citations using [source_id] when a <source_id> tag is explicitly provided in the context.
- Do not cite if the <source_id> tag is not provided in the context.
- Do not use XML tags in your response.
- Ensure citations are concise and directly related to the information provided.
Example of Citation:
If the user asks about a specific topic and the information is found in "whitepaper.pdf" with a provided <source_id>, the response should include the citation like so:
- "According to the study, the proposed method increases efficiency by 20% [whitepaper.pdf]."
If no <source_id> is present, the response should omit the citation.
Output:
Provide a clear and direct response to the user's query, including inline citations in the format [source_id] only when the <source_id> tag is present in the context.
<context>
{{CONTEXT}}
</context>
<user_query>
{{QUERY}}
</user_query>
3は使わないモデルがメモリに居座り続けることがあったので、その対策です。メモリが少ない時には設定したほうが無難だと思います。
これでなんとなく早くなった気分になりました。
次回
評価編、お楽しみに。
Discussion