Using the same preprocessing code for both training and inference in sagemaker
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The safest way to keep SageMaker training and inference consistent is to put preprocessing logic in one shared code path and reuse it in both places. If training normalizes one way and inference normalizes another, the model is effectively seeing different features in production than it saw during fitting.
Separate Stateless Logic From Fitted State
Preprocessing usually has two parts:
- stateless transformations, such as trimming strings, selecting columns, or parsing timestamps
- fitted state, such as category mappings, means and standard deviations, or token vocabularies
The stateless logic should live in shared code that both training and inference import. The fitted state should be learned during training, saved as an artifact, and loaded again during inference.
That design avoids a very common mistake: copying the same transformation code into two files and then letting them drift apart over time.
Put Shared Logic in a Common Module
A simple project layout might look like this:
The shared preprocessing module can expose functions for fitting and transforming:
Now there is one definition of the cleaning and feature ordering logic.
Reuse It During Training
Your training entry point should call the shared functions, fit the preprocessor, train the model, and save both artifacts into the SageMaker model directory.
The important detail is that the training script saves the fitted preprocessor, not just the model weights.
Reuse the Same Logic During Inference
In SageMaker inference, load both the model and the preprocessor from the model artifact. Then call the same shared transform function before prediction.
That is the core pattern: one preprocessing module, one saved fitted preprocessor, one consistent transform path.
Why This Matters in SageMaker
SageMaker does not automatically guarantee that your training-time feature engineering and inference-time feature engineering match. It gives you the infrastructure hooks, but you still need to structure the code correctly.
Common mismatches include:
- columns reordered between training and inference
- missing values filled differently
- category encoding learned on training but rebuilt incorrectly at serving time
- normalization applied in one path and forgotten in the other
The shared-module approach removes most of those risks.
Consider Using a Pipeline Object
If you are using scikit-learn, a Pipeline or ColumnTransformer can make this even cleaner because the fitted preprocessing and model travel together as one artifact.
You can fit and serialize that pipeline directly. In many SageMaker setups, that is the simplest way to ensure training and inference do exactly the same thing.
Common Pitfalls
The biggest pitfall is duplicating preprocessing logic in train.py and inference.py. The code starts identical, then one side changes and the model begins receiving different features in production.
Another common mistake is saving only the model and forgetting the fitted preprocessing state. If your encoder or scaler is rebuilt from scratch during inference, predictions can become meaningless.
Hardcoding feature order is another source of subtle bugs. Keep the feature-selection logic in one place so the same columns and order are used everywhere.
Finally, be clear about where preprocessing should run. For lightweight tabular transforms, putting the logic inside the model artifact is usually fine. For heavy image, NLP, or multi-stage ETL workflows, a separate SageMaker Processing or serial inference step may be cleaner.
Summary
- Put shared preprocessing logic in a reusable module.
- Learn preprocessing state during training and save it with the model artifact.
- Load the same preprocessor during SageMaker inference.
- Avoid duplicating feature engineering code across training and serving paths.
- If possible, serialize a single pipeline object so preprocessing and prediction stay coupled.

