Avatar for the Nixtla user
Nixtla
mlforecast
BlogDocsChangelog

Performance History

Latest Results

perf(pooled): reduce time and memory usage (#728)
main
12 hours ago
Fix transfer conformal edge cases
janrth:bug/interval_transfer
23 hours ago
Remove report demo notebook
janrth:feat/model_report
1 day ago
fix: fit the real estimator in the ray worker Addresses the review on #731. The training loop now builds and fits the library's own estimator in the worker and checkpoints it, as lightgbm.dask's _train_part does, instead of checkpointing a bare Booster and synthesizing a local estimator from it on the driver. The checkpoint carries the estimator next to ray's standard booster artifact, so RayTrainReportCallback keeps reporting per-iteration metrics and get_model still works on the result. The models are LGBMRegressor / XGBRegressor subclasses again, so clone() and isinstance() work as they did on main, and all of the parameter handling is the library's: - lightgbm's objective aliases are honored rather than dropped by a setdefault on the canonical name - all 11 num_iterations aliases resolve, with lightgbm's own precedence - the random_state -> seed translation is gone; xgb.train knows the name - model_ keeps the user's params and the booster's scores, because it is the estimator that was fitted rather than one rebuilt from native params That removes get_params, set_params, _translate_params, _pop_num_boost_round and the 11 private attribute writes of the graft. Two fixes on top: - lightgbm needs tree_learner=data_parallel and ray's network params, or each worker trains an independent model on its own shard and rank 0's is the one checkpointed, with no error anywhere. xgboost is unaffected; XGBoostConfig wraps the loop in a CommunicatorContext. - the booster's thread pool is sized from the worker's assigned CPUs, as lightgbm_ray and xgboost_ray did, rather than from every core on the node. xgboost keeps callbacks as a parameter, so the ray reporting callback is cleared before the estimator is reported; otherwise it would ride back to the driver and into DistributedMLForecast.save's pickle.
ray-train-v2-migration
2 days ago
fix(pooled): address review -- NaN rows, update() folds, key bound, std centring Row kernels skip NaN targets. `_CellStore` already dropped them at aggregation but `_RowStore` kept every row, so one NaN in a window poisoned the whole quantile (and the expanding one for good) and NaN rows counted toward `min_samples`. The quantile kernels now gather from a cached NaN-free view of the rows; `LookupLag` keeps reading every row, since a NaN occurrence is still an occurrence there, as on main. `TimeSeries.update` advances the pooled accumulators. `Expanding*`/EWM fold one source cell per `PooledState.update`, which predict calls once per timestamp; `_update_pooled_states` only appended columns, so the next predict folded the newest source and skipped the ones in between (the last fitted timestamp among them). The same call is now made once per appended timestamp. An update with no new rows is a no-op instead of an error. `_RowStore` keys are `bucket * 2**32 + ordinal` with the bucket count bounded (and checked) at 2**31 instead of an unenforced 2**23; `search` clamps targets before the calendar so a window reaching back past ordinal 0 cannot cross into the bucket before. `sumsq` is centred per bucket on the bucket's first observed cell, carried by the store across trims, appends and bucket growth, and `_StdKernel` combines the shifted sums. The plain formula lost three significant figures at `y ~ 1e6 +- 1`; the relative error against an extended-precision reference drops from ~2e-3 to ~1e-9. Each `time_agg` view carries a centre of its own. Also replaces the tautological positional check in `test_polars_join_preserves_row_order` with `uniques[bids]` reconstructing the per-row keys. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0138Wd4g3r3EX4kEoo3V8WDx
feat/pooled-keys-memory
2 days ago
fix: maintain Expanding*/EWM state in TimeSeries.update `Expanding*` and `ExponentiallyWeightedMean` carry a running accumulator (`stats_`) that coreforecast advances by one observation per `update` call, reading the value `lag` positions from the end. `TimeSeries.update` appended several values at once and advanced nothing, so the accumulators stayed behind by the number of appended timestamps, and an update that introduced a new serie left `stats_` with fewer rows than groups. Fold the appended values into the accumulators one timestamp at a time, over a per-serie window of the last `max_lag` stored values followed by the new ones. Series that run out of appended values get their `stats_` rows restored after each step, since coreforecast advances every group. New series are handled after the fold by priming a copy of each transform with `transform` over their own values, which also takes care of the reordering when a new id sorts into the middle. Recomputing the state instead isn't possible, `keep_last_n` has already dropped the history the accumulator summarizes. Also fix the `keep_last_n` inference for these transforms: they reported `update_samples=1` but each update reads the value `lag` back, so at a lag above the largest plain lag the trim left too little history and every predicted value was null. Closes #726 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MXQFsD8TDT7L4cv8dLtSjg
fix/update-stateful-lag-transforms
3 days ago

Latest Branches

CodSpeed Performance Gauge
0%
fix: support dynamic exogenous features in transfer intervals#722
23 hours ago
070e358
janrth:bug/interval_transfer
CodSpeed Performance Gauge
0%
1 day ago
8f542d4
janrth:feat/model_report
CodSpeed Performance Gauge
0%
2 days ago
e39dc3f
ray-train-v2-migration
© 2026 CodSpeed Technology
Home Terms Privacy Docs