colaboratoryとGCSのregionを一致させる

https://jsapachehtml.hatenablog.com/entry/2021/04/25/142900
こちらの書いたことの補足として調べたことをメモ

サーバの位置を割り出すipinfo.ioを参照するのが簡単そうだった。
モダンなIPアドレス表示サービス「ipinfo.io」 - ソフトアンテナブログ

colabでも curl するだけでわかりやすく表示されるためよい

https://colab.research.google.com/notebooks/empty.ipynb
こちらから使い捨てのcolab notebookを2つ開いて位置を確認してみた

!curl ipinfo.io
{
  "ip": "35.238.215.102",
  "hostname": "102.215.238.35.bc.googleusercontent.com",
  "city": "Council Bluffs",
  "region": "Iowa",
  "country": "US",
  "loc": "41.2619,-95.8608",
  "org": "AS15169 Google LLC",
  "postal": "51502",
  "timezone": "America/Chicago",
  "readme": "https://ipinfo.io/missingauth"
}
!curl ipinfo.io
{
  "ip": "35.186.165.109",
  "hostname": "109.165.186.35.bc.googleusercontent.com",
  "city": "Washington",
  "region": "Washington, D.C.",
  "country": "US",
  "loc": "38.8951,-77.0364",
  "org": "AS15169 Google LLC",
  "postal": "20045",
  "timezone": "America/New_York",
  "readme": "https://ipinfo.io/missingauth"
}

アイオワとワシントンだった

ちなみに何度か試してみたところ上記以外のregionも出てきたが、us以外から割り当てられたことはなかった。ただし、この部分は各地域のインスタンス稼働率に依ってくると思うのでasiaが出てくることがないとは言えない

gcpのregionのリストはこちら
https://cloud.google.com/compute/docs/regions-zones?hl=ja#available

アイオワgcpのregionとしてあるのでわかりやすくus-central1、ワシントンというregionはgcpにはないものの、地図で調べればバージニア州のすぐ東隣なのでus-east4であろうことが推測できる

ちょうどus-centralにバケットを作ってあり2.5GBのzipファイルを上げてあったのでそれぞれ一回ずつgsutilでダウンロードしてみた結果がこちら

# アイオワ
[1 files][  2.5 GiB/  2.5 GiB]   45.4 MiB/s  
# ワシントン
[1 files][  2.5 GiB/  2.5 GiB]   51.8 MiB/s 

ほぼ同じ速度だった。当然ネットワーク環境に応じてブレがあるはずなので一回だけでは確かなことは何も言えないものの、同一であれば桁違いに速いとかではなさそう

この日はこれしかgcsにアクセスしなかったので後日課金額を調べてみたところ2.7円くらいとなっていた。おそらくこちらの料金体系だろうと考えていたのと一致する
https://cloud.google.com/storage/pricing?hl=ja#network-buckets

アイオワは同一regionなので無料、ワシントンはregion違いだが同一大陸なので$0.01/GBが課金されたと考えられる

ということで

  • ipinfo.ioで位置を調べることでregionを特定することができる
  • 同一regionだからといって桁違いに速いわけではなさそう
  • 同一regionのインスタンスを使うことでgcsからのネットワーク料金を無料にできる

巨大なデータセットを使いたい場合(とはいってもcolabの場合は最大でもストレージが225GBだが)は同一のインスタンスに合わせて使うことでネットワーク料金を節約できる。

また、無料の範囲で活用する場合でもgoogle driveの容量を空けるのに役立ちそう。driveに5GB弱のデータセットを置いておくと他のものを置く余地が減って出力ファイルの整理を頻繁にやる必要が出てくるので意外と面倒。gcsのalways free分(5GB)を移すことでdriveの容量を空けられるのはなかなかありがたい。

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コア)、データセットが大きくなるほど差は顕著になる。

google colaboratoryでGCSからデータ取得

gcsとデータをやり取りする場合、gcloudを入れて初期設定をしてから付属のgsutilを使うという流れでやっていたが、実はgcloudは入れなくてもよいことに気づいたのでメモ

gsutilの公式のインストール方法として、Pythonパッケージからのインストールという項目がある
https://cloud.google.com/storage/docs/gsutil_install?hl=ja#alt-install

試験運転中と書かれており最近追加された方法のようだがcolabであればこれが一番楽。python系のツールはもともと入っているため以下のコマンドのみでOK

!pip install gsutil
!gsutil config

あとはoauthの認証が走るのでwebからtokenをコピペするのと、アクセスしたいgcpのproject idを入力するだけ

これで使える