Open GenuineWWD opened 2 months ago
有相同的疑问。感觉应该先做conv3d再flatten成token sequence,但是代码实现刚好相反。 raised a thread here to draw more visibility https://huggingface.co/Qwen/Qwen2-VL-7B-Instruct/discussions/39
@GenuineWWD 我的理解是“使用3D卷积从而不增加视频帧所占的序列长度”是跟多图使用2d卷积相比。2d卷积的kernel是1414,3d卷积的kernel是214*14。
@GenuineWWD 我的理解是“使用3D卷积从而不增加视频帧所占的序列长度”是跟多图使用2d卷积相比。2d卷积的kernel是14_14,3d卷积的kernel是2_14*14。
多谢关注。从这个角度看的话相较于2D的确减少了token的数量,是说得通的。不过这样似乎对于长视频的支持或者增强时间维度理解的意义并不是特别大。还是希望官方团队解答一下疑惑
可以看下我放在HF上的问题,从mask 角度看,模型并没有学习到多帧之间的关联,只在两帧组内部进行attention。也就是说无所谓有没有在time dim上进行3D conv,最后还是没关注时间维度。单纯从理论上看,视频理解能力有一定局限性。
class FramePatchEmbed(nn.Module):
def __init__(self,
patch_size,
temporal_patch_size,
in_channels,
embed_dim,
spatial_merge_size
):
super().__init__()
self.patch_size = patch_size
self.temporal_patch_size = temporal_patch_size
self.in_channels = in_channels
self.embed_dim = embed_dim
self.spatial_merge_size = spatial_merge_size
kernel_size = (temporal_patch_size, patch_size, patch_size)
self.proj = nn.Conv3d(in_channels, embed_dim, kernel_size, stride=kernel_size, bias=False)
def forward(self, hidden_states):
# hidden_states is image tensor in shape of (t, in_channels, h, w)
target_dtype = self.proj.weight.dtype
hidden_states = hidden_states.transpose(0, 1).to(target_dtype) # (in_channels, t, h, w)
hidden_states = self.proj(hidden_states) # (embed_dim, grid_t, grid_h, grid_w)
_, grid_t, grid_h, grid_w = hidden_states.shape
hidden_states = hidden_states.permute(1, 2, 3, 0)
hidden_states = hidden_states.reshape(
grid_t,
grid_h // self.spatial_merge_size,
self.spatial_merge_size,
grid_w // self.spatial_merge_size,
self.spatial_merge_size,
self.embed_dim
)
hidden_states = hidden_states.permute(0, 1, 3, 2, 4, 5)
hidden_states = hidden_states.reshape(
grid_t * grid_h * grid_w, self.embed_dim
)
return hidden_states # (grid_t * grid_h * grid_w, embed_dim)
简单改了下patchembed,先做conv3D再flatten,并且保持merge patch需要的顺序关系。 supposed to work,但是plug到原模型还需要改下输入
可以看下我放在HF上的问题,从mask 角度看,模型并没有学习到多帧之间的关联,只在两帧组内部进行attention。也就是说无所谓有没有在time dim上进行3D conv,最后还是没关注时间维度。单纯从理论上看,视频理解能力有一定局限性。
谢谢解答,我看过你的问题了。是否可以这么理解,模型的3D卷积只是为了把token减少一半而已,后面还是希望使用不引入时间维度的处理,甚至加了mask人为的把时间维度剥离开?不知道这个设计是不是qwen团队有意为之,看起来有点不够简洁
请教一个问题,关于论文和代码有个地方对应不太上。论文中说视频embedding使用3D卷积从而不增加视频帧所占的序列长度,图像的embedding使用两个图像叠起来。但是我看代码里写的并非如此。Patchembed代码中,无论是图像还是视频,输入永远是一个二维的tensor,并且temporal_patch_size这个变量的值永远是2,这也就意味着无论是图像还是视频,在这一步都是拆成了2帧再进行3D卷积,(尽管image_processor在生成pixel_value的时候对于视频grid_t 并不是2)。对于这一步我有以下疑问:
附上PatchEmbed的forward函数与论文的截图: