UE5でニューラルネットを使ういくつかの方法

50.7K Views

April 28, 24

スライド概要

Unreal Engine Meetup in Osaka Vol.02での発表資料です。
Unreal Engine 5でニューラルネットによる推論をGPUを使って高速に実行したい場合、公式プラグインであるNNEを使う、 ONNX Runtime等を自前のプラグインとして組み込む、マテリアルの中のカスタムHLSLコードでゴリゴリと実装するといった方法があります。これらを実際にやってみての所感や実装の勘所などを紹介します。

動画はこちら:https://youtu.be/-yOo2qGfyWE?si=AvauWbvRbSYaS1Dy

profile-image

地域社会の安心に貢献し、暮らしやすい世の中をつくるために、主な事業として空き家専門の工事会社・不動産屋として空き家再生・活用に取り組んでいます。また、演劇教室「劇ゼミ」の運営、VR・AI技術開発も行っています。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

(ダウンロード不可)

関連スライド

各ページのテキスト
1.

UE5でニューラルネットを 使ういくつかの方法 NNE、自作プラグイン、マテリアル 2024/04/28 Unreal Engine Meetup in Osaka Vol.02 株式会社空き家総合研究所

2.

スピーカー • 麻場 健司(𝕏:@KenjiASABA) • 株式会社空き家総合研究所 • 社員5人 • 全員、関西の学生劇団出身 • 主な事業は3つ • 空き家再生 • 演劇教室 • VR・AI技術開発

3.

UE × AI な製品を作っています • MocapForAll (2021) • 複数ウェブカメラで モーションキャプチャ • UE4.26 × 姿勢推定 https://vrlab.akiyasouken.co.jp/video/mocapforall.mp4

4.

UE × AI な製品を作っています • MocapForStreamer (2022) • 2台のウェブカメラで 上半身モーキャプ • UE4.26 × 姿勢推定 https://vrlab.akiyasouken.co.jp/video/mocapforstreamer.mp4

5.

UE × AI な製品を作っています • WhisperRealtime (2023) • 音声→テキスト • UE4.26 × 音声認識 https://vrlab.akiyasouken.co.jp/video/whisperrealtime_ja.mp4

6.

UE × AI な製品を作っています • 3D Gaussians Plugin (2023) • 3D Gaussian Splatting 描画プラグイン • UE5.1 × 3DGS https://vrlab.akiyasouken.co.jp/video/3dgaussian.mp4

7.

UE × AI な技術支援も行っています • KSIN • 株式会社ユニキャスト様、 株式会社デジタル・フロンティア様 • アバター接客システム • UE4.27 × 姿勢推定 https://www.youtube.com/watch?v=W2fn3rl95QI

8.

UE × AI な技術支援も行っています • Vista Splat Pro • バーチャル・ライン・スタジオ株式会社様、 株式会社デジタル・フロンティア様 との共同開発 • UE5.1 × 3DGS https://www.youtube.com/watch?v=PWtyqMOHOyg

9.

UE × AI な技術支援も行っています • UEとAIで何かしたい • 知見がほしい、手が足りない → ご相談ください!

10.

https://www.unrealengine.com/ja/blog/unreal-engine-5-4-is-now-available

11.

機械学習 ニューラルネット? MLモデル? • 計算の手続きを定めたもの(≒関数) • UEのBPやマテリアルのように • 演算(処理)を表すノード • 定数 • 入出力 ノード 定数 入出力 を組み合わせて表すのが一般的 実行順

12.

機械学習 ニューラルネット? MLモデル? • 計算の手続きを定めたもの(≒関数) • UEのBPやマテリアルのように • 演算(処理)を表すノード • 定数 • 入出力 ノード 定数 入出力 を組み合わせて表すのが一般的 • 定数は「重み」とも呼ばれる • 同じ演算でもこれが違えば結果が違う • 所望の結果を返す関数となるように定数を 求める過程が「学習」 • 学習後、所望の結果を返す関数として単に 使うことを「推論」と呼ぶ 実行順

13.

今日お話しすること ニューラルネットと呼ばれるちょっと特殊な形式で定義された関数を UEに取り込んで実行するにはどうすればいいのか、というお話 具体的には • UE5でのニューラルネットによる推論の実行方法3つ • 公式NNEプラグイン • 自作プラグイン • マテリアル内のカスタムHLSLノード 今日お話ししないこと • ニューラルネットの学習

14.

NNEプラグイン 私がコードを読んで推測した内容を多分に含みます

15.

NNE公式ドキュメント • Neural Network Engine Overview - 5.4 • https://dev.epicgames.com/documentation/en-us/unreal-engine/neural-network-engine-overviewin-unreal-engine • 情報は整備中の様子 • NNE - Quick Start Guide - 5.3 • https://dev.epicgames.com/community/learning/tutorials/34q9/unreal-engine-nne-quick-startguide-5-3 • UE5.3で動くコードがあるが、UE5.4では動かない → これの UE5.4版 & GPU版 を紹介します

16.

:実験的機能 β :ベータ機能 NNEの構成 NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU

17.

β :ベータ機能 NNEの構成(抜粋) NNE エンジンモジュール NNERuntimeORT プラグイン β ONNX Runtime ランタイム DirectML (Winのみ) ハードウェア CPU GPU

18.

ONNX Runtime? ONNX形式のニューラルネットを実行するライブラリ 各 種 機 械 学 習 フ レ ー ム ワ ー ク エクスポート 実行 …

19.

β :ベータ機能 NNEの構成(抜粋・再掲) NNE エンジンモジュール NNERuntimeORT プラグイン β ONNX Runtime ランタイム DirectML (Winのみ) ハードウェア CPU GPU

20.

DirectML? • 機械学習でよく使われる演算を GPUで効率よく実行するための ライブラリ • DirectX 12対応のGPUで動作する ハードウェアアクセラレータ と呼ばれるものの一つ NVIDIA、AMD等の いずれでもOK

21.

ONNX Runtimeのメリット①: クロスプラットフォーム https://onnxruntime.ai/getting-started :NNEでサポート

22.

ONNX Runtimeのメリット②: 計算の自動最適化 • 不要な計算ノードの削除 • 計算ノードの結合 • 実際に速くなるかは環境による 最適化 最適化 https://onnxruntime.ai/docs/performance/mobile-performance-tuning.html

23.

:実験的機能 β :ベータ機能 NNEの構成(再掲) NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU

24.

NNE使い方 - 全体の流れ • プラグイン有効化 • ONNXモデルインポート • 依存モジュールに追加 • ランタイム取得 • モデルインスタンス生成 • 入力形状のセット • 入出力のバインドと実行 ↑エディタ ↓C++, C# ↑定型作業 ↓モデル個別

25.

NNE使い方1:プラグイン有効化

26.

NNE使い方2:ONNXモデルインポート

27.

NNE使い方3:依存モジュールに追加 ModuleName.build.cs

28.

NNE使い方4:ランタイム取得(1/2)

29.

:実験的機能 β :ベータ機能 NNEの構成(再掲) NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU

30.

NNE使い方4:ランタイム取得(2/2)

31.

NNE使い方5:モデルインスタンス生成

32.

複数の配列(テンソル)を入出力する ~~~~~~~~~ 略 ~~~~~~~~~ 可変サイズの入力が可能な場合がある https://netron.app/

33.

NNE使い方6:入力形状のセット 入力形状が可変のモデルの場合 … 入力形状を手動で指定 入力形状をセット

34.

NNE使い方6:入力形状のセット 入力形状が固定のモデルの場合 モデルの入力形状を取得 … モデルの入力形状を指定 入力形状をセット

35.

NNE使い方7:入出力をバインドし実行 入力TArray(の配列) 出力TArrayの配列 FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync

36.

NNE使い方7:入出力をバインドし実行 入出力データを保持するメモリ領域を確保 入力TArray(の配列) 出力TArrayの配列 FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync

37.

NNE使い方7:入出力をバインドし実行 入力TArray(の配列) 出力TArrayの配列 NNE入出力用の統一的な形式にする FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync データへのポインタ とサイズ

38.

NNE使い方7:入出力をバインドし実行 入力TArray(の配列) 出力TArrayの配列 FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync

39.

NNE使い方7:入出力をバインドし実行 入力TArray(の配列) 出力TArrayの配列 FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync この中でCPU⇔GPUのデータ転送も実行

40.

CPU⇔GPUのデータ転送? 入力TArrayの配列 出力TArrayの配列 入力バッファ 出力バッファ 入力 データ CPU(ホスト)メモリ GPU(デバイス)メモリ CPU GPU

41.

CPU⇔GPUのデータ転送? コピー 入力TArrayの配列 出力TArrayの配列 入力 データ 入力バッファ 出力バッファ 入力 データ CPU(ホスト)メモリ GPU(デバイス)メモリ CPU GPU

42.

CPU⇔GPUのデータ転送? 入力TArrayの配列 出力TArrayの配列 入力 データ CPU(ホスト)メモリ 入力バッファ 出力バッファ 入力 データ 出力 データ GPU(デバイス)メモリ 演算 CPU GPU

43.

CPU⇔GPUのデータ転送? コピー 入力TArrayの配列 出力TArrayの配列 入力バッファ 出力バッファ 入力 データ 出力 データ 入力 データ 出力 データ CPU(ホスト)メモリ GPU(デバイス)メモリ CPU GPU

44.

:実験的機能 β :ベータ機能 NNEの構成(再掲) NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU

45.

NNERuntimeRDG • RDG? • Render Dependency Graph • レンダリング依存関係グラフ • UEの描画機能を呼び出すAPI • GPU上のメモリを直接読み書き してAIを実行できる • CPU⇔GPU間のデータ転送が不要 な画像処理等に向いている • NeuralRenderingプラグインから 利用されている 入力バッファ 出力バッファ 入力 データ 出力 データ GPU(デバイス)メモリ 演算 GPU

46.

NeuralRenderingプラグイン ツイート: https://twitter.com/historia_Inc/status/ 1777993243613155652 記事: https://historia.co.jp/archives/40788/

47.

NNERuntimeRDGのサンプル • NeuralRenderingの処理 • ApplyNeuralNetworks_RenderingThread • 入出力バッファに対する前処理・後処理 • 下記の「Execute」を実行 • UNeuralPostProcessModelInstance::Execute • 入出力のバインディング • ModelInstanceRDGに対して「EnqueueRDG」を実行 • NNERuntimeORTの「RunSync」に対応

48.

AI系の他のプラグインから参照 :実験的機能 β :ベータ機能 MLDeformer/NearestNeighborModel MLDeformer/NeuralMorphModel LearningAgent NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU

49.

:実験的機能 β :ベータ機能 モバイル・エッジ デバイス向け? NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU

50.

:実験的機能 UE5.3でのNNEの構成 NNE プラグイン NNERuntimeORTCpu NNERuntimeORTGpu NNERuntimeRDG ONNX Runtime ONNX Runtime ONNX Runtime ランタイム ハードウェア NVIDIA CUDA CPU DirectML (Winのみ) GPU UE独自実装 (HLSL)

51.

NNE所感 • NNERuntimeORT • ONNX Runtimeのラッパー • 基本的な使い方はUEとORTの公式ドキュメントを読めばOK • 対応するプラットフォームやランタイムは少ないが、今後増えるかも? • 現状は、Win・Linux・Mac、CPU・DirectML • ONNX Runtimeのビルド済みバイナリを適切に追加すればこれを増やせる • NNERuntimeRDG • UEのRDGバッファを入出力に使う • CPU⇔GPU間のデータ転送をしない画像処理等に適した設計 • UE5.4のNeuralRenderingプラグインから使われている • 今後、他の公式プラグインからも使用される可能性はありそう • 現段階では対応する演算が少ないなど実利用は難しそう? • 今後に期待!!

52.

自作プラグイン NNEで飽き足らない場合は自分で作ろう

53.

あえて自作プラグインを作る理由 • NNE(またはその前身のNNI)がサポートされていない環境がある • 過去の UE バージョン • 最新の ONNX Runtime バージョン • プラットフォーム • Android、iOS等 • ランタイムライブラリ • TensorRT等 UEバージョンとONNX Runtimeバージョンの関係(若干自信ないです) UE ~4.27 5.0 5.1 5.2 5.3 5.4 NNI - 1.10 1.12 1.12 - - NNE - - - 1.13 1.13 1.14 ※2024/4/22時点で ONNX Runtime最新は v1.17.3

54.

作ったのでマケプレで公開してます 名前がNNEとややこしい… 公開はこちらが先なので勘弁して… 実態はONNX Runtimeの ラッパー

55.

O N N X R u n t i m e UE外のライブラリを組み込むには • Build.csに依存先を書く • Include • Lib • DLL 公式ドキュメントにも説明あり • DLLの遅延ロード処理をモジュールクラスに書く(Windowsの場合) • ライブラリ固有の初期化処理を書く

56.

Build.csの書き方1:Include Pathを使うのに必要 ここからスタート 単に便利なので定義 PublicIncludePaths.Add

57.

Build.csの書き方2:Lib PublicAdditionalLibraries.Add

58.

Build.csの書き方3:DLL RuntimeDependencies.Add

59.

Build.csの書き方4:DLL遅延ロード準備 PublicDelayLoadDLLs.Add

60.

モジュールクラスでDLLロード実行 DLLのパスを取得 DLLロード実行 FPlatformProcess::GetDllHandle

61.

モジュールクラスでDLL後始末 DLLの解放 FPlatformProcess::FreeDllHandle

62.

ONNX Runtime固有の初期化処理(1/2) ONNX Runtimeの初期化を手動でやると宣言 PublicDefinitions.Add("ORT_API_MANUAL_INIT");

63.

ONNX Runtime固有の初期化処理(2/2) ONNX Runtimeを手動で初期化! Ort::InitApi();

64.

あとはAPIを叩くだけ…! etc...

65.

自作プラグイン所感 • NNEで届かない所に手が届く • プラットフォーム • ランタイム • 特にUE5.4でCUDAランタイムがなくなったように、ベンダ依存の最適化は公式 はやってくれないかも… • 一方で、NNERuntimeRDGのようにGPU上のデータを直接入出 力するのは大変そう • 結局、自作プラグインとNNERuntimeRDGのどちらの方が高パ フォーマンスになるかは計測しないとわからない

66.

マテリアル カスタムHLSLノードでゴリゴリ実装!

67.

やりたいこと:ニューラルな描画処理 • ニューラルネットを使って色を計算して描画したい • GPUでやりたい → マテリアルの中に処理を書くのが理にかなう • マテリアルの「カスタムノード」は、HLSLで任意の処理が書けるので、 そこにニューラルネットを力業で実装すればいいじゃ~ん!^^

68.

MERF • 写真群から3D再構成するNeRFの高効率版 →再構成済みデータをUEでリアルタイム描画 https://www.youtube.com/watch?v=GjpzMDur7UY

69.

マテリアルの概要

70.

レイに沿って ボリュームテクスチャ を積算 ニューラルネットで 色を計算

71.

レイの始点と向きを取得

72.

RGB A レイに沿って2種類の ボリュームテクスチャを積算 ・色と密度 (RGBA) ・特徴量 (F1F2F3F4) (実際はOccupancyグリッドやTri-planeを 併用して効率化しているが省略)

73.

dxdydz F1F2F3F4 RGB ニューラルネットで ピクセルの色を計算 ニューラルネット の定数(重み) ↓画像としてはこんな感じ

74.

Multi-Layer Perceptron ニューラルネットの中身 = MLP dx dy dz Spherical Harmonics Encoding R G B F1 F2 F3 F4 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 … × 𝒘𝟎 × 𝒘𝟏 × 𝒘𝟐 … sum I0 I1 I2 I3 I4 I5 I6 I7 I8 I9 I10 I11 I12 I13 I14 I15 R G B

75.

入力4次元→出力4次元のレイヤーの場合 O0 O1 O2 O3 I0 I1 I2 I3 float4 output float4x4 weight float4 input O0 w00 w01 w02 w03 I0 O1 O2 O3 = × I1 I2 I3 output = mul(weight, input);

76.

入力4次元→出力8次元のレイヤーの場合 float4 output0 float4x4 weight0 O0 w00 w01 w02 w03 O1 O2 = float4 input × I0 O3 I1 float4 output1 float4x4 weight1 I2 O4 O5 O6 I3 = × O7 output0 = mul(weight0, input); output1 = mul(weight1, input);

77.

入力8次元→出力8次元のレイヤーの場合 float4 output00 float4x4 weight00 float4 input0 float4 output0 O0 O0 O2 O1 O3 O2 O1 O4 float4 output1 O6 O5 O6 O7 output0 = mul(weight00, input0); output1 = mul(weight01, input1); output0 += mul(weight10, input0); output1 += mul(weight11, input1); = × I0 I1 float4 output01 float4x4 weight01 O3 O4 w00 w01 w02 w03 O5 O7 I2 I3 = × float4 output10 float4x4 weight10 float4 input1 O0 O1 O2 = × I4 O3 I5 I6 float4 output11 float4x4 weight11 O4 O5 O6 O7 I7 = ×

78.

実際のコード(抜粋) (参考)MERFの公式実装 https://github.com/google-research/googleresearch/blob/master/merf/webviewer/view dependency.glsl UEのNNERuntimeRDGのHLSLによる実装も参 考になりそう

79.

マテリアルで実装 - 所感 • つらい • デバッグしにくい • 実装例が少ない • よいところ • 大抵の環境で動作する • 描画に関する機能に適している • CPUとのデータ転送なし • 作るのは楽しい • ニューラルネットの理解も深まる

80.

まとめ 「UE5でニューラルネットを使っておもしろいことしたい…!」となったら → まずは NNERuntimeORT を試しましょう • 一番簡単 → 画像処理系のモデルの場合は NNERuntimeRDG に挑戦してもよいかも • まだ Experimental なことには注意 → NNEのプラットフォームやランタイムに不満があるなら自前プラグインを作る • 少し面倒だが自由度は上がる →シンプルなモデルならマテリアルの中でHLSLで実装してもいい • 大変だけど、いろいろな環境で動作する

81.

株式会社空き家総合研究所 空き家再生事業のご案内

82.

■空き家再生の業務フロー 買う 直す 貸す 売る 管理する ・空き家再生のはじめからおわりまでを一気通貫で管理 ・家賃収入を目的とした投資家向け収益物件を取り扱い

83.

■なぜ「空き家再生」? 企業理念

84.

■つまり・・・ 企業理念 空き家を直すと… 暮らしやすい世の中に…

85.

■つまり・・・ 企業理念 空き家を直すと… 暮らしやすい世の中に… ならない

86.

■「30分歩くと100戸の空き家が」・・・ ・30分歩くと100戸の空き家が見つかる ・直せる戸数はせいぜい年間20戸 ・直している間に別の100戸が空き家に…

87.

■つまり・・・・・・? 株式会社空き家総合研究所は 「空き家問題解決」を目指しません >>ならばなぜ空き家事業を継続するのか?

88.

■ある日のお問い合わせ 「一時的に避難できる家を借りられないか」 (1)DV被害を受けている母親からの電話 (2)夫からDVを受けていて仕事もできない状況 (3)小さい子供は父親に懐いていて、物心つくまでは離婚は…… (4)家庭事情により、親類や友人を頼ることもできず…… 問題点 (1)保証会社の審査が通らない (2)生活保護は婚姻関係があると受からない (3)公営シェルター(DV被害者のための避難施設)は 連絡手段を持ち込めず学校にも通えない 結果 >>社会福祉施設への案内をすることしかできなかった

89.

空き家を一時避難シェルターとして運用することができたら… 企業理念 >>そのため…

90.

■新規事業・不動産証券化事業 2024年内(予定)に新規事業を開始します! 不動産の収益権を分割し、複数人の投資家たちに 出資額を基に家賃利益や売却利益を分配する 出資 分配

91.

■なぜ「証券化」? 空き家総合研究所 ・不動産投資の敷居を下げたい! 未来の投資家様 ・不動産投資にチャレンジしたい! ・より大きい事業にチャレンジしたい! ・投資を通じて社会に還元したい! ・理念に共感してくれる仲間が欲しい! ・どうせなら面白い企業に出資したい!

92.

100万円あれば始められる 空き家再生をワンストップで行う会社による 社会還元を見越した不動産投資サービス

93.

100万円あれば始められる 空き家再生をワンストップで行う会社による 社会還元を見越した不動産投資サービス 株式会社空き家総合研究所 空き家再生事業 X(旧twitter)