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
8 changes: 8 additions & 0 deletions areal/api/cli_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,13 @@ class GenerationHyperparameters:
)
},
)
reward_normalization_use_std: bool = field(
default=True,
metadata={
"help": "Divide grouped rollout rewards by their standard deviation. "
"Set False to subtract only the mean when reward_normalization is enabled."
},
)
drop_incomplete_group: bool = field(
default=False,
metadata={
Expand Down Expand Up @@ -324,6 +331,7 @@ def to_openai_agents_model_settings_dict(
# OpenAI client kwargs even when users enable them.
_WORKFLOW_ONLY_ARGS: ClassVar[set[str]] = {
"reward_normalization",
"reward_normalization_use_std",
"drop_incomplete_group",
}

Expand Down
5 changes: 5 additions & 0 deletions areal/api/engine_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Submit a batch of requests and wait for results.

Expand Down Expand Up @@ -247,6 +248,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Prepare a batch of data for training from a dataloader.

Expand Down Expand Up @@ -751,6 +753,7 @@ def submit(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> int:
"""Submit a request to the inference engine and return immediately.

Expand Down Expand Up @@ -860,6 +863,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Submit a batch of requests to the inference engine and wait for the results.

Expand Down Expand Up @@ -911,6 +915,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Asynchronously submit and wait until a full batch is ready with controlled staleness.

Expand Down
4 changes: 4 additions & 0 deletions areal/engine/fsdp_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
self._check_rollout_engine_connected()
return self.rollout_coordinator.rollout_batch(
Expand All @@ -595,6 +596,7 @@ def rollout_batch(
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand All @@ -609,6 +611,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
self._check_rollout_engine_connected()
return self.rollout_coordinator.prepare_batch(
Expand All @@ -620,6 +623,7 @@ def prepare_batch(
min_usable_group_size=min_usable_group_size,
dynamic_bs=dynamic_bs,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down
4 changes: 4 additions & 0 deletions areal/engine/megatron_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
self._check_rollout_engine_connected()
return self.rollout_coordinator.rollout_batch(
Expand All @@ -1049,6 +1050,7 @@ def rollout_batch(
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand All @@ -1063,6 +1065,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
self._check_rollout_engine_connected()
return self.rollout_coordinator.prepare_batch(
Expand All @@ -1074,6 +1077,7 @@ def prepare_batch(
min_usable_group_size=min_usable_group_size,
dynamic_bs=dynamic_bs,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down
6 changes: 6 additions & 0 deletions areal/engine/sglang_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ def submit(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> int:
"""Submit a request to the inference engine."""
return self._engine.submit(
Expand All @@ -690,6 +691,7 @@ def submit(
is_eval=is_eval,
proxy_addr=proxy_addr,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down Expand Up @@ -719,6 +721,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> dict[str, Any]:
"""Submit a batch of requests and wait for results.

Expand All @@ -732,6 +735,7 @@ def rollout_batch(
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand All @@ -746,6 +750,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
):
"""Asynchronously submit and wait until a full batch is ready."""
return self._engine.prepare_batch(
Expand All @@ -757,6 +762,7 @@ def prepare_batch(
min_usable_group_size=min_usable_group_size,
dynamic_bs=dynamic_bs,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down
6 changes: 6 additions & 0 deletions areal/engine/vllm_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ def submit(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> int:
"""Submit a request to the inference engine."""
return self._engine.submit(
Expand All @@ -454,6 +455,7 @@ def submit(
is_eval=is_eval,
proxy_addr=proxy_addr,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down Expand Up @@ -483,6 +485,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> dict[str, Any]:
"""Submit a batch of requests and wait for results.

Expand All @@ -496,6 +499,7 @@ def rollout_batch(
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand All @@ -510,6 +514,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
):
"""Asynchronously submit and wait until a full batch is ready."""
return self._engine.prepare_batch(
Expand All @@ -521,6 +526,7 @@ def prepare_batch(
min_usable_group_size=min_usable_group_size,
dynamic_bs=dynamic_bs,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down
4 changes: 4 additions & 0 deletions areal/experimental/engine/archon_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Perform rollout using connected inference engine."""
self._check_rollout_engine_connected()
Expand All @@ -710,6 +711,7 @@ def rollout_batch(
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand All @@ -724,6 +726,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Prepare batch from dataloader with rollout."""
self._check_rollout_engine_connected()
Expand All @@ -736,6 +739,7 @@ def prepare_batch(
min_usable_group_size=min_usable_group_size,
dynamic_bs=dynamic_bs,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down
4 changes: 3 additions & 1 deletion areal/experimental/openai/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ def normalize_group_rewards(

def normalize_logical_rollout_rewards(
results: list[dict[str, InteractionWithTokenLogpReward] | None],
*,
use_std: bool = True,
) -> bool:
"""Normalize row rewards against one explicit or equal-row rollout reference."""
if not results or any(not result for result in results):
Expand Down Expand Up @@ -390,7 +392,7 @@ def normalize_logical_rollout_rewards(
std = (
rewards.std(unbiased=False) if len(references) > 1 else rewards.new_tensor(1.0)
)
scale = torch.where(std <= 1e-8, 1.0, std + 1e-8)
scale = torch.where(std <= 1e-8, 1.0, std + 1e-8) if use_std else 1.0
row_rewards = torch.tensor(
[v.reward for result in results for v in result.values()], dtype=torch.float32
)
Expand Down
8 changes: 8 additions & 0 deletions areal/infra/controller/rollout_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ class _RemoteRolloutTaskInput:
min_usable_group_size: int = 1
proxy_addr: str | None = None
reward_normalization: bool = False
reward_normalization_use_std: bool = True
drop_incomplete_group: bool = False


Expand Down Expand Up @@ -1098,6 +1099,7 @@ async def _submit_then_wait() -> WorkflowTaskResult | None:
callback_addr=f"http://{self.callback_addr}/callback/rollout_complete",
proxy_addr=proxy_addr,
reward_normalization=pending_task.reward_normalization,
reward_normalization_use_std=pending_task.reward_normalization_use_std,
drop_incomplete_group=pending_task.drop_incomplete_group,
)

Expand Down Expand Up @@ -1169,6 +1171,7 @@ def submit(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> int:
validate_rollout_group_sizes(group_size, min_usable_group_size)

Expand Down Expand Up @@ -1197,6 +1200,7 @@ def submit(
min_usable_group_size=min_usable_group_size,
proxy_addr=proxy_addr,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down Expand Up @@ -1229,6 +1233,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
perf_tracer.instant(
"rollout_controller.rollout_batch",
Expand All @@ -1244,6 +1249,7 @@ def rollout_batch(
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)
results = self.wait(count=len(data))
Expand All @@ -1262,6 +1268,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Prepare a batch with controlled staleness.

Expand Down Expand Up @@ -1292,6 +1299,7 @@ def task_input_generator():
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down
4 changes: 4 additions & 0 deletions areal/infra/controller/train_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
return self.rollout.prepare_batch(
dataloader=dataloader,
Expand All @@ -862,6 +863,7 @@ def prepare_batch(
min_usable_group_size=min_usable_group_size,
dynamic_bs=dynamic_bs,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand All @@ -875,6 +877,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
return self.rollout.rollout_batch(
data=data,
Expand All @@ -884,6 +887,7 @@ def rollout_batch(
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)

Expand Down
4 changes: 4 additions & 0 deletions areal/infra/dist_rollout.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ def rollout_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Generate rollout batch with distributed coordination (synchronous).

Expand Down Expand Up @@ -311,6 +312,7 @@ def rollout_batch(
group_size=group_size,
min_usable_group_size=min_usable_group_size,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)
)
Expand All @@ -330,6 +332,7 @@ def prepare_batch(
reward_normalization: bool = False,
drop_incomplete_group: bool = False,
min_usable_group_size: int = 1,
reward_normalization_use_std: bool = True,
) -> list[dict[str, Any]]:
"""Prepare async rollout batch with distributed coordination.

Expand Down Expand Up @@ -388,6 +391,7 @@ def _prepare_until_dispatchable() -> list[dict[str, Any]]:
min_usable_group_size=min_usable_group_size,
dynamic_bs=dynamic_bs,
reward_normalization=reward_normalization,
reward_normalization_use_std=reward_normalization_use_std,
drop_incomplete_group=drop_incomplete_group,
)
except Exception as exc:
Expand Down
Loading
Loading