以下の文章は、DVC(Data Version Control) を使うようになる前に書いた文章です。
いまは、Git LFS からDVC(Data Version Control) に移行した話のように考えていて、submodule の利用をしていません。そのことをご承知のうえ読んでください。
機械学習のためのデータセットは、日に日に規模が大きくなりがちた。
それを単一のgit のリポジトリで管理しようとすると、git lfs を使っても管理しきれなくなってしまう。
そこで、大規模なデータセットを作る際に、git submodule を使おうというのが、この記事の主張だ。
単一のgit lfs のリポジトリで管理しようとすると問題になること。
- 単一のリポジトリのデータ容量が際限なく大きくなる。
- 大規模データセットを構築する小規模なデータセットの構造が見えなくなる。
- 大規模なデータセットでは、コミットログも巨大なものになってしまう。
- 品質を確認しきれた範囲と、作業中で品質を確認できていないものが同一のリポジトリに含まれる状況が生じやすい。
- git clone する際の負荷が際限なく大きくなってしまう。
- 構成する小規模なデータセットのアノテーションを修正したいとしよう。そのときに問題を生じやすい。
- 単一の巨大なリポジトリをgit clone してからでないと、その小規模なデータセットのアノテーションを修正することができない。
- リポジトリが巨大であればあるほど、複数の人で作業をするとconflictを生じやすくなる。
- アノテーションにconflict を生じたときに、どちらのアノテーションが正しいのかを数値データをみて判断することは、ほぼ不可能。
結論
規模の大きな学習用データセットを作る時に、単一のリポジトリにしてはならない。
解決方法
- 子になる小規模データセットをそれぞれのgit のリポジトリにする。
- 親になるリポジトリを作る。
- 親になるリポジトリの中に、個々の小規模データセットを含めるフォルダを仮にsubmodules という名前で作る。
- 親になるリポジトリの中で
cd submodules
とする。 - そこで子になる小規模データセットのリポジトリをsubmoduleとして登録する。
$ git submodule add {追加するgitのリポジトリの指定}
このようにすることで、大規模データセットの構築を小規模データセットのリポジトリの登録に分解することができる。
git submodule のコマンド類
$ git submodule
そのリポジトリにあるsubmodule の一覧とハッシュを表示する。
$ git submodule update
そのリポジトリにあるsubmoduleの設定を submodule を含んでいる側のリポジトリの設定を更新する。
$ git submodule update --remote
submodule の設定を、それぞれのsubmoduleの最新状況を、このリポジトリに取り込む。
利点
- 親のリポジトリの中では、個々の小規模データセットのリポジトリのリポジトリ名とどのコミットを参照するのかを記録するだけになります。
- 親のリポジトリのコミットの履歴が簡単になります。
- 個々の小規模のリポジトリの側では、データを利用可能になるまでの全ての作業をコミットログに含めても問題がありません。利用可能な水準に達していない段階では、親のリポジトリにgit submodule add をしなければよいだけの話です。
- submodule のフォルダの中にバージョン管理されていないファイルがあると、
$ git submodule
で状態を確認すると、バージョンされていない余分なファイルがあると通知してくれます。- そのため、バージョン管理されていないファイルによって挙動が違ってしまうなどの問題をなくすことができます。