Rails appをAWSデプロイしようとしたら<top (required)>’: uninitialized constant Devise (NameError)

はじめに

Railsでアプリケーションの簡単な骨組みだけを作り、AWSでデプロイしようとしたらunicornがうまく走りませんでした。

ps aux | grep unicorn

を叩いて見てもウンともすんとも言わず・・・

気になったので

less log/unicorn.stderr.log

と入力してみたところ下記のエラーが出てきました。

〜〜/config/initializers/devise.rb:5:in `<top (required)>': uninitialized constant Devise (NameError)

ここまでに試したこと

bundle install
bundle update
rails g devise:install

その他
/initializer/devise.rb内のconfig.secret_keyの使用

試してみましたがエラーの改善には繋がりませんでした。

試したこと

/config/application.rb内に

require 'devise'

を記述。エラーがなくなりました。

参考にしたサイト

【Ruby】デプロイ時にDeviseでエラーが発生してしまいます。
https://teratail.com/questions/15041

devise.rb:3: uninitialized constant Devise (NameError)
https://github.com/plataformatec/devise/issues/1605

最後に

自分なりに調べ現象の改善に繋げることができましたが原因がわからないため
「とりあえず改善した方法」の一つだと思われます。
ご参考までに
ruby 2.3.1
Rails 5.0.6
nginx 1.12.1

続きを読む

BIG-IP ve Device Trustを確立しよう(失敗編)

はじめに

前回の方法でAWS上にBIG-IP veを2台デプロイしました。ここからHAの設定をしていきたいのですが、そのためにはBIG-IP同士がお互いを認識する必要があります。そのために必要な設定をしていきます。

バージョンは13.1.0.2です。

アドレスの確認

HAを構成したい個々のBIG-IPをDevice、Device同士がお互いを認識することを「Device Trustを確立する」と表現します。Trustを確立するためにはまずお互いのIPアドレスを知る必要があります。
Trustに使うIPアドレスは、アプライアンスでは実通信に利用しないManagement IPを、AWSでは適当なPrivate IPを指定することが推奨されています。

参考資料:https://support.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/bigip-system-device-service-clustering-administration-13-1-0/3.html

今回はAWSですので、デプロイ時に作ったNICのIPアドレス10.0.4.11および10.0.4.12を使いましょう。

NTP同期状態の確認

AWSではあまり意識する必要がありませんが、Deviceが正しい時刻を持っていないとTrustを確立できません。NTP同期状態は念のため確認しておきましょう。

[admin@ip-10-0-4-11:Active:Standalone] ~ # ntpq -np
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*127.127.1.0     .LOCL.          10 l   53   64  377    0.000    0.000   0.000
[admin@ip-10-0-4-11:Active:Standalone] ~ # 

コンフィグ同期用アドレスの設定……のはずだった

Trust確立の前提として、自分にコンフィグ同期用IPアドレスを設定しておく必要があります。このIPアドレスには適当なPrivateアドレスを使うことが推奨されています。

メニューから「Device Management」>「Devices」>自分のデバイスを選択します。続いて上のメニューで「ConfigSync」を選び、Local AddressのIPをドロップダウンから選択します。

image.png

「Update」を押して完了です。

image.png

あ、あれ……。駄目ですか。AWSならいけるかと思ったのですが、アプライアンスと同じManagement IPでは駄目なようです。

残念ながらここで時間切れになってしまったため、来週リベンジします。

続きを読む

Glacier Expressヤクの毛刈り(CloudFormation CLI tool) メモ (2018/02/03) (未整理)

  • Glacier Expressのヤクの毛刈りとしてCloudFormation 用のCLI toolの作成を行う
  • ただ、現状ではTool の作成どころか設計のための情報も足りず、検証段階と言える
  • 今日の検証はStackのイベントの追跡
    • いままでの検証で
    • describe_stack_eventsで追跡できそうなことはわかったため、更に検証を進めた
  • 結果としては順調に情報の取得ができた
  • イベントは時系列(降順)で取得できる
  • next_tokenで次の以降のイベントに限って取得できると考えたが、実際には”一定以上イベントが積み重なっている場合のPagerである”ことが判明したあまり使用することは想定されない
    • アウトプットが1MBを超えたときに使用する
    • カウント方法が分からないためなんとも言えないが1MBはレスポンスとしては非常に大きいため当面は対応する必要はないように感じる
  • ただ、イベントすべてを取得するため、今回適用分以外も表示されると考えた方が良い
  • client_request_tokenをeventの情報の要素に見つける、これなら今回適用分のみ判別することに使えるかもしれない
  • 再度試行してみるも、client_request_tokenの値が空白(null or 空文字列)であった
  • API Referenceを再度確認すると、どうもclient_request_token はcreate-stackを行う際に指定するようだ。
  • 指定してみたところその文字列が表示された。
  • さて、ではイベント取得の終了条件について考えてみることにする
  • create, update, delete、それぞれを確認してみたところ、どの変更であったとしても最初と最後のイベントは論理IDはstack_nameと同じものとなっている
  • そのため論理IDとステータスを見張れば終了がわかると考える
  • 試行してみたところ概ね成功
    • ただし、削除の場合は失敗
    • どうもDELETE_COMPLETEはstack_nameが論理IDの場合はない模様
    • 終了はスタックが存在するかどうかで判断する必要があるらしい
    • あと実際にはstack_nameだけじゃなくてリソースタイプがAWS::CloudFormation::Stackであるかも条件に加えた方がいいと思われる

続きを読む

CodeDeployでGitHubのソースをEC2にデプロイするまとめ

AWSが用意してくれているドキュメントがところどころ分かりにくかったのでざっくりとまとめ。コンソールの操作です。

用意するもの

  • EC2インスタンス
  • GitHubにレポジトリ

インスタンスにタグをつける

デプロイ先のEC2インスタンスをタグで管理します。デプロイ実行するときに、ここでつけるタグを指定することでデプロイ先を選択することになります。

EC2コンソールの左メニューから「インスタンス」>「アクション」>「インスタンスの設定」>「タグの追加/編集」
codedeploy1.png

適当にキーと値を設定します。インスタンスを管理しやすい形でWEBサーバーとかAPサーバーとかで設定するのもよし、新機能検証やパフォーマンステストなどの目的別に設定するのもよし。スクショは今回のインスタンスでLINEのAPIをテストしたかったのでPurpose=LineTestなるタグを設定してますが、まあなんでもOK。
codedeploy2.png

ロールを割り当て

IAMコンソールからからAmazonS3ReadOnlyAccessとAWSCodeDeployRoleを追加
codedeploy3.png

AmazonS3ReadOnlyAccess

CodeDeployエージェントをEC2インスタンスにインストールするときS3バケットからパッケージを持ってくるのでこのロールが必要。「AWSサービス」>「EC2」>「EC2」を選んで次のステップをポチ。
スクリーンショット 2018-02-03 10.png

次のページでAmazonS3ReadOnlyAccessを選んで適当にロール名を入れてロールを作成。

AWSCodeDeployRole

CodeDeployの実行ロールを作成。②のところでEC2を選んでもCodeDeployのロールが作成できたんですが、EC2ではデプロイできませんでした。②のところではCodeDeployを選択します。
スクリーンショット 2018-02-04 9.png

次の画面でははそのまま「次のステップ」、その次の画面でロール名をつけてロールを作成。

CodeDeployの設定

CodeDeployエージェントをEC2インスタンスにインストールし、CodeDeployコンソールからデプロイするアプリケーションを作成します。

EC2インスタンスにCodeDeployエージェントをインストール

# この辺はすでにインストールされてるかと思いますが
sudo yum update
sudo yum install ruby
sudo yum install wget

# ディレクトリはどこでもいいとは思いますがドキュメントに沿って
cd /home/ec2-user

# CodeDeployエージェント
wget https://aws-codedeploy-ap-northeast-1.s3.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto

# 実行
sudo service codedeploy-agent start

こちらのドキュメントにはwget https://bucket-name.s3.amazonaws.com/latest/installと書いており、下の方にbucket-nameを該当リージョンに変更するようにとありますので、東京の場合はaws-codedeploy-ap-northeast-1に書き換えます。

アプリケーションを作成

CodeDeployのコンソールから「アプリケーションの作成」をクリックし作成画面に移動。

FireShot Capture 1 - AWS CodeDeploy_ - https___ap-northeast-1.png
アプリケーション名、デプロイグループ名は適当に。
環境設定のタグのところで前述したタグを設定する。
詳細設定のサービスロールでAWSCodeDeployRoleのロールを選択し「アプリケーションの作成」を押して作成完了。

デプロイ実行

いよいよ最後になります。CodeDeployのメニューから「デプロイ」を選択、デプロイ画面で「デプロイの作成」から作成画面に移ります。

FireShot Capture 2 - AWS CodeDeploy_ - https___ap-northeast-1.png
アプリケーション名とデプロイグループはアプリケーションの作成で設定した名前を選択。
リポジトリタイプはGitHubを選択しGitHubアカウントとレポジトリ名、それからデプロイしたいコミットのハッシュを入力し「デプロイ」をクリック。
これでGitHubからソースのデプロイが完了。

まとめ

この程度ならEC2インスタンスからgit pullすればできちゃいますが、複数のインスタンスを管理するとなるとCodeDeployを使うメリットは大きいです。今回は基本的な設定をまとめてみましたが、デプロイの自動タスク化なんかもできて便利そうです。その辺も今後触ってみて、またまとめておきたいと思います。

続きを読む

{AWS(CloudFront+S3)+Node.js} 署名付きURLの使用したプライベートコンテンツの配信

はじめに

短期間のみ有効な署名付き URL を使用してプライベートコンテンツを配信するにあたり、Node.js環境下での情報が公式にはのっていなかったので、その対応方法をメモとして残します。

公式ガイド
https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html

環境準備

  1. プライベートコンテンツを格納するS3のバケットを作成する
  2. 上記バケットを非公開とする
  3. CloudFrontのディストリビューションを作成する
    • CloudFront経由に限り上記S3バケットにアクセス出来る用に設定する
  4. 署名付きURL生成のためにCloudFront のキーペアを作成する
    • この処理だけはAWSアカウント(ルートアカウント)が必要

〇参考URL
https://dev.classmethod.jp/cloud/aws/cf-s3-deliveries-use-signurl/
http://blog.mekachan.net/?p=105

コード実装

現在JavaScriptのaws-sdkライブラリではCloudfrontの署名付きURL生成がサポートされていないため、「aws-cloudfront-sign」ライブラリを活用して対応する

aws-cloudfront-sign

https://www.npmjs.com/package/aws-cloudfront-sign

サンプルコード

// 30分だけ有効な署名付きURLを生成するコード
var cf = require('aws-cloudfront-sign')
var options = {
  keypairId: 'XXXXXX',
  privateKeyPath: 'XXXX/XXXXXX-private-pk-XXXXX.pem',
  expireTime: (new Date().getTime() + 30 * 60 * 1000)
}
// CloudFrontの「Domain Name」を指定する
// https://${Domain Name}/${Origin path(S3バケット内のパス)}
var signedUrl = cf.getSignedUrl('https://dXXX.cloudfront.net/example.mp4', options);
console.log('Signed URL: ' + signedUrl);

options(オプション)の説明

項目 内容
expireTime 有効期限(任意設定:省略時は30秒)指定する際はミリ秒で指定する
keypairId 作成したクラウドフロントキーペアのアクセスキー ID
privateKeyString
または
privateKeyPath
作成したクラウドフロントキーペアの秘密鍵ファイルパス

参考 S3上で署名付きURLを利用するの場合

このケースではクラウドフロントを介しません。
S3上で生成した署名付きURL経由で非公開バケット中のリソースへアクセスする方式です。
特別なライブラリは不要でaws-sdkで対応可能です。

const AWS = require('aws-sdk')

AWS.config.update({
  accessKeyId: 'XXXXXX',
  secretAccessKey: 'XXXXXX'
  // ,
  // region: 'ap-northeast-1'
})
const s3 = new AWS.S3()

const url = s3.getSignedUrl('getObject', {
    Bucket: 'private-bucket',
    Key: 'example.mp4',
    Expires: 60 // 単位は秒
})

console.log(url)

参考(AWS-CLI)の場合

aws cloudfront sign
 --url http://dXXX.cloudfront.net/example.mp4
 --key-pair-id XXXXXX
 --private-key file://C:/XXX-private-pk-XXXXX.pem
 --date-less-than YYYY-mm-dd

続きを読む

5分で構築、AmazonLinux+PHP7+Nginx+WordPress

使用した環境

以下環境のバージョンなど
AMIは、amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2
Nginxは、version1.12.1
Wordpressは、version4.9.2日本語版

php70.x86_64                         7.0.25-1.26.amzn1             @amzn-updates
php70-cli.x86_64                     7.0.25-1.26.amzn1             @amzn-updates
php70-common.x86_64                  7.0.25-1.26.amzn1             @amzn-updates
php70-fpm.x86_64                     7.0.25-1.26.amzn1             @amzn-updates
php70-json.x86_64                    7.0.25-1.26.amzn1             @amzn-updates
php70-mbstring.x86_64                7.0.25-1.26.amzn1             @amzn-updates
php70-mysqlnd.x86_64                 7.0.25-1.26.amzn1             @amzn-updates
php70-pdo.x86_64                     7.0.25-1.26.amzn1             @amzn-updates
php70-process.x86_64                 7.0.25-1.26.amzn1             @amzn-updates
php70-xml.x86_64                     7.0.25-1.26.amzn1             @amzn-updates

インストール

yumのアップデート

sudo yum -y update

yumで必要なものを入れる

sudo yum -y install php70
sudo yum -y install php70-mbstring
sudo yum -y install php70-pdo
sudo yum -y install php70-fpm
sudo yum -y install php70-mysqlnd

設定

apacheのユーザから、nginxに置き換える

/etc/php-fpm.d/www.conf
user = nginx
group = nginx

Nginxの設定

nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    index   index.php index.html index.htm;

}

作成するサイトのドメインをsample.comとする

/etc/nginx/conf.d/sample.conf
server {
    listen       80;
    client_max_body_size 20M;
    server_name  sample.com;
    root         /var/www/html/sample;
    index        index.php index.html;

    location ~ .php$ {
        root           html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME /var/www/html/sample$fastcgi_script_name;
        #fastcgi_param  PATH_INFO $fastcgi_script_name;
        include        fastcgi_params;
        fastcgi_read_timeout 180;
    }


    include /etc/nginx/default.d/*.conf;

    location / {
    }

    # redirect server error pages to the static page /40x.html
    #
    error_page 404 /404.html;
        location = /40x.html {
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }

}

以下のコマンドを打って、/var/www/html以下に、wordpressを配置

cd /var/www/html
sudo wget https://ja.wordpress.org/wordpress-4.9.2-ja.zip
sudo unzip wordpress-4.9.2-ja.zip
sudo mv wordpress sample
sudo chown -R nginx:nginx sample

起動時にNginxとPHPが立ち上がるようにする

sudo chkconfig nginx on
sudo chkconfig php-fpm-7.0 on

起動

sudo service nginx start
sudo service php-fpm-7.0 start

アクセスしてWordpressをインストール

サーバのIPアドレスにアクセス

続きを読む

Auroraのメンテナンスイベントについて

Auroraのメンテナンスイベントについて知らなければ!という衝動に突き動かされたわけではなく
意図しないアップグレードで少しやられてしまったので必要に迫られた故、メモ書きする。

メンテナンスの種類

RDSのマネージメントコンソールのクラスターのメンテナンス列で確認できる模様。
確認時に気づいたけれど大幅にUIが変更されたなー。Lambdaは頻繁に変わっているイメージだけど。。。

image.png

利用可能(Available)と必須(Required)がある。

Availableなイベントは延期が可能で、Requiredなイベントはメンテナンスウィウンドウで自動実行される。

Requiredなイベントについて、事前に知る必要がある。

describe-pending-maintenance-actions

Auroraのメンテナンス通知はメールで届いたりしないので、自分でAPIを叩いてメンテナンス情報を取得する必要がある。

describe-pending-maintenance-actions

上記APIを叩くと、以下のようなレスポンスが取得できる。

{
    "PendingMaintenanceActions": [
        {
            "PendingMaintenanceActionDetails": [
                {
                    "Action": "system-update", 
                    "Description": "Aurora 1.16 release"
                }
            ], 
            "ResourceIdentifier": "arn:aws:rds:ap-northeast-1:XXXXXXXX:cluster:XXXXXXXXXXXXXX"
        }
    ]
}

Requiredや、Available等表示されない。
どのように知るか?

API Output

Action

Auroraクラスタのメンテナンスの場合、基本的には”os-upgrade”あるいは”system-update”が返される。

  • os-upgrade:
    AuroraクラスタのOS更新
  • system-update:
    AuroraクラスタのDBエンジン更新
  • db-upgrade:
    主にRDS DBインスタンスにおけるDBエンジンの更新

AutoAppliedAfterDate, ForcedApplyDate

  • AutoAppliedAfterDate:
    更新が適用されるメンテナンスウィンドウの指定。この項目で指定された日付以降の最初のメンテナンスウィンドウでアクションを実行される。
  • ForcedApplyDate:
    指定された場合、メンテナンスウィンドウ外でも指定された日時でメンテナンスが実行される。

「メンテナンスウィンドウ外でも」 

これは絶対チェックやな。

OptInStatus

AutoAppliedAfterDate, ForcedApplyDateが指定されない場合や、指定された日時よりも早くメンテナンスを実行したい場合はapply-pending-maintenance-actionを–opt-in-typeオプションを指定して実行することができる。
メンテナンスに対する選択(opt-in)状態を示す。
opt-in とは「事前許可を求めるやりかた」というようなことらしい。
この項目は明示的にapply-pending-maintenance-actionを実行した場合にのみ追加される。

apply-pending-maintenance-action
ステータスは以下。

  • next-maintenance:
    次のメンテナンスウィンドウ
  • immediate: 即座
  • undo-opt-in: next-maintenanceの指定がキャンセルされた

CurrentApplyDate

CurrentApplyDateは、AutoAppliedAfterDate, ForcedApplyDate, OptInStatusのすべてを考慮したうえで、「現時点で実際にメンテナンスの自動適用が予定されている日時」

結論

AutoAppliedAfterDate 、ForcedApplyDateが設定されているものがRequiredなイベントなので、事前にちゃんと知るようにする。

参考サイト

続きを読む

AWS と Azure と自宅の PC で NVIDIA GPU Cloud (NGC) のコンテナを動かしてみた

こんにちは。エヌビディアの佐々木です。

NVIDIA GPU Cloud (NGC) というサービスをご存知でしょうか。端的に書けば 「NVIDIA が公開している Docker コンテナリポジトリ」 です。CaffeChainerTensorFlow 等の各種ディープラーニング フレームワークや、GAMESSGromacsLAMMPS といった HPC アプリケーションのコンテナが揃っており、もちろん GPU 実行に最適化されています。このコンテナを使えば、計算環境構築の手間をかなり削減することができます。

「Cloud」とあるので、クラウドで GPU を使うためのサービスと思われることがあるのですが、NGC は「コンテナを提供するクラウドサービス」であって、そのコンテナはクラウドに限らず、オンプレミスのコンピューターでも利用できます。

今のところ、コンテナの利用環境としてエヌビディアが正式にサポートするのは AWS の P3 インスタンス と、NVIDIA TITAN V を搭載するコンピューターのみですが、それ以外の環境でも Pascal 世代以降の GPU であれば動作するはずです。

というわけで、次のような3つの環境で試してみました。

  • AWS の P3 インスタンス (Tesla V100 搭載)
  • Microsoft Azure の ND インスタンス (Tesla P40 搭載)
  • 私の自宅 PC (GeForce GTX 1050 Ti 搭載)

※ 私の PC だけちょっと弱めですが、ロープロファイルのカードしか付かないんです…

NGC のアカウントを作る

まず、 NGC のサインアップページでアカウントを作成します。無料です。
2018-01-28_205005.png

NGC の API キーを生成する

アカウントができたらログインして、画面右上の “Get API Key” をクリックしてください。
2018-01-28_205552.png

次に、”Generate API Key” をクリックして API キーを生成します。これは後ほど NGC からコンテナを pull する際に使用します。
2018-01-28_210946.png

生成されたキーは必ずどこかに控えておいてください。”This is the only time your API Key will be displayed.” とあるとおり、二度と表示されません。
2018-01-28_211158.png

さて、アカウントと API Key ができたら、あとは実行環境の準備です。要件は次の通り。

  • Pascal 世代以降の GPU (と、そのドライバ)
  • NVIDIA Docker

では、AWS, Azure, 自宅 PC のそれぞれで試していきます。

実行環境を作る (AWS で)

AWS は NGC の正式サポート環境なので、準備も簡単です。NVIDIA Volta Deep Learning AMI という AMI をエヌビディアが提供していますので、これを使って P3 インスタンスを作れば OK です。ドライバも NVIDIA Docker もインストール済み。別途セットアップする必要はありません。(なお、G2, G3, P2 は、GPU が Kepler や Maxwell 世代なので NGC 非対応)

早速作ってみます。
2018-01-28_212822.png
東京は高いのでオレゴンで、インスタンスタイプは p3.2xlarge (Tesla V100 を1基搭載)を選びました。

インスタンスが動き始めたらログインしてみます。シェルのプロンプトが出る前にこんなことを聞いてきます。

Welcome to the NVIDIA Volta Deep Learning AMI. This environment is provided to
enable you to easily run the Deep Learning containers from the NGC Registry.
All of the documentation for how to use NGC and this AMI are found at
  http://docs.nvidia.com/deeplearning/ngc
Initializing nvidia-docker volume...

Please enter your NGC APIkey to login to the NGC Registry:

ここで、先ほど生成した API キーを入力(ペースト)します。

Logging into the NGC Registry at nvcr.io...Login Succeeded

こうなれば NGC 利用準備完了です。コンテナを動かす前に、 GPU を確認してみます。

$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.81                 Driver Version: 384.81                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-SXM2...  On   | 00000000:00:1E.0 Off |                    0 |
| N/A   32C    P0    19W / 300W |     10MiB / 16152MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

本当に Tesla V100 SXM2 だ!テンション上がりますねー

では、コンテナを動かしてみます。NGC サイトの AWS のチュートリアルにある、PyTorch での MNIST 手書き文字認識が動作確認には手軽です。

$ nvidia-docker run --rm -ti nvcr.io/nvidia/pytorch:17.10
17.10: Pulling from nvidia/pytorch
f5c64a3438f6: Pull complete
51899d335aae: Pull complete
<略>

初回なのでいろいろとダウンロードする必要があり、少し時間がかかりますが、うまくコンテナが動き出しました。

=============
== PyTorch ==
=============

NVIDIA Release 17.10 (build 192702)

Container image Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.

Copyright (c) 2016-     Facebook, Inc            (Adam Paszke)
Copyright (c) 2014-     Facebook, Inc            (Soumith Chintala)
Copyright (c) 2011-2014 Idiap Research Institute (Ronan Collobert)
Copyright (c) 2012-2014 Deepmind Technologies    (Koray Kavukcuoglu)
Copyright (c) 2011-2012 NEC Laboratories America (Koray Kavukcuoglu)
Copyright (c) 2011-2013 NYU                      (Clement Farabet)
Copyright (c) 2006-2010 NEC Laboratories America (Ronan Collobert, Leon Bottou, Iain Melvin, Jason Weston)
Copyright (c) 2006      Idiap Research Institute (Samy Bengio)
Copyright (c) 2001-2004 Idiap Research Institute (Ronan Collobert, Samy Bengio, Johnny Mariethoz)
All rights reserved.

Various files include modifications (c) NVIDIA CORPORATION.  All rights reserved.
NVIDIA modifications are covered by the license terms that apply to the underlying project or file.

NOTE: The SHMEM allocation limit is set to the default of 64MB.  This may be
   insufficient for PyTorch.  NVIDIA recommends the use of the following flags:
   nvidia-docker run --ipc=host ...

root@b3d044efeae1:/workspace#

コンテナの中で、サンプルスクリプトを動かしてみます。

root@b3d044efeae1:/workspace# cd /opt/pytorch/examples/mnist && python main.py
Train Epoch: 1 [0/60000 (0%)]   Loss: 2.390087
<中略>
Train Epoch: 10 [58880/60000 (98%)]     Loss: 0.272635
Train Epoch: 10 [59520/60000 (99%)]     Loss: 0.082086

Test set: Average loss: 0.0553, Accuracy: 9804/10000 (98%)

root@b3d044efeae1:/opt/pytorch/examples/mnist#

1分半ほどで10エポック完了しました。環境構築の手間いらずで、実に簡単ですね。

実行環境を作る (Azure で)

Microsoft Azure の仮想マシンで、Pascal 以降の GPU を搭載しているのは次の3種類です。

  • NCv2 (Tesla P100)
  • ND (Tesla P40)
  • NCv3 (Tesla V100: ただし、2018年1月時点ではプレビュー提供中)

今回は ND シリーズの一番小さいやつ(ND6s)をData Science Virtual Machine for Linux (Ubuntu)で作りました。これは AWS の NVIDIA Volta Deep Learning AMI のように、GPU ドライバや NVIDIA Docker があらかじめインストールされた仮想マシンイメージです。楽ちんです。

2018-01-28_221052.png

ログインしたら GPU を確認。確かに、Tesla P40 が搭載されていますね。こいつの GPU メモリサイズは 24GB と、P100 や V100 よりも大きいのです。

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 384.111                Driver Version: 384.111                   |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla P40           Off  | 00008B49:00:00.0 Off |                    0 |
| N/A   25C    P8    11W / 250W |     10MiB / 22912MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

では、動作確認を。Azure の場合、 AWS の NVIDIA Volta Deep Learning AMI のようにログイン時に NGC のキーを入力していませんので、まずは NGC へのログインが必要です。

下記コマンドの ‘$oauthtoken’ の部分は「環境に応じて適切に置き換えてください」という意味ではなく、「そのまま」入力してください。シェルに変数展開されないようにシングルクォートで括る必要があります。

$ docker login -u '$oauthtoken' --password-stdin nvcr.io <<< 'API キー'
Login Succeeded

あとは、AWS の場合と同じです。こちらでも PyTorch の MNIST を試してみました。同じことをやっても面白くありませんが、「同じものがどこでも動く」というのがコンテナの便利なところなので。

$ nvidia-docker run --rm -ti nvcr.io/nvidia/pytorch:17.10

=============
== PyTorch ==
=============

NVIDIA Release 17.10 (build 192702)

Container image Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.

<略>

root@84835550d223:/opt/pytorch/examples/mnist# cd /opt/pytorch/examples/mnist && time python main.py

<略>

Train Epoch: 1 [0/60000 (0%)]   Loss: 2.390087
Train Epoch: 1 [640/60000 (1%)] Loss: 2.350225

<略>

Train Epoch: 10 [58880/60000 (98%)]     Loss: 0.307370
Train Epoch: 10 [59520/60000 (99%)]     Loss: 0.081178

Test set: Average loss: 0.0546, Accuracy: 9813/10000 (98%)

root@84835550d223:/opt/pytorch/examples/mnist#

(当たり前ですが) 無事に動きました。簡単ですね。

実行環境を作る (自宅の PC 等で)

さて、2種類のクラウドを試しましたが、次に自宅の PC でも試してみました。環境は次の通りです。

  • OS: Ubuntu 16.04.3 LTS
  • GPU: GeForce GTX 1050 Ti (Pascal 世代)

Deep Learning AMI のような便利なものはないので、GPUのドライバと NVIDIA Docker は自分でインストールする必要があります。

GPU ドライバのインストール

NVIDIA のドライバダウンロードページから、自分の GPU に対応したドライバのインストーラーをダウンロードしてインストールします。なお、NVIDIA Docker さえ動けば良いので、CUDA Toolkit のインストールは不要です。

NVIDIA Docker のインストール

NVIDIA Docker のインストールには前提条件として Docker が必要です。私はこちらのページを参考にして、Docker CE をインストールしました。実行したコマンドは次の通りです。

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce

次に、 NVIDIA Docker をインストールします。こちらのページに手順がまとまっています。実行したコマンドは次の通りです。

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt update

sudo apt install nvidia-docker2
sudo pkill -SIGHUP dockerd

あと、sudo なしで Docker を実行できるように、自分を docker グループに追加しました。

sudo gpasswd -a 自分 docker

コンテナの動作確認

「またか」という感じですが、PyTorch で MNIST してみます。

$ docker login -u '$oauthtoken' --password-stdin nvcr.io <<< 'API キー'
Login Succeeded
$ nvidia-docker run --rm -ti nvcr.io/nvidia/pytorch:17.10

=============
== PyTorch ==
=============

NVIDIA Release 17.10 (build 192702)

Container image Copyright (c) 2017, NVIDIA CORPORATION.  All rights reserved.

<略>

root@2dc683eff1b2:/opt/pytorch/examples/mnist# cd /opt/pytorch/examples/mnist && python main.py

<略>

Train Epoch: 1 [0/60000 (0%)]   Loss: 2.390087
Train Epoch: 1 [640/60000 (1%)] Loss: 2.350225

<略>

Train Epoch: 10 [58880/60000 (98%)]     Loss: 0.288593
Train Epoch: 10 [59520/60000 (99%)]     Loss: 0.084271

Test set: Average loss: 0.0529, Accuracy: 9821/10000 (98%)

root@2dc683eff1b2:/opt/pytorch/examples/mnist#

無事に動きました!

まとめ

NVIDIA GPU Cloud のコンテナを、2種のクラウドと自宅の PC で動かしてみました。
AWS と Azure は GPU ドライバと NVIDIA Docker インストール済みの仮想マシンイメージが使えるのでとても簡単。それ以外の環境でも、NVIDIA Docker の環境さえ作ってしまえば、あとは毎月更新される最新のコンテナを活用することで、環境構築とメンテナンスをかなり効率化できます。是非お試しを!

関連情報

続きを読む