shivam2k3 commited on
Commit
3165871
·
1 Parent(s): 9e53c0c

add scripts/run_resume_stage2.sh

Browse files

Resume the GRPO curriculum from stage 2 by pulling the SFT and
stage1 LoRA adapters from the Hub. Used after an HF Spaces /data
wipe so we don't redo SFT and stage1 work that already survived.

Made-with: Cursor

Files changed (1) hide show
  1. scripts/run_resume_stage2.sh +115 -0
scripts/run_resume_stage2.sh ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ # Resume the GRPO curriculum from stage 2.
3
+ #
4
+ # Assumes:
5
+ # - Stages 1 has already been pushed to
6
+ # shivam2k3/opensoc-defender-grpo-stage1_basic
7
+ # - SFT adapter has been pushed to
8
+ # shivam2k3/opensoc-defender-grpo-sft
9
+ #
10
+ # Run this from the project root *after* /data has been wiped and the
11
+ # repo has been re-cloned. Safe to re-run.
12
+ set -euo pipefail
13
+
14
+ # Reuse the install logic from run_full_pipeline.sh by sourcing only
15
+ # steps 1 and 2. We'd rather duplicate a few lines than risk source-ing
16
+ # a script that exits early if SFT adapter is missing.
17
+ echo "[1/6] Installing GPU stack ..."
18
+ pip install -q --upgrade pip setuptools wheel
19
+ pip install -q "future>=1.0.0"
20
+ pip install -q "torch==2.10.0" "torchvision==0.25.0" \
21
+ --index-url https://download.pytorch.org/whl/cu128
22
+ pip install -q "transformers>=4.46,<5"
23
+ pip install -q --no-deps "unsloth @ git+https://github.com/unslothai/unsloth.git"
24
+ pip install -q --no-deps "unsloth_zoo"
25
+ pip install -q --no-deps "trl>=0.18.2,<=0.24.0" peft accelerate bitsandbytes
26
+ pip install -q "datasets>=3.4.1,<4.4.0" tyro tensorboard matplotlib sentencepiece protobuf huggingface_hub
27
+ pip install -q hf_transfer msgspec "torchao>=0.13.0" cut_cross_entropy || true
28
+ pip install -q -r requirements.txt
29
+
30
+ echo "[2/6] Building / verifying datasets ..."
31
+ python -m data.build_holdout
32
+
33
+ echo "[3/6] Skipped (SFT + Stage 1 already on Hub)."
34
+
35
+ echo "[3.5/6] Pulling SFT and Stage 1 adapters from the Hub ..."
36
+ python - <<'PY'
37
+ import os
38
+ from huggingface_hub import snapshot_download
39
+ sft = snapshot_download(
40
+ "shivam2k3/opensoc-defender-grpo-sft",
41
+ local_dir="checkpoints/defender_sft_adapter",
42
+ local_dir_use_symlinks=False,
43
+ )
44
+ print("SFT adapter ->", sft)
45
+ stage1 = snapshot_download(
46
+ "shivam2k3/opensoc-defender-grpo-stage1_basic",
47
+ local_dir="checkpoints/defender_grpo/stage1_basic/adapter",
48
+ local_dir_use_symlinks=False,
49
+ )
50
+ print("Stage 1 adapter ->", stage1)
51
+ PY
52
+
53
+ echo "[4/6] Resuming GRPO from stage 2 (3 remaining stages) ..."
54
+ python -m train.train_grpo \
55
+ --model unsloth/Qwen2.5-3B-Instruct \
56
+ --sft-adapter checkpoints/defender_grpo/stage1_basic/adapter \
57
+ --stages stage2_multi,stage3_mixed,stage4_adversarial \
58
+ --steps-per-stage 200 --num-generations 8 \
59
+ --batch-size 2 --grad-accum 4 --lr 5e-6 \
60
+ --report-to tensorboard \
61
+ --out checkpoints/defender_grpo
62
+
63
+ echo "[5/6] Eval + plots ..."
64
+ python -m eval.eval \
65
+ --baseline unsloth/Qwen2.5-3B-Instruct \
66
+ --trained-adapter checkpoints/defender_grpo/stage4_adversarial/adapter \
67
+ --holdout data/holdout.jsonl --out-dir eval/results
68
+ python -m eval.plot_results --in eval/results/summary.json --out-dir eval/results
69
+ python -m eval.plot_training --grpo-root checkpoints/defender_grpo --out-dir eval/results
70
+
71
+ echo "[6/6] Baking demo data for the Gradio /demo Space ..."
72
+ python -m eval.bake_demo \
73
+ --baseline unsloth/Qwen2.5-3B-Instruct \
74
+ --trained-adapter checkpoints/defender_grpo/stage4_adversarial/adapter \
75
+ --n 50 --out data/demo_examples.json
76
+
77
+ if [ -n "${HF_TOKEN:-}" ] && [ -n "${HF_PUSH_TARGET:-}" ]; then
78
+ echo "[7/7] Uploading artifacts back to ${HF_PUSH_TARGET} ..."
79
+ python - <<'PY'
80
+ import os
81
+ from huggingface_hub import HfApi, upload_folder
82
+ token = os.environ["HF_TOKEN"]
83
+ target = os.environ["HF_PUSH_TARGET"]
84
+ adapter_repo = os.environ.get(
85
+ "HF_ADAPTER_REPO", target.split("/")[0] + "/opensoc-defender-grpo"
86
+ )
87
+ api = HfApi(token=token)
88
+ adapter_dir = "checkpoints/defender_grpo/stage4_adversarial/adapter"
89
+ if os.path.isdir(adapter_dir):
90
+ api.create_repo(adapter_repo, exist_ok=True, private=False)
91
+ upload_folder(repo_id=adapter_repo, folder_path=adapter_dir,
92
+ commit_message="GRPO-trained Qwen2.5-3B-Instruct LoRA defender adapter",
93
+ token=token)
94
+ print(" adapter ->", adapter_repo)
95
+ for p in [
96
+ "data/demo_examples.json",
97
+ "eval/results/summary.json",
98
+ "eval/results/bar_macro_f1.png",
99
+ "eval/results/bar_dismiss_on_malicious.png",
100
+ "eval/results/confusion_baseline_zero_shot.png",
101
+ "eval/results/confusion_opensoc_grpo.png",
102
+ "eval/results/training_curves.png",
103
+ "eval/results/training_kl_loss.png",
104
+ ]:
105
+ if os.path.exists(p):
106
+ api.upload_file(
107
+ path_or_fileobj=p, path_in_repo=p,
108
+ repo_id=target,
109
+ commit_message="trained: refresh " + os.path.basename(p),
110
+ token=token,
111
+ )
112
+ print(" ", p, "->", target)
113
+ print("PIPELINE_DONE")
114
+ PY
115
+ fi