@@ -55,6 +55,7 @@ def __init__(self, fd_config: FDConfig, models, local_rank: int):
5555 self ._capture_model_state ()
5656 self .rdma_handle = None
5757 self .use_gdr_checkpoint_transfer = envs .FD_USE_GDR_CHECKPOINT_TRANSFER
58+ self ._gdr_ct_handle = None
5859
5960 if self .use_gdr_checkpoint_transfer :
6061 self .update_weights_by_gdr ()
@@ -175,14 +176,8 @@ def update_weights_by_gdr(
175176 f"load_strategy:{ self .load_config .load_strategy } , step_id:{ step_id } "
176177 )
177178
178- from checkpoint_transfer .transfer import CheckpointTransfer
179-
180- transfer_config = self ._build_ct_transfer_config (config )
181- logger .info (f"CheckpointTransfer config:{ transfer_config } " )
182- ct_handle = CheckpointTransfer (transfer_config )
183-
184179 total_start = time .perf_counter ()
185- asyncio . run ( ct_handle . initialize () )
180+ ct_handle = self . _ensure_gdr_handle ( config )
186181 try :
187182 weights_iterator = ct_handle .receive_weights_sync (step_id = step_id , output_framework = "paddle" )
188183
@@ -192,8 +187,9 @@ def update_weights_by_gdr(
192187 paddle .empty (target_param .shape , dtype = target_param .dtype )._share_buffer_to (target_param )
193188 logger .debug (f"Restored cleared parameter storage before GDR checkpoint transfer load: { name } " )
194189 update_count , mtp_cache_count = self ._load_models_from_weight_iterator (weights_iterator )
195- finally :
196- asyncio .run (ct_handle .cleanup ())
190+ except Exception :
191+ self ._destroy_gdr_handle ()
192+ raise
197193 self ._capture_model_state (log_params = False )
198194 total_cost = time .perf_counter () - total_start
199195 logger .info (
@@ -210,6 +206,32 @@ def update_weights_by_gdr(
210206 "mtp_cache_count" : mtp_cache_count ,
211207 }
212208
209+ def _ensure_gdr_handle (self , config : dict ):
210+ """Lazily create and initialize the CheckpointTransfer handle (once)."""
211+ if self ._gdr_ct_handle is not None :
212+ return self ._gdr_ct_handle
213+
214+ transfer_config = self ._build_ct_transfer_config (config )
215+ logger .info (f"CheckpointTransfer config:{ transfer_config } " )
216+
217+ from checkpoint_transfer .transfer import CheckpointTransfer
218+
219+ ct_handle = CheckpointTransfer (transfer_config )
220+ asyncio .run (ct_handle .initialize ())
221+
222+ self ._gdr_ct_handle = ct_handle
223+ logger .info ("[GDR] CheckpointTransfer initialized and cached for reuse" )
224+ return ct_handle
225+
226+ def _destroy_gdr_handle (self ):
227+ """Destroy the cached GDR handle (e.g. on error)."""
228+ if self ._gdr_ct_handle is not None :
229+ try :
230+ asyncio .run (self ._gdr_ct_handle .cleanup ())
231+ except Exception :
232+ pass
233+ self ._gdr_ct_handle = None
234+
213235 def _build_ct_transfer_config (self , config : dict ):
214236 from dataclasses import fields
215237
0 commit comments