Reproduction
AsyncGRPOTrainer documentation says that reward functions passed to the spawned rollout worker can be module-level functions, functools.partial objects, or callable class instances.
However, _AsyncRolloutLoop currently creates reward metric names using:
self.reward_func_names = [f.__name__ for f in reward_funcs]
functools.partial objects and typical callable class instances do not define __name__. As a result, a valid picklable reward callable can fail during rollout-worker initialization with an AttributeError.
Minimal example:
from functools import partial
def correctness_reward(completions, **kwargs):
return [1.0] * len(completions)
reward_func = partial(correctness_reward)
reward_func.__name__
# AttributeError: 'functools.partial' object has no attribute '__name__'
Proposed fix:
- Preserve normal names for functions and methods.
- Unwrap
functools.partial and use the wrapped function name.
- Use the class name for callable instances.
- Add focused CPU-only regression coverage for partial and callable-instance reward functions.
System Info
Not applicable, this is a source-level issue identified by code inspection.
Checklist
Reproduction
AsyncGRPOTrainerdocumentation says that reward functions passed to the spawned rollout worker can be module-level functions,functools.partialobjects, or callable class instances.However,
_AsyncRolloutLoopcurrently creates reward metric names using:functools.partialobjects and typical callable class instances do not define__name__. As a result, a valid picklable reward callable can fail during rollout-worker initialization with anAttributeError.Minimal example:
Proposed fix:
functools.partialand use the wrapped function name.System Info
Not applicable, this is a source-level issue identified by code inspection.
Checklist