Support precomputed multimodal features for Qwen-VL and Gemma3 models. (#6136)
Co-authored-by: Yury Sulsky <ysulsky@tesla.com>
This commit is contained in:
@@ -177,10 +177,10 @@ class MultimodalDataItem:
|
||||
image_offsets: Optional[list] = None
|
||||
|
||||
# the real data, pixel_values or audio_features
|
||||
# data: Union[List[torch.Tensor], List[np.array]]
|
||||
pixel_values: Union[torch.Tensor, np.array] = None
|
||||
image_grid_thws: Union[torch.Tensor, np.array] = None
|
||||
video_grid_thws: Union[torch.Tensor, np.array] = None
|
||||
# data: Union[List[torch.Tensor], List[np.ndarray]]
|
||||
pixel_values: Union[torch.Tensor, np.ndarray] = None
|
||||
image_grid_thws: Union[torch.Tensor, np.ndarray] = None
|
||||
video_grid_thws: Union[torch.Tensor, np.ndarray] = None
|
||||
|
||||
image_emb_mask: Optional[torch.Tensor] = None
|
||||
image_spatial_crop: Optional[torch.Tensor] = None
|
||||
@@ -189,9 +189,11 @@ class MultimodalDataItem:
|
||||
# [num_images, (n, w, h)]
|
||||
tgt_size: Tuple[int, int] = None
|
||||
|
||||
audio_features: Union[torch.Tensor, np.array] = None
|
||||
audio_features: Union[torch.Tensor, np.ndarray] = None
|
||||
audio_feature_lens: Optional[List[torch.Tensor]] = None
|
||||
|
||||
precomputed_features: Optional[Union[torch.Tensor, np.ndarray]] = None
|
||||
|
||||
@staticmethod
|
||||
def is_empty_list(l):
|
||||
if l is None:
|
||||
@@ -249,7 +251,9 @@ class MultimodalDataItem:
|
||||
return tensor_hash([f])
|
||||
return data_hash(f)
|
||||
|
||||
if self.is_audio():
|
||||
if self.precomputed_features is not None:
|
||||
self.hash = hash_feature(self.precomputed_features)
|
||||
elif self.is_audio():
|
||||
self.hash = hash_feature(self.audio_features)
|
||||
else:
|
||||
self.hash = hash_feature(self.pixel_values)
|
||||
@@ -258,19 +262,24 @@ class MultimodalDataItem:
|
||||
self.pad_value = self.hash % (1 << 30)
|
||||
|
||||
def is_audio(self):
|
||||
return (
|
||||
self.modality == Modality.AUDIO
|
||||
) and not MultimodalDataItem.is_empty_list(self.audio_features)
|
||||
return (self.modality == Modality.AUDIO) and (
|
||||
self.precomputed_features is not None
|
||||
or not MultimodalDataItem.is_empty_list(self.audio_features)
|
||||
)
|
||||
|
||||
def is_image(self):
|
||||
return (
|
||||
self.modality == Modality.IMAGE or self.modality == Modality.MULTI_IMAGES
|
||||
) and not MultimodalDataItem.is_empty_list(self.pixel_values)
|
||||
) and (
|
||||
self.precomputed_features is not None
|
||||
or not MultimodalDataItem.is_empty_list(self.pixel_values)
|
||||
)
|
||||
|
||||
def is_video(self):
|
||||
return (
|
||||
self.modality == Modality.VIDEO
|
||||
) and not MultimodalDataItem.is_empty_list(self.pixel_values)
|
||||
return (self.modality == Modality.VIDEO) and (
|
||||
self.precomputed_features is not None
|
||||
or not MultimodalDataItem.is_empty_list(self.pixel_values)
|
||||
)
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
return self.is_image() or self.is_video() or self.is_audio()
|
||||
@@ -279,6 +288,16 @@ class MultimodalDataItem:
|
||||
...
|
||||
# TODO
|
||||
|
||||
@staticmethod
|
||||
def from_dict(obj: dict):
|
||||
kwargs = dict(obj)
|
||||
modality = kwargs.pop("modality")
|
||||
if isinstance(modality, str):
|
||||
modality = Modality[modality]
|
||||
ret = MultimodalDataItem(modality=modality, **kwargs)
|
||||
ret.validate()
|
||||
return ret
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class MultimodalInputs:
|
||||
|
||||
Reference in New Issue
Block a user