【AWS】AWSでGPUコンピューティングする際の環境セットアップ
Usage
アカウント登録
まずはAWSのアカウント登録を行います。
下記ページを参考に、AWSのアカウントを作成してください。
aws.amazon.com
インスタンスの作成
GPUインスタンスの作成を行います。 AWSトップページの左上「サービス」プルダウンをクリックし、コンピューティング->EC2 を選択。
するとEC2ダッシュボード画面に遷移するので、「インスタンスを作成」ボタンをクリック。
インスタンス一覧に「Deep Learning AMI (Ubuntu) Version 12.0」があるので「選択」をクリック。
今回はGPUを使用したいので、「GPUインスタンス」である「p2.xlarge」を選択し、「確認と作成」ボタンをクリックします。
※有料です。料金は下記記載
2018/07/28時点では 0.900 USD/h( 米国東部 (バージニア北部) および米国西部 (オレゴン) の価格)
有料との脅しが入りますが、課金の心意気をもって作成をクリック。
インスタンス作成にあたり、キーペアを作成します。
キー名を入力し「キーペアのダウンロード」ボタンを押します。
今後インスタンスへのSSHログイン等に使用するので、厳重に保管してください。再取得はできないので、紛失時は新たな鍵を生成する必要があります。
キーペアが作成できたら、「インスタンスの作成」をクリック。
するとインスタンスの作成が開始されます。
初回の作成ではインスタンスの作成に失敗するので、http://aws.amazon.com/contact-us/ec2-request/にアクセスし、インスタンス上限を増やしてもらいましょう。「申請理由の説明」欄には、DeepLearningを検証したい旨を書きます。 申請を送信してからおよそ30分くらいで申請が受理されるはずなので、再度インスタンスの作成を行ってみてください。
インスタンス作成ステータス画面が表示され、「インスタンスを表示」ボタンを押した先のページでインスタンスが表示されていればインスタンス作成成功です。
SSHログイン
次は立ち上げたインスタンス内の環境にログインします。
$ ssh -i [key_pair_path] [user_name]@[パブリック DNS or IPv4 パブリック IP] The authenticity of host '[パブリックDNS(IPv4 パブリック IP)]' can't be established. ECDSA key fingerprint is SHA256:[SHA256ハッシュ値] Are you sure you want to continue connecting (yes/no)? yes
[key_pair_path]には先程ダウンロードした鍵ファイルへのパスを、
[user_name]には今回ログインするユーザ(ubuntu)を、
[パブリック DNS or IPv4 パブリック IP]にはインスタンスのパブリックDNS、またはIPv4アドレスを入力してください。
ちなみにDNSドメインとIPv4アドレスはインスタンス一覧のページに載っています。
ログインに成功すると↓のような出力がなされます。
============================================================================= __| __|_ ) _| ( / Deep Learning AMI (Ubuntu) Version 12.0 ___|\___|___| ============================================================================= Welcome to Ubuntu 16.04.4 LTS (GNU/Linux 4.4.0-1062-aws x86_64v)...
tensorflow環境をセットアップ
今回使用するインスタンスにはすでに様々な仮想環境が用意されています。
Please use one of the following commands to start the required environment with the framework of your choice: for MXNet(+Keras2) with Python3 (CUDA 9.0 and Intel MKL-DNN) _______________________________ source activate mxnet_p36 for MXNet(+Keras2) with Python2 (CUDA 9.0 and Intel MKL-DNN) _______________________________ source activate mxnet_p27 for TensorFlow(+Keras2) with Python3 (CUDA 9.0 and Intel MKL-DNN) _____________________ source activate tensorflow_p36 for TensorFlow(+Keras2) with Python2 (CUDA 9.0 and Intel MKL-DNN) _____________________ source activate tensorflow_p27 for Theano(+Keras2) with Python3 (CUDA 9.0) _______________________________________________ source activate theano_p36 for Theano(+Keras2) with Python2 (CUDA 9.0) _______________________________________________ source activate theano_p27 for PyTorch with Python3 (CUDA 9.0 and Intel MKL) ________________________________________ source activate pytorch_p36 for PyTorch with Python2 (CUDA 9.0 and Intel MKL) ________________________________________ source activate pytorch_p27 for CNTK(+Keras2) with Python3 (CUDA 9.0 and Intel MKL-DNN) _________________________________ source activate cntk_p36 for CNTK(+Keras2) with Python2 (CUDA 9.0 and Intel MKL-DNN) _________________________________ source activate cntk_p27 for Caffe2 with Python2 (CUDA 9.0) ________________________________________________________ source activate caffe2_p27 for Caffe with Python2 (CUDA 8.0) __________________________________________________________ source activate caffe_p27 for Caffe with Python3 (CUDA 8.0) __________________________________________________________ source activate caffe_p35 for Chainer with Python2 (CUDA 9.0 and Intel iDeep) ______________________________________ source activate chainer_p27 for Chainer with Python3 (CUDA 9.0 and Intel iDeep) ______________________________________ source activate chainer_p36 for base Python2 (CUDA 9.0) __________________________________________________________________ source activate python2 for base Python3 (CUDA 9.0) __________________________________________________________________ source activate python3
Tensorflow(GPU)用仮想環境もあるので、ぜひ使わせてもらいましょう。
下記コマンドを打つと仮想環境に入ります。
$ source activate tensorflow_p36
pythonを起動してtensorflow上でGPUが使用できるか確認してみましょう。
$ python Python 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 17:14:51) [GCC 7.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tensorflow /home/ubuntu/anaconda3/envs/tensorflow_p36/lib/python3.6/site-packages/h5py/__init__.py:36: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`. from ._conv import register_converters as _register_converters >>> from tensorflow.python.client import device_lib >>> device_lib.list_local_devices() [name: "/device:CPU:0" device_type: "CPU" memory_limit: 268435456 locality { } incarnation: 7836901512070260373 , name: "/device:GPU:0" device_type: "GPU" memory_limit: 11285538407 locality { bus_id: 1 links { } } incarnation: 3647875569071979833 physical_device_desc: "device: 0, name: Tesla K80, pci bus id: 0000:00:1e.0, compute capability: 3.7" ] >>>
ちゃんとTensorflowにGPUが認識されていることが確認できました!
参考
【Java】Jacksonがパースする文字列のフィールド名にDouble Quoteがついていない状態でもパース可能にする
Jackson
Double-Quote問題
JacksonのObjectMapperでJSON文字列パースしてJavaオブジェクトに変換するとき、フィールド名にダブルクォートがないと怒られてしまいます。
String json = "{user_id: 1, age: 20, item_id: 2, item_name: "hoge"}"; ObjectMapper mapper = new ObjectMapper(); TypeReference<Map<String, String>> type = new TypeReference<Map<String, String>>() {} List<Map<String, String>> list = mapper.readValue(json, type);
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('u' (code 105)): was expecting double-quote to start field name at [Source: {user_id: 1, age: 20, item_id: 2, item_name: "hoge"}; line: 1, column: 4]
そのため、クォートなしのJSONをパースするためには
mapper.configure()
メソッドでFeature.ALLOW_UNQUOTED_FIELD_NAMES
フラグを有効化します。
mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
参考
【Java】Jacksonで配列形式のJSON文字列をJavaオブジェクトに変換する
Jackson
配列形式のJSON
JSONのrootがオブジェクト形式ではなく配列形式の場合、ObjectMapperによるパースは以前の記事同様TypeReferenceを用いて行うことができます。
rootが配列形式のJSON
[ { "user_id": 1, "age": 20 }, { "user_id": 2, "age": 22 }, ]
Usage
String json = "[{ "user_id": 1, "age": 20}, {"user_id": 2, "age": 22}]"; ObjectMapper mapper = new ObjectMapper(); TypeReference<List<Map<String, String>>> type = new TypeReference<List<Map<String, String>>>() {} List<Map<String, String>> list = mapper.readValue(json, type);
参考
【Shell】expectでシェルの対話的処理を自動化する
expect
expect
は、シェル上での対話的なコマンドライン処理を自動化するためのツールです。
シェルスクリプトでルーチンを自動化したいときに対話的な処理が入ってしまって、どうしても手入力が発生してしまう・・・そんなときに重宝します。
Usage
実行環境はMac OS X High Sierra 10.13.4です。
brew
でGUIツールキットtcl-tk
と、expect
をインストールします。
$ brew install tcl-tk --without-tcllib $ brew install expect --with-brewed-tk
tcl-tk
のインストールは少し時間がかかります。
Source
以下にscp
コマンドでのパスワード入力を自動化するスクリプト例を示します。
#!/bin/bash TARGET="{target_path}" PASSWORD="P@ssw0rd" echo "copy .txt file in '${TARGET}' to remote server ..." expect -c " spawn scp ${TARGET}/*.txt usr01@10.132.235.71:~ expect \"usr01@10.132.235.71's password:\" send \"${PASSWORD}\n\" interact "
expect -c
自動化対象となるコマンドリストを引数にとり、引数のコマンドを実行します。
spawn
expectの引数に渡されたコマンドリスト内で使用します。
対話処理を行うコマンドを引数にして渡すことで、後述するsend
コマンドによる自動嘔吐が可能な状態になります。
send
spawn
コマンドによって実行されたコマンドの対話処理に対して、どのような応答を行うかを定義します。
interact
自動応答処理を終了します。
参考
【NW】PPPoE
PPPoEとは
PPPoEとは、イーサネットを利用してPPPの機能を提供するプロトコルです。
イーサネットはデータリンクとして広く普及した規格です。多くのネットワーク機器やNICがこのイーサネットに準拠しています。
しかし、イーサネットがサポートする機能だけでは限界があります。例えば、イーサネットにはコネクションの確立・切断機能はありません。また二点間の認証機能も持ち合わせておりません。
そのような機能に対するニーズをイーサネットで満たすため、インタフェースとしてはイーサネットでありながら、PPPの機能を提供する新しい形のプロトコルが生まれました。それがPPPoEです。
利用用途として、一般家庭とプロバイダ間のデータリンク接続が挙げられます。プロバイダとしてはデータ通信の利用者の識別や利用時間等の計測を行いたいので、コネクションの確立や認証を必要とします。PPPoEであれば、これらをイーサネットの形で行うことができるので、多くのプロバイダが顧客とのデータリンクの接続にPPPoEを採用しています。
※PPPについてはこちらの記事参照 rennnosukesann.hatenablog.com
PPPoEのステージ
PPPにおける通信では、すでに送信先の相手との通信経路が固定された状態で通信が行われます。一方で、イーサネットではブロードキャスト通信などにより多数の送信先に対して無指向通信を行い、データの送信先ホストだけが返信を行うという形でデータの送受信を行います。そのため、イーサネット上でPPPとして振る舞うPPPoEは、このイーサネットの無指向通信の上でPPPの通信を再現する必要があります。
PPPの通信を再現するため、PPPoEでは通信処理を以下の二段階に分けて定義しています。
- ディスカバリステージ
- PPPセッションステージ
ディスカバリステージ
ディスカバリステージでは、送信先相手へのMACアドレスの伝達を行います。また、後述するPPPセッションステージで用いるセッションIDの特定・セッションの確立も行います。
PPPセッションステージ
ディスカバリステージによってセッションが確立されて以降は、PPPに則った通信が開始されます。
PPPoEのフレームフォーマット
イーサネットヘッダ
PPPoEヘッダ
PPPoEで必要な情報を含むヘッダ。
PPPプロトコル
PPP上で用いられるプロトコル。
FCS
フレームの破損を検出するためのシーケンス番号。
参考
(マスタリングTCP/IP 入門編 第5版)[https://www.amazon.co.jp/%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0TCP-IP-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%AC%AC5%E7%89%88-%E7%AB%B9%E4%B8%8B/dp/4274068765)
【NW】PPP
まえがき
この記事は、4年前に投稿したPPPに関する記事のリライトになります。
結構前に書いたもので内容うろ覚えだったので、復習も兼ねて再度調査してまとめ直してみました。
上記記事にない情報も追加したので、双方参照していただけると嬉しいです。
PPPとは
PPP(Point to Point Protocol)とはデータリンク層のプロトコルであり、一対一でコンピュータを接続するためのデータリンク仕様を定義しています。
前回の記事で紹介したイーサネットは、物理層とデータリンク層にまたがる規格でした。PPPは物理層に該当する仕様はなく、純粋なOSI第二層データリンクプロトコルになります。
そのため、PPPをデータリンク層プロトコルとして採用した場合、物理層に該当する規格・プロトコルを別途選定する必要があります。その点で、PPPはイーサネットと比較して物理レベルでは柔軟と言えます。
LCP/NCP
PPPはLCP(Link Controll Protocol)とNCP(Network Controll Protocol)の2つのプロトコルに分類することができます。LCPは上位層のプロトコルに依存しないプロトコルであり、逆にNCPは上位層に依存するプロトコルになります。
PPPではデータ通信開始時、PPPレベルでのコネクションの確立を行います。コネクション確立時には認証、圧縮、暗号化の設定も行います。LCPはそれらの処理について責務を持ち、コネクションの確立・切断、プロトコルの設定、通信品質監視設定等を行います。
NCPは上位層のプロトコルに依存するため、ネットワーク層プロトコルによって定義が変わります。
PPPの認証方式
PPPでは、エンドポイント間のコネクション確立時に認証を行います。このとき、LCPの中で複数の認証方式から一つを採用します。PPPで利用される認証方式には、PAP(Password Authentication Protocol)とCHAP(Challenge Handshake Authentication Protocol)の二種類があります。
PAP(Password Authentication Protocol)
PAPはその名の通り、パスワードによる認証を行います。パスワードとIDを相手に送信することで認証を行うのですが、これらのデータは平文で送信されてしまいます。
CHAP(Challenge Handshake Authentication Protocol)
こちらはチャレンジレスポンス方式を利用した認証方式を採用します。
チャレンジと呼ばれる意味のないビット列から特定の関数を用いて新たな値Aを計算し、それを相手に送ります。相手は送信元と同じ関数を持っているので、もとのビット列から同じ計算を行い値Bを生成します。相手はAとBを比較し、一致していることが確認できたら認証を完了します。
チャレンジレスポンスでは毎回渡すビット列を変更しているので、PPPと比較して一回の認証に対する盗聴に強いという特徴を持ちます。ただし、共有する関数を第三者に知られていないということが前提になります。
PPPデータフレームフォーマット
PPPのデータフレームフォーマットは以下の様になっています。
フラグ
フレームの先頭・末尾に付加される、通信の開始・終了を表すビット列です。
アドレス
送信先アドレスを指します。基本的に、この領域には11111111(ブロードキャスト)が挿入されます。
制御
データリンクプロトコルHDLCで規定される「非番号制フレーム」を表す制御ビット00000011が挿入されます(PPPはHDLCを参考に作られている)。
データ
上位層プロトコルによるデータ・コンテンツを含む領域。
タイプ
データ部の上位プロトコルタイプが挿入されます。
FCS
フレームの破損検出を行うためのビット列です。
参考
(マスタリングTCP/IP 入門編 第5版)[https://www.amazon.co.jp/%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0TCP-IP-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%AC%AC5%E7%89%88-%E7%AB%B9%E4%B8%8B/dp/4274068765)
【NW】無線LAN規格IEEE802.11
IEEE802.11
IEEE802.11は、IEEEが定義した無線LANプロトコルにおける物理層・データリンク層(の一部)の規格の総称です(元祖IEEE802.11の規格名でもあります)。
IEEE802.11には規格内容によって無印/a/b/g/nなどの種類があり、それぞれ最大速度や周波などの特徴が異なります。基本的に後者ほど新しい規格となり、通信速度も向上しています。
近年無線通信の通信向上とともに、オフィスや一般家庭、店舗などでも利用されるようになり、ネットワーク技術の中でも特に注目を浴びている規格です。
CSMA/CA
IEEE802.11では、通信品質を向上するために CSMA/CA(Carrier Sense Multiple Access with Collision Avoidance)と呼ばれるアクセス制御方式を用いています。CSMA/CDは、無線LAN上で他の通信が行われていた場合に、自身の通信と衝突しないよう通信タイミングを調節するアクセス制御を行います。
通信開始前に、無線上の受信を試みます。他のホストが通信しているかどうかを確認します。
他のホストが通信をしていなければ、自身の通信を開始します。
他のホストが通信をしているのであれば、ランダムな時間待機し、待機後再び1.を試みます(永遠に待ち続けるのを防ぐため、待ち時間は徐々に短くなっていきます)。
似たようなアクセス制御にCSMA/CDという方式がありますが、こちらはすぐさま通信を開始し、衝突を検知したときに初めて通信を中断し、ランダム時間待機後に再送を行います。CSMA/CDは有線LAN規格など衝突検出可能な環境下で採用されますが、無線LANでは衝突検出が難しいため、衝突検出を必要としないCSMA/CA方式を採用しています。
IEE802.11(無印)
元祖IEEE802.11規格です。
物理層において電波・赤外線を用い、1~2Mbpsの通信速度を実現します。現在では後述するIEE802.11b/g/a/nの通信速度が優れているためあまり使われません。
IEE802.11a
元祖IEEE802.11と比較すると、飛躍的な通信速度(54Mbps)の進歩を遂げた企画です。
周波数帯が5GHzとなっているため、他の家電等による電波干渉の影響が少ないものの、障害物に弱いという特徴があります。
IEEE802.11b
こちらも元祖IEEE802.11と比較すると通信速度は向上していますが、11MbpsとIEEE802.11aには劣ります。 周波数帯が2.4GHzのため、5GHzと比較して他の無線機器・電磁波の影響を受けやすいですが、障害物に強いという特徴があります。
IEEE802.11g
IEEE802.11bの上位互換です。周波数帯は2.4GHzとかわらぬまま、通信速度が54MbpsとIEEE802.11aと同等になっています。多くの無線LANルーターではIEEE802.11aとgのどちらかが選択できるようになっています。
IEEE802.11n
IEEE802.11gとaの技術をベースにして、アンテナの本数を増やし各通信処理を同期させる技術を採用しています。これをMIMO(Multi-Input Multi-Output)といいます。周波数帯は5GHz帯、2.4GHz帯のどちらかを選べます。他の周波数帯を利用するシステムがない場合には、40GHz帯を利用しての最大150Mbps通信を利用できます。
IEEE802.11ng
IEEE802.11nをさらにグレードアップさせた規格です。帯域幅を最大160GHzにまで拡大できるようになり、理想値で最大速度6.93Gbpsを叩き出します。ただし現在利用できる周波数帯が5GHzのみとなります。