はじめに

DPO(Direct Preference Optimization)訓練の実験を繰り返す中で、完全自動化されたGPU訓練システムを構築しました。 結果:たった1コマンドで、訓練から検証まで全て自動実行され、16分後には結果が手元に届きます。

従来の問題点

手動オペレーションの煩雑さ

DPO訓練の実験には、多くの手動作業が必要でした:

1. Lambda Labs WebUIでGPUインスタンス起動(3-5分待機)

2. SSH接続

ssh ubuntu@xxx.xxx.xxx.xxx

3. ファイル転送(複数回)

scp train_sft.py ubuntu@xxx.xxx.xxx.xxx:~/workspace/ scp train_dpo.py ubuntu@xxx.xxx.xxx.xxx:~/workspace/ scp verify.py ubuntu@xxx.xxx.xxx.xxx:~/workspace/ scp preference_data.py ubuntu@xxx.xxx.xxx.xxx:~/workspace/

4. 依存パッケージインストール

pip install transformers peft trl accelerate sentencepiece

5. 訓練実行(ターミナルを開きっぱなし)

python3 train_sft.py python3 train_dpo.py python3 verify.py

6. 結果ファイル取得

scp ubuntu@xxx.xxx.xxx.xxx:~/workspace/*.log ./ scp ubuntu@xxx.xxx.xxx.xxx:~/workspace/*_results.txt ./

7. インスタンス終了(WebUI操作)

問題点:
  • ❌ 手動オペレーションが10ステップ以上
  • ❌ 待ち時間が多い(起動待ち、訓練待ち)
  • ❌ ターミナルを開きっぱなし
  • ❌ インスタンスの終了忘れでコスト増
  • ❌ 実験の再現性が低い

解決策:lambda_auto_train.py

完全自動化された訓練パイプライン

python3 ~/lambda_auto_train.py \
    --instance-type gpu_1x_a100_sxm4 \
    --region us-east-1 \
    --project-name trial19 \
    --files train_trial19_sft.py train_trial19_dpo_beta005.py \
           verify_trial19.py preference_data_ja_callcenter_50pairs.py \
    --command "pip install -q 'transformers==4.44.0' 'peft==0.13.0' 'trl==0.9.6' 'accelerate==0.34.0' sentencepiece && \
               cd workspace && \
               python3 train_trial19_sft.py 2>&1 | tee trial19_sft.log && \
               python3 train_trial19_dpo_beta005.py 2>&1 | tee trial19_dpo.log && \
               python3 verify_trial19.py 2>&1 | tee trial19_verify.log"
たったこれだけ!

自動化の詳細

1. インスタンス起動(自動)

[INFO] インスタンス起動
インスタンスタイプ: gpu_1x_a100_sxm4
リージョン: us-east-1
料金チェック: $1.29/時間 ✅

✅ インスタンス起動成功: 1eeabe868cd8429cbdf98daa05f10f9a

自動で実行:
  • Lambda Labs APIでGPUインスタンス起動
  • 料金制限チェック(デフォルト$2.00/時間以下のみ)
  • インスタンスID取得

2. 起動完了待機(自動)

⏳ インスタンス起動待機中(最大10分)...
.............................................
✅ インスタンス起動完了: 150.136.90.145
自動で実行:
  • インスタンスのステータス監視
  • IP割り当て確認
  • 最大10分間のポーリング

3. SSH接続待機(自動)

⏳ SSH接続待機中(150.136.90.145、最大6分)...
✅ SSH接続成功
自動で実行:
  • SSH接続の可用性確認
  • リトライ機能(最大3回)
  • 最大6分間の待機

4. 環境セットアップ(自動)

⚙️  環境セットアップ中...
✅ 環境セットアップ完了(Keras 3無効化済み)
自動で実行:
  • 依存パッケージインストール
  • Keras 3の無効化(transformersとの競合回避)

5. ファイル転送(自動)

📤 ファイル転送中...
  - train_trial19_sft.py
  - train_trial19_dpo_beta005.py
  - verify_trial19.py
  - preference_data_ja_callcenter_50pairs.py
✅ ファイル転送完了(4ファイル)
自動で実行:
  • scp経由でファイル転送
  • リトライ機能(最大3回)
  • タイムアウト設定(5分)

6. 訓練実行(自動)

🚀 訓練開始(tmuxセッション: trial19_train)...
✅ 訓練開始成功

👀 訓練監視中... ⏱️ 経過時間: 0.1分 ⏱️ 経過時間: 1.1分 ⏱️ 経過時間: 2.2分 ... ⏱️ 経過時間: 15.9分 ✅ 訓練完了(所要時間: 15.9分)

自動で実行:
  • tmuxセッションで訓練実行
  • SSH切断してもバックグラウンド継続
  • 進捗監視(10分ごとに状況確認)
  • 完了検出(tmuxセッションの終了監視)

7. 結果取得(自動)

📥 結果取得中...
  📄 ログファイルと結果ファイル取得中...
  ✅ trial19_sft.log
  ✅ trial19_dpo.log
  ✅ trial19_verify.log
  ✅ trial19_generation_results.txt
✅ 結果取得完了(4ファイル)
自動で実行:
  • ログファイル取得(*.log)
  • 結果ファイル取得(*.txt)
  • リトライ機能(最大3回)
  • 部分的失敗許容(一部取得失敗でも続行)

8. インスタンス終了(自動)

🛑 インスタンス終了中: 1eeabe868cd8429cbdf98daa05f10f9a
✅ インスタンス終了成功

============================================================ 🎉 全自動訓練完了! ============================================================

自動で実行:
  • Lambda Labs APIでインスタンス終了
  • リトライ機能(最大3回)
  • 料金の節約(訓練完了後すぐに終了)

実際の使用例:Trial 19

実行コマンド

python3 ~/lambda_auto_train.py \
    --instance-type gpu_1x_a100_sxm4 \
    --region us-east-1 \
    --max-price 2.0 \
    --project-name trial19_with_results \
    --files train_trial19_sft.py train_trial19_dpo_beta005.py \
           train_trial19_dpo_beta003.py train_trial19_dpo_beta001.py \
           test_trial19_actual_generation.py preference_data_ja_callcenter_50pairs.py \
    --command "pip install -q 'transformers==4.44.0' 'peft==0.13.0' 'trl==0.9.6' 'accelerate==0.34.0' sentencepiece && \
               cd workspace && \
               python3 train_trial19_sft.py 2>&1 | tee trial19_sft.log && \
               python3 train_trial19_dpo_beta005.py 2>&1 | tee trial19_dpo_beta005.log && \
               python3 train_trial19_dpo_beta003.py 2>&1 | tee trial19_dpo_beta003.log && \
               python3 train_trial19_dpo_beta001.py 2>&1 | tee trial19_dpo_beta001.log && \
               python3 test_trial19_actual_generation.py 2>&1 | tee trial19_generation.log" \
    --output-dir trial19_with_results_output

実行結果

| 項目 | 結果 | |------|------| | 所要時間 | 15.9分 | | コスト | $0.49 | | GPU | gpu_1x_a100_sxm4 ($1.29/時間) | | 実行内容 | SFT訓練 + 3×DPO訓練 + 未知質問テスト | | 取得ファイル | 7ファイル(ログ6個、結果1個) |

内訳:
  • インスタンス起動: 4.1分
  • 環境セットアップ: 0.2分
  • ファイル転送: 0.6分
  • 訓練実行: 15.9分
  • 結果取得: 0.2分
  • インスタンス終了: 0.1分
  • 合計: 22.7分(うち訓練15.9分)
コスト計算:
  • $1.29/時間 × 22.7分 ≈ $0.49

技術的な工夫

1. tmux セッション管理

なぜtmux?
  • SSH切断してもバックグラウンドで継続
  • リアルタイムで出力取得可能
  • セッション監視で完了検出
実装:

tmuxセッションで訓練開始

ssh ubuntu@ip "tmux new-session -d -s train_session 'cd workspace && python3 train.py'"

進捗監視(10分ごと)

while session_exists: output = ssh ubuntu@ip "tmux capture-pane -t train_session -p | tail -20" print(output) time.sleep(600) # 10分待機

完了検出

if not session_exists: print("訓練完了")

2. リトライ機能

失敗時の自動リトライ:
  • ファイル転送失敗 → 3回リトライ(5秒間隔)
  • 結果取得失敗 → 3回リトライ(3秒間隔)
  • インスタンス終了失敗 → 3回リトライ(5秒間隔)
実装:
def retry_operation(func, max_retries=3, delay=5):
    for attempt in range(max_retries):
        try:
            return func()
        except Exception as e:
            if attempt < max_retries - 1:
                print(f"失敗(試行 {attempt+1}/{max_retries})")
                time.sleep(delay)
            else:
                raise e

3. 料金制限

高額インスタンスの誤起動を防止:

デフォルト$2.00/時間以下のみ

if instance_price > max_price: raise Exception(f"料金超過: ${instance_price}/時間 > ${max_price}/時間")
利用可能なインスタンス($2.00以下):
  • gpu_1x_rtx6000: $0.50/時間
  • gpu_1x_a10: $0.75/時間
  • gpu_1x_a6000: $0.80/時間
  • gpu_1x_a100: $1.29/時間
  • gpu_1x_a100_sxm4: $1.29/時間
  • gpu_1x_gh200: $1.49/時間

4. 部分的失敗許容

重要なファイルが取得できれば続行:

ログファイル取得

try: get_logs() # ✅ 成功 except: print("警告: ログ取得失敗")

結果ファイル取得

try: get_results() # ❌ 失敗(ファイルなし) except: print("警告: 結果ファイル取得失敗")

重要なファイルが取得できたので続行

terminate_instance() # ✅ 続行

なぜLoRAアダプターをアップロードしないのか

毎回訓練する理由

Question: LoRAアダプターを保存して使い回せば、さらに速くなるのでは?
Answer: 訓練が十分速いので、シンプルさを優先しています。

| 方法 | 所要時間 | メリット | デメリット | |------|---------|---------|----------| | 毎回訓練 | 8分 | シンプル、再現性高い | - | | アダプター使い回し | 3分 | 速い | 複雑、管理コスト |

Trial 19の場合:
  • SFT訓練: 5分
  • DPO訓練: 3分
  • 合計: 8分
アダプター使い回しの場合:
  • アダプター転送: 1分(6MB)
  • 推論のみ: 2分
  • 合計: 3分
差分: たった5分 判断: 5分の差なら、シンプルさと再現性を優先

アダプター使い回しが有効なケース

以下の場合は、アダプターを保存して使い回すべき:

1. 本番環境のAPI(推論のみ、訓練不要) 2. 大規模モデル(70B+)(訓練に数時間かかる) 3. 頻繁な推論テスト(同じモデルで複数回テスト)

実験の効率化

Before(手動オペレーション)

所要時間: 30-40分(手動作業10分 + 訓練20分 + 待機10分) 手間: 10ステップ以上の手動操作 リスク: インスタンスの終了忘れ

After(完全自動化)

所要時間: 16分(訓練のみ、手動作業0分) 手間: 1コマンドのみ リスク: 自動終了でリスクゼロ

効率改善

  • 時間: 30-40分 → 16分(50%削減
  • 手間: 10ステップ → 1コマンド(90%削減
  • コスト: 不定(終了忘れ) → $0.49(確定

実験の再現性

完全な自動化による再現性

同じコマンドを実行すれば、必ず同じ結果:

Trial 19を完全再現

python3 ~/lambda_auto_train.py \ --instance-type gpu_1x_a100_sxm4 \ --region us-east-1 \ --project-name trial19_replication \ --files train_trial19_sft.py train_trial19_dpo_beta005.py verify_trial19.py preference_data_ja_callcenter_50pairs.py \ --command "pip install -q 'transformers==4.44.0' 'peft==0.13.0' 'trl==0.9.6' 'accelerate==0.34.0' sentencepiece && cd workspace && python3 train_trial19_sft.py && python3 train_trial19_dpo_beta005.py && python3 verify_trial19.py"
保証される要素:
  • ✅ 同じGPU
  • ✅ 同じパッケージバージョン
  • ✅ 同じ訓練スクリプト
  • ✅ 同じデータセット
  • ✅ 同じハイパーパラメータ

まとめ

達成したこと

1. ✅ 1コマンドで全自動(起動→訓練→取得→終了) 2. ✅ 16分で完結(SFT + DPO + 検証) 3. ✅ コスト最適化($0.49、自動終了) 4. ✅ 完全な再現性(同じコマンド = 同じ結果) 5. ✅ ターミナル不要(バックグラウンド実行)

技術的な工夫

1. tmuxセッション管理(SSH切断でも継続) 2. リトライ機能(失敗時の自動リトライ) 3. 料金制限(高額インスタンスの誤起動防止) 4. 部分的失敗許容(重要なファイルが取得できれば続行)

実験の効率化

| 項目 | Before | After | 改善 | |------|--------|-------|------| | 所要時間 | 30-40分 | 16分 | 50%削減 | | 手動作業 | 10ステップ | 1コマンド | 90%削減 | | コスト | 不定 | $0.49 | 確定 | | 再現性 | 低い | 高い | 完全 |

今後の展開

1. 他のTrialへの適用(Trial 20、Trial 21...) 2. さらなる自動化(結果分析、ブログ投稿) 3. マルチGPU対応(分散訓練) 4. コスト最適化(スポットインスタンス)

関連記事

--- 自動化スクリプト: ~/lambda_auto_train.py ドキュメント: ~/LAMBDA_AUTO_TRAIN_README.md Lambda Labs API: https://cloud.lambdalabs.com/api/v1/docs