keras model.fit_generator several times slower than model.fit
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
If model.fit_generator is much slower than model.fit, the bottleneck is usually not the optimizer or the network itself. The slowdown almost always comes from how batches are produced, transferred, decoded, or augmented before the model sees them.
Why fit_generator can be slower
Historically, model.fit worked with in-memory arrays and model.fit_generator worked with Python generators. In modern Keras, fit_generator is effectively folded into model.fit, but the performance difference still matters because Python-driven input pipelines behave very differently from preloaded arrays.
With in-memory arrays, the model can consume batches with very little overhead:
If the data is already in RAM as NumPy arrays, there is no per-batch file read, image decode, Python loop, or user-defined augmentation function in the hot path.
By contrast, a generator may do some or all of the following every batch:
- read files from disk
- decode images
- resize or normalize data
- allocate new arrays
- run Python code under the GIL
- wait for the next batch before the GPU can continue
That is why training can become several times slower even with the same model.
A slow generator pattern
The following style is common and often underperforms:
This works, but it does all preprocessing synchronously in Python. If the model finishes a training step before the next batch is ready, the accelerator sits idle.
Better options: Sequence and tf.data
If you need Python-side loading, keras.utils.Sequence is safer than a bare generator because it is indexable and works better with multiprocessing.
Even better, use tf.data when possible:
prefetch lets the input pipeline prepare future batches while the current batch is training, which is one of the easiest wins for throughput.
When the generator overhead dominates
The gap is especially noticeable when the model is small or the hardware is fast. If each training step takes only a few milliseconds, input overhead becomes a large percentage of total step time.
For example, a compact CNN on cached images may train quickly, so repeated Python-level augmentation can dominate runtime. On the other hand, a very large transformer may hide some generator cost because the compute phase is much longer.
That is why the right question is not "Why is fit_generator always slower?" but "Is my input pipeline slower than my model?"
Practical ways to speed it up
Several fixes usually help:
- move from a plain generator to
Sequenceortf.data - precompute expensive preprocessing steps
- store data in a format optimized for sequential reads
- use parallel mapping and prefetching
- avoid Python loops in per-sample transforms when vectorization is possible
A typical image pipeline with tf.data might look like this:
This usually outperforms a Python generator because TensorFlow can pipeline and parallelize the work more effectively.
Common Pitfalls
- Comparing in-memory arrays against a generator that reads files from disk and expecting equal speed.
- Using a Python generator for work that
tf.datacan pipeline more efficiently. - Measuring model speed without checking whether the GPU is waiting on input.
- Keeping expensive augmentations in the training loop when they could be cached or vectorized.
- Treating
fit_generatoras a separate modern API. In current Keras,model.fitalready handles generator-like inputs.
Summary
- Generator-based training is often slower because input preparation happens batch by batch.
- The slowdown is usually caused by Python, disk I/O, decoding, or preprocessing overhead.
- '
keras.utils.Sequenceis safer than a bare generator for batch loading.' - '
tf.datawith batching and prefetching is usually the best long-term pipeline.' - The smaller and faster the model, the more visible input pipeline overhead becomes.
Related reading
- Keras model.predict always 0
- Keras model.predict function giving input shape error
- Keras model.predict slower on first iteration then gets faster
- Keras model.summary object to string
- Keras model.fit with tf.dataset API validation_data
- keras model.fit with validation data - which batch_size is used to evaluate the validation data?
- Keras not using full CPU cores for training
- Keras shows no Improvements to training speed with GPU partial GPU usage?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
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.