mlflow How to save a sklearn pipeline with custom transformer?
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
Saving a scikit-learn pipeline with a custom transformer in MLflow requires that the custom transformer class is importable at load time. The standard approach is to define your custom transformer in a separate module (not in a notebook or __main__), then log the pipeline with mlflow.sklearn.log_model(). If the transformer lives in __main__, MLflow cannot deserialize it on load. The solution is to either package the transformer as a module or use MLflow's code_path parameter to include the source file.
The Problem
The issue is that pickle (used by MLflow's sklearn flavor) stores the module path of the class. If the class is in __main__, it cannot be found during deserialization in a different process.
Solution 1: Define Transformer in a Separate Module
The key requirement is that custom_transformers must be importable when loading the model — it must be installed as a package or on the Python path.
Solution 2: Use code_path Parameter
Include the source file with the model artifact:
When loading, MLflow adds the code_path files to sys.path, making the custom classes importable:
Solution 3: Package as a Python Module
For production, package your transformers as an installable module:
Solution 4: Use MLflow's Pyfunc Flavor
For maximum portability, wrap the pipeline in a custom pyfunc model:
Custom Transformer with Parameters
Scikit-learn requires get_params() and set_params() to work with Pipeline, GridSearchCV, and serialization. BaseEstimator provides default implementations that use __init__ parameter names.
Complete Example
Common Pitfalls
- Defining custom transformers in
__main__: Pickle stores the module path. If the class is in__main__(a notebook cell or the main script), it cannot be deserialized in a different process. Always define custom transformers in importable modules. - Forgetting
code_path: Withoutcode_path, the model artifact does not include your custom code. Loading the model in a different environment fails withModuleNotFoundError. Always specifycode_pathor install the transformer module. - Mismatched
__init__parameters andget_params: Scikit-learn's defaultget_params()inspects__init__parameter names. If__init__takesself.thresholdbut you setself._threshold, cloning and serialization break. The attribute name must match the parameter name. - Stateful transformers without
fit: If your transformer learns from data (e.g., computes mean/std), those fitted attributes must be serializable. Avoid storing non-picklable objects (database connections, file handles) as fitted attributes. - Version mismatches: The scikit-learn version used to save the model must match the version used to load it. Log the version with
mlflow.log_param("sklearn_version", sklearn.__version__)and specify it inpip_requirements.
Summary
- Define custom transformers in separate importable modules, not in
__main__ - Use
code_path=["my_module.py"]inmlflow.sklearn.log_model()to bundle custom code - For production, package transformers as installable Python packages
- Inherit from
BaseEstimatorandTransformerMixinfor scikit-learn compatibility - Ensure
__init__parameter names match attribute names forget_params()to work - Use
mlflow.pyfunc.log_model()for maximum portability across environments
Related reading
- MLPReLu stops learning after few iterations. Tensor Flow
- mnist CNN ValueError expected min_ndim4, found ndim3. Full shape received 32, 28, 28
- Mnist recognition using keras
- MobileNet vs SqueezeNet vs ResNet50 vs Inception v3 vs VGG16
- mlflow.exceptions.MlflowException Changing param values is not allowed. Param with key'input_rows' was already logged with value'32205
- Mnist dataset splitting
- module 'tensorflow' has no attribute 'logging
- MongoDB Community Kubernetes Operator and Custom Persistent Volumes

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.