新しいワークステーションで研究コードを再現する方法

新しいワークステーションで研究コードを再現する方法

公開されている研究リポジトリでも、そのまま動くとは限りません。論文にはアルゴリズムが十分に書かれていても、実際の実行環境は研究室メンバーのシェル履歴にしか残っていないことがあります。特定の commit、記録されていない引数、ベンダー SDK、ドライバーの版、暗黙のデータ構造などです。

最初から全体を再構築するより、判断に必要な一工程だけを選び、入力を固定し、小さな再現パケットを作る方が早いことが多いです。何が動き、どこで止まり、次へ進む価値があるかを明確にします。

一つの工程と一つの観測可能な結果を決める

「リポジトリを再現する」では広すぎます。例えば次のように定義します。

REVISION で、利用権限のあるサンプルに対して scripts/make_plot.py を実行し、空でない PNG と終了コード 0 を得る。

結果は、既知のスキーマを持つ表、通過するテスト、特定の出力に結び付いたログでも構いません。環境を変更する前に成功条件を決め、対象外も明記します。可視化スクリプトの成功は取得ハードウェアの検証ではなく、前処理の成功は論文の最終指標の再現でもありません。

デバッグ前にソースを固定する

mkdir -p repro/environment repro/output
git rev-parse --verify HEAD > repro/environment/git-commit.txt
git status --short > repro/environment/git-status.txt
git submodule status --recursive > repro/environment/git-submodules.txt

`git rev-parse --verify` はリビジョンを具体的なオブジェクト ID に解決します。作業ツリーの状態も同じくらい重要です。clean な commit と、ローカルパッチが三つ乗った commit は別の入力です。

リリースや環境ロックがない場合、新しく作ったものを上流由来のように扱わないでください。互換性修正は分離し、変更をすべて記録します。

秘密情報を含めずにマシンを記録する

python -VV > repro/environment/python.txt 2>&1
python -m platform > repro/environment/platform.txt
python -m pip --version > repro/environment/pip.txt
python -m pip freeze --all > repro/environment/packages.txt

if command -v nvidia-smi >/dev/null 2>&1; then
  nvidia-smi --query-gpu=name,driver_version --format=csv,noheader > repro/environment/gpu.txt
fi

Python の `platform` はシステムとインタープリターの概要を取得できます。`pip freeze` はインストール済みパッケージの記録であり、完全な lockfile や依存関係ソルバーの結果ではありません。

GPU コードでは GPU、ドライバー、拡張のビルドに使った toolkit、フレームワークから見える CUDA runtime を記録します。NVIDIA の CUDA compatibility guide を見ると、「CUDA 12」だけでは条件を特定できない理由が分かります。

共有前に、ユーザー名、ホスト名、非公開パス、トークン、ネットワークアドレス、ライセンス情報、デバイスのシリアル番号を点検して除いてください。

データを移す前に入力契約を書く

依存関係の問題に見える失敗が、実は入力形状の違いということは珍しくありません。最低限、次を記録します。

  • ファイル形式、配列キー、表の列;
  • 次元、dtype、単位、順序、座標規約;
  • 値域と欠損値の扱い;
  • テスト fixture の SHA-256;
  • 合成、公開、許諾済み、または非公開提供のどれか。

顧客や研究室のデータを公開パケットに入れないでください。小さな合成 fixture はファイルとインターフェースの経路確認には使えますが、実験との科学的同等性は証明しません。

プロジェクト自身の環境手順を優先する

リポジトリに lockfile、環境 YAML、コンテナ定義、正確なインストールスクリプトがあるなら、まずその手順と版を保存します。

コンテナを使う場合は、タグだけでなく image digest も記録します。Docker の `image pull` にある通り、digest は不変の一版を固定しますが、タグは後から移動します。

ロックがない場合は clean な環境を作り、コマンド履歴を残します。原因が分かる前にグローバル Python を更新したり、システム CUDA を入れ替えたり、無関係なパッケージチャネルを追加したりしない方が安全です。

最初の実エラーを残す

set +e
python -u scripts/make_plot.py --input sample/input.npz --output repro/output/result.png > repro/output/run.log 2>&1
run_status=$?
set -e
echo "$run_status" > repro/output/exit-code.txt

最初の失敗ログを、最後の成功ログで上書きしないでください。不足している共有ライブラリ、予期しないキー、shape の不一致、未対応のデバイス機能など、最も重要な情報がそこに残ります。

各修正では、観測したエラー、最小の変更、変更理由、次の実行結果の四点を記録します。「いろいろ入れたら動いた」を、他の人が検証できる経路に変えられます。

パケットをハッシュし、判断する

環境、入力契約、ログ、出力、失敗台帳、レポートを一緒に保存します。選んだ fixture、スクリプト、ログ、出力には SHA-256 を付けます。Python の `hashlib` は対応する全ビルドで SHA-256 を提供し、Linux なら sha256sum でも十分です。

ハッシュは科学的な正しさを証明しません。レポートがどのバイト列を指すかを固定します。

最後は曖昧な「成功」ではなく、次のいずれかで終えます。

  • GO: 記録した環境で指定工程が完了し、合意した結果を生成した。
  • GO WITH LIMITS: 記録した修正後に完了したが、移植性やデータ仮定に制限が残る。
  • NO-GO: 依存関係、入力、ライセンス、ハードウェア要件、または受け入れ条件で停止した。

範囲の明確な NO-GO にも価値があります。次の層で数日を浪費する前に、必要な変更を示せるからです。

OpenHI の具体例

この方法で、イベントベースのハイパースペクトル画像プロジェクト OpenHI の公開工程を一つ試しました。リビジョン 080ad074… の weighted-cumulative 可視化スクリプトは、4,096 イベントの決定的な合成 fixture を使って headless 実行を完了しました。パケットには Python 3.10.13、NumPy 2.2.6、Matplotlib 3.10.9、正確なコマンドとログ、120 個の time bin、生成 PNG、入出力ハッシュが含まれます。

判定は意図的に狭くしています。対象のファイル、インターフェース、可視化経路には GO。取得、学習済み補償、較正、再構成精度、ハードウェア互換性、論文の科学的結果については証拠になりません。

同じ形式を使う前に、完全な OpenHI software-stage sample を確認できます。

既存ワークステーション上の OpenHI 一工程について判断したい場合は、まずメタデータだけの fit checkから始められます。任意の固定 USD 500 sprint では、合意した一工程と許諾済みデータ一式に対して、同じ環境記録、コマンド、出力、失敗台帳、go/no-go を作成します。ハードウェアと新規の科学開発は別扱いです。

順序は単純です。工程を決め、ソースを固定し、入力を記述し、環境を記録し、最初の失敗を残し、証拠から判断します。

Leave a Reply