nemo_automodel.components.speculative.streaming.store
nemo_automodel.components.speculative.streaming.store
Pluggable data-plane transport for the speculative-training stream.
The :class:FeatureStore ABC abstracts where the supervision tensors actually
live — an in-process dict for build/test, a POSIX shared mount for
multi-node/colocated, or NCCL for GPU-to-GPU in later PRs. The
:class:SampleRefQueue reads the store’s :meth:FeatureStore.health to
decide whether to back off.
The contract is deliberately small (5 methods + 1 property) so PR 2 and later have an obvious surface to extend:
- :meth:
put— produce-side: stash tensors for a sample. - :meth:
get— consume-side: materialize them; returns a :class:StoreHandlethe consumer must hand to :meth:releaseonce it’s done with them. - :meth:
release— consume-once: free / drop the materials. - :meth:
gc— sweep partially-released handles (a stale lease, a crashed consumer) so the store cannot leak. - :meth:
health— ints only; the queue uses these for backpressure. - :meth:
close— dispose store resources at shutdown.
Module Contents
Classes
Functions
Data
API
Abstract transport every feature-store backend implements.
Implementations must be safe to call from one thread per operation;
cross-thread concurrency is the queue’s responsibility and outside this
contract. The :class:~nemo_automodel.components.speculative.streaming.queue.SampleRefQueue
uses :meth:health for backpressure; everything else is the
produce/consume pair plus release / gc for lifecycle.
Release every resource owned by the store (file handles, NCCL groups, …).
After close, all subsequent calls raise :class:RuntimeError.
Idempotent with respect to an already-closed store.
Sweep stale entries (e.g. failed releases from a crashed consumer).
Returns the number of entries reclaimed. Called opportunistically by
the :class:SampleRefQueue between leases and unconditionally by
:meth:close.
Materialize ref’s tensors on device and hand back a :class:StoreHandle.
The returned tensors are detached copies (clone for cuda
tensors, plain detach for CPU views) so prefetch cannot observe
aliasing through :meth:release. Returns one tensor per key in
:attr:SampleRef.feature_keys, in the same insertion order, so the
consumer can wire them straight into the per-algorithm batch.
Return a ints-only :class:StoreHealth snapshot for backpressure.
Must not block on tensor I/O (no .cpu(), no .to()); in-memory
counters are sufficient. Backends that do background I/O MUST serve
:meth:health from cached counters, not from the in-flight I/O
thread.
Stash tensors for sample_id and return a tensor-free :class:SampleRef.
The producer-side metadata (run_id, algorithm, schema_version,
target_model_version, draft_weight_version, num_tokens) is
the data the :class:SampleRef carries on the control plane, so the
store must accept it here even though it does not inspect the values
beyond building the ref. Consumers see the ref unchanged.
Implementations must validate that the tensors match what they
declare (dtype, shape per feature, numel * element_size
summed across features == ref.estimated_bytes) and reject the
put with a specific exception when they do not, before any partial
write is observable.
Free the resources backing handle; idempotent.
After this returns, the sample is no longer present in the store and
a second :meth:get on the same :class:SampleRef raises
:class:KeyError. gc retries releases that a previous call
rejected (e.g. transient I/O), so the queue can rely on
gc + release being idempotent + retriable.
Opaque token the consumer must return to :meth:FeatureStore.release.
Each :meth:FeatureStore.get mints a fresh handle with a unique
:attr:handle_id. Two get calls on the same sample return two
distinct handles; :meth:FeatureStore.release matches against
handle_id so releasing one handle twice (or releasing a stale
handle after a sibling has been acquired) cannot decrement a
sibling’s outstanding count.
Holds the producing store, the sample id, the originating
:class:SampleRef, and the per-get handle identity.
Integers-only snapshot of store residency for backpressure decisions.
Mint a fresh :attr:StoreHandle.handle_id (module-level counter).