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
地域社会の安心に貢献し、暮らしやすい世の中をつくるために、主な事業として空き家専門の工事会社・不動産屋として空き家再生・活用に取り組んでいます。また、演劇教室「劇ゼミ」の運営、VR・AI技術開発も行っています。
UE5でニューラルネットを 使ういくつかの方法 NNE、自作プラグイン、マテリアル 2024/04/28 Unreal Engine Meetup in Osaka Vol.02 株式会社空き家総合研究所
スピーカー • 麻場 健司(𝕏:@KenjiASABA) • 株式会社空き家総合研究所 • 社員5人 • 全員、関西の学生劇団出身 • 主な事業は3つ • 空き家再生 • 演劇教室 • VR・AI技術開発
UE × AI な製品を作っています • MocapForAll (2021) • 複数ウェブカメラで モーションキャプチャ • UE4.26 × 姿勢推定 https://vrlab.akiyasouken.co.jp/video/mocapforall.mp4
UE × AI な製品を作っています • MocapForStreamer (2022) • 2台のウェブカメラで 上半身モーキャプ • UE4.26 × 姿勢推定 https://vrlab.akiyasouken.co.jp/video/mocapforstreamer.mp4
UE × AI な製品を作っています • WhisperRealtime (2023) • 音声→テキスト • UE4.26 × 音声認識 https://vrlab.akiyasouken.co.jp/video/whisperrealtime_ja.mp4
UE × AI な製品を作っています • 3D Gaussians Plugin (2023) • 3D Gaussian Splatting 描画プラグイン • UE5.1 × 3DGS https://vrlab.akiyasouken.co.jp/video/3dgaussian.mp4
UE × AI な技術支援も行っています • KSIN • 株式会社ユニキャスト様、 株式会社デジタル・フロンティア様 • アバター接客システム • UE4.27 × 姿勢推定 https://www.youtube.com/watch?v=W2fn3rl95QI
UE × AI な技術支援も行っています • Vista Splat Pro • バーチャル・ライン・スタジオ株式会社様、 株式会社デジタル・フロンティア様 との共同開発 • UE5.1 × 3DGS https://www.youtube.com/watch?v=PWtyqMOHOyg
UE × AI な技術支援も行っています • UEとAIで何かしたい • 知見がほしい、手が足りない → ご相談ください!
https://www.unrealengine.com/ja/blog/unreal-engine-5-4-is-now-available
機械学習 ニューラルネット? MLモデル? • 計算の手続きを定めたもの(≒関数) • UEのBPやマテリアルのように • 演算(処理)を表すノード • 定数 • 入出力 ノード 定数 入出力 を組み合わせて表すのが一般的 実行順
機械学習 ニューラルネット? MLモデル? • 計算の手続きを定めたもの(≒関数) • UEのBPやマテリアルのように • 演算(処理)を表すノード • 定数 • 入出力 ノード 定数 入出力 を組み合わせて表すのが一般的 • 定数は「重み」とも呼ばれる • 同じ演算でもこれが違えば結果が違う • 所望の結果を返す関数となるように定数を 求める過程が「学習」 • 学習後、所望の結果を返す関数として単に 使うことを「推論」と呼ぶ 実行順
今日お話しすること ニューラルネットと呼ばれるちょっと特殊な形式で定義された関数を UEに取り込んで実行するにはどうすればいいのか、というお話 具体的には • UE5でのニューラルネットによる推論の実行方法3つ • 公式NNEプラグイン • 自作プラグイン • マテリアル内のカスタムHLSLノード 今日お話ししないこと • ニューラルネットの学習
NNEプラグイン 私がコードを読んで推測した内容を多分に含みます
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版 を紹介します
:実験的機能 β :ベータ機能 NNEの構成 NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU
β :ベータ機能 NNEの構成(抜粋) NNE エンジンモジュール NNERuntimeORT プラグイン β ONNX Runtime ランタイム DirectML (Winのみ) ハードウェア CPU GPU
ONNX Runtime? ONNX形式のニューラルネットを実行するライブラリ 各 種 機 械 学 習 フ レ ー ム ワ ー ク エクスポート 実行 …
β :ベータ機能 NNEの構成(抜粋・再掲) NNE エンジンモジュール NNERuntimeORT プラグイン β ONNX Runtime ランタイム DirectML (Winのみ) ハードウェア CPU GPU
DirectML? • 機械学習でよく使われる演算を GPUで効率よく実行するための ライブラリ • DirectX 12対応のGPUで動作する ハードウェアアクセラレータ と呼ばれるものの一つ NVIDIA、AMD等の いずれでもOK
ONNX Runtimeのメリット①: クロスプラットフォーム https://onnxruntime.ai/getting-started :NNEでサポート
ONNX Runtimeのメリット②: 計算の自動最適化 • 不要な計算ノードの削除 • 計算ノードの結合 • 実際に速くなるかは環境による 最適化 最適化 https://onnxruntime.ai/docs/performance/mobile-performance-tuning.html
:実験的機能 β :ベータ機能 NNEの構成(再掲) NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU
NNE使い方 - 全体の流れ • プラグイン有効化 • ONNXモデルインポート • 依存モジュールに追加 • ランタイム取得 • モデルインスタンス生成 • 入力形状のセット • 入出力のバインドと実行 ↑エディタ ↓C++, C# ↑定型作業 ↓モデル個別
NNE使い方1:プラグイン有効化
NNE使い方2:ONNXモデルインポート
NNE使い方3:依存モジュールに追加 ModuleName.build.cs
NNE使い方4:ランタイム取得(1/2)
:実験的機能 β :ベータ機能 NNEの構成(再掲) NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU
NNE使い方4:ランタイム取得(2/2)
NNE使い方5:モデルインスタンス生成
複数の配列(テンソル)を入出力する ~~~~~~~~~ 略 ~~~~~~~~~ 可変サイズの入力が可能な場合がある https://netron.app/
NNE使い方6:入力形状のセット 入力形状が可変のモデルの場合 … 入力形状を手動で指定 入力形状をセット
NNE使い方6:入力形状のセット 入力形状が固定のモデルの場合 モデルの入力形状を取得 … モデルの入力形状を指定 入力形状をセット
NNE使い方7:入出力をバインドし実行 入力TArray(の配列) 出力TArrayの配列 FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync
NNE使い方7:入出力をバインドし実行 入出力データを保持するメモリ領域を確保 入力TArray(の配列) 出力TArrayの配列 FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync
NNE使い方7:入出力をバインドし実行 入力TArray(の配列) 出力TArrayの配列 NNE入出力用の統一的な形式にする FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync データへのポインタ とサイズ
NNE使い方7:入出力をバインドし実行 入力TArray(の配列) 出力TArrayの配列 FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync
NNE使い方7:入出力をバインドし実行 入力TArray(の配列) 出力TArrayの配列 FTensorBindingGPU の配列 FTensorBindingGPU の配列 ModelInstance->RunSync この中でCPU⇔GPUのデータ転送も実行
CPU⇔GPUのデータ転送? 入力TArrayの配列 出力TArrayの配列 入力バッファ 出力バッファ 入力 データ CPU(ホスト)メモリ GPU(デバイス)メモリ CPU GPU
CPU⇔GPUのデータ転送? コピー 入力TArrayの配列 出力TArrayの配列 入力 データ 入力バッファ 出力バッファ 入力 データ CPU(ホスト)メモリ GPU(デバイス)メモリ CPU GPU
CPU⇔GPUのデータ転送? 入力TArrayの配列 出力TArrayの配列 入力 データ CPU(ホスト)メモリ 入力バッファ 出力バッファ 入力 データ 出力 データ GPU(デバイス)メモリ 演算 CPU GPU
CPU⇔GPUのデータ転送? コピー 入力TArrayの配列 出力TArrayの配列 入力バッファ 出力バッファ 入力 データ 出力 データ 入力 データ 出力 データ CPU(ホスト)メモリ GPU(デバイス)メモリ CPU GPU
:実験的機能 β :ベータ機能 NNEの構成(再掲) NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU
NNERuntimeRDG • RDG? • Render Dependency Graph • レンダリング依存関係グラフ • UEの描画機能を呼び出すAPI • GPU上のメモリを直接読み書き してAIを実行できる • CPU⇔GPU間のデータ転送が不要 な画像処理等に向いている • NeuralRenderingプラグインから 利用されている 入力バッファ 出力バッファ 入力 データ 出力 データ GPU(デバイス)メモリ 演算 GPU
NeuralRenderingプラグイン ツイート: https://twitter.com/historia_Inc/status/ 1777993243613155652 記事: https://historia.co.jp/archives/40788/
NNERuntimeRDGのサンプル • NeuralRenderingの処理 • ApplyNeuralNetworks_RenderingThread • 入出力バッファに対する前処理・後処理 • 下記の「Execute」を実行 • UNeuralPostProcessModelInstance::Execute • 入出力のバインディング • ModelInstanceRDGに対して「EnqueueRDG」を実行 • NNERuntimeORTの「RunSync」に対応
AI系の他のプラグインから参照 :実験的機能 β :ベータ機能 MLDeformer/NearestNeighborModel MLDeformer/NeuralMorphModel LearningAgent NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU
:実験的機能 β :ベータ機能 モバイル・エッジ デバイス向け? NNE エンジンモジュール プラグイン NNERuntimeBasicCpu NNERuntimeIREE NNERuntimeORT IREE ONNX Runtime β NNERuntimeRDG ランタイム DirectML (Winのみ) UE独自実装 (ISPC) ハードウェア CPU UE独自実装 (HLSL) GPU
:実験的機能 UE5.3でのNNEの構成 NNE プラグイン NNERuntimeORTCpu NNERuntimeORTGpu NNERuntimeRDG ONNX Runtime ONNX Runtime ONNX Runtime ランタイム ハードウェア NVIDIA CUDA CPU DirectML (Winのみ) GPU UE独自実装 (HLSL)
NNE所感 • NNERuntimeORT • ONNX Runtimeのラッパー • 基本的な使い方はUEとORTの公式ドキュメントを読めばOK • 対応するプラットフォームやランタイムは少ないが、今後増えるかも? • 現状は、Win・Linux・Mac、CPU・DirectML • ONNX Runtimeのビルド済みバイナリを適切に追加すればこれを増やせる • NNERuntimeRDG • UEのRDGバッファを入出力に使う • CPU⇔GPU間のデータ転送をしない画像処理等に適した設計 • UE5.4のNeuralRenderingプラグインから使われている • 今後、他の公式プラグインからも使用される可能性はありそう • 現段階では対応する演算が少ないなど実利用は難しそう? • 今後に期待!!
自作プラグイン NNEで飽き足らない場合は自分で作ろう
あえて自作プラグインを作る理由 • 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
作ったのでマケプレで公開してます 名前がNNEとややこしい… 公開はこちらが先なので勘弁して… 実態はONNX Runtimeの ラッパー
O N N X R u n t i m e UE外のライブラリを組み込むには • Build.csに依存先を書く • Include • Lib • DLL 公式ドキュメントにも説明あり • DLLの遅延ロード処理をモジュールクラスに書く(Windowsの場合) • ライブラリ固有の初期化処理を書く
Build.csの書き方1:Include Pathを使うのに必要 ここからスタート 単に便利なので定義 PublicIncludePaths.Add
Build.csの書き方2:Lib PublicAdditionalLibraries.Add
Build.csの書き方3:DLL RuntimeDependencies.Add
Build.csの書き方4:DLL遅延ロード準備 PublicDelayLoadDLLs.Add
モジュールクラスでDLLロード実行 DLLのパスを取得 DLLロード実行 FPlatformProcess::GetDllHandle
モジュールクラスでDLL後始末 DLLの解放 FPlatformProcess::FreeDllHandle
ONNX Runtime固有の初期化処理(1/2) ONNX Runtimeの初期化を手動でやると宣言 PublicDefinitions.Add("ORT_API_MANUAL_INIT");
ONNX Runtime固有の初期化処理(2/2) ONNX Runtimeを手動で初期化! Ort::InitApi();
あとはAPIを叩くだけ…! etc...
自作プラグイン所感 • NNEで届かない所に手が届く • プラットフォーム • ランタイム • 特にUE5.4でCUDAランタイムがなくなったように、ベンダ依存の最適化は公式 はやってくれないかも… • 一方で、NNERuntimeRDGのようにGPU上のデータを直接入出 力するのは大変そう • 結局、自作プラグインとNNERuntimeRDGのどちらの方が高パ フォーマンスになるかは計測しないとわからない
マテリアル カスタムHLSLノードでゴリゴリ実装!
やりたいこと:ニューラルな描画処理 • ニューラルネットを使って色を計算して描画したい • GPUでやりたい → マテリアルの中に処理を書くのが理にかなう • マテリアルの「カスタムノード」は、HLSLで任意の処理が書けるので、 そこにニューラルネットを力業で実装すればいいじゃ~ん!^^
MERF • 写真群から3D再構成するNeRFの高効率版 →再構成済みデータをUEでリアルタイム描画 https://www.youtube.com/watch?v=GjpzMDur7UY
マテリアルの概要
レイに沿って ボリュームテクスチャ を積算 ニューラルネットで 色を計算
レイの始点と向きを取得
RGB A レイに沿って2種類の ボリュームテクスチャを積算 ・色と密度 (RGBA) ・特徴量 (F1F2F3F4) (実際はOccupancyグリッドやTri-planeを 併用して効率化しているが省略)
dxdydz F1F2F3F4 RGB ニューラルネットで ピクセルの色を計算 ニューラルネット の定数(重み) ↓画像としてはこんな感じ
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
入力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);
入力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);
入力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 = ×
実際のコード(抜粋) (参考)MERFの公式実装 https://github.com/google-research/googleresearch/blob/master/merf/webviewer/view dependency.glsl UEのNNERuntimeRDGのHLSLによる実装も参 考になりそう
マテリアルで実装 - 所感 • つらい • デバッグしにくい • 実装例が少ない • よいところ • 大抵の環境で動作する • 描画に関する機能に適している • CPUとのデータ転送なし • 作るのは楽しい • ニューラルネットの理解も深まる
まとめ 「UE5でニューラルネットを使っておもしろいことしたい…!」となったら → まずは NNERuntimeORT を試しましょう • 一番簡単 → 画像処理系のモデルの場合は NNERuntimeRDG に挑戦してもよいかも • まだ Experimental なことには注意 → NNEのプラットフォームやランタイムに不満があるなら自前プラグインを作る • 少し面倒だが自由度は上がる →シンプルなモデルならマテリアルの中でHLSLで実装してもいい • 大変だけど、いろいろな環境で動作する
株式会社空き家総合研究所 空き家再生事業のご案内
■空き家再生の業務フロー 買う 直す 貸す 売る 管理する ・空き家再生のはじめからおわりまでを一気通貫で管理 ・家賃収入を目的とした投資家向け収益物件を取り扱い
■なぜ「空き家再生」? 企業理念
■つまり・・・ 企業理念 空き家を直すと… 暮らしやすい世の中に…
■つまり・・・ 企業理念 空き家を直すと… 暮らしやすい世の中に… ならない
■「30分歩くと100戸の空き家が」・・・ ・30分歩くと100戸の空き家が見つかる ・直せる戸数はせいぜい年間20戸 ・直している間に別の100戸が空き家に…
■つまり・・・・・・? 株式会社空き家総合研究所は 「空き家問題解決」を目指しません >>ならばなぜ空き家事業を継続するのか?
■ある日のお問い合わせ 「一時的に避難できる家を借りられないか」 (1)DV被害を受けている母親からの電話 (2)夫からDVを受けていて仕事もできない状況 (3)小さい子供は父親に懐いていて、物心つくまでは離婚は…… (4)家庭事情により、親類や友人を頼ることもできず…… 問題点 (1)保証会社の審査が通らない (2)生活保護は婚姻関係があると受からない (3)公営シェルター(DV被害者のための避難施設)は 連絡手段を持ち込めず学校にも通えない 結果 >>社会福祉施設への案内をすることしかできなかった
空き家を一時避難シェルターとして運用することができたら… 企業理念 >>そのため…
■新規事業・不動産証券化事業 2024年内(予定)に新規事業を開始します! 不動産の収益権を分割し、複数人の投資家たちに 出資額を基に家賃利益や売却利益を分配する 出資 分配
■なぜ「証券化」? 空き家総合研究所 ・不動産投資の敷居を下げたい! 未来の投資家様 ・不動産投資にチャレンジしたい! ・より大きい事業にチャレンジしたい! ・投資を通じて社会に還元したい! ・理念に共感してくれる仲間が欲しい! ・どうせなら面白い企業に出資したい!
100万円あれば始められる 空き家再生をワンストップで行う会社による 社会還元を見越した不動産投資サービス
100万円あれば始められる 空き家再生をワンストップで行う会社による 社会還元を見越した不動産投資サービス 株式会社空き家総合研究所 空き家再生事業 X(旧twitter)