【Raspberry Pi】今更だけど初期インストール方法をちゃんと書く@ラズパイ3

わけあってクリーンインストールする必要があったため、設定方法を記載しておきます。
ラズパイ自体は、ラズパイ1〜3まで4年ぐらい使ってるけど、初期インストールは他者様のページを見ながらやってました。
昔と設定方法も少し変わってるので、流石に自分なりの方法を残しておきたい。
なお、GUI機能とか余計なソフトはいらないので、インストールOSはRaspbian Liteです。

1.NOOBSをSDカードに入れる

NOOBSはインストール時にGUIで自動インストールしてくれるソフト
www.raspberrypi.org
でダウンロードします。

SDに入れるのは「NOOBS LITE」。
これは最小インストーラ構成のみが入っているもので、普通の「NOOBS」はRaspbianも含めたインストーラですが、今回入れるRaspbian Liteは、「NOOBS LITE」でも「NOOBS」でもネットワーク越しでインストールファイルを落としてくるためどちらでもいい。ので、サイズの小さい「NOOBS LITE」を落とします。
※2018/9/29時点での「NOOBS LITE」はv2.8

落としたZIPファイルは解凍しておきます。

2.SDカードのバックアップ

念の為に以前のラズパイ環境を残します。
SDカードはリーダに突っ込んでLinux上で実施。SDカードは/dev/sdhで認識されていたので、それを対象にLinux上でSDカード丸ごとで。
32GBカードなので、gzでサイズ圧縮も実施。

sudo dd if=/dev/sdh bs=16M conv=noerror,sync | gzip -c > /mnt/3TB//raspi3-backup.img.gz

3.SDカードのフォーマット

Linuxでもできますが、Windowsで信頼と安心のSDメモリカードフォーマッターを使います。
www.sdcard.org

クイックフォーマットを選べばあっという間に終わる。

4.SDカードにNOOBS LITEを設置。

解凍しておいたNOOBS LITEのファイルをフォーマットしたSDカードに丸ごと入れます。これは普通にファイルをコピペするだけ。

5.SDカードをラズパイ3に入れて起動

NOOBS LITEはGUIで動くため、Raspbian Liteにチェックと入れて、インストールボタンを押下。
※写真撮り忘れ

後は自動でインストールが始まるので、終わるまで待つ。
f:id:engetu21:20180929192531j:plain

OKを押すと再起動し、CUI画面で起動します。

6.ログインとパスワード変更とか

とりあえずログイン。
初期ユーザと初期パスワードは以下の通り。

login:pi
Password:raspberry

ログインが完了したら以下のコマンドでコンフィグモードに。

$ sudo raspi-config

・パスワードの変更
「1 Change User Password」 →新規パスワードを設定
f:id:engetu21:20180929194203j:plain

・ホスト名の変更
「2 Network Options」→「N1 Hostname」を選択
f:id:engetu21:20180929194529j:plain
名前はとりあえず『raspi3』とします。
f:id:engetu21:20180929194601j:plain

・ロケーション設定を変更
「4 Localisation Options」→「I1 Change Locale」でロケーションを変更。
「ja_JP.UTF-8 UTF-8」を見つけて(jキーを入力すると頭文字がjの項目に飛ぶ)、スペースを押下。OKを押す。
f:id:engetu21:20180929200041j:plain

・Timezone設定を変更
「4 Localisation Options」→「I2 Cange Timezone」でTimezoneを変更。
「Asia」→「Tokyo」を選択。OKを押す。
f:id:engetu21:20180929200355j:plain

・キーボード設定の変更
※基本的にSSH接続するからやらなくてもOK。
「4 Localisation Options」→「I3 Change Keyboard Layout」を選択。
「Generic 105-key (intl) PC」→「Other」→「Japanese」→「The default for the Keyboard layout」→「No Compose key」と設定していく。
f:id:engetu21:20180930070124j:plain
f:id:engetu21:20180930070204j:plain
f:id:engetu21:20180930070226j:plain
f:id:engetu21:20180930070304j:plain
f:id:engetu21:20180930070332j:plain

SSHサーバの有効化
「5 Interfacing Options」を選択し、「P2 SSH」を選択
f:id:engetu21:20180930064715j:plain
f:id:engetu21:20180930064742j:plain

7.ネットワークの設定(固定ローカルIP設定)

ifconfigでネットワーク設定を確認します。
eth0が有線、wlan0が無線。
DHCPでIPはすでに割り当てられているけど、SSH接続は基本的にIP固定でアクセスしたいので、無線は無効化しつつ、有線に固定IPを割り当てます。

以下のファイルを変更する。

$ sudo vi /etc/dhcpcd.conf

※以下設定値はコメントアウトを外して設定。
interface eth0
static ip_address=192.168.11.83/24
#static ip6_address=XXXXXXXXX #使わないのでコメントアウトのまま
static routers=192.169.11.38 #デフォルトゲートウェイ
static domain_name_servers=xxx.xxx.xxx.xxx #googleDNSを使うなら8.8.8.8

無線の無効化は2つ方法があるらしいです。
qiita.com

ブラックリストに入れるのはアレなので、ブート時に動かない1つ目を採用。
ついでにBluetoothも使わないので無効化。

$ sudo vi /boot/config.txt

#wifi bluetooth off
dtoverlay=pi3-disable-wifi
dtoverlay=pi3-disable-bt

ここで一旦再起動する。

$ sudo shutdown -r now

ネットワーク設定が変更されていることを確認(この時点で別PCからSSHが可能)

$ ifconfig
eth0: flags=4163 mtu 1500
inet 192.168.11.83 netmask 255.255.255.0 broadcast 192.168.11.255
※以下略

lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
※以下略

8.パッケージとOSの更新

次のコマンドを実行します。

$ sudo apt update # パッケージリストの更新
$ sudo apt upgrade # パッケージの更新
$ sudo apt dist-upgrade # OSのアップグレード

9.ファームウェアの更新

次のコマンドを実行します。

$ sudo apt install rpi-update # インストール
$ sudo rpi-update # 更新実行
$ sudo shutdown -r now # 反映のための再起動


以上!

【Raspberry Pi】【AVS Device SDK】ラズパイでAlexaする

自宅でのスマートホーム化はすでにやっていますが、
engetu21.hatenablog.com


Alexa使ってみたかったのでやり方のメモ。
本記載は2018/8/20時点の内容です。
なお、使うのはAVS Device SDK(ver1.8.1)です。(https://github.com/alexa/avs-device-sdk
そのため、先駆者の皆様とは手順が若干異なります。

具体的には
・製品登録時の「許可された出荷地」にhttp://localhost:3000を設定
とか、
・ラズパイのデスクトップでブラウザ開いて認証を進める
とかはやりません。

以下の手順は、すべてラズパイとは別のマシンでSSH等で操作した記録です。

※2018/10/1追記
※↑のリンクで実施しているJulius-plusとの共存についてですが、
それぞれscreenで仮想端末を作ったうえで
①AVS Device SDKのstartsample.shを実行
②Julius-plusを実行

としないとダメなようです。
Julius-plusが動いている状態でstartsample.shを実行すると、startsample.shが強制終了します。
(逆だと大丈夫なのが謎)

1.製品登録をする

以下のAmazon Developerのサイトにアクセスして製品登録します。
といっても本当に製品を登録するわけではなく、Alexaを利用するための下ごしらえみたいなものなので、この時点でラズパイが用意出来てなくても問題ありません。

https://developer.amazon.com/avs/home.html#/avs/home
Amazon Developerアカウントを作成していなければここで作成しておく。
 というかすでにAmazonアカウントを持っていれば、多分それが使えるはず。

「ALEXA VOICE SERVICE」タブを押してメニューを開き、「製品を作成する」を押す
f:id:engetu21:20180820211112j:plain

・製品名
適当でいい。私は「raspi3」としました。

・製品ID
適当でいい。私は「raspi3」としました。
なお、この設定は2項で使います。

・製品はアプリやデバイスを使用しますか ?
「端末」を選択

・商品カテゴリー
適当でたぶん大丈夫。とりあえず「家電」を選択。

・製品概要
適当に、「家電操作など」

・エンドユーザーは、商品とどのようにやり取りするのでしょうか ?
どれかを選択すれば問題なさそう。
ハンズフリー
「ファーフィールド」
を選択。

・画像をアップロード
特にいらないので、何もいらない。

・この製品を商品として配信する予定ですか ?
「いいえ」を選択

・これは子供向け商品、それ以外は13歳以下の子供向けですか ?
「いいえ」を選択

次にセキュリティの設定を行う。
・セキュリティプロファイル
適当に入れる。

・セキュリティプロファイルの説明
適当に入れる。



これによってクライアントIDとクライアントシークレットが作成されます。

が、作成されたものは使いません。
同様に他ブログで書かれている「許可された出荷地」「許可された返品URL」にも
http://localhost:3000」といった内容も設定しません。

おそらく「ウェブ」というタブでそこらへんが表示されていると思いますが、
使うのは「他のデバイスやプラットフォーム」のタブです。
f:id:engetu21:20180820214036j:plain

f:id:engetu21:20180820214045j:plain
クライアントID名は「raspi3」としてボタンを押せば、勝手にIDが生成されます。
今回はそれを使います。
一度、「ウェブ」に記載されているクライアントIDで実施しましたが、それだと認証が通りません。
詳しくはここら辺見てください。
https://github.com/alexa/avs-device-sdk/issues/743

2.ラズパイにAVS Device SDKをセッティング

AVS Device SDKにはラズパイ向けのクイックスタートページがあるため、それを元にインストールします。
https://github.com/alexa/avs-device-sdk/wiki/Raspberry-Pi-Quick-Start-Guide-with-Script

とりあえず、各種ソフトを更新

$ sudo apt update
$ sudo apt upgrade

ホームディレクトリにディレクトリを作ります。名前は何でもいい。

$ mkdir ~/avs-sdk
$ cd ~/avs-sdk

・セットアップ用にファイルを落とします。

$ wget https://raw.githubusercontent.com/alexa/avs-device-sdk/master/tools/Install/setup.sh && wget https://raw.githubusercontent.com/alexa/avs-device-sdk/master/tools/Install/config.txt && wget https://raw.githubusercontent.com/alexa/avs-device-sdk/master/tools/Install/pi.sh

configファイルを変更します。

$ vi config.txt

#NOTE: The Device Serial Number can be any unique number
DEVICE_SERIAL_NUMBER="123456"
CLIENT_ID="************************"
PRODUCT_ID="raspi3"

DEVICE_SERIAL_NUMBERは適当でいいです。というかデフォルトのままでOK。
CLIENT_IDには1項の最後に書いた「他のデバイスやプラットフォーム」のタブに記載されたクライアントIDを設定します。
PRODUCT_IDは製品IDとして指定したraspi3を設定します。


シェルスクリプトの実行権限を変更します。

$ sudo chmod 755 pi.sh setup.sh startsample.sh

pipが入っていないかも知れないので、インストールしておきます。
(セットアップ実行時に止まってしまったので順序としてここに入れておく)

$ curl -kL https://bootstrap.pypa.io/get-pip.py | sudo python3


・セットアップ実行

$ sudo ./setup.sh config.txt
################################################################################
################################################################################


AVS Device SDK Raspberry Pi Script - Terms and Agreements


The AVS Device SDK is dependent on several third-party libraries, environments,
and/or other software packages that are installed using this script from
third-party sources ("External Dependencies"). These are terms and conditions
associated with the External Dependencies
(available at https://github.com/alexa/avs-device-sdk/wiki/Dependencies) that
you need to agree to abide by if you choose to install the External Dependencies.


If you do not agree with every term and condition associated with the External
Dependencies, enter "QUIT" in the command line when prompted by the installer.
Else enter "AGREE".


################################################################################
################################################################################

※[AGREE]と入力し、Enter

勝手にインストールが始まる。

途中でライセンス承認などの対応が必要。(Enter押したりyesと入力したり)
また、git cloneを自動で実行し、GitHubから「avs-device-sdk」の取得模様。
(おそらくhttps://github.com/alexa/avs-device-sdkからDLしている)
gitのインストールはすでにやっていたが、これも事前にやっておいたほうがいいかは不明。


終わったら以下のように表示される。
**** Completed Configuration/Build ***



■startsample.shを実行(この段階では動かない)

$ sudo ./startsample.sh
2018-08-18 16:01:09.545 [ 1] I sdkVersion: 1.8.1
configFile /home/pi/avs-sdk/build/Integration/AlexaClientSDKConfig.json
Running app with log level: DEBUG9
2018-08-18 16:01:09.560 [ 1] 0 ConfigurationNode:initializeSuccess
2018-08-18 16:01:09.572 [ 1] 9 MediaPlayer:createCalled
2018-08-18 16:01:09.612 [ 1] E MediaPlayer:setupPipelineFailed:reason=createAudioSinkElementFailed,audioSinkElement=alsasink
2018-08-18 16:01:09.612 [ 1] E MediaPlayer:initPlayerFailed:reason=setupPipelineFailed
2018-08-18 16:01:09.612 [ 1] 9 MediaPlayer:~MediaPlayerCalled

(SampleApp:15078): GStreamer-CRITICAL **: gst_object_unref: assertion 'object != NULL' failed
2018-08-18 16:01:09.612 [ 1] 9 MediaPlayer:resetPipeline

(SampleApp:15078): GLib-CRITICAL **: g_main_context_find_source_by_id: assertion 'source_id > 0' failed
2018-08-18 16:01:09.612 [ 1] E RequiresShutdown:~RequiresShutdownFailed:reason=notShutdown,name=SpeakMediaPlayer
2018-08-18 16:01:09.613 [ 1] C SampleApplication:Failed to create media player for speech!
2018-08-18 16:01:09.613 [ 1] C SampleApplication:Failed to initialize SampleApplication
Failed to create to SampleApplication!

動かないっぽいので、質問サイトを元に gstreamer1.0-alsa をインストールします。
https://github.com/alexa/avs-device-sdk/issues/643

$ sudo apt install gstreamer1.0-alsa


・再度実行

$ sudo ./startsample.sh

※実行中の以下の内容をメモする。

##################################
# NOT YET AUTHORIZED #
##################################

################################################################################################
# To authorize, browse to: 'https://amazon.com/us/code' and enter the code: XXXXX #
################################################################################################

Checking for authorization (x)...

先駆者たちの記録を見ると、どうやらこのURL部分が「許可された出荷地」で設定した「http://localhost:3000」になるらしい。
上記URLにアクセスしても実際にはAmazonのページに遷移するだけみたいですが、
localhostに接続するんだったら、確かにラズパイ上のGUIでやらないとダメですね。
まぁ、今回の手順では関係ありませんが。


指定されたURLにアクセスします。インターネットに繋がるどのマシンからでも問題ありません。
f:id:engetu21:20180820220713j:plain

URLと共に表示された「code」を入力し、Continueを押します。
f:id:engetu21:20180820221058j:plain

問題なければAllowを押します。
f:id:engetu21:20180820222639j:plain


コードが認証されれば以下のようにラズパイCLIに出力されます。

##################################################
# Checking for authorization (32)... #
##################################################

2018-08-18 16:55:20.233 [ 2] 5 HttpPost:doPostSucceeded:code=400
2018-08-18 16:55:20.233 [ 2] 5 CBLAuthDelegate:receiveTokenResponse:code=400
2018-08-18 16:55:20.234 [ 2] 5 CBLAuthDelegate:mapHTTPStatusToError:code=400,error=INVALID_REQUEST
2018-08-18 16:55:20.234 [ 2] 5 CBLAuthDelegate:errorInLwaResponseBody:error=authorization_pending,errorCode=AUTHORIZATION_PENDING
2018-08-18 16:55:20.234 [ 2] 5 CBLAuthDelegate:setAuthError:authError=AUTHORIZATION_PENDING
2018-08-18 16:55:20.234 [ 2] 0 CBLAuthDelegate:receiveTokenResponseFailed:result=AUTHORIZATION_PENDING
##################################################
# Checking for authorization (33)... #
##################################################

2018-08-18 16:55:25.235 [ 2] 5 CBLAuthDelegate:requestToken
2018-08-18 16:55:25.847 [ 2] 5 HttpPost:doPostSucceeded:code=200
2018-08-18 16:55:25.847 [ 2] 5 CBLAuthDelegate:receiveTokenResponse:code=200

3.サンプルを動かしてみる。

サンプルといっても、Alexaを呼び出すにはこれで十分なんですが。

$ sudo ./startsample.sh

                  #    #     #  #####      #####  ######  #    #              
                 # #   #     # #     #    #     # #     # #   #               
                #   #  #     # #          #       #     # #  #                
               #     # #     #  #####      #####  #     # ###                 
               #######  #   #        #          # #     # #  #                
               #     #   # #   #     #    #     # #     # #   #               
               #     #    #     #####      #####  ######  #    #              
                                                                              
       #####                                           #                      
      #     #   ##   #    # #####  #      ######      # #   #####  #####      
      #        #  #  ##  ## #    # #      #          #   #  #    # #    #     
       #####  #    # # ## # #    # #      #####     #     # #    # #    #     
            # ###### #    # #####  #      #         ####### #####  #####      
      #     # #    # #    # #      #      #         #     # #      #          
       #####  #    # #    # #      ###### ######    #     # #      #          

       SDK Version 1.8.1

+----------------------------------------------------------------------------+
|                                  Options:                                  |
| Wake word:                                                                 |
|       Simply say Alexa and begin your query.                               |
| Tap to talk:                                                               |
|       Press 't' and Enter followed by your query (no need for the 'Alexa').|
| Hold to talk:                                                              |
|       Press 'h' followed by Enter to simulate holding a button.            |
|       Then say your query (no need for the 'Alexa').                       |
|       Press 'h' followed by Enter to simulate releasing a button.          |
| Stop an interaction:                                                       |
|       Press 's' and Enter to stop an ongoing interaction.                  |
| Privacy mode (microphone off):                                             |
|       Press 'm' and Enter to turn on and off the microphone.               |
| Echo Spatial Perception (ESP): This is for testing purpose only!           |
|       Press 'e' followed by Enter at any time to adjust ESP settings.      |
| Playback Controls:                                                         |
|       Press '1' for a 'PLAY' button press.                                 |
|       Press '2' for a 'PAUSE' button press.                                |
|       Press '3' for a 'NEXT' button press.                                 |
|       Press '4' for a 'PREVIOUS' button press.                             |
| Settings:                                                                  |
|       Press 'c' followed by Enter at any time to see the settings screen.  |
| Speaker Control:                                                           |
|       Press 'p' followed by Enter at any time to adjust speaker settings.  |
| Firmware Version:                                                          |
|       Press 'f' followed by Enter at any time to report a different        |
|       firmware version.                                                    |
| Info:                                                                      |
|       Press 'i' followed by Enter at any time to see the help screen.      |
| Reset device:                                                              |
|       Press 'k' followed by Enter at any time to reset your device. This   |
|       will erase any data stored in the device and you will have to        |
|       re-register your device.                                             |
|       This option will also exit the application.                          |
| Quit:                                                                      |
|       Press 'q' followed by Enter at any time to quit the application.     |
+----------------------------------------------------------------------------+

#############################
#       Connecting...       #
#############################
###########################
#       Authorized!       #
###########################
########################################
#       Alexa is currently idle!       #
########################################

正常に動いてますね!
この状態で「Alexa」としゃべるか「t」を入力することで、音声入力待ちの状態になります。
ただし、日本語で受け答えするには4項の対応が必要です。


なお、config.txtの設定が誤ってたりすると以下のように限定的な動作になるようです。

###############################################################
#       UNRECOVERABLE CAPABILITIES API ERROR: FORBIDDEN       #
#       Entering limited interaction mode.                    #
###############################################################

+----------------------------------------------------------------------------+
|                          In Limited Mode:                                  |
+----------------------------------------------------------------------------+
| Status : Unrecoverable Capabilities API call failure.                      |
+----------------------------------------------------------------------------+
| Info:                                                                      |
|       Press 'i' followed by Enter at any time to see the help screen.      |
| Stop an interaction:                                                       |
|       Press 's' and Enter to stop an ongoing interaction.                  |
| Privacy mode (microphone off):                                             |
|       Press 'm' and Enter to turn on and off the microphone.               |
| Speaker Control:                                                           |
|       Press 'p' followed by Enter at any time to adjust speaker settings.  |
| Reset device:                                                              |
|       Press 'k' followed by Enter at any time to reset your device. This   |
|       will erase any data stored in the device and you will have to        |
|       re-register your device.                                             |
|       This option will also exit the application.                          |
| Quit:                                                                      |
|       Press 'q' followed by Enter at any time to quit the application.     |
+----------------------------------------------------------------------------+

4.日本語に対応させる。

$ sudo ./startsample.sh
で、起動後に

>c
+----------------------------------------------------------------------------+
|                          Setting Options:                                  |
| Change Language:                                                           |
|       Press '1' followed by Enter to see language options.                 |
+----------------------------------------------------------------------------+


>1
+----------------------------------------------------------------------------+
|                          Language Options:                                 |
|                                                                            |
| Press '1' followed by Enter to change the language to US English.          |
| Press '2' followed by Enter to change the language to UK English.          |
| Press '3' followed by Enter to change the language to German.              |
| Press '4' followed by Enter to change the language to Indian English.      |
| Press '5' followed by Enter to change the language to Canadian English.    |
| Press '6' followed by Enter to change the language to Japanese.            |
| Press '7' followed by Enter to change the language to Australian English.  |
| Press '8' followed by Enter to change the language to French.              |
+----------------------------------------------------------------------------+


>6
###################################
#       locale set to ja-JP       #
###################################

で、日本語化完了。


5.Web上のAlexa設定画面でタイムゾーンを変える

Alexaの設定でタイムゾーンを日本のものにすることで、今何時?とかに正確に答えてくれるようになります。
https://alexa.amazon.co.jp/spa/index.html
f:id:engetu21:20180820223314j:plain

なお、本ページではAlexaと話したことが履歴として見れます。
ピカチュウと話した内容は録音はしてるけどテキストとしては残してない模様。
f:id:engetu21:20180820223652j:plain

6.ウェイクアップワードの反応が鈍いのでライブラリを変えてみる。

「アレクサ!」と話しかけても全然反応しない。
待機画面で「t」を入力することで代用可能ですが、流石にそれでは意味がない。
ライブラリはデフォルトではSensoryというのを使ってるみたいですが、snowboyというのがいいらしいのでそれに変えます。

※参考HP

Raspberry PiにAlexaを召喚する3つの方法
GitHub - Kitt-AI/snowboy: DNN based hotword and wake word detection toolkit
ラズパイにAlexaをインストールする – 草大福の備忘録



・Snowboyをダウンロード

$ cd ~/avs-sdk/third-party
$ sudo git clone https://github.com/Kitt-AI/snowboy.git

・libatlas(行列計算ライブラリらしい)をインストール

$ sudo apt install libatlas-base-dev

・setup.shの内容を変える。
cmakeの記述部分を変更する。以下の通り。

$ sudo vi ~/avs-sdk/setup.sh
cmake "$SOURCE_PATH/avs-device-sdk" \
"${CMAKE_PLATFORM_SPECIFIC[@]}" \
-DGSTREAMER_MEDIA_PLAYER=ON -DPORTAUDIO=ON \
-DPORTAUDIO_LIB_PATH="$THIRD_PARTY_PATH/portaudio/lib/.libs/libportaudio.$LIB_SUFFIX" \
-DPORTAUDIO_INCLUDE_DIR="$THIRD_PARTY_PATH/portaudio/include" \
-DCMAKE_BUILD_TYPE=DEBUG

cmake "$SOURCE_PATH/avs-device-sdk" \
"${CMAKE_PLATFORM_SPECIFIC[@]}" \
-DGSTREAMER_MEDIA_PLAYER=ON -DPORTAUDIO=ON \
-DPORTAUDIO_LIB_PATH="$THIRD_PARTY_PATH/portaudio/lib/.libs/libportaudio.$LIB_SUFFIX" \
-DPORTAUDIO_INCLUDE_DIR="$THIRD_PARTY_PATH/portaudio/include" \
-DCMAKE_BUILD_TYPE=DEBUG
-DKITTAI_KEY_WORD_DETECTOR=ON \
-DKITTAI_KEY_WORD_DETECTOR_LIB_PATH="$THIRD_PARTY_PATH/snowboy/lib/rpi/libsnowboy-detect.a" \
-DKITTAI_KEY_WORD_DETECTOR_INCLUDE_DIR="$THIRD_PARTY_PATH/snowboy/include" \

※一番最後の3行を追加


・startsample.shの内容を変更する。

$ sudo vi ~/avs-sdk/startsample.sh

./SampleApp "/home/pi/avs-sdk/build/Integration/AlexaClientSDKConfig.json" "/home/pi/avs-sdk/third-party/alexa-rpi/models" DEBUG9

./SampleApp "/home/pi/avs-sdk/build/Integration/AlexaClientSDKConfig.json" "/home/pi/avs-sdk/third-party/snowboy/resources" DEBUG9
~

・alexa.umdlをsnowboy/resourcesにコピー

$ sudo cp -a ~/avs-sdk/third-party/snowboy/resources/alexa/alexa-avs-sample-app/alexa.umdl ~/avs-sdk/third-party/snowboy/resources/

・ビルドでエラーになるらしいところを修正。

$ sudo vi ~/avs-sdk/avs-device-sdk/KWD/KittAi/src/KittAiKeyWordDetector.cpp
m_maxSamplesPerPush{(audioFormat.sampleRateHz / HERTZ_PER_KILOHERTZ) * msToPushPerIteration.count()} {

m_maxSamplesPerPush{(audioFormat.sampleRateHz / HERTZ_PER_KILOHERTZ) * static_cast(msToPushPerIteration.count())}{
→ここ、1.9.0で直ってるっぽいので対応不要で大丈夫な模様(2018/9/30)

$ sudo vi ~/avs-sdk/avs-device-sdk/build/cmake/BuildOptions.cmake
# Set up the compiler flags.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

した

# Set up the compiler flags.
add_definitions (-D_GLIBCXX_USE_CXX11_ABI=0) ←これを追加する
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

・ウェイクアップワード検知後に音を鳴らす。

$ sudo vi ~/avs-sdk/avs-device-sdk/SampleApp/src/UIManager.cpp
case DialogUXState::LISTENING:
ConsolePrinter::prettyPrint("Listening...");

case DialogUXState::LISTENING:
system("aplay ~/avs-sdk/third-party/snowboy/resources/dong.wav 1>/dev/null 2>/dev/null ");
ConsolePrinter::prettyPrint("Listening...");


・再ビルド

$ sudo ./setup.sh config.txt

**** Completed Configuration/Build ***
で無事完了

変えてみたけど、「アレクサ」というより、「ァルェクサァ」と英語的発音のほうが反応する模様。
こればっかりはしょうがないかなぁ。

なお、Snowboyの感度とボリュームの変更についてですが、SampleApplication.cppの

static const double KITT_AI_SENSITIVITY = 0.60;
static const float KITT_AI_AUDIO_GAIN = 2.0;

で設定されている値を変更すればいいと参考サイトには書いてありますが、
SDK1.7.0(Version 1.7.0 of the avs-device-sdk · alexa/avs-device-sdk@7bea05a · GitHub)の更新時に該当の定数定義は削除されているため、参考サイトの様に変更はできません。
じゃあどこでできるのかというと、これがわからず。
わかる人教えてください!


※2018/9/30追記
コメントで教えていただいたサイトを参考に、以下の設定でウェイクアップの感度を変えられる模様。
上野家のホームページ - PC/RaspberryPi/スマートスピーカー/alexaAVS Device SDKを動かしてみる - 資料室

sudo vi ~/avs-sdk/avs-device-sdk/KWD/KWDProvider/src/KeywordDetectorProvider.cpp
/// The sensitivity of the Kitt.ai engine.
static const double KITT_AI_SENSITIVITY = 0.6;

/// The audio amplifier level of the Kitt.ai engine.
static const float KITT_AI_AUDIO_GAIN = 2.0;

/// The sensitivity of the Kitt.ai engine.
static const double KITT_AI_SENSITIVITY = 0.70;

/// The audio amplifier level of the Kitt.ai engine.
static const float KITT_AI_AUDIO_GAIN = 0.5;


※2018/10/1追記
クリーンインストールしたラズパイに、これまでの手順で設定してみたら、どうもAlexaが返事をしてくれない。
というより、返事はしてくれてるけど、音声を再生できてなさそう(aplayなどでwavファイルなどが普通に再生できることは確認済み)。
どうもgstreamerあたりが怪しいみたいなので、以下のサイトを参考にとりあえず片っ端からインストールしました。
saikoro-house.com
といっても、そのままのコマンドではなく、現状aptにあるのをひとまずインストール。
で、これまで入ってなかったのが、gstreamer1.0-libavで、これ入れたらAlexaが喋ってくれました。

$ sudo apt install gstreamer1.0-libav

【CentOS】OpenStack(RDO)をインストールしてみる

https://www.rdoproject.org/

RDO is a community of people using and deploying OpenStack on CentOS, Fedora, and Red Hat Enterprise Linux.
ということで、OpenStackはどんなもんじゃろうということで、空いているHDDにCentOSを入れて、インストールしてみました。
(LinuxMintでDevStackを入れようと思ったら上手く入らなかった)

といっても、基本的にはここにある通り、コマンドを打てば簡単にインストール可能
https://www.rdoproject.org/install/packstack/

$ su -
$ yum update -y
$ yum install -y centos-release-openstack-queens

(略)
Installed:
centos-release-openstack-queens.x86_64 0:1-1.el7.centos

Dependency Installed:
centos-release-ceph-luminous.noarch 0:1.1-2.el7.centos
centos-release-qemu-ev.noarch 0:1.0-3.el7.centos
centos-release-storage-common.noarch 0:2-2.el7.centos
centos-release-virt-common.noarch 0:1-1.el7.centos

Complete!


$ yum update -y
$ yum install -y openstack-packstack

(略)
Installed:
openstack-packstack.noarch 1:12.0.0-2.el7

Dependency Installed:
facter.x86_64 1:2.4.4-4.el7
hiera.noarch 1:1.3.4-5.el7
libimagequant.x86_64 0:2.8.2-2.el7
libselinux-ruby.x86_64 0:2.5-12.el7
openjpeg2.x86_64 0:2.1.2-1.el7
openstack-packstack-puppet.noarch 1:12.0.0-2.el7
puppet.noarch 0:4.8.2-1.el7
puppet-aodh.noarch 0:12.4.0-1.el7
puppet-apache.noarch 0:2.3.1-1.e587f2agit.el7
puppet-archive.noarch 0:2.2.1-0.10888dbgit.el7
puppet-ceilometer.noarch 0:12.5.0-1.el7
puppet-certmonger.noarch 0:2.3.0-1.el7
puppet-cinder.noarch 0:12.4.0-1.el7
puppet-concat.noarch 0:4.1.1-1.d4857dfgit.el7
puppet-corosync.noarch 0:6.0.1-0.9940eb9git.el7
puppet-firewall.noarch 0:1.12.0-1.3dc1990git.el7
puppet-glance.noarch 0:12.5.0-1.el7
puppet-gnocchi.noarch 0:12.4.0-1.el7
puppet-heat.noarch 0:12.4.0-1.el7
puppet-horizon.noarch 0:12.4.0-1.el7
puppet-inifile.noarch 0:2.2.0-1.d2c38b9git.el7
puppet-ironic.noarch 0:12.4.0-1.el7
puppet-keystone.noarch 0:12.4.0-1.el7
puppet-magnum.noarch 0:12.2.0-1.el7
puppet-manila.noarch 0:12.4.0-1.el7
puppet-memcached.noarch 0:3.1.0-1.el7
puppet-mysql.noarch 0:5.2.1-1.a5497b2git.el7
puppet-neutron.noarch 0:12.4.0-1.el7
puppet-nova.noarch 0:12.4.0-1.el7
puppet-nssdb.noarch 0:1.0.1-1.el7
puppet-openstack_extras.noarch 0:12.4.0-1.el7
puppet-openstacklib.noarch 0:12.4.0-1.el7
puppet-oslo.noarch 0:12.4.0-1.el7
puppet-ovn.noarch 0:12.4.0-1.el7
puppet-panko.noarch 0:12.4.0-1.el7
puppet-rabbitmq.noarch 0:8.1.1-0.d4b06b7git.el7
puppet-redis.noarch 0:3.2.0-2.bfcc212git.el7
puppet-remote.noarch 0:0.0.1-3.7420908git.el7
puppet-rsync.noarch 0:0.4.0-3.447685fgit.el7
puppet-sahara.noarch 0:12.4.0-1.el7
puppet-ssh.noarch 0:3.0.1-4.fb2de75git.el7
puppet-staging.noarch 0:1.0.4-1.b466d93git.el7
puppet-stdlib.noarch 0:4.24.0-1.b0d99adgit.el7
puppet-swift.noarch 0:12.4.0-1.el7
puppet-sysctl.noarch 0:0.0.11-1.el7
puppet-tempest.noarch 0:12.5.0-1.el7
puppet-trove.noarch 0:12.4.0-1.el7
puppet-vcsrepo.noarch 0:2.3.0-1.bb1209egit.el7
puppet-vswitch.noarch 0:8.4.0-1.el7
puppet-xinetd.noarch 0:3.0.0-1.b95c79cgit.el7
python-docutils.noarch 0:0.11-0.3.20130715svn7687.el7
python2-olefile.noarch 0:0.44-1.el7
python2-pbr.noarch 0:3.1.1-8.el7
python2-pillow.x86_64 0:4.0.0-1.el7
ruby-augeas.x86_64 0:0.5.0-1.el7
ruby-shadow.x86_64 0:1.4.1-23.el7
rubygem-rgen.noarch 0:0.6.6-2.el7

Complete!


$ sudo packstack --allinone
Welcome to the Packstack setup utility

The installation log file is available at: /var/tmp/packstack/20180811-164344-0UZHo_/openstack-setup.log
Packstack changed given value to required value /root/.ssh/id_rsa.pub

Installing:
Clean Up [ DONE ]
Discovering ip protocol version [ DONE ]
Setting up ssh keys [ DONE ]
Preparing servers [ DONE ]
Pre installing Puppet and discovering hosts' details [ DONE ]
Preparing pre-install entries [ DONE ]
Setting up CACERT [ DONE ]
Preparing AMQP entries [ DONE ]
Preparing MariaDB entries [ DONE ]
Fixing Keystone LDAP config parameters to be undef if empty[ DONE ]
Preparing Keystone entries [ DONE ]
Preparing Glance entries [ DONE ]
Checking if the Cinder server has a cinder-volumes vg[ DONE ]
Preparing Cinder entries [ DONE ]
Preparing Nova API entries [ DONE ]
Creating ssh keys for Nova migration [ DONE ]
Gathering ssh host keys for Nova migration [ DONE ]
Preparing Nova Compute entries [ DONE ]
Preparing Nova Scheduler entries [ DONE ]
Preparing Nova VNC Proxy entries [ DONE ]
Preparing OpenStack Network-related Nova entries [ DONE ]
Preparing Nova Common entries [ DONE ]
Preparing Neutron LBaaS Agent entries [ DONE ]
Preparing Neutron API entries [ DONE ]
Preparing Neutron L3 entries [ DONE ]
Preparing Neutron L2 Agent entries [ DONE ]
Preparing Neutron DHCP Agent entries [ DONE ]
Preparing Neutron Metering Agent entries [ DONE ]
Checking if NetworkManager is enabled and running [ DONE ]
Preparing OpenStack Client entries [ DONE ]
Preparing Horizon entries [ DONE ]
Preparing Swift builder entries [ DONE ]
Preparing Swift proxy entries [ DONE ]
Preparing Swift storage entries [ DONE ]
Preparing Gnocchi entries [ DONE ]
Preparing Redis entries [ DONE ]
Preparing Ceilometer entries [ DONE ]
Preparing Aodh entries [ DONE ]
Preparing Puppet manifests [ DONE ]
Copying Puppet modules and manifests [ DONE ]
Applying 192.168.11.XXX_controller.pp
192.168.11.XXX_controller.pp: [ DONE ]
Applying 192.168.11.XXX_network.pp
192.168.11.XXX_network.pp: [ DONE ]
Applying 192.168.11.XXX_compute.pp
192.168.11.XXX_compute.pp: [ DONE ]
Applying Puppet manifests [ DONE ]
Finalizing [ DONE ]

**** Installation completed successfully ******

Additional information:
* A new answerfile was created in: /root/packstack-answers-20180811-164344.txt
* Time synchronization installation was skipped. Please note that unsynchronized time on server instances might be problem for some OpenStack components.
* Warning: NetworkManager is active on 192.168.11.XXX. OpenStack networking currently does not work on systems that have the Network Manager service enabled.
* File /root/keystonerc_admin has been created on OpenStack client host 192.168.11.XXX. To use the command line tools you need to source the file.
* To access the OpenStack Dashboard browse to http://192.168.11.XXX/dashboard .
Please, find your login credentials stored in the keystonerc_admin in your home directory.
* Because of the kernel update the host 192.168.11.XXX requires reboot.
* The installation log file is available at: /var/tmp/packstack/20180811-164344-0UZHo_/openstack-setup.log
* The generated manifests are available at: /var/tmp/packstack/20180811-164344-0UZHo_/manifests

インストールができればダッシュボードにアクセスが可能。
なお、パスワードは以下のファイルに記載されている(ランダム生成)。
/root/keystonerc_admin

以下で、アクセス可能。
http://192.168.11.XXX/dashboard
user:admin
password:****************

【LinuxMint】カーネルロールバック

仮想マシンのLinuxMintをカーネルを4.13にしたらうまく動くなったので、4.10に戻しました。

キャプチャとかできなかったので雑に。
仮想マシン起動後に即ESCキーを実行、一度GRUB画面でカーネル4.10で起動します。
Ubuntu Kernel Update Utility (Ukuu) - GUIから簡単にカーネルのバージョンを確認して古いカーネルを削除できる | Ubuntuアプリのいいところ
を参考に

$ sudo apt-add-repository ppa:teejee2008/ppa
$ sudo apt update
$ sudo apt install ukuu

ukuuをGUI起動し、4.13カーネルをremoveすることで、4.10での起動ができるようになります。

※今どのカーネルを利用できるかは以下のコマンドで確認可能

$ uname -r

【KVM/QEMU】仮想マシン(Win10)と実マシン(Win10)のベンチマーク比較(おまけで仮想ディスクベンチマーク)

タイトルの通りですが、どんなもんだろうと思って比較しました。

■前提条件

仮想マシンはついこないだ構築したばかり(【Linux Mint】KVMによるパススルー設定 - かっこいいブログ名つけたい)でLinuxMint上のWin10です。

・実マシンと言っているのは、↑とは別のSSDにインストール済みの元々使っていたWin10ですが、割と使い込んでいるのでいろいろアプリが入ってます。

・基本的に各パターン1回程度の実行です。本当は何回かやったほうがいいと思うけど、時間が足りない。

・一応、環境を再記載

マザボ:ASRock Z170 Extreme4

メモリ:DDR4 32GB

CPU:Core i7-6700K 

グラボ:STRIX-GTX1060-DC2O6G

 

1.cpu-z(1.84)でのCPUベンチマーク比較

パターン①:virt-managerの設定にて

・設定:「ホストCPUの設定をコピー」

トポロジー:ソケット数2 コア数:4

f:id:engetu21:20180410204603p:plain

 

パターン②:virt-managerの設定にて

・設定:「ホストCPUの設定をコピー」

トポロジー:ソケット数1 コア数:8

f:id:engetu21:20180410204332p:plain

 

パターン③:virt-managerの設定にて

・設定:モデルに直接「host-passthrough」(参考:KVM - ArchWiki)

トポロジー:手動設定なし

f:id:engetu21:20180410205139p:plain

 

パターン④:virt-managerの設定にて

・設定:モデルに直接「host-passthrough」(参考:KVM - ArchWiki)

トポロジー:ソケット数2 コア数:4

f:id:engetu21:20180410205300p:plain

 

パターン⑤:実マシン

f:id:engetu21:20180410205408p:plain

 

整理すると

パターン

設定

ソケット数

コア数

CPU Single Thread

CPU Multi Thread

パターン①

ホストCPUの設定をコピー

2

4

418

2322.1

パターン②

ホストCPUの設定をコピー

1

8

427.8

2288.8

パターン③

host-passthrough

手動設定なし

手動設定なし

440.4

869.7

パターン④

host-passthrough

2

4

412.2

2335.5

パターン⑤

-

1

8

435.2

2408.8

です。

計測時の画像でReferenceを設定していたりしていなかったりはご愛嬌で・・・。

パターン③のCPU Multi Threadが極端に遅いのはソケット数とコア数がともに2ずつしか認識していないからですね。Windows7~10ではソケット数の上限が2個に制約されてしまうらしいです(WindowsServerならそうでもないらしい?)。ので、Redhat仮想化のチューニングと最適化ガイド - Red Hat Customer Portalで記載されている、

「注記

環境によっては要件が異なることもありますが、 ソケット数を選択する場合、 コア、 スレッドいずれもひとつのみにした方が一般的には最善のパフォーマンスとなります。」

というのを信じて、仮想Windowsマシンをソケット数8でコア数1で設定しても、パターン③同様にソケット数は2個として認識されます。

 

実際のところ、仮想環境でオーバーヘッドがかかるかと思いきやそうでもない感じですかね?

実マシンとの性能差異がない、というか、Referenceの6700Kと比較しても遜色がないですな・・・。

ちなみに

【Linux/QEMU/KVM】 CPU Pinning(CPUアフィニティ)の設定でゲスト上のWindowsを快適に動かす - TECHLOGICS

を参考にCPU Pinningをやっていますが、やっていない状態とあまりスコアの違いは見られませんでした。

 

なお、設定を「ホストCPUの設定をコピー」と「host-passthrough」ではcpu-z上でCPU欄は以下のように変わります。

・「ホストCPUの設定をコピー」

f:id:engetu21:20180410212007p:plain

・「host-passthrough」

f:id:engetu21:20180410222205p:plain

「host-passthrough」のほうはプロセッサ情報が実CPU情報になるようですね。面白いですねぇ。

 

2.CrystalMark2004R7での比較

パターン①:virt-managerの設定にて

・設定:「ホストCPUの設定をコピー」

トポロジー:ソケット数1 コア数:8

f:id:engetu21:20180410213633p:plain

 

パターン②:virt-managerの設定にて

・設定:モデルに直接「host-passthrough」(参考:KVM - ArchWiki)

トポロジー:ソケット数2 コア数:4

f:id:engetu21:20180410213437p:plain

 

パターン③:実マシン

f:id:engetu21:20180410213320p:plain

 

総合スコアでみるとなぜか実マシンが負けるという・・・

 

3.結論

ベンチマーク的に見れば仮想環境でも十分性能は発揮できる。1項の設定パターンについては、思った以上にはスコア差出なかったのでパターン③以外であれば何でもいいんじゃないですかね。(適当)

 

4.おまけ

ところで仮想環境上ではSSDの読み書きは遅くなるのかな? と思って測ってみました。

ただ、フォーマットはqcow2とrawで比較するとraw(非スパース)のほうがいいらしい。

なんでもqcow2は使った分だけディスク領域を使うがオーバーヘッドが発生し、raw(非スパース)は定義したディスク領域を最初からガツっと確保するらしいので、オーバーヘッドが起きにくいとか。ということなので、それも比較。

参考:KVMを使う(ディスク性能編その2) « さくらインターネット研究所

 

パターン①【qcow2】

・仮想ディスクのパフォーマンスオプション
キャッシュモデル:ハイパーパイザーのデフォルト(writethrough)
IOモード:ハイパーパイザーのデフォルト

f:id:engetu21:20180410214459p:plain

 

パターン②【raw(非スパース)】

※qcow2→raw(スパース)→raw(非スパース)に変換したもの

・仮想ディスクのパフォーマンスオプション
キャッシュモデル:ハイパーパイザーのデフォルト(writethrough)
IOモード:ハイパーパイザーのデフォルト

f:id:engetu21:20180410214812p:plain

 

あまり変わりませんね・・・?

qcow2はディスク拡張すると性能劣化が激しいと聞いており、実際やりましたが(【LinuxMint】【QEMU/KVM】ディスク容量を拡張する - かっこいいブログ名つけたい)、そうでもありませんね。

というより、CT250MX500SSD1使っていますが、read:560MB/s、wirte:510MB/sなのになぜそれより早いのか? 仮想マシンだからキャッシュメモリを使ってるとかそんな感じかな?

仮想マシンで動かしたほうが早くなるってことになるのかな・・・?(謎)

【LinuxMint】【QEMU/KVM】ディスク容量を拡張する

KVM上に入れたWindows10ですが、250GBのうち、仮想マシン用として80GB用意してデータ移管していたらあっという間に容量がなくなったため、更に50GB追加します。ので容量拡張方法をメモ。 

1.バックアップを取る

バックアップを取りますが、qcow2形式で仮想マシンを作っており、かつスナップショットを利用していた場合、スナップショットを削除してからバックアップをとったほうが良いです。

スナップショットを消さずに拡張しようとしたらエラーになりました。

$ sudo qemu-img resize win10.qcow2 +50G
qemu-img: Can't resize an image which has snapshots
qemu-img: This image does not support resize

 スナップショットは以下の画面から操作可能。

f:id:engetu21:20180404232932p:plain

スナップショットを削除後、容量のあるドライブにイメージファイルを退避。

普通に仮想マシンを作っていれば以下に格納されているはず。

$ cd /var/lib/libvirt/images

$ ls

win10.qcow2

 

 /var/lib/libvirt/imagesはアクセス拒否されるかもしれないので、chmod755でパーミッションを変更したほうがいいかも

 

・イメージを退避

$ sudo cp -a win10.qcow2 /mnt/3TB/noSnapshot-win10-backup.qcow2

 

2.ディスクの拡張

以下のコマンドで実行されます。今回は50Gを拡張

$ sudo qemu-img resize win10.qcow2 +50G

Image resized.

 

3.Windows上でのディスク拡張

2項を実行後に仮想マシンのWin10を起動。この状態では、増えた容量は未割当て状態になるため、これを使えるようにする。

エクスプローラを開き、「PC」→右クリック→「管理」→「記憶域」→「ディスクの管理(ローカル)」

拡張できていれば空き領域50GB分ができているはずなので、割り当て済みの領域((C:)と書かれているところ)の上で右クリックし、「ボリュームの拡張」を選択

f:id:engetu21:20180404234404p:plain

 

サイズを選択。ここではすべて

f:id:engetu21:20180404234406p:plain

 

拡張が完了すれば、すべての領域がWin10上で使用可能になる。

f:id:engetu21:20180404234408p:plain

 

【Linux Mint】KVMによるGPUパススルー設定

かっこいいブログ名付けたいと思ったのでブログ名を変えました。

-------------------------------------------------

さて、STRIX-GTX1060-DC2O6Gを購入しましたが、現状はゲームで利用しているだけで流石にどうかとおもったので、思い切ってメインPCの構成を変えることにしました。

以下の内容は個人的なメモではあるものの、GPUパススルーをやってみたいという方への助けになればと思ってます。

■参考サイト

Running Windows 10 on Linux using KVM with VGA Passthrough – Heiko's Blog

うらもちゃのブログ: ゲストにPCIパススルー(GPU割当)

CentOS7 KVM で PCIパススルー、USBパススルー - わすれないうちにメモしよう

PCI passthrough via OVMF - ArchWiki

 KVM GPUパススルー設定 - 睡分不足

 

あと、用語はこちらが参考になるかと

KVM-wiki TOP - PukiWiki

1.やりたいこと

有り余るマシンスペックを使うべく、考えた構成は以下のとおりです。

・ホストとなるベースOSはLinuxにしたい

・ホストの上に仮想マシンを構築し、Windows10とそれとは別にLinuxを載せたい

・グラボについては、仮想Win10でのモニタ表示、仮想LinuxGPGPUとして使いたい(グラボのリソースは共有できないので、どちらか一方が起動していたらどちらかは落ちてる状態)

 

正直、今のグラボは性能はいいですが、いかんせんユーザ(私)自身が十分にスペックを活用できているかというとそうではありません。

また、機械学習(AI)の勉強をしてみたいと思っており、そうであればGPUを使わない手はありません。

であれば、グラボを活用できるように構成を見直す、というのがコンセプトです。

なお、グラボに関してですが、ホストOSでは一切使用できません。ホストOSで画面描写に利用するのはCore i7-6700Kに搭載されている内蔵GPU機能となります。

 

2.構成

メインPCとして利用しているマシンの構成は以下のとおりです。

マザボ:ASRock Z170 Extreme4

・メモリ:DDR4 32G

・CPU:Core i7-6700K 

・グラボ:STRIX-GTX1060-DC2O6G

 

3.KVMの利用について

まず、メインPCとして利用するホストOSについてですが、

Linux Mint 18.3 Cinnamon - Linux Mint

とします。Ubuntu系であるというのと、GUIにそれなりに気を配っている点を考慮してです。

仮想化については、KVMを使います。KVM自体はLinuxカーネルに含まれる仮想化基盤となるため、今回はQEMUと組み合わせての利用となります。

普通に仮想基板上で画面描写をした場合、これはもうFF14ベンチマークがローディングで止まるぐらいクソ遅いのですが、ここで重要になるのが仮想基盤を通さず、直接グラボとやり取りできる、いわゆるGPUパススルーです。が、それが今回の大きな難関なわけで、esxi 6.5とProxmox VEでやってみたけど、挫折してQEMU/KVMにしたというのが正直なところ・・・。

 

3.マザボの設定

いくつかのサイトで既に記載されていますが、CPUがIntel製であれば、基本的にVT-dをONに設定できるマザボである必要があります。

幸い、私のマザボのASRockはそこら辺がだいたい全部対応してるとのことで、UFEIでVT-DをONにするだけでいけます。他のメーカは・・・まぁそれぞれによるかと。

基本的に「Intel VT-d」「I/O Virtualization Technology」などの名前の設定項目を有効にすれば問題なし。

 

4.ホストOSのインストール

これは普通にインストールをするだけなので省略。

 

5.GRUBの設定

GPUパススルーをするにはintelの仮想化支援機構である、IOMMUを活性化する必要があります。これはGRUB、要するにLinuxブートローダですが、これを実行するときにIOMMUの指定が必要です。設定するファイルは以下の通り。

$ sudo vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash "

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"

$ sudo update-grub

※PCを再起動

 

参考サイトによっては、GRUB_CMDLINE_LINUX_DEFAULTで定義したり、GRUB_CMDLINE_LINUXで定義したり・・・。

両方試しましたが、どちらでもよさそうで、以下のように『IOMMU enabled』が確認できればとりあえず問題ない(はず)です。

 $ dmesg | grep -e DMAR -e IOMMU
[ 0.000000] ACPI: DMAR 0x0000000087A48EA0 000070 (v01 INTEL SKL 00000001 INTL 00000001)
[ 0.000000] DMAR: IOMMU enabled

 

6.IOMMUグループが有効であることを確認する

一旦以下のシェルを作り、PCIバイスがどのようにIOMMUグループにマップされているかを確認できます。暫定的に作るのでファイル名は適当。

$cd ~/

$ vi aaa

#!/bin/bash
shopt -s nullglob
for d in /sys/kernel/iommu_groups/*/devices/*; do
n=${d#*/iommu_groups/*}; n=${n%%/*}
printf 'IOMMU Group %s ' "$n"
lspci -nns "${d##*/}"
done;

 

$ sudo chmod 755 aaa
$ ./aaa

IOMMU Group 0 00:00.0 Host bridge [0600]: Intel Corporation Sky Lake Host Bridge/DRAM Registers [8086:191f] (rev 07)
IOMMU Group 1 00:01.0 PCI bridge [0604]: Intel Corporation vfio-pciSky Lake PCIe Controller (x16) [8086:1901] (rev 07)
IOMMU Group 1 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1c03] (rev a1)
IOMMU Group 1 01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f1] (rev a1)

・・・

 

今回は赤文字のグラボをパススルーします。なお、以下のコマンドでよって、グラボが現状どのドライバを使っているか詳細に確認できます。(後々重要)

$ lspci -nnk -d 10de:1c03

01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1c03] (rev a1) Subsystem: ASUSTeK Computer Inc. Device [1043:85c5]

Kernel driver in use: nouveau

Kernel modules: nvidiafb, nouveau

$ lspci -nnk -d 10de:10f1

01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f1] (rev a1) Subsystem: ASUSTeK Computer Inc. Device [1043:85c5]

Kernel driver in use: snd_hda_intel

Kernel modules: snd_hda_intel

 

7.各種必要なソフトウェアのインストール

aptでインストールできるlibvirtに関しては、びっくりするほどバージョンが古いため、LinuxMintのGUI上のソフトウェアソースにて、以下のPPAを予め設定しておきます。

ppa:jacob/virtualisation

f:id:engetu21:20180402225313p:plain

 

上記を行ったうえで、qemu, libvirt, ovmf, virt-managerをそれぞれインストールします。

$ sudo apt update
$ sudo apt install qemu-kvm qemu-utils qemu-efi ovmf libvirt-bin libvirt-dev libvirt0 virt-manager

libvirt:仮想化管理用の共通APIを提供する

OVMF:仮想環境で UEFI を使えるようにする

virt-manager:仮想環境をGUI上で管理運用できるようにするオープンソースソフトウェア

 

以下のコマンドで、libvirtとvirtlog(libvirtのログ出力サービス)の実行と自動実行設定を行います。

$ sudo systemctl start libvirtd
$ sudo systemctl enable libvirtd

$ sudo systemctl start virtlogd
$ sudo systemctl enable virtlogd

 

 なお、この際にlibvirtdのstatusを確認し、エラーが発生していた場合は以下の対応をします。

参考:https://kernhack.hatenablog.com/entry/2014/05/12/221554

$ sudo systemctl status libvirtd
● libvirtd.service - Virtualization daemon
Loaded: loaded (/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
Active: active (running) since 木 2018-03-29 18:21:51 JST; 1s ago
Docs: man:libvirtd(8)
http://libvirt.org
Main PID: 4130 (libvirtd)
CGroup: /system.slice/libvirtd.service
└─4130 /usr/sbin/libvirtd

3月 29 18:21:51 XXXX-desktop systemd[1]: Starting Virtualization daemon...
3月 29 18:21:51 XXXX-desktop systemd[1]: Started Virtualization daemon.
3月 29 18:21:51 XXXX-desktop libvirtd[4130]: libvirt version: 2.2.0, package: 0~16.04~ppa0 (Jacob Zimmermann <ppa@jzimm.net> Wed, 07 Sep 2016 22:
3月 29 18:21:51 XXXX-desktop libvirtd[4130]: hostname: XXXXXXX
3月 29 18:21:51 XXXX-desktop libvirtd[4130]: direct firewall backend requested, but /sbin/ebtables is not available: そのようなファイルやディレク
3月 29 18:21:51 XXXX-desktop libvirtd[4130]: 内部エラー: Failed to initialize a valid firewall backendIOMMU Group 1 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1c03] (rev a1)
IOMMU Group 1 01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f1] (rev a1)

※ebtablesをインストール。

$ sudo apt install ebtables

$ sudo systemctl status libvirtd
● libvirtd.service - Virtualization daemon
Loaded: loaded (/lib/systemd/system/libvirtd.service; enab。led; vendor preset: enabled)
Active: active (running) since 木 2018-03-29 18:26:31 JST; 5s ago
Docs: man:libvirtd(8)
http://libvirt.org
Main PID: 5341 (libvirtd)
CGroup: /system.slice/libvirtd.service
├─5341 /usr/sbin/libvirtd
└─5444 /usr/sbin/libvirtd

3月 29 18:26:31 XXXX-desktop systemd[1]: Starting Virtualizod 755 aaa ation daemon...
3月 29 18:26:31 XXXX-desktop systemd[1]: Started Virtualization daemon.

 

8.仮想マシンを作る

CPUやメモリサイズに関しては各自の設定したいスペックに合わせて。

Win10の仮想マシンを作るときの最後のダイアログで、「インストールの前に設定をカスタマイズする」にチェックを入れ(これ重要)、完了。

出てきたダイアログの【概要】のファームウェアUEFIを選択します。

f:id:engetu21:20180402232240p:plain

 

f:id:engetu21:20180402232200p:plain

参考にさせていただいたhttp://mmi.hatenablog.com/entry/2018/03/25/010933では仮想マシン作成後に直接設定ファイルを弄ってましたが、これは一度仮想マシンを作るとGUI上は変更できないようで、作る際に上記のようにGUIで操作しておけば問題ない模様。

 

・Windows10インストール

Win10は

Windows 10 のディスク イメージ (ISO ファイル) のダウンロード

からisoファイルのダウンロードしてマウントし、クリーンインストールします。

注意点として、インストール時にVirtIOのドライバがないと、ドライバを読み込めと言われて先に進めなくなります。

そのため、まず

https://docs.fedoraproject.org/quick-docs/en-US/creating-windows-virtual-machines-using-virtio-drivers.html#virtio-win-direct-downloads

にある「Stable virtio-win iso」をダウンロードします。

virt-managerで『ハードウェアの追加』からCD-ROMデバイスを追加し、先ほど落としたvirtio-win.isoをマウントしておきます。

f:id:engetu21:20180404230347p:plain

もう一度整理すると、Window10インストール時はWin10自体のイメージとVirtIOドライバ用のイメージの両方が必要になります。

9.vendor id偽装

今回使用するのは、NVIDIAGeForceですが、これはグラフィック用に販売されているだけあって、GPUパススルーをするにはロックがかかっていて通常はできないらしいです(NVIDIA TeslaのようなGPGPU専用製品はそうではない模様)。

しかし、今回はパススルーするために以下のように8項で作っておいた仮想マシンの設定を変更することでGPUパススルーができるようになります(※もちろんメーカ非推奨のため注意!)。

なお、仮想マシン名はwin10です。

$ virsh edit win10

<features>
  <acpi/>
  <apic/>
  <hyperv>
    <relaxed state='on'/>
    <vapic state='on'/>
    <spinlocks state='on' retries='8191'/>
    <vendor_id state='on' value='whatever'/> ←追加
  </hyperv>
  <kvm> ←追加
    <hidden state='on'/>←追加
  </kvm>←追加

</features>

 

10.vfio-pciの使用

VIFOについては↓のブログで説明されているのですが、

VFIOによるデバイス操作 - 睡分不足

vfio-pciは要するに擬似ドライバみたいなものらしく(あってる?)、それを使うというのはどういうことかというと、要するにホストOS(私の環境ではLinuxMint)で認識されているグラボを認識から外す、と言った感じになるようです。

現状のグラボのドライバ読み込みは以下のようになっています。

$ lspci -v -d 10de:1c03 | grep Kernel

Kernel driver in use: nouveau

Kernel modules: nvidiafb, nouveau

$ lspci -v -d 10de:10f1 | grep Kernel

Kernel driver in use: snd_hda_intel

Kernel modules: snd_hda_intel

nouveauはNVIDIA グラボ用のフリードライバとのこと。

1項で書いたとおり、ホストOSではグラボは使いません(ホストOSのモニタ表示はCPU内臓のGPU機能を使う)。

グラボはホストOS上の仮想Win10のモニタ表示と仮想LinuxGPGPUとして使いたいので、上記のようにホストOSでグラボが認識できるようNVIDIA用のドライバが読み込まれていると不都合なわけです。

そのため、グラボのドライバをvfio-pciにすることで、ホストOSによるモニタ表示に使えなくします(これをしないとホストOSとゲストOS(win10)でグラボを取り合うことになるので画面は正常に動かなくなる模様)。

 

 ・vfio-pciが使えるか確認

$ modinfo vfio-pci
filename: /lib/modules/4.13.0-37-generic/kernel/drivers/vfio/pci/vfio-pci.ko
description: VFIO PCI - User Level meta-driver
author: Alex Williamson <alex.williamson@redhat.com>
license: GPL v2
version: 0.201です。:00.1
srcversion: 559BDF748E53047F2FF090B
depends: vfio,irqbypass,vfio_virqfd
intree: Y
name: vfio_pci
vermagic: 4.13.0-37-generic SMP mod_unload
parm: ids:Initial PCI IDs to add to the vfio driver, format is "vendor:device[:subvendor[:subdevice[:class[:class_mask]]]]" and multiple comma separated entries can be specified (string)
parm: nointxmask:Disable support for PCI 2.3 style INTx masking. If this resolves problems for specific devices, report lspci -vvvxxx to linux-pci@vger.kernel.org so the device can be fixed automatically via the broken_intx_masking flag. (bool)
parm: disable_vga:Disable VGA resource access through vfio-pci (bool)
parm: disable_idle_d3:Disable using the PCI D3 low power state for idle, unused devices (bool) 

上記のように表示されればまず問題ないはず。というか、Linuxカーネル4.1以上でvfio-pciは組み込まれているはずなので、それ以上であれば問題ないはず。

 

・モジュールリストの更新。

以下を追加することでブート時に読み込むモジュール指定できます。

$ sudo vi /etc/modules
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
kvm
kvm_intel

※この段階で一度再起動する

・上記の設定が問題なければ、追加したモジュールはlsmodで見れます。

$ lsmod | grep vfio
vfio_pci 40960 0
vfio_virqfd 16384 1 vfio_pci
irqbypass 16384 2 kvm,vfio_pci
vfio_iommu_type1 24576 0
vfio 28672 2 vfio_iommu_type1,vfio_pci


$ lsmod | grep kvm
kvm_intel 204800 0
kvm 589824 1 kvm_intel
irqbypass 16384 2 kvm,vfio_pci

・/etc/modprobe.d/vfio.confを新規に作ってデバイスを設定

LinuxMintにはvfio.confがはいっていなかったので、新規に作ります。私の環境では以下の通りですが、これは6項に一度記載した グラボのグラフィックとオーディオのPCI ID部分が設定対象になります。

 IOMMU Group 1 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1c03] (rev a1)
IOMMU Group 1 01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f1] (rev a1)

 

$ sudo vi /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:1c03,10de:10f1,1b21:1242,1033:0194

後ろの2つのPCI-IDはUSB PCIのパススルー設定ですが、今回は説明を割愛。

・一度再起動した後、以下のコマンドを実行


$ dmesg | grep -i vfio
[ 3.382020] VFIO - User Level meta-driver version: 0.3
[ 3.390893] vfio_pci: add [10de:1c03[ffff:ffff]] class 0x000000/00000000
[ 3.412048] vfio_pci: add [10de:10f1[ffff:ffff]] class 0x000000/00000000
[ 3.412053] vfio_pci: add [1b21:1242[ffff:ffff]] class 0x000000/00000000
[ 3.412054] vfio_pci: add [1033:0194[ffff:ffff]] class 0x000000/00000000

上記のように登録されていればOK。

ここでマシンを再起動します。

 

再起動後、ホストOS上でグラボにどのドライバが設定されているかを見ます。

$ lspci -v -d 10de:1c03 | grep Kernel

Kernel driver in use: nouveau

Kernel modules: nvidiafb, nouveau

$ lspci -v -d 10de:10f1 | grep Kernel

Kernel driver in use: vfio-pci

Kernel modules: snd_hda_intel

上記のようにオーディオが変わっているが、グラフィックのほうが変わっていない場合は更に設定を変更します。

方法は3つ。なお、私の環境では①はうまく動かず、②は他のサイトに書いてありましたが未実施、というか③のほうがより明示的な指定なので、③の方式にしました。

ブラックリストに/etc/modprobe.d/blacklist.confに記載を追加

$ sudo  vi /etc/modprobe.d/blacklist.conf
blacklist nouveau
blacklist snd-hda-intel

※保存後、再起動

②/etc/default/grubの設定で、nomodesetを追加

$ sudo vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT=01:00.1"quiet splash intel_iommu=on"

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on nomodeset"

$ sudo update-grub

※再起動

 

③/etc/default/grubの設定で、modprobe.blacklist=nouveauを追加

$ sudo vi /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on"

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on modprobe.blacklist=nouveau"

$ sudo update-grub

※再起動

 

設定後に以下のようになっていればOK

$ lspci -v -d 10de:1c03 | grep Kernel

Kernel driver in use: vfio-pci

Kernel modules: nvidiafb, nouveau

 

 11.仮想マシン設定でパススルーするPCIを設定

仮想マシンの「ハードウェアの追加」からPCIを選択します。

f:id:engetu21:20180403002513p:plain

 IOMMU Group 1 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:1c03] (rev a1)
IOMMU Group 1 01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f1] (rev a1)

 6項で確認したデバイスの番号と合うものを選択します。

 

後は仮想マシン設定で「ディスプレイSpice」と「ビデオQXL」を削除します。

仮想マシンを起動して、グラボに繋いだHDMIからモニタに出力されていればGPUパススルーは完了です。

 

12.グラボのGPUパススルーと直使用の比較

FF14ベンチマークをやってみました。

GPUパススルー】

f:id:engetu21:20180403003206p:plain

【直】

f:id:engetu21:20180403003222p:plain

 

やはり性能差は出る模様ですが、ゲームをする分には支障ないレベルみたいです。

おそらくチューニングをやれば性能は上がると思われますが…