Skip to content

[Claude-led] Feature/inference - #8

Draft
dougbrn wants to merge 8 commits into
devfrom
feature/inference
Draft

dougbrn wants to merge 8 commits into
devfrom
feature/inference

Conversation

@dougbrn

@dougbrn dougbrn commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator

Change Description

Inference path from the initial design (§7). Stacked on the training PR; merge that first.

Solution Description

  • predict(catalog, model, spec, outputs, ...) returns a lazy lsdb.Catalog with prediction columns and correct meta.
  • ModelDeployment / ModelPlugin: a Dask WorkerPlugin builds the model once per worker from a ModelSpec (factory + weights path, or an in-memory module). It loads plain state dicts or TrainSession checkpoints, switches to eval(), and moves to the device resolved on the worker. Without a distributed client, the model is built once in-process for the synchronous/threaded schedulers.
  • Alignment by construction: each partition is processed in order with task-local state only (no shared mutable dataset, as in the hyrax#1062 prototype). Predictions are attached by position to the same frame, never joined on _healpix_29, and row counts are checked per batch.
  • Example: docs/examples/predict_on_catalog.py.

Tests: alignment after a filter that empties partitions plus reordering, duplicate _healpix_29 values, one model build per worker across many partitions, meta dtypes matching computed dtypes, nested inputs, and clear failures for wrong row counts and closed deployments.

🤖 Generated with Claude Code

dougbrn and others added 8 commits October 15, 2026 11:58
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ColumnSpec maps flat and nested catalog columns to tensors. resolve()
validates against catalog meta (nested sub-column dtypes come from
NestedDtype.column_dtypes) without computing data, and reports every
problem at once. Nested columns are padded to the batch maximum with a
mask and lengths, fully vectorized via nest.len() and nest.to_flat().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Partitions are sharded across DDP ranks and DataLoader workers from a
shared per-epoch permutation, so every row is read exactly once per
epoch for any worker count and world size. Each shard streams its
partitions through lsdb's CatalogStream; batches are cut within a chunk
and never span chunks. Supports fixed epochs and open-ended streaming.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Context-manager session modeled on Hyrax's train_stream: iterate
(batch, metrics), stop(), close() returns the model. The optimization
step is a user callable (SupervisedStep covers the common case).
Periodic and final atomic checkpoints, rank-0 only; DDP runs under
model.join() so uneven batch counts across ranks do not hang.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ModelSpec ships only a factory and weights path; each worker builds
the model once in its WorkerPlugin setup, loads weights (plain state
dicts or TrainSession checkpoints), switches to eval and moves to the
device resolved on the worker. OutputSpec builds output meta and
validates every batch's output shape against it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each partition is processed in order with task-local state only and
predictions are attached by position to the same frame, so output is
aligned with input even for duplicate _healpix_29 values. Tests cover
a filtered and reordered partition layout, duplicate indices, and
load-once-per-worker; a reversed-batch mutation fails them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dougbrn
dougbrn changed the base branch from main to dev October 15, 2026 19:46
@codecov

codecov Bot commented Oct 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.03730% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.06%. Comparing base (c9ed114) to head (fe19bcf).

Files with missing lines Patch % Lines
src/lsdb_ml/spec.py 95.79% 9 Missing ⚠️
src/lsdb_ml/data/source.py 91.07% 5 Missing ⚠️
src/lsdb_ml/device.py 86.36% 3 Missing ⚠️
src/lsdb_ml/inference/plugin.py 96.29% 3 Missing ⚠️
src/lsdb_ml/training/checkpoint.py 90.62% 3 Missing ⚠️
src/lsdb_ml/training/session.py 97.16% 3 Missing ⚠️
src/lsdb_ml/training/steps.py 91.17% 3 Missing ⚠️
src/lsdb_ml/inference/outputs.py 96.77% 2 Missing ⚠️
src/lsdb_ml/collate.py 98.00% 1 Missing ⚠️
src/lsdb_ml/data/dataset.py 98.50% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@             Coverage Diff             @@
##               dev       #8      +/-   ##
===========================================
- Coverage   100.00%   96.06%   -3.94%     
===========================================
  Files            2       18      +16     
  Lines            7      864     +857     
===========================================
+ Hits             7      830     +823     
- Misses           0       34      +34     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant