Freeleticsで神に挑む - ゴッドワークアウト一巡り

f:id:shiumachi:20201206165919j:plain
Photo by Gordon Cowie on Unsplash

この記事は pyspa Advent Calendar 2020 の 7日目の記事です。昨日は rokujyouhitoma でした。

昨年はプロダクト開発についての話を書きましたが、今年はガラッと方向性を変えて、筋トレの話をすることにします。

2019年3月からFreeleticsというAIパーソナルトレーナーアプリを使ってトレーニングを続けています。

Freeleticsについては過去にいくつか記事を書いているので、Freeleticsって何?って人は記事末尾の関連記事を読んでみてください。

さて、Freeleticsでは、複数のトレーニングを組み合わせたワークアウトを多数用意しています。それぞれに神話の神々の名前をつけていて、これらはゴッドワークアウトと呼ばれています。

このゴッドワークアウトでスターを獲得する(途中で休まず、正しいフォームでワークアウトを完走する)、そして自己ベストタイムを超えていくことがFreeleticsでの大きな目標の一つとなります。

この記事では、このゴッドワークアウトの中から代表的なものをピックアップし、紹介していきます。

誰でもすぐ試せるよう、基本的には器具なし、ランニングなしのワークアウトのみを選んでいます。(一部例外あり)

f:id:shiumachi:20201206153231p:plain
ゴッドワークアウト


ゴッドワークアウトは初級・中級・上級の三段階にわかれているので、それぞれからいくつかピックアップして紹介していきます。

しかし、注意しなければいけないのは、この難易度分類は全く当てにならないということです。

初級なのに明らかに中級以上の負荷のものもあれば、非常に簡単なのに中級に当てはまっているものもあり、単にこの難易度分類だけを見てワークアウトを選択すると大変なことになります。

(この分類いい加減見直してほしい…)

ここではあくまで便宜上の分類だと思ってください。

可能な限り公式の動画を引用しますが、公式の動画が存在しないものについては、Freeletics上での動きと同様の動画を引用しています。

同じ名前の運動でもジムやトレーナーによって動きが微妙に違ったりしますので注意してください。

初級編

アテナ

日本でも有名な、ギリシャの守護女神アテナです。

f:id:shiumachi:20201206153332p:plain
アテナ
1セット目 クライマー x 25 シットアップ x 25 スクワット x 25 休憩 25秒
2セット目 クライマー x 20 シットアップ x 20 スクワット x 20 休憩 20秒
3セット目 クライマー x 15 シットアップ x 15 スクワット x 15 休憩 15秒
4セット目 クライマー x 10 シットアップ x 10 スクワット x 10 休憩 10秒
5セット目 クライマー x 5 シットアップ x 5 スクワット x 5

Freeleticsを代表するワークアウトの一つです。Freeleticsユーザーで挑戦したことがない人はいないはず。
スクワットは有名なので説明は省略しますが、クライマーとシットアップという2つの運動を覚える必要があります。

クライマーは、両手をついて足を伸ばしたハイプランクの状態から、片足づつ交互に手元まで踏み込んでいくという運動です。

クライマー

シットアップは、一般的な腹筋運動をさらにきつくしたものです。腹筋運動のポーズをしてから、頭の上と脚の前を両手で交互に触っていく運動です。


シットアップ

運動習慣がない人にとっては腹筋がめちゃくちゃきつくなります。私は、最初の2セットでお腹がつりました。しかし、Freeleticsに慣れてくるとアテナくらいの負荷はむしろ休憩に感じてくるくらい簡単に思えてきます。

モルペウス

夢の神モルペウスです。マトリックスのモーフィアスの方が有名かもしれないです。

アテナと並んで、最も有名なゴッドワークアウトの一つです。

中級に位置づけられていますが、あまりに簡単すぎるのと、内容がわかりやすいので初級編で紹介しています。

プッシュアップができるかどうかがポイントです。

f:id:shiumachi:20201206153358p:plain
モルペウス
1セット目 プッシュアップ x 5 ランジ x 10 ジャンピングジャック x 20
2セット目 プッシュアップ x 7 ランジ x 15 ジャンピングジャック x 30
3セット目 プッシュアップ x 10 ランジ x 20 ジャンピングジャック x 40
4セット目 プッシュアップ x 7 ランジ x 15 ジャンピングジャック x 30
5セット目 プッシュアップ x 5 ランジ x 10 ジャンピングジャック x 20


プッシュアップは、ご存知腕立て伏せです。Freeleticsのプッシュアップは、地面に胸をつけて両手を一度浮かせるのが特徴です。

プッシュアップ

ランジは、直立した状態から脚を交互に前に出して膝立ちの状態になる運動です。

ランジ

ジャンピングジャックは、直立の状態からジャンプして両手両足を開き、その後もう一度ジャンプして脚を閉じながら両手を頭の後ろに組む運動です。ラジオ体操などでも似たような運動があるので、ほとんどの人は簡単にできるでしょう。


ジャンピングジャック

レイア

大地の女神レアです。

Freeleticsのゴッドワークアウトの中で最も簡単なものです。

f:id:shiumachi:20201206153426p:plain
レイア
1セット目 ハイニー x 20 クランチ x 20 スクワット x 20
2セット目 ハイニー x 15 クランチ x 15 スクワット x 15
3セット目 ハイニー x 10 クランチ x 10 スクワット x 10


ハイニーは、要するにもも上げです。


ハイニー

自分の経験上は、レイア単体で出てくることはまずなく、レイア x2 で出てきたことしかありません。それでも3分ちょっとで終わるので非常に簡単です。

メティス

知恵の女神メーティスです。

このあたりからFreeletics のヤバいメニューの紹介に移っていきます。
初級に位置付けられてますが、先に紹介したモルペウスより遥かにキツいです。

f:id:shiumachi:20201206153454p:plain
メティス
1セット目 バーピー x 10 クライマー x 10 ジャンプ x 10
2セット目 バーピー x 25 クライマー x 25 ジャンプ x 25
3セット目 バーピー x 10 クライマー x 10 ジャンプ x 10

バーピーは日本でもかなり有名な有酸素運動ですが、Freeleticsでも頻繁に取り入れられています。


バーピー

クライマーはアテナの項を参照してください。

ジャンプは、直立の状態から両足をジャンプさせて膝を腰の上くらいまで持ってきます。(動画は省略)

一見分量が少なくて簡単そうに見えますが、全ての運動で「脚でジャンプする」という動作が入るため脚が休む暇がなく、またバーピー→クライマーの流れではどちらも肩を使うため肩の疲労も相当なものになります。

5分間全力で両足ジャンプし続けるようなものなので、とにかく脚が持ちません。

セレネ

月の女神セレネです。

初級の中でぶっちぎりで凶悪なワークアウトです。というかこれが初級なのが本当に理解できません。

f:id:shiumachi:20201206092308j:plain
セレネ
1セット目 ジャンピングジャック x 50 クランチ x 20 ランジ x 20 バーピー x 20
2セット目 ジャンピングジャック x 50 クランチ x 20 ランジ x 20 バーピー x 20
3セット目 ジャンピングジャック x 50 クランチ x 20 ランジ x 20 バーピー x 20
4セット目 ジャンピングジャック x 50 クランチ x 20 ランジ x 20 バーピー x 20
5セット目 ジャンピングジャック x 50 クランチ x 20 ランジ x 20 バーピー x 20

クランチは、多くの人がよく知る腹筋運動に一番近いです。頭の上と膝を両手で交互に触っていきます。

クランチ

セレネはバーピーを合計100回行うのみならず、メティスと同様、バーピー→ジャンピングジャックの流れでジャンプ運動を連続して行うため、ジャンピングジャックでさえ凄まじくきつく感じます。

クランチだけが唯一の癒やしポイントになります。腹筋が鍛えられていないと癒やしにはなりませんが、セレネに挑戦する人がクランチ100回をできないということはまずないでしょう。

中級編

プロメテウス

火の神プロメテウスです。

f:id:shiumachi:20201206153544p:plain
プロメテウス
1セット目 クライマー x 30 プッシュアップ x 10 シットアップ x 30 スクワット x 30 ジャンピングジャック x 50 休憩 30秒
2セット目 クライマー x 20 プッシュアップ x 7 シットアップ x 20 スクワット x 20 ジャンピングジャック x 50 休憩 30秒
3セット目 クライマー x 10 プッシュアップ x 5 シットアップ x 10 スクワット x 10 ジャンピングジャック x 50 休憩 30秒
4セット目 クライマー x 20 プッシュアップ x 7 シットアップ x 20 スクワット x 20 ジャンピングジャック x 50 休憩 30秒
5セット目 クライマー x 30 プッシュアップ x 10 シットアップ x 30 スクワット x 30 ジャンピングジャック x 50

アテナの上位版みたいな内容で、初級コースの大半を完走できれば問題なくできるワークアウトです。

サーキットの後半でだんだん分量が増えていくのがちょっと大変ですが、インターバルが30秒あるので非常に良心的な内容です。

アテナとモルペウスに飽きたらこれをやるのがおすすめです。

アマゾナ

このワークアウトは開発された時期が異なるのか、かなり特殊なワークアウトです。神々の名前がついていないというのも特異ですが、その内容もかなり変わっていて、このワークアウトでしか登場しない運動がいくつもあります。
全身運動が多いゴッドワークアウトの中で、ひたすら下半身に特化しているというのも特徴です。そのため、肩を痛めたときによくこれをやってました。

f:id:shiumachi:20201206153634p:plain
アマゾナ
1セット目 ランジ x 20 コサックスクワット x 20 スプリットランジ x 20 リバースランジ x 20 スクワットジャンプ x 20 プランクレッグリフト x 100
2セット目 ランジ x 20 コサックスクワット x 20 スプリットランジ x 20 リバースランジ x 20 スクワットジャンプ x 20 プランクレッグリフト x 100


コサックスクワットは、片足を伸ばし、もう片足を曲げる、屈伸運動のような動作をする片足スクワットです。見た目は簡単そうですがかなり負荷のある運動です。


コサックスクワット

スプリットランジは、ランジの格好からジャンプして脚を交互に入れ替える運動です。ジャンプ運動なのでかなり脚に負荷がかかります。


スプリットランジ

リバースランジは、ランジの逆で、膝をつく方の脚を後ろに出し、膝を立てる方の脚をその場に残してランジします。


リバースランジ

スクワットジャンプは、スクワットして膝を曲げた後に伸ばしてジャンプする運動です。これもジャンプ運動でかなり負荷がかかります。


スクワットジャンプ

プランクレッグリフトは、プランクの状態で交互に脚を上げる運動です。


プランクレッグリフト

連続して大腿筋に負荷をかけていくので、後半のスクワットジャンプとプランクレッグリフトがかなりきつくなります。インターバルがないので、2セット目は特にきついです。

アフロディテ

愛と美の女神アフロディーテです。最近はなくなりましたが、昔のFreeleticsのアプリの更新履歴には「アフロディテが終わるより早くバグ対応します!」と書かれていたりしました。

内容もとてもシンプルで、Freeleticsを代表するワークアウトの一つです。

あまりにきつすぎて私はまだ挑戦したことありませんが。

f:id:shiumachi:20201206153707p:plain
アフロディテ
1セット目 バーピー x 50 スクワット x 50 シットアップ x 50
2セット目 バーピー x 40 スクワット x 40 シットアップ x 40
3セット目 バーピー x 30 スクワット x 30 シットアップ x 30
4セット目 バーピー x 20 スクワット x 20 シットアップ x 20
5セット目 バーピー x 10 スクワット x 10 シットアップ x 10

バーピー→スクワット→シットアップのサーキットをインターバルなしでそれぞれ150回づつ行うというもの。初級最難関のセレネでさえバーピー100回やクランチ100回なので、アフロディテがどれだけ凶悪かおわかりでしょうか。

リーダーボードを見てみると、上級者達はこのアフロディテを15分以下で完走してます。

上級編

ここから先は私もほぼ未踏の領域です。(ハーフセット等は挑戦したことあるけどフルセットはほぼ未体験)

ヘカテ

冥界の女神ヘカテーです。

f:id:shiumachi:20201206153731p:plain
ヘカテ
1セット目 クラッピングプッシュアップ x 16 ピストルスクワット x 16
1セット目 クラッピングプッシュアップ x 12 ピストルスクワット x 12
1セット目 クラッピングプッシュアップ x 8 ピストルスクワット x 8
1セット目 クラッピングプッシュアップ x 6 ピストルスクワット x 6
1セット目 クラッピングプッシュアップ x 4 ピストルスクワット x 4

クラッピングプッシュアップは、プッシュアップの上位版で、腕を伸ばす代わりに腕でジャンプして拍手するというものです。


クラッピングプッシュアップ

ピストルスクワットは要するに片足スクワットです。脚への負荷も相当なものですが、バランスを取るのがとても難しい運動です。


ピストルスクワット

どちらも肘・肩と膝にものすごい負荷がかかるので、よほど筋力に自信がない限りやめた方がいいです。

一方で心肺機能としての負荷はそこまで高くないので、筋力が十分あれば上級の中では比較的とっつきやすいのではないかと思います。(といいつつ私はまだフルセット未チャレンジですが)

ケルベロス

地獄の番犬ケルベロスです。ひたすらプランクを行うワークアウトで、その姿勢が四つん這いなのでケルベロス(=犬)の名前をつけたのではないかと思います。

f:id:shiumachi:20201206092547j:plain
ケルベロス
1セット目 プランクホールド 60秒 プランクスイッチ x 10 スクワット x10
2セット目 プランクホールド 120秒 プランクスイッチ x 20 スクワット x 20
3セット目 プランクホールド 180秒 プランクスイッチ x 30 スクワット x 30

プランクスイッチは、ハイプランクの状態から肩肘づつ曲げていきロープランクの状態に移り、そこからまた肩肘づつ伸ばしてハイプランクの状態に戻るという運動です。

アプリ内の説明動画では、昔はロープランク→ハイプランク→ロープランクという運動だったのですが、最近のアップデートで説明動画が更新されると、なぜかハイプランク→ロープランク→ハイプランクという動作になりました。以下の動画は旧バージョンの動きなので注意してください。


プランクスイッチ(旧バージョン)

とにかくプランクホールド合計6分間がきついです。この間なにもできずにじっとしてるだけなので肉体的のみならず精神的にもきついです。プランクホールドが終わった直後のプランクスイッチもきついです。スクワット合計60回は完全におまけです。

ウェヌス

愛と美の女神ヴィーナスです。ギリシャ神話の神々の名前が多く用いられる中、ウェヌスは珍しくローマ神話からの引用です。アフロディテの別名とも言われています。

メニューもアフロディテと同様にとてもシンプルです。

f:id:shiumachi:20201206092540j:plain
ウェヌス
1セット目 プッシュアップ x 50 クランチ x 20 スクワット x 50
2セット目 プッシュアップ x 50 クランチ x 20 スクワット x 50
3セット目 プッシュアップ x 50 クランチ x 20 スクワット x 50
4セット目 プッシュアップ x 50 クランチ x 20 スクワット x 50

つまり、腕立て200回腹筋80回スクワット200回をやるだけ。とてもシンプルです。腕立て50回 x 4セットをインターバルなしでできる人なら問題ないはず。私はできません。

ヘリオス

太陽神ヘリオスです。おそらくランニングなし + 器具なしのゴッドワークアウトの中では最難関と思われます。

f:id:shiumachi:20201206092615j:plain
ヘリオス
1セット目 バーピー x 100 ランジ x 125 クライマー x 150 シットアップ x 125 クライマー x 150 ランジ x 125 バーピー x 100

なんと1セットのみ。別に変わった運動が入るわけでもなく、シンプルに分量が膨大なワークアウトとなっています。

バーピー200回、ランジ250回、クライマー300回、シットアップ125回をインターバルなしで走り切るのは相当な身体能力が要求されます。

リーダーボードを見ると、上級者はこの内容を30分以下で完走しています。恐ろしい…。

ゼウス (器具あり最難関)

ご存知、全能の神ゼウスです。ゼウスの名を冠するだけあってその難易度もかなりのものなので、参考までに紹介しておきます。

倒立するための壁と、懸垂をするためのバーが必要になります。

f:id:shiumachi:20201206092706j:plain
ゼウス
1セット目 ストリクトハンドスタンドプッシュアップ x 10 プルアップ x 20 プッシュアップ x 30 シットアップ x 40 スクワット x 50
2セット目 ストリクトハンドスタンドプッシュアップ x 10 プルアップ x 20 プッシュアップ x 30 シットアップ x 40 スクワット x 50
3セット目 ストリクトハンドスタンドプッシュアップ x 10 プルアップ x 20 プッシュアップ x 30 シットアップ x 40 スクワット x 50
4セット目 ストリクトハンドスタンドプッシュアップ x 10 プルアップ x 20 プッシュアップ x 30 シットアップ x 40 スクワット x 50

ストリクトハンドスタンドプッシュアップは、要するに壁を使った逆立ち腕立て伏せです。


ストリクトハンドスタンドプッシュアップ

プルアップは、反動を使った懸垂です。ちなみに私はハーフラックで懸垂を行っているので反動を使うとさすがにひっくり返るため、プルアップは全て反動なしで行っています(その方が効く)。


プルアップ

まず、逆立ち腕立てができない人は門前払いです。できたとしても、逆立ち腕立て→懸垂→腕立てを連続して行うのはかなりの強靭な肉体がないと厳しいでしょう。

さらなる高みを目指して

ゴッドワークアウト1セットでは物足りない、という人たち向けに、Freeleticsでは最大3セットまでゴッドワークアウトを連続実行できるようになっています。

リーダーボードを見ると、ヘリオス3セットを完走している人が何人かいます。恐ろしい体力です…。

f:id:shiumachi:20201206154732j:plain
鉄人達が並ぶリーダーボード

こんなんできるか!

はい、初級はともかく中級以上でフルセットやるのは普通の人にはまず無理です。

実際のFreeleticsでは部分セットだけをメニューに組み込むなど、アスリートの身体能力に合わせたメニューを用意してくれるので安心してください。

(例えば「セレネ 1セット目のみ」「ケルベロス 1セット目のみ」など)

ですが、部分セットだけをこなしても記録の見直しができないので、やっぱりフルセットできるようになる方が楽しいです。フルセットのゴッドワークアウトをこなすと、以下のようなログに記録が残ります。

f:id:shiumachi:20201206154119p:plain
アテナの記録

Freeleticsに興味を持った人へ

Freeleticsは有料のアプリです。年間1万円のサブスクリプションです。
3ヶ月プランや6ヶ月プランもあるので、続ける自信がないという人はこちらを購入してもいいです。14日間は返金に応じてくれるので、試しに買ってみて、合わなかったら返金しましょう。

Freeleticsを始めてみたいという人は、下記のリンクから購入すれば20%オフで買えます。 Coach と Nutrition (食生活改善)の二種類が出てきますが、Nutrition は自分は試していません。運動だけなら Coach で十分と思いますが、誰か Nutrition を試した人がいたら感想教えてください。

https://www.freeletics.com/r/124871187

pyspaアドベントカレンダーの次回予告

明日は、Freeleticsのゴッドワークアウトなんて鼻歌交じりに完走できるほど屈強な肉体を手に入れてしまった ymotongpoo です。

pandas.concatでcsvファイルを読み込み、連結する際に簡易的に整合性チェックを行う

@hurutoriya さんが、先日以下の記事を投稿していました。

shunyaueta.com

その後ツイッター上でやりとりしているうちにこんな話がありました。

当初は簡単にできるかなと思ったのですが、mergeならともかくconcatとなると、そんなに簡単にはいきません。

こうしたコードを使うケースというのは、大抵の場合探索的データ分析していたり、「素早く手軽に読み込みたい」というものなので、手軽さを失わないようにしながら最低限のチェックを行っていく必要があります。

連続したcsvを読み込むときにひっかかるケースの大きなものとしては、カラムの不一致とデータ型の不一致です。なので、この2つに絞ってバリデーションを行う、validate関数を作ってみました。

コードは長くなるので記事の末尾に載せています。

使い方は簡単で、まず、dfのリストの代わりに、 (pathlib.Path, df) のタプルのリストを作ります。

    data = [(path, pd.read_csv(str(path))) for path in pathlib.Path(f_path).glob('*.csv')]

あとはこれを validate(data) に入れて、 pd.concat に渡すだけです。

    pd.concat(validate(data))

もしカラムが一致していない場合は以下のようなエラーが出ます。

ValueError: ambiguous columns: file2.csv, file3.csv

もしカラムが一致していてもdtypeが一致していない場合は以下のようなエラーが出ます。

ValueError: inconsistent dtypes: int64, object in file2.csv, file4.csv


適当に作ったコードなのでエラー等あるかもしれません。
もし不具合等あったらお気軽にご報告ください。

コード全体(デモコードつき)

import pathlib
import typing

import pandas as pd

# data definition
## valid data
df1 = pd.DataFrame(
    [
        {"c1": 100, "c2": "a100"},
        {"c1": 101, "c2": "a101"},
    ]
)
## valid data
df2 = pd.DataFrame(
    [
        {"c1": 200, "c2": "a200"},
        {"c1": 202, "c2": "a202"},
    ]
)
## invalid data: ambiguous column names
df3 = pd.DataFrame(
    [
        {"c1": 300, "c3": "a300"},
        {"c1": 301, "c3": "a301"},
    ]
)
## invalid data: inconsistent dtypes

df4 = pd.DataFrame(
    [
        {"c1": "400", "c2": "a400"},
        {"c1": 401, "c2": "a401"},
    ]
)

## dataset test case 1: ambiguous column names
data1 = [
    (pathlib.Path("file1.csv"), df1),
    (pathlib.Path("file2.csv"), df2),
    (pathlib.Path("file3.csv"), df3),
]
## dataset test case 2: inconsistent dtypes
data2 = [
    (pathlib.Path("file1.csv"), df1),
    (pathlib.Path("file2.csv"), df2),
    (pathlib.Path("file4.csv"), df4),
]


def validate(
    data: typing.Sequence[typing.Tuple[pathlib.Path, typing.Sequence[pd.DataFrame]]]
) -> typing.Sequence[pd.DataFrame]:
    """simple data validation

    :param data: [(path, df)]
    :return: [df]
    """
    for x, y in zip(data, data[1:]):
        if x[1].columns.tolist() != y[1].columns.tolist():
            raise ValueError(f"ambiguous columns: {x[0]}, {y[0]}")
        for xd, yd in zip(x[1].dtypes, y[1].dtypes):
            if xd != yd:
                raise ValueError(f"inconsistent dtypes: {xd}, {yd} in {x[0]}, {y[0]}")
    return [x[1] for x in data]


print("### validate ambiguous columns demo ###")
try:
    pd.concat(validate(data1))
except ValueError as ve:
    print(ve)

print("### validate inconsistent dtypes demo ###")
try:
    pd.concat(validate(data2))
except ValueError as ve:
    print(ve)

謝辞

@aodag (zipのエレガントな書き方を教えてくれてありがとうございます)

Hadoop DistCp実践ガイド2020年版

Hadoop DistCp (distributed copy, でぃすとしーぴー、でぃすとこぴー) は、MapReduceを用いてHadoopクラスタ間でデータコピーするためのツールです。保守運用している場合を除き、おそらく2020年においても運用上の選択肢として残っている最後のMapReduceのツールです。この記事では、DistCpの紹介と実践的な使い方の基本について説明していきます。内容としては以下の通りです。

  • Distcpの概要と原理
  • 実践DistCp
    • DistCpにドライランはない
    • コピーとアップデートの挙動の違いを押さえる
    • スナップショットを取得する
    • ソースと宛先、どちらのクラスタでDistCpを実行するか
    • 異なるメジャーバージョン間でのデータ転送にwebhdfsを使う
    • -p オプションの挙動
    • 2つのコピー戦略: uniformizeとdynamic
    • map数の調整
    • 転送帯域

なんで今更DistCp?

DistCpの使い方についてきちんと書いているドキュメントがなかったので書きました。Hadoopのバイブルである象本さえ、DistCpについては本当に簡単なことしか書いておらず、実際の使い方についてまとめているドキュメントがありませんでした。Clouderaのようなベンダーの場合は Cloudera Manager という素晴らしいツールが持つデータレプリケーション機能に包含されていて、ユーザーはボタン一発でクラスタ間データ転送ができるため、DistCpについて細かい話を知る必要はありません。そこで、素のHadoopを使う人のためのDistCpの記事を書いておくことにしました。

DistCpについての機能一覧などの詳細については公式ドキュメントを参照してください。

Hadoop 第3版

Hadoop 第3版

  • 作者:Tom White
  • 発売日: 2013/07/26
  • メディア: 大型本

hadoop.apache.org

DistCpの概要

DistCp は、MapReduceを用いてHadoopクラスタ間で高速にデータコピーするためのツールで、Apache Hadoop の標準リリースに含まれています。Apache Hadoopは、分散ストレージのHDFS(Hadoop Distributed File System、Hadoop分散ファイルシステム)と、分散コンピューティングフレームワークのYARNから構成されている分散処理フレームワークで、MapReduceはYARN上で動く代表的なアプリケーションの一つです。 Hadoopクラスタ間と書きましたが、正確には分散ストレージ間と言った方が正しいでしょう。DistCpは、HDFSだけでなく、Amazon S3Azure Storage といったオブジェクトストレージにも対応しています。

DistCpはコマンドラインツールで、以下のような形式で実行します。

$ hadoop distcp hdfs://cluster1/foo/bar hdfs://cluster2/foo

これは、cluster1というHDFSクラスタの、 /foo/bar というパスを、cluster2 というHDFSクラスタの、 /foo というディレクトリにコピーする、というコマンドとなります。

DistCpの原理

DistCpは、MapReduceフレームワークで動作します。まず、MapReduceについて簡単におさらいします。MapReduceは、複数のノードで別個に計算処理を行うMap、特定のキーごとにデータを転送して集約するShuffle、集約されたデータに対し、Mapと同様、ノードごとに独立して処理を行うReduceという3つのフェーズで分散処理を行うフレームワークです。
以下の図は、MapReduceの処理の流れを表しています。

f:id:shiumachi:20200719122107p:plain

DistCpは、Map処理のみを使い、何も計算せず(恒等関数)、入力と出力を別のクラスタで行うという形でMapReduceを使用しています。

以下の図は、DistCpの処理の流れを表しています。

f:id:shiumachi:20200719122509p:plain

DistCpのソース(読み込み元)と宛先(書き込み先)はURIで表されます。先程の例では、宛先を hdfs://cluster2/foo としましたが、この宛先は s3a://bucket1/foo でも問題なく動作します。これは、S3上の bucket1 というバケットの配下にある foo という名前空間にデータをコピーすることを意味します。

実践DistCp: ドライランはない

DistCpは、非常に大規模かつ不可逆変更を行うツールであるにも関わらず、ドライランに相当する機能が存在しないという点に注意してください。ドライランがないということは、十分に検証クラスタでテストした後、本番での実行が成功することを、神(あるいはあなたが信仰する何か)に祈るしかなくなります。そして大抵の場合その祈りが届くことはありません。頑張りましょう。

ドライランについては6年間オープンしているJIRAがありますので、我こそはという方は実装お待ちしています。

issues.apache.org

実践DistCp: コピーとアップデートの挙動の違いを押さえる

hadoop distcp コマンドは、何もオプションをつけない場合は、コピーという挙動になります。これは、以下の操作を行います。

  • ソースにパスが存在し、宛先に存在しない場合はコピーする
  • ソースと宛先に同じパスが存在する場合は何もしない
  • ソースにパスが存在せず、宛先に存在する場合は何もしない

hadoop distcp -update では、以下のように挙動が変わります。

  • ソースにパスが存在し、宛先に存在しない場合はコピーする
  • ソースと宛先に同じパスが存在する場合、チェックサムなどコンテンツの中身を確認し、コンテンツが異なる場合はコピーする。コンテンツが同一の場合は何もしない
  • ソースにパスが存在せず、宛先に存在する場合は何もしない

hadoop distcp -update -delete では、以下のように挙動が変わります。

  • ソースにパスが存在し、宛先に存在しない場合はコピーする
  • ソースと宛先に同じパスが存在する場合、チェックサムなどコンテンツの中身を確認し、コンテンツが異なる場合はコピーする。コンテンツが同一の場合は何もしない
  • ソースにパスが存在せず、宛先に存在する場合はそのパスを削除する

これらの挙動をまとめると、以下の図のようになります。

f:id:shiumachi:20200719122945p:plain

hadoop distcp に -update をつける場合、コンテンツの中身を比較するため、オーバーヘッドが発生します。そのため、-updateなしに比べて処理性能が落ちることに注意してください。


DistCpのコピーとアップデートの挙動の違いは間違えやすく、そしてその間違いが重大な事故を起こしてしまう可能性がありますので絶対に覚えてください。

以下の2つの例を見てください。

# 例1
$ hadoop distcp hdfs://cluster1/foo/bar hdfs://cluster2/foo
# 例2: 誤った方法
$ hadoop distcp -update hdfs://cluster1/foo/bar hdfs://cluster2/foo

例1は、cluster2/foo の直下に cluster1/foo/bar をコピーするので、結果として cluster2/foo/bar が作成されます。
例2は、 cluster2/foo を cluster1/foo/bar の内容でアップデートするので、 cluster2/foo/bar は作成されず、cluster2/foo のコンテンツが cluster1/foo/bar と同じものになります。

図にすると以下のようになります。

f:id:shiumachi:20200719123329p:plain

この一例だけだとピンとこないかもしれませんので、もっと実務上実行する可能性のあるコマンドでみてみましょう。

# 例3
$ hadoop distcp hdfs://cluster1/user/sato hdfs://cluster2/user
# 例4: 誤った方法
$ hadoop distcp -update -delete hdfs://cluster1/user/sato hdfs://cluster2/user

hadoop distcp の -delete オプションは -update オプションと一緒に使わないと利用できないオプションで、ソースクラスタには存在しないけど宛先クラスタには存在する全てのパスを削除します。つまり、-delete を付与すると、ソースと宛先のコンテンツが全く同一のものとなります。
例3は、 cluster1/user/sato を、 cluster2/user/ にコピーします。よって、cluster2/user/sato が作成されます。
例4は、 cluster2/user のコンテンツが、cluster1/user/sato と全く同じものになります。つまり、 /user ディレクトリ配下に存在する全てのユーザーデータが完全に削除され、その代わりにユーザ sato のコンテンツだけが置かれるようになります。

図に表すと、以下のようになります。

f:id:shiumachi:20200719123553p:plain

「ゴミ箱機能があるから即座に削除されることはないのでは?」と思うかもしれませんが、DistCpのバグでゴミ箱は機能しません。この問題は2020/07/15現在未解決です。詳細については以下のJIRAも参照してください。

issues.apache.org

運用者はこのコマンドを誤って実行した時点で、即座に緊急事態のアラートを出さなければいけなくなるでしょう。

この例4は、正しくは以下のように書くべきでした。

# 例4: 誤った方法
$ hadoop distcp -update -delete hdfs://cluster1/user/sato hdfs://cluster2/user
# 例5: 例4の正しい書き方
$ hadoop distcp -update -delete hdfs://cluster1/user/sato hdfs://cluster2/user/sato

では、ここでもう一つの例を紹介しましょう。cluster2に既に/userが存在するときに、以下のコマンドを実行すると何が起きるでしょうか。

# 例6: 誤った方法
$ hadoop distcp hdfs://cluster1/user hdfs://cluster2/user

これが、-update ( -delete ) がついていたならば、問題なかったかもしれません。しかし、今回は -update がついていません。よって、 cluster1/user が cluster2/user の配下にコピーされます。つまり、 cluster2/user/user が作成されます。これは、多くの運用者にとって意図した挙動ではないでしょう。

このとき、安易に cluster2/user/user を削除することはできません。なぜなら、 cluster2/user/user というディレクトリはコピー前から存在していた可能性があり、その中にコンテンツが存在していた可能性があるからです。一度混じってしまえば、cluster1由来のコンテンツとcluster2オリジナルのコンテンツをふるい分けるのは困難でしょう。-update オプションがないときも決して油断してはいけません。
cluster1の/userをcluster2の/userにコピーする場合、以下のように書くべきでした。

# 例6: 誤った方法
$ hadoop distcp hdfs://cluster1/user hdfs://cluster2/user
# 例7: 例6の正しい書き方
$ hadoop distcp hdfs://cluster1/user hdfs://cluster2/

図に表すと、以下のようになります。

f:id:shiumachi:20200719124216p:plain

手動・自動での実行に関わらず、パスの確認は絶対に最後の最後まで確実に行うようにしてください。

実践DistCp: スナップショットを取得する

DistCpは、通常非常に膨大な時間がかかります。クラスタ全体のデータ転送の場合、1日や2日は当たり前で、1週間や1ヶ月に渡って転送し続ける、ということは頻繁に起こります。DistCpはMapReduce実行前に対象パスの一覧を取得しますので、転送中にソースファイルが変化しても一切考慮することはできません。大抵の場合、転送中にファイルが削除され、何日もかけたDistCpが失敗することになるでしょう。運良く転送に成功したとしても、コンテンツの中身に不整合が発生していれば、Hive等の別のアプリケーションでの処理結果が意図しないものとなり、いいことは一つもありません。そのため、ソースはスナップショットを指定するのが鉄則です。
スナップショットの取得は、以下の2つのコマンドを順番に実行します。

$ hdfs dfsadmin -allowSnapshot hdfs://cluster1/foo/bar
$ hdfs dfs -createSnapshot hdfs://cluster1/foo/bar snapshot1

hdfs dfsadmin -allowSnapshot は hdfs ユーザでないと実行できませんが、hdfs dfs -createSnapshot は、対象ディレクトリの権限を持っている一般ユーザでも実行可能です。上記コマンドを実行すると、 hdfs://cluster1/foo/bar/.snapshot/snapshot1 というディレクトリが作成され、この配下には hdfs://cluster1/foo/bar のコンテンツと全く同じハードリンクが作成されます。
snapshot1はスナップショット名なので、自由に変更してコマンドを実行してください。

スナップショットを使ったDistCpは以下のように記述します。

$ hadoop distcp hdfs://cluster1/foo/bar/.snapshot/snapshot1 hdfs://cluster2/foo

実践DistCp: ソースと宛先、どちらのクラスタでDistCpを実行するか

DistCpは、基本的には宛先クラスタ側で実行することを推奨します。DistCpを宛先クラスタ側で実行しなければならないケースとしては以下のようなものがあります。

  • 非セキュアクラスタからセキュアクラスタにデータをコピーする場合
  • 低いメジャーバージョンのクラスタから高いメジャーバージョンにデータをコピーする場合

また、新規クラスタへのデータ移行の場合、ソースクラスタは通常業務のアプリケーションが稼働している一方、宛先クラスタは大抵の場合本番稼働前なので、ソースクラスタの負荷を増やさずに、宛先のリソースを有効活用することができます。

DistCpをソースクラスタで実施しなければいけないケースもあります。例えば、セキュアクラスタから非セキュアクラスタへデータを転送する場合です。

Clouderaの以下のドキュメントの記載を引用します。

docs.cloudera.com

You can use DistCp and WebHDFS to copy data between a secure cluster and an insecure cluster. Note that when doing this, the distcp commands should be run from the secure cluster.

セキュアクラスタにおけるDistCpの方法についてはこの記事では扱いませんが、DistCpをどちらのクラスタで実施するかを検討する場合には頭の片隅にとどめておいてください。

実践DistCp: 異なるメジャーバージョン間でのデータ転送にwebhdfsを使う

webhdfsプロトコルを使うことで、メジャーバージョンの低いバージョンから高いバージョンへのデータ転送を行うことができます。

$ hadoop distcp webhdfs://cluster1/foo/bar hdfs://cluster2/foo

以下は参考リンクです。

docs.cloudera.com

実践DistCp: -p オプションの挙動

デフォルトでは、DistCpはファイル属性等はコピーしません。ファイル属性をコピーするには -p オプションを使いますが、このオプションの挙動には様々な制約事項が存在します。例えば、 -update オプションはコンテンツの中身が同一のパスに対してはコピーを実施しませんが、このときファイル属性だけが違っていてもその属性を更新したりはしません。
以下の例で、両クラスタに /foo/bar/file1 というファイルがあるとします。

$ hadoop distcp -update hdfs://cluster1/foo/bar hdfs://cluster2/foo

このとき、cluster1/foo/bar/file1 のパーミッションが644で、 cluster2/foo/bar/file1 のパーミッションが600となっていて、ファイルのコンテンツが全く同一である場合、cluster2/foo/bar/file1 のパーミッションは 600 のまま変更されません。

別の例を紹介しましょう。 -pt オプションを使うと更新日時などを保持できますが、このオプションは、NameNodeの設定の一つ、 dfs.namenode.accesstime.precision (デフォルト1時間) が0(無効)の場合利用できません。dfs.namenode.accesstime.precision を 0 にしたまま以下のコマンドを実行しても、失敗します。

$ hadoop distcp -pt hdfs://cluster1/foo/bar hdfs://cluster2/foo

このとき、以下のようなエラーが出力されます。

Error: org.apache.hadoop.ipc.RemoteException(java.io.IOException): Access time for hdfs is not configured. Please set dfs.namenode.accesstime.precision configuration parameter.

アクセス時間の設定はパフォーマンスの最適化のために0にするのが推奨で、Ambari / HDP はデフォルト0になっていますが、コミュニティ版もClouderaもデフォルト1時間なので、設定そのものを知らない人も多いと思います。 -p オプションを使うときはドキュメントを読むだけで設計せず、必ず検証をしてください。

実践DistCp: 2つのコピー戦略: uniformizeとdynamic

DistCpが各Mapタスクに処理対象のパスを振り分ける戦略は2タイプ存在します。デフォルトはuniformizeという、データサイズで分割する方法です。例えば転送対象のデータが100TBあり、mapタスクを1000で設定した場合、各mapタスクは100GBのデータを転送するように、ファイルパスを振り分けられます。この挙動は、ソースコードを読めばわかりますが、リストされたファイルを上から順に取り出していきサイズを足していき、転送対象の全データサイズ/map数を超えたら次のmapタスクに渡す、という操作を行っています。

github.com

理想的なHDFSの環境ではこれで問題ないのですが、小さいファイルが大量にある環境の場合は、uniformizeではうまくいきません。
uniformizeでは、どれだけたくさんのファイルがあっても、一定のサイズを超えない限りはそれらのファイルが1mapタスクに割り当てられてしまいます。割り当てられるファイルは、ファイルリストの上から順にファイルを取り出されます。ファイルリストは、単純に対象ディレクトリの配下のファイル・ディレクトリを再帰的にリストしているだけなので、同一ディレクトリのファイルは一箇所に固まっています。その結果、あるディレクトリのファイルは1タスクに集中することになります。
1ファイルに対するHDFSアクセスは非常に遅いです。環境にもよりますが、1ファイルあたり数msのオーダーは見たほうがいいでしょう。そのため、スモールファイルが多いストレージでは、データ転送速度は非常に遅くなります。そして、多くの場合、スモールファイルは局所化しています。これはすなわち、特定のディレクトリにスモールファイルが集中していることを意味します。
まとめると、特定のディレクトリに集中したスモールファイル群がまとめて1つのmapタスクに割り当てられる結果、mapタスクのスキューが発生し、そのmapタスクだけが極端に遅くなるという現象が発生します。

このような環境では、dynamic というもう一つのコピー戦略を使います。dynamic はファイル数でタスクあたりの割当を分割するオプションです。例えば、1億ファイルあるシステムで1000mapタスクで処理を分割する場合、1タスクあたり10万ファイルを担当することになります。
dynamicオプションを使う場合、uniformizeと逆に、極端にファイルサイズが大きいデータが集中しているケースに注意してください。ファイルサイズを考慮しないでデータを分割するため、特定のタスクだけ極端に大きなデータを処理しなければいけないというリスクが発生します。転送対象のデータ特性は必ず事前に調査しましょう。
dynamic 戦略を使うには、以下のようにオプションを与えます。

$ hadoop distcp -strategy dynamic hdfs://cluster1/foo/bar hdfs://cluster2/foo

実践DistCp: map数の調整

デフォルトではDistCpは20mapタスクしか使用しません。データ量やリソース状況に応じて、map数の調整をしたほうがいいでしょう。以下の例は、map数を100とする場合の例です。

$ hadoop distcp -m 100 hdfs://cluster1/foo/bar hdfs://cluster2/foo

map数の調整は、基本的なHadoopアプリケーションと同様、ストレージIOやリソースに応じて調整する必要があります。リソースをフルに使えるのであれば、総ディスク数の1~2倍くらいにしておくのがいいと思いますが、例えばスモールファイル中心のクラスタの場合IOよりもCPU依存になるはずなので、CPUコア数からタスク数を計算した方がいいかもしれませんし、クラスタのリソースが逼迫している状態であればむしろmap数を減らしてゆっくり処理した方がいいかもしれません。このあたりの計算に自信がなければ、まずはデフォルトで試験的に転送してみて、転送速度を計算した上で必要があればチューニングするという程度でいいと思います。

実践DistCp: 転送帯域

ネットワークの帯域リソースが逼迫している場合は、転送用の帯域を制御した方がいいでしょう。以下のように設定することで、1mapあたりの転送帯域を10MB/sに抑えることができます。

$ hadoop distcp -bandwidth 10 hdfs://cluster1/foo/bar hdfs://cluster2/foo

この記事で書いていないこと

ただコピーするといっても、細かい要件はプロジェクトによって異なり、それに応じてDistCpの様々な機能を活用していく必要があります。
この記事でカバーしていない内容は以下の通りです。

そして、クラスタ移行という話になったときは、必要な作業はDistCpだけではありません。例えば、HiveメタストアDBのデータ移行や、管理ツールのデータ移行など、考えるべき課題は他にもあります。これらについて、最新の情報をベースに体系的にまとめられた書籍は存在しないので、もし自信がないという場合はCloudera等のベンダーに相談することをおすすめします。

参考リンク

既出も含めて、参考リンクをまとめておきます。

謝辞

本記事の執筆にあたり、以下の方々にレビューしていただきました。この場を借りてお礼申し上げます。(順不同、敬称略)

自然言語処理ナイト #dllab

dllab.connpass.com

NLPに関するイベントとして目に入ってきたので参加してみました。

業界関係者でも自分がきちんと知っている分野でもなく、純粋に勉強目的で一参加者として勉強会に参加したのは久々でしたが、非常に内容の濃いイベントで面白かったです。主催されたマイクロソフト様と登壇者の皆様、ありがとうございます。

以下、自分の理解の範囲で書いたまとめを記しておきます。

Attention is all you need !!! を入門するまえに!

(Microsoft 得上竜一さん)

Transformer論文 Attention is All You Need を読むための前提知識を紹介したセッション。

arxiv.org

Attention is All You Need の解説記事は日本語でもあります。

deeplearning.hatenablog.com


  • Attentionは、注目したデータに従って出力する仕組み
    • 例: 画像処理
    • 背景が映った画像をそのまま処理すると背景情報を取り込んでしまう
    • Attentionを使うことで人だけに注目することができる
    • 人間は、人間が移ったとき写真について背景を無視することを自然とできるが、それと同じ
    • Convolution を二層に分岐して片方でsigmoidで出力して最後に分岐を合流させる。sigmoidが0に近い値はその後の処理に影響を与えなくなる
  • SENet
    • Convolutionによって複数の出力を得る。縦横のエッジ、色、明るさなど
    • 普通のCNNではこれら全ての特徴を後続の層でも利用する
    • 人間が注目する場合はどこに注目するかはケースバイケース
    • SENetでは画像の特徴をダイナミックに決定するアテンションになる
    • 画像全体に対してAvg. Poolingを取り、Conv(1,1)で特徴をとり最後にSigmoidを取る
    • このような仕組みを各Conv Unit で使えば、少し演算量増える程度で性能を上げることが確認できている
  • 言語処理におけるAttention
    • 典型的な文章分類問題
    • 特定の位置にある単語に注目するようにネットワークを構成することができる
    • 単語の特徴量を得られているとすると、それに対しアテンションを計算し、特徴ベクトルに掛け合わせる
  • 翻訳
    • Encoderで特徴抽出を行い、Decoderで別の言語に書き出していく
    • LSTMでは単語から次の単語への出力を行っていく
    • 契約書などでは単語の対応などの正確性が必要
    • Attentionを用いて、最初に翻訳すべき単語を決める
    • その単語をもとに次のAttentionを決めていく
    • 各単語の特徴とDecoderの初期ベクトルの内積を取る。これがAttentionの初期スコアになる。このスコアにSoftmaxをかけると、それがAttentionのスコアになる
    • 画像のときはSigmoidを使って全てのピクセルで注目するか否かを表現していたが、言語の場合はsoftmaxを使って、周りに比べて注目すべきかどうかを考える
    • どのような翻訳をするのかを出力するQuery vector と Key vector内積をとってsoftmaxにかける
  • Self Attention
    • Query /Key / Value をEncoder / Decoder ではなく同じタイミングで特徴抽出を行う
    • ある単語は文章中の他の単語に依って意味が変わる
    • あなたを「嫌い」では「ない」
    • Self Attentionは他の単語に特徴づける動作をもたせることができる
    • 嫌いというQueryと全ての単語のKeyとの内積を取り、softmaxを出し、Valueとかけたものを現在の単語ベクトルに足す
    • Self Attentionで他の単語を使って自分自身を特徴づけることができる
  • Attention is All You Need
    • Transformerの話
    • RNNの問題点: 一つ前の単語の計算が終わるまで次の単語の計算ができない
    • RNNのレイヤーをSelf AttentionのレイヤーにおきかえるのがTransformer
    • BERT / GPT-2 などもTransformerを使う
    • これで基礎知識はついたのでこの論文を読んでね

生成系NLPの研究動向

(Microsoft 伊藤 駿汰さん)

今回このセッションを聞くために参加しましたが、非常にいい内容でした。

  • 文生成とは
    • 文字: 言語を表記するために使われる記号の最小単位
    • 単語: 文字を組み合わせて作られる、意味を表し構文上の働きを持つ最小単位
    • 文: 単語を組み合わせて作られるまとまりある考え
    • 単語列: 単語を並べたもの。文も単語列の一種
    • 文生成: 単語の数、単語の種類、単語の順番を決定すること
    • 一定の制限を入れないと解けない。次の単語を予測を骨格とした文生成
    • 次単語予測: ある単語列が与えられたとき、次に来る単語を予測すること。例: スマホの予測入力
    • ある単語列が与えられたとき、次にどの単語になるか確率を計算し、最も確率が大きい単語を選ぶ
    • 文生成最初の単語Aを予測し、AからBを予測し、という流れを文が終わるまで繰り返す
  • 文生成モデルの歴史
    • 文生成モデルの歴史は言語モデルの歴史と絡んでいる
    • 言語モデル: ある文wが生じる確率を与える確率分布P(w)のこと
    • P(w)がわかると
      • 複数文で尤度比較ができる
      • 分布からいくらでも文を生成できそう
    • 言語モデル
      • 文を構成する単語の数は可変
      • 1種類の言語には数万程度の単語が存在
    • P(w)の計算は無理
      • 逐次的アプローチで近似する
      • 次に来る単語はそれより前の単語が何かで決まると仮定
    • N-gram言語モデル
      • ある単語より前の単語全部を見るのがつらいので見る数を決めて計算を軽くする
      • 前のN-1個の単語の並びに対し、次にきそうな単語の確率がわかればP(w)が計算できる
      • たくさんのデータから統計的に確率は得られる
      • P(wi|wi+1-N, Wi-1)があれば次単語予測ができて文生成ができる
    • 統計的手法を用いる文生成
      • 現実には5-gram程度が限界
      • Pitman-Yor過程を使って可変長N-Gramなども使われる
      • 現代ではあまり使われていない
    • DNNの学習
      • 入力と正解が必要
      • 予測が正解に近くなるよう学習を進めていく
      • RNN言語モデル(Mikolov 2010)
      • RNN (Rumelhart 1986)
      • P(w)が得られない変わりに、ある単語をいれたとき、次に来る単語の確率を予測させる
      • 入力: 単語、正解: 次の単語
    • RNNの問題点
      • プレーンRNNは遠い過去のデータの情報が急速に消えていくもしくは爆発的に増大していく
      • LSTM( Hochreiter 1997)GRU( Cho 2014) といった手法によって十分学習可能な水準に到達
    • Seq2Seq (Sutskever 2014)
      • 文の意味を取り出すエンコーダーRNN、取り出した意味から文を生成するデコーダーRNNをつなげて、文から文への変換を行うモデル
    • S2S + Attention (Luong 2015)
      • 過去の情報を重み付けして再度利用するAttention機構をSeq2Seqに追加して精度を改善したモデル
    • 生じてきた問題: RNNは過去の情報を処理してからでないと処理できない
    • Transformer (Vaswani 2017)
      • Seq2Seqと同じ文変換を行うモデル
      • 再帰構造を持たないNNとAttentionのみで構成され、高速
      • 翻訳タスクにおいて、RNN系手法よりはるかに少ない学習でSOTA
      • 長期依存を取れない問題を解決
      • 軽量・高速で並列化向きの構造
    • BERT (Devlin 2018)
      • 巨大な12層のTransformer Encoder
      • 2種類の言語モデル的事前学習
        • マスクされた単語の予測
        • 文の連続判定: 2つの文が連続した文であるかどうかの確率値
      • 膨大なデータで事前学習 + 少数のデータで目的タスクに転移学習
      • NLPの幅広いベンチマークでSOTA
      • 少量のデータで学習できるというのが産業利用上非常に大きかった
      • 工夫された事前学習によってTransformerの双方向学習が可能に。言語モデル的事前学習の有効性を示す
    • GPT-2 (Radford 2019)
    • UniLM(Dong 2019)
      • Transformer Prefix LM を使った事前学習モデル
      • 複数種類の言語モデル学習
      • 読解系タスクでBERT並、生成系タスクでSOTA
    • T5 (Raffel 2019)
      • Encoder - Decoder 構造を持つ巨大事前学習モデル(Transformerと同じ)
      • 全てのタスクを文変換として事前学習を行う
    • GPT-3 (Brown 2020)
      • 1750億パラメータの超巨大モデル
      • BERT: 3.4億
      • T5: 110億
      • 構造はGPT-2を踏襲
      • モデルのパラメータを増やすことで少ないデータの転移学習でも性能を出せるようになる
    • トレンドの推移
      • 2018年
        • LSTM→Transformer
        • Transformer改善
        • BERT
      • 2019年
        • BERTの流れを組む巨大事前学習モデル
        • 生成系タスクでGPT-2, T5が台頭
      • 2020年
        • NLPGPUとお金で殴る世界。GPU4000台並べるような世界
        • GPT-3
  • 今後のトレンド予測
    • Self-AttentionなどのTransformerの各要素の有効性についての知見が集積
    • Transformerは精度改善や軽量化の亜種が登場
    • GPT-3の方向性は実用上極めて重要
  • 発表者の研究
    • Memory Attention
    • Seq2Seq に発話に対する応答生成をAttentionを使って選んでいく
    • 研究から得られた知見
      • Attentionとは実質類似度の計算、情報の抽出に利用できる
      • 計算負荷も小さい、大小関係、解釈性
      • Transformerは新しい情報の流れを追加することが難しいが、LSTMベースのSeq2Seqは比較的簡単
      • シンプルなため、実装や構造検討に時間がかからない、とりあえずの実装として価値あり
      • 文生成の自動評価は難しい、対話系生成モデルは自動評価が極めて困難
        • BLEUやMETEOR等もあるけど不適切

NLPソリューション開発の最前線

(ISID 深谷勇次さん、小川雄太郎さん、ファイサルさん)

ISIDが5月にリリースした新製品のアーキテクチャ言語モデルの解説。

isid-industry.jp

  • フロントエンド
    • Azure Blob Storage に静的サイトをデプロイ
    • Vue.js / Nuxt.js フレームワークで静的サイトを構築し、axiosでバックエンドと通信
  • APサーバ
    • Azure VM上でDocker Compose を使ってコンテナ管理
      • ACIはマルチコンテナ運用が困難で、k8sは重たかった
    • Python + Django REST Framework
    • 非同期処理: Celery + RabbitMQ
    • DB: Azure PostgreSQL
    • 運用監視・ログ収集: Azure Log Analytics & Azure Logic Apps
  • MLサービス
    • Azure ML
    • GPU搭載のDSVMをAzure ML に紐付け
    • APサーバからMLサービスを経由しDSVMにPythonファイルと引数を投げて実行
  • 言語モデル
    • ISIDオリジナルALBERTを作った
    • 業務システムに組み込む要件としてGPUリソースのコストとパフォーマンスの問題があったため、高速・小規模なモデルを選定した
  • ALBERT
    • 埋め込み行列の因数分解
    • レイヤーパラメーターの共有
      • 12個のレイヤーで1つのパラメータを使う
    • NSPの代わりにSentence-Order Predictionの新補助タスク
    • LAMB アルゴリズム使用
      • 大きいバッチで学習
    • n-gram マスキング
    • SentencePiece対応
  • ALBERT日本語版はまだ1つしかない
  • ISIDオリジナルALBERT
    • モデル長1024語
    • Sudachiを使用。これはNICTの実験結果により、事前に形態素解析を行ったら良い精度が達成できることがわかっているため
    • Whole Word Masking (WWM) を使う
    • コーパス: Wikipedia日本語
    • トークナイザー: Sudachi モードC + Wordpiece
    • Livedoorニュースでファインチューニング
  • 今後の課題
    • 最長の長さを1024にしたため推論時間に影響がある
    • ナレッジ蒸留手法 DistillBERTなどの検討、Sparse Attentionの使用

Azure ML 自然言語処理の最新動向

(Microsoft 女部田啓太さん)

github.com

  • Classical Text Explainer
    • 古典的な機械学習パイプライン
    • sklearn の線形モデル coefs_
    • Treeベースのアンサンブルモデル feature_importances
    • デフォルト 1-gram BoW + sklern CountVectorizer + LR
  • Unified Information Explainer (Guan 2019)
    • MSのSOTAの研究
    • 相互情報量をベースにした post-hoc のアプローチ
    • DNNの隠れ層についての説明
    • 現在はBERTのみ対応
  • Introspective Rationale Explainer (Yu 2019)
    • MSのEMNLPで発表した研究
    • モデル学習の仕組みに埋め込むタイプ
    • 内省的生成機(Introspective Generator) を前処理で利用
    • 入力テキストを根拠(raitionales) と半根拠(anti-rationales) に分岐
    • 根拠のみを使って精度が最大になるように学習
    • モデルは入力テキストから生成された根拠しかみない

オープンコレクターに入社して3ヶ月が経った

f:id:shiumachi:20200701012420j:plain

Photo by Zoltan Tasi on Unsplash

shiumachi.hatenablog.com

オープンコレクターに入社してからあっという間に3ヶ月が経ちました。

ここでの仕事は、とにかく密度が濃いです。ミーティングは週2-3回ある程度で、余計な割り込みが一切なくひたすら技術に関係する仕事だけに取り組んでいます。

こんなにミーティングがないのはClouderaの最初の1-2年のときくらいかもしれません。


仕事は案件対応をやっています。HadoopNLPなど、自分がClouderaやLuminosoで得た技術をフルに使う仕事をやっています。

二年前、別の分野で一から始めたいと思ってClouderaを飛び出しましたが、結局仕事になるのは自分が培ってきた技術や知識なので、なかなかそこから逃れるのは難しいですね。

shiumachi.hatenablog.com

データ基盤と機械学習/NLPの知識を両方持っているというのはそれなりに希少価値があるはずなので、このあたりを自分の得意分野として伸ばしていければいいかなと考えています。


とはいえ、いざ案件対応すると、今まで習得した自分の知識だけでは全然足りないということを実感します。

ベンダーにいた頃に想定する環境は、いわば理想的なきれいな環境でした。実案件においては、お客様のビジネス要件や様々な制約を伴う環境と直面します。

あるべき論は通用せず、目の前にある様々な条件を考慮した上で課題を解決していく必要が出てきます。

正論の知識だけでは全く通用しない、実戦の技術というものが要求される中で、自分の実力不足を日々痛感しています。


仕事の負荷としては全く高くなく、非常に快適です。

10年ぶりに深夜・早朝のメール・チャット・ミーティングなどに悩まされない生活を過ごしていますが、これは精神衛生上とてもいいです。規則正しい生活になるだけで身体の負担が全く違います。

通勤も全くないので、仕事量の割には疲労が少なく、かなり健全な生活サイクルになっています。


英語を日常的に書かなくなったというのも大きな変化です。

海外とやりとりすることもあるので全くないというわけではないのですが、基本的には日本語だけで仕事ができています。

とはいえ、あまり自分にとってはどちらの言語使ってもそんなに変わらないので体感的にはあまり気になりません。

前回の記事でも書いたように、社長の @moriyoshit をはじめ、オープンコレクターのメンバーは技術力が非常に高く、一緒に仕事して楽しい人達ばかりです。

いい人達と一緒に仕事をするということの方が、言語的な問題よりも大きいとあらためて実感します。

shiumachi.hatenablog.com


自分の実力はまだまだですが、さらに知識と技術を身につけていき、新しい取り組みを色々とこなしていきたいと考えています。

在宅勤務で自宅トレーニングを長く続けるための7つのコツ

2021年版のFreeleticsガイドができました!この記事より新しいので、そちらを参照してください。

shiumachi.hatenablog.com

最近在宅勤務する人が増えてジムが利用禁止になったからか、 AIパーソナルトレーナーアプリのFreeleticsを始める仲間が増えてきました…が、どうも皆さんきついのか長続きしないようです。

6割近くの人がコロナ太りしたというニュースもあり、在宅勤務において継続的な運動は必須の習慣となっています。

www3.nhk.or.jp


そこで、Freeleticsを1年3ヶ月続けた経験から、自宅トレーニングを長く続けるコツをいくつか紹介したいと思います。


f:id:shiumachi:20200609005030p:plain

大原則: 長続きさせることを目的にする!

レーニングが長く続かないのは、「一日でも早く痩せなきゃ」とか、「以前よりももっと高い負荷でやらなきゃ」とか、キツい目的を掲げるから逆に尻込みしてしまうというのも原因の一つです。

まずそういうのを一旦おいて、とにかく長続きさせるということだけ考えてください。重要なのは、「長続きさせれば楽でもいい」ということです。

ちょっとこの辺はFreeleticsの思想と外れますが、重要なのは習慣化であり、習慣化したあとにゆっくり負荷を上げればいいと私は思ってます。

今日スクワット100回やって2日休むよりも、3日間毎日50回やる方が結果的にたくさんの運動を行っています。

習慣化することだけに注力しましょう。

コツ1: 疲れてるときは休むことを恐れない

1つ目の話を踏まえた上で、疲れたらきっちり休むというのを心がけましょう。

オンライン飲み会のあとで寝不足だったり二日酔いだったりするときは無理してやるのをやめましょう。

その代わり、その日のトレーニングは「体調を整えて、早く寝る」ことだと気持ちを切り替えます。

体調を万全に整えた方がやる気が出ます。

コツ2: ブランク明けのトレーニングは軽めに

サボったりするとどうしても今までのトレーニングがきつく感じて、「今日はやめとこう…」と尻ごみしてそのままトレーニングをやめてしまいます。

今までの進捗が後退するのはどうしても抵抗を感じてしまいます。

勇気を出して、しばらくはとにかく軽めなものをやるだけにしましょう。

レーニングを再開したというのはそれだけですごいことです。喜びましょう!

幸い、最新のFreeleticsではその日の強度を変更する機能がついているので、勇気を出して負荷を軽くしましょう。

f:id:shiumachi:20200609003113p:plain

コツ3: ウォーミングアップとクールダウンはサボらない

他の人に話を聞くと、結構みんなカジュアルにウォーミングアップとクールダウンをサボっているので驚きます。

ウォーミングアップとクールダウンは絶対にやりましょう。これやるだけで疲労が全然違うし怪我のリスクも下がります。あとはトレーニングのやる気を出すための儀式的な意味もあります。

f:id:shiumachi:20200609003442p:plain

コツ4: トレーニングウェアを着る

前は普通のTシャツをそのまま使っていたのですが、やっぱりトレーニングウェアを用意した方が気分的な意味でトレーニングをやる気になります。

安いものでいいのであった方がいいでしょう。

コツ5: フィットネスマットを敷く

怪我防止や防音効果も重要ですが、トレーニングウェアと同様、やはり「これからトレーニングをやる」という気持ちを高めるためにもあるに越したことはないです。

自重トレーニングはかなり負荷がかかるので、可能な限り厚めのマットを選んでおくといいでしょう。


コツ6: トレーニング用スマートウォッチをつける(オプション)

それなりの値段がするので「できればあった方がいい」程度ですが、トレーニング中に心拍数を見て運動強度を見たり、心拍数記録から運動状況を把握するのに使うことはできます。

私は Fitbitしか持っていないのですが、Freeleticsのスマートウォッチ連携はApple Watchにしか対応していません。

お金に余裕があるとか、すでにApple Watchを持っているならそれを使うべきですが、「これから運動を始める人のやる気を高める」という目的で進めるにはあまりに高いんですよねApple Watch……。

個人的には、今何もスマートウォッチ持っていないなら、3-5万するApple Watchを買うよりは最安1万弱で変えるFitbitの方がいいと思います。私は上位機種のChargeを使ってますが、それでも1万円台です。

コツ7: 過度な食制限と並行でやらない

運動でつらい思いをしながら、糖質制限とか無茶な食制限をすると、凄まじいストレスがかかります。

ただでさえ自宅から出れなくてストレスが溜まっている状況でこんなことしたらそれだけで心身ともに病気になってしまいます。

食制限しなくても運動だけで6kg痩せたので、食事は気にせず食べた方がいいです。

shiumachi.hatenablog.com

余談ですが、今年に入ってからほぼ自宅から出ていませんしお酒も甘いものも普通に飲み食いしてますが、さらに3kgほど痩せました。

まとめ

レーニングを始めようというときはキツいトレーニングも頑張ろうという気持ちが高くてある程度は出来ますが、それだけでは長続きしません。

とにかく、常に「どうすれば習慣化できるか」「どうすればサボっても復帰できるか」を考えながらやることが重要だと思います。

健康的な在宅ライフを!

Freeleticsの購入方法

Freeleticsは有料のアプリです。年間1万円のサブスクリプションです。
3ヶ月プランや6ヶ月プランもあるので、続ける自信がないという人はこちらを購入してもいいです。14日間は返金に応じてくれるので、試しに買ってみて、合わなかったら返金しましょう。

Freeleticsを始めてみたいという人は、下記のリンクから購入すれば20%オフで買えます。 Coach と Nutrition (食生活改善)の二種類が出てきますが、Nutrition は自分は試していません。運動だけなら Coach で十分と思いますが、誰か Nutrition を試した人がいたら感想教えてください。

https://www.freeletics.com/r/124871187

とびきりのハッカーと同じチームで仕事をすることは福利厚生である

先日、社長の moriyoshi と一緒にある案件を行っていました。
リリース直前の前夜、どうしても現在のライブラリでは技術的に不可能な問題が発覚しました。
入社して一ヶ月も経てば、仕事の場でmoriyoshiがどう動くのか大体わかるようになります。

「じゃあ作るしかないな」
「できそう?」

moriyoshiは答えません。次の答えはもう分かっていたので、私はmoriyoshiが作成しているであろうプラグインを組み込むことを想定したテストコードとそのデプロイ手順を確認します。

私がテストコードとデプロイの準備を整えた頃、moriyoshiはSlackに再び現れました。

「できた」

予想通りの答えでした。私はすぐさまプラグインリポジトリに取り込み、テストを実行し、デプロイ作業を実施しました。

~~~

最近は、特に外資系ではどの会社も様々な福利厚生を用意しています。

Googleランチ育児休暇は有名ですし、マイクロソフト新型コロナウィルスに対応するため全従業員に12週間の有給休暇を付与するなど、世界に名だたる大企業は争うように手厚い福利厚生を提供することで人材の獲得に必死になっています。

しかし、どのような会社も、とびきりのハッカーと同じチームで仕事ができることを福利厚生として提供してはいません。

もちろん、上記の会社には優秀な社員がたくさんいるのは知っていますし、オープンコレクターだって別にそんなことを福利厚生として定義しているわけではありません。

ですが、金銭以外の報酬によって社員のロイヤリティを高めることが福利厚生であるならば、moriyoshiと一緒に仕事することは間違いなく自分が今まで経験した中で最高の福利厚生です。


オープンコレクターは、Joel Spolsky がソフトウェア開発者採用ガイドの中で言うところの、「頭が良く、物事を成し遂げる(p.95)」の集団です。オープンコレクターのメンバーは誰もが高い技術力とチーム同士の協力を惜しまない、本当に優秀なエンジニアの集まりです。

ソフトウェア開発者採用ガイド

ソフトウェア開発者採用ガイド

  • 作者:Joel Spolsky
  • 発売日: 2008/03/20
  • メディア: 単行本(ソフトカバー)

その中でも社長のmoriyoshiは正真正銘のハッカーであり、見栄えのいいパワポ資料を作ったり、世界を変える壮大な夢を描いて万人にそれを語ったりする代わりにコードを書くことで価値を示す、まさに「ハッカーと画家」から飛び出してきたような、とびきりのハッカーです。

一流のハッカーのそばにいて一緒に仕事をしながら学ぶことができるという福利厚生は、どんなにお金を積んでも買えるものではありません。


このような恵まれた環境で働くということに幸せを感じるとともに、いつか自分もそう思われるよう、努力を重ねていきたいと思っています。