Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/agentcore_rl_toolkit/backends/experimental/sagemaker/SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,15 @@ cp config.yaml.example config.yaml
cd src/agentcore_rl_toolkit/backends/experimental/sagemaker
python train_grpo.py --config config.yaml
```

To train with DAPO instead, run `train_dapo.py` with the same config:

```bash
python train_dapo.py --config config.yaml
```

`train_dapo.py` is the GRPO loop plus dynamic sampling (each step rolls out batches of
prompts and keeps only groups whose rewards differ, until `batch_size` groups are kept) and
Clip-Higher (`clip_low_threshold` / `clip_high_threshold`). Its extra settings are in the
DAPO section of `config.yaml.example`. Each step logs a `sampling:` line with the number of
generation batches and the filtered fraction.
17 changes: 13 additions & 4 deletions src/agentcore_rl_toolkit/backends/experimental/sagemaker/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass, field
from typing import Literal
from typing import Literal, TypeVar

import yaml

Expand Down Expand Up @@ -58,9 +58,18 @@ class Config:
rollout_log_path: str = "" # JSONL file for per-rollout diagnostics; auto-named if empty


def load_config(path: str) -> Config:
ConfigT = TypeVar("ConfigT", bound=Config)


def load_config(path: str, config_cls: type[ConfigT] = Config) -> ConfigT:
"""Load a YAML file into ``config_cls``: ``Config``, or a recipe's subclass that adds fields.
Keys that ``config_cls`` does not define are ignored, so one YAML file can serve several
recipes (e.g. ``train_grpo`` skips the fields only ``train_dapo`` reads). Returns an
instance of ``config_cls``.
"""
with open(path) as f:
raw: dict = yaml.safe_load(f) or {}

fields = Config.__dataclass_fields__
return Config(**{k: v for k, v in raw.items() if k in fields})
fields = config_cls.__dataclass_fields__
return config_cls(**{k: v for k, v in raw.items() if k in fields})
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# GRPO training — rollout gateway + SageMaker Training Sessions
# GRPO / DAPO training — rollout gateway + SageMaker Training Sessions
# Both train_grpo.py and train_dapo.py read this file; each ignores keys it does not use.

# --- AWS resources (required) ---
role_arn: "arn:aws:iam::<account-id>:role/<your-sagemaker-role>"
Expand Down Expand Up @@ -51,3 +52,8 @@ acr_tps_limit: 5
# --- Logging ---
wandb_project: ""
wandb_run_name: "" # defaults to the SageMaker training session name

# --- DAPO (train_dapo.py only; train_grpo.py ignores these) ---
clip_low_threshold: 0.8 # PPO ratio lower bound, 1 - eps_low
clip_high_threshold: 1.28 # PPO ratio upper bound, 1 + eps_high (Clip-Higher)
max_num_gen_batches: 10 # dynamic sampling: max generation batches per step (0 = no cap)
Loading
Loading