nemo_rl.data_plane.tq_token_sink#
TransferQueue implementations of NeMo-Gym’s token staging protocols.
TQStagingStore is NeMo RL’s single keyed-row transport for token custody.
Both vLLM and MInf write canonical Gym call deltas through TQTokenSink.
This module is the only hot-path file that knows tokens live in TQ; Gym sees
opaque staging keys.
Each staged row carries three jagged columns (token_ids_delta,
token_mask_delta, generation_logprobs_delta), the complete receipt
identity/lineage metadata, and all digest inputs so it round-trips to a
normally validated StagedCallBaseSnapshot. On media-enabled partitions the
same put also carries the processed media the engine ran on (see
MEDIA_STAGING_FIELDS), so staged coordinates acknowledge tokens and
pixels together. Masks/logprobs are float32 on
the wire, matching compute_staging_digest’s float32-bit-pattern scheme, so
digest recomputation over fetched values is byte-exact. Route payloads never
ride inside snapshots: the source returns them as separate RouteFragment
values keyed by staging key, digest-verified by the plan executor at point of
use. With policy.generation.top_logprobs the worker adds two more jagged
columns to the same staging put through the opaque attachment mapping: the
sampler’s top-k ids and log-probs of the call’s generated tokens. They are not
digest-covered; the finalizer checks their shape against the generated length.
Module Contents#
Classes#
One staged call’s validated media bundle, in the engine’s native shapes. |
|
One explicitly identified small-column finalization fetch result. |
|
Shared keyed-row transport for all token-capture TQ codecs. |
|
Gym |
|
One resolved |
|
Worker-local cache of resolved |
|
Gym |
Functions#
Encode non-empty bytes as one jagged TQ row. |
|
Group |
|
Placeholders for absent media, one per tensor column, in that column’s dtype. |
|
Check a media bundle against the Omni capture contract. |
|
Call a DataPlaneClient method on a local client or a Ray actor handle. |
|
Resolve a |
|
Resolve a |
|
Encode one row’s media columns for a media-enabled partition. |
|
Slice one row out of a batched fetch, restoring single-row shapes. |
|
Rebuild one normally validated base snapshot; route bytes never enter it. |
|
Verify media-partition metadata before exposing the decoded extras. |
|
Extract one staged route payload beside (never inside) the snapshot. |
|
Read one required scalar from a single-row TQ result. |
|
Read one required bool flag from a single-row TQ result. |
|
The |
Data#
API#
- nemo_rl.data_plane.tq_token_sink.MEDIA_PRESENT_FIELD#
‘media_present’
- nemo_rl.data_plane.tq_token_sink.MEDIA_HAS_FRAMES_FIELD#
‘media_has_frames’
- nemo_rl.data_plane.tq_token_sink.MEDIA_IMGS_FIELD#
‘media_imgs’
- nemo_rl.data_plane.tq_token_sink.MEDIA_IMGS_SIZES_FIELD#
‘media_imgs_sizes’
- nemo_rl.data_plane.tq_token_sink.MEDIA_NUM_FRAMES_FIELD#
‘media_num_frames’
- nemo_rl.data_plane.tq_token_sink.MEDIA_METADATA_DIGEST_FIELD#
‘media_metadata_digest’
- nemo_rl.data_plane.tq_token_sink.MEDIA_TENSOR_COLUMNS: dict[str, str]#
None
- nemo_rl.data_plane.tq_token_sink.MEDIA_FLAG_FIELDS#
None
- nemo_rl.data_plane.tq_token_sink.MEDIA_METADATA_FIELDS#
None
- nemo_rl.data_plane.tq_token_sink.MEDIA_STAGING_FIELDS#
None
- nemo_rl.data_plane.tq_token_sink._MEDIA_REQUIRED#
(‘imgs’, ‘imgs_sizes’)
- nemo_rl.data_plane.tq_token_sink._MEDIA_PIXEL_DTYPES#
()
- nemo_rl.data_plane.tq_token_sink._MEDIA_INDEX_DTYPES#
()
- nemo_rl.data_plane.tq_token_sink.STAGING_FIELDS#
None
- nemo_rl.data_plane.tq_token_sink._MODE_TO_CODE#
None
- nemo_rl.data_plane.tq_token_sink._CODE_TO_MODE#
None
- exception nemo_rl.data_plane.tq_token_sink.MediaMetadataIntegrityError#
Bases:
ValueErrorStored media metadata does not match its framework-owned checksum.
Initialization
Initialize self. See help(type(self)) for accurate signature.
- nemo_rl.data_plane.tq_token_sink._bytes_tensor(value: bytes) torch.Tensor#
Encode non-empty bytes as one jagged TQ row.
- nemo_rl.data_plane.tq_token_sink._optional_digest_fields(
- value: str | None,
- class nemo_rl.data_plane.tq_token_sink.StagedMediaTensors#
One staged call’s validated media bundle, in the engine’s native shapes.
imgsis[1, total_patches, 3*P*P]packed patches,imgs_sizes[N, 2]per-frame[height, width],num_frames[N_videos]frame counts partitioningimgs_sizes(Nonefor still images).- imgs: torch.Tensor#
None
- imgs_sizes: torch.Tensor#
None
- num_frames: torch.Tensor | None#
None
- property patch_size: int#
- property item_sizes: nemo_rl.data_plane.tq_token_sink.MediaItemSizes#
The
(height, width)rows of each media item, seemedia_item_sizes.
- nemo_rl.data_plane.tq_token_sink.MediaItemSizes#
None
- nemo_rl.data_plane.tq_token_sink.media_item_sizes(
- imgs_sizes: torch.Tensor,
- num_frames: torch.Tensor | None,
Group
imgs_sizesrows into media items.The one definition of an item boundary: a video is one item spanning its
num_framesrows ofimgs_sizes, a still image one item of one row. The sink’s prefix reader (media_count/media_sizes) and the Megatron stager’s media slicing both use it, so the count the preparer carries forward and the slice point the stager cuts at cannot disagree.- Raises:
ValueError –
num_framesdoes not tile theimgs_sizesrows.
- nemo_rl.data_plane.tq_token_sink._media_sentinels(pixel_dtype: torch.dtype) dict[str, torch.Tensor]#
Placeholders for absent media, one per tensor column, in that column’s dtype.
TQ rows cannot be empty, and TQ keeps one dtype per field across all live rows: a later put with a different dtype is logged by the controller and silently loses its shape metadata, which the KV (Mooncake) backend needs to reconstruct the row. So a sentinel must never introduce a second dtype into a column; each keeps its real column’s dtype and rank.
- nemo_rl.data_plane.tq_token_sink.validate_media_tensors(
- attachments: collections.abc.Mapping[str, Any] | None,
Check a media bundle against the Omni capture contract.
Shared by the sink (before any write) and the source (after every read), so malformed geometry is rejected at both ends instead of surfacing as a reshape error in the learner.
None(no attachments) returnsNone; anything else must be a mapping withimgsandimgs_sizesand an optionalnum_frames. RaisesTypeError/ValueError; supported dtypes are preserved, never cast.
- nemo_rl.data_plane.tq_token_sink._check_int32_positive(tensor: torch.Tensor, name: str) None#
- class nemo_rl.data_plane.tq_token_sink.FetchedStagedCall#
One explicitly identified small-column finalization fetch result.
fragmentis populated only when the fetch requested route payloads (direct mode); deferred finalization leaves route bytes in TQ and carries onlyrouted_lentransport metadata.sampler_topkis the call’s staged sampler top-k(ids, logprobs), each[generated_len, k], only when the fetch requested it.- staging_key: str#
None
- snapshot: nemo_gym.token_id_capture.staging.records.StagedCallBaseSnapshot#
None
- routed_len: int#
None
- fragment: nemo_rl.experience.route_assembly.RouteFragment | None#
None
- extras: dict[str, Any] | None#
None
- media_present: bool#
False
- media_has_frames: bool#
False
- sampler_topk: tuple[torch.Tensor, torch.Tensor] | None#
None
- nemo_rl.data_plane.tq_token_sink._call_dp(
- dp_client: Any,
- method_name: str,
- **kwargs: Any,
Call a DataPlaneClient method on a local client or a Ray actor handle.
- class nemo_rl.data_plane.tq_token_sink.TQStagingStore(dp_client: Any, *, staging_partition: str)#
Shared keyed-row transport for all token-capture TQ codecs.
Initialization
- put(
- key: str,
- field_dict: dict[str, torch.Tensor],
- *,
- tags: dict[str, Any] | None = None,
- get(
- keys: list[str],
- *,
- select_fields: list[str],
- clear(keys: list[str]) None#
- class nemo_rl.data_plane.tq_token_sink.TQTokenSink(
- dp_client: Any,
- *,
- staging_partition: str,
- capture_media: bool = False,
- media_pixel_dtype: torch.dtype | None = None,
Gym
StagingSinkoverDataPlaneClient.put_samples.stageis synchronous and returns only after TQ acknowledged the write, so the capture layer’s fail-closed ordering (bytes durable before the model call is acked) holds by construction. Failures are reported in theStageResult; the finalizer turns a poisoned rollout into a placeholder row (seeRolloutReassembler.finalize_group).stageis thread-safe per theStagingSinkcontract: it holds no per-call mutable state, so the capture host may run writes for unrelated calls concurrently.capture_mediamirrors the staging partition’s schema: a media-enabled partition registersMEDIA_STAGING_FIELDSand every row written here carries them (flags False + sentinels for text calls); a text-only partition rejects media attachments. Route attachments are supported on both kinds of partition.Initialization
- property media_pixel_dtype: torch.dtype | None#
The pixel dtype this partition’s media column is pinned to (
Nonefor text).
- stage(
- record: nemo_gym.token_id_capture.staging.records.StagedCallRecord,
- *,
- attachments: collections.abc.Mapping[str, Any] | None = None,
Write tokens, routes, media and sampler attachments in one
put.Success is returned only after the combined write was acknowledged, so
stagedcoordinates vouch for tokens and pixels together. TQ has no transactional rollback: if the write raises, the attempted key is discarded best-effort before the failure is reported (see_discard_failed_write).
- _discard_failed_write(key: str) None#
Reclaim whatever a failed combined write may have left behind.
TQ writes a row field by field and only then publishes readiness, so a raise mid-write can leave partial field keys with no logical row. Gym’s
capture_failedcoordinates carry no staging key, so the finalizer never learns about this key; the sink is the only owner able to clean it. The discard is idempotent (clearing an unknown key is a no-op). If it fails too the storage state is uncertain and is logged at ERROR for the operator; the call is still reported failed.
- clear(staging_keys: list[str]) None#
Drop staged rows (finalizer / eviction cleanup).
- class nemo_rl.data_plane.tq_token_sink.StagedPrefix#
One resolved
staging_chain: its tokens plus how much media it staged.expandedis the concatenatedtoken_ids_deltachain: what the engine prompt must start with, what the Megatron preparer splices in, and what Gym’s capture core verifies.media_countis how many media items (images, or videos) the chain’s rows staged, so the next call can stage only the media new to it and the engine expands only the media after it.media_sizesgives each of those items’(height, width)rows (one for a still, one per frame for a video) so the next call can check that the engine saw the retained media at the staged geometry, not just as many items.- expanded: list[int]#
None
- media_count: int#
0
- media_sizes: nemo_rl.data_plane.tq_token_sink.MediaItemSizes#
()
- class nemo_rl.data_plane.tq_token_sink.ChainPrefixCache(
- source: nemo_rl.data_plane.tq_token_sink.TQTokenSource | None = None,
Worker-local cache of resolved
staging_chainprefixes.Initialization
- install( ) None#
Attach (or replace) the
TQTokenSourceand drop cached chains.
- fetch(staging_chain: list[str]) list[int]#
Assemble the flat (expanded) prefix token ids from staging_chain.
The vLLM worker’s path. It goes through
fetch_chainsso both entry points fill the one cache with the same entry: the media count is never cached as 0 for a chain that staged media.
- fetch_chains(
- staging_chain: list[str],
Assemble the prefix and its media count from staging_chain.
Resolves through a worker-local FIFO (256-entry) cache.
- nemo_rl.data_plane.tq_token_sink.resolve_admission_prefix(
- admission: Any,
- chain_prefix: nemo_rl.data_plane.tq_token_sink.ChainPrefixCache,
Resolve a
CaptureAdmissionto the flat prefix the engine prompt starts with.
- nemo_rl.data_plane.tq_token_sink.resolve_admission_prefix_chains(
- admission: Any,
- chain_prefix: nemo_rl.data_plane.tq_token_sink.ChainPrefixCache,
Resolve a
CaptureAdmissionto its prefix and staged media count.An inline
required_prefix_token_idsprefix carries no media: Gym only inlines prefixes for text chains.
- nemo_rl.data_plane.tq_token_sink._media_columns(
- media: nemo_rl.data_plane.tq_token_sink.StagedMediaTensors | None,
- sentinels: dict[str, torch.Tensor],
Encode one row’s media columns for a media-enabled partition.
Tensors are written with TQ’s row dimension prepended and otherwise native:
imgsdrops its own leading 1 so the row is[total_patches, F]and the patch dim is the row’s leading (ragged) dim, exactly liketoken_ids_delta/routed_experts, which is what a batched nested read requires.fetch_mediarestores[1, total_patches, F]. Integer geometry is written as int32 (validated to fit) so each column has one dtype across real rows andsentinels.
- class nemo_rl.data_plane.tq_token_sink.TQTokenSource(
- dp_client: Any,
- *,
- staging_partition: str,
- capture_media: bool = False,
Gym
StagingSourceoverDataPlaneClient.get_samples.All requested rows are fetched in a single batched
get_samplescall (TQ returns jagged delta columns as nested tensors;_from_wirepreserves the raggedness), in the order requested. A missing or unreadable row raisesKeyErrorper the protocol — the finalizer maps that to a placeholder, never a silent skip. TQ’s field-readiness check is all-or-nothing across a batch, so the extras fallback is batch-level: extras-free runs land in the base schema exactly like the old per-key probe, but a batch with mixed extras presence degrades every row to the base schema (worker feature-gating makes presence uniform per run).Initialization
- fetch(
- staging_keys: list[str],
Gym
StagingSourceconformance: base snapshots only, in order.
- fetch_prefix_chains(
- staging_keys: list[str],
Bulk-fetch the ordered delta chain and describe the media it staged.
media_countandmedia_sizesare read off the small media columns (never the pixels) and are only computed when this source was built withcapture_media=True; otherwise it is 0 regardless of what the rows staged. The Megatron preparer’smedia_prev_counttherefore depends on the source’scapture_mediamatching the sink’s – both are set from setup’scapture_mediainmegatron_worker.setup_token_capture.
- fetch_media(
- items: list[nemo_rl.data_plane.tq_token_sink.FetchedStagedCall],
One batched read of the media tensor columns for rows known to carry media.
itemscome fromfetch_for_finalization(their flags were read with the base columns) and must all havemedia_present=Trueand the samemedia_has_frames: a sentinelnum_framesrow is all zeros and would fail validation beside real frame counts. Results are returned in request order. A transport miss raisesKeyError; malformed columns raiseTypeError/ValueError.
- fetch_for_finalization(
- staging_keys: list[str],
- *,
- include_route_fragments: bool = False,
- include_sampler_topk: bool = False,
Fetch digest-covered base columns, plus route payloads when requested.
Deferred mode (the default) never selects
routed_experts— route bytes stay in TQ for the policy worker. Direct mode passesinclude_route_fragments=Trueto pull the payloads in the same batched read and receives them asRouteFragmentvalues beside the base snapshots, never inside them.include_sampler_topkadds the sampler top-k columns (policy.generation.top_logprobs); a row without them fails the fetch like a missing row.
- nemo_rl.data_plane.tq_token_sink._select_row(
- rows: tensordict.TensorDict,
- index: int,
Slice one row out of a batched fetch, restoring single-row shapes.
_row_to_base_snapshotpredates batching and expects each field with a leading batch dim of 1 (the shape a single-keyget_samplesreturns), so re-add it after indexing. Indexing a nested tensor yields that row’s dense component, which is exactly the jagged-row payload.
- nemo_rl.data_plane.tq_token_sink._row_leaf(row: Any, name: str) torch.Tensor#
- nemo_rl.data_plane.tq_token_sink._row_text(row: Any, name: str) str#
- nemo_rl.data_plane.tq_token_sink._row_to_base_snapshot(
- row: Any,
Rebuild one normally validated base snapshot; route bytes never enter it.
- nemo_rl.data_plane.tq_token_sink._row_extras(
- row: Any,
- *,
- verify_media: bool,
Verify media-partition metadata before exposing the decoded extras.
- nemo_rl.data_plane.tq_token_sink._row_to_route_fragment(
- row: Any,
Extract one staged route payload beside (never inside) the snapshot.
- nemo_rl.data_plane.tq_token_sink._row_scalar_int(row: Any, field_name: str) int#
Read one required scalar from a single-row TQ result.
- nemo_rl.data_plane.tq_token_sink._row_scalar_bool(row: Any, field_name: str) bool#
Read one required bool flag from a single-row TQ result.
- nemo_rl.data_plane.tq_token_sink._row_media_item_sizes(
- row: Any,
The
(height, width)rows of each item one media-enabled row staged.Item boundaries come from
media_item_sizes, shared with the Megatron stager’s slicing.- Raises:
ValueError –
num_framesdoes not tile theimgs_sizesrows.