7070from nemo_rl .models .generation .sglang import SGLangConfig , SGLangGeneration
7171from nemo_rl .models .generation .vllm import VllmConfig , VllmGeneration
7272from nemo_rl .models .policy import PolicyConfig
73- from nemo_rl .models .policy .interfaces import ColocatablePolicyInterface
73+ from nemo_rl .models .policy .interfaces import OffloadMode , PolicyTrainerInterface
7474from nemo_rl .models .policy .lm_policy import Policy
7575from nemo_rl .utils .checkpoint import CheckpointingConfig , CheckpointManager
7676from nemo_rl .utils .logger import (
@@ -220,7 +220,7 @@ def setup(
220220 val_dataset : Optional [AllTaskProcessedDataset ],
221221 processor : Optional [AutoProcessor ] = None ,
222222) -> tuple [
223- ColocatablePolicyInterface ,
223+ PolicyTrainerInterface ,
224224 Optional [GenerationInterface ],
225225 tuple [RayVirtualCluster , RayVirtualCluster ],
226226 Optional [WeightSynchronizer ],
@@ -1089,7 +1089,7 @@ def _extract_prompt_only_messages(message_logs: list) -> list:
10891089
10901090
10911091def refit_policy_generation (
1092- policy : ColocatablePolicyInterface ,
1092+ policy : PolicyTrainerInterface ,
10931093 policy_generation : GenerationInterface ,
10941094 colocated_inference : bool ,
10951095 _refit_buffer_size_gb : Optional [int ] = None ,
@@ -1117,26 +1117,23 @@ def refit_policy_generation(
11171117 DeprecationWarning ,
11181118 stacklevel = 2 ,
11191119 )
1120+ from nemo_rl .models .policy .interfaces import OffloadMode
1121+
11201122 if colocated_inference :
1121- policy .offload_before_refit ( )
1123+ policy .finish_training ( offload_mode = OffloadMode . OPTIMIZER_ONLY )
11221124 policy_generation .prepare_for_generation (tags = ["weights" ])
11231125
1124- # Create a context manager that does nothing when timer is None
11251126 timer_context = (
11261127 timer .time ("prepare_for_generation/transfer_and_update_weights" )
11271128 if timer is not None
11281129 else nullcontext ()
11291130 )
11301131 with timer_context :
1131- # update weights
11321132 update_success = False
11331133 if colocated_inference :
1134- # get model param keys, which is grouped by size
11351134 if _refit_buffer_size_gb is not None :
11361135 buffer_size_bytes = _refit_buffer_size_gb * (1024 ** 3 )
11371136 else :
1138- # Empirically sets ratio as 30% to maximize efficiency.
1139- # The remaining 70% is a necessary buffer reserved for the parameter all-gathering across the expert-parallelism dimension.
11401137 memory_ratio = os .getenv ("NRL_REFIT_BUFFER_MEMORY_RATIO" , "0.3" )
11411138 buffer_size_bytes = int (
11421139 policy .get_free_memory_bytes () * float (memory_ratio )
@@ -1146,41 +1143,33 @@ def refit_policy_generation(
11461143 sglang_url_to_gpu_uuids = (
11471144 policy_generation .get_sglang_url_to_gpu_uuids ()
11481145 )
1149- # Stream weights via HTTP
11501146 flush_success = policy_generation .invalidate_kv_cache ()
11511147 if not flush_success :
11521148 print ("SGLang KV cache invalidation failed before weight update. " )
11531149 futures_train = policy .stream_weights_via_http (
11541150 sglang_url_to_gpu_uuids = sglang_url_to_gpu_uuids ,
11551151 )
1156- # Wait for all workers to complete
11571152 ray .get (futures_train )
11581153 update_success = True
11591154 else :
1160- # Original ZMQ IPC path for vLLM
11611155 futures_train = policy .stream_weights_via_ipc_zmq (
11621156 buffer_size_bytes = buffer_size_bytes
11631157 )
11641158 futures_inference = policy_generation .update_weights_via_ipc_zmq ()
1165- # wait for all futures to complete
11661159 ray .get (futures_train )
11671160 results = ray .get (futures_inference )
11681161 update_success = all (result for result in results if result is not None )
11691162 else :
1170- # update weights through nccl
1171- # SGLang haven't implemented non-colocated inference mode.
11721163 if isinstance (policy_generation , SGLangGeneration ):
11731164 raise NotImplementedError (
11741165 "SGLang haven't implemented non-colocated inference mode. "
11751166 )
11761167 futures_train = policy .broadcast_weights_for_collective (kv_scales = kv_scales )
11771168 futures_inference = policy_generation .update_weights_from_collective ()
1178- # wait for all futures to complete
11791169 ray .get (futures_train )
11801170 results = ray .get (futures_inference )
11811171 update_success = all (result for result in results if result is not None )
11821172
1183- # check if update is successful
11841173 if not update_success :
11851174 error_tag = "cuda-ipc" if colocated_inference else "nccl"
11861175 error_message = (
@@ -1191,7 +1180,7 @@ def refit_policy_generation(
11911180 raise RuntimeError (error_message )
11921181
11931182 if colocated_inference :
1194- policy .offload_after_refit ( )
1183+ policy .finish_training ( offload_mode = OffloadMode . FULL )
11951184 policy_generation .prepare_for_generation (tags = ["kv_cache" ])
11961185
11971186
@@ -1308,7 +1297,7 @@ def compute_and_apply_seq_logprob_error_masking(
13081297
13091298
13101299def grpo_train (
1311- policy : ColocatablePolicyInterface ,
1300+ policy : PolicyTrainerInterface ,
13121301 policy_generation : Optional [GenerationInterface ],
13131302 wrapped_dataloader : StatefulDataLoader | MultipleDataloaderWrapper ,
13141303 val_dataloader : Optional [StatefulDataLoader ],
@@ -1460,7 +1449,7 @@ def grpo_train(
14601449 # Compute KV scales if needed for FP8 quantization
14611450 if sync_kv_scales and kv_scales_cache is None :
14621451 print ("▶ Computing KV cache scales..." , flush = True )
1463- policy .prepare_for_lp_inference ( )
1452+ policy .finish_training ( offload_mode = OffloadMode . EVAL_ONLY )
14641453 # Align with training data processing to ensure parallel training compatibility
14651454 calib_flat , calib_input_lengths = (
14661455 batched_message_log_to_flat_message (
@@ -1494,7 +1483,7 @@ def grpo_train(
14941483 )
14951484 else :
14961485 if colocated_inference :
1497- policy .offload_after_refit () # unload optimizer to make space for generation
1486+ policy .finish_training ()
14981487 policy_generation .prepare_for_generation ()
14991488
15001489 dynamic_sampling_num_gen_batches += 1
@@ -1727,7 +1716,7 @@ def grpo_train(
17271716 memory_tracker .snapshot_start_of_stage ("Computing logprobs" , dir ())
17281717 print ("▶ Preparing for logprob inference..." , flush = True )
17291718 with timer .time ("logprob_inference_prep" ):
1730- policy .prepare_for_lp_inference ( )
1719+ policy .finish_training ( offload_mode = OffloadMode . EVAL_ONLY )
17311720
17321721 print ("▶ Computing logprobs..." , flush = True )
17331722 with timer .time ("policy_and_reference_logprobs" ):
@@ -1841,7 +1830,7 @@ def grpo_train(
18411830 )
18421831 else :
18431832 if colocated_inference :
1844- policy .offload_after_refit () # unload optimizer to make space for generation
1833+ policy .finish_training ()
18451834 policy_generation .prepare_for_generation ()
18461835 val_metrics , validation_timings = validate (
18471836 policy_generation ,
@@ -2350,7 +2339,7 @@ def validate(
23502339
23512340
23522341def async_grpo_train (
2353- policy : ColocatablePolicyInterface ,
2342+ policy : PolicyTrainerInterface ,
23542343 policy_generation : Optional [GenerationInterface ],
23552344 dataloader : StatefulDataLoader ,
23562345 val_dataloader : Optional [StatefulDataLoader ],
@@ -2768,7 +2757,7 @@ def async_grpo_train(
27682757 # Training phase (same as sync version)
27692758 print ("▶ Preparing for logprob inference..." )
27702759 with timer .time ("logprob_inference_prep" ):
2771- policy .prepare_for_lp_inference ( )
2760+ policy .finish_training ( offload_mode = OffloadMode . EVAL_ONLY )
27722761
27732762 print ("▶ Computing logprobs..." )
27742763 with timer .time ("policy_and_reference_logprobs" ):
@@ -3048,7 +3037,7 @@ def async_grpo_train(
30483037 os .path .join (checkpoint_path , "train_dataloader.pt" ),
30493038 )
30503039 checkpointer .finalize_checkpoint (checkpoint_path )
3051- policy .offload_after_refit ()
3040+ policy .finish_training ()
30523041
30533042 # Logging
30543043 # Log training data (match sync GRPO logging payload for parity)
0 commit comments