Qwen原生多模态开源,浅析一下!

发布于 2025-3-28 00:45
浏览
0收藏

Qwen2.5-Omni 7B开源,Qwen的第一个端到端的多模态模型,可以文本、图像、音频和视频输入,同时以流式方式生成文本和自然语音回复。

提出了 Thinker-Talker 架构。

Qwen原生多模态开源,浅析一下!-AI.x社区

PR还没合进去,要注意安装方式

Qwen原生多模态开源,浅析一下!-AI.x社区

评测的榜似乎画的有点赶,看不出信息量。

Qwen原生多模态开源,浅析一下!-AI.x社区

提出了一种新的位置嵌入,称为 TMRoPE(时间对齐多模态 RoPE),用于同步视频输入的时戳与音频。

资源占用:理论值如下,实际要在高1.2倍,看起来消耗有点大。


瞄下代码,关于输入,每个模态都有专门的处理组件:

class Qwen2_5OmniProcessor(ProcessorMixin):
    attributes = ["omni_processor", "feature_extractor", "tokenizer"]
    omni_processor_class = "Qwen2VLImageProcessor"
    feature_extractor_class = "WhisperFeatureExtractor"
    tokenizer_class = ("Qwen2Tokenizer", "Qwen2TokenizerFast")
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

视频这里,还计算每个视频时间网格对应的实际秒数,用于TMRoPE中的时间对齐

if videos is not None:
    videos_inputs = self.omni_processor(images=None, videos=videos, **output_kwargs["videos_kwargs"])
    if fps is None:
        fps = [2.0] * len(videos)
    videos_inputs["video_second_per_grid"] = [
        fps[i] / self.omni_processor.temporal_patch_size for i in range(len(fps))
    ]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

模型代码的核心由3块构成,Thinker,Talker,Token2Wav

talker是将文本转成语音编码,Token2Wav是将编码转成波形。

里边实现了几个Token2Wav变体:

  • Qwen2_5OmniToken2WavDiTModel:基于扩散模型的波形生成
  • Qwen2_5OmniToken2WavBigVGANModel:基于GAN的波形生成
  • Qwen2_5OmniToken2WavModel:通用基类

文本输出和语音输出是两条并行的路径:

  • 文本输出:输入 → Thinker → 文本输出
  • 语音输出:输入 → Thinker → Talker → Token2Wav → 语音输出

只有当需要语音输出时,才会激活Talker模块和Token2Wav模块,将Thinker生成的文本内容转换为语音。

细节可以自行看源码,不贴了。


在看看新的位置编码。

对于纯文本,使用常规的1D位置编码。

对于包含视觉(图像/视频)和文本的混合输入,函数分别计算:

  • 视觉部分用3D位置编码
  • 文本部分用1D位置编码

比如说,一个有3个时间片、2×2空间分辨率的视频示例:

输入序列: [V V V V V V V V V V V V T T T T T]
视觉时间位置ID: [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]
视觉高度位置ID: [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1]
视觉宽度位置ID: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
文本位置ID从视觉最大位置ID+1开始: [3, 4, 5, 6, 7]
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

将时间维度映射到位置ID,考虑每秒对应多少个位置单位(position_id_per_seconds)

t_index = (torch.arange(grid_t) * second_per_grids[video_idx] * position_id_per_seconds).long()
llm_pos_ids = self.get_llm_pos_ids_for_vision(
    start_idx, video_idx, spatial_merge_size, t_index, grid_hs, grid_ws
)
  • 1.
  • 2.
  • 3.
  • 4.

针对视频中包含音频的情况,还单独处理了,视频和音频交替编码,按时间块组织,每个时间块包含视频帧和对应的音频段,音频有特殊的开始和结束标记(audio_start_token_id和audio_end_token_id)

# 视频和音频混合处理
t_index_split_chunk = self.split_list_into_ranges(t_index, t_ntoken_per_chunk)

for t_chunk in t_index_split_chunk:
    vision_ntoken_per_chunk = len(t_chunk) * grid_h * grid_w // (spatial_merge_size**2)
    new_src_item.extend([video_token_id] * vision_ntoken_per_chunk)
    # 为视频区块分配位置ID
    
    new_src_item.extend(min(t_ntoken_per_chunk, pure_audio_len - added_audio_len) * [audio_token_id])
    # 为音频区块分配位置ID
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

最后开源地址:https://huggingface.co/Qwen/Qwen2.5-Omni-7B

代码地址:https://github.com/huggingface/transformers/blob/3a1ead0aabed473eafe527915eea8c197d424356/src/transformers/models/qwen2_5_omni/modeling_qwen2_5_omni.py#L1175

本文转载自​​NLP前沿​​,作者:NLP前沿


收藏
回复
举报


回复
相关推荐