r1cksync commited on
Commit
8d39d55
·
1 Parent(s): 94db88e

fix(colab): silence Qwen max_length FutureWarning, real 120-update training run, validated task IDs

Browse files
colab/train_incident_commander.ipynb CHANGED
@@ -75,9 +75,18 @@
75
  "import os, subprocess, sys, zipfile\n",
76
  "REPO_DIR = '/content/incident-commander'\n",
77
  "\n",
 
 
 
 
 
 
78
  "IC_REPO_URL = os.environ.get('IC_REPO_URL', '')\n",
79
  "if IC_REPO_URL and not os.path.isdir(REPO_DIR):\n",
80
- " subprocess.run(['git','clone','--depth','1', IC_REPO_URL, REPO_DIR], check=True)\n",
 
 
 
81
  "\n",
82
  "if not os.path.isdir(REPO_DIR) and os.path.exists('/content/incident-commander.zip'):\n",
83
  " os.makedirs(REPO_DIR, exist_ok=True)\n",
@@ -92,7 +101,8 @@
92
  "assert os.path.isdir(REPO_DIR), 'No repo present — pick Option A/B/C above.'\n",
93
  "%cd /content/incident-commander\n",
94
  "sys.path.insert(0, '/content/incident-commander')\n",
95
- "sys.path.insert(0, '/content/incident-commander/rl-agent')"
 
96
  ]
97
  },
98
  {
@@ -102,9 +112,14 @@
102
  "source": [
103
  "## 3 · Hugging Face token\n",
104
  "\n",
105
- "`HF_TOKEN` powers (a) actor weight downloads and (b) the Qwen2.5-72B critic over the Inference Providers router. Get one at https://huggingface.co/settings/tokens — **Read** scope is enough for training (add **Write** if you want this notebook to push your trained adapter).\n",
 
 
 
 
 
106
  "\n",
107
- "> **Security:** rotate the two HF tokens that were leaked in earlier chat (`hf_RLF…`, `hf_IBf…`)."
108
  ]
109
  },
110
  {
@@ -115,13 +130,27 @@
115
  "outputs": [],
116
  "source": [
117
  "import os, getpass\n",
 
 
 
 
 
 
 
 
 
 
 
118
  "if not os.environ.get('HF_TOKEN'):\n",
119
  " os.environ['HF_TOKEN'] = getpass.getpass('Paste your HF token (hf_…): ')\n",
 
120
  "os.environ['HUGGING_FACE_HUB_TOKEN'] = os.environ['HF_TOKEN']\n",
121
  "os.environ['INCIDENT_COMMANDER_MOCK'] = 'true'\n",
122
- "from huggingface_hub import login\n",
 
123
  "login(os.environ['HF_TOKEN'], add_to_git_credential=False)\n",
124
- "print('HF login OK')"
 
125
  ]
126
  },
127
  {
@@ -196,30 +225,64 @@
196
  "metadata": {},
197
  "outputs": [],
198
  "source": [
 
 
 
 
 
 
199
  "from colab.train_lib import CFG, train_loop\n",
 
 
 
 
200
  "CFG.update({\n",
201
- " 'total_updates': 40, # bump to 80–120 for the real run\n",
202
- " 'rollouts_per_update': 4,\n",
203
- " 'max_steps_per_ep': 14,\n",
204
- " 'critic_provider': 'hf',\n",
205
- " 'critic_model': 'Qwen/Qwen2.5-72B-Instruct',\n",
206
- " 'lr': 1e-5,\n",
207
- " 'run_name': 'demo01',\n",
 
 
 
 
208
  " 'tasks': [\n",
 
 
 
209
  " 'sim_easy_lambda_throttle_001',\n",
 
210
  " 'sim_med_eb_lambda_016',\n",
 
211
  " 'sim_hard_apigw_chain_001',\n",
 
 
212
  " 'sim_advanced_cascade_users_db_001',\n",
213
  " 'sim_advanced_runbook_trap_postgres_001',\n",
214
  " 'sim_advanced_trolley_orders_db_001',\n",
215
  " 'sim_advanced_saboteur_duel_001',\n",
216
  " 'sim_advanced_slack_redherring_001',\n",
217
- " 'sim_gen_app_leak_checkout_005',\n",
 
218
  " 'sim_gen_db_duel_users_db_003',\n",
219
- " 'sim_gen_redherring_payments_007',\n",
 
 
220
  " 'sim_gen_cascade_payments_db_004',\n",
 
 
 
 
221
  " ],\n",
222
  "})\n",
 
 
 
 
 
 
223
  "log_path = train_loop()\n",
224
  "print('Training log:', log_path)"
225
  ]
@@ -294,7 +357,9 @@
294
  "source": [
295
  "## 9 · Push trained adapter + logs back to Hugging Face\n",
296
  "\n",
297
- "Set `IC_HF_USER` to your HF username before running. Creates (or re-uses) a public model repo `<user>/incident-commander-actor`."
 
 
298
  ]
299
  },
300
  {
@@ -306,22 +371,25 @@
306
  "source": [
307
  "import os, glob\n",
308
  "from huggingface_hub import HfApi, create_repo\n",
309
- "IC_HF_USER = os.environ.get('IC_HF_USER', '')\n",
310
- "if not IC_HF_USER:\n",
311
- " print('Skipping push — set os.environ[\"IC_HF_USER\"] to enable.')\n",
312
- "else:\n",
313
- " api = HfApi()\n",
314
- " repo = f'{IC_HF_USER}/incident-commander-actor'\n",
315
- " create_repo(repo, exist_ok=True, repo_type='model')\n",
316
- " final = sorted(glob.glob('colab/logs/adapter_*_final'))[-1]\n",
317
- " api.upload_folder(folder_path=final, repo_id=repo, repo_type='model',\n",
 
 
318
  " path_in_repo='adapter')\n",
319
- " api.upload_folder(folder_path='colab/logs', repo_id=repo, repo_type='model',\n",
320
- " path_in_repo='logs', allow_patterns=['*.json'])\n",
 
321
  " api.upload_folder(folder_path='rl-agent/replays', repo_id=repo,\n",
322
  " repo_type='model', path_in_repo='replays',\n",
323
  " allow_patterns=['*.html'])\n",
324
- " print(f'Pushed → https://huggingface.co/{repo}')"
325
  ]
326
  },
327
  {
 
75
  "import os, subprocess, sys, zipfile\n",
76
  "REPO_DIR = '/content/incident-commander'\n",
77
  "\n",
78
+ "# Default to the user's HF Space so the notebook works zero-config.\n",
79
+ "# Override either of these env vars to clone from somewhere else.\n",
80
+ "os.environ.setdefault('IC_HF_SPACE', 'sagnik-mukherjee/incodent-commander')\n",
81
+ "# Optional: GitHub mirror — also defaulted to the user's repo.\n",
82
+ "os.environ.setdefault('IC_REPO_URL', 'https://github.com/r1cksync/meta-rl-hack.git')\n",
83
+ "\n",
84
  "IC_REPO_URL = os.environ.get('IC_REPO_URL', '')\n",
85
  "if IC_REPO_URL and not os.path.isdir(REPO_DIR):\n",
86
+ " try:\n",
87
+ " subprocess.run(['git','clone','--depth','1', IC_REPO_URL, REPO_DIR], check=True)\n",
88
+ " except subprocess.CalledProcessError:\n",
89
+ " print(f'GitHub clone failed for {IC_REPO_URL}; will try the HF Space next.')\n",
90
  "\n",
91
  "if not os.path.isdir(REPO_DIR) and os.path.exists('/content/incident-commander.zip'):\n",
92
  " os.makedirs(REPO_DIR, exist_ok=True)\n",
 
101
  "assert os.path.isdir(REPO_DIR), 'No repo present — pick Option A/B/C above.'\n",
102
  "%cd /content/incident-commander\n",
103
  "sys.path.insert(0, '/content/incident-commander')\n",
104
+ "sys.path.insert(0, '/content/incident-commander/rl-agent')\n",
105
+ "print('Repo ready at', REPO_DIR)"
106
  ]
107
  },
108
  {
 
112
  "source": [
113
  "## 3 · Hugging Face token\n",
114
  "\n",
115
+ "`HF_TOKEN` powers (a) actor weight downloads and (b) the Qwen2.5-72B critic over the Inference Providers router.\n",
116
+ "\n",
117
+ "**Two ways to provide it** — the cell below tries them in order:\n",
118
+ "\n",
119
+ "1. **Colab Secret (recommended)** — open the 🔑 icon in Colab's left sidebar → **Add new secret** → name `HF_TOKEN`, paste your `hf_…` token, toggle **Notebook access** on. The cell picks it up automatically with no prompt.\n",
120
+ "2. **Inline `getpass`** — if no secret is set, the cell falls back to a hidden prompt where you paste the token.\n",
121
  "\n",
122
+ "> The token you wanted to use first (`hf_IBf…Mhl`) cannot be checked into this notebook because Hugging Face's pre-receive hook blocks any file that contains a token string. Paste it via secret or `getpass` instead. **Rotate it after this run** — it has been shared in plaintext."
123
  ]
124
  },
125
  {
 
130
  "outputs": [],
131
  "source": [
132
  "import os, getpass\n",
133
+ "\n",
134
+ "# 1) Try Colab's built-in secrets manager (left sidebar → Secrets → add HF_TOKEN).\n",
135
+ "try:\n",
136
+ " from google.colab import userdata # type: ignore\n",
137
+ " _t = userdata.get('HF_TOKEN')\n",
138
+ " if _t:\n",
139
+ " os.environ['HF_TOKEN'] = _t\n",
140
+ "except Exception:\n",
141
+ " pass\n",
142
+ "\n",
143
+ "# 2) Otherwise prompt for it (paste your hf_… token).\n",
144
  "if not os.environ.get('HF_TOKEN'):\n",
145
  " os.environ['HF_TOKEN'] = getpass.getpass('Paste your HF token (hf_…): ')\n",
146
+ "\n",
147
  "os.environ['HUGGING_FACE_HUB_TOKEN'] = os.environ['HF_TOKEN']\n",
148
  "os.environ['INCIDENT_COMMANDER_MOCK'] = 'true'\n",
149
+ "\n",
150
+ "from huggingface_hub import login, whoami\n",
151
  "login(os.environ['HF_TOKEN'], add_to_git_credential=False)\n",
152
+ "me = whoami(token=os.environ['HF_TOKEN'])\n",
153
+ "print(f\"HF login OK as: {me.get('name', me)}\")"
154
  ]
155
  },
156
  {
 
225
  "metadata": {},
226
  "outputs": [],
227
  "source": [
228
+ "import warnings, logging\n",
229
+ "warnings.filterwarnings('ignore', category=FutureWarning, module='transformers')\n",
230
+ "warnings.filterwarnings('ignore', message='.*max_new_tokens.*max_length.*')\n",
231
+ "warnings.filterwarnings('ignore', message='.*attention mask API.*')\n",
232
+ "logging.getLogger('transformers').setLevel(logging.ERROR)\n",
233
+ "\n",
234
  "from colab.train_lib import CFG, train_loop\n",
235
+ "\n",
236
+ "# REAL training run — 120 PPO updates × 6 rollouts/update ≈ 11.5 k transitions\n",
237
+ "# (~70–90 min on a T4, ~25 min on an A100). Bump `rollouts_per_update` and\n",
238
+ "# `total_updates` together if you want even longer.\n",
239
  "CFG.update({\n",
240
+ " 'total_updates': 120,\n",
241
+ " 'rollouts_per_update': 6,\n",
242
+ " 'max_steps_per_ep': 16,\n",
243
+ " 'critic_provider': 'hf',\n",
244
+ " 'critic_model': 'Qwen/Qwen2.5-72B-Instruct',\n",
245
+ " 'lr': 1e-5,\n",
246
+ " 'kl_coef': 0.02,\n",
247
+ " 'clip_eps': 0.20,\n",
248
+ " 'gae_lambda': 0.92,\n",
249
+ " 'checkpoint_every': 20,\n",
250
+ " 'run_name': 'real01',\n",
251
  " 'tasks': [\n",
252
+ " # Mix difficulty + saboteur/Slack templates so the policy sees the\n",
253
+ " # full task distribution every update. All IDs verified against the\n",
254
+ " # rl-agent/scenarios/sim/ tree.\n",
255
  " 'sim_easy_lambda_throttle_001',\n",
256
+ " 'sim_easy_lambda_throttle_010',\n",
257
  " 'sim_med_eb_lambda_016',\n",
258
+ " 'sim_med_eb_lambda_021',\n",
259
  " 'sim_hard_apigw_chain_001',\n",
260
+ " 'sim_hard_ddb_chain_021',\n",
261
+ " 'sim_hard_iam_chain_011',\n",
262
  " 'sim_advanced_cascade_users_db_001',\n",
263
  " 'sim_advanced_runbook_trap_postgres_001',\n",
264
  " 'sim_advanced_trolley_orders_db_001',\n",
265
  " 'sim_advanced_saboteur_duel_001',\n",
266
  " 'sim_advanced_slack_redherring_001',\n",
267
+ " 'sim_gen_app_leak_checkout_007',\n",
268
+ " 'sim_gen_app_leak_payments_019',\n",
269
  " 'sim_gen_db_duel_users_db_003',\n",
270
+ " 'sim_gen_db_duel_orders_db_015',\n",
271
+ " 'sim_gen_redherring_payments_013',\n",
272
+ " 'sim_gen_redherring_auth_001',\n",
273
  " 'sim_gen_cascade_payments_db_004',\n",
274
+ " 'sim_gen_cascade_users_db_023',\n",
275
+ " 'sim_gen_cache_warm_session_cache_004',\n",
276
+ " 'sim_gen_peak_frontend_001',\n",
277
+ " 'sim_gen_restore_payments_db_001',\n",
278
  " ],\n",
279
  "})\n",
280
+ "\n",
281
+ "print(f\"Starting REAL run: {CFG['total_updates']} updates × \"\n",
282
+ " f\"{CFG['rollouts_per_update']} rollouts × \"\n",
283
+ " f\"{CFG['max_steps_per_ep']} steps ≈ \"\n",
284
+ " f\"{CFG['total_updates'] * CFG['rollouts_per_update'] * CFG['max_steps_per_ep']:,} transitions max\")\n",
285
+ "\n",
286
  "log_path = train_loop()\n",
287
  "print('Training log:', log_path)"
288
  ]
 
357
  "source": [
358
  "## 9 · Push trained adapter + logs back to Hugging Face\n",
359
  "\n",
360
+ "Defaults to `IC_HF_USER=sagnik-mukherjee`, so this cell will create / update the public model repo **`sagnik-mukherjee/incident-commander-actor`** with the adapter, replays, and training logs. Override `os.environ['IC_HF_USER']` if you want a different account.\n",
361
+ "\n",
362
+ "> Requires a **Write**-scope HF token. The pre-filled token (`hf_IBf…Mhl`) needs Write to push successfully — if it is Read-only, regenerate one with Write at https://huggingface.co/settings/tokens."
363
  ]
364
  },
365
  {
 
371
  "source": [
372
  "import os, glob\n",
373
  "from huggingface_hub import HfApi, create_repo\n",
374
+ "\n",
375
+ "os.environ.setdefault('IC_HF_USER', 'sagnik-mukherjee')\n",
376
+ "IC_HF_USER = os.environ['IC_HF_USER']\n",
377
+ "\n",
378
+ "api = HfApi(token=os.environ['HF_TOKEN'])\n",
379
+ "repo = f'{IC_HF_USER}/incident-commander-actor'\n",
380
+ "create_repo(repo, exist_ok=True, repo_type='model', token=os.environ['HF_TOKEN'])\n",
381
+ "\n",
382
+ "finals = sorted(glob.glob('colab/logs/adapter_*_final'))\n",
383
+ "if finals:\n",
384
+ " api.upload_folder(folder_path=finals[-1], repo_id=repo, repo_type='model',\n",
385
  " path_in_repo='adapter')\n",
386
+ "api.upload_folder(folder_path='colab/logs', repo_id=repo, repo_type='model',\n",
387
+ " path_in_repo='logs', allow_patterns=['*.json'])\n",
388
+ "if os.path.isdir('rl-agent/replays'):\n",
389
  " api.upload_folder(folder_path='rl-agent/replays', repo_id=repo,\n",
390
  " repo_type='model', path_in_repo='replays',\n",
391
  " allow_patterns=['*.html'])\n",
392
+ "print(f'Pushed → https://huggingface.co/{repo}')"
393
  ]
394
  },
395
  {
colab/train_lib.py CHANGED
@@ -254,6 +254,20 @@ class QwenActor:
254
  self._train_mode = False
255
  self.max_seq_len = max_seq_len
256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  # -----------------------------------------------------
258
  def _format(self, observation: str) -> str:
259
  msgs = [{"role": "system", "content": self.SYSTEM_PROMPT},
 
254
  self._train_mode = False
255
  self.max_seq_len = max_seq_len
256
 
257
+ # Silence the noisy `Both max_new_tokens and max_length seem to have
258
+ # been set` FutureWarning. Qwen ships a default max_length=32768 in
259
+ # its generation_config; we always pass max_new_tokens at call time,
260
+ # so dropping the inherited max_length is correct.
261
+ try:
262
+ self.model.generation_config.max_length = None
263
+ except Exception: # noqa: BLE001
264
+ pass
265
+ import warnings as _w
266
+ _w.filterwarnings("ignore", category=FutureWarning,
267
+ module="transformers")
268
+ _w.filterwarnings("ignore", message=".*max_new_tokens.*max_length.*")
269
+ _w.filterwarnings("ignore", message=".*attention mask API.*")
270
+
271
  # -----------------------------------------------------
272
  def _format(self, observation: str) -> str:
273
  msgs = [{"role": "system", "content": self.SYSTEM_PROMPT},