OllamaをIntel内蔵GPU『Arc Graphics』で動かす

# 1. はじめに

ノート PC を新調してスペック（と気分）がアガったので、これまで手を出せなかった生成 AI アプリを [Dify](https://dify.ai/jp) で作ってみようと思い立ちました。
参考にした情報は以下。

https://qiita.com/yuki_ink/items/c3125f45fb725612910e

今回は特にプロキシを使う環境ではなかったのですが、説明が分かりやすかったので参考にさせていただきました。

手順に従い、インストーラで Ollama を入れて動作確認します。今回、LLM は 15 歳の現役高校生（！）が作った『ArrowPro-7B-KUJIRA』[^1]を使ってみました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/0855e961-f05d-a762-9b7d-fa4ce195713e.png" width=80%>

おおお、動いた！すごい！！

感動です。ノート PC を新調した甲斐がありました。
さて負荷はどんな感じかな、とタスクマネージャーを覗いてみたところ。。。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/1fa65e8b-d4e9-0325-bb46-230ee72fa278.png" width=80%>

・・・GPU 使ってなくない？

# 2. 環境

OS:	Windows 11 Home
CPU: Intel(R) Core(TM) Ultra 7 155H   3.80 GHz
RAM: 32GB
GPU: Intel(R) Arc(TM) Graphics　**←これ！**

# 3. 対処

ググってみたところ、[Run Ollama with IPEX-LLM on Intel GPU](https://github.com/intel-analytics/ipex-llm/blob/main/docs/mddocs/Quickstart/ollama_quickstart.md) という、それっぽい記事を見つけました。
Intel の GPU を使ってもらうにはインストーラーで入れた Ollama ではダメなようで、手作業でのセットアップが必要なようです。[^2]

> Visit [Run llama.cpp with IPEX-LLM on Intel GPU Guide](https://github.com/intel-analytics/ipex-llm/blob/main/docs/mddocs/Quickstart/llama_cpp_quickstart.md), and follow the instructions in section [Prerequisites](https://github.com/intel-analytics/ipex-llm/blob/main/docs/mddocs/Quickstart/llama_cpp_quickstart.md#0-prerequisites) to setup and section [Install IPEX-LLM cpp](https://github.com/intel-analytics/ipex-llm/blob/main/docs/mddocs/Quickstart/llama_cpp_quickstart.md#1-install-ipex-llm-for-llamacpp) to install the IPEX-LLM with Ollama binaries.
（「llama.cpp with IPEX-LLM on Intel GPU Guide」を参照し、「Prerequisites」セクションの指示に従ってセットアップ、「Install IPEX-LLM cpp」セクションの指示に従って Ollama バイナリをインストールします。）

llama.cpp を先にセットアップしなさいと~~たらい回し~~アドバイスされます。
というわけで、まずは llama.cpp のセットアップを実施します。

## 3.1. llama.cpp のセットアップ

https://github.com/intel-analytics/ipex-llm/blob/main/docs/mddocs/Quickstart/llama_cpp_quickstart.md

ざっと目を通してみると、Miniforge プロンプトでコマンドを入力する必要があるようなので、Miniforge が未インストールの場合は
[GitHub - conda-forge/miniforge: A conda-forge distribution.](https://github.com/conda-forge/miniforge)
でインストーラーを取得し、インストールを行います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/5dab77c7-1f40-d6b4-7ed4-32fca7233f43.png" width=70%>

ちなみにインストールでは、私は上記のように上3つにチェックを入れました（デフォルト状態では一番上の1つのみがチェックされています）。

:::note info
以降の手順において、Miniforge プロンプトでコマンドを実行する際に上手くいかない場合があるかもしれないため、2番目(Miniforge3 の PATH 追加)にはチェックを入れておいた方がよいかもしれません。
:::

### 3.1.1. IPEX-LLM のインストール

```shell:IPEX-LLM のインストール
conda create -n llm-cpp python=3.11
conda activate llm-cpp
pip install --pre --upgrade ipex-llm[cpp]
```

Miniforge プロンプトで上記のコマンドを実行します。
これで、"llm-cpp" という Python の仮想環境が作成され、「IPEX-LLM」がインストールされます。

```shell:"llama-cpp"ディレクトリの作成
mkdir llama-cpp
```
続けて、任意の場所に "llama-cpp" ディレクトリを作成します。
上記コマンドはカレントディレクトリに "llama-cpp" ディレクトリを作成しています。

### 3.1.2. llama.cpp の実行環境のセットアップ

**管理者権限**で Miniforge プロンプトを別に起動し、先程作成した "llama-cpp" ディレクトリに移動します（```cd "llama-cpp"ディレクトリのパス```）。

```shell:llama.cpp の実行環境のセットアップ(管理者権限)
conda activate llm-cpp
init-llama-cpp.bat
```

上記コマンドを実行すると、"llama-cpp" ディレクトリ内に Python ファイルや DLL、大量のシンボリックリンクが作成されます。

:::note info
シンボリックリンクの作成に管理者権限が必要であるため、Miniforge プロンプトを管理者権限で起動する必要があります。
:::
:::note warn
[情報元サイト](https://github.com/intel-analytics/ipex-llm/blob/main/docs/mddocs/Quickstart/llama_cpp_quickstart.md#initialize-llamacpp-with-ipex-llm)には `conda activate llm-cpp` のコマンドは記載されていませんが、`init-llama-cpp.bat` の実行の前にこれが必要です。
:::

## 3.2. Ollama の実行環境のセットアップ

https://github.com/intel-analytics/ipex-llm/blob/main/docs/mddocs/Quickstart/ollama_quickstart.md

引き続き、**管理者権限**で起動した Miniforge プロンプトにて作業します。

```shell:Ollama の実行環境のセットアップ(管理者権限)
init-ollama.bat
```

カレントディレクトリが "llama-cpp" ディレクトリであることを確認して、上記コマンドを実行します。
すると、"llama-cpp" ディレクトリ内に Ollama 関連のシンボリックリンクが作成されます。

:::note info
「3.1.2. llama.cpp の実行環境のセットアップ」で `conda activate llm-cpp` のコマンドを実行済みであるため、ここでの同コマンドの実行は必要ありません。
:::

## 3.3. 環境変数 PATH の設定

必須の対応ではありませんが、どこからでも "ollama" コマンドを叩けるようにするため、私は "llama-cpp" ディレクトリを Windows 環境変数「PATH」に追加しました。

# 4. Ollama サーバーの起動

Miniforge プロンプトを起動します（通常ユーザー権限でOKです）。

```shell:Ollama サーバーの起動
conda activate llm-cpp

set OLLAMA_NUM_GPU=999
set no_proxy=localhost,127.0.0.1
set ZES_ENABLE_SYSMAN=1
set SYCL_CACHE_PERSISTENT=1
set SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1
set OLLAMA_HOST=0.0.0.0
set OLLAMA_ORIGINS=*

ollama serve
```

上記コマンドを実行すると Ollama サーバーが立ち上がります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/4526f399-781c-b8d2-af4b-c0d78080cb0a.png" width=80%>

:::note info
[情報元サイト](https://github.com/intel-analytics/ipex-llm/blob/main/docs/mddocs/Quickstart/ollama_quickstart.md#3-run-ollama-serve)には
`set SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1`
の環境変数登録コマンドについて以下の注意書きがあります。

> under most circumstances, the following environment variable may improve performance, but sometimes this may also cause performance degradation
（たいていの場合、以下の環境変数によってパフォーマンスが向上する可能性がありますが、場合によってはパフォーマンスの低下を引き起こすこともあります。）


調べたところ、Intel のサイト「[Level Zero Immediate Command Lists](https://www.intel.com/content/www/us/en/developer/articles/guide/level-zero-immediate-command-lists.html)」に以下のような記載がありました。

> On Intel® Arc™ Graphics, Intel® Data Center GPU Flex Series and Intel® Data Center GPU Max Series, a custom kernel with VM_BIND is used to support ULLS. There has not been much performance tuning of this feature on Intel® Arc™ Graphics and Intel® Data Center GPU Flex Series, with the focus being on Intel® Data Center GPU Max Series. 
（インテル® Arc™ グラフィックス、インテル® Data Center GPU Flex シリーズ、およびインテル® Data Center GPU Max シリーズでは、ULLS をサポートするために VM_BIND を備えたカスタム・カーネルが使用されます。インテル® Arc™ グラフィックスとインテル® Data Center GPU Flex シリーズでは、この機能のパフォーマンスチューニングはあまり行われておらず、インテル® Data Center GPU Max シリーズに重点が置かれています。）

データセンター用の GPU に注力しているということですね（うーむ :sweat:）。
場合によっては、この環境変数は外しておいた方がよいかもしれません。
:::

続けて、もうひとつチャット起動用に Miniforge プロンプトを起動します（こちらも通常ユーザー権限で OK です）。

```shell:LLM の読み込みとチャット起動
conda activate llm-cpp
ollama run hawkclaws/datapilot-arrowpro-7b-kujira
```

Miniforge プロンプトで上記コマンドを実行します。
今回も LLM は『ArrowPro-7B-KUJIRA』を使います。

:::note info
『ArrowPro-7B-KUJIRA』を未取得の場合は初回ダウンロードに時間がかかります。
なお、『ArrowPro-7B-KUJIRA』のサイズは 7.7GB あり、GPU の RAM も同等以上のサイズが必要です。
:::

:::note info
Ollama サーバーを起動した Miniforge プロンプトを見ると、GPU のそれっぽい情報が出力されています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/d3ab3009-ee47-2037-da6a-ae69b75c45cb.png" width=100%>
:::

チャット起動した Miniforge プロンプトに「自己紹介して」と入力し、AI に自己紹介してもらいました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/7b83b30e-d52a-e687-0f4b-fd47b8f32e97.png" width=90%>

タスクマネージャーを確認すると・・・。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512108/d8ddf673-1d0f-c29d-667f-20b25897d424.png" width=90%>

ばっちり GPU が使われています！

# 5. [余談] Ollama サーバーの終了方法

Ollama サーバーを起動した Miniforge プロンプトで「Ctrl + C」を入力すると、Ollama サーバーが終了しますが、実は一部の関連プロセスが残ったままの状態になります。この状態では Ollama サーバーを再度起動しても LLM の読み込みに失敗します。[^3]

なので少々力業ですが、私は PowerShell で次のコマンドを実行して Ollama サーバーを終了させるようにしています。

```shell: Ollama サーバーの終了
Get-Process | Where-Object {$_.ProcessName -like '*ollama*'} | kill
```

# 6. おわりに

私は AI については超初心者で分からないことだらけです。
この状態で AI を触ってみようと思ったのは [Dify](https://dify.ai/jp) の存在が大きいです。
Dify を使うと私のような AI 初心者でも、生成 AI アプリをノーコードで作れたり、それを自前のサイトに容易に組み込めたり、使用する LLM も自由自在に切り替えられたりと、AI のハードルが一気に下がります。
Dify 最高です！（この記事には Dify は登場しないですけど）

# 7. 参考にさせていただいた情報

プロキシ環境下のローカルPCに"Dify"と"Ollama"を導入して、インターネットを通らない「完全ローカルRAGアプリ」を作る #生成AI - Qiita
https://qiita.com/yuki_ink/items/c3125f45fb725612910e

GitHub - intel-analytics/ipex-llm
https://github.com/intel-analytics/ipex-llm/tree/main

[^1]: ArrowPro-7B-KUJIRA はベンチマーク (ELYZA-TASK100) において約 3.8(LLaMa3-70B 準拠) をマークし、7B において日本語性能世界一を達成しました。（[DataPilot/ArrowPro-7B-KUJIRA · Hugging Face](https://huggingface.co/DataPilot/ArrowPro-7B-KUJIRA) より転載）

[^2]: Ollama の [GPU](https://github.com/ollama/ollama/blob/main/docs/gpu.md) ページを確認すると、サポート対象に Intel GPU の記載がないことに気が付きました。

[^3]: インストーラーで入れた Ollama の場合は、タスクトレイの Ollama アイコンより  Ollama サーバーを終了させることができますが、この場合は残留プロセスはなく、正常に終了します。