Skip to content

Latest commit

 

History

History
235 lines (175 loc) · 6.24 KB

File metadata and controls

235 lines (175 loc) · 6.24 KB

Bug Fix Summary - SimpleImputer AttributeError

Problem Statement

Error: 'SimpleImputer' object has no attribute '_fill_dtype' Location: /opt/render/project/src/src/pipeline/predict_pipeline.py:28 Root Cause: Scikit-learn version incompatibility between training and deployment environments

Technical Analysis

Why This Happened

  1. Version Mismatch: The pickled preprocessor.pkl was created with an older version of scikit-learn
  2. Internal Changes: Scikit-learn changed internal attributes between versions (specifically the _fill_dtype attribute in SimpleImputer)
  3. Render Update: Render's free tier automatically updated dependencies, installing a newer/different scikit-learn version
  4. Pickle Incompatibility: Python pickle files are NOT forward/backward compatible across library versions

The Specific Issue

# In predict_pipeline.py line 28
data_scaled = preprocessor.transform(features)  # ← Fails here

# The preprocessor contains SimpleImputer that was pickled with old sklearn
# New sklearn version doesn't recognize old internal attributes
# Result: AttributeError

Solutions Implemented

1. ✅ Pinned Dependencies (requirements.txt)

Before:

scikit-learn
pandas
numpy
...

After:

scikit-learn>=1.3.0,<1.8.0
pandas>=2.0.3,<3.0.0
numpy>=1.24.3,<2.0.0
...

Why: Ensures consistent versions across environments while allowing patch updates

2. ✅ Automatic Model Retraining (retrain_models.py)

Created a comprehensive retraining script that:

  • Runs complete data ingestion pipeline
  • Regenerates preprocessor with current sklearn version
  • Retrains model with best hyperparameters
  • Saves new pickle files compatible with deployment environment

3. ✅ Build Script for Render (build.sh)

#!/bin/bash
# Automatically runs during Render deployment
pip install -r requirements.txt
python retrain_models.py  # Regenerates models with correct versions

Why: Ensures models are always compatible with the deployed sklearn version

4. ✅ Production Server Setup (start.sh)

gunicorn --bind 0.0.0.0:$PORT --workers 2 --timeout 120 app:app

Why:

  • Flask development server is not production-ready
  • Gunicorn handles multiple requests efficiently
  • Proper timeout prevents hanging requests

5. ✅ Enhanced Error Handling (src/utils.py)

Added detailed logging for version mismatch issues:

except AttributeError as ae:
    logging.error("This is likely due to scikit-learn version incompatibility.")
    logging.error("Please retrain the model with the current environment.")

Why: Better debugging and clearer error messages

Deployment Instructions for Render

Step 1: Update Repository

git add .
git commit -m "Fix sklearn version incompatibility - add auto-retrain"
git push origin main

Step 2: Configure Render Dashboard

Go to your Render service settings:

Build Command:

bash build.sh

Start Command:

bash start.sh

Step 3: Deploy

Render will automatically:

  1. Install pinned dependencies
  2. Run retrain_models.py to generate compatible pickle files
  3. Start the app with gunicorn

Step 4: Verify

Test the prediction endpoint - should work without errors!

Prevention Strategy

For Future Updates

  1. Never update sklearn alone - Update all dependencies together
  2. Always retrain after dependency updates - Run python retrain_models.py
  3. Test locally first - Verify before deploying
  4. Use version ranges carefully - Pin major.minor, allow patch updates

Monitoring

Check Render logs for:

RETRAINING PIPELINE COMPLETED SUCCESSFULLY
R2 Score: [score]

If you see this, deployment succeeded!

Files Modified

File Status Purpose
requirements.txt ✏️ Modified Pinned all dependency versions
src/utils.py ✏️ Modified Enhanced error handling
.gitignore ✏️ Modified Added artifacts documentation
retrain_models.py ✨ Created Model retraining script
build.sh ✨ Created Render build automation
start.sh ✨ Created Production server startup
DEPLOYMENT.md ✨ Created Deployment guide
FIX_SUMMARY.md ✨ Created This document

Testing Checklist

  • Requirements pinned
  • Build script created
  • Start script created
  • Retraining script created
  • Error handling enhanced
  • Deploy to Render
  • Test prediction endpoint
  • Verify logs show successful retraining
  • Test with multiple predictions

Troubleshooting

If error persists after deployment:

  1. Check Render logs for build errors
  2. Verify build.sh ran - look for "RETRAINING" messages
  3. Check file permissions - chmod +x build.sh start.sh
  4. Force clean deploy - Delete artifacts folder in Render shell
  5. Check Python version - Should be 3.10 or 3.11

Common Issues:

Q: Build timeout? A: Increase timeout in Render settings (can take 5-10 min for GridSearchCV)

Q: Still getting AttributeError? A: Models didn't retrain. Check build logs. May need to delete old artifacts manually.

Q: Different error now? A: Check that all dependencies installed. Verify requirements.txt syntax.

Expected Behavior After Fix

✅ Application starts successfully ✅ Prediction endpoint responds ✅ No AttributeError ✅ Predictions return correct format ✅ Logs show model loaded successfully

Performance Notes

  • First deployment will take longer (model training ~5-10 minutes)
  • Subsequent deployments reuse artifacts if they exist
  • Gunicorn provides better performance than Flask dev server
  • 2 workers handle concurrent requests efficiently

Architecture Overview

User Request
    ↓
Gunicorn (2 workers)
    ↓
Flask App
    ↓
PredictPipeline
    ↓
Load preprocessor.pkl (compatible sklearn version) ✅
    ↓
Load model.pkl (compatible sklearn version) ✅
    ↓
Transform & Predict
    ↓
Return Result

Conclusion

This fix ensures long-term stability by:

  1. Controlling dependency versions
  2. Automatically regenerating models on deployment
  3. Using production-grade server
  4. Providing clear error messages
  5. Documenting the entire process

The app should now work reliably on Render! 🎉