Memory Leak in Logistic Regression.

### Describe the bug

Extreme RAM spike and OOM after upgrade (0.24.2 → 1.1.1) for ultra‑wide sparse L1 Logistic Regression (liblinear & saga) – baseline 680 GB → >1.4 TB (ref #28993)



Summary

After upgrading scikit‑learn and Python, fitting an L1 Logistic Regression on a very large, sparse, high‑dimensional dataset now triggers a massive memory spike (baseline ~680 GB → allocates >1.4 TB → OOM). Previously (with 0.24.2) peak memory stabilized around 750–770 GB for the same data shape. Switching solvers (liblinear → saga) and using SGDClassifier did not resolve the issue.



Workload Scale

Samples: ~7,500,000

Features: ~550,000

Binary classification, L1 regularization

Input matrix: sparse (CSR)



Environments

Stable (old):

Python 3.9

scikit-learn 0.24.2

numpy 1.23.5

scipy 1.7.1

Peak during fit: ~750–770 GB



Problematic (new):

Python 3.10

scikit-learn 1.1.1

scipy 1.14.1

numpy 1.23.5

Baseline resident memory before calling .fit: ~680 GB (holding data & process)

During .fit: climbs rapidly past ~1.4 TB → OOM



Models Tried

Original:

Python

LogisticRegression(

    solver='liblinear',

    C=1.0,

    penalty='l1',

    intercept_scaling=3.0,

    random_state=123,

)



Alternative:

Python

SGDClassifier(

    loss='log_loss',

    penalty='l1',

    alpha=1.0,

    random_state=123,

)



Attempt with saga (still spikes):

Python

LogisticRegression(

    solver='saga',

    C=1.0,

    penalty='l1',

    max_iter=1000,

    n_jobs=-1,

    random_state=123,

)



New Observation

Memory right before training (after data load / preprocessing) sits around 680 GB.

Training triggers a single large jump rather than gradual leakage across multiple fits.

This suggests a large dense working allocation or multiple parallel buffers rather than slow accumulation.



Questions

Are there known regressions or algorithmic changes between 0.24.2 and 1.1.1 that increase memory for sparse, high‑feature L1 logistic regression (liblinear or saga)?
Does liblinear (L1) or saga under certain conditions implicitly densify parts of X at this scale?
Could n_jobs=-1 for saga (or OpenMP threads) multiply large temporary buffers? Is single-thread execution recommended for memory control here?
Is intercept_scaling=3.0 relevant for any hidden copy or augmentation step that becomes costly at extreme dimensionality?
Are there scipy 1.14.1 sparse changes that alter memory layout or workspace usage compared to what 0.24.2 relied on?
Recommended solver / pipeline for this regime (7.5M × 550k, very sparse, L1): saga vs SGD vs feature hashing + SGD vs dimensionality reduction first?
Would upgrading to a newer scikit-learn (1.5.x / 1.6.dev) likely help (any memory PRs touching saga/liblinear)?


### Steps/Code to Reproduce

LogisticRegression(
    solver='liblinear',
    C=1.0,
    penalty='l1',
    intercept_scaling=3.0,
    random_state=123,
)

### Expected Results

The peak memory usage should be below 780Gb. 

### Actual Results

The memory is exceeding 1.5Tb

### Versions

```shell
old: 0.24.2
new: 1.1.1
```

COMMENT:
Thanks @adrinjalali, The issue is fixed with following changes.

numpy==2.2.6
pandas==2.3.3
scikit-learn==1.7.2
scipy==1.15.3

The code is unchanged.

Labels: Bug, Needs Info, Needs Reproducible Code