ノートブックIDEアンチがKaggleで初submitするまで
概要
KaggleではKaggle Notebookとかいうふざけた開発環境がデフォルトになっています。私はノートブック形開発環境アンチです。ここではどうにかノートブックの嫌なところを回避してコンペにコード提出までやろうとした方法を紹介します。ただ、結局はノートブックやKaggleカーネルの仕様に付き合っている部分が多いです。やったこととしては以下です。
- Pythonスクリプトをローカルのエディタで作る
- 複数モジュールを用いる(自作モジュールのimportをする)場合はkaggle側の設定が必要になる
- 動作確認をKaggleのDockerイメージで行う
- 筆者環境がM2 Macなせいで一部できなかった。。
- 作成したPythonスクリプトをkaggleカーネル(スクリプトモード)にコピペして保存、提出
- kaggle API使えばモードとか気にしなくてもいいのかもしれないけど未検証
もちろん、もっといい方法が見つかって試せたら今後アプデするかもしれません。
この記事ではノートブックアンチ話の他にも、そもそもkaggle初心者としてよくわからなかった点もまとめています。
なぜノートブックアンチなのか
オーキド博士が教えてくれたように、ものには使いどきがあります。ノートブックも適切に使えばよいものです。ノートブックが適している用途は個人的には以下だと考えています。
- 分析など、思考の流れを、それを実現したコードや実行結果を含めて説明したいとき
- EDAなどで、一時的に素早くデータの可視化を行いたいとき
上記の用途では、バージョン管理や再利用性よりも、分析実施から結果共有までのスピードや手軽さが重視されるとも言えます。このような場面で、pythonスクリプトで実装、分析結果の説明を別のテキストファイルで、とかやってるとまとめるの大変になるのでノートブック形式が優れています。コンペの解法を説明してくれているノートブックが色々あるけど、あれはいい使い方です。ノートブック形式でなかったら今ほど解法開示文化は発展してないでしょう。
一方、ノートブックのダメな点として、バージョン管理、再利用性、デバッグが終わっています。
- 実態がjson
- CLI環境で編集できやしない
- diffが見れたもんじゃない。リッチなビューワが今後できれば改善される可能性もあるが
- コーディング規約やフォーマッタが効かない
- 機能分割しにくい。リファクタがしにくい
- セルとかいうUIのおかげで1モジュールで完結させるように思考が誘導されがち
- デバッガがない
- VSCodeでインストールライブラリへのF12ができない
また、バックグラウンド実行できない点で訓練や大量推論などの長時間処理には不適切です。
ノートブックとkaggleの相性は悪い
昨今のコンペはめちゃでかいニューラルネットワークをぶん回す戦いになっていると聞いています。また、コンペ中は開発したコードを次々に改造したりハイパーパラメタいじったりといった継続的な変更が発生することが予見されます。それってノートブックの特性とあってないんじゃないかい?昔はそういう戦いではなくてノートブックがあってた時代もあったのがそのままなのかなあ・・・。各種クラウドのAI開発系APIみたいにインスタンスとdockerイメージだけ用意しといて、ユーザ側でストレージとエントリーポイント指定して実行形式にならないですかね。
ノートブックを回避してkaggleで実行、submitしよう
ここからは実際にやったことの紹介ですが、まずkaggle初心者向けに前提条件の話をします。
kaggleコンペでのinput, output
input(訓練データ、テストデータ)はコンペ主催が用意してくれるようです。とりあえず参加するのには自前でデータ集めなくても大丈夫です。コンペによってはさらにデータを追加してもよいルールのこともあり、これが雌雄を決することもあったりするとの噂。
outputは以下のリンクにまとめてくれている通り、2パターンあって、大体Code Competitionのようです。この記事は全体的に参考になりました。
モデル開発にはだいたい訓練ターンと推論ターンがあるわけですが、Code Competitionではinputとしてテストデータ(test.csv)を受け取り、その推論結果を提出データ(submission.csv)として出力するスクリプトを提出すればよい、つまり、推論スクリプトだけ提出でよいです。これは訓練はお好きな環境で、kaggleカーネルの実行制限時間やGPUクォータに関係なく実行できることを意味します。「自前のGPUが用意できた!これでkaggleかつる!」みたいな喜びがたまに聞こえるのはこのためだったのですね。
また、猛者たちが素晴らしいノートブックを公開してくれていますが、あれはみんなに見せるように美しくしてくれているやつです。提出する全てのコードが晒されるわけではないのでどんなコードだろうが提出データが出力されればOKです。
次の節から実際にこのような機能のスクリプトを作っていきます。
pythonスクリプトを作ろう
ローカルPCでpythonスクリプトを好きなように作ります。ただし、importモジュールを複数の階層構造にしない方がよさそうです。
kaggle上の実行ではimport関係があるときは呼び出されるスクリプトのカーネル(ノートブック)を呼び出し元に手動で紐付ける必要があります。その時の紐付けには階層といった概念がなく全部並列になります。詳しい操作は以下を参照ください。
「階層構造にしない方がよさそう」と言っているのは、動作確認してないけどカーネル上のディレクトリ構造をいじってあげればできるかもなあ、という気持ちの表れです。上記記事でlibの中身を見ているように、ファイル自体はカーネル上にあって手の届く範囲にあるのでこの階層構造をいじってあげればいいんじゃないかと。ただ、できたとしてカーネル起動毎に毎回それやるように作るのもなあ。。
また、1カーネル1スクリプト(モジュール)にしかできず、1つ1つモジュールを実行スクリプトに紐付ける必要があるのであまり大量のモジュールを作ると紐付けが大変です。今回は、入力整形、訓練(推論)、モデル保存など後処理、の3モジュールで事足りたのでそこまで酷くなかったですが、今後、モデルクラスとかもっといじりたーいってなると大変そう。
ローカルでのデバッグ、動作確認
お持ちのPCがAppleチップのMacの場合、残念ながらkaggleカーネルと同一の環境での完全な動作確認はできません。なぜならkaggleがarm64アーキテクチャのdockerイメージを用意してくれていないからです。ただ、一部のコードは動きます。それでもよければ、以下の記事を参考に何回か失敗しながらになると思いますがdocker imageをビルドして利用することができます。
rosettaがamd64のエミュレートをしてくれるのですが、全ての命令に対応できるわけではないようです。今回試した中では、torchでの推論はできたけど訓練ができませんでした。
from transformers import AutoTokenizer, AutoModelForSequenceClassification, TrainingArguments # ここまではOK
from transformers import Trainer # この時点でpythonごと終了し`illegal instruction`とだけターミナルに出る
ちなみに、ローカルで動作確認せずとも、スクリプトをkaggleカーネルにコピペしてkaggle環境で動作確認しながら開発すればいいと思うかもしれません。以下の点に注意すれば行けなくもないでしょう。
- 当然デバッガはない
- スクリプトモードでのコンソールがスクロールすると謎に畳まれたり、カーネル自体の起動のログ(?)が混ざって出力されたりして読みにくい
- 以下のスクショがスクリプトモードでのコンソールです。
Cannot read properties of undefined (reading 'status')
あたりはカーネル自体のログです。エラーのスタックトレースがたたまれてて伸ばせるのですが、上下にスクロールして見切れた後に同じ部分に帰ってくるとご丁寧にも畳み直してくれています。今トレース追いかけてたとこなんだけど?
- 以下のスクショがスクリプトモードでのコンソールです。
デバッガがない開発なんてできない筆者は困りましたが、Trainer
さえimportしなければ大丈夫だったのでimportをコメントアウトしてTrainer以外の部分を動作確認しました。今回はそれで事足りたけど、ローカルの動作確認環境がないのは今後の課題です。最悪pyenvでpythonライブラリだけ揃えてよしとしようかな。
kaggleカーネルで動かす
作成したスクリプトをkaggleカーネルで動かします。筆者は今回は手動コピペで済ませてしまいましたが、真面目に継続的に開発するならkaggle APIを使ってpushできるようにした方が手間がかからなそうです。
新規ノートブックはデフォルトでノートブックモードになっているのをスクリプトモードにします。左上のタブメニューから、File > Editor Type > Script でできます。
実行前に前述のimportモジュールやinputデータの紐付けをお忘れなく。
ここで左上のRun Allを押すとそのセッション上で処理を開始し、処理後にセッションが開きっぱなしになります。長時間処理の時は右上のSave Versionから、Save & Runにすればバックグラウンドでカーネル起動して処理、終わったらカーネル停止してくれます。
その他
筆者はChromeブラウザの翻訳機能で英語を自動で日本語に翻訳する設定にして生活しています。しかし、kaggleサイトではこれをしていると頻繁にエラーが発生します。特にノートブックとかデータセットのページは全然だめでした。どういう仕組みかわからないけど。自動で翻訳にしている方はお気をつけください。
おしまい
思ったよりノートブックの残念な部分を回避できてないですね。特にモジュール関係はkaggleカーネルの使用上1スクリプト1カーネルにせざるを得ないのがクソです。あとimportモジュールの更新があった場合、実行スクリプト側での更新ボタンクリックが必要になりそんなん絶対忘れます。kaggle APIを駆使したらCI/CDできるのかな・・・誰か作ってないの・・・? To Be Continued.
参考させてもらった記事の方々、本当にありがとうございます。
読んでくれた皆さん、ありがとうございます。素晴らしいkaggleおよびエンジニアライフにお役立てください。
Discussion