Skip to content

TensorStream

Structuring Multimodal Data for Causal Transformers

def pack_sequences(tensor_stream_iter: Iterable, L: int):
  buf_stream = TensorStream([])
  for tensor_stream in tensor_stream_iter():
    # you can concatenate TensorStream as if they were lists
    buf_stream += tensor_stream

    while len(buf) >= L + 1:
      # TensorStream.slice handles updates to all Event descriptors.
      # e.g. slicing through image tokens will duplicate the Event in the resulting
      # TensorStream and adjust the idx_ranges accordingly
      packed_data, buf = buf[:L+1], buf[L+1:]
      yield packed_data
def embed_stream(self, tensor_stream: TensorStream) -> dict[ModalityType, torch.Tensor]:
  per_modality_stream: dict[ModalityType, TensorStream] = group_streams(
    tensor_stream, group_fn=lambda ev: ev.modality
  )
  # TensorStream.compact concatenates all tokens on first dimension.
  # we do this to batch embedding
  per_modality_compact_stream = {k: v.compact() for k, v in per_modality_stream.items()}

  embedded_stream = {}
  for modality in per_modality_compact_stream:
    tensor = per_modality_compact_stream[modality]
    input_data = (tensor,)
    if modality == VisionType:
      # NaViT embedding requires image dimensions
      # we use `virtual=False` because we want the true image dimensions
      token_dims = [event.dims(virtual=False) for event in per_modality_stream[VisionType]]
      input_data = (tensor, token_dims)
    embedded_stream[modality] = self.embed_fns[modality](*input_data)
  return embedded_stream
def interleave_compact_embeddings(
  compact_embedded_streams: dict[ModalityType, torch.Tensor], source_s: TensorStream
) -> torch.Tensor:
  T, D = len(source_s), next(iter(compact_embedded_streams.values())).shape[-1]

  per_modality_stream = group_streams(source_s, group_fn=lambda ev: ev.modality)
  mod = modality_mask(source_s)
  interleaved_tensor = torch.empty((T, D))

  for mod_type, compact_tensor in compact_embedded_streams.items():
    # the compact streams have multiple events concatenated on the sequence dimension. 
    # some of those events could be sliced so we create a token validity mask
    valid_token_mask = valid_token_mask(per_modality_stream[mod_type])
    assert valid_token_mask.sum() == (mod == mod_type.value).sum()
    # embeddings are compacted in order; we can insert using indexing
    interleaved_tensor[mod == mod_type.value] = compact_tensor[valid_token_mask]
  return interleaved_tensor

# example simple library functions
def event_mask(
  s: TensorStream,
  tag_fn: Callable[[Event], int | None],
) -> torch.Tensor:
  def to_label(ev: Event) -> Any:
    label = tag_fn(ev)
    return [label] * ev.num_tokens()
  # TensorStream.map_compact fuses map with compact to save time on Tensor creation
  return s.map_compact(to_label).squeeze(-1)

def modality_mask(ts: TensorStream) -> torch.Tensor:
  # creates a (T_virtual,) shaped tensor s.t. mask[i] = modality.value
  return event_mask(ts, lambda ev: ev.modality.value)

def valid_token_mask(ts: TensorStream) -> torch.Tensor:
  # returns a (T_real,) shaped tensor s.t. mask[i] = 1.0 if valid
  # e.g. if the TensorStream has 1 Event with 5 tokens but its idx_range=(1,3):
  # returns: torch.Tensor([0, 1, 1, 0, 0]).bool()
  return ts.map_compact(
    lambda ev: [
      int(ev.idx_range[0] <= i < ev.idx_range[1]) 
      for i in range(ev.num_tokens(virtual=False))
    ]
  ).bool()
@article{perceptron2025tensorstream,
  author = {Maciej Kilian and PerceptronAI},
  title = {TensorStream: Structuring Multimodal Data for Causal Transformers},
  journal = {PerceptronAI Research Blog},
  year = {2025},
  note = {https://perceptron.inc/blog/tensorstream},
}
Footnote

What we’re describing here is our internal framework for handling TensorStreams. For our release of Isaac 0.1 we shared a min-cut of this which is required to get inference working. If there’s enough interest we can invest some time in releasing the full version.