日々精進

新しく学んだことを書き留めていきます

同じ条件で前処理を実行してもアノテーションの順序が変わってしまう問題

原因は前処理の一部に実行の度に結果が変わってしまう部分があったため。random seedは固定していたがそれでもだめなところがあった。

それは、以下のようにglobでファイルを取得している箇所。

for p in Path("/path/to").glob("*"):
  ...

Dockerコンテナにsshでログインしてpythonスクリプトを実行する分には変わらないが、SageMakerからProcessing Jobを起動して前処理をすると何故か取得するファイルの順序が実行の度に変わる。。そうすると、データセットの中のファイルの順序が変わり、学習の再現性が低くなってしまう。

以下のようにsortすると毎回同じ順序でファイルパスを取得出来るようになった。

for p in sorted(Path("/path/to").glob("*")):
  ...

参考:

stackoverflow.com

SageMakerでトレーニングジョブが「AlgorithmError: , exit code: 137」「InternalServerError: We encountered an internal error. Please try again.」エラー

exit code 137の場合、OOMが原因という情報があった。詳細は以下参照。

goody-jp.com

137はSIGKILLによってプロセスがKILLされたことを意味するので、OOM以外が原因の場合もあるが、今回はほぼ同じコードで学習データのみ変更してこのエラーが出たのでOOMが原因と推測した。

もっとメモリの多いインスタンスで再度学習中。学習は時間がかかるのでもう一度回すのがつらい・・ エラー発生したらSlackに通知が飛ぶようにできないのかな。ロジックの不具合でエラーが発生した場合はtry-exceptを使って通知を飛ばすようにしているがインフラレイヤーが原因の場合はどうすればいいのか・・

DataFrameにSeriesをappendするとintがfloatになる

df = DataFrame()
df = df.append(Series({"a": 1}))

のような感じでappendすると、Seriesのa列はint型なのに、append後のdfのa列はfloat型になっている。。

以下によると、DataFrameインスタンスを生成する時に、列を定義してそのdtypeをintにすればいいらしいが、 Seriesを生成するところとDataFrameを生成するところで二重に列を定義しないといけないのがいやだ。。

stackoverflow.com

なので以下のようにSeriesの配列を作ってそれをDataFrameに変換することで対応した。

s = []
s.append(Series({"a": 1})
df = DataFrame(s)

SageMakerで使う、ml.~系インスタンスタイプの上限緩和申請の出し方

mlインスタンスタイプの上限緩和申請は他のサービスクォータの上限緩和申請とやり方が違っていてめんどくさい。。手順は以下。

サポートダッシュボードを表示

https://us-east-1.console.aws.amazon.com/support/home?region=us-east-1#/

Create Caseをクリック

Service limit increaseをクリック

Case detailsに緩和申請の内容を入力

Case descriptionを適当に書いてSubmit

実際緩和されるまで数日かかるのもイヤダ。。なぜ自動化されてないのだろうか。

aws cliでS3からファイルをダウンロードする時、沢山あるファイルをzipにまとめるとダウンロードが30倍速くなった

約15000ファイルの画像データセットを、普通にダウンロードした場合とzipに固めたものをダウンロードした場合でどの程度速度差があるのか計測してみた。

EC2インスタンスはg4dn.2xlarge。

普通にダウンロードした場合:300秒
zipに固めてからダウンロードした場合:10秒

zipを解凍するのにかかった時間は10秒ぐらい。

速さを気にする場合はzipに固めておいてもいいかも。

boto3でS3からファイルをダウンロード・アップロードするのを高速化する

boto3のS3.Client.download_fileメソッドを使って大量のファイルをダウンロードすると、aws cliでダウンロードするよりかなり遅い。

boto3.amazonaws.com

理由はdownload_fileは同期処理なのに対してaws cliはマルチスレッド(ちゃんと調べてないのでマルチプロセスかも)で並列実行しているため。アップロードも同様。

以下を参考に、transfer_managerを使って並列実行するよう実装するとアップロード・ダウンロードが7倍程度早くなった。

stackoverflow.com

PyCharmが重い問題

いつもPyCharmを複数起動しているせいか、非常に重くてイライラしていたが、軽くする方法を見つけたのでメモ。

設定の「Upload changed files automatically to the default server」をAlwaysからNeverに変更するとかなり軽くなった。

手動でファイルをアップロードするのは面倒だけど、まだましかな・・