Transformers 文档

Qwen2Audio

Hugging Face's logo
加入Hugging Face社区

并获得增强版文档体验

开始使用

Qwen2Audio

概述

Qwen2-Audio 是 Qwen 团队最新的大型音频语言模型系列。Qwen2-Audio 能够接受各种音频信号输入,并根据语音指令执行音频分析或直接进行文本响应。我们引入了两种不同的音频交互模式

  • 语音聊天:用户可以在没有文本输入的情况下,自由地与 Qwen2-Audio 进行语音交互
  • 音频分析:用户可以在交互过程中提供音频和文本指令进行分析

它在 Qwen2-Audio 技术报告 中提出,由 Chu Yunfei、Xu Jin、Yang Qian、Wei Haojie、Wei Xipin、Guo Zhifang、Leng Yichong、Lv Yuanjun、He Jinzheng、Lin Junyang、Zhou Chang 和 Zhou Jingren 撰写。

论文的摘要如下

我们介绍了 Qwen-Audio 的最新进展,这是一个名为 Qwen2-Audio 的大型音频语言模型,它能够接受各种音频信号输入,并根据语音指令执行音频分析或直接进行文本响应。与复杂的层次化标签相比,我们通过使用自然语言提示对不同的数据和任务进行了简化预训练过程,并进一步扩大了数据量。我们增强了 Qwen2-Audio 的指令遵循能力,并为语音聊天和音频分析实现了两种不同的音频交互模式。在语音聊天模式下,用户可以在没有文本输入的情况下,自由地与 Qwen2-Audio 进行语音交互。在音频分析模式下,用户可以在交互过程中提供音频和文本指令进行分析。请注意,我们没有使用任何系统提示来切换语音聊天和音频分析模式。Qwen2-Audio 能够智能地理解音频中的内容,并遵循语音命令做出适当的响应。例如,在一个音频片段中,如果同时包含声音、多方对话和语音命令,Qwen2-Audio 可以直接理解命令,并对音频进行解释和响应。此外,DPO 优化了模型在事实性和遵守预期行为方面的性能。根据 AIR-Bench 的评估结果,Qwen2-Audio 在侧重于音频中心指令遵循能力的测试中,优于之前的 SOTA,例如 Gemini-1.5-pro。Qwen2-Audio 开源发布,旨在促进多模态语言社区的发展。

使用技巧

Qwen2-Audio-7BQwen2-Audio-7B-Instruct 可在 Huggingface Hub 上找到

在下文中,我们将演示如何使用 Qwen2-Audio-7B-Instruct 进行推理,支持语音聊天和音频分析模式。请注意,我们使用了 ChatML 格式进行对话,在本演示中,我们将展示如何利用 apply_chat_template 来实现此目的。

语音聊天推理

在语音聊天模式下,用户可以在没有文本输入的情况下,自由地与 Qwen2-Audio 进行语音交互

from io import BytesIO
from urllib.request import urlopen
import librosa
from transformers import Qwen2AudioForConditionalGeneration, AutoProcessor

processor = AutoProcessor.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct")
model = Qwen2AudioForConditionalGeneration.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct", device_map="auto")

conversation = [
    {"role": "user", "content": [
        {"type": "audio", "audio_url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/guess_age_gender.wav"},
    ]},
    {"role": "assistant", "content": "Yes, the speaker is female and in her twenties."},
    {"role": "user", "content": [
        {"type": "audio", "audio_url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/translate_to_chinese.wav"},
    ]},
]
text = processor.apply_chat_template(conversation, add_generation_prompt=True, tokenize=False)
audios = []
for message in conversation:
    if isinstance(message["content"], list):
        for ele in message["content"]:
            if ele["type"] == "audio":
                audios.append(librosa.load(
                    BytesIO(urlopen(ele['audio_url']).read()), 
                    sr=processor.feature_extractor.sampling_rate)[0]
                )

inputs = processor(text=text, audios=audios, return_tensors="pt", padding=True)
inputs.input_ids = inputs.input_ids.to("cuda")

generate_ids = model.generate(**inputs, max_length=256)
generate_ids = generate_ids[:, inputs.input_ids.size(1):]

response = processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]

音频分析推理

在音频分析中,用户可以提供音频和文本指令进行分析

from io import BytesIO
from urllib.request import urlopen
import librosa
from transformers import Qwen2AudioForConditionalGeneration, AutoProcessor

processor = AutoProcessor.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct")
model = Qwen2AudioForConditionalGeneration.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct", device_map="auto")

conversation = [
    {'role': 'system', 'content': 'You are a helpful assistant.'}, 
    {"role": "user", "content": [
        {"type": "audio", "audio_url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/glass-breaking-151256.mp3"},
        {"type": "text", "text": "What's that sound?"},
    ]},
    {"role": "assistant", "content": "It is the sound of glass shattering."},
    {"role": "user", "content": [
        {"type": "text", "text": "What can you do when you hear that?"},
    ]},
    {"role": "assistant", "content": "Stay alert and cautious, and check if anyone is hurt or if there is any damage to property."},
    {"role": "user", "content": [
        {"type": "audio", "audio_url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/1272-128104-0000.flac"},
        {"type": "text", "text": "What does the person say?"},
    ]},
]
text = processor.apply_chat_template(conversation, add_generation_prompt=True, tokenize=False)
audios = []
for message in conversation:
    if isinstance(message["content"], list):
        for ele in message["content"]:
            if ele["type"] == "audio":
                audios.append(
                    librosa.load(
                        BytesIO(urlopen(ele['audio_url']).read()), 
                        sr=processor.feature_extractor.sampling_rate)[0]
                )

inputs = processor(text=text, audios=audios, return_tensors="pt", padding=True)
inputs.input_ids = inputs.input_ids.to("cuda")

generate_ids = model.generate(**inputs, max_length=256)
generate_ids = generate_ids[:, inputs.input_ids.size(1):]

response = processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]

批处理推理

我们还支持批处理推理

from io import BytesIO
from urllib.request import urlopen
import librosa
from transformers import Qwen2AudioForConditionalGeneration, AutoProcessor

processor = AutoProcessor.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct")
model = Qwen2AudioForConditionalGeneration.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct", device_map="auto")

conversation1 = [
    {"role": "user", "content": [
        {"type": "audio", "audio_url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/glass-breaking-151256.mp3"},
        {"type": "text", "text": "What's that sound?"},
    ]},
    {"role": "assistant", "content": "It is the sound of glass shattering."},
    {"role": "user", "content": [
        {"type": "audio", "audio_url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/f2641_0_throatclearing.wav"},
        {"type": "text", "text": "What can you hear?"},
    ]}
]

conversation2 = [
    {"role": "user", "content": [
        {"type": "audio", "audio_url": "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/1272-128104-0000.flac"},
        {"type": "text", "text": "What does the person say?"},
    ]},
]

conversations = [conversation1, conversation2]

text = [processor.apply_chat_template(conversation, add_generation_prompt=True, tokenize=False) for conversation in conversations]

audios = []
for conversation in conversations:
    for message in conversation:
        if isinstance(message["content"], list):
            for ele in message["content"]:
                if ele["type"] == "audio":
                    audios.append(
                        librosa.load(
                            BytesIO(urlopen(ele['audio_url']).read()), 
                            sr=processor.feature_extractor.sampling_rate)[0]
                    )

inputs = processor(text=text, audios=audios, return_tensors="pt", padding=True)
inputs['input_ids'] = inputs['input_ids'].to("cuda")
inputs.input_ids = inputs.input_ids.to("cuda")

generate_ids = model.generate(**inputs, max_length=256)
generate_ids = generate_ids[:, inputs.input_ids.size(1):]

response = processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)

Qwen2AudioConfig

class transformers.Qwen2AudioConfig

< >

( audio_config = None text_config = None audio_token_index = 151646 **kwargs )

参数

  • audio_config (Union[AutoConfig, dict], 可选,默认值为 CLIPVisionConfig) — 音频主干的配置对象或字典。
  • text_config (Union[AutoConfig, dict], 可选, 默认为 LlamaConfig) — 文本主干的配置对象或字典。
  • audio_token_index (int, 可选, 默认为 151646) — 用于编码图像提示的图像 token 索引。

这是一个用于存储 Qwen2AudioForConditionalGeneration 的配置类。它用于根据指定的参数实例化 Qwen2-Audio 模型,定义模型架构。使用默认值实例化配置将产生类似于 Qwen2-Audio 的配置。

例如 Qwen/Qwen2-Audio-7B

配置对象继承自 PretrainedConfig,可以用于控制模型输出。阅读 PretrainedConfig 的文档以了解更多信息。

示例

>>> from transformers import Qwen2AudioForConditionalGeneration, Qwen2AudioConfig, Qwen2AudioEncoderConfig, Qwen2Config

>>> # Initializing a Qwen2AudioEncoder config
>>> audio_config = Qwen2AudioEncoderConfig()

>>> # Initializing a Qwen2 config
>>> text_config = Qwen2Config()

>>> # Initializing a Qwen2Audio configuration
>>> configuration = Qwen2AudioConfig(audio_config, text_config)

>>> # Initializing a model from the qwen2-audio style configuration
>>> model = Qwen2AudioForConditionalGeneration(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config

Qwen2AudioConfig

class transformers.Qwen2AudioEncoderConfig

< >

( num_mel_bins = 128 encoder_layers = 32 encoder_attention_heads = 20 encoder_ffn_dim = 5120 encoder_layerdrop = 0.0 d_model = 1280 dropout = 0.0 attention_dropout = 0.0 activation_function = 'gelu' activation_dropout = 0.0 scale_embedding = False init_std = 0.02 max_source_positions = 1500 **kwargs )

参数

  • num_mel_bins (int, 可选, 默认为 128) — 每个输入特征使用的梅尔特征数。应与 `Qwen2AudioProcessor` 类中使用的值一致。
  • encoder_layers (int, 可选, 默认为 32) — 编码器层数。
  • encoder_attention_heads (int, 可选, 默认为 20) — Transformer 编码器中每个注意力层的注意力头数。
  • encoder_ffn_dim (int, 可选, 默认为 5120) — 编码器中“中间”层(通常称为前馈层)的维度。
  • encoder_layerdrop (float, 可选, 默认为 0.0) — 编码器的 LayerDrop 概率。有关更多详细信息,请参阅 [LayerDrop 论文](请参阅 https://arxiv.org/abs/1909.11556)。
  • d_model (int, 可选, 默认为 1280) — 层的维度。
  • dropout (float, 可选, 默认为 0.0) — 嵌入、编码器和池化器中所有全连接层的 dropout 概率。
  • attention_dropout (float, 可选, 默认为 0.0) — 注意概率的 dropout 比例。
  • activation_function (str, 可选, 默认为 "gelu") — 编码器和池化器中的非线性激活函数(函数或字符串)。如果为字符串,则支持 "gelu""relu""silu""gelu_new"
  • activation_dropout (float, 可选, 默认为 0.0) — 全连接层内部激活的 dropout 比例。
  • scale_embedding (bool, 可选, 默认为 False) — 通过除以 sqrt(d_model) 来缩放嵌入。
  • init_std (float, 可选, 默认为 0.02) — 用于初始化所有权重矩阵的 truncated_normal_initializer 的标准差。
  • max_source_positions (int, 可选, 默认为 1500) — 此模型可能使用的 log-mel 滤波器组特征的最大序列长度。

这是用于存储 Qwen2AudioEncoder 配置的配置类。它用于根据指定的参数实例化 Qwen2-Audio 音频编码器,定义模型架构。使用默认值实例化配置将产生与 Qwen2-Audio 架构的音频编码器类似的配置。

例如 Qwen/Qwen2-Audio-7B

配置对象继承自 PretrainedConfig,可以用于控制模型输出。阅读 PretrainedConfig 的文档以了解更多信息。

示例

>>> from transformers import Qwen2AudioEncoderConfig, Qwen2AudioEncoder

>>> # Initializing a Qwen2AudioEncoderConfig
>>> configuration = Qwen2AudioEncoderConfig()

>>> # Initializing a Qwen2AudioEncoder (with random weights)
>>> model = Qwen2AudioEncoder(configuration)

>>> # Accessing the model configuration
>>> configuration = model.config

Qwen2AudioProcessor

class transformers.Qwen2AudioProcessor

< >

( feature_extractor = None tokenizer = None chat_template = None )

参数

  • tokenizer (Qwen2TokenizerFast, 可选) — 分词器是必需的输入。
  • chat_template (Optional[str], 可选) — 用于格式化对话的 Jinja 模板。 如果未提供,则使用默认的聊天模板。

构建 Qwen2Audio 处理器,它将 Qwen2Audio 特征提取器和 Qwen2Audio 分词器封装到单个处理器中。

Qwen2AudioProcessor 提供了 WhisperFeatureExtractorQwen2TokenizerFast 的所有功能。 有关更多信息,请参阅 __call__()decode()

batch_decode

< >

( *args **kwargs )

此方法将其所有参数转发到 Qwen2TokenizerFast 的 batch_decode()。 有关更多信息,请参阅此方法的文档字符串。

decode

< >

( *args **kwargs )

此方法将其所有参数转发到 Qwen2TokenizerFast 的 decode()。 有关更多信息,请参阅此方法的文档字符串。

Qwen2AudioForConditionalGeneration

class transformers.Qwen2AudioForConditionalGeneration

< >

( config: Qwen2AudioConfig )

参数

  • config (Qwen2AudioConfig) — 模型配置类,包含模型的所有参数。 使用配置文件初始化不会加载与模型关联的权重,只加载配置。 请查看 from_pretrained() 方法来加载模型权重。

QWEN2AUDIO 模型,它包含音频主干和语言模型。 此模型继承自 PreTrainedModel。 请查看超类文档以了解库为所有模型实现的通用方法(如下载或保存、调整输入嵌入的大小、修剪头等)。

此模型也是 PyTorch torch.nn.Module 子类。 像使用普通 PyTorch 模块一样使用它,并参考 PyTorch 文档了解所有与一般使用和行为相关的事项。

forward

< >

( input_ids: LongTensor = None input_features: FloatTensor = None attention_mask: Optional = None feature_attention_mask: Optional = None position_ids: Optional = None past_key_values: Optional = None inputs_embeds: Optional = None labels: Optional = None use_cache: Optional = None output_attentions: Optional = None output_hidden_states: Optional = None return_dict: Optional = None ) transformers.models.qwen2_audio.modeling_qwen2_audio.Qwen2AudioCausalLMOutputWithPasttuple(torch.FloatTensor)

参数

  • input_ids (torch.LongTensor 形状为 (batch_size, sequence_length)) — 输入序列词元在词表的索引。如果您提供填充,默认情况下将忽略填充。

    可以通过 AutoTokenizer 获取索引。有关详细信息,请参见 PreTrainedTokenizer.encode()PreTrainedTokenizer.call()

    什么是输入 ID?

  • input_features (torch.FloatTensor 形状为 (batch_size, feature_size, feature_sequence_length)) — 从原始语音波形中提取的浮点型梅尔特征。可以通过将 .flac.wav 音频文件加载到 List[float]numpy.ndarray 类型数组中获取原始语音波形,例如 通过 soundfile 库 (pip install soundfile)。要将数组准备成 input_features,应使用 AutoFeatureExtractor 提取梅尔特征,填充并转换为 torch.FloatTensor 类型的张量。有关详细信息,请参见 call()
  • attention_mask (torch.Tensor 形状为 (batch_size, sequence_length)可选) — 掩码,以避免对填充词元索引执行注意力。掩码值在 [0, 1] 中选择:

    • 1 表示未掩码的词元,
    • 0 表示掩码的词元。

    什么是注意力掩码?

    可以通过 AutoTokenizer 获取索引。有关详细信息,请参见 PreTrainedTokenizer.encode()PreTrainedTokenizer.call()

    如果使用 past_key_values,则可以选择仅输入最后一个 decoder_input_ids(参见 past_key_values)。

    如果您想更改填充行为,您应该阅读 modeling_opt._prepare_decoder_attention_mask 并根据您的需求进行修改。有关默认策略的更多信息,请参见 论文 中的图 1。

    • 1 表示头部未掩码
    • 0 表示头部掩码
  • feature_attention_mask (torch.Tensor 形状为 (batch_size, feature_sequence_length)) — 掩码,以避免对填充特征索引执行注意力。掩码值在 [0, 1] 中选择:

    • 1 表示未掩码的词元,
    • 0 表示掩码的词元。
  • position_ids (torch.LongTensor 形状为 (batch_size, sequence_length)可选) — 输入序列词元在位置嵌入中的位置索引。在 [0, config.n_positions - 1] 范围内选择。什么是位置 ID?
  • past_key_values (tuple(tuple(torch.FloatTensor))可选,在传递 use_cache=Trueconfig.use_cache=True 时返回) — 长度为 config.n_layerstuple(torch.FloatTensor) 元组,每个元组都有 2 个形状为 (batch_size, num_heads, sequence_length, embed_size_per_head) 的张量) 和 2 个形状为 (batch_size, num_heads, encoder_sequence_length, embed_size_per_head) 的附加张量。

    包含预计算的隐藏状态(自注意力块和交叉注意力块中的键和值),这些状态可以用于(参见 past_key_values 输入)加速顺序解码。

    如果使用 past_key_values,用户可以选择仅输入最后一个 decoder_input_ids(其过去键值状态未提供给此模型)的形状为 (batch_size, 1),而不是所有 decoder_input_ids 的形状为 (batch_size, sequence_length)

  • inputs_embeds (torch.FloatTensor 形状为 (batch_size, sequence_length, hidden_size)可选) — 可选地,您可以选择直接传递嵌入式表示,而不是传递 input_ids。如果您希望比模型的内部嵌入查找矩阵对如何将 input_ids 索引转换为关联向量有更多控制,这将很有用。
  • use_cache (bool可选) — 如果设置为 True,则返回 past_key_values 键值状态,可用于加速解码(参见 past_key_values)。
  • output_attentions (bool, 可选) — 是否返回所有注意力层的注意力张量。有关更多详细信息,请参阅返回张量下的 attentions
  • output_hidden_states (bool, 可选) — 是否返回所有层的隐藏状态。有关更多详细信息,请参阅返回张量下的 hidden_states
  • return_dict (bool, 可选) — 是否返回一个 ModelOutput 而不是一个简单的元组。

    参数 — labels (torch.LongTensor 形状为 (batch_size, sequence_length), 可选): 用于计算掩码语言建模损失的标签。索引应在 [0, ..., config.vocab_size] 或 -100 之间(参见 input_ids 文档字符串)。索引设置为 -100 的标记将被忽略(掩码),损失仅针对标签在 [0, ..., config.vocab_size] 之间的标记计算。

返回

transformers.models.qwen2_audio.modeling_qwen2_audio.Qwen2AudioCausalLMOutputWithPasttuple(torch.FloatTensor)

一个 transformers.models.qwen2_audio.modeling_qwen2_audio.Qwen2AudioCausalLMOutputWithPast 或一个 torch.FloatTensor 元组(如果传递了 return_dict=False 或当 config.return_dict=False 时),包含根据配置 (Qwen2AudioConfig) 和输入的不同元素。

  • loss (torch.FloatTensor 形状为 (1,), 可选, 当提供 labels 时返回) — 语言建模损失(用于下一个标记预测)。

  • logits (torch.FloatTensor 形状为 (batch_size, sequence_length, config.vocab_size)) — 语言建模头的预测分数(SoftMax 之前每个词汇标记的分数)。

  • past_key_values (tuple(tuple(torch.FloatTensor)), 可选, 当传递 use_cache=True 或当 config.use_cache=True 时返回) — 长度为 config.n_layerstuple(torch.FloatTensor) 元组,每个元组都有 2 个形状为 (batch_size, num_heads, sequence_length, embed_size_per_head) 的张量。

    包含预先计算的隐藏状态(自注意力块中的键和值),可以用于(参见 past_key_values 输入)加速顺序解码。

  • hidden_states (tuple(torch.FloatTensor), 可选, 当传递 output_hidden_states=True 或当 config.output_hidden_states=True 时返回) — torch.FloatTensor 元组(一个用于嵌入的输出,如果模型具有嵌入层,+ 一个用于每层的输出)形状为 (batch_size, sequence_length, hidden_size)

    模型在每层输出处的隐藏状态,加上可选的初始嵌入输出。

  • attentions (tuple(torch.FloatTensor), 可选, 当传递 output_attentions=True 或当 config.output_attentions=True 时返回) — torch.FloatTensor 元组(每层一个)形状为 (batch_size, num_heads, sequence_length, sequence_length)

    注意力 softmax 后的注意力权重,用于计算自注意力头中的加权平均值。

  • attention_mask (torch.FloatTensor, 可选) — 注意力掩码,用于更新注意力掩码和位置 ID。

The Qwen2AudioForConditionalGeneration 正向方法,覆盖了 __call__ 特殊方法。

虽然正向传递的配方需要在此函数内定义,但之后应该调用 Module 实例而不是此函数,因为前者负责运行前后处理步骤,而后者会静默地忽略它们。

示例

>>> from io import BytesIO
>>> from urllib.request import urlopen
>>> import librosa
>>> from transformers import AutoProcessor, Qwen2AudioForConditionalGeneration

>>> model = Qwen2AudioForConditionalGeneration.from_pretrained("Qwen/Qwen2-Audio-7B")
>>> processor = AutoProcessor.from_pretrained("Qwen/Qwen2-Audio-7B")

>>> prompt = "<|audio_bos|><|AUDIO|><|audio_eos|>Generate the caption in English:"
>>> url = "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen2-Audio/audio/glass-breaking-151256.mp3"
>>> audio, _ = librosa.load(BytesIO(urlopen(url).read()), sr=self.processor.feature_extractor.sampling_rate)

>>> inputs = processor(text=prompt, audios=audio, return_tensors="pt")

>>> # Generate
>>> generate_ids = model.generate(**inputs, max_length=30)
>>> processor.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
"Generate the caption in English: Glass is breaking."
< > 在 GitHub 上更新