@@ -182,17 +182,24 @@ def setup_config(args) -> Config:
182182 config_name = config_path .stem # Get filename without extension
183183 output_folder = f"outputs/{ config_name } /"
184184
185- # Update checkpoint dirpath to use the new output folder
186- cfg .monitor .checkpoint .dirpath = f"{ output_folder } checkpoints/"
185+ # Update checkpoint dirpath only if not provided by the user
186+ if not getattr (cfg .monitor .checkpoint , "dirpath" , None ):
187+ cfg .monitor .checkpoint .dirpath = str (Path (output_folder ) / "checkpoints" )
188+ else :
189+ cfg .monitor .checkpoint .dirpath = str (Path (cfg .monitor .checkpoint .dirpath ))
187190
188- # Update inference output path to use the new output folder
189- cfg .inference .data .output_path = f"{ output_folder } results/"
191+ # Update inference output path only if not provided by the user
192+ if not getattr (cfg .inference .data , "output_path" , None ):
193+ cfg .inference .data .output_path = str (Path (output_folder ) / "results" )
194+ else :
195+ cfg .inference .data .output_path = str (Path (cfg .inference .data .output_path ))
190196
191197 # Note: We handle timestamping manually in main() to create run directories
192198 # Set this to False to prevent PyTorch Lightning from adding its own timestamp
193199 cfg .monitor .checkpoint .use_timestamp = False
194200
195- print (f"📁 Output folder set to: { output_folder } " )
201+ print (f"📁 Checkpoints base directory: { cfg .monitor .checkpoint .dirpath } " )
202+ print (f"📂 Inference output directory: { cfg .inference .data .output_path } " )
196203
197204 # Apply CLI overrides
198205 if args .overrides :
@@ -1111,8 +1118,9 @@ def main():
11111118 # Subsequent invocations (with LOCAL_RANK set) reuse the existing timestamp.
11121119 if args .mode == "train" :
11131120 # Extract output folder from checkpoint dirpath (remove /checkpoints suffix)
1114- checkpoint_dirpath = cfg .monitor .checkpoint .dirpath
1115- output_base = Path (checkpoint_dirpath ).parent # This gives us outputs/experiment_name/
1121+ checkpoint_dir = Path (cfg .monitor .checkpoint .dirpath )
1122+ checkpoint_subdir = checkpoint_dir .name or "checkpoints"
1123+ output_base = checkpoint_dir .parent # Base directory containing timestamped runs
11161124
11171125 # Check if this is a DDP re-launch (LOCAL_RANK is set by PyTorch Lightning)
11181126 import os
@@ -1129,10 +1137,11 @@ def main():
11291137 timestamp = datetime .now ().strftime ("%Y%m%d_%H%M%S" )
11301138 run_dir = output_base / timestamp
11311139
1132- # Update checkpoint dirpath to use the timestamped directory
1133- cfg .monitor .checkpoint .dirpath = str (run_dir / "checkpoints" )
1140+ # Update checkpoint dirpath to use the timestamped directory (preserve leaf name)
1141+ checkpoint_path = run_dir / checkpoint_subdir
1142+ cfg .monitor .checkpoint .dirpath = str (checkpoint_path )
11341143
1135- run_dir .mkdir (parents = True , exist_ok = True )
1144+ checkpoint_path .mkdir (parents = True , exist_ok = True )
11361145 print (f"📁 Run directory: { run_dir } " )
11371146
11381147 # Save config to run directory
@@ -1156,7 +1165,8 @@ def main():
11561165 if timestamp_file .exists ():
11571166 timestamp = timestamp_file .read_text ().strip ()
11581167 run_dir = output_base / timestamp
1159- cfg .monitor .checkpoint .dirpath = str (run_dir / "checkpoints" )
1168+ checkpoint_path = run_dir / checkpoint_subdir
1169+ cfg .monitor .checkpoint .dirpath = str (checkpoint_path )
11601170 print (f"📁 [DDP Rank { local_rank } ] Using run directory: { run_dir } " )
11611171 else :
11621172 raise RuntimeError (
0 commit comments