ビルド・テスト環境の仮想化
連載記事 ailia SDKの品質を支えるビルド&テスト環境の第3回目です。
ailia SDKはWindows Mac iOS Android Linuxといった様々な環境に対応する クロスプラットフォーム対応高速CNN推論エンジンです。
AVXやNEONといった各環境で利用可能なSIMD命令に対応したり、GPGPUの性能を最大限引き出すためcuDNNやMetalの他にVulkanなどにも対応することで各環境での高速推論を実現しております。
はじめに
第2回ではailiaで行っている単体テストの自動生成方法について解説しました。
今回はailiaで使用しているCI環境のうち、Linuxビルド・テスト環境とAndroidホストサーバーの仮想化のお話です。
事の発端
当時私のデスクの上には以下のように開発PCの他にCI環境へつなげていた検証機材が配置されていました。

デスクの上のマシン構成
この状態でailiaのLinux対応が始まり、ビルド用マシンとテスト用マシンの追加の検討が始まりました。

Linuxビルド・検証環境の追加案
流石にデスクの上に4台のマシンを並べるのはスペース的に厳しいのと、管理する台数が増え管理の手間が増える上、ハードウェア故障の際に困るという問題があるので既存のAndroidホストサーバーと新規で追加するLinuxマシンを仮想化することとしました。
KVMについて
KVM (Kernel-based Virtual Machine)はLinuxカーネルをハイパーバイザーとして動作させるカーネルモジュールです。
KVMを利用するにはホストマシンのCPUが仮想化支援(Intel VT/AMD-V)に対応している必要があります。
通常は仮想マシンエミュレーターであるQEMUと併用することで高速な仮想マシン環境を実現します。
また、仮想デバイスのI/Oを高速化するためvirtioを利用して準仮想化デバイスを実現することも可能です。
KVMやQEMUの仮想環境の操作にはlibvirtやそれをWeb UIでラップしたcockpitが便利です。
仮想化環境の構成

仮想環境の構成
ailiaの検証に必要な3台を仮想化します。また、これらのマシンを接続する仮想スイッチを用意し、Linux検証環境にはホストPCに接続されているGPUをPCIeパススルーで接続、AndroidホストサーバーにはPCIe-USBコントローラをPCIeパススルーで接続します。
KVM+QEMUでUSBパススルーも実現可能ですが、切断・再接続時の信頼性を考えUSBコントローラーごとパススルーをさせることとしました。
(なお、ホストマシンに別のUSBコントローラーが存在しない場合、ホストマシンではUSBが利用できなくなります。)
環境構築
ホスト環境はCentOS8で構築を行いました。
まずは必要なパッケージをインストールします。
を参考に作業しました。
続けてPCIeパススルーが利用できるよう、IOMMUの設定とvfio-pciのロードを行いました。
を参考に作業しました。
なお、GPUのVendor ID・Device IDの他USBコントローラーのVendor ID・Device IDも調査しておきます。
$ lspci -nn...
00:14.0 USB controller [0c03]: Intel Corporation 100 Series/C230 Series Chipset Family USB 3.0 xHCI Controller [8086:a12f] (rev 31)
...
次に仮想スイッチを作成します。
nmcli con add type bridge ifname <ブリッジネットワーク名>nmcli con mod <ホストマシンのNICのコネクション名> master <ブリッジコネクション名(通常はbridge-<ブリッジネットワーク名>)> slave-type bridge
ブリッジネットワーク作成後ホストマシンのNICのコネクションの設定をブリッジコネクションへコピーしておきます。
また、仮想マシンの操作を管理者権限不要で行えるよう、作業中ユーザーをlibvirtグループへ追加します。
sudo usermod -aG libvirt <ユーザー名>
これで仮想マシンのホスト環境が整いました。
仮想マシンの作成
まずは仮想マシンのディスクを作成します。
ディスクフォーマットは色々ありますが、パフォーマンスを優先してrawを選択しました。
qemu-img create -f raw <仮想ディスクへのパス> <ディスクサイズ>
続けてVMを作成します。
仮想マシンの作成コマンド例
このとき--hostdev でPCIデバイスを指定することでゲスト環境へパススルーをさせることができます。
仮想マシン作成後自動的に仮想マシンが立ち上がるのでvirt-viewerなどでVMの仮想ディスプレイへ接続し、ゲストOSのインストール作業を行います。
インストール後仮想マシンをシャットダウンし、ブートローダーを変更します。
virsh edit <仮想マシン名>
仮想マシンの構成ファイルが表示されるため<os><boot dev='cdrom,hd'>を<os><boot dev='hd'>に変更します。
その後仮想ディスクを取り外しVMを起動します。
virsh change-media <仮想マシン名> <cdromのVM上のデバイス名 例:sda> --eject
virsh start <仮想マシン名>
仮想マシン起動後ゲストOS側でシリアルポートの有効化を行います。
ゲストOSがCentOS8の場合は/etc/default/grubにGRUB_TERMINAL_OUTPUTの追加とGRUB_COMMANDLINE_LINUXの末尾にconsole=ttyS0を追記します。
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="... console=ttyS0"
VMを再起動後ホストマシンからシリアル経由でゲストマシンへ接続できるかテストします。
virsh console <仮想マシン名>
シリアルポートに接続できることを確認したあと、仮想ディスプレイを削除します。
virsh edit <仮想マシン名>
仮想マシンの構成ファイルが表示されるため <graphics>を削除します。
おわりに
今回はailiaで使用している検証環境を仮想化するお話をさせていただきました。
ailiaの検証環境ではこのあと、テスト用データを検証環境間で共有するために内部ネットワークを追加し、Sambaでファイル共有を追加したり、cockpitを導入してWebから仮想マシンの管理を行えるように変更したりしました。
また、検証環境を仮想化することで、検証環境のバックアップがファイルコピーで可能になったり、複数のディストリビューションのディスクイメージを用意し、同じGPUを利用しての検証ができるなどの追加メリットもありました。
アイリア株式会社はAIを実用化する会社として、クロスプラットフォームでGPUを使用した高速な推論を行うことができるailia SDKを開発しています。アイリア株式会社ではコンサルティングからモデル作成、SDKの提供、AIを利用したアプリ・システム開発、サポートまで、 AIに関するトータルソリューションを提供していますのでお気軽にお問い合わせください。
ailia Tech BLOG