ヴェズルフェルニルの研究ノート

座右の銘「ただ一人犀の角のように歩め」的な研究活動ノート

Microsoft Azureで仮想マシンを作成してみる [2]

前記事に続いて、Azureで作成した仮想マシンへリモート接続する環境を構築していく。

SSHによる仮想マシンへの接続

最初にAzureで作成した仮想マシンIPアドレスを知る必要があるが、その方法は前記事に書いた。

当然ながら、以降の操作を行うには、先にAzureポータルサイト仮想マシンを起動しておく必要がある。

なお、本記事では、仮想マシン・テンプレートとしてUbuntu Server 20.04を選択したことを前提として説明していく。

仮想マシンSSH経由で接続するには、下のコマンドを使う。

$ ssh -i ~/.ssh/id_rsa azureuser@VM_IP_ADDRESS

Azureポータルサイトでの仮想マシン作成時に、ssh-keygenコマンドによって生成された~/.ssh/id_rsa.pubの内容を公開キーとして指定したなら、デフォルトでは秘密キーは~/.ssh/id_rsaに格納されているはずだ。上のコマンドでは、このファイルを指定してSSHクライアントにより仮想マシンへの接続を試みている。

SSHクライアントで仮想マシンへ接続すると、以下のようなメッセージが表示されてログインできる。

Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-1041-azure x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Jul  2 03:01:48 UTC 2023

  System load:  0.08              Processes:             138
  Usage of /:   5.2% of 28.89GB   Users logged in:       0
  Memory usage: 4%                IPv4 address for eth0: 10.0.0.4
  Swap usage:   0%

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo ".
See "man sudo_root" for details.

ssh-keygenコマンドによるSSHキー組の作成時にパスフレーズを設定した場合は、それをパスワードとして入力することを求められるので、正しいパスフレーズを入力すれば仮想マシンにログインできる。

仮想マシンへの接続ログイン時にパスフレーズ入力を省略したい場合は、ローカル側で以下のコマンドを実行すれば良い。

$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rda

Macの場合、ssh-addコマンドを下のように変える。

% ssh-add --apple-use-keychain ~/.ssh/id_rda

毎回ssh-keygenコマンドに上記のオプションを指定するのが面倒なら、以下のような内容の~/.ssh/configを作成しておくと良い。

```bash:~/.ssh/config Host VM_HOST_NAME HostName VM_IP_ADDRESS Port 22 User azureuser UseKeychain yes IdentityFile ~/.ssh/id_rsa IdentitiesOnly yes TCPKeepAlive yes ServerAliveInterval 60 ServerAliveCountMax 5

  
このファイルを作成しておけば、下のコマンドによって仮想マシンへ接続できるようになる。
  

$ ssh VM_HOST_NAME

  
# リモートデスクトップによる仮想マシンへの接続

リモートデスクトップを使ってAzureの仮想マシンへ接続したい場合は、仮想マシン側のRDP用受信ポートを開放しておく必要がある。  
  
Azureポータルサイトのホーム画面 > [Virtual Macines] > 目的の仮想マシン > [ネットワーク]の画面でそれができる。この画面の[ 受信ポートの規則を追加する ]を押すと、下のような画面になる。  

[f:id:Vedfolnir:20230702115409p:plain]

この画面の **[サービス]** メニューから **[RDP]** を選んで、[ 追加 ]を押せば、仮想マシンへRDP用受信ポートを追加できる。  
  
Ubuntu ServerなどのCLIベースの仮想マシン・テンプレートを選択した場合は、仮想マシン上にGUIデスクトップは存在しないので、それを先にインストールしておく必要がある。  

Linux用のGUIデスクトップはいくつか種類があるが、UbuntuデフォルトのGNOMEは描画処理が重くて、リモートデスクトップでの利用には適していないと思う。GNOMEの代わりにXfceやMATEを利用することを薦める。あえてGNOMEを利用したい場合は、下のリンクを参照してほしい。  

[https://kogelog.com/2020/05/12/20200512-01/:embed:cite]

XfceあるいはMATEを利用する場合は、以下のコマンドをSSH接続中の仮想マシン上で実行することでインストールできる。  

- Xfce

<pre style="background-color:#1f1f1f;"><code style="color: #ffffff;">$ sudo apt update
$ sudo apt install -y xubuntu-desktop
$ sudo apt install -y xfce4 xfce4-goodies
</code></pre>

- MATE

<pre style="background-color:#1f1f1f;"><code style="color: #ffffff;">$ sudo apt update
$ sudo apt install -y ubuntu-mate-desktop
</code></pre>

初めて仮想マシンへGUIデスクトップをインストールした場合は、下のようなディスプレイマネージャの選択を求める画面が表示されるが、この画面ではどちらを選んでも問題ない。  

[f:id:Vedfolnir:20230702125501p:plain]

リモートデスクトップを使ってAzureの仮想マシンへ接続したい場合は、仮想マシン側にRDPサーバーをインストールして稼働状態にしておく必要がある。以下のコマンドによってそれを行える。  
  
<pre style="background-color:#1f1f1f"><code class="language-bash" style="color: #ffffff">$ sudo apt install -y  xrdp
$ sudo systemctl enable xrdp
$ sudo adduser xrdp ssl-cert
$ echo "xfce4-session" > ~/.xsession
$ sudo service xrdp restart
</code></pre>
  
上記は、GUIデスクトップとしてXfceを利用する場合で、MATEの場合は`echo`コマンドを下のように変える。  
  
<pre style="background-color:#1f1f1f"><code class="language-bash" style="color: #ffffff">$ echo "mate-session" > ~/.xsession
</code></pre>
  
RDP経由で仮想マシンへ接続する場合、SSH認証情報は利用できないので、通常の方法でログインするしかない。そのため、RDP接続用に最低でも一つのユーザーの通常ログイン用パスワードを設定する必要がある。以下のコマンドによって、仮想マシン上のユーザーのパスワードを設定しておく。  
  
<pre style="background-color:#1f1f1f"><code class="language-bash" style="color: #ffffff">$ sudo passwd azureuser
</code></pre>
  
以上の操作が済めば、仮想マシン側でのRDP経由接続の受け入れ準備が整う。

あとは、ローカル側からリモートデスクトップ・クライアントを使って仮想マシンへ接続することになる。UbuntuならRemmina、MacならMicrosoft Remote Desktopが有名どころだろう。  
  
RDPクライントから仮想マシンへ接続する場合は、その前に必ずローカル側で下のコマンドを実行しておく。  
  

$ ssh -L 3389:localhost:3389 azureuser@VM_HOST_NAME

  
このコマンドを実行すると、仮想マシンへSSH接続できるが、同時にローカル側でポート3389への通信をリモート(仮想マシン)側のポート3389へ転送する状態になる。この状態でRDPクライントから`localhost:3389`へ接続すれば、仮想マシンへRDP経由で接続できる。  
  
Microsoft Remote Desktopなら、下のような内容のリモート接続設定を作成して、それを使ってAzure仮想マシンへ接続する。  

[f:id:Vedfolnir:20230702220945p:plain]

RDPクライントで仮想マシンへ接続しようとすると、毎回下のような警告が表示されるが、この画面では [Continue] を押せば、仮想マシンへの接続が継続される。  

[f:id:Vedfolnir:20230702230314p:plain]

仮想マシンへ接続されると、下のようなログイン画面が表示されるので、上記で設定したユーザーのパスワードを入力すればログインできる。  

[f:id:Vedfolnir:20230702231336p:plain]

[f:id:Vedfolnir:20230702233824p:plain]

# X2Goによる仮想マシンへの接続

MicrosoftのAzureヘルプ情報サイトでは、xrdp/RDPよりもX2Goというリモートデスクトップの方が描画性能が高いので、X2Goを使うことが推薦されている。  

[https://learn.microsoft.com/ja-jp/azure/lab-services/how-to-enable-remote-desktop-linux:embed:cite]

実際に使ってみると、たしかにX2Goの方が描画が速いので、私もいまはX2Goを使っている。  
  
Ubuntuベースの仮想マシンにX2Goサーバーをインストールするには、下のコマンドを実行すれば良い。    
  

<pre style="background-color:#1f1f1f"><code class="language-bash" style="color: #ffffff">$ sudo apt install -y x2goserver x2goserver-xsession
</code></pre>
  
ローカル側にX2Goクライアントをインストールするには、Ubuntuなら下のコマンドによってできる。  
  

$ sudo apt install -y x2goclient

  
Macなら、下のサイトからインストーラをダウンロードできる。  

[https://wiki.x2go.org/doku.php/download:start:embed:cite]

なお、Macでx2goclientを使う場合は、先に<a href="https://www.xquartz.org/" target="_blank">XQuartz</a>をインストールしておく必要がある。

[f:id:Vedfolnir:20230703080829j:plain]

x2goclientのAzure仮想マシン用セッション設定は、下のような内容になる(**[Session name]** は任意の名前、**[Host]** には仮想マシンのIPアドレスを入力)。  

[f:id:Vedfolnir:20230703070653j:plain]

なお、仮想マシンへのリモートデスクトップ接続にX2Goだけを利用する場合、仮想マシン側の受信ポートは SSH (22) だけが使用されるので、RDP (3389) は削除しておいた方が良い。

# 補足情報

以下のサイトに、GNOME/xrdp、MATE/X2Go、Xfce/X2Goを一括でインストールできるシェルスクリプトが掲載されている。
このシェルスクリプトを利用すると、一度のコマンド実行でこれらの組み合わせをUbuntuベースのAzure仮想マシンへインストールできる。  

[https://github.com/Azure/LabServices/blob/main/TemplateManagement/PowerShell/LinuxGraphicalDesktopSetup/GNOME_MATE/ReadMe.md:embed:cite]

[https://github.com/Azure/LabServices/blob/main/TemplateManagement/PowerShell/LinuxGraphicalDesktopSetup/XFCE_Xubuntu/ReadMe.md:embed:cite]
  
  
**【参照リンク】**

[https://learn.microsoft.com/ja-jp/azure/virtual-machines/linux-vm-connect?tabs=Linux:embed:cite]

[https://www.hiroom2.com/ubuntu-2004-xrdp-xfce-ja/:embed:cite]

[https://www.hiroom2.com/ubuntu-2004-xrdp-mate-ja/:embed:cite]

[https://www.digitalocean.com/community/tutorials/how-to-set-up-a-remote-desktop-with-x2go-on-ubuntu-20-04:embed:cite]

[blog:g:4207112889945342980:banner]

Microsoft Azureで仮想マシンを作成してみる [1]

ある人に勧められたのがきっかけで、Microsoft Azureクラウドコンピューティング・サービスを使ってみた。

その経験を2つに分けて、本記事ではAzureで仮想マシンを作成するまでを、2回目の記事ではその仮想マシンをリモートで使える状態にするまでの作業過程を書く。

Azureクラウドコンピューティングの概要

Azureのクラウドコンピューティング・サービスを利用するには、先にMicrosoftアカウントを作成しておく必要があるが、こちらの説明は省略する。

本記事を書いている時点で、Azureにアカウント登録すると30日間有効な$200分の無料枠が提供される。先にこの無料枠を前課金分として取得しておかないと、新しい仮想マシンを作成することはできない。無料枠を取得すれば、その分の前課金範囲内であれば無償でAzureのクラウドコンピーティングを利用することができる。

Azureには色々な用途別に環境が設定済みの仮想マシン・テンプレートが用意されている。例えば「data science」で検索すると、下のように多くのテンプレートが存在する。

この中から選んで仮想マシンを作成すれば、基本的な開発・稼働環境構築作業の手間を省ける。また、OSだけを選んで仮想マシンを作成し、そこへ一から環境を構築していくこともできる。今回はこの方法を選ぶことにした。

Azureでの仮想マシン作成

無料枠を取得すると、サブスクリプションが作成されて、その分が前課金としてチャージされる。その状態では、Azureのホーム画面は下のようになる。

この画面から [リソースの作成] を選ぶと、下のような画面に変わる。

この画面のいずれかの仮想マシン種別の [作成] を選ぶと、仮想マシンの設定画面が表示される(または、前述の仮想マシン・テンプレート検索結果画面から一つを選んだ上で、その画面内の [作成] を押しても、下の仮想マシンの設定画面へ移ることができる)。

上が仮想マシンの設定開始画面だが、まず最初にリージョンを決めないといけない。リージョンとは仮想マシンが設置される場所で、リージョンによって選択可能なマシンサイズ(CPU種別やメモリ、ストレージサイズなどのマシン構成の種類)とそれらの料金が異なることがある。地理的に遠くのリージョンはアクセス速度が遅くなるので、取りあえず、無難な選択として一番近い [(Asia Pacific) Japan East]を選んでおいた。

次に決めるべき設定項目はマシンサイズだ。同種のマシンサイズでもリージョンによって料金が異なる場合があるので、あらかじめ各リージョンのマシンサイズの料金を調べておいて、その中から一番安価なものを選んでも良いだろう。ちなみに、Azureのマシンサイズ種類の詳細情報は下のサイトで確認することができる。

learn.microsoft.com

下のようにAzureのマシンサイズには多くの種類が存在するが、当然ながら高性能なものほど料金は高くなる。

これらの中から、サブスクリプション無料チャージ分$200に収まるものとして今回は「D4lds_v5」というものを選んでみた。

続いて、SSH公開キーの設定方法を決めないといけない。[新しいキーの組の生成] を選ぶと、Azureがキーの組を生成してくれて、公開キーを後で取得できるようだが、今回は自分で生成したキーを使うことにした。その場合は、自分で ssh-keygen コマンドによってSSHキーの組を作成し、[SSHキーのソース | 既存の公開キーを使用] を選んだ上で [SSH公開キー] 欄に公開キーの内容をコピべすれば良い。

上記の設定が済んだら、最後に [仮想マシンの名前] 欄に適当な名前を入力して、[ 次: ディスク > ] を押すと、[ディスク] の設定画面に移る。

ディスクの設定項目は特に変更する必要はないが、一つだけ [OSディスク | VMと共に削除] という項目には注意しなければならない。これをオフにすると、仮想マシンの停止後もディスクの実体が残ってしまうからだ(ここで言うディスクとは一時ストレージのことで、これは通常は仮想マシンの起動時に生成され停止時に削除される)。その場合、ディスクが存在するかぎり料金が発生することになる。これを避けるために、この項目は有効にしておいた方が良い。

これを言い換えると、[VMと共に削除] をオンした場合、毎回仮想マシンを起動した後で一時ディスクへデータなどをアップロードした上で利用し、使用後は必ず仮想マシンを停止するという使い方をしなければならないことを意味している。Azureのようなクラウドコンピューティング仮想マシンは通常はこのような使い方をすることになる。 [VMと共に削除] 設定が無効な仮想マシンを起動したままだと、その間ずっと仮想マシンと一時ディスクの両方の料金が発生してしまう。

ディスクの設定に続いて、次は [ネットワーク] の設定画面になるが、これらの項目は特に変更する必要はないだろう。

ただし、[受信ポートを選択][SSH (22)] が有効なっていることは確認しておいた方が良い。この設定項目は、SSHの他に [HTTP (80)][HTTPS (443)][RDP (3389)] も選べるようになっている。リモートディスクトップを使いたい場合は [RDP (3389)] をオンにすれば良い(仮想マシンを生成した後で受信ポート設定を変更追加することもできる)。

続いて、[管理] というが画面が表示されるが、これも特に変更する必要はないだろう。

ただし、[無料のBasicプランを有効にする] がオンになっていることは確認するべきだ。これがオフだと、既存のサブスクリプション無料分は使われずに、別に課金が発生してしまうからだ。

さらに続いて、[監視] というが画面が表示されるが、これも特に変更すべき設定項目はない。

またさらに続いて、[詳細]という画面が表示されるが、これも変更する必要はないだろう。

ただし、[パフォーマンス (NVMe) | NVMeを使用してリモートディスク ストレージ パフォーマンスを高める] は無効になっていることは確認するべきだ。これがオンだと、NVMeが一時ストレージとして使われ、追加料金が発生してしまうので。

またさらに続いて、[タグ] という画面が表示されるが、この画面に記載されている機能を利用するなら設定すれば良いだけで、特に必要がなれば変更しなくても良いだろう。

最後に、 [確認および作成] という画面にここまでの仮想マシンの設定内容が表示される。

この画面の内容を確認して [ 作成 ] を押すと、仮想マシンの作成(デプロイ)が始まる。仮想マシンの作成が成功すると、下のような画面が表示される。

この画面の [ リソースに移動 ] を押すと、作成された仮想マシンの概要情報が表示される。

この画面は、ホーム画面から [Virtual Machines] を選んで、作成済みの仮想マシンを選択することでも見ることができる。

次の記事に書く、仮想マシンをリモートで使用できる状態にする作業で使うことになるので、上の画面の [パブリックIPアドレス] の値を記憶しておく。

メーカー不明中華製IPカメラを調べる

ずいぶん長い間ご無沙汰してしまって、ずっと本ブログの更新ができないでいた。 個人的に仕事と生活の両方で大変な状況が続き、こちらに時間を割けない状態が続いていた。やっと仕事も生活も落ち着いて安定した暮らしがおくれるなったので、これからまた本ブログの更新を続けていく。

ちなみに、以前は本業で別の仕事しながら、副業でIT業をやっていた。いまはIT専業で働いている。 仕事と趣味活動の両方で新しい分野の研究も始めたので、これからブログ記事に書けるネタは増えていくだろう。


さて、本題の今回の記事の内容だが、本記事ではONVIFという仕様を取り上げる。 ja.wikipedia.org とある事情から、中華製IPカメラ(いわゆる監視カメラ)を借りられたので、こいつがどんな仕様なのか調べることになった。

WiFi Smart Camera」という名前がつけられたメーカー不明の奴だが、どうも中国の小メーカーが製造したボードが搭載されているようだ。

WiFi Smart Camera(メーカー不明中華製IPカメラ)

iCSeeという名前の純正アプリがGoogle PlayApp Storeに在って、これをAndrid/iOSスマホへインストールして使うことを前提としているようだ。

iCSeeアプリ(Android

カメラの初期設定は、iCSeeアプリでWiFiに接続した上で、アプリ側に表示されたQRコードをカメラ本体に読ませることでできるようになっている。

これは上手い方法だなぁと思う。ネットワークデバイス用アプリはこの方法を搭載すれば簡単に初期設定ができるので、ONVIF仕様とは別にこの方法がどういう仕組になっているのかも知りたくなった。

ONVIF Device Managerによる調査

最近のこの手のIPカメラは大抵ONVIF(Open Network Video Interface Forum)という仕様に準拠している。

www.onvif.org

ONVIF準拠カメラを操作することが目的のツールがいくつかあって、その中でもONVIF Device Managerというのが一番有名。

sourceforge.net

このツールを使って、対象IPカメラを調べてみた。

ONVIF Device Manager を起動すると、すぐに対象機が検出された。 やはりこいつもONVIF準拠カメラだということが判った。

ONVIF Device Manager〔対象機種〕

ただし、一概にONVIF準拠とは言っても、結構準拠程度に違いがあるらしい。 特に中華製IPカメラはONVIF準拠程度のバラツキが大きいと聞いたことがある。

このカメラもONVIF Device Managerの映像取得系コマンドは全滅で、下のようなエラーが表示されてしまう。

ONVIF Device Manager - Video streaming〔対象機種〕

VLCによる対象機カメラ映像の取得

ONVIF仕様を調べていくと、この仕様にはRTSP(Real Time Streaming Protocol)が含まれていて、デフォルト状態でONVIF準拠IPカメラはRTSPストリームが有効になっていることが解った。

ja.wikipedia.org

そこで、VLCを使って対象機からRTSP経由でカメラ映像の取得を試みてみた。

VLC RTSP設定〔対象機〕
VLC取得カメラ映像〔対象機〕

すると、問題なく対象機からカメラ映像を取得することができた。

対象機カメラのONVIF準拠程度

上記の情報だけでは不十分だと思ったので、他の調査方法がないかググってみた。そうしたら、ONVIF準拠情報を可能なかぎり詳しく調べることができるツールが見つかったので、このツールを使って本カメラの準拠程度を調べてみた。

その結果、本機のONVIF準拠には以下のような問題があることが判った。

  1. Media Configuration
    • 本系列コマンドによって取得されるURI記述に 'H265' != 'H264' という誤りあり
  2. Real Time Streaming
    • 本系列コマンドによって取得されるURI記述に 'H265' != 'H264' という誤りあり
  3. Real Time Streaming using Media2
    • 本系列コマンドによって取得されるURI記述に '=' != ':' という誤りあり
  4. PTZ using Media2 | Move Operation | PTZ CONTINUOUS MOVE USING MEDIA2 PROFILE
    • 本コマンドを実行すると、デバイスがリセットされてしまう → デバイスとの接続が切断される

上記の1〜3がONVIF Device Managerでカメラ映像が取得できない原因だろう。4は本機搭載ファームウェアのバグによる障害現象のようだ(iCSeeアプリでも、パン・チルト・ズーム操作をすると同現象が発生することがあるので)。

ここまで調べたのは、将来ONVIFカメラ用アプリ(Android, iOS, Windows, Mac版全部)を自作するつもりなので、現時点でONVIF仕様をある程度詳しく知っておきたかったから。

ONVIFカメラ用アプリを作り始めたら、その過程の情報を記事にしていこうと思っている。

【Homebrew】macOS High Sierraでの最新版LLVMのインストール

macOSのパッケージマネージャーとしてHomebrewを利用しています。GitHubなどから入手したプログラムソースをビルドしてMacで利用するには、Homebrewは必須のツールです。Homebrewがなければ、Macでのオープンソースを利用したソフトウェア開発はできないとも言えます。

ところが、現行のHomebrew(本記事執筆時点はバージョン3.6.1)ではmacOS 10.13 High Sierra はサポート対象外となっており、何かパッケージをインストールする度に次のような警告が表示されます。

Warning: You are using macOS 10.13.  
We (and Apple) do not provide support for this old version.  
You will encounter build failures with some formulae.  
Please create pull requests instead of asking for help on Homebrew's GitHub,  
Twitter or any other official channels. You are responsible for resolving  
any issues you experience while you are running this  
old version. 

Homebrewの多くフォーミュラはすでにBig Sur以降用に更新されているようで、一部のフォーミュラはそのままではHigh Sierraにインストールできなくなってしまっています。

事情があって、High Sierraを使い続けている人は結構多いのではないでしょうか。そういう私も2台のMacでまだHigh Sierraを使っています(マルチパーティションでBig Surと共存させたりしていますが)。一つの大きな理由として、NVIDIA GPUボードがHigh Sierraまでしか利用できないことがあります。NVIDIA GPUボード用ドライバがHigh Sierra対応版までしかリリースされておらず、macOS 10.14 Mojave以降ではCUDAや機械学習ディープラーニングのソフトウェア開発ができません。

HomebrewでHigh Sierraにインストールできないフォーミュラの一つとしてLLVMがというものがあります。Command Line Toolsにも入っているclangコンパイラを含んでいるLLVMの最新版ですが、この最新版LLVMにはclangも最新版バージョンが収納されています。この最新版LLVMをインストールできないことはHomebrewを利用したソフトウェア開発にとって大きな障害となります。多くのフォーミュアがこの最新バージョンのclangでビルドすることを前提として更新されており、それらは先に最新版LLVMがインストールされるからです。OpenCVやQtなどのメジャーなフォーミュラが最新版LLVMに依存しているため、High Sierraでは現行のHomebrewを使ってこれらをインストールすることができません。

GitHubから入手したいくつかのプログラムをビルドしようとして、この障害に何度か遭遇しましたが、試行錯誤しながら解決することができました。同じ問題によって困っている人は多いと思うので、その解決方法を本記事に書いておきます。

LLVMインストール時のエラー障害

High Sierra上でHomebrewを使って最新版LLVM(本記事執筆時点はバージョン14.0.6)をインストールしようとすると、以下のようなエラーが起きます。

% brew install llvm
... ...
==> Downloading https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.6/llvm-project-14.0.6.src.tar.xz
/usr/local/Homebrew/Library/Homebrew/shims/shared/curl --disable --cookie /dev/null --globoff --show-error --user-agent Homebrew/3.6.1\ \(Macintosh\;\ Intel\ Mac\ OS\ X\ 10.13.6\)\ curl/7.54.0 --header Accept-Language:\ en --retry 3 --location --silent --head --request GET https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.6/llvm-project-14.0.6.src.tar.xz
Already downloaded: /Users/yuhri/Library/Caches/Homebrew/downloads/ca2953276467b5dcc28485aa2b1afc3bcf32bbf84d5e0236f6284234afca2d8d--llvm-project-14.0.6.src.tar.xz
... ...
tar --extract --no-same-owner --file /Users/yuhri/Library/Caches/Homebrew/downloads/ca2953276467b5dcc28485aa2b1afc3bcf32bbf84d5e0236f6284234afca2d8d--llvm-project-14.0.6.src.tar.xz --directory /private/tmp/d20220915-7100-llrho7
cp -pR /private/tmp/d20220915-7100-llrho7/llvm-project-14.0.6.src/. /private/tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src
==> cmake -G Unix Makefiles .. -DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;lld;lldb;mlir;polly -DLLVM_ENABLE_RUNTIMES=compiler-rt;libcxx;libcxxabi;libunwind;
==> cmake --build .
... ...
[ 80%] Built target lldELF
make: *** [all] Error 2

HomebrewはLLVMをソースからビルドしてインストールしようと試みますが、このエラーによってビルド処理が停止するため、LLVMのインストールは失敗してしまいます。

High Sierraに最新版LLVMをインスールする手順

上記のエラー障害を解決して、High Sierra上でHomebrewを使ってLLVMをインスールする手順を以降に説明します。

Xcode 10.1をインストールする

まずXcodeをHigh Sierraへインストールしておく必要があります。Xcode 10.1がHigh Sierraで利用可能な最終バージョンですが、これをApple Developerサイトからダウンロードした上で解凍し、Applicationsフォルダへコピーしてください。

Homebrewをインストール済みならCommand Line Toolsは単独でインストールされているはずで、フォーミュラのビルドは通常こちらを使って行われます。しかし、LLVMのインストールではXcodeに含まれる一部のツールがビルド処理で使われます。

すでにXcode 10.1をインストール済みなら、この操作を行う必要はありません。

なお、HombrewがXcodeの存在を認識しているかどうかは、以下のコマンドによって確認できます。

% brew config
HOMEBREW_VERSION: 3.6.1
ORIGIN: https://github.com/Homebrew/brew
HEAD: 6e2b162c4786e075323f038d46bfb566d91889e7
Last commit: 5 days ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 4d6529affa1851ffb992a33fe5641b0cd739c895
Core tap last commit: 2 hours ago
Core tap branch: master
HOMEBREW_PREFIX: /Users/yuhri/homebrew
HOMEBREW_REPOSITORY: /Users/yuhri/homebrew
HOMEBREW_CELLAR: /Users/yuhri/homebrew/Cellar
HOMEBREW_CASK_OPTS: []
HOMEBREW_DISPLAY: /private/tmp/com.apple.launchd.gBCDRKkzIz/org.xquartz:0
HOMEBREW_MAKE_JOBS: 24
Homebrew Ruby: 2.6.8 => /Users/yuhri/homebrew/Library/Homebrew/vendor/portable-ruby/2.6.8_1/bin/ruby
CPU: 24-core 64-bit westmere
Clang: 10.0.0 build 1000
Git: 2.17.2 => /Library/Developer/CommandLineTools/usr/bin/git
Curl: 7.54.0 => /usr/bin/curl
macOS: 10.13.6-x86_64
CLT: 10.1.0.0.1.1539992718
Xcode: 10.1

Xcodeがインストールされていないと、 "Xcode: N/A" と表示されます。

Command Line ToolsをXcode側へ切り替える

xcode-select コマンドを使って、Xcode側のCommand Line Toolsが使われるように変更します。

% xcode-select -p
/Library/Developer/CommandLineTools
$ sudo xcode-select -s /Applications/Xcode.app
Password:
% xcode-select -p
/Applications/Xcode.app/Contents/Developer

LLVMのインストールを”--debug”オプション付きで開始する

brew コマンドには --debug というオプションがありますが、このオプションを指定してLLVMのインストールを開始します。

% brew install --debug llvm

--debug オプションをつけると、エラーが起きた時点で、以下のようなメッセージが表示されてHomebrewのインストール処理が停止します。

... ...
[ 80%] Built target lldELF
make: *** [all] Error 2
/usr/local/Homebrew/Library/Homebrew/shims/shared/git --version
/usr/local/Homebrew/Library/Homebrew/shims/shared/curl --version
/usr/local/Homebrew/Library/Homebrew/ignorable.rb:29:in `block in raise'
BuildError: Failed executing: cmake --build .
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 5
When you exit this shell, you will return to the menu.
%

この”Choose an action:” プロンプトに対して ”5”  を選ぶと、シェルプロンプトに復帰します。

LLVMのビルド・エラーの原因を解決する

シェルプロンプトになったら、以下のように作業ディレクトリを移動します。

% pwd
/private/tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src
% cd llvm/build

そして、 HostInfoMacOSX.mm というファイルを以下のように編集します。

% vi ../../lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
--- ../../lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm.orig  2022-06-22 16:46:24.000000000 +0000
+++ ../../lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm    2022-09-15 13:18:17.000000000 +0000
@@ -228,7 +228,7 @@
     len = sizeof(is_64_bit_capable);
     ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0);

-    if (cputype == CPU_TYPE_ARM64 && cpusubtype == CPU_SUBTYPE_ARM64E) {
+    if (cputype == CPU_TYPE_ARM64) {
       // The arm64e architecture is a preview. Pretend the host architecture
       // is arm64.
       cpusubtype = CPU_SUBTYPE_ARM64_ALL;

手動でLLVMのビルド処理を継続する

HostInfoMacOSX.mm の修正が終わったら、以下の一連のコマンドを順次実行していきます。

% cmake . -DLLVM_CREATE_XCODE_TOOLCHAIN=On
...   ...
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src/llvm/build
% cmake --build .
...   ...
[100%] Built target lldb-vscodex
/usr/local/Cellar/cmake/3.24.1/bin/cmake -E cmake_progress_start /tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src/llvm/build/CMakeFiles 0
% cmake --build . --target install
...   ...
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/lib/cmake/llvm/./FindSphinx.cmake
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/lib/cmake/llvm/./FindGRPC.cmake
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/lib/cmake/llvm/./TableGen.cmake
% cmake --build . --target install-xcode-toolchain

上記の最後のコマンドによるビルド処理が終わると、以下のようなメッセージが表示されます。

ここでの"Choose an action:"プロンプトでは、すべて "2" を選択します。

...   ...
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/Toolchains/LLVM14.0.6.xctoolchain//usr/lib/cmake/llvm/./FindSphinx.cmake
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/Toolchains/LLVM14.0.6.xctoolchain//usr/lib/cmake/llvm/./FindGRPC.cmake
-- Installing: /usr/local/Cellar/llvm/14.0.6_1/Toolchains/LLVM14.0.6.xctoolchain//usr/lib/cmake/llvm/./TableGen.cmake
Built target install-xcode-toolchain
/usr/local/Cellar/cmake/3.24.1/bin/cmake -E cmake_progress_start /tmp/llvm-20220915-7100-9zovwz/llvm-project-14.0.6.src/llvm/build/CMakeFiles 0
%
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 2
==> cmake --build . --target install
Last 15 lines from /Users/yuhri/Library/Logs/Homebrew/llvm/03.cmake:
2022-09-15 07:06:11 +0000

cmake
--build
.
--target
install

Error: could not load cache
/usr/local/Homebrew/Library/Homebrew/shims/shared/curl --version
/usr/local/Homebrew/Library/Homebrew/ignorable.rb:29:in `block in raise'
BuildError: Failed executing: cmake --build . --target install
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 2

2回 "2" を選択すると、LLVMのビルド処理が終了し、以降はHomebrewによってインストール処理が継続実行されます。

...   ...
==> Fixing /usr/local/Cellar/llvm/14.0.6_1/lib/python3.9/site-packages/clang/cindex.py permissions from 644 to 444
==> Fixing /usr/local/Cellar/llvm/14.0.6_1/lib/python3.9/site-packages/clang/enumerations.py permissions from 644 to 444
...   ...
==> Changing dylib ID of /Users/yuhri/homebrew/Cellar/llvm/14.0.6_1/lib/libomp.dylib
  from @rpath/libomp.dylib
    to /Users/yuhri/homebrew/opt/llvm/lib/libomp.dylib
==> Changing dylib ID of /Users/yuhri/homebrew/Cellar/llvm/14.0.6_1/lib/libunwind.1.0.dylib
  from @rpath/libunwind.1.dylib
    to /Users/yuhri/homebrew/opt/llvm/lib/libunwind.1.dylib
/Users/yuhri/homebrew/Library/Homebrew/brew.rb (Formulary::FromPathLoader): loading /Users/yuhri/homebrew/opt/llvm/.brew/llvm.rb
==> Caveats
To use the bundled libc++ please add the following LDFLAGS:
  LDFLAGS="-L/Users/yuhri/homebrew/opt/llvm/lib -Wl,-rpath,/Users/yuhri/homebrew/opt/llvm/lib"

llvm is keg-only, which means it was not symlinked into /Users/yuhri/homebrew,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have llvm first in your PATH, run:
  echo 'export PATH="/Users/yuhri/homebrew/opt/llvm/bin:$PATH"' >> ~/.zshrc

For compilers to find llvm you may need to set:
  export LDFLAGS="-L/Users/yuhri/homebrew/opt/llvm/lib"
  export CPPFLAGS="-I/Users/yuhri/homebrew/opt/llvm/include"

==> Summary
🍺  /Users/yuhri/homebrew/Cellar/llvm/14.0.6_1: 11,663 files, 1.8GB, built in 76 minutes 6 seconds
...   ...

そして、最後はLLVMのインストールが成功して終わります。

インストールされたLLVMを確認する

インストールされたLLVMが利用可能かどうかは 、以下のコマンドによって確認できます。

% /usr/bin/clang --version
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
% /Library/Developer/CommandLineTools/usr/bin/clang --version
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
% /usr/local/opt/llvm/bin/clang --version
Homebrew clang version 14.0.6
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin

/usr/bin/clangXcode 10.1のclangコンパイラ/Library/Developer/CommandLineTools/usr/bin/clang がCommand Line Toolsのclang、/usr/local/opt/llvm/bin/clang がインストールしたLLVMのclangです。

Command Line Toolsの選択を元に戻す

上記までの手順でLLVMのインストールは完了ですが、"brew install --debug llvm " コマンドを実行する前に変更したCommand Line Toolsの選択を元に戻しておきます。

% xcode-select -p
/Applications/Xcode.app/Contents/Developer
% sudo xcode-select -s /Library/Developer/CommandLineTools
Password:
% xcode-select -p
/Library/Developer/CommandLineTools

【参考リンク】

stackoverflow.com

seq2point-nilmのDockerfileを作る

あるサイトのエンジニア募集ページに記載されていた情報から、NILM(Nonintrusive Load Monitoring:非侵入型負荷監視)という技術が存在することを知りました。

en.wikipedia.org電源ラインの一次配電盤に取り付けたセンサーによって電圧や電流の変化データを取得し、そのデータから電源ライン上の装置や機器の消費電力や稼働状況をモニタリングする技術らしいです。

こういう技術が在ることは聞いたことがありましたが、これには機械学習が使われていることは知りませんでした。NILMの一つの実装例としてseq2point-nilmというものが在ることも上述のページで知りました。

github.com

コロナ拡大の社会情勢下で電力消費が増大しており、エネルギー・エコ化も永続的な社会トレンドとなっている中で、さらにIoTにも繋がる技術としてNILMへの注目度が急上昇しているらしいです。

 

NILMがどういう技術で、その動作原理や使われているアルゴリズムがどんなものかを知りたくなったので、手始めに、このseq2point-nilmを動かしてみることにしました。ちなみに、seq2point-nilmの機械学習処理はTensorFlowとKerasを使って実現されているようです。

 

このような機械学習プログラムを手っ取り早く動かすにはDockerを利用するのが一番楽な方法です。そこで、Dockerfileを作りながらseq2point-nilmの動作確認を試みました。

以下が、私が自作したseq2point-nilmのDockerfileです。

FROM continuumio/anaconda3:2021.05

# install prerequistites
ENV DEBCONF_NOWARNINGS yes
RUN apt-get update && \
    apt-get install -y wget git unzip p7zip-full && \
    apt-get autoremove -y

# copy the seq2point-nilm
COPY ./seq2point-nilm /seq2point-nilm

# create a Python environment for seq2point-nilm installing python prerequistites
WORKDIR /seq2point-nilm
RUN conda env create -f environment.yml

ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES utility,compute

# download the REFIT dataset file
WORKDIR /seq2point-nilm/dataset_management/refit
RUN wget https://pureportal.strath.ac.uk/files/62090184/CLEAN_REFIT_081116.7z && \
    7z x -oCLEAN_REFIT_081116 CLEAN_REFIT_081116.7z && \
    rm -f CLEAN_REFIT_081116.7z

# download the UK-DALE datasets file
WORKDIR /seq2point-nilm/dataset_management/ukdale
RUN wget http://data.ukedc.rl.ac.uk/simplebrowse/edc/efficiency/residential/EnergyConsumption/Domestic/UK-DALE-2017/UK-DALE-FULL-disaggregated/ukdale.zip && \
    unzip ukdale.zip -d ukdale && \
    rm -f ukdale.zip

# download the REDD datasets file
WORKDIR /seq2point-nilm/dataset_management/redd
RUN wget --http-user="redd" --http-password="disaggregatetheenergy" http://redd.csail.mit.edu/data/low_freq.tar.bz2 && \
    tar -jxvf low_freq.tar.bz2 && \
    rm -f low_freq.tar.bz2

ARG AGGREGATE_MEAN=522
ARG AGGREGATE_STD=814

# create a REFIT dataset
WORKDIR /seq2point-nilm/dataset_management/refit
RUN mkdir dataset && \
    cd dataset && \
    python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'kettle' --save_path './' && \
    python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'microwave' --save_path './' && \
    python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'fridge' --save_path './' && \
    python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'dishwasher' --save_path './' && \
    python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'washingmachine' --save_path './'
    #python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'kettle' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './' && \
    #python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'microwave' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './' && \
    #python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'fridge' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './' && \
    #python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'dishwasher' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './' && \
    #python ../create_dataset.py --data_dir '../CLEAN_REFIT_081116/' --appliance_name 'washingmachine' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './'

# create a UK-DALE dataset
WORKDIR /seq2point-nilm/dataset_management/ukdale
RUN mkdir dataset && \
    mkdir dataset/kettle dataset/microwave dataset/fridge dataset/dishwasher dataset/washingmachine &&& \
    PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'kettle' --save_path './dataset/kettle/' && \
    PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'microwave' --save_path './dataset/microwave/' && \
    PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'fridge' --save_path './dataset/fridge/' && \
    PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'dishwasher' --save_path './dataset/dishwasher/' && \
    PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'washingmachine' --save_path './dataset/washingmachine/'
    #PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'kettle' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/kettle/' && \
    #PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'microwave' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/microwave/' && \
    #PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'fridge' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/fridge/' && \
    #PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'dishwasher' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/dishwasher/' && \
    #PYTHONPATH="${PYTHONPATH}:../" python create_trainset_ukdale.py --data_dir './ukdale/' --appliance_name 'washingmachine' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/washingmachine/'

# create a REDD dataset
WORKDIR /seq2point-nilm/dataset_management/redd
RUN mkdir dataset && \
    mkdir dataset/microwave dataset/fridge dataset/dishwasher dataset/washingmachine && \
    python create_trainset_redd.py --data_dir './low_freq/' --appliance_name 'microwave' --save_path './dataset/microwave/' && \
    python create_trainset_redd.py --data_dir './low_freq/' --appliance_name 'fridge' --save_path './dataset/fridge/' && \
    python create_trainset_redd.py --data_dir './low_freq/' --appliance_name 'dishwasher' --save_path './dataset/dishwasher/' && \
    python create_trainset_redd.py --data_dir './low_freq/' --appliance_name 'washingmachine' --save_path './dataset/washingmachine/'
    #python create_trainset_redd.py --data_dir './low_freq/' --appliance_name 'microwave' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/microwave/'
    #python create_trainset_redd.py --data_dir './low_freq/' --appliance_name 'fridge' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/fridge/'
    #python create_trainset_redd.py --data_dir './low_freq/' --appliance_name 'dishwasher' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/dishwasher/'
    #python create_trainset_redd.py --data_dir './low_freq/' --appliance_name 'washingmachine' --aggregate_mean AGGREGATE_MEAN --aggregate_std AGGREGATE_STD --save_path './dataset/washingmachine/'

WORKDIR /seq2point-nilm
ENTRYPOINT ["/bin/bash"]

Dockerfileは何度か作っていますが、これの難易度は中程度位でした。

このDockerfileは私のGitHubリポジトリに置いてあります。

github.comこのDockerfileの使い方は簡単で、まず以下の手順によって上のDockerfileが格納されたリポジトリ取得します。

$ git clone https://github.com/ketus-ix/seq2point-nilm_docker.git
$ cd seq2point-nilm_docker
$ git submodule update --init --recursive

その後、以下のコマンドを実行すると、seq2point-nilmのDockerイメージを作成できます。

$ cp docker/Dockerfile.conda .
$ docker build . -t seq2point-nilm_conda -f Dockerfile.conda

このDockerコンテナの中で、REFIT(514.3MB)、UK-DALE(3.59GB)、REDD(169.4MB)という3つのデータセットのダウンロードを行っています。そのため、Dockerイメージが生成されるのにかなり時間がかかります。これらのデータセットはseq2point-nilmによって利用されます。

 

このDockerfileによって作成したDockerコンテナは、すべてのデータセットがseq2point-nilmが使用する形式に変換・作成されるところまで確認してあります。

以下のディレクトリにseq2point-nilmが使用する形式の各データセットが格納されます。

 

 /seq2point-nilm/dataset_management/refit/dataset

 /seq2point-nilm/dataset_management/ukdale/dataset

 /seq2point-nilm/dataset_management/redd/dataset

 

seq2point-nilmの学習処理とテスト処理はこの作成済みのデータセットを用いて実行することができます。機械学習の肝であるこれらの処理も確認してみたかったのですが、残念ながらそれはできませんでした。いま手元にNVIDIA GPUボードを持っていないからです。

 

過去の仕事で利用していた機械学習環境が整ったPCを使っているので、GPUボードさえ有ればすぐに動作確認を行えるのですが、いまはGPUボードを手放してしまっています。

 

ここまでだと中途半端なので、上のDockerfileから作成したイメージを使って、seq2point-nilmの動作確認を行う手順を一応書いておきます。

 

まず、seq2point-nilmのDockerコンテナをGPUアクセスを有効にした状態で起動します。

$ docker run -it --rm --gpus all seq2point-nilm_conda

ただし、このコマンドを実行したときに、以下のようなエラーに遭遇してDockerコンテナを起動できないことがあります。

$ docker: Error response from daemon: could not select device driver "" with capabilities: gpu

nvidia-driverがインストールされておりnvidia-smiコマンドも使える状態なのに、このようなエラーが起きる場合は、システムにNVIDIA Container Runtimeが入っていないからです。

このようなケースでは、以下の手順を実行して、NVIDIA Container Runtimeをインストールしてください。

$ vi nvidia-container-runtime-script.sh
curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
  sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
sudo apt-get update
$ sh nvidia-container-runtime-script.sh
$ sudo apt-get install nvidia-container-runtime
$ sudo systemctl restart docker.service

seq2point-nilmのDockerコンテナを起動できたら、その中で作業ディレクトリが /seq2point-nilm になっていることを確認してください。

(base) root@9d1c222ac40e:/seq2point-nilm# ls
README.md    appliance_data.py	dataset_management  images     model_structure.py		   remove_space.py    seq2point_train.py  train_main.py
__pycache__  data_feeder.py	environment.yml     model.png  nvidia-container-runtime-script.sh  seq2point_test.py  test_main.py

この状態で以下のコマンドを実行すると、REFITデータセットから抽出した ケトルの観測電気データに対するseq2point-nilmの学習処理を開始することがきます。

# python train_main.py --appliance_name 'kettle' --training_directory './dataset_management/refit/dataset/kettle/kettle_training_.csv' --validation_directory './dataset_management/refit/dataset/kettle/kettle_validation_H5.csv' --crop 10000

さらに以下のコマンドによって、REFITデータセットのケトルの観測電気データに対するテスト処理も実行できます。

# python test_main.py --appliance_name 'kettle' --test_directory './dataset_management/refit/dataset/kettle/kettle_test_H2.csv' --crop 10000

このテスト処理では、先に実行した学習処理によって生成された学習モデルが使われます。

上の2つの操作は実際には試していませんが、多分動くんじゃないかと思います。

 

近いうちにGPUボードを入手する予定なので、そのときにseq2point-nilmの学習処理とテスト処理もやってみるつもりです。その結果は、また別の記事として投稿する予定です。

 

参照リンク

arxiv.org

 

OpenVSLAM(stella_vslam)のUbuntu 18.04でのビルド

ある人から教えてもらった情報が元なんですが、画像認識の一分野としてSLAM(Simultaneous Localization and Mapping:自己位置推定)という技術が在ることを知りました。現存の物だと、お掃除ロボット、未来の物だと、自動運転車などに利用される技術らしいです。

github.com

画像認識はいまの自分の主たる研究テーマの一つなのに、こんな興味深い技術をいままで知らないでいたとは不覚です。慌てて、SLAMについて調べ始めています。

入力データの形式によってSLAMにも複数の種類があるようですが、その中でもVisual SLAMに注目しています。

オープンソースとして公開されているVisual SLAMの代表的な実装例として、OpenVSLAMというものがあります。これは国立研究開発法人産業技術総合研究所が開発したものだそうです。

本記事執筆時点でOpenVSLAMのソースは非公開になっているのですが、OpenVSLAMのコミュニティ・フォーク版がGithHub上にいくつか存在しているので、ソースを入手することはできます。

これらの中からstella_vslamを選んで、Ubuntu 18.04上でのビルドと動作確認までやってみました。

stella_vslamのビルドに必要なパッケージの導入

$ sudo apt install -y build-essential pkg-config cmake git wget curl unzip
$ sudo apt install -y libatlas-base-dev libsuitesparse-dev
$ sudo apt install -y libgtk-3-dev
$ sudo apt install -y ffmpeg
$ sudo apt install -y libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libavresample-dev
$ sudo apt install -y gfortran
$ sudo apt install -y binutils-dev
$ sudo apt install -y libyaml-cpp-dev libgflags-dev
$ sudo apt install -y libglew-dev
$ sudo apt install -y libsqlite3-dev

stella_vslamとリンクされるライブラリのビルドとインストール

Eigenのビルドとインストール

$ git clone -b 3.3 https://gitlab.com/libeigen/eigen.git
$ cd eigen
$ mkdir build && cd build
$ cmake \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=/usr/local \
      ..
$ make -j4
$ sudo make install

OpenCVのビルドとインストール

$ wget -q https://github.com/opencv/opencv/archive/3.4.0.zip
$ unzip -q 3.4.0.zip
$ cd opencv-3.4.0
$ mkdir build && cd build
$ cmake \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=/usr/local \
      -DENABLE_CXX11=ON \
      -DBUILD_DOCS=OFF \
      -DBUILD_EXAMPLES=OFF \
      -DBUILD_JASPER=OFF \
      -DBUILD_OPENEXR=OFF \
      -DBUILD_PERF_TESTS=OFF \
      -DBUILD_TESTS=OFF \
      -DWITH_EIGEN=ON \
      -DWITH_FFMPEG=ON \
      -DWITH_OPENMP=ON \
      -DWITH_CUDA=OFF \
      -DWITH_NVCUVID=OFF \
      ..
$ make -j4
$ sudo make install

FBoWのビルドとインストール

$ git clone https://github.com/stella-cv/FBoW.git
$ cd FBoW
$ mkdir build && cd build
$ cmake \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=/usr/local \
      ..
$ make -j4
$ sudo make install

g2oのビルドとインストール

$ git clone https://github.com/RainerKuemmerle/g2o.git
$ cd g2o
$ git checkout 9b41a4ea5ade8e1250b9c1b279f3a9c098811b5a
$ mkdir build && cd build
$ cmake \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=/usr/local \
      -DCMAKE_CXX_FLAGS=-std=c++11 \
      -DBUILD_SHARED_LIBS=ON \
      -DBUILD_UNITTESTS=OFF \
      -DG2O_USE_CHOLMOD=OFF \
      -DG2O_USE_CSPARSE=ON \
      -DG2O_USE_OPENGL=OFF \
      -DG2O_USE_OPENMP=OFF \
      ..
$ make -j4
$ sudo make install

PangolinViewerのビルドとインストール

$ git clone https://github.com/stevenlovegrove/Pangolin.git
$ cd Pangolin
$ git checkout ad8b5f83222291c51b4800d5a5873b0e90a0cf81
$ mkdir build && cd build
$ cmake \
      -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=/usr/local \
      ..
$ make -j4
$ sudo make install

stella_vslamのビルドとインストール

$ git clone https://github.com/stella-cv/stella_vslam.git
$ cd stella_vslam
$ git submodule update -i --recursive
$ mkdir build && cd build
$ cmake \
      -DUSE_PANGOLIN_VIEWER=ON \
      -DINSTALL_PANGOLIN_VIEWER=ON \
      -DUSE_SOCKET_PUBLISHER=OFF \
      -DBUILD_TESTS=ON \
      -DBUILD_EXAMPLES=ON \
      ..
$ make -j4
$ sudo make install

stella_vslamの動作確認

$ ./run_kitti_slam -h
Allowed options:
  -h, --help               produce help message
  -v, --vocab arg          vocabulary file path
  -d, --data-dir arg       directory path which contains dataset
  -c, --config arg         config file path
  --frame-skip arg (=1)    interval of frame skip
  --no-sleep               not wait for next frame in real time
  --wait-loop-ba           wait until the loop BA is finished
  --auto-term              automatically terminate the viewer
  --log-level arg (=info)  log level
  --eval-log               store trajectory and tracking times for evaluation
  -p, --map-db arg         store a map database at this path after SLAM

上のような結果になれば、stella_vslamのビルドとインストールは成功しているはず。

 

上記のビルド手順は、stella_vslamのドキュメントサイトに掲載されている情報とほぼ同じですが、一点だけ相違があり、ビルドに必要なパッケージとしてlibsqlite3-devを追加インストールしています。これを入れないと、stella_vslamの "cmake ..." 過程で以下のようなエラーに遭遇します。

CMake Error at /usr/share/cmake-3.10/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
  Could NOT find SQLite3 (missing: SQLite3_INCLUDE_DIR SQLite3_LIBRARY)
Call Stack (most recent call first):
  /usr/share/cmake-3.10/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
  cmake/FindSQLite3.cmake:57 (find_package_handle_standard_args)
  src/stella_vslam/CMakeLists.txt:10 (find_package)


-- Configuring incomplete, errors occurred!

ビルドできたんなら当然動かしてみたい。プログラムを動かしてみるのが、その中で使われている技術を理解する早道だし。

公式サイトで推薦されているKITTI Visual Odometryという車載画像データセットを利用してstella_vslamの動作確認をやってみました。

下のような手順によって、このデータセットを使ってstella_vslamの動作確認ができます。

# at the stella_vsalm/build directory 
$ mkdir ../vocab
$ mkdir ../dataset
$ cd ../vocab
$ curl -sL "https://github.com/stella-cv/FBoW_orb_vocab/raw/main/orb_vocab.fbow" -o orb_vocab.fbow
$ cd ../dataset
# Download KITTI Odometry dataset (grayscale, 22 GB)
$ wget -q HTTPS_URLPATH_TO_KITTI_DATASET/data_odometry_gray.zip
$ unzip -q data_odometry_gray.zip $ cd ../build $ ./run_kitti_slam -v ../vocab/orb_vocab.fbow -d ../dataset/dataset/sequences/00/ -c ../example/kitti/KITTI_mono_00-02.yaml --frame-skip 1 --no-sleep --map-db map-KITTI_mono_00-02.msg

上の手順中のdata_odometry_gray.zipというのが対象のデータセットが格納された圧縮ファイルですが、これはKITTI(The KITTI Vision Benchmark Suite)のサイトでアカウント登録をしないとダウンロードできません。

このデータセットでstella_vslamを作動させると、下の動画のように、Visual SLAMの動きが良く解ります。 

www.youtube.com

 

参照リンク

arxiv.org

qiita.com