GPU を使用して ML モデルをトレーニングする 2 つのスクリプトがあります。寝る前にスクリプトを開始して、夜間に実行し、朝に結果を確認したいと考えています。
しかし、GPU メモリが限られているため、並列ではなくシリアルで実行したいと考えています。
;でそれを行うことができますpython train_v1.py && python train_v2.py
が、 のトレーニングを開始したとしますtrain_v1
。 トレーニングには長い時間がかかるため、2 番目のスクリプト の実装を開始して完了し、 が終了しtrain_v2.py
たら自動的に実行したいと思いますpython train_v1.py
。
どうすればそれを実現できるでしょうか? ありがとうございます。
答え1
ループを伴わず、他のプロセスがまだ生きているかどうかを確認したり、train_v1.py
通常とは異なる方法で呼び出したりしないアプローチを次に示します。
$ python train_v1.py
^Z
[1]+ Stopped python train_v1.py
$ % && python train_v2.py
は、プロセスの実行中に+を押して、シグナルを送信してスリープ状態にする^Z
ことです。次に、をコマンドとして使用して、シェルに で起動するように指示し、最後に を追加できます。これにより、最初からを実行した場合と同じように動作します。CtrlZtrain_v1.py
SIGTSTP
%
&& python train_v2.py
python train_v1.py && python train_v2.py
の代わりに%
を使用することもできますfg
。同じことです。シェルのこれらの機能について詳しく知りたい場合は、以下を参照してください。bash のマニュアルページの「ジョブ制御」セクション。
編集: キューに追加し続ける方法
jamesdlin がコメントで指摘したように、train_v3.py
たとえば v2 が開始する前に追加するパターンを継続しようとすると、できないことがわかります。
$ % && python train_v2.py
^Z
[1]+ Stopped python train_v1.py
train_v1.py
停止されるのは開始されていないからだけでありtrain_v2.py
、開始されていないものを停止/一時停止/スリープ状態にすることはできません。
$ % && python train_v3.py
結果は同じになる
python train_v1.py && python train_v3.py
は最後に中断されたプロセスに対応するためです。このよう%
に追加する代わりに、履歴を使用する必要があります。v3
$ !! && python train_v3.py
% && python train_v2.py && python train_v3.py
上記のように履歴を展開するか、キーバインド (up など) を使用して最後のコマンドを呼び出して、最後に v3 を追加することができます。
$ % && python train_v2.py && python train_v3.py
これを繰り返すことで、パイプラインにさらに追加することができます。
$ !! && python train_v3.py
% && python train_v2.py && python train_v3.py
^Z
[1]+ Stopped python train_v1.py
$ !! && python train_v4.py
% && python train_v2.py && python train_v3.py && python train_v4.py
答え2
すでに開始している場合は、を使用してそのプロセスが消えるまでポーリングし、2 番目の Python スクリプトを実行することpython train_v1.py
ができます。pgrep
while pgrep -u "$USER" -fx 'python train_v1.py' >/dev/null
do
# sleep for a minute
sleep 60
done
python train_v2.py
と を使用すると-f
、-x
最初の Python スクリプトを起動するために使用された正確なコマンド ラインと一致させることができます。一部のシステムでは、はオプションpgrep
を実装し-q
、それを静かにします ( と同様grep -q
)。つまり、 へのリダイレクトは/dev/null
不要になります。
この-u
オプションは、一致を自分が実行しているコマンド(同じシステム上の友人や他のユーザーのコマンドではない)に制限します。
最初のスクリプトをまだ開始していない場合:
コメントで述べたように、最初のスクリプトの直後に 2 番目のスクリプトを起動することもできます。2 番目のスクリプトが存在しないか、まだ実行準備ができていないという事実は問題ではありません (最初のスクリプトが終了したときに実行準備ができている限り)。
python train_v1.py; python train_v2.py
この方法を実行すると、最初のスクリプトの終了ステータスに関係なく、2 番目のスクリプトが起動します。質問に示されているように、&&
の代わりにを使用する;
ことも機能しますが、2 番目のスクリプトを開始するには、最初のスクリプトが正常に終了する必要があります。
答え3
最初のスクリプトは次のように起動できます。
python train_v1.py; touch finished
次に、存在するかどうかを定期的にチェックするループを作成しますfinished
。
while [ ! -f finished ] ; do
sleep 5
done
python train_v2.py
rm finished
答え4
最初のスクリプトの終了ステータスを知る必要がない場合は、次のようなものをお勧めします。クサラナンダが書いたもの。
終了ステータスを知る必要がある場合(この場合はおそらく必要ありませんが、これを行うソリューションを探している人が他にもいるかもしれません)、状況はより複雑になります。私は小さなLinuxユーティリティpwait
プロセスが終了するまで待機し、その終了ステータスを確認できます。