ESXiにGeforce 4060tiを積んでLlama3を動かしてみた！

出遅れた感はありますが、これから類似環境でやってみたいという方もいるかなーと思ったのと、久々にそれらしい事をしましたので備忘録的な感じで（今回も割と雑な記事ですみません。)

# 前提
ESXi：7.0 Update 2 / CPU: 11th i7-11700 / MEM: 128
仮想OS : Ubuntu 22.04.01 LTS / CPU:	8 vCPUs/ MEM: 8GB / HDD: 500 GB
Kernel: 5.15.0-105-generic
GPU：GEFORCE RTX 4060 Ti(16GB)
 ドライバー関連: NVIDIA-SMI:550.54.15 / Driver Version: 550.54.15 / CUDA Version: 12.4


# 0. ESXiへGPU取付・仮想OS設定
電源が550W以上と記載があったので念のため電源(Thermaltake TOUGHPOWER GF3 850W)を購入したのですがいざESXiのケースを開けたらなんと同じ850Wでした。。。よってそのままGPUは取り付けました。
※GPUは価格も高いですが、4060Tiは約8万円でMEM16GB!! 頑張れば手の届く範囲だったので思い切って購入。ただし、現在取り扱っているお店も少なく秋葉原でもパソコン工房ぐらいしか見当たりませんでした。

ではGPU取付・ESXi起動後にGPUパススルー設定を行います。画面左ナビゲータから管理をクリックし以下のような管理画面を表示させ、「ハードウェア」タブをクリックします。正しく認識していればnVidiaのデバイスが表示されますので画面の様にチェックを入れて、「パススルーの切り替え」ボタンをクリックして、パススルーが「アクティブ」になっていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/b923d98f-55c1-5b8c-b3bf-90a11507a740.png)


次に仮想OS設定になります。まずメモリ設定で「すべてのゲストメモリを予約（すべてロック）にチェックを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/607c67c8-3431-28a6-a68a-c94096a391d2.png)

新規PCIデバイスを追加して、パススルー設定されたVGAを選択されている状態であることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/a25c8a7a-26b2-dc49-9ac1-d3ad452ae05f.png)

続いて、仮想マシンオプションボタンをクリックし、起動オプションから「ファームウェア」をEFIにしておき、一度仮想マシンの設定を完了させます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/6d770555-4903-3f24-4f16-187e8c2f3f1e.png)

再度仮想マシンのオプションを開いて、設定パラメータから以下二つを追加しておきます。
```bash
pciPassthru.use64bitMMIO TRUE
pciPassthru.64bitMMIOSizeGB 64
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/046bb265-7677-6660-0d70-9b0cd6bce106.png)

この後はインストーラーの支持に従ってUbuntuをインストールします。

# 1. ドライバーインストール
すぐにでもNVIDIAのグラフィックスドライバをインストールして認識させたいところですが、Linux上のnouveauグラフィックスドライバが有効になっている場合、NVIDIAドライバのインストールに失敗して動作しません。Ubuntuでも有効化されていましたので、まずこれを無効化するところから始めます。

```bash
sh -c "echo 'blacklist nouveau' > /etc/modprobe.d/blacklist-nouveau.conf"
sh -c "echo 'options nouveau modeset=0' >> /etc/modprobe.d/blacklist-nouveau.conf"
update-initramfs -u
reboot #反映の為一旦リブート

sudo su -
lsmod | grep nouveau #何も表示されなければOK
apt update
apt install vim wget pciutils git #とりあえず利用するpackageを入れておきます。
```

続いてドライバー関連のインストールをします。私の場合はcuda-toolkitを入れてからドライバーをインストールしました。
```bash
### cuda-toolkit install
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-ubuntu2204.pin
mv cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/12.4.1/local_installers/cuda-repo-ubuntu2204-12-4-local_12.4.1-550.54.15-1_amd64.deb
dpkg -i cuda-repo-ubuntu2204-12-4-local_12.4.1-550.54.15-1_amd64.deb
cp /var/cuda-repo-ubuntu2204-12-4-local/cuda-*-keyring.gpg /usr/share/keyrings/
apt-get update
apt-get -y install cuda-toolkit-12-4

### nvidia-driver, cuda-driver install
apt-get install -y nvidia-driver-550-open
apt-get install -y cuda-drivers-550

### cudnn install
wget https://developer.download.nvidia.com/compute/cudnn/9.1.1/local_installers/cudnn-local-repo-ubuntu2204-9.1.1_1.0-1_amd64.deb
dpkg -i cudnn-local-repo-ubuntu2204-9.1.1_1.0-1_amd64.deb
cp /var/cudnn-local-repo-ubuntu2204-9.1.1/cudnn-*-keyring.gpg /usr/share/keyrings/
apt-get update
apt-get -y install cudnn

reboot #反映の為リブート
```

リブート後、nvidia-smiコマンドを実行して以下のような画面が出力されれば正しく仮想OS上で認識されています。
```bash
# nvidia-smi
Sun May  5 08:58:46 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.15              Driver Version: 550.54.15      CUDA Version: 12.4     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4060 Ti     Off |   00000000:03:00.0 Off |                  N/A |
|  0%   34C    P8             14W /  165W |       4MiB /  16380MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+
```

この後、npmなどのパッケージなどを入れようとした際に、なぜかパッケージインストールがいつまでも完了しないという自体になりました。どうやら、needrestartというpackageが阻害していたようでしたので、私はこのパッケージを削除しています。(必要に応じでどうするか判断し貰えればとおもいます)

```bash
apt purge needrestart
```

# 2. Ollamaインストール
ローカル環境でLlama3を動作させるためにOllamaをインストールします。※割とサクッと終わります。
```bash
curl -fsSL https://ollama.com/install.sh | sh
```

# 3. 言語モデルダウンロード
ではOllamaを用いてLlama3の8Bを使ってみます。以下コマンドでllama3:8Bを事前にpullします。
```bash
ollama pull llama3:8b

ollama list # ダウンロードされた言語モデルの確認
NAME            ID              SIZE    MODIFIED
llama3:8b       a6990ed6be41    4.7 GB  23 hours ago
```

# 4. Ollama起動
ではOllamaを起動させてアクセス確認してみたいと思います。コマンドで起動させます。今回は外部からアクセスさせることも想定してOLLAMA_ORIGINSと、OLLAMA_HOSTをそれぞれ以下の様に設定して起動させます。

|項目  |値  |備考  |
|---|---|---|
|OLLAMA_ORIGINS  |http://10.2.0.*  |クライアントから受付られるように指示  |
|OLLAMA_HOST  |0.0.0.0  |LISTENするインタフェース(全指定)  |

```bash
OLLAMA_ORIGINS=http://10.2.0.* OLLAMA_HOST=0.0.0.0:11434 ollama serve
```

# 5. ブラウザ(Chrome)からアクセス
Chromeの拡張機能(ollama-ui)を利用してアクセスしたいと思います。拡張機能インストール後にollama-uiをクリックすると以下のような画面が表示されます。
※拡張機能インストールはこちら(https://support.google.com/chrome_webstore/answer/2664769?hl=ja)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/48f3de64-251d-1828-a2a5-19f677e00ba7.png)

Hostnameは起動させているUbuntuのIPをセット、modelは事前ダウンロードしたllama3:8bとして質問してみます。最近までメールで飛んでいたPaloaltoのCVEについて聞いてみました。(あまり良い例を思いつかず、すみません。)
```bash
以下のニュースについてSE視点で分析してください。分析過程がわかるようステップバイステップ形式でお願いします。###ニュース\n2024年4月12日（現地日付）、パロアルトネットワークスは、PAN-OSのGlobalProtect機能におけるOSコマンドインジェクションの脆弱性（CVE-2024-3400）に関するアドバイザリを公開しました。GlobalProtectはリモートアクセス（VPN）などを提供する機能です。本脆弱性の悪用により、認証されていません遠隔の第三者が、ルート権限で任意のコードを実行する可能性があります。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/470f85d9-229b-550b-ffdd-631f1fc88b9a.png)
ちゃんとステップバイステップで結果が表示されています！

気になるGPUの利用状況ですが、以下の様になっていました。
※約5GBほど利用しています。
```bash
# nvidia-smi
Sun May  5 09:25:00 2024
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.15              Driver Version: 550.54.15      CUDA Version: 12.4     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 4060 Ti     Off |   00000000:03:00.0 Off |                  N/A |
| 31%   38C    P2             36W /  165W |    5087MiB /  16380MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A      2788      C   ...unners/cuda_v11/ollama_llama_server       5078MiB |
+-----------------------------------------------------------------------------------------+
```

llama3:8bだとレスポンスも非常に早く割と正確な内容を返してくれる印象です。
ollamaコンソールに表示されている値を見ても
```bash
prompt eval time = 129.58 ms / 162 tokens ( 0.80 ms per token,  1250.22 tokens per second)
eval time = 8601.28 ms / 433 runs ( 19.86 ms per token, 50.34 tokens per second)
```
と画像表示に8秒ほどで、Elyzaと比べてかなり早いと感じました。ただ、日本語については今一つのところもありそうです。