timeagent / code /OpenTSLM /src /opentslm /model /llm /TimeSeriesFlamingoWithTrainableEncoder.py
roh8exe's picture
Upload folder using huggingface_hub
60b21d3 verified
Raw
History Blame Contribute Delete
2.63 kB
# SPDX-FileCopyrightText: 2025 Stanford University, ETH Zurich, and the project authors (see CONTRIBUTORS.md)
# SPDX-FileCopyrightText: 2025 This source file is part of the OpenTSLM open-source project.
#
# SPDX-License-Identifier: MIT
import torch
from torch import nn
from open_flamingo import Flamingo
from einops import rearrange
class TimeSeriesFlamingoWithTrainableEncoder(Flamingo):
def __init__(
self,
vision_encoder: nn.Module,
lang_encoder: nn.Module,
eoc_token_id: int,
media_token_id: int,
vis_dim: int,
cross_attn_every_n_layers: int = 1,
gradient_checkpointing: bool = False,
):
super().__init__(vision_encoder, lang_encoder, eoc_token_id, media_token_id, vis_dim, cross_attn_every_n_layers, gradient_checkpointing)
# Override the _encode_vision_x method to handle time series data
# In the original Flamingo, the vision_encoder is a CLIPModel, which is not trainable (with torch.no_grad())
# Here, we use a TimeSeriesCNNEncoder, which is trainable
def _encode_vision_x(self, vision_x):
# Handle time series data while still using the TimeSeriesCNNEncoder
if vision_x.ndim == 4: # For shape (b, T_img, F, features)
b, T, F, features = vision_x.shape
# Flatten batch, time and frame dimensions
vision_x = rearrange(vision_x, "b T F c -> (b T F) c")
# Process through encoder - will return [batch, patches, features]
vision_x = self.vision_encoder(vision_x) # Shape: [(b*T*F), patches, features]
# Reshape to expected format for perceiver
# The transformer output already has the "tokens" dimension we need (patches)
vision_x = rearrange(vision_x, "(b T F) p d -> b T F p d", b=b, T=T, F=F)
# Process through perceiver
vision_x = self.perceiver(vision_x)
else:
# Original image processing path
assert vision_x.ndim == 6, "vision_x should be of shape (b, T_img, F, C, H, W)"
b, T, F = vision_x.shape[:3]
assert F == 1, "Only single frame supported"
vision_x = rearrange(vision_x, "b T F c h w -> (b T F) c h w")
vision_x = self.vision_encoder(vision_x)[1]
vision_x = rearrange(vision_x, "(b T F) v d -> b T F v d", b=b, T=T, F=F)
vision_x = self.perceiver(vision_x)
for layer in self.lang_encoder._get_decoder_layers():
layer.condition_vis_x(vision_x)