0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TrueNAS SCALE環境でAMD XDNA2 NPU (Strix) を認識させ、FastFlowLM (FLM) でPrefill速度1,000 tok/s超えを達成した記録

0
Posted at

TrueNAS SCALE(LinuxベースのアプライアンスOS)上で、AMD Ryzen APU内蔵のXDNA2 NPU(Strix / Strix Halo等)を認識させ、Dockerコンテナ上の FastFlowLM (FLM) / Lemonade Server からNPU推論を実行させるまでの構築記録とベンチマーク結果です。

6.12系カーネルにおける SVA (Shared Virtual Addressing) API不適合によるフリーズエラー(ret -95)を「IOVA強制モード(force_iova=1)」で打破するノウハウ や、実際にGemmaモデルを走らせて 8kコンテキスト時に1,000 tok/s超のPrefill(プロンプト処理)速度 を確認した結果などをまとめています。

なお、記事にまとめる中で対応した事象と記述順序が前後している箇所があります。ご了承くださいませ

1. 動作環境・システム構成

項目 詳細・バージョン情報
ホストOS TrueNAS SCALE (Kernel: 6.12.91-production+truenas)
CPU / APU AMD Ryzen AI 5 340 ES (Strix)
NPU AMD Strix Neural Processing Unit (PCI ID: 1022:17f0, rev 20)
ストレージ構成 OCuLink ➔ LSI 9211-8i HBA ➔ 5 x 8TB HDDs (RAIDZ1)
推論基盤 FastFlowLM (FLM) / Lemonade Server (Dockerコンテナ)
目標成果物 amdxdna.ko モジュールロード ➔ /dev/accel/accel0 生成 ➔ FLMでNPU推論
  • こんなミニPC
    image.png

2. カーネルモジュール(amdxdna.ko)のビルド方針

アプライアンスOSであるTrueNAS SCALEのローカル環境上で直接ビルド環境(DKMSや開発ツールチェーン)を整えるのはシステム保護の観点から推奨されません。

そのため、別体のDebian VM環境にて外付けビルドを行う手法を採りました。

  • カーネルヘッダーの抽出: TrueNAS上の稼働カーネル(6.12.91-production+truenas)からヘッダー情報を抽出し、VM側へ移動し、下記xdna-driverをビルドする際のカーネルヘッダとします。(※カーネルバージョンのアップグレード毎に再構築が必要となる、非常に高度かつ自己責任を伴う工程です)
  • ドライバソースコード: ビルドに利用するドライバソースコードはAMD公式のGitHub https://github.com/amd/xdna-driver から取得しました
  • カーネルヘッダ・ビルドオプションの細かな適合: GCC 14でビルドを行うとxdna-driverのコードや動作しているTrueNASから抽出したヘッダ情報にて、GCC由来の厳密な型チェックやヘッダバージョンが推奨より低いことから発生するシンボル名エラー等が多発します。それらを乗り越えるべく、CFLAG補正やシンボル名や引数の数を合わせるためのCマクロをヘッダに定義するなどを繰り返してコンパイルを通し、amdxdna.ko を生成します。

3. 構築およびロード手順

ステップ0: GRUBでのAMD IOMMU有効化(事前準備)

TrueNASのGRUBカーネルオプションでは intelのIOMMUは有効になっていますが、AMDのIOMMUは有効化されていません。幸いにしてカーネルドライバそのものは存在するため、GRUBのオプションを書き換えるだけで AMD IOMMUを有効にできます。NPUがPCIeデバイスとして正しくメモリ空間を扱えるように、AMD IOMMUが有効でなければ以下を追記してTrueNASホストを再起動しておきます。

# /etc/default/grub.d/truenas.cfg の GRUB_CMDLINE_LINUX_DEFAULT 行へ追記
# 例: GRUB_CMDLINE_LINUX_DEFAULT="... amd_iommu=on iommu=pt"

# GRUB設定の反映と再起動
sudo update-grub
sudo reboot

ステップ1: ZFSルートの保護解除と成果物配置

TrueNASはアプライアンスOSのため、ルートデータセットはZFSレベルでRead-Only保護されています。
そのため、カーネルオブジェクト等配置のため一時的にRead-Only保護を解除する必要があります。

WSL2等からTrueNASの /tmp/npu_install/ へビルド済みモジュールおよびファームウェアを一括転送し、ZFSレベルのRead-Only保護を一時解除してファイルを配置します。

# TrueNAS側:ZFSルートデータセットのロック一時解除とRW再マウント  
sudo zfs list -H -o name | grep '/ROOT/' | xargs -I {} sudo zfs set readonly=off {}  
sudo mount -o remount,rw /

# ファームウェアとモジュールの配置  
sudo mkdir -p /lib/firmware/amdnpu  
sudo cp -r /tmp/npu_install/amdnpu/* /lib/firmware/amdnpu/  
sudo mkdir -p /lib/modules/$(uname -r)/kernel/drivers/accel/amdxdna  
sudo cp /tmp/npu_install/amdxdna.ko /lib/modules/$(uname -r)/kernel/drivers/accel/amdxdna/  
sudo depmod -a

# FastFlowLM要求バージョン(1.1.2.64等)へシンボリックリンク更新  
cd /lib/firmware/amdnpu/17f0_10  
sudo ln -sf npu.sbin.1.1.2.64 npu.sbin

ステップ2: 【最重要】SVA無効化とIOVA強制モードでのドライバロード

TrueNAS SCALEの6.12カーネルでは、最新NPUドライバが要求するSVA (Shared Virtual Addressing) の処理で *ERROR* amdxdna_sva_init: SVA bind device failed, ret -95 となりNPUがフリーズする問題が発生します。

※ この件は /dev ノードが生成された時点では判別できず、実際にFLMで推論を走らせた際の dmesg で初めてSVAバインド失敗が発覚しました……

これを回避するため、モジュールロード時に force_iova=1 パラメータを付与して標準IOVAモードで動作させます。

# 古いモジュールをアンロード  
sudo rmmod amdxdna

# 魔法の引数 force_iova=1 を与えてロード  
sudo modprobe amdxdna force_iova=1

# dmesgで初期化ログを確認  
sudo dmesg | tail -n 20 | grep -iE "amdxdna|accel"

【期待される出力ログ例】

[drm] amdxdna_iommu_init: Enabled force_iova mode.  
[drm] Load firmware amdnpu/17f0_10/npu.sbin  
[drm] Initialized amdxdna_accel_driver 0.16.0 for 0000:c7:00.1 on minor 0

4. 動作確認(/dev/accel/accel0 導通テスト)

/dev/accel/accel0 が生成されていることを確認し、Pythonの記述でデバイスノードが正常にオープンできるかテストします。

# デバイスノードの確認  
ls -al /dev/accel/accel0  
# crw-rw---- 1 root render 261, 0 Aug 4 21:56 /dev/accel/accel0

# アクセステスト  
sudo python3 -c \  
  "import os; fd = os.open('/dev/accel/accel0', os.O_RDWR); print('大勝利! fd:', fd)"

【期待される出力結果】

大勝利! fd: 3

5. FastFlowLM (FLM) 実行時のノウハウ(カーネルバージョンチェックの偽装)

/dev/accel/accel0 が生えた後、Dockerコンテナ上で FastFlowLM (FLM) や Lemonade Server を起動して NPU を使用する際、「TrueNASのカスタムカーネル文字列」「未対応カーネルバージョン」 であるとしてランタイム側で弾かれる罠があります。

ハマりポイントと対策: uname -a の偽装 (uname-shim)

FLMのソースコード等では、以下のように uname システムコールを発行してカーネルバージョン(major > 6 または major == 6 && minor >= 17 等)の互換性チェックを行っています。

// FLMソースコードにおけるカーネルチェック処理の例  
struct utsname u_name;  
uname(&u_name);  
int major, minor;  
sscanf(u_name.release, "%d.%d", &major, &minor);  
bool kernel_ok = (major > 6) || (major == 6 && minor >= 17);

TrueNASの 6.12.91-production+truenas のようなバージョンではチェックに抵触し Kernel version incompatible with this version of FLM で終了してしまいます。

そのため、コンテナ内で LD_PRELOAD を用いた uname 関数のフックライブラリ(libuname_shim.so)を挟み込み、システムコールに対して公式サポート風のカーネル文字列(例: 6.18.0 等)を応答させることで判定をバイパスさせました。

Dockerコンテナ起動コマンド例

docker run -d \  
  --name lemonade-npu-server \  
  --device=/dev/accel/accel0 \  
  --group-add render \  
  -v /opt/lemonade:/opt/lemonade \  
  -e LD_PRELOAD=/usr/local/lib/libuname_shim.so \  
  lemonade-npu-image

わたしが作成したDockerfile

# 1. 移管された最新の公式イメージをベースにする!
FROM ghcr.io/lemonade-sdk/lemonade-server:latest

# 2. パッケージをインストールするために、一時的に root 権限にチェンジ!
USER root

# 3. NPU 駆動に必須な libdrm2、libfftw3 に加え、偽装用の gcc を追加!
RUN apt-get update && apt-get install -y \
    libdrm2 \
    libfftw3-single3 \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# 4. FastFlowLM の展開 & 闇の魔術(カーネル偽装)の錬成!
ARG FLM_VERSION=0.9.46
RUN mkdir -p /opt/fastflowlm && \
    cd /tmp && \
    curl -LO https://github.com/ROCm/FastFlowLM/releases/download/v${FLM_VERSION}/fastflowlm_${FLM_VERSION}_linux.tar.gz && \
    tar -xzf fastflowlm_${FLM_VERSION}_linux.tar.gz -C /opt/fastflowlm && \
    rm fastflowlm_${FLM_VERSION}_linux.tar.gz && \
    printf '#include <sys/utsname.h>\n#include <string.h>\nint uname(struct utsname *buf) {\n    strcpy(buf->sysname, "Linux");\n    strcpy(buf->nodename, "truenas");\n    strcpy(buf->release, "6.17.0-fake");\n    strcpy(buf->version, "#1 SMP");\n    strcpy(buf->machine, "x86_64");\n    return 0;\n}\n' > /tmp/fake_uname.c && \
    gcc -shared -fPIC -o /opt/fastflowlm/fake_uname.so /tmp/fake_uname.c && \
    rm /tmp/fake_uname.c && \
    chmod 755 /opt/fastflowlm/fake_uname.so && \
    ln -s /opt/fastflowlm/flm /usr/local/bin/flm && \
    chown -R lemonade:lemonade /opt/fastflowlm

# 5. 偽装ライブラリをシステム全体で強制ロード!
ENV LD_PRELOAD="/opt/fastflowlm/fake_uname.so"
ENV PATH="/opt/fastflowlm:${PATH}"
ENV LD_LIBRARY_PATH="/opt/fastflowlm:/opt/fastflowlm/lib:/opt/fastflowlm/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH}"

6. Dockerコンテナ(FastFlowLM)でのNPU推論ベンチマーク

無事にランタイムのチェックを突破後、flm bench で性能測定を行いました。

① Gemma 4-E2B (gemma4-it:e2b)

docker exec -u root -it lemonade-npu-server flm bench gemma4-it:e2b
Context Length TTFT (s) Prefill Speed (tok/s) Decoding Speed (tok/s)
1k 1.592 614.96 21.77
2k 2.362 824.99 20.98
4k 4.084 951.70 19.42
8k 7.677 1011.13 17.17
16k 16.537 938.03 13.82
32k 41.596 745.49 9.96

8kコンテキスト時のPrefill(プロンプト処理)速度は 1,000 tok/s 超え を達成。

② Gemma 4-E4B (gemma4-it:e4b)

docker exec -u root -it lemonade-npu-server flm bench gemma4-it:e4b
Context Length TTFT (s) Prefill Speed (tok/s) Decoding Speed (tok/s)
1k 2.466 396.95 12.17
2k 3.873 503.01 11.86
4k 6.822 569.53 11.30
8k 12.702 610.92 10.31
16k 26.124 593.60 8.78
32k 61.068 507.69 6.78

7. 運用上の注意点(TrueNAS SCALEアップデート時のリスク)

TrueNAS SCALEはアプライアンスOSであるため、システムアップデート(OSメジャー/マイナーバージョンアップ)を実行すると、以下のリスクが生じます。

  1. 手動配備ファイルの消滅: /lib/modules/ や /lib/firmware/ 配下に配置した amdxdna.ko やファームウェアがアップデート処理で上書き・消去される可能性があります。
  2. カーネルシンボル不一致: アップデート後の新カーネル(例: 6.18系等)では、旧環境でビルドした amdxdna.ko がシンボル不一致によりロードできなくなります。

【対策】

  • OSアップデート前にビルド用のDebian VM環境(およびビルド手順)を維持しておくこと。
  • アップデート後の新カーネルヘッダーを抽出し、ヘッダー参照の補正を行った上で amdxdna.ko を再ビルド・再配備する運用計画を立てておくことが推奨されます。

8. まとめ

TrueNAS SCALE というアプライアンスストレージOS環境において、以下のステップを踏むことで完全にNPUを実稼働させることができました。

  1. カーネルモジュールの外付けビルド: ヘッダー整合とコンパイラオプションの調整
  2. カーネル制約の回避: force_iova=1 による SVA 依存エラーの回避
  3. ランタイムチェックの回避: LD_PRELOAD(uname-shim)によるカーネルバージョン判定突破
  4. コンテナパススルー: /dev/accel/accel0 のマウントと FastFlowLM による高速推論

NASとしての本業(ZFSアレイの運用)に影響を与えることなく、空きリソースのNPUを活用して1,000 tok/s規模の超高速Prefill環境を同居させることが可能となりました。

この記事、当然ながら公式での方法ではありませんし、試行錯誤の上に成り立っているものとなります。また、TrueNASのバージョンが上がれば .ko ファイルは作り直しになりますし、次バージョンで xdnaモジュールを有効化してくるかもしれません。 At your own risk でお願いしますねっ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?