こんにちわ。さくらインターネット在籍の @hasegaw です。今年も Advent Calendar に参加……していたのですが体調不良により投稿が大幅に遅れました😫
今回は、2019年4月に開催されたAI・人工知能EXPO さくらインターネットブースで展示したデモンストレーションの構築時に使ったトリック(?)を紹介します。
弊社ブース@AI人工知能EXPO 2019 |
今回展示したデモ |
デモ制作の背景
2019年は、さくらインターネットとしてもこれまでより大きなブースを作ることになり、立ち寄られた方に楽しんでもらえる「インタラクティブなデモ」をしよう、ということになりました。
以前の展示会でのデモは私が制作していたのですが、時間の都合もあり、今回のデモの実装は Pegara 社にお願いしました。
データセンター内で映像デモを構築
高火力コンピューティングのノードを展示会場で稼働させることにしたのですが、その場での推論結果を大型ディスプレイに表示するには、 Tesla V100 では役不足です(同モデルにはビデオ出力がない)。サーバー用の組み込みビデオプロセッサでは、ビデオの出力性能が貧弱で、今回のデモのようなインタラクティブな描画には向きません。このため、 Tesla の代わりに Quadro RTX 5000 を搭載し、同ボードから映像を出すことにしました。
実質的に「Quadro RTX 5000 を搭載したデュアルプロセッサのワークステーション」ですが、非常に大きなマシンなので、搬出・搬入も一苦労します。このため、最初から最後までデータセンター内でマシン(予備機を含めて2台)のセットアップを済ませておき、データセンターからビックサイトの展示会場まで直送することにしました。
ただ、会場でデモ中に映像が途切れるようなことがあってはテンションだだ下がりです。このため、データセンターに置いたまま、デモの動作が途切れないかを確認するための手段が必要でした。
通常のサーバーであれば、 BMC のリモートコンソール機能が有効ですが、後から Quadro RTX 5000 ビデオカードを増設した場合には、そのような便利機能は使えません。
IP-KVM 装置でも倉庫に転がっていればよかったのですが、そもそもホスティング事業が主なビジネスともいえる弊社の場合、KVM切り替え機すらほとんど見かけません。このため、 Quadro から出力された映像をリモートから確認するというイレギュラーな要件に適したオモチャを適当に見繕う必要がありました。
データセンター内のHDMI映像を観測するためにどうするか
FPGA と言っても、今回利用した PYNQ-Z1 ボードでは、用意されているイメージを microSD カードに書きこむだけで、 HDMI ポートからの DVI-D 信号キャプチャーが可能です。
プログラマブルロジックに Xilinx の AXI Video DMA IP がインプリメントされているので、このレジスタを自分でARMコア側から叩いてやれば、DVI-D から1フレームを読み取るのは割と簡単です。
以前、実験的に「PYNQ-Z1にDVI-Dで入力された映像がが映るVNCサーバ」を試作していたため、それを使いました(使ってみたかったw)
DVI-D信号が映る謎なVNCサーバー |
4-in-1 HDMI マルチビューアの利用
今回、会期中にマシン障害が発生した場合の対策として本番機と予備機の2台を準備しました。この2台のマシンの出力を同時にモニタリングするために複数映像を同時表示できるHDMIマルチビューアを利用しました。
この装置を介しておくとマシンの再起動中などにも常に 1080p60 の信号が出続ける特徴があり、長期間にわたるビデオキャプチャのトラブルを防ぐ上でも有効です。
今回使用した 4-in-1 マルチビューアはシリアルコンソール操作により表示内容の切り替えも可能ですので、両方の画面を出力したり、片方の画面をフルスクリーン表示したり、と遠隔操作することも可能です。
データセンターに設置
全体像 |
データセンターから送られてきたサーバーの映像 (Ubuntu 16.04と、BIOSのPOST画面が映っている) |
これでリモートからVNC経由でデータセンター内の画面を表示できるようになりました。この仕組みは1ヶ月以上無事に動き続け、でデモの開発はほぼリモートで行われ、実際にマシンの前で作業を行ったのは搬出前の動作確認(1日)のみで済みました。
最適化の余地
コードを見られるとすぐわかるのですが、非常に雑な実装でフレームバッファのコピーを繰り返しています。
PYNQのbitstreamに含まれているビデオキャプチャはOpenCVで用いられる1pxあたり24bit BGR順フォーマットに合わせられており、libvncserverが求める1pxあたり32bit RGB順のピクセルフォーマットとは異なっています。このため、今回のコードではOpenCVをcvtColor関数を用いてソフトウェアでフォーマット変換していますが、ちゃんと性能を出したければ PL 側で libvncserver が要求するビデオフォーマットに変換した状態で DMA コントローラに食わることでゼロコピー化も可能でしょう。
以前から事情が変わっていなければOpenCVをNEON命令を利用するように再コンパイルするだけでも上記の色変換処理の速度はあがるのですが、PYNQ-Z1のメモリ帯域幅は細いのので PL からビデオのピクセルデータを受け取る時点で工夫するのが理想です。
また、フレームバッファのなかで変化した範囲を libvncserver に渡せれば画面の差分転送が可能になるので、そこまでやりきれば、一般的なデスクトップ画面などを転送する場合にパフォーマンスが高いものが作れるのではないかと思っています。
VNCは、変更があった領域のみを転送することが可能なプロトコルですので、各種パフォーマンスのチューニングをしていけば今後で活用余地が見いだせるのではないかと思っています。
別の実装方法
今回使用したVNCサーバーは、まだホントに画面が映るだけで差分転送をしていないので画面全体を毎回再転送するため非効率でした。正直なところ、性能だけを考えれば、入力フレームをMotion JPEG にエンコードしてストリーミングする実装を使ったほうが良かったと思います。
— IkaLog_JA (@IkaLog_ja) February 23, 2017
別のハードウェアを使う方法として Raspberry Pi シリーズは H.264 エンコーダを持っているので、映像のストリーム送信の用途には向いています。CSI-2 カメラインターフェイスにHDMI to CSI変換モジュールを取り付けるとHDMI映像をキャプチャできます。私がこの作業を行ったときはまだ OpenMomoなどが利用できる状況にはなかったのですが、今時だとH.264+WebRTCなどもアリですね。
手元でも Raspberry Pi 4 + B101 ボードで色々試しています。 |
まとめ
映像デモマシンをデータセンター内に設置して開発するために、今回は手持ちの ARM+FPGA ボードでこしらえた「受信したDVI-D映像を表示できるVNCサーバー」を使ってみました。
HDMI映像をIP経由でストリーミングできる手段は増えてきていますが、こんな方法もあるということで参考になれば幸いです。
この記事はさくらインターネット Advent Calendar 2019 の 6日目でした。7日目の記事もお楽しみに。
過去に参加した Advent Calendar まとめ
- 2018年12月: AMD GPUによるディープラーニング環境の構築
- 2015年12月: スプラソン機材セットをつくりました
- 2015年12月: おうちハックで戦った話
- 2015年12月: Fluent-bit と XBee で作るセンサーネットワーク
- 2013年12月: 次世代I/Oインターフェイス「Eject-io」
- 2012年12月: 割り込みはいかにしてゲストの割り込みハンドラに届くのか
- 2011年1月: FreeBSD VIMAGEを使ったTCP/IPのルーティング デモンストレーション