hydraに''(クォーテーション)を消されて深夜にキレそうになった話
はじめに
まず、これを見てください。
svd_layers="'3'"
きっっっしょ!!!!!!
なにこの "'...'" っていう書き方。
クォーテーションサンドイッチかよ。タイプミスかよ。
これを見ただけでちょっと吐き気がする人は、正常な感覚の持ち主です。
でも、これが深夜に僕を救った唯一の「力技」だったんです。
なぜかエラーになる
事の発端は、Hydraで構成管理をしているDeep Learningの実験コードを回そうとしたときのこと。
特定の層だけSVD(特異値分解)を適用したくて、こんなコマンドを叩きました。
# 普通こう書くよね?
python main.py svd_layers="3"
Python側では svd_layers を文字列として受け取り、内部でパースして処理する想定です。
しかし、実行すると謎のエラーで落ちる。
怪しいと思ってコードの冒頭で print(type(svd_layers)) を仕込んでみると……。
<class 'int'>
なんで int になってんの!?
ダブルクォーテーション " で囲ったじゃん! 文字列として渡したじゃん!
GPT敗北、そしてGemini Thinkingへ
「これはHydraの挙動がおかしい」と思い、某GPTに聞いてみるも、要領を得ない回答。
「configの型定義を確認しろ」とか「YAMLを書き直せ」とか、いやそうじゃなくてCLIからサクッと渡したいだけなんだよ……。
そこで、最近「推論能力がGPTを上回った」と噂の Gemini (Thinking mode) に投げてみました。
すると、一瞬で回答が。
Gemini:
「それはシェルが"を解釈して消してしまい、Hydraには裸の3が届いているからです。Hydraは数字を見ると勝手にintに変換します。
文字列として認識させるには、シェル用とPython用のクォーテーションを二重に巻いてください」
Gemini最強!!!
お前がナンバーワンだ。
原因と対策
要するに、こういうことらしいです。
-
コマンド:
svd_layers="3" -
シェル (bash/sh): 「お、
"は引数をまとめる記号だな。中身の3だけ渡したろ!」 -
Hydra: 「
3が来たな。これはどう見ても数字(int)や。intとして処理したろ!」 - Pythonコード: 「えっ、ここ文字列(str)が来るはずなんですけど……エラー!」
シェルとHydraの「余計なお世話」が連鎖した結果でした。
これを回避するための対策が、冒頭のアレです。
# 対策:シェル用に " で囲み、さらにHydra用に ' で囲む
python main.py svd_layers="'3'"
こうすると、シェルが外側の " を剥がしても、Hydraには '3' が届くので、無事に文字列として認識されるというわけです。
結論
hydraとshellのかみ合いが悪かった!ということでした。
yamlファイルでは "'...'" と書いて動いたのにshでshellに書き込む形式にした瞬間にエラーが出たのは、shellがクォーテーションを消し、hydraがそれをそのまま認識したからということでした。
これにて無事解決!!!
おわりに
「svd_layers="'3'"」
見た目は最悪ですが、これで無事にコードが動きました。
Hydraは便利ですが、たまにこういう頑固なところ(厳格な型推論)があって深夜にハマると危険ですね。
みなさんも、Hydraに型を勝手に変えられてキレそうになったら、クォーテーションの重ねがけを試してみてください。
そして困ったときはGeminiに聞きましょう。彼、賢いです。
以上、深夜テンションブログでした。
Discussion