From 7b8b637ca50bfcb9b212a6db93b4a5473b1ee2d2 Mon Sep 17 00:00:00 2001 From: Qiyuan Chen Date: Mon, 2 Nov 2026 15:57:07 +0800 Subject: [PATCH] [v5] Register only reward-model scorers for adaptive scaling Rule rewards arrive as sync wrappers and have no Ray model handle. Reading .model on them aborts cluster setup before training starts. Co-authored-by: Cursor --- swift/dev/recipe/grpo/assembly.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/swift/dev/recipe/grpo/assembly.py b/swift/dev/recipe/grpo/assembly.py index 9de43192b8..f241367cb2 100644 --- a/swift/dev/recipe/grpo/assembly.py +++ b/swift/dev/recipe/grpo/assembly.py @@ -343,10 +343,16 @@ def initialize_cluster( # registration reads it off the proxy the adapter will actually drive. elastic_models = {} if adapter is not None: + from swift.dev.rewards.scorer import RewardModel + for scorer in (*orm_scorers, *prm_scorers): + # Rules arrive as _AwaitableToSync and judges are not frozen RM proxies. Only a + # RewardModel carries the ray handle the adapter can scale; the rest stay static. + if not isinstance(scorer, RewardModel): + continue scorer_model = scorer.model if ( - getattr(scorer, "placement_key", None) is not None + scorer.placement_key is not None and getattr(scorer_model, "_worker_factory", None) is not None ): elastic_models[scorer.placement_key] = scorer_model