Pulastya B commited on
Commit
f47adf5
·
1 Parent(s): f1ace72

Fix hyperparameter_tuning output_path bug: save to both artifact store AND user-requested path

Browse files

CRITICAL BUG FIX:
- hyperparameter_tuning was saving models to artifact store temp paths (e.g., tmpa4t7tgci.pkl)
- But LLM was looking for models at user-specified output_path (e.g., hyperparameter_tuned_model.pkl)
- This caused generate_model_report and subsequent tools to fail with 'File not found'

SOLUTION:
- Don't overwrite output_path variable with artifact store's temp path
- Save to BOTH locations: artifact store (for internal tracking) AND user-requested path (for LLM)
- Return user-requested path in model_path field so LLM can find it

CHANGES:
1. hyperparameter_tuning(): Save to both artifact store AND output_path
2. ensemble_models() voting/stacking: Save to both locations
3. ensemble_models() blending: Save to both locations

All three functions now:
- Use actual_model_path for artifact store internal path
- Keep output_path unchanged for LLM
- Save model to output_path so LLM can find it
- Return output_path in result's model_path field

This was NOT a streaming bug - tool implementation bug that existed before streaming.

Files changed (1) hide show
  1. src/tools/advanced_training.py +29 -5
src/tools/advanced_training.py CHANGED
@@ -293,9 +293,11 @@ def hyperparameter_tuning(
293
  }
294
 
295
  # Save model if output path provided
 
296
  if output_path:
297
  if ARTIFACT_STORE_AVAILABLE:
298
- output_path = save_model_with_store(
 
299
  model_data=final_model,
300
  filename=os.path.basename(output_path),
301
  metadata={
@@ -306,10 +308,15 @@ def hyperparameter_tuning(
306
  "test_metrics": test_metrics
307
  }
308
  )
 
 
 
 
309
  else:
310
  os.makedirs(os.path.dirname(output_path), exist_ok=True)
311
  joblib.dump(final_model, output_path)
312
- print(f"💾 Model saved to: {output_path}")
 
313
 
314
  return {
315
  'status': 'success',
@@ -512,9 +519,11 @@ def train_ensemble_models(
512
  }
513
 
514
  # Save for blending
 
515
  if output_path:
516
  if ARTIFACT_STORE_AVAILABLE:
517
- output_path = save_model_with_store(
 
518
  model_data={
519
  'base_models': dict(base_models),
520
  'meta_model': meta_model,
@@ -528,6 +537,13 @@ def train_ensemble_models(
528
  "num_base_models": len(base_models)
529
  }
530
  )
 
 
 
 
 
 
 
531
  else:
532
  os.makedirs(os.path.dirname(output_path), exist_ok=True)
533
  joblib.dump({
@@ -535,6 +551,7 @@ def train_ensemble_models(
535
  'meta_model': meta_model,
536
  'ensemble_type': 'blending'
537
  }, output_path)
 
538
 
539
  return {
540
  'status': 'success',
@@ -573,9 +590,11 @@ def train_ensemble_models(
573
  improvement = ensemble_metrics['r2'] - best_individual_metric
574
 
575
  # Save model
 
576
  if output_path:
577
  if ARTIFACT_STORE_AVAILABLE:
578
- output_path = save_model_with_store(
 
579
  model_data=ensemble,
580
  filename=os.path.basename(output_path),
581
  metadata={
@@ -585,10 +604,15 @@ def train_ensemble_models(
585
  "improvement_pct": float(improvement * 100)
586
  }
587
  )
 
 
 
 
588
  else:
589
  os.makedirs(os.path.dirname(output_path), exist_ok=True)
590
  joblib.dump(ensemble, output_path)
591
- print(f"💾 Ensemble model saved to: {output_path}")
 
592
 
593
  return {
594
  'status': 'success',
 
293
  }
294
 
295
  # Save model if output path provided
296
+ actual_model_path = None
297
  if output_path:
298
  if ARTIFACT_STORE_AVAILABLE:
299
+ # Save using artifact store (returns internal storage path)
300
+ actual_model_path = save_model_with_store(
301
  model_data=final_model,
302
  filename=os.path.basename(output_path),
303
  metadata={
 
308
  "test_metrics": test_metrics
309
  }
310
  )
311
+ # Also save to user-requested path for LLM to find it
312
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
313
+ joblib.dump(final_model, output_path)
314
+ print(f"💾 Model saved to: {output_path} (artifact store: {actual_model_path})")
315
  else:
316
  os.makedirs(os.path.dirname(output_path), exist_ok=True)
317
  joblib.dump(final_model, output_path)
318
+ actual_model_path = output_path
319
+ print(f"💾 Model saved to: {output_path}")
320
 
321
  return {
322
  'status': 'success',
 
519
  }
520
 
521
  # Save for blending
522
+ actual_model_path = None
523
  if output_path:
524
  if ARTIFACT_STORE_AVAILABLE:
525
+ # Save using artifact store (returns internal storage path)
526
+ actual_model_path = save_model_with_store(
527
  model_data={
528
  'base_models': dict(base_models),
529
  'meta_model': meta_model,
 
537
  "num_base_models": len(base_models)
538
  }
539
  )
540
+ # Also save to user-requested path for LLM to find it
541
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
542
+ joblib.dump({
543
+ 'base_models': dict(base_models),
544
+ 'meta_model': meta_model,
545
+ 'ensemble_type': 'blending'
546
+ }, output_path)
547
  else:
548
  os.makedirs(os.path.dirname(output_path), exist_ok=True)
549
  joblib.dump({
 
551
  'meta_model': meta_model,
552
  'ensemble_type': 'blending'
553
  }, output_path)
554
+ actual_model_path = output_path
555
 
556
  return {
557
  'status': 'success',
 
590
  improvement = ensemble_metrics['r2'] - best_individual_metric
591
 
592
  # Save model
593
+ actual_model_path = None
594
  if output_path:
595
  if ARTIFACT_STORE_AVAILABLE:
596
+ # Save using artifact store (returns internal storage path)
597
+ actual_model_path = save_model_with_store(
598
  model_data=ensemble,
599
  filename=os.path.basename(output_path),
600
  metadata={
 
604
  "improvement_pct": float(improvement * 100)
605
  }
606
  )
607
+ # Also save to user-requested path for LLM to find it
608
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
609
+ joblib.dump(ensemble, output_path)
610
+ print(f"💾 Ensemble model saved to: {output_path} (artifact store: {actual_model_path})")
611
  else:
612
  os.makedirs(os.path.dirname(output_path), exist_ok=True)
613
  joblib.dump(ensemble, output_path)
614
+ actual_model_path = output_path
615
+ print(f"💾 Ensemble model saved to: {output_path}")
616
 
617
  return {
618
  'status': 'success',