colaboratoryで使うdatasetをどこに置いておくのがよいか調べる

前回こんな記事を書いたが、どこに置いておくのが効率よいのか気になったので調べてみた
https://blog.hatena.ne.jp/y-kamiya/jsapachehtml.hatenablog.com/edit?entry=26006613718710543

colaboratoryは起動のたびにまっさらの状態になるためデータセットなどのリソースは永続化可能な別の場所に置いておく必要がある。publicなデータセットを使う場合であっても、ダウンロード速度の問題で自前で用意した場所に置いた方がよい場合もある。

よって以下のような条件を満たす最適な場所を探したい

  • ダウンロードが速い
  • 無料で使える(or なるべく安価で)

ちなみにuploadの計測で使った環境はこちら

  • 場所: 東京
  • アップロード速度: 200Mbps
  • 試したパターン
    • 500MBx1: 1ファイルで500MBの場合
    • 1MBx500: 1MBのファイルが500個ある場合

ダミーデータはこちらで生成

# 500MBx1
cat /dev/urandom | base64 | head -c $((1024*1024*500)) > dummydata500m

# 1MBx500
for i in $(seq 0 499); do bash -c 'cat /dev/urandom | base64 | head -c $((1024*1024))' > dummy/data"$i"; done

参考: https://hacknote.jp/archives/25181/

Google Cloud Storage (GCS)

upload、downloadともに安定して速く、特に複数ファイルであっても並列処理できるため速いことが特徴。ただし、colaboratoryの場合はcpu2つなのでそこまで桁違い速くなるわけではない。

データ形式 upload[sec] download[sec]
500MB x 1 20 11
1MB x 500 25 46

upload, download共に1MBx500の場合は gsutil -m cp として並列にした

また、zip展開にかかる時間はunzipを用いて7sec程度だった(dummyディレクトリ自体をzip化したもので試した)

GCSの永久無料枠
https://cloud.google.com/storage/pricing?hl=ja#cloud-storage-always-free
5GB, 50000回のGETリクエスト、1GBの下り帯域

それ以上使った場合の料金
https://cloud.google.com/storage/pricing?hl=ja#price-tables

オペレーション数については、zipでまとめてやり取りすれば基本的に無料枠に収まると思われるためストレージサイズと通信量次第になる。colaboratoryはgoogle cloud上で動いているため通信量についてはこちらにある料金となる
https://cloud.google.com/storage/pricing?hl=ja#network-buckets

そのため同じリージョンでバケットを作成すれば無料で済むことになるが、割り当てられるインスタンスがリージョン固定とは思えないため複数のリージョンのバケットを用意しておく必要がありそう

一応以下を参考にリージョンを調べようとしたのだがビルド済みバイナリのバケットが削除されているようで簡単にインストールできなかったので別途調べてみることにする

https://qiita.com/kasagon/items/2dd5475ce00f16333a6a

こちらのqiitaにある内容からすると通信時間は同一リージョンか否かで数倍変わっている

仮にリージョンまたぎになった状態で10GBのデータセットを使うとして、毎日1回ダウンロードを実行するなら$0.01 * 10GB * 30日 = $3となる。なので100GBなら$30とそれなりになってくるので大規模のデータセットを使うなら、料金としても通信時間としてもリージョン一致を考えた方がいいかも

ちなみに私の試した環境は以下のようになっていたと考えられる

  • GCS: us-central
  • colaboratory: usのどこか(central以外)

GCSから数GBをダウンロードした結果、GCPの料金の履歴で確認したところ4円が課金されていたため、こちらの料金が適用されていたと思われるため

同じ大陸の別のロケーション間のデータの移動(上記の無料ケースのいずれも当てはまらない場合)

Google Drive

データ形式 upload[sec] download[sec]
500MB x 1 24 7.6
1MB x 500 (推定)250 (推定)480

uploadはwebUI経由で実行したもので、推定となっているのは途中で止めたため。webUIによるuploadは10ファイル毎に分割されるようでprogressが表示されるが、100ファイル上がった時点で十分時間がかかっていたので打ち切ったのだがそこまでで50secだった。
(ちなみにgoogle-backup-and-syncでも500ファイル分uploadを試したが450sec程度かかった)

ダウンロード時間としては最も小さく済んだ。ただし、GCSの項目で書いたようにリージョンが関係しているので、同一リージョンにできるならGCSも同じ時間or小さい時間で済むのではと考えられる。google driveがどこのリージョンで動いているかわからないが、こちらの方が速かった以上同じ大陸内という条件よりはさらに近い位置にあったのではと

driveは15GBまで無料枠が用意されているものの以下に注意

  • この容量はdriveだけのものではない
  • 仮にdriveだけに使ったとしてもcheckpointや出力ファイルの保存にも消費することになる

なのでデータセット自体の大きさは最大でも10GBくらいが限度ではないかと考えられる

ちなみに有料プランはこちら
https://one.google.com/plans

数GBのデータセットで使う用と考えておけばよさそう。とはいえいろいろ実験するための環境というcolaboratoryの用途上、その用途で使う分にはdriveで十分とも言える。

Github

githubはprivateレポジトリが無料で作れるようになったのでデータセットを置いて置く場所として使うこともできそうということで調べる(publicになっているデータセットでも再頒布不可となっているものもあるのでそういうものを自前管理で置いておくにはprivateにする必要がある)

ちなみに計測したuploadはadd, commit, pushの時間込み

また、二段階認証ONであればprivate repositoryへアクセスするためには事前にaccess tokenを発行する必要がある
https://qiita.com/ynaito/items/9171d13f21210da9a5c3#comment-f5a53dc4fc0483990146

LFS

制約

データ形式 upload[sec] download[sec]
500MB x 1 110 30
1MB x 500 160 28

colab上のgitにはlfsが入ってないためこちらのようにinstallが必要

!curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
!sudo apt-get install git-lfs

25secほどかかる

時間としても速いわけではなく制約も厳しいのでそもそもデータセットを置いておくには適さない

Without LFS

差分が関係ないファイルということでlfsで検証していたが、考えてみれば今回の用途ならlfsを使わずにコミットしてあっても問題ないのでこちらも確認してみた

制約

データ形式 upload[sec] download[sec]
1MB x 500 150 20

driveやGCSは使ったことないけどgithubならいつも使ってる、みたいな状況ならひとまずやってみる段階ではありかも、、くらい

colaboratoryへの直アップロード

以下のコードで直にアップロードできる

from google.colab import files
uploaded = files.upload()

ただし大きなファイルはとても時間がかかる(500MBの1ファイルを上げるのに10分経っても終わらなかったため止めた)

まとめ

以下のような基準で使っていくとよさそう

  • 数GBまでのデータセット or 絶対に課金を避ける場合
    • zipとして一つのファイルにまとめておきgoogle driveに置く
  • 数十GBまでの大きさのデータセット
    • zipとして複数個のファイルにまとめておきGCSを活用
    • colaboratoryと同じリージョンがベストだが同じ大陸内のリージョンくらいでもそこまで課金額は大きくならない
      • storageサイズによる課金の方が大きくなるかもなので注意(50GBで100円/month)
  • それ以上の大きさのデータセット
    • zipとして複数個のファイルにまとめておきGCSを活用
    • colaboratoryと同じリージョンになるように工夫

ちなみに、同じリージョンになるように工夫と書いたが具体的な方法はまだ調べられてないのであしからず。ただし、usのどこかにしておくのが良さそうな感じはある。
→こちらに書きました
https://jsapachehtml.hatenablog.com/entry/2021/05/01/122449

いろいろ気にしなくてよいし十分速いという意味で日頃まず使うのはdriveがよさそう。少し大きなデータセットを使う場合やdriveの無料枠におさめるためのファイル削除など管理が面倒になった場合はGCSを使えばよい。

ダウンロード速度の面だけで考えても、大きなデータセットになるほどGCSが有利になっていくはず。gsutilは並列処理可能であるためデータ全体を2つのzipに分けておけば単純計算で5GBのデータを落とす時間で済むことになり(colaboratory上のcpuは2コア)、データセットが大きくなるほど差は顕著になる。