ぱたへね

はてなダイアリーはrustの色分けができないのでこっちに来た

Rustでグラフ

ほとんどライブラリの使い方レベルだけど、なんとか動いた。

extern crate petgraph;

use std::fs;
use std::io::Write;

// https://docs.rs/petgraph/0.4.13/petgraph/
use petgraph::Graph;
use petgraph::algo;
use petgraph::dot::Dot;

fn main() {

    let mut graph = Graph::new_undirected();
    let na = graph.add_node("a");
    let nb = graph.add_node("b");
    let nc = graph.add_node("c");
    let nd = graph.add_node("d");
    let ne = graph.add_node("e");
    let nf = graph.add_node("f");

    graph.add_edge(na, nb, 20);
    graph.add_edge(nb, nc, 20);
    graph.add_edge(nc, nd, 10);
    graph.add_edge(na, ne, 10);
    graph.add_edge(nb, ne, 10);
    graph.add_edge(nb, nf, 30);
    graph.add_edge(nd, nf, 10);
    graph.add_edge(ne, nf, 20);

    let mut f = fs::File::create("graph.dot").unwrap();
    let dot_str = format!("{:?}", Dot::with_config(&graph, &[]));
    f.write(dot_str.as_bytes()).unwrap();

    let path = algo::dijkstra(
        &graph,
        na,
         Some(nd),
        |e| *e.weight()
    );
    println!("result: {:?}", path);
}

実行結果

f:id:natsutan:20181019131430p:plain

なんとなく動いているっぽい

result: {NodeIndex(1): 20, NodeIndex(5): 30, NodeIndex(0): 0, NodeIndex(3): 40, NodeIndex(4): 10, NodeIndex(2): 40}

久しぶりにKerasを動かしたときのメモ

import keras しただけでこういうエラーがでる。

ImportError: libcublas.so.9.0: cannot open shared object file: No such file or directory

libcublasが見つからないだけなので、.bashrcにLD_LIBRARY_PATHを追加する。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-9.0/lib64/

ターミナルから動いてPyCharmで同じエラーが出る場合は、PyCharmのrun configurations(working directoryとかを設定する画面)から、Environmet variables に上のLD_LIBRARY_PATHを追加する。

TVMで使われている最適化の探索手法

TVMとは

ペーパーはこちらからダウンロードできます。 https://arxiv.org/abs/1802.04799

TVMは、ASICやAPGAの様な組込様CPU等、様々なバックエンドでDeep Learningを動かすことを目的としたコンパイラです。 グラフレベルや演算子レベルの様々な最適化を行います。

興味本位でペーパーを読んでみたら、僕の知らない最適化テクニックが使われていたので紹介します。 他にも面白いことは書いてあったのですが、最も気になった2つを紹介します。

TVM stack

f:id:natsutan:20181013084651p:plain

TVMは図のようなスタック構造になっています。上から順番に最適化をしていって、最後にLLVMやCUDAのソースコードを生成します。High level Graph Rewritingの話(Section 3)や、Tensorとスケジューリングの話(Section 4)で最適化した後、それらの組み合わせを考慮するときに、機械学習を使って最適化をしています。

TVMは、このOptimizerに来る前に可能な限りの最適化を考えます。その結果、10億以上の最適化の組み合わせ(configuration)から、実際のワークロードに適した組み合わせの検索をOptimizerが行います。つまり 、Optimizerは実際に最適化をするのではなく、最適化の組み合わせの探索に機械学習を使っています。

ML based Cost Model

最適化の探索には、様々なファクターがあります。 - メモリアクセスパターン - データの再利用 - パイプラインの依存性 - スレッドのパターン - etc 最適化のするに当たっては計算のコストモデルを作る必要があります。 従来のAuto-turningの手法では良い組み合わせを探すのに多くの実験が必要になります。定義済みのコストモデルを使う場合は、バックエンドのハードウェアへの依存性が高くなります。そこでTVMでは、機械学習を使ったアプローチを取っています。

f:id:natsutan:20181013084809p:plain

図のように、ループの構文ツリーをTreeRNNに入れ、特徴量を出しコストを予想しています。

Schedule Exploration

コストモデルが決まった後は、そのコストモデルに従って一番良い組み合わせを探します。理想的には全てのコンフィグレーションを試し上位のいくつかを選択すれば良いのですが、それには強大な探索空間が必要になります。その問題を解決するために、TVMは a parallel simulated annealing algorithmを使います。

まずはランダムに選んだコンフィグレーションから開始し、ランダムウォークをしながら、コストモデルが予測するコストが低い方へ移動していきます。ランダムウォークはコストの低いところを見つけ、移動しなくなるまで続けられます。

感想

コンパイラの最適化技術がここまで進んでいるとは思いませんでした。個別のターゲットに対して、個別の最適化を行う時代は過ぎているだと思います。AIによって世界中の誰でも、どのデバイスでも、最適化職人の技術の恩恵にあずかれると思うと素晴らしいですね。

コンパイラ勉強会が来月に開催されるようで、申し込んではみましたが抽選に通るかどうか難しいそうです。 https://connpass.com/event/103976/

Rustで文字列の連結

Rust Standard Library Cookbookを読み始めました。

Amazon CAPTCHA

この本ではRustの文字列連結として3つの方法が紹介されています。

moveによる連結

一番標準の方法。わかりやすく効率も良いが、連結後はmoveによりhelloは使えなくなる。

fn by_moving() {
    let hello = "hello ".to_string();
    let world = "world";

    let hello_world = hello + world;

    println!("{}", hello_world);
}

helloはStringで、worldが&str。この2つを連結するとStringになるというのもよくわかってない。(なんで to_string()が必要なの?)

cloneによる連結

clone()を使うことで、一時変数が作られ、それをmoveすることで文字列を連結している。連結後もhelloが使えることがポイント。

fn by_cloning() {
    let hello = "hello".to_string();
    let world = "world";

    let hello_world = hello.clone()  + world;
    println!("{} ", hello_world);
}

mutingによる連結

helloをmutableで宣言して、push_strを使う方法。エレガントじゃないらしい。

fn by_mutating() {
    let mut hello = "hello".to_string();
    let world = "world";

    hello.push_str(world);
    println!("{} ", hello);
}

今まで勉強したプログラミング言語の中で一番文字列がめんどくさい。

元のソースはこちらです。 github.com

GCPUG in Osaka #8【GCP】〜 Google TPU Day 〜


マーチンのおっかけで、GCPUGへ参加してきました。
https://gcpug-osaka.connpass.com/event/100106/

Tensorflow and modern convnets グーグル Martin Görner さん・吉川さん

Google martinによる。最新のコンボリューションネットワークの紹介。CNNの基本から始めて、inception modelやsquuzenet等、最近の画像系ネットワークに関して、さわりの説明がありました。

デモは飛行機検出のデモでした。京都とは違う確度から説明されていて、ハイパーパラメータのチューニングに関するトピックもありました。基本はアイデアをいくつか実装してGCPを使って一気に動かすこと。お金持ちの発想の気がします。

複数のハイパーパラメータから最適な物を探すときには、グリッドサーチでは無くランダムに振った方が良い。ただし、いろいろとハイパーパラメータを振る前に学習を安定させるのが大事と。飛行機の例だと、ハイパーパラメータを降る前にデータオーギュメンテーションを行って、学習が安定(曲線がなだらかに)してから、いろいろ振った方が良いみたいです。

TPUに関しては、安くて速い、使わないと損という感じの猛プッシュでした。200円ネタを外したのは残念。おもしろいのに。

BigQueryネタ [Cavity LLC.](http://www.cavity.jp/) 中田 さん

京都でも聞いたBigQueryネタ。正直、名前しか聞いたことが無いが、これだけ話題になるんだからすごいんだろうと思う。Googleさんが、こういうサービスのアイコンを公開して好きに使っていいよ〜ってやってたのが、勉強会で良い効果がでているなと感じました。

Firebase x スマートスピーカー x GCF がおまる さん

https://www.amazon.co.jp/dp/479805481X/

スマートスピーカーの本争奪じゃんけん大会がありました。今手が出せないから参加しなかったのですが、大阪の開発メンバーなら喜んでくれそうで、参加すれば良かったと後悔。社内で紹介しておこう。

最後に

GCPUGに初めての参加でしたが、とても楽しめました。GCPUGのみなさん、会場を提供いただいたGMO様、ありがとうございました。

DevFest Kyoto 2018 & TPU

日曜日にDevFest Kyotoに参加してTPUの情報を集めてきました。
https://gdgkyoto.connpass.com/event/99527/

Twitterでは見たことがあるこの図を生で見れたのが良かったです。

TPUで使用されているbfloatフォーマットについて。

よく見ると、指数部を増やして、仮数部を減らしています。推論で使うことを考えると、適切な正規化を行うことでデータの範囲をある程度制御でき、むしろ指数部が要らない気がします。となると学習時の勾配をハンドルするために、指数部を増やしていると思います。学習に関しては、最初はbflot16で進めて、learning rateを下げるタイミングでfp32に切り替えたりしたら、速度と精度のバランス取れそうです。妄想が膨らみますね。

消費電力について

TPU v3の消費電力はシークレットという事ですが、水冷が必要になっている時点でお察し案件だと思います。TPU v2について上から見た写真しかなく、横から見た写真が公開されていないのは、放熱器の大きさからだいたいの消費電力がばれるからだと思います。
僕の勝手な予想だと両方とも100Wくらいあるのではと思います。

発表資料

マーチンのTPU発表資料はこちらです。
https://docs.google.com/presentation/d/1iodAZkOX0YMnUwohgQqNsbEkhR0zAnO-jncK9SkJ69o/edit

お礼

すごく楽しいイベントを企画していただき、運営の方々ありがとうございました。
Lispの人にも挨拶できなかったのが気がかりです。たまに使ってますよLisp

TFUG KANSAI Meetup 2018

今回は急な開催となり告知期間が短い中、57名の方に参加していただきました。
平日の微妙な天気の中、ご参加いただきありがとうございました。

さくらインターネット様には素敵な会場提供だけでなく、講演者へのお声がけや、懇親会の費用も負担していただき実質のスポンサーとしてご協力いただきました。ありがとうございました。

全体的には特にトラブルも無く無事終わりました。

各セッションの感想を簡単に。とにかく全てが面白いセッションでした。

Google 下田様 「Google Cloud Next で発表された最新ML情報のアップデート」

前半は機械学習の環境をマネージメントするKubeflowについてのお話でした。僕たちが使うには、日本語の情報が増え、各コンポーネントがそろってからで良いかなと感じました。時代の先端を行きたい人は使ってみましょう。こういう仕組みが一般に広まっていくと、お客様との仕事の進め方がやりやすくなるなという感想です。前半のデータの管理の方が自分たちの業務に標準として取り込みたい部分です。

後半はEdge TPUの話でした。なんと言っても小さい。画像で見たときの大きなチップがEdge TPUだと思っていて、これはどうかなと思っていたのですが、横にある小さい方がEdge TPUです。PLL内蔵で単一電源で動いたりしたらめっちゃうれしい。

山口様 「囲碁プログラムAQの強化学習戦略と神の一手までの道のり」

囲碁AIにおいて、神の一手が概念的な話では無く実際に達成できる道のりとしてロードマップが出てきたところにしびれました。最強のAIが出てきたとしたら、その最強のAI同士の勝負は必ず引き分けになるという所から、いつ頃最強AIができそうなのかという話でした。

前から気になっていたAIによるトレーニングについても質疑応答でお話が聞けました。今は最強を目指す方向にみんな向かっているが、中国ではAIを使って人間の実力を上げる事もやっているようです。強さが点数として出るので、そういう取り組みがやりやすいそうです。面白い。

Google Martin Görner 様 「Tensorflow, deep learning and Recurrent Neural Networks, without a PhD」

TensorFlowのソースコードを学習させて、自動でコード生成をする話が最高に面白かったです。ここから順に見ていってください。

https://docs.google.com/presentation/d/18MiZndRCOxB7g-TcCl2EZOElS5udVaCuxnGznLnmOlE/pub?slide=id.g139650d17f_0_1283

最初はぐだぐだだったのが、だんだんPythonのキーワードを覚えたり、コロンの使い方を覚えたりしていきます。学習途中だと、[]の対応ができてなかったり、関数名が無駄に長かったり、初心者っぽさがでています。そして学習を続けると、いきなり偽アパッチライセンスを主張し始め、なんとTensorFlowのtipまで付け加えるという優秀っぷりを発揮します。

word単位では無くchar単位で生成させて、ここまでできることに驚きました。

Pegara 中塚様 「時代はAMD GPUやで」

AMDGPUを使ってDeep Learningをする話。ボトルネックを調べると、データのやりとりの部分で律速しているので、お高いGPUを使う意味は無いという話。実測しているので説得力がありました。一方、やりたいことに対してfp16やfp64本当に必要?fp32で十分でしょという所も実感としてはその通りですね。

AMDGPU環境としてROCm(ロックエム)の紹介がありました。今なら十分使えるようです。機会があれば(無理してでも作って)、一度評価してみたいですね。対策済みの脆弱性の紹介で、GPUのファンを回しっぱなしにしてデバイスにダメージを与えるという話が面白かったです。ハッカーぽさを感じました。

さくらインターネット 長谷川様 「さくらインターネット 高火力コンピューティングのご紹介」

つかみのイカの話はすごく面白く、もっと聞きたかった人も多かったと思います。

高火力サーバーの導入事例として、PFNさんなど有名な企業が並ぶ中、突然のDeep AAに衝撃をうけました。紹介時期はこちらにあります。

http://ascii.jp/elem/000/001/672/1672886/

今後間違いなく廃れて行くであろうAAに注ぐ情熱に、才能の無駄遣いを感じずにはいられませんでした。一方、職人が持っている属人的な技術を、AAで誰でも使えるようにしたいという要望は製造現場では少なからずあります。日本の高齢化社会の問題にも一石投じる素晴らしい取り組みだと思いました。

Edge TPU

予想以上に小さかったEdge TPUへの期待は大きいです。
気になるのは
・チップ単体での販売はあるのか、その価格帯は?
・低消費電力を実現するために量子化がマストになると、精度のチューニングに苦労するのでは無いか。
・通常の半導体のようなデータシートが公開されるのか?
・供給能力がめちゃ不安。ディスコンのアナウンスとか、いきなり来そう
と言った点です。

続報を待ちたいです。