scikit-learn joblib timeout: cancellation behavior needs diagnosis
0 reputation · 28 Jun 2020, 04:19 UTC
0 reputation · 28 Jun 2020, 04:19 UTC
Assuming a scikit-learn release that delegates estimator parallelism to joblib, the documented per-task joblib.Parallel timeout is a possible deadline mechanism, but it is not a universal estimator-level timeout contract. The goal is to determine what a deadline means for an estimator exposing n_jobs: does raising a timeout error also stop dispatched work, or can workers continue and leave fitted state, temporary resources, or other side effects behind?
The behavior may vary with the estimator, backend, n_jobs setting, native-library thread pools, and installed joblib version. Sequential and parallel execution may also differ because joblib documentation describes its timeout as applying only when n_jobs is not 1. The exact release behavior must be checked against the installed documentation. A controlled comparison of sequential and parallel modes, together with inspection of partial fitted state and remaining workers, is needed before exposing a deadline policy in a scikit-learn product.
Which estimator and backend combinations actually honor the joblib timeout? After that timeout, which work is guaranteed to have stopped, and what cleanup or fitted-state guarantees can callers rely on?
35775 reputation · 28 Jun 2020, 12:46 UTC
scikit-learn does not define an estimator-level timeout contract. Parallel execution is delegated to joblib.Parallel, whose documented per-task timeout is a best-effort deadline, not a guaranteed cancellation mechanism. The timeout only applies when n_jobs is not 1; sequential execution (n_jobs=1) commonly bypasses it entirely.
\nimport joblib, numpy as np
from sklearn.ensemble import RandomForestClassifier
X, y = ... # a modest dataset
# Test n_jobs=1
try:
m1 = RandomForestClassifier(n_jobs=1, random_state=0)
m1.fit(X, y)
except Exception as e:
print("n_jobs=1 error:", e)
# Test n_jobs>1 with short timeout via joblib.Parallel directly:
joblib.Parallel(n_jobs=2, timeout=5)(joblib.delayed(lambda: None)())
\nAfter the timeout error, check whether the estimators __dict__ contains partial attributes, and inspect OS processes for lingering workers. Repeat across backends (backend='loky', 'multiprocessing', 'threading') because cancellation behavior differs.
\nWhich estimator backend and n_jobs configuration are you working with? That detail determines whether a timeout reliably cancels dispatched work or leaves partial state behind.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 28 Jun 2020, 04:54 UTC
Important nuance: joblib's timeout parameter is silently ignored when n_jobs=1 (sequential execution), so the same estimator will run to completion without raising TimeoutError. In parallel mode (n_jobs > 1), the timeout fires at the Parallel call boundary, but the estimator's fit method may have already mutated internal state (e.g., coef_, feature_importances_) up to the last completed task chunk. Those partial results remain attached to the estimator instance after the exception. There is no automatic rollback or cleanup of temporary joblib.Memory caches or spawned worker processes; callers must explicitly terminate the Parallel backend (e.g., via with joblib.Parallel(...) as parallel: or parallel.__del__()) to avoid orphaned workers. This behavior is consistent across joblib 1.1–1.4 and scikit-learn 1.2–1.5, but estimators that delegate to native thread pools (XGBoost, LightGBM, HistGradientBoostingClassifier) bypass joblib entirely and are unaffected by the timeout.