Add kaggle/train_grpo.py
Browse files- kaggle/train_grpo.py +125 -26
kaggle/train_grpo.py
CHANGED
|
@@ -22,18 +22,39 @@ import traceback
|
|
| 22 |
from pathlib import Path
|
| 23 |
from typing import Any, Callable
|
| 24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
# ---------------------------------------------------------------------------
|
| 26 |
# Bootstrap package (notebook may only download this file)
|
| 27 |
# ---------------------------------------------------------------------------
|
| 28 |
|
| 29 |
|
| 30 |
def _ensure_package() -> None:
|
|
|
|
| 31 |
try:
|
| 32 |
import deepagents_rl # noqa: F401
|
| 33 |
|
|
|
|
| 34 |
return
|
| 35 |
except ImportError:
|
| 36 |
-
|
| 37 |
|
| 38 |
token = os.environ.get("HF_TOKEN")
|
| 39 |
if not token:
|
|
@@ -55,6 +76,8 @@ def _ensure_package() -> None:
|
|
| 55 |
sys.path.insert(0, str(pkg_parent))
|
| 56 |
import deepagents_rl # noqa: F401
|
| 57 |
|
|
|
|
|
|
|
| 58 |
|
| 59 |
# ---------------------------------------------------------------------------
|
| 60 |
# Secrets
|
|
@@ -62,6 +85,7 @@ def _ensure_package() -> None:
|
|
| 62 |
|
| 63 |
|
| 64 |
def load_secrets() -> None:
|
|
|
|
| 65 |
try:
|
| 66 |
from kaggle_secrets import UserSecretsClient
|
| 67 |
|
|
@@ -123,6 +147,13 @@ def load_secrets() -> None:
|
|
| 123 |
os.environ.setdefault("WANDB_PROJECT", "deepagents-rl-coding")
|
| 124 |
os.environ.setdefault("HF_HUB_ENABLE_HF_TRANSFER", "0")
|
| 125 |
os.environ.setdefault("TRL_EXPERIMENTAL_SILENCE", "1")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
|
| 127 |
|
| 128 |
# ---------------------------------------------------------------------------
|
|
@@ -217,12 +248,16 @@ def run_heldout_agent_eval(
|
|
| 217 |
|
| 218 |
rows = []
|
| 219 |
model.eval()
|
| 220 |
-
|
|
|
|
| 221 |
env = DeepAgentSWEEnv()
|
|
|
|
|
|
|
| 222 |
try:
|
| 223 |
env.reset(**{k: v for k, v in p.items() if k != "prompt"})
|
| 224 |
tools = _env_tool_callables(env)
|
| 225 |
tool_map = {t.__name__: t for t in tools}
|
|
|
|
| 226 |
prompt = p.get("prompt")
|
| 227 |
if isinstance(prompt, list):
|
| 228 |
messages = list(prompt)
|
|
@@ -232,6 +267,7 @@ def run_heldout_agent_eval(
|
|
| 232 |
final_text = ""
|
| 233 |
lf = getattr(env, "_lf", None)
|
| 234 |
for turn in range(max_turns):
|
|
|
|
| 235 |
try:
|
| 236 |
prompt_text = tokenizer.apply_chat_template(
|
| 237 |
messages,
|
|
@@ -279,11 +315,26 @@ def run_heldout_agent_eval(
|
|
| 279 |
completion = _generate_once()
|
| 280 |
calls = _parse_tool_calls(completion)
|
| 281 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 282 |
final_text = completion
|
| 283 |
messages.append({"role": "assistant", "content": completion})
|
| 284 |
if not calls:
|
|
|
|
| 285 |
break
|
| 286 |
for call in calls:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 287 |
fn = tool_map.get(call["name"])
|
| 288 |
if fn is None:
|
| 289 |
result = f"Unknown tool: {call['name']}"
|
|
@@ -307,31 +358,34 @@ def run_heldout_agent_eval(
|
|
| 307 |
|
| 308 |
reward = float(env.get_reward())
|
| 309 |
report = getattr(env, "_last_report", {}) or {}
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
|
| 319 |
-
|
| 320 |
-
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
"
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
|
|
|
|
|
|
|
| 330 |
except Exception as e: # noqa: BLE001
|
| 331 |
traceback.print_exc()
|
|
|
|
| 332 |
rows.append(
|
| 333 |
{
|
| 334 |
-
"task_id":
|
| 335 |
"prompt": str(p.get("prompt"))[:2000],
|
| 336 |
"completion": f"EVAL_ERROR: {e}",
|
| 337 |
"pass_frac": 0.0,
|
|
@@ -340,6 +394,7 @@ def run_heldout_agent_eval(
|
|
| 340 |
"resolution": "ERROR",
|
| 341 |
}
|
| 342 |
)
|
|
|
|
| 343 |
finally:
|
| 344 |
try:
|
| 345 |
env._end_trace()
|
|
@@ -488,11 +543,21 @@ def make_eval_before_save_callback(
|
|
| 488 |
|
| 489 |
rev = f"grpo-step-{step}"
|
| 490 |
problems = eval_problems[:n_eval]
|
| 491 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 492 |
try:
|
| 493 |
results = run_heldout_agent_eval(
|
| 494 |
model, tokenizer, problems, max_turns=max_eval_turns
|
| 495 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 496 |
import wandb
|
| 497 |
|
| 498 |
wandb_run_id = None
|
|
@@ -668,9 +733,25 @@ def _load_swe_splits(cfg: Cfg):
|
|
| 668 |
def main(cfg: Cfg | None = None) -> None:
|
| 669 |
global _TOKENIZER
|
| 670 |
cfg = cfg or Cfg()
|
|
|
|
| 671 |
load_secrets()
|
| 672 |
_ensure_package()
|
| 673 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 674 |
import torch
|
| 675 |
import wandb
|
| 676 |
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
|
|
@@ -686,15 +767,20 @@ def main(cfg: Cfg | None = None) -> None:
|
|
| 686 |
headers = {"ngrok-skip-browser-warning": "1"}
|
| 687 |
if os.environ.get("SWE_GRADER_TOKEN"):
|
| 688 |
headers["Authorization"] = f"Bearer {os.environ['SWE_GRADER_TOKEN']}"
|
|
|
|
| 689 |
health = requests.get(f"{grader}/health", headers=headers, timeout=30)
|
| 690 |
health.raise_for_status()
|
| 691 |
-
|
| 692 |
|
| 693 |
os.environ["WANDB_PROJECT"] = os.getenv("WANDB_PROJECT", "deepagents-rl-coding")
|
|
|
|
| 694 |
wandb.login(key=os.environ["WANDB_API_KEY"])
|
| 695 |
|
|
|
|
| 696 |
model_id = resolve_model()
|
|
|
|
| 697 |
train, eval_problems = _load_swe_splits(cfg)
|
|
|
|
| 698 |
|
| 699 |
bnb = BitsAndBytesConfig(
|
| 700 |
load_in_4bit=True,
|
|
@@ -702,6 +788,7 @@ def main(cfg: Cfg | None = None) -> None:
|
|
| 702 |
bnb_4bit_quant_type="nf4",
|
| 703 |
bnb_4bit_use_double_quant=True,
|
| 704 |
)
|
|
|
|
| 705 |
tokenizer = AutoTokenizer.from_pretrained(
|
| 706 |
model_id, token=os.environ["HF_TOKEN"], trust_remote_code=True
|
| 707 |
)
|
|
@@ -709,6 +796,7 @@ def main(cfg: Cfg | None = None) -> None:
|
|
| 709 |
tokenizer.pad_token = tokenizer.eos_token
|
| 710 |
_TOKENIZER = tokenizer
|
| 711 |
|
|
|
|
| 712 |
model = AutoModelForCausalLM.from_pretrained(
|
| 713 |
model_id,
|
| 714 |
quantization_config=bnb,
|
|
@@ -716,6 +804,7 @@ def main(cfg: Cfg | None = None) -> None:
|
|
| 716 |
token=os.environ["HF_TOKEN"],
|
| 717 |
trust_remote_code=True,
|
| 718 |
)
|
|
|
|
| 719 |
model = prepare_model_for_kbit_training(model)
|
| 720 |
lora = LoraConfig(
|
| 721 |
r=cfg.lora_r,
|
|
@@ -758,7 +847,8 @@ def main(cfg: Cfg | None = None) -> None:
|
|
| 758 |
},
|
| 759 |
)
|
| 760 |
|
| 761 |
-
|
|
|
|
| 762 |
baseline = run_heldout_agent_eval(
|
| 763 |
model,
|
| 764 |
tokenizer,
|
|
@@ -845,6 +935,13 @@ def main(cfg: Cfg | None = None) -> None:
|
|
| 845 |
max_eval_turns=cfg.max_eval_turns,
|
| 846 |
)
|
| 847 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 848 |
trainer = GRPOTrainer(
|
| 849 |
model=model,
|
| 850 |
args=args,
|
|
@@ -855,7 +952,9 @@ def main(cfg: Cfg | None = None) -> None:
|
|
| 855 |
)
|
| 856 |
cb.trainer = trainer
|
| 857 |
|
|
|
|
| 858 |
trainer.train()
|
|
|
|
| 859 |
|
| 860 |
final_step = int(trainer.state.global_step)
|
| 861 |
rev = f"grpo-step-{final_step}-final"
|
|
|
|
| 22 |
from pathlib import Path
|
| 23 |
from typing import Any, Callable
|
| 24 |
|
| 25 |
+
|
| 26 |
+
def _vlog(msg: str, **fields: Any) -> None:
|
| 27 |
+
extra = ""
|
| 28 |
+
if fields:
|
| 29 |
+
try:
|
| 30 |
+
extra = " | " + json.dumps(fields, default=str)[:1500]
|
| 31 |
+
except Exception:
|
| 32 |
+
extra = f" | {fields!r}"[:1500]
|
| 33 |
+
print(f"[darl] {msg}{extra}", flush=True)
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def _truncate_preview(obj: Any, n: int = 400) -> str:
|
| 37 |
+
try:
|
| 38 |
+
s = obj if isinstance(obj, str) else json.dumps(obj, default=str)
|
| 39 |
+
except Exception:
|
| 40 |
+
s = repr(obj)
|
| 41 |
+
return s if len(s) <= n else s[:n] + "..."
|
| 42 |
+
|
| 43 |
+
|
| 44 |
# ---------------------------------------------------------------------------
|
| 45 |
# Bootstrap package (notebook may only download this file)
|
| 46 |
# ---------------------------------------------------------------------------
|
| 47 |
|
| 48 |
|
| 49 |
def _ensure_package() -> None:
|
| 50 |
+
_vlog("bootstrap.ensure_package.begin")
|
| 51 |
try:
|
| 52 |
import deepagents_rl # noqa: F401
|
| 53 |
|
| 54 |
+
_vlog("bootstrap.ensure_package.already_importable")
|
| 55 |
return
|
| 56 |
except ImportError:
|
| 57 |
+
_vlog("bootstrap.ensure_package.download_from_hf")
|
| 58 |
|
| 59 |
token = os.environ.get("HF_TOKEN")
|
| 60 |
if not token:
|
|
|
|
| 76 |
sys.path.insert(0, str(pkg_parent))
|
| 77 |
import deepagents_rl # noqa: F401
|
| 78 |
|
| 79 |
+
_vlog("bootstrap.ensure_package.done", path=str(pkg_parent))
|
| 80 |
+
|
| 81 |
|
| 82 |
# ---------------------------------------------------------------------------
|
| 83 |
# Secrets
|
|
|
|
| 85 |
|
| 86 |
|
| 87 |
def load_secrets() -> None:
|
| 88 |
+
_vlog("secrets.load.begin")
|
| 89 |
try:
|
| 90 |
from kaggle_secrets import UserSecretsClient
|
| 91 |
|
|
|
|
| 147 |
os.environ.setdefault("WANDB_PROJECT", "deepagents-rl-coding")
|
| 148 |
os.environ.setdefault("HF_HUB_ENABLE_HF_TRANSFER", "0")
|
| 149 |
os.environ.setdefault("TRL_EXPERIMENTAL_SILENCE", "1")
|
| 150 |
+
os.environ.setdefault("DARL_LOG_LEVEL", "DEBUG")
|
| 151 |
+
_vlog(
|
| 152 |
+
"secrets.load.done",
|
| 153 |
+
has_grader=bool(os.getenv("SWE_GRADER_URL")),
|
| 154 |
+
grader_host=(os.getenv("SWE_GRADER_URL") or "")[:60],
|
| 155 |
+
wandb_project=os.getenv("WANDB_PROJECT"),
|
| 156 |
+
)
|
| 157 |
|
| 158 |
|
| 159 |
# ---------------------------------------------------------------------------
|
|
|
|
| 248 |
|
| 249 |
rows = []
|
| 250 |
model.eval()
|
| 251 |
+
_vlog("heldout_eval.begin", n_problems=len(problems), max_turns=max_turns)
|
| 252 |
+
for pi, p in enumerate(problems):
|
| 253 |
env = DeepAgentSWEEnv()
|
| 254 |
+
task_id = p.get("task_id") or p.get("instance_id")
|
| 255 |
+
_vlog("heldout_eval.problem.begin", i=pi, task_id=task_id)
|
| 256 |
try:
|
| 257 |
env.reset(**{k: v for k, v in p.items() if k != "prompt"})
|
| 258 |
tools = _env_tool_callables(env)
|
| 259 |
tool_map = {t.__name__: t for t in tools}
|
| 260 |
+
_vlog("heldout_eval.tools", tools=list(tool_map.keys()))
|
| 261 |
prompt = p.get("prompt")
|
| 262 |
if isinstance(prompt, list):
|
| 263 |
messages = list(prompt)
|
|
|
|
| 267 |
final_text = ""
|
| 268 |
lf = getattr(env, "_lf", None)
|
| 269 |
for turn in range(max_turns):
|
| 270 |
+
_vlog("heldout_eval.llm_turn.begin", task_id=task_id, turn=turn)
|
| 271 |
try:
|
| 272 |
prompt_text = tokenizer.apply_chat_template(
|
| 273 |
messages,
|
|
|
|
| 315 |
completion = _generate_once()
|
| 316 |
calls = _parse_tool_calls(completion)
|
| 317 |
|
| 318 |
+
_vlog(
|
| 319 |
+
"heldout_eval.llm_turn.end",
|
| 320 |
+
task_id=task_id,
|
| 321 |
+
turn=turn,
|
| 322 |
+
completion_preview=completion[:400],
|
| 323 |
+
n_tool_calls=len(calls),
|
| 324 |
+
tool_names=[c["name"] for c in calls],
|
| 325 |
+
)
|
| 326 |
final_text = completion
|
| 327 |
messages.append({"role": "assistant", "content": completion})
|
| 328 |
if not calls:
|
| 329 |
+
_vlog("heldout_eval.stop_no_tools", task_id=task_id, turn=turn)
|
| 330 |
break
|
| 331 |
for call in calls:
|
| 332 |
+
_vlog(
|
| 333 |
+
"heldout_eval.tool_dispatch",
|
| 334 |
+
task_id=task_id,
|
| 335 |
+
tool=call["name"],
|
| 336 |
+
arguments=_truncate_preview(call.get("arguments")),
|
| 337 |
+
)
|
| 338 |
fn = tool_map.get(call["name"])
|
| 339 |
if fn is None:
|
| 340 |
result = f"Unknown tool: {call['name']}"
|
|
|
|
| 358 |
|
| 359 |
reward = float(env.get_reward())
|
| 360 |
report = getattr(env, "_last_report", {}) or {}
|
| 361 |
+
row = {
|
| 362 |
+
"task_id": task_id,
|
| 363 |
+
"prompt": (
|
| 364 |
+
prompt
|
| 365 |
+
if isinstance(prompt, str)
|
| 366 |
+
else json.dumps(prompt)[:2000]
|
| 367 |
+
),
|
| 368 |
+
"completion": final_text[:4000],
|
| 369 |
+
"pass_frac": float(report.get("pass_frac") or reward),
|
| 370 |
+
"reward_total": reward,
|
| 371 |
+
"resolved": bool(report.get("resolved")),
|
| 372 |
+
"resolution": report.get("resolution"),
|
| 373 |
+
"n_tool_calls": len(getattr(env, "_tool_calls", []) or []),
|
| 374 |
+
"tools_used": [
|
| 375 |
+
c.get("name") for c in (getattr(env, "_tool_calls", []) or [])
|
| 376 |
+
],
|
| 377 |
+
"langfuse_trace_id": getattr(env, "_trace_id", "") or "",
|
| 378 |
+
}
|
| 379 |
+
rows.append(row)
|
| 380 |
+
_vlog("heldout_eval.problem.done", **{k: row[k] for k in (
|
| 381 |
+
"task_id", "reward_total", "pass_frac", "resolved", "n_tool_calls", "tools_used"
|
| 382 |
+
)})
|
| 383 |
except Exception as e: # noqa: BLE001
|
| 384 |
traceback.print_exc()
|
| 385 |
+
_vlog("heldout_eval.problem.error", task_id=task_id, error=str(e))
|
| 386 |
rows.append(
|
| 387 |
{
|
| 388 |
+
"task_id": task_id,
|
| 389 |
"prompt": str(p.get("prompt"))[:2000],
|
| 390 |
"completion": f"EVAL_ERROR: {e}",
|
| 391 |
"pass_frac": 0.0,
|
|
|
|
| 394 |
"resolution": "ERROR",
|
| 395 |
}
|
| 396 |
)
|
| 397 |
+
_vlog("heldout_eval.done", n=len(rows))
|
| 398 |
finally:
|
| 399 |
try:
|
| 400 |
env._end_trace()
|
|
|
|
| 543 |
|
| 544 |
rev = f"grpo-step-{step}"
|
| 545 |
problems = eval_problems[:n_eval]
|
| 546 |
+
_vlog("ckpt_eval.begin", step=step, rev=rev, n=len(problems))
|
| 547 |
+
print(
|
| 548 |
+
f"\n=== AGENT EVAL BEFORE CHECKPOINT step={step} rev={rev} n={len(problems)} ===",
|
| 549 |
+
flush=True,
|
| 550 |
+
)
|
| 551 |
try:
|
| 552 |
results = run_heldout_agent_eval(
|
| 553 |
model, tokenizer, problems, max_turns=max_eval_turns
|
| 554 |
)
|
| 555 |
+
_vlog(
|
| 556 |
+
"ckpt_eval.rollouts_done",
|
| 557 |
+
step=step,
|
| 558 |
+
mean_reward=sum(float(r["reward_total"]) for r in results)
|
| 559 |
+
/ max(len(results), 1),
|
| 560 |
+
)
|
| 561 |
import wandb
|
| 562 |
|
| 563 |
wandb_run_id = None
|
|
|
|
| 733 |
def main(cfg: Cfg | None = None) -> None:
|
| 734 |
global _TOKENIZER
|
| 735 |
cfg = cfg or Cfg()
|
| 736 |
+
_vlog("main.begin", cfg_dataset=getattr(cfg, "dataset_id", None))
|
| 737 |
load_secrets()
|
| 738 |
_ensure_package()
|
| 739 |
|
| 740 |
+
try:
|
| 741 |
+
from deepagents_rl.observability.logging import configure_logging
|
| 742 |
+
|
| 743 |
+
out_log = Path("/kaggle/working/grpo-out")
|
| 744 |
+
out_log.mkdir(parents=True, exist_ok=True)
|
| 745 |
+
configure_logging(
|
| 746 |
+
level=os.getenv("DARL_LOG_LEVEL", "DEBUG"),
|
| 747 |
+
log_file=out_log / "run.log",
|
| 748 |
+
events_jsonl=out_log / "events.jsonl",
|
| 749 |
+
force=True,
|
| 750 |
+
)
|
| 751 |
+
_vlog("main.logging_configured", log_file=str(out_log / "run.log"))
|
| 752 |
+
except Exception as e: # noqa: BLE001
|
| 753 |
+
_vlog("main.logging_configure_failed", error=str(e))
|
| 754 |
+
|
| 755 |
import torch
|
| 756 |
import wandb
|
| 757 |
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
|
|
|
|
| 767 |
headers = {"ngrok-skip-browser-warning": "1"}
|
| 768 |
if os.environ.get("SWE_GRADER_TOKEN"):
|
| 769 |
headers["Authorization"] = f"Bearer {os.environ['SWE_GRADER_TOKEN']}"
|
| 770 |
+
_vlog("main.grader_health_check", url=grader)
|
| 771 |
health = requests.get(f"{grader}/health", headers=headers, timeout=30)
|
| 772 |
health.raise_for_status()
|
| 773 |
+
_vlog("main.grader_health_ok", body=health.json())
|
| 774 |
|
| 775 |
os.environ["WANDB_PROJECT"] = os.getenv("WANDB_PROJECT", "deepagents-rl-coding")
|
| 776 |
+
_vlog("main.wandb_login")
|
| 777 |
wandb.login(key=os.environ["WANDB_API_KEY"])
|
| 778 |
|
| 779 |
+
_vlog("main.resolve_model")
|
| 780 |
model_id = resolve_model()
|
| 781 |
+
_vlog("main.load_dataset")
|
| 782 |
train, eval_problems = _load_swe_splits(cfg)
|
| 783 |
+
_vlog("main.dataset_ready", train_n=len(train), eval_n=len(eval_problems))
|
| 784 |
|
| 785 |
bnb = BitsAndBytesConfig(
|
| 786 |
load_in_4bit=True,
|
|
|
|
| 788 |
bnb_4bit_quant_type="nf4",
|
| 789 |
bnb_4bit_use_double_quant=True,
|
| 790 |
)
|
| 791 |
+
_vlog("main.load_tokenizer", model_id=model_id)
|
| 792 |
tokenizer = AutoTokenizer.from_pretrained(
|
| 793 |
model_id, token=os.environ["HF_TOKEN"], trust_remote_code=True
|
| 794 |
)
|
|
|
|
| 796 |
tokenizer.pad_token = tokenizer.eos_token
|
| 797 |
_TOKENIZER = tokenizer
|
| 798 |
|
| 799 |
+
_vlog("main.load_model_4bit", model_id=model_id, cuda=torch.cuda.is_available())
|
| 800 |
model = AutoModelForCausalLM.from_pretrained(
|
| 801 |
model_id,
|
| 802 |
quantization_config=bnb,
|
|
|
|
| 804 |
token=os.environ["HF_TOKEN"],
|
| 805 |
trust_remote_code=True,
|
| 806 |
)
|
| 807 |
+
_vlog("main.prepare_lora")
|
| 808 |
model = prepare_model_for_kbit_training(model)
|
| 809 |
lora = LoraConfig(
|
| 810 |
r=cfg.lora_r,
|
|
|
|
| 847 |
},
|
| 848 |
)
|
| 849 |
|
| 850 |
+
_vlog("main.baseline_eval.begin", n_eval=cfg.n_eval)
|
| 851 |
+
print("=== BASELINE AGENT EVAL (step 0) ===", flush=True)
|
| 852 |
baseline = run_heldout_agent_eval(
|
| 853 |
model,
|
| 854 |
tokenizer,
|
|
|
|
| 935 |
max_eval_turns=cfg.max_eval_turns,
|
| 936 |
)
|
| 937 |
|
| 938 |
+
_vlog(
|
| 939 |
+
"main.trainer_init",
|
| 940 |
+
environment="DeepAgentSWEEnv",
|
| 941 |
+
max_steps=cfg.max_steps,
|
| 942 |
+
num_generations=cfg.num_generations,
|
| 943 |
+
max_tool_calling_iterations=cfg.max_tool_calling_iterations,
|
| 944 |
+
)
|
| 945 |
trainer = GRPOTrainer(
|
| 946 |
model=model,
|
| 947 |
args=args,
|
|
|
|
| 952 |
)
|
| 953 |
cb.trainer = trainer
|
| 954 |
|
| 955 |
+
_vlog("main.trainer.train.begin")
|
| 956 |
trainer.train()
|
| 957 |
+
_vlog("main.trainer.train.done", global_step=int(trainer.state.global_step))
|
| 958 |
|
| 959 |
final_step = int(trainer.state.global_step)
|
| 960 |
rev = f"grpo-step-{final_step}-final"
|