nemo_automodel.components.speculative.streaming.refs
nemo_automodel.components.speculative.streaming.refs
Tensor-free control-plane contracts for the speculative-training stream.
Per the train-inference disaggregation RFC (issue #3062), every produced sample
is split into a tensor-free reference (this module) and the actual supervision
tensors, which live in a pluggable :mod:store. References hop between the
target-side producer and the draft-side consumer over queues, HTTP, and
checkpoint metadata — places where serializing a :class:torch.Tensor would be
either expensive or wrong.
Three guarantees back this module:
- :func:
assert_no_tensorsenforces “no tensors” recursively on every public object exposed from this package, so a producer that slipped a tensor into a queue or ref trips a validation error before it lands on a wire. - :class:
SampleRefis a frozen dataclass. Once placed on a queue, a ref cannot be mutated under the holder, so the consumer is guaranteed to see the same feature keys the producer promised. - :class:
FeatureSpeccarriesdtype+shape(and nothing else), the minimum metadata a consumer needs to preallocate the receive buffer before materializing the tensor — mirroring how :func:nemo_automodel.components.speculative.eagle.remote.protocol.encode_nccl_metadataalready ships dtype + shape ahead of an NCCL recv so the client can allocate.
Module Contents
Classes
Functions
Data
API
Bases: enum.Enum
Which speculative-decoding draft family produced this sample.
The on-wire string value (eagle3 / dflash / dspark) is the
stable schema key the consumer matches against. New algorithms land by
adding a member here plus a schema row in the RFC’s “Feature schema per
algorithm” table; both moves are part of the same change.
Shape + dtype metadata for one named feature in a :class:SampleRef.
Mirrors the {dtype_code, shape} pair the EAGLE-3 remote protocol
encodes in :func:nemo_automodel.components.speculative.eagle.remote.protocol.encode_nccl_metadata
so the client can preallocate the NCCL receive buffer. Consumers here use
it to preallocate the receive tensor before calling
:meth:FeatureStore.get.
Tensor-free reference to one produced sample in a feature store.
Return the feature names in insertion order.
The order is significant because some algorithms size the draft’s
fc projection by the order of the aux hidden states, not just
their count; the producer chooses the order once, the ref freezes it,
and the consumer preserves it through :meth:FeatureStore.get.
Required feature-name set per algorithm (RFC “Feature schema per algorithm”).
Mirrors the “Required feature keys” column of the RFC’s schema table. PR 2 widens this into a typed registry that also validates per-key dtypes / shapes; PR 1 only checks that the producer named the right set.
Recursively validate that obj carries no tensors.
Walks dataclasses (any nested dataclass included), dict with str
keys, and list / tuple. Anything else must be a primitive
(str/int/float/bool/None/bytes) — a tensor, numpy
array, or duck-typed tensor-like (has data_ptr + is_cuda + numel) at
any depth raises :class:ValueError.
The check is structural, not nominal: a third-party tensor type that quacks like one is rejected. PR 2’s registry / schema validators layer on top of this primitive guard, not instead of it.