VITA-1.5:GPT-4o级别的实时视觉和语音交互模型

[📖 VITA-1.5 Paper] [🤖 Basic Demo] [🍎 VITA-1.0]

[📽 VITA-1.5 Demo Show! Here We Go! 🔥]

引言

近年来,多模态大语言模型(MLLMs)在视觉和文本的结合上取得了显著进展。然而,随着人机交互需求的增加,语音在多模态对话系统中的作用变得愈发重要。语音不仅是信息传递的关键媒介,还能显著提升交互的自然性和便捷性。因此,如何将视觉和语音模态高效整合,实现高性能的多模态交互,成为了当前研究的重点。

VITA-1.5的提出正是为了解决这一挑战。通过精心设计的多阶段训练方法,VITA-1.5逐步训练大语言模型(LLM)理解视觉和语音信息,最终实现了流畅的视觉和语音交互。与现有模型相比,VITA-1.5不仅保留了强大的视觉-语言能力,还实现了高效的语音对话能力,显著加速了多模态端到端的响应速度。

VITA-1.5

模型架构

图 2:VITA-1.5 的整体架构。输入端由视觉和音频编码器及其连接到 LLM 的适配器组成。输出端有一个端到端的语音生成模块,而不是像初始 VITA-1.0 版本那样直接使用外部 TTS 模型。

VITA-1.5的整体架构如图2所示。输入侧与VITA-1.0版本相同,采用“多模态编码器-适配器-LLM”的配置。它将视觉/音频Transformer和多层连接器与LLM结合进行联合训练,旨在增强对视觉、语言和音频的统一理解。在输出侧,VITA-1.5拥有自己的端到端语音模块,而不是像原始VITA-1.0版本那样使用外部TTS模型。

视觉模态

视觉编码器:VITA-1.5采用InternViT-300M作为视觉编码器,输入图像大小为448×448像素,每张图像生成256个视觉标记。对于高分辨率图像,VITA-1.5采用动态分块策略捕捉局部细节,提高图像理解的准确性。

视频处理:视频被视为一种特殊的多图像输入。如果视频长度短于4秒,则均匀采样4帧;对于4到16秒的视频,每秒采样一帧;对于超过16秒的视频,均匀采样16帧。视频帧不应用动态分块,以避免过多的视觉标记影响处理效率。

视觉适配器:使用两层MLP将视觉特征映射到适合LLM理解的视觉标记。

音频模态

语音编码器:类似于[56],我们的音频编码模块由多个下采样卷积层(4倍下采样)和24个Transformer块(隐藏大小为1024)组成。下采样层有助于降低音频特征的帧率,提高LLM的处理速度。音频编码器约有350M参数,输出帧率为12.5Hz。使用Mel滤波器组特征作为音频编码器的输入,窗口大小为25ms,偏移为10ms。

语音适配器:由多个2倍下采样的卷积层组成。

语音解码器:使用TiCodec作为我们的编解码模型,定制了一个大小为1024的单码本。这种单码本设计简化了推理阶段的解码过程。编解码模型负责将连续语音信号编码为离散语音标记,频率为40Hz,同时能够将这些标记解码回采样率为24,000Hz的语音信号。

当前的LLM只能输出文本标记,语音生成能力要求LLM能够输出语音标记。为此,我们在文本标记后添加了两个语音解码器:1)非自回归(NAR)语音解码器,全局处理文本标记并建模语义特征,旨在生成语音标记的初始分布;2)自回归(AR)语音解码器,基于NAR解码器生成的语音信息逐步生成更高质量的语音标记。最终的语音标记序列通过编解码模型的语音解码器解码为连续语音信号流(波形)。我们为NAR和AR语音解码器采用了4个LLaMA解码层,隐藏大小为896,参数大小约为120M。

训练数据

如表1所示,多模态指令微调的训练数据涵盖了广泛的类别,如描述数据和问答数据,包括中文和英文。在不同的训练阶段,从整体数据集中选择性地采样子集以服务于不同的目标。具体来说,数据集分类如下:

  • 图像描述数据:使用ShareGPT4V、ALLaVA-Caption、SharedGPT4o-Image和合成数据等数据集训练模型生成图像的描述性语言。
  • 图像问答数据:使用LLaVA-150K、LLaVA-Mixture-sample、LVIS-Instruct、ScienceQA、ChatQA和从LLaVA-OV采样的子集(如通用图像问答和数学推理数据集)等数据集训练模型回答基于图像的问题和执行视觉推理任务。
  • OCR和图表数据:支持模型理解OCR和图表内容,使用Anyword-3M、ICDAR2019-LSVT、UReader、SynDOG、ICDAR2019-LSVT-QA和从LLaVA-OV采样的相应数据等数据集。
  • 视频数据:使用ShareGemini和合成数据等数据集训练模型处理视频输入并执行诸如描述和基于视频的问答等任务。
  • 纯文本数据:增强模型理解和生成语言的能力,促进基于文本的问答任务。

除了表1中列出的图像和视频数据外,还纳入了110,000小时的内部语音-转录配对ASR数据,涵盖中文和英文,用于训练音频编码器并将音频编码器与LLM对齐。此外,使用TTS系统生成的3,000小时文本-语音配对数据用于训练语音解码器。

三阶段训练策略

为了确保VITA-1.5在涉及视觉、语言和音频的任务中表现良好,我们必须面对一个关键挑战,即不同模态之间的训练冲突。例如,添加语音数据可能会对视觉数据的理解产生负面影响,因为语音的特征与视觉的特征显著不同,导致学习过程中的干扰。为了解决这一挑战,我们设计了一个三阶段训练策略,如图3所示。核心思想是逐步将不同模态引入模型,使其在增加新模态能力的同时保持现有模态的能力。

VITA-1.5的训练管道。训练过程分为三个阶段,以逐步将视觉和音频纳入LLM同时缓解了形态冲突。第一阶段的重点是视觉训练,包括视觉对齐(阶段1.1,使用表1中的20%字幕数据),视觉理解(阶段1.2,使用100%的字幕数据)以及用于Visual QA的指令调整(阶段1.3,使用20%字幕数据和100%QA数据)。阶段2引入音频输入调整,并具有音频对齐(阶段2.1,使用11,000小时的语音转录对)和语音质量检查的指令调整(阶段2.2,采样4%字幕数据和20%的QA数据)。最后,第3阶段的重点是音频输出调整,包括对编解码器模型的训练(使用3,000个小时的文本语音数据)和语音解码器培训(阶段3.2)。图像中显示的百分比对应于表1中指定的数据采样率。

阶段1:视觉训练

阶段1.1 视觉对齐:在此阶段,我们的目标是弥合视觉和语言之间的差距。前者的特征从预训练的视觉编码器InternViT-300M中提取,后者通过LLM引入。我们使用表1中20%的描述性描述数据进行训练,其中只有视觉适配器是可训练的,而其他模块是冻结的。这种方法允许LLM初步对齐视觉模态。

阶段1.2 视觉理解:在此阶段,我们的目标是教会LLM转录图像内容。为此,我们使用表1中所有的描述性描述数据。在此过程中,视觉模块的编码器和适配器以及LLM都是可训练的。重点是使模型通过学习关于图像的描述性文本,建立视觉和语言之间的强连接,使其能够通过生成自然语言描述来理解图像内容。

阶段1.3 视觉SFT:在阶段1.2之后,模型已经获得了对图像和视频的基本理解。然而,指令跟随能力仍然有限,难以应对视觉问答任务。为了实现这一点,我们使用表1中所有的问答数据,同时保留20%的描述性描述数据以增加数据集的多样性和任务的复杂性。

在训练过程中,视觉模块的编码器和适配器以及LLM都是可训练的。此阶段的关键目标是使模型不仅能够理解视觉内容,还能够根据指令回答问题。

阶段2:音频输入微调

阶段2.1 音频对齐:在完成阶段1的训练后,模型已经建立了强大的图像和视频理解基础。在此阶段,我们的目标是基于阶段1减少音频和语言之间的差异,使LLM能够理解音频输入。训练数据包括11,000小时的语音-转录对。我们采用两步方法:(a)语音编码器训练:我们采用常见语音识别系统中使用的训练框架,使用连接时序分类(CTC)损失函数[18]训练语音编码器。目的是使编码器从语音输入中预测转录文本。此步骤确保音频编码器能够提取语音特征并将其映射到文本表示空间。(b)语音适配器训练:在训练语音编码器后,我们将其与LLM集成,使用音频适配器将音频特征引入LLM的输入层。此阶段的训练目标是使LLM能够输出语音数据的转录文本。

此外,在步骤(b)中,我们引入了特殊的可训练输入标记来指导语音理解过程。这些标记提供了额外的上下文信息,指导用于问答任务的LLM执行ASR任务。

阶段2.2 音频SFT:此阶段的重点是引入语音问题和文本答案的问答功能。为此,我们从表1中采样4%的描述数据和20%的问答数据。在数据处理方面,大约一半的基于文本的问题被随机替换为其对应的语音版本,使用TTS系统生成。

在此阶段,视觉编码器和适配器、音频编码器和适配器以及LLM都是可训练的,旨在提高模型对多模态输入的适应性。此外,我们在LLM的输出中添加了一个分类头。该头用于区分输入是来自语音还是文本。结果,模型可以更准确地解释语音输入,并高效灵活地处理不同模态。

阶段3:音频输出微调

在前两个训练阶段,VITA-1.5模型已经有效地发展了其多模态理解能力。然而,一个关键的能力,即语音输出,仍然缺失,这对于其作为交互助手的角色至关重要。为了在不影响模型基本能力的情况下引入语音输出功能,我们借鉴了[56]的策略,使用3,000小时的文本-语音数据,并采用两步训练方法(见图3)。

阶段3.1 编解码训练:此步骤的目标是使用语音数据训练具有单码本的编解码模型。编解码模型的编码器能够将语音映射到离散标记,而解码器可以将离散标记映射回语音流。在VITA-1.5的推理阶段,仅使用解码器。

阶段3.2 NAR + AR解码器训练:此阶段的训练使用文本-语音配对数据,其中文本被输入到LLM的分词器和嵌入层以获得其嵌入向量,语音被输入到编解码模型的编码器以获得其语音标记。文本嵌入向量被发送到NAR语音解码器以获得全局语义特征,然后将这些特征发送到AR语音解码器,预测相应的语音标记。请注意,在此阶段LLM是冻结的,因此多模态性能不受影响。

评估

视觉-语言评估

基线:我们比较了一系列开源MLLMs,包括VILA-1.5、LLaVA-Next、CogVLM2、InternLM-XComposer2.5、Cambrian-1、MiniCPM-V-2.6、Ovis1.5、InternVL-Chat-1.5、InternVL-2、LLaVA-OV和Video-LLaVA、SilME和LongVA,以及5个闭源MLLMs,包括GPT-4V、GPT-4o、GPT-4o-mini、Gemini 1.5 Pro和Claude 3.5 Sonnet。

评估基准:为了评估VITA-1.5的图像感知和理解能力,我们使用了多个评估基准,包括MME、MMBench、MMStar、MMMU、MathVista、HallusionBench、AI2D、OCRBench和MMVet。这些基准涵盖了广泛的方面,包括通用多模态能力(如MME、MMBench和MMMU)、数学推理(MathVista)、幻觉检测(HallusionBench)、图表(AI2D)和OCR(OCRBench)理解,提供了全面的评估结果。对于视频理解,我们使用了代表性的评估基准,包括Video-MME、MVBench和TempCompass。

视觉-语言能力:表2展示了VITA-1.5的图像理解性能比较。在三个阶段的训练后,VITA-1.5的表现与最先进的开源模型相当,甚至超过了一些闭源模型,如GPT-4V和GPT-4o-mini。这一结果突显了VITA-1.5在图像-语言任务中的强大能力。如表3所示,VITA-1.5在视频理解评估中表现出与顶级开源模型相当的性能。与专有模型的显著差距表明,VITA-1.5在视频理解方面仍有显著的改进空间和潜力。请注意,在阶段2(音频输入微调)和阶段3(音频输出微调)的训练后,VITA-1.5几乎保留了其在阶段1(视觉-语言训练)中的原始视觉-语言能力。

语音评估

基线:以下三个基线模型用于比较:Wav2vec2-base、Mini-Omini2、Freeze-Omini和VITA-1.0。

评估基准普通话评估集包括三个数据集:aishell-1、test net和test meeting。这些数据集用于评估模型在普通话语音上的表现。评估指标是字符错误率(CER)。英语评估集包括四个数据集:dev-clean、dev-other、test-clean和test-other,用于评估模型在英语语音上的表现。评估指标是词错误率(WER)。

ASR性能:表4中的评估结果表明,VITA-1.5在普通话和英语ASR任务中均取得了领先的准确性。这表明VITA-1.5已成功集成了先进的语音能力,以支持多模态交互。

结论

本文介绍了VITA-1.5,这是一个通过精心设计的三阶段训练策略整合视觉和语音的多模态LLM。通过缓解模态之间的固有冲突,VITA-1.5在视觉和语音理解方面实现了强大的能力,无需依赖单独的ASR或TTS模块即可实现高效的语音到语音交互。广泛的评估表明,VITA-1.5在多模态基准测试中表现出色。我们希望VITA-1.5能够接过VITA-1.0的旗帜,继续推动开源模型在实时多模态交互领域的进步。

ASR语音识别指标计算

#coding=utf-8
import os
import sys
import re
from typing import List, Union
import jiwer
import pdb


def cal_wer(path_ref, path_hyp, metric_type, output_detail, path_output):

    ref_text, hyp_text, ref_key = _read_file(path_ref, path_hyp, metric_type)
    
    cal_wer_from_list(ref_text, hyp_text, ref_key, metric_type, output_detail, path_output)


def cal_wer_from_list(
    reference: Union[str, List[str]], 
    hypothesis: Union[str, List[str]], 
    key: Union[str, List[str]], 
    metric_type: str, 
    output_detail: bool, 
    path_output: str
):
    if isinstance(reference, str):
        reference = [reference]
    if isinstance(hypothesis, str):
        hypothesis = [hypothesis]
    if isinstance(key, str):
        key = [key]

    # 根据ref是否为空, 先分别计算wer指标再汇总
    ref_normal, hyp_normal, key_normal = [], [], []
    ref_empty, hyp_empty, key_empty = [], [], []
    for i in range(len(reference)):
        if len(reference[i]) != 0:
            ref_normal.append(reference[i])
            hyp_normal.append(hypothesis[i])
            key_normal.append(key[i])
        else:
            ref_empty.append(reference[i])
            hyp_empty.append(hypothesis[i])
            key_empty.append(key[i])

    res_normal, out_normal = _cal_wer_normal(ref_normal, hyp_normal, metric_type)
    res_empty, out_empty = _cal_wer_empty(hyp_empty, metric_type)
    _summary(ref_normal, hyp_normal, res_normal, out_normal.alignments, key_normal, 
             hyp_empty, res_empty, out_empty, key_empty, 
             metric_type, output_detail, path_output)


def _read_file(path_ref, path_hyp, metric_type):
    ref_key, ref_text = _preprocess(path_ref, '\t', metric_type)
    hyp_key, hyp_text = _preprocess(path_hyp, '\t', metric_type)

    tmp_dict = {}
    tmp_text = []
    for i in range(len(hyp_key)):
        if hyp_key[i] not in tmp_dict.keys():
            tmp_dict[hyp_key[i]] = hyp_text[i]
        else:
            print ("repeated key")
    for i in range(len(ref_key)):
        if ref_key[i] in tmp_dict.keys():
            tmp_text.append(tmp_dict[ref_key[i]])
        else:
            tmp_text.append("")

    return ref_text, tmp_text, ref_key


def _preprocess(path_in, sep, metric_type):
    res_key, res_text = [], []

    with open(path_in, "r", encoding="utf-8") as f_in:
        lines = f_in.readlines()
        for line in lines:
            line = line.strip().split(sep, 1)
            if len(line) == 2:
                key, text = line
                text = re.sub("<s>", "", text)
                text = re.sub("</s>", "", text)
                text = re.sub("<unk>", "", text)
                text = re.sub("@@ ", "", text)
                text = re.sub("@ ", "", text)
                text = re.sub("@@", "", text)
                text = re.sub("@", "", text)
                #text = re.sub(" ", "", text)
                text = text.lower()
            else:
                key = line[0]
                text = ""

            text = [x for x in text]
            text_tmp = ""
            if metric_type == "wer":
                for ch in text:
                    if '\u4e00' <= ch <= '\u9fff':
                        text_tmp += " " + ch + " "
                    else:
                        text_tmp += ch
                text = text_tmp.strip().replace("  ", " ")
            elif metric_type == "cer":
                text_tmp = "".join(text)
                text = text_tmp.strip().replace(" ", "")
            else:
                assert False

            res_key.append(key)
            res_text.append(text)

    return res_key, res_text


def _cal_wer_normal(reference, hypothesis, metric_type):
    if metric_type == "wer":
        out = jiwer.process_words(reference=reference, hypothesis=hypothesis)
        ERR = out.wer
    elif metric_type == "cer":
        out = jiwer.process_characters(reference=reference, hypothesis=hypothesis)
        ERR = out.cer
    else:
        assert False

    H = out.hits
    S = out.substitutions
    D = out.deletions
    I = out.insertions
    N = H + S + D

    res = [ERR, N, S, D, I]

    return res, out


def _cal_wer_empty(hypothesis, metric_type):
    out = []

    I = 0
    for hyp in hypothesis:
        if hyp == "":
            i = 0
        else:
            if metric_type == "wer":
                i = len(hyp.split(" "))
            elif metric_type == "cer":
                i = len(hyp)
            else:
                assert False
        I += i
        out.append(i)

    res = [0, 0, 0, 0, I]

    return res, out


def _summary(ref_normal, hyp_normal, res_normal, out_normal, key_normal,
             hyp_empty, res_empty, out_empty, key_empty, 
             metric_type, output_detail, path_output):
    # wer/cer计算
    _, N, S, D, I = res_normal
    I += res_empty[-1]
    if N != 0:
        ERR = (S + D + I) / N
        SUB = S / N
        DEL = D / N
        INS = I / N
        N_WORD = N
    else:
        if I == 0:
            ERR = 0
        else:
            ERR = 1
        SUB, DEL, INS, N_WORD = 0, 0, I, 0

    # 句准计算 + 详细错误指标 + 详细错误统计
    utt_normal, alignments_normal, statistics_normal = _analyse_normal(
        ref_normal, hyp_normal, out_normal, key_normal, metric_type)
    utt_empty, alignments_empty, statistics_empty = _analyse_empty(
        hyp_empty, out_empty, key_empty, metric_type)

    utt = utt_normal + utt_empty
    alignments = alignments_normal + alignments_empty
    for key in statistics_empty['insert'].keys():
        if key not in statistics_normal['insert'].keys():
            statistics_normal['insert'][key] = statistics_empty['insert'][key]
        else:
            statistics_normal['insert'][key] += statistics_empty['insert'][key]
    N_SENT = len(out_normal) + len(out_empty)
    ACC_UTT = utt / N_SENT
    res = [ERR, SUB, DEL, INS, N_WORD, ACC_UTT, N_SENT]

    _format_output(res, alignments, statistics_normal, metric_type, output_detail, path_output)


def _analyse_normal(ref_normal, hyp_normal, out_normal, key_normal, metric_type):
    utt_normal = 0
    alignments_normal = []
    statistics_normal = {'substitute' : {}, 'delete' : {}, 'insert' : {}}

    for i, alignment in enumerate(out_normal):
        err, n_hit, n_sub, n_del, n_ins = 0, 0, 0, 0, 0
        ref_align, hyp_align = "", ""
        sub_align, del_align, ins_align = "", "", ""
        for j, chunk in enumerate(alignment):
            if (metric_type == "wer" and (ref_align != "" or hyp_align != "")):
                ref_align += " "
                hyp_align += " "
            if chunk.type == 'equal':
                n_hit += chunk.ref_end_idx - chunk.ref_start_idx
                ref_align += _extract_string(ref_normal[i], chunk.ref_start_idx, chunk.ref_end_idx, metric_type)
                hyp_align += _extract_string(hyp_normal[i], chunk.hyp_start_idx, chunk.hyp_end_idx, metric_type)

            elif chunk.type == 'substitute':
                err += 1
                n_sub += chunk.ref_end_idx - chunk.ref_start_idx

                ref_sub = _extract_string(ref_normal[i], chunk.ref_start_idx, chunk.ref_end_idx, metric_type)
                hyp_sub = _extract_string(hyp_normal[i], chunk.hyp_start_idx, chunk.hyp_end_idx, metric_type)

                ref_align += ref_sub
                hyp_align += hyp_sub

                key_sub = "(" + ref_sub + ") --> (" + hyp_sub + ")"

                sub_align += key_sub + "\t"

                if key_sub not in statistics_normal['substitute'].keys():
                    statistics_normal['substitute'][key_sub] = 1
                else:
                    statistics_normal['substitute'][key_sub] += 1

            elif chunk.type == 'delete':
                err += 1
                n_del += chunk.ref_end_idx - chunk.ref_start_idx

                ref_del = _extract_string(ref_normal[i], chunk.ref_start_idx, chunk.ref_end_idx, metric_type)
                hyp_del = "*"

                ref_align += ref_del
                hyp_align += hyp_del

                key_del = ref_del

                del_align += key_del + "\t"

                if key_del not in statistics_normal['delete'].keys():
                    statistics_normal['delete'][key_del] = 1
                else:
                    statistics_normal['delete'][key_del] += 1

            elif chunk.type == 'insert':
                err += 1
                n_ins += chunk.hyp_end_idx - chunk.hyp_start_idx

                ref_ins = "*"
                hyp_ins = _extract_string(hyp_normal[i], chunk.hyp_start_idx, chunk.hyp_end_idx, metric_type)

                ref_align += ref_ins
                hyp_align += hyp_ins

                key_ins = hyp_ins

                ins_align += key_ins + "\t"

                if key_ins not in statistics_normal['insert'].keys():
                    statistics_normal['insert'][key_ins] = 1
                else:
                    statistics_normal['insert'][key_ins] += 1

            else:
                assert False

        if err == 0:
            utt_normal += 1
        alignments_normal.append((key_normal[i], ref_align, hyp_align, 
                                  sub_align, del_align, ins_align, 
                                  n_hit, n_sub, n_del, n_ins))

    return utt_normal, alignments_normal, statistics_normal


def _analyse_empty(hyp_empty, out_empty, key_empty, metric_type):
    utt_empty = 0
    alignments_empty = []
    statistics_empty = {'insert' : {}}

    for i, ins in enumerate(out_empty):
        ref_align, hyp_align = "", ""
        sub_align, del_align, ins_align = "", "", ""

        if ins == 0:
            utt_empty += 1
        else:
            ref_ins = "*"
            hyp_ins = _extract_string(hyp_empty[i], 0, len(hyp_empty[i]), metric_type)

            ref_align += ref_ins
            hyp_align += hyp_ins

            key_ins = hyp_ins

            ins_align += key_ins + "\t"

            if key_ins not in statistics_empty['insert'].keys():
                statistics_empty['insert'][key_ins] = 1
            else:
                statistics_empty['insert'][key_ins] += 1
        alignments_empty.append((key_empty[i], ref_align, hyp_align, 
                                sub_align, del_align, ins_align, 
                                0, 0, 0, ins))

    return utt_empty, alignments_empty, statistics_empty


def _extract_string(s, begin, end, metric_type):
    res = ""
    if metric_type == 'wer':
        res = ' '.join(s.split(' ')[begin:end])
    elif metric_type == 'cer':
        res = s[begin:end]
    else:
        assert False
    return res


def _format_output(res, alignments, statistics, metric_type, output_detail, path_output):
    with open(path_output, "w", encoding="utf-8") as f_out:
        if output_detail == True:
            f_out.write("-"*100 + "\n")
            for i, sample in enumerate(alignments):
                key, ref, hyp = sample[0:3]
                sub_align, del_align, ins_align = sample[3:6]
                n_hit, n_sub, n_del, n_ins = sample[6:]

                f_out.write("KEY: " + key + "\n")
                f_out.write("REF: " + ref + "\n")
                f_out.write("HYP: " + hyp + "\n")
                f_out.write("CNT: " + "H(" + str(n_hit) + ") " + \
                                      "S(" + str(n_sub) + ") " + \
                                      "D(" + str(n_del) + ") " + \
                                      "I(" + str(n_ins) + ")\n")
                f_out.write("SUB: " + sub_align + "\n")
                f_out.write("DEL: " + del_align + "\n")
                f_out.write("INS: " + ins_align + "\n\n")
            f_out.write("-"*100 + "\n")

            f_out.write("-"*100 + "\n")
            lst_sub = list(sorted(statistics['substitute'].items(), key = lambda x : x[1], reverse=True))
            lst_del = list(sorted(statistics['delete'].items(), key = lambda x : x[1], reverse=True))
            lst_ins = list(sorted(statistics['insert'].items(), key = lambda x : x[1], reverse=True))
            f_out.write("\n替换错误统计: \n")
            for x in lst_sub:
                f_out.write("\t" + x[0] + "(" + str(x[1]) + ")" + "\n")
            f_out.write("\n删除错误统计: \n")
            for x in lst_del:
                f_out.write("\t" + x[0] + "(" + str(x[1]) + ")" + "\n")
            f_out.write("\n插入错误统计: \n")
            for x in lst_ins:
                f_out.write("\t" + x[0] + "(" + str(x[1]) + ")" + "\n")
            f_out.write("-"*100 + "\n")

        f_out.write("-"*100 + "\n")
        f_out.write(metric_type.upper() + ": " + str(round(res[0] * 100.0, 2)) + '%\n')
        f_out.write("WORDS: " + str(res[4]) + "\t")
        f_out.write("SUB: " + str(round(res[1] * 100.0, 2)) + "%\t")
        f_out.write("DEL: " + str(round(res[2] * 100.0, 2)) + "%\t")
        f_out.write("INS: " + str(round(res[3] * 100.0, 2)) + "%\n")
        f_out.write("ACC_UTT: " + str(round(res[5] * 100.0, 2)) + '%\t')
        f_out.write("SENTS: " + str(res[6]) + '\n')
        f_out.write("-"*100 + "\n")
    
    print (metric_type + " calculation done")
    print ("saved to " + path_output)


if __name__ == '__main__':

    '''
    # example of function cal_wer_from_list
    ref = ["今 天 天 气", "hello 我 ok 的", ""]
    hyp = ["今 天 天", "halo 我 ok 的 呀", "噪 声"]
    key = ["000", "001", "002"]
    path_output = "./example.wer"
    cal_wer(ref, hyp, key, "wer", True, path_output)

    ref = ["今天天气", "hello我ok的", ""]
    hyp = ["今天天", "halo我ok的呀", "噪声"]
    key = ["000", "001", "002"]
    path_output = "./example.cer"
    cal_wer_from_list(ref, hyp, key, "cer", True, path_output)
    '''

InspireMusic–阿里通义开源音乐生成框架

InspireMusic是由通义实验室开源的音乐生成技术,旨在打造一款集音乐生成、歌曲生成、音频生成能力为一体的开源AIGC工具包。

为研究者和开发者提供音乐/歌曲/音频生成模型的训练和调优工具及模型,方便优化生成效果;同时为音乐爱好者提供一个易于使用的文本生成音乐/歌曲/音频创作工具,可通过文字描述或音频提示来控制生成内容。

目前,InspireMusic已开源了音乐生成的训练和推理代码,支持通过简单的文字描述或音频提示,快速生成多种风格的音乐作品。

InspireMusic的文生音乐创作模式涵盖了多种曲风、情感表达和复杂的音乐结构控制,提供了极大的创作自由度和灵活性。未来计划进一步开放歌唱生成和音频生成的基础模型,欢迎研究者、开发者及用户积极参与体验和研发。该开源工具包为社区开发者提供了丰富的技术资源,支持从学术研究到产品开发的广泛应用。

🎶 主要特点

  • 统一的音频生成框架:基于音频大模型技术,InspireMusic支持音乐、歌曲及音频的生成,为用户提供多样化选择;
  • 灵活可控生成:基于文本提示和音乐特征描述,用户可精准控制生成音乐的风格和结构;
  • 简单易用:简便的模型微调和推理工具,为用户提供高效的训练与调优工具。

🌟代码仓库

核心模型

InspireMusic由音频tokenizer、自回归Transformer模型、基于常微分方程的扩散模型即Conditional Flow Matching (CFM)模型、Vocoder所组成,可支持文本生成音乐、音乐续写等任务。通过具有高压缩比的单码本WavTokenizer将输入的连续音频特征转换成离散音频token,然后利用基于Qwen模型初始化的自回归Transformer模型预测音频token,再由CFM扩散模型重建音频的潜层特征,最终通过Vocoder输出高质量的音频波形。两种推理模式的设计:fast模型和高音质模型,为不同需求的用户提供了灵活的选择。

工具包安装使用指南

第一步:下载代码库

git clone --recursive https://github.com/FunAudioLLM/InspireMusic.git
# If you failed to clone submodule due to network failures, please run the following command until success
cd InspireMusic
git submodule update --init --recursive

第二步:安装代码库

conda create -n inspiremusic python=3.8
conda activate inspiremusic
cd InspireMusic
# pynini is required by WeTextProcessing, use conda to install it as it can be executed on all platforms.
conda install -y -c conda-forge pynini==2.1.5
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com
# install flash attention to speedup training, support version 2.6.3
pip install flash-attn --no-build-isolation

第三步:下载模型

InspireMusic-Base模型(https://www.modelscope.cn/iic/InspireMusic)
# git模型下载,请确保已安装git lfs
mkdir -p pretrained_models
git clone https://www.modelscope.cn/iic/InspireMusic.git pretrained_models/InspireMusic-Base

第四步:基本用法说明快速开始

cd InspireMusic/examples/music_generation/
bash run.sh

训练LLM和flow matching模型样例脚本。

torchrun --nnodes=1 --nproc_per_node=8 \
    --rdzv_id=1024 --rdzv_backend="c10d" --rdzv_endpoint="localhost:0" \
    inspiremusic/bin/train.py \
    --train_engine "torch_ddp" \
    --config conf/inspiremusic.yaml \
    --train_data data/train.data.list \
    --cv_data data/dev.data.list \
    --model llm \
    --model_dir `pwd`/exp/music_generation/llm/ \
    --tensorboard_dir `pwd`/tensorboard/music_generation/llm/ \
    --ddp.dist_backend "nccl" \
    --num_workers 8 \
    --prefetch 100 \
    --pin_memory \
    --deepspeed_config ./conf/ds_stage2.json \
    --deepspeed.save_states model+optimizer \
    --fp16

torchrun --nnodes=1 --nproc_per_node=8 \
    --rdzv_id=1024 --rdzv_backend="c10d" --rdzv_endpoint="localhost:0" \
    inspiremusic/bin/train.py \
    --train_engine "torch_ddp" \
    --config conf/inspiremusic.yaml \
    --train_data data/train.data.list \
    --cv_data data/dev.data.list \
    --model flow \
    --model_dir `pwd`/exp/music_generation/flow/ \
    --tensorboard_dir `pwd`/tensorboard/music_generation/flow/ \
    --ddp.dist_backend "nccl" \
    --num_workers 8 \
    --prefetch 100 \
    --pin_memory \
    --deepspeed_config ./conf/ds_stage2.json \
    --deepspeed.save_states model+optimizer

推理脚本

cd InspireMusic/examples/music_generation/
bash infer.sh

带有CFM的推理模式

pretrained_model_dir = "pretrained_models/InspireMusic/"
for task in 'text-to-music' 'continuation'; do
  python inspiremusic/bin/inference.py --task $task \
      --gpu 0 \
      --config conf/inspiremusic.yaml \
      --prompt_data data/test/parquet/data.list \
      --flow_model $pretrained_model_dir/flow.pt \
      --llm_model $pretrained_model_dir/llm.pt \
      --music_tokenizer $pretrained_model_dir/music_tokenizer \
      --wavtokenizer $pretrained_model_dir/wavtokenizer \
      --result_dir `pwd`/exp/inspiremusic/${task}_test \
      --chorus verse \
      --min_generate_audio_seconds 8 \
      --max_generate_audio_seconds 30 
done

不带CFM的fast推理模式

pretrained_model_dir = "pretrained_models/InspireMusic/"
for task in 'text-to-music' 'continuation'; do
  python inspiremusic/bin/inference.py --task $task \
      --gpu 0 \
      --config conf/inspiremusic.yaml \
      --prompt_data data/test/parquet/data.list \
      --flow_model $pretrained_model_dir/flow.pt \
      --llm_model $pretrained_model_dir/llm.pt \
      --music_tokenizer $pretrained_model_dir/music_tokenizer \
      --wavtokenizer $pretrained_model_dir/wavtokenizer \
      --result_dir `pwd`/exp/inspiremusic/${task}_test \
      --chorus verse \
      --fast \
      --min_generate_audio_seconds 8 \
      --max_generate_audio_seconds 30 
done

FireRedASR -小红书语音识别大模型

小红书 FireRed 团队正式发布并开源了基于大模型的语音识别模型 ——FireRedASR,在语音识别领域带来新突破。在业界广泛采用的中文普通话公开测试集上,FireRedASR 凭借卓越的性能取得了新 SOTA!FireRedASR 在字错误率(CER)这一核心技术指标上,对比此前的 SOTA Seed-ASR,错误率相对降低 8.4%,充分体现了团队在语音识别技术领域的创新能力与技术突破。

FireredAsr,旨在满足各种应用程序中出色的性能和最佳效率的各种要求。 fireredasr包括两个变体:

FireRedASR-LLM

采用Encoder-Adapter-LLM,结合了文本预训练 LLM 的能力,为极致的 ASR 准确率而生,适用于对准确率要求极高的应用场景。在公共普通话基准上,fireredasr-LLM (8.3b参数)达到3.05%的平均字符错误率(CER),超过了3.33%的最新SOTA,相对CER(CERR)8.4%。它显示出优于工业级基线的卓越概括能力,在多源普通话ASR方案(例如视频,现场和智能助理)中,达到24%-40%的CERR。

FireRedASR-AED

基于经典的 Attention-based Encoder-Decoder 架构,FireRedASR-AED 通过扩展参数至 1.1B,成功平衡了 ASR 语音识别的高准确率与推理效率。适用于资源受限的应用程序。

主要贡献

  • High-Accuracy Models with Efficiency: ASR识别准确率优于Seed-ASR[字节跳动],模型在保持效率的同时达到卓越精度的能力。
  • Robust Real-World Performance: 在各种实用的场景中,包括简短的视频,直播,字幕生成,语音输入和智能助手,我们的模型表现出了出色的功能,与相比的相对减少(CERR)相比实现了24%-40%流行的开源基线和领先的商业解决方案。
  • 多功能识别能力:支持方言/中文/英文/歌曲识别。而且在歌词识别中表现出色

模型结构:

FireRedASR-AED是基于注意的编码器-解码器 ASR模型。训练数据:包括大约70,000小时的音频数据,主要是高质量的普通话语音。与Whisper中使用的弱标记数据集不同,我们的大多数数据都是由专业注释者手动转录的,从而确保了高转录精度和可靠性。该数据集还包含大约11,000小时的英语语音数据,以增强英语ASR功能。

Input Features: 输入25ms窗口的80-dimensional  log Mel filterbank (Fbank),10ms frame shifts,然后是全局均值和方差归一化。

Encoder Structure:编码器由两个主要组件组成:一个下采样模块和Conformer  blocks堆叠。

Decoder Structure:解码器遵循Transformer 体系结构。

Tokenization:BPE编码英文文本, 1,000 English BPE tokens, 6,827 Chinese characters, and 5 special tokens.

FireRedASR-LLM: Encoder-Adapter-LLM 架构。

Input Features and Encoder: 训练数据和处理、encoder跟FireredAsr-AED相同。

Adapter Structure:一个简单但有效的线性RELU线性网络组成,该网络投射了编码器的输出维度,以匹配输入LLM。在适配器的开头合并了一个额外的框架剪接操作。此操作进一步将时间分辨率从40ms降低到每个帧的80ms,从而降低了序列长度并提高了计算效率LLM。

LLM初始化和处理:LLM用QWEN2-7B-INSTRUCT的预训练的重量初始化。训练数据格式:(prompt, speech, transcript)

Training Strategy编码器和适配器是完全训练的,LLM采用lora微调,保证LLM的文本能力。此策略可确保编码器和适配器经过充分训练,以将语音特征映射到LLM的语义空间中,同时保留其预训练能力。训练目标基于交叉熵损失,损失仅在输入的转录部分上计算,忽略提示和语音嵌入。

Evaluation

缩放定律的观察

LLMs 方面的最新研究表明,模型性能通常会随着模型尺寸的增加而提高,这称为缩放定律 。如表3所示,我们研究了具有不同模型大小的模型的缩放行为。对于 FireRedASR-AED,我们将模型大小逐步从 140M、413M、732M 扩展到 1.1B 参数。随着模型尺寸的增加,性能持续提高,从 XS 扩展到 S、从 S 扩展到 M 以及从 M 扩展到 L 配置时分别实现 6.1%、5.3% 和 5.6% 的 CERR。对于 FireRedASR-LLM,专注于扩展编码器,同时保持 LLM 主干不变。编码器大小从 86M 增加到 710M 参数,适配器参数的变化很小(17M 到 22M)。这表现出相似的扩展模式并带来一致的性能改进,从 XS(3.29%)到 L(3.05%)配置的总体 CERR 为 7.3%。这些结果证明了我们的扩展策略的有效性,并表明通过更大的模型容量可以进一步改进。

下图是 FireRedASR 和其他 ASR 大模型的对比,在业界常用的中文普通话公开测试集上,FireRedASR-LLM(8.3B 参数量)取得了最优 CER 3.05%、成为新 SOTA!FireRedASR-AED (1.1B 参数量)紧随其后取得 3.18%,两者均比 Seed-ASR(12+B 参数量)的 3.33% 低、并且参数量更小。FireRedASR 也比 Qwen-Audio、SenseVoice、Whisper、Paraformer 取得了更优的 CER。

FireRedASR 不仅在公开测试集上表现优异,在多种日常场景下,也展现了卓越的语音识别效果。
如下图所示,在由短视频、直播、语音输入和智能助手等多种来源组成的 Speech 测试集上,与业内领先的 ASR 服务提供商(ProviderA)和 Paraformer-Large 相比, FireRedASR-LLM 的 CER 相对降低 23.7%~40.0%,优势十分明显。
值得一提的是,在需要歌词识别能力的场景中,FireRedASR-LLM 也表现出极强的适配能力,CER 实现了 50.2%~66.7% 的相对降低,这一成果进一步拓宽了 FireRedASR 的应用范围,使其不仅能胜任传统语音识别需求,还能在创新性的多媒体场景中大放异彩。

值得一提的是,FireRedASR 在中文方言和英语场景中同样表现不俗。在 KeSpeech(中文方言)和 LibriSpeech(英语)测试集上,FireRedASR 的 CER 显著优于此前的开源 SOTA 模型,使其在支持好普通话 ASR 的前提下,在中文方言和英语上也足够通用,进一步凸显了其鲁棒的语言适配能力。

Discussion:

FireredAsr模型优于竞争模型的原因:

高质量和多样化的训练数据:语料库主要由从现实世界情景中收集的专业转录音频组成,该音频比在受控环境中提供的传统阅读式录音相比,它提供的训练信号明显更高。该数据集包括声音条件,扬声器,重音和内容域的广泛差异,总计数万小时。这种多样性和规模使我们的模型能够学习强大的语音表征和语言模式。

实证研究表明,一千小时的高质量,人工标注的数据比一万小时的弱标记数据(例如,来自视频标题,OCR结果或其他ASR模型的输出)更好的结果,这解释了我们比Whisper的优势 。此外,在我们的语料库中包含唱歌数据为处理音乐内容时的基线模型的显着改进做出了贡献。

优化的训练策略:将FireredAsr-A的扩展为140m到1.1b参数时,我们将正则化和学习率确定为影响模型收敛的关键因素。我们制定了一种渐进式正则化训练策略:最初没有正则化技术以实现快速收敛,然后逐渐引入更强的正则化,因为出现了过度拟合的趋势。此外,较大的模型需要降低学习率,这对于调整此参数的最佳性能至关重要。

高效的ASR框架

总结:提出了fireredasr-LLM和FireredAsr-AED,两种针对普通话优化的高性能ASR模型。通过全面的评估,我们证明了他们的体系结构,培训策略和高质量的数据集可以在保持计算效率的同时达到最先进的性能。

关于数据batch!=1时候短音频末尾重复出字的问题:

原因:组 batch时候要对音频特征进行pad到最大长度,特征补了0 padding

问题的关键可能是padded_feat,原来的方式是一个一个wav提特征得到feats,如果多个并且有时长相差较大的wav放入提特征得到padded_feats,就会出现某个wav的feat有很多个0 padding,就可能会导致重复出字。发现重复解码的case都是完整且正确地得到了结果,然后重复出字,确实是padding影响了实际问题

训练的时候按照readme所说做一个时长的数据预处理,将时长相近的wav组成一个个batch来提feats,那么理论上会导致该问题的发生,因为模型会学习到不同的 feat长度对应不同的文本label长度,所以在推理时候补pad后模型认为输出也应该更长。

实际上如果训练时候不对相近的音频组batch,而是随机各种长度组batch进行训练,模型应该就不会出现重复问题,但训练效率会大大降低!!!

好训练组batch时候可以不在音频特征后补pad,而是最终在 “音频+prompt+lebel” 之后在补 -100【ignore id】,就不会出现这个问题

Baichuan-Omni-1.5 多模态语音大模型

Baichuan-Omni-1.5 🤗 | Baichuan-Omni-1.5-Base 🤗 | 技术报告 📖

OpenMM-Medical 🤗 | OpenAudioBench 🤗

Github: https://github.com/baichuan-inc/Baichuan-Omni-1.5/

Baichuan-Omni-1.5 是 Baichuan-omni 系列的最新、性能一流模型。该模型通过端到端方式训练和推理。与其他开源模型相比,Baichuan-Omni-1.5 在文本、图像、音频和视频输入的理解能力有显著提升,并支持了可控的实时语音对话和多模态实时交互的新功能。此外,Baichuan-Omni-1.5 也是目前最出色的开源医疗多模态模型。Baichuan-Omni-1.5 的主要特性包括:

  • 多模态理解和交互能力: Baichuan-Omni-1.5 接受图像、视频、文本、音频作为输入,并生成高质量文本和语音输出,能够在不损害任何模态能力的情况下实现无缝的高质量跨模态交互,并和用户进行实时语音对话。在针对全模态理解的综合评测基准 OminiBench 中,Baichuan-Omni-1.5 取得开源社区一流水平,并超过了 GPT-4o-mini
  • 优秀的视觉能力: Baichuan-Omni-1.5 在 OpenCompass 常用的十个视觉评测集上平均得分 73.3,在7B量级的大小下,在图像理解方面超越了 GPT-4o-mini,比GPT-4o-mini平均高出6分,并且和GPT-4o的结果相近。此外,视频理解表现也优于GPT-4V
  • 出色的语音能力: Baichuan-Omni-1.5 通过一个 8 层 RVQ 音频Tokenizer(Baichuan-Audio-Tokenizer),在 12.5 Hz 帧率下实现了语义和声学信息捕获的最佳平衡,支持高质量可控制声音的中英双语实时对话。Baichuan-Omni-1.5 在语音理解任务优于 GLM-4-Voice,并在语音对话的语义和声学评估中展现了开源模型中最高的语音生成性能。同时,我们还开源了音频理解和生成基准(OpenAudio-Bench),以评估音频的端到端能力。
  • 领先的医疗图像理解能力: 我们从开源数据集中收集了一个比较全面的医学理解基准(OpenMM-Medical)用于评估模型的医学能力。Baichuan-Omni-1.5 在 GMAI-MMBench 以及 OpenMM-Medical 上取得了最佳的表现。在 OpenMM-Medical 上,Baichuan-Omni-1.5 仅使用 7B 的 LLM 取得了 83.8% 的高分,超过 Qwen2-VL-72B 的 80.7%。
在图像、视频和音频模态上的评估。(左)Baichuan-Omni-1.5覆盖了比Qwen2 VL更多的模态,并且超越了当前领先的全模态模型VITA-1.5和MiniCPM-o 2.6。(右)各模态在所有基准测试中的平均得分。

简介

Baichuan-Omni-1.5是一款全模态模型,具备全模态理解能力,并提供端到端的音频生成能力。为了实现跨模态的流畅高质量互动,同时不妥协任何模态的能力,优先优化了三个关键方面。首先,建立了一个全面的数据清洗和合成管道,用于多模态数据处理,获得了约5000亿条高质量数据(包括文本、音频和视觉数据)。其次,设计了一种音频分词器(Baichuan-Audio-Tokenizer),能够同时捕捉音频中的语义和声学信息,从而实现无缝集成,并提升与多模态大语言模型(MLLM)的兼容性。最后设计了一个多阶段的训练策略,逐步整合多模态对齐和多任务微调,确保各模态之间的有效协同。Baichuan-Omni-1.5在全模态能力方面领先于当前的模型(包括GPT4o-mini和MiniCPM-o 2.6)。值得注意的是,在多个多模态医学基准测试中,它取得了与领先模型(如Qwen2-VL-72B)相媲美的成绩。

与开源对手相比,Baichuan-Omni-1.5在文本、图像、音频和视频输入的理解能力上表现出显著的提升。特别地,该模型在可控实时语音互动和跨模态实时协同理解方面展示了令人印象深刻的能力。除了其通用能力外,Baichuan-Omni-1.5在医疗领域作为最出色的多模态大语言模型(MLLM)脱颖而出。这为人工智能在促进人类社会福祉方面开辟了令人兴奋的新可能性。Baichuan-Omni-1.5的架构如下图所示。根据评估结果,我们总结了Baichuan-Omni-1.5的关键优势和贡献:

全模态互动:Baichuan-Omni-1.5旨在处理文本、图像、音频和视频输入,输出高质量的文本和语音。它能够实现无缝、高质量的跨模态互动,且不会妥协任何模态的能力。

卓越的视觉-语言能力:Baichuan-Omni-1.5在十个图像理解基准测试中平均得分为73.3,超越GPT-4o-mini平均6分。

统一且出色的语音能力:我们设计了一种8层的RVQ音频分词器(Baichuan-Audio-Tokenizer),在捕捉语义和声学信息之间达到了最佳平衡,帧率为12.5Hz,支持高质量的可控双语(中文和英文)实时对话。同时,我们还开源了音频理解和生成基准(OpenAudioBench),用于评估音频的端到端能力。

领先的医学图像理解能力:我们收集了一个全面的医学理解基准:OpenMM-Medical,这是多个现有数据集的整合。我们的模型在GMAI-MMBench和OpenMM-Medical上取得了最先进的表现。具体来说,在OpenMM-Medical上,Baichuan-Omni-1.5使用7B大语言模型取得了83.8%的得分,超过了Qwen2-VL-72B的80.7%。

模型架构:

Baichuan-Omni-1.5 的架构。我们的模型旨在处理纯文本/音频输入以及视频/图像与文本/音频的组合。在生成音频时,Baichuan-Omni-1.5 LLM Decoder 交替预测文本标记和音频标记。然后,音频解码器对音频令牌进行解码,以生成最终音频。

Baichuan-Omni-1.5

高质量预训练数据

Baichuan-Omni-1.5的预训练数据集展示:我们构建了一个广泛的全模态数据集,包括文本、图像-文本、视频-文本、音频-文本及它们之间的交互。我们的数据集还包含了交织的图像-音频-文本和视频-音频-文本数据。

构建了全面且高质量的跨模态数据集,包含文本、图像-文本、视频-文本、音频-文本及它们之间的交互

图像数据:我们将图像训练数据分为三种类型:交织的图像-文本数据、图像描述数据和问答数据。为了提高数据的多样性并提升模型性能,我们采用了以下两种图像数据合成策略:

1)我们利用公司内收集的书籍和论文,并解析它们生成交织的图像-文本、OCR数据和图表数据。这些数据具有高度的完整性、专业性和知识密集性。

2)我们根据[19]的方案,训练了一个专用的描述模型,能够生成所需的图像描述,如OCR提示。这些描述提供了图像内容的深入说明。

3)目前,大量的开源数据集主要是英文数据。为了避免模型的中文能力下降,我们合成了大量的中文描述和交织数据。

视频数据:视频数据集包含了广泛的公开资源,涵盖了视频分类 、动作识别 和时间定位等多种任务。视频-文本数据源可以分为视频描述数据和视频问答(QA)数据。

音频数据:音频数据可以大致分为两种主要类型:音频理解数据和音频生成数据。音频理解数据包括自动语音识别(ASR)、音频问答(AQA)、语音转文本翻译和音频-文本交织数据。音频生成数据包括文本转语音(TTS)、交织的文本转语音数据和纯音频数据。交织数据由文本和音频模态交替组成,并以标点符号分隔,以促进跨模态知识的迁移。完全对齐的生成数据由完全对齐的文本和音频内容组成,旨在增强模型在文本监督下生成音频标记的能力。音频-文本配对数据(例如ASR和TTS数据)提高了基础语音任务的表现。纯音频数据则增强了独立处理音频模态的能力。

文本数据:为了构建一个高质量的文本语料库,我们从各种来源聚合了数据,包括网页、书籍、学术论文、代码等。我们遵循之前研究中的数据处理指南,采用严格的选择方法,旨在提高文本语料库的多样性和质量。这种多样性确保训练语料库涵盖了广泛的主题和语言风格,适用于不同的应用。同时,我们的高质量处理技术旨在消除冗余和过滤噪声,从而丰富数据集的信息密度和整体效用。最终,我们获得了1.507亿条纯文本数据。

跨模态交互数据:为了增强模型的跨模态交互能力,我们合成了一系列跨模态交互数据集,涵盖了图像-音频-文本视频-音频-文本格式。图像-文本数据来源包括两种类型:图像-文本描述数据和图像-文本交织数据。具体而言,文本数据首先在句子级别进行分割。然后,将四分之一的文本通过我们的内部文本转语音(TTS)接口转换为音频元素。随后,我们利用生成的音频元素替换原始图像-文本数据中的相应文本句子。这种方法通过将多样化的音频元素融入现有的文本内容,促进了丰富的跨模态交互框架。我们的音频数据包含44种不同的语音类型,确保了语调的多样性。此设置配有任务提示,如“请听以下音频,描述图像的内容。您的任务是在听完后结合音频和图像补充额外信息”,旨在预测剩余的三分之二文本描述。对于视频-文本数据集,音频成分直接从原始视频中提取,作为跨模态的音频元素。总计,我们生成了1000亿个用于跨模态交互的标记数据。

模型结构:

Baichuan-Omni-1.5是一个统一的全模态模型,由视觉分支、音频分支和一个预训练的大型语言模型(LLM)主干组成,支持文本、音频、视觉输入以及端到端的文本和音频输出。

视觉分支
像当前主流的MLLM一样,视觉分支旨在将图像和视频输入处理为视觉标记,并将其与文本标记一起输入到LLM中。我们使用Qwen2-VL的NaViT作为视觉编码器,该编码器能够动态处理任意分辨率和纵横比的图像和视频。然后,我们应用一个由两层MLP组成的视觉投影器,将视觉特征压缩为2×2的因子,从而在性能和效率之间取得平衡。

音频分支
音频分支扩展了LLM,使其能够支持端到端的语音输入和输出。这通过引入Baichuan-Audio-Tokenizer和基于流匹配的解码器来实现,前者负责将音频信号转换为离散标记,后者负责将音频标记解码为语音波形。我们在下图中展示了详细信息。

Baichuan-Audio-Tokenizer基于残差向量量化(RVQ)和多目标训练,帧率为12.5 Hz。在使用Whisper Large Encoder 从Mel谱图特征中提取高级特征后,残差卷积网络执行下采样以获得低帧率序列特征。然后使用8层残差向量量化器对这些特征进行量化,生成音频标记。这些标记随后被输入到音频解码器和预训练的LLM中,分别执行Mel谱图重建和转录预测。音频解码器采用与Whisper编码器对称的结构,并使用多尺度Mel损失来增强声音重建的质量。在训练过程中,预训练LLM的参数保持不变,以确保音频标记器和文本空间之间的语义对齐。

除了传统的任务如ASR、AQA和S2TT外,我们还将一定比例的交织文本-音频数据融入其中,以提高VQ模块建模复杂上下文场景的能力。

为了进一步增强合成音频的质量和感知逼真度,音频解码器模块通过流匹配模型进行优化。借鉴Matcha-TTS 和CosyVoice 的设计,U-Net包括一个单独的下采样块、一个上采样块和12个中间块。具体而言,流匹配解码器在24 kHz音频数据上进行训练,以生成目标Mel谱图,然后使用HiFi-GAN 声码器将其转换为语音波形。

多阶段模型训练:

图像-文本预训练

图像-文本预训练阶段扩展了LLM,使其能够处理和理解视觉输入,使用3000亿图像-文本样本,该阶段可以分为两个部分。

第一阶段:在第一阶段,我们训练视觉投影器,利用开源图像描述数据(例如LAION-5B数据集),建立图像表示与文本之间的初步对齐。在此阶段,我们冻结LLM和视觉编码器,仅训练视觉投影器,学习率为1e−3。

第二阶段:在第二阶段,我们解冻视觉编码器和LLM,以促进图像和文本表示之间更好的对齐。具体来说,我们以学习率1e−5训练LLM和视觉投影器,并以更低的学习率1e−6训练视觉编码器。我们使用公共和内部图像文本数据,包含交织数据和图像描述数据,以增强视觉-语言的表现力。具体来说,我们收集并标注高质量的OCR数据和图表数据,以增强文本/图表识别和理解能力。此外,我们还使用高质量的纯文本数据,这些数据占总数据的40%,以更好地保持语言模型的原始能力。

图像-音频-文本预训练

图像-音频-文本预训练阶段扩展了一个预训练在视觉数据上的LLM,使其能够以端到端的方式理解音频数据,使用887k小时的语音-文本数据,并结合我们的Baichuan-Audio-Tokenizer、新引入的音频嵌入层和独立音频头

具体来说,Baichuan-Audio-Tokenizer生成的音频令牌首先通过音频嵌入层转化为音频嵌入。音频LLM交替生成对齐的文本令牌和音频令牌,使用一个特殊令牌实现文本与音频之间的模态切换。生成的音频令牌由独立的音频头处理,该音频头基于先前的工作设计,包含3层深度变换器和8个分类头。

为了缓解语音和文本特征之间显著差异带来的冲突,我们参考了之前的工作,采用音频和文本数据交织的方法进行预训练。此外,采用了两阶段训练策略,以保持原始LLM的文本知识,同时有效地整合音频模态。

第一阶段:在第一阶段,我们冻结LLM、视觉模块和音频标记器的参数,只有音频嵌入层和音频头的参数更新,学习率为1e−4。我们在这一阶段使用包括ASR、TTS、INTLV和ITTS数据的音频数据。

第二阶段:在第二阶段,训练扩展到除视觉编码器和音频标记器之外的所有参数,学习率为1e−5。具体来说,我们使用音频数据、图像数据和纯文本数据,分别占比0.2、0.4和0.4,这可以更好地提升音频能力,同时保持视觉和语言能力。

全模态预训练

基于之前预训练阶段获得的视觉和音频能力,我们继续使用高质量的跨模态交互数据集进行训练,数据集涵盖图像-音频-文本和视频-音频-文本格式,并将最大序列长度扩展到64k,以支持长时间的语音和视频流。具体来说,输入的视频帧以每秒1帧的速率进行采样,每个视频最多包含32帧。每个输入帧被调整为最大分辨率560×1120像素,以保持最佳质量和细节。这一精心配置在性能和效率之间达到了平衡,促进了有效的模型训练,同时管理了计算负载。此训练过程使用4e−6的低学习率,以进一步优化与语言模态和跨模态交互的对齐。

多模态监督微调

在本节中,我们描述了全模态监督微调(SFT)阶段,旨在增强模型在各种任务中执行复杂全模态指令的能力。我们收集了包括开源、合成和内部注释数据在内的综合数据集。这些数据集涵盖了多个任务,包含大约1700万个数据对,跨越文本、音频、图像-文本、视频-文本和图像-音频组合等多种模态。关于这些数据类型和数量的详细信息见表4。

实验

如表6所示,Baichuan-Omni-1.5 在纯文本基准测试中表现出色,特别是在与仅专注于语言模态的开源LLM模型相比时。例如,在通用MMLU基准测试中,Llama3-Instruct的得分为67.1%,而Baichuan-Omni-1.5则达到了72.2%。Baichuan-Omni-1.5在语言模态上的成功,主要归功于我们在训练策略上的调整以及多模态训练数据的平衡比例,其中保持了适当比例的纯文本数据。这些结果表明,我们的数据合成与平衡方法,以及多阶段的训练策略,能够有效解决在多模态训练过程中纯语言任务性能下降的问题。此外,相较于最新的开源多模态模型MiniCPM-o 2.6,Baichuan-Omni-1.5在中文基准测试中展示了明显的优势,例如CMMLU(63.3%对75.5%)和C-Eval(61.5%对73.1%),并且在通用基准测试中也大大超过了MiniCPM-o 2.6,MMLU(65.3%对72.2%)和AGIEval(50.9%对54.4%)。这些结果表明,相较于当前的全模态模型,这些模型在训练非文本模态数据后可能会导致文本理解能力下降,而我们的模型在理解纯文本方面依然保持强大能力。

如表7和表8所示,显然,我们的模型在大多数基准测试中优于最新的开源模型VITA-1.5和MiniCPM-o 2.6。例如,与最近的MiniCPM-o 2.6相比,我们的模型在包括MMBench、SEED-IMG、MME和MMMU在内的十个基准测试中的六个上表现更好,这些基准测试要求具备专家级的感知和推理能力。这表明,我们的全模态模型已经处于开源模型的前沿。此外,与其他非全模态模型相比,Baichuan-Omni-1.5也取得了相当或更优的表现。例如,与MiniCPM-Llama3-V 2.5相比,我们的模型在大多数视觉问答(VQA)任务中表现更好。总体而言,与Qwen2-VL-7B相比,我们的模型在各类图像理解基准测试中的表现相当。我们的模型在MMBench-CN(81.9%对83.6%)、MMMU(52.7%对53.9%)、MathVista-mini(58.2%对63.6%)和ChartQA(83.0%对84.9%)等方面取得了更好的表现。此外,值得注意的是,在MMBench-EN/CN和OCRBench上,我们的模型已经超越了像GPT4o这样的闭源模型。

总结

在这项工作中,我们介绍了Baichuan-Omni-1.5,一个全模态模型,代表了朝着开发一个涵盖所有人类感官的综合框架迈出的重要一步。通过使用高质量的多模态数据以及多阶段的全模态预训练和微调策略,Baichuan-Omni-1.5在处理视频、图像、文本和音频理解方面取得了优异的表现。Baichuan-Omni-1.5的关键特点包括:(1) 强大的纯文本和多模态理解能力;(2) 全模态输入(文本、图像、视频、文本)和双模态输出(文本和音频)的端到端并行处理;(3) 在医疗场景中的卓越表现;以及(4) 高质量的可控音频生成。

尽管这些结果很有前景,但每种模态的基础能力仍有相当大的改进空间。即:(1) 增强文本理解能力;(2) 支持更长的视频帧理解;以及(3) 改进音频理解和生成,不仅能识别人类声音,还能识别自然环境中的声音,如流水声、鸟鸣声和碰撞声等。

我们的未来研究将专注于完善这些领域,以确保开发出更复杂、更通用的模型,能够理解和与复杂环境互动。我们预计,在这些领域的持续进展将对实现人工通用智能(AGI)的更广泛目标做出重要贡献。

Kokoro TTS:支持多语言的轻量级TTS模型

最近,HuggingFace模型趋势榜上有一个很火的开源模型Kokoro-82M

开源模型:https://huggingface.co/hexgrad/Kokoro-82M

Kokoro-82M不是大模型,而是一个参数量只有82M的TTS(Text-to-Speech)模型。虽然模型不大,但是Kokoro-82M在TTS Arena榜单上排行第一!TTS Arena 是一个用于评估语音合成模型的平台,其灵感来源于 LMsys 的 Chatbot Arena。用户可以通过输入文本并对比两个模型的合成语音来投票选择更自然的结果,模型名称在投票后才会显示。该平台旨在解决语音合成领域缺乏有效质量评估方法的问题,通过公开排名使结果更透明且易于访问。虽然这个排行榜很有参考意义。

在人工智能语音合成技术快速发展的今天,Kokoro TTS 以其轻量级设计和高效性能脱颖而出。作为一个仅有82M参数的文本转语音(TTS)模型,Kokoro 在 TTS Spaces Arena 中击败了许多参数规模更大的竞争对手,成为语音合成领域的一颗新星。

模型架构与参数规模

Kokoro TTS 基于 StyleTTS 2 架构,其参数规模仅为82M,远低于许多主流 TTS 模型(如 XTTS v2 的467M 参数和 MetaVoice 的1.2B 参数),但在单声道设置下表现卓越。

支持的语音与语言

Kokoro 最新版(0.23)支持多语言支持与声音克隆,包括:中、英、法、日、韩。每种语言支持多种音色以及男、女声,每种语音包都经过专业调校,确保音质清晰自然。英语支持美国英语和英国英语,并提供了10种独特的语音包,包括男声和女声(如 af_bella、af_sarah、am_adam 等)。

不过还不支持中文或韩文中与英语混合的情况。

性能优势与创新点

Kokoro 的训练数据量不到100小时,远低于其他模型(如 XTTS v2 的10,000小时),但其在 TTS Spaces Arena 中排名第一,证明了其在参数效率上的优势。此外,Kokoro 采用 espeak-ng 进行字形到音素(g2p)转换,进一步提升了语音合成的自然度。

本地部署步骤

模型地址:https://huggingface.co/hexgrad/Kokoro-82M

以下步骤为notebook中使用

# 1️⃣ Install dependencies silently
!git lfs install
!git clone https://huggingface.co/hexgrad/Kokoro-82M
%cd Kokoro-82M
!apt-get -qq -y install espeak-ng > /dev/null 2>&1
!pip install -q phonemizer torch transformers scipy munch

# 2️⃣ Build the model and load the default voicepack
from models import build_model
import torch
device = 'cuda' if torch.cuda.is_available() else 'cpu'
MODEL = build_model('kokoro-v0_19.pth', device)
VOICE_NAME = [
    'af', # Default voice is a 50-50 mix of Bella & Sarah
    'af_bella', 'af_sarah', 'am_adam', 'am_michael',
    'bf_emma', 'bf_isabella', 'bm_george', 'bm_lewis',
    'af_nicole', 'af_sky',
][0]
VOICEPACK = torch.load(f'voices/{VOICE_NAME}.pt', weights_only=True).to(device)
print(f'Loaded voice: {VOICE_NAME}')

# 3️⃣ Call generate, which returns 24khz audio and the phonemes used
from kokoro import generate
text = "How could I know? It's an unanswerable question. Like asking an unborn child if they'll lead a good life. They haven't even been born."
audio, out_ps = generate(MODEL, text, VOICEPACK, lang=VOICE_NAME[0])
# Language is determined by the first letter of the VOICE_NAME:
#    'a' => American English => en-us
#    'b' => British English => en-gb

# 4️⃣ Display the 24khz audio and print the output phonemes
from IPython.display import display, Audio
display(Audio(data=audio, rate=24000, autoplay=True))
print(out_ps)

API 接口与 Docker 化部署

Kokoro-FastAPI 是一个基于 Docker 的 FastAPI 封装,支持 NVIDIA GPU 加速和队列处理功能。用户可以通过 API 接口发送文本转语音请求,并获取高质量的语音输出。

Kokoro-FastAPI地址:https://github.com/remsky/Kokoro-FastAPI

TangoFlux-TTA 高效的文本到音频 (TTA) 生成模型

NVIDIA发布了新模型TangoFlux,TangoFlux和Flux采用类似的MMDiT架构,但与Flux不同的是,TangoFlux是用于根据文本来生成与之匹配的音频(Text-to-Audio,TTA)。注意,TTA与文本生成语音(Text-to-Speech,TTS)是两个不同的任务,TTS是根据文本合成口语化的语音,而TTA更复杂,是根据文本内容生成相应的背景音、环境音或者情感表达的音频。TangoFlux模型参数只有515M,能够在单个A40 GPU上仅用3.7秒生成长达30秒的44.1kHz音频,而且效果上实现了SOTA,所以是一个又快又好的TTA模型。目前,TangoFlux的代码和代码均已经开源:

在对齐 TTA(文本到音频)模型时,一个关键挑战在于生成偏好对的困难,因为 TTA 缺乏像大型语言模型(LLMs)那样的结构化机制,例如可验证的奖励或黄金标准答案。为了解决这一问题,我们提出了一种新颖的框架——CLAP 排序偏好优化(CRPO),通过迭代生成和优化偏好数据来增强 TTA 的对齐性能。研究表明,使用 CRPO 生成的音频偏好数据集优于现有的替代方案。借助这一框架,TangoFlux 在客观和主观基准测试中均达到了最先进的性能。

贡献

  • 引入了 TANGOFLUX,这是一种基于修正流的小型高效 TTA 模型,能够在完全非专有的训练数据上实现最先进的性能。
  • 提出了 CRPO,这是一种简单而有效的策略,用于生成音频偏好数据并对修正流进行对齐,其在音频偏好数据集上的表现优于其他方法。
  • 公开发布了代码和模型权重,以促进文本到音频生成领域的研究。

方法:

TangoFlux 由 FluxTransformer 块组成,这些块是基于扩散变换器(Diffusion Transformer, DiT,Peebles & Xie,2023)和多模态扩散变换器(Multimodal Diffusion Transformer, MMDiT,Esser 等,2024)的模型,通过文本提示和时长嵌入进行条件化,以生成最高 44.1kHz、时长达 30 秒的音频。TangoFlux 从通过变分自动编码器(VAE,Kingma & Welling,2022)编码的音频潜在表示中学习修正流轨迹。

TangoFlux 的训练流程包括三个阶段:预训练、微调和偏好优化。通过 CRPO 对 TangoFlux 进行对齐,CRPO 通过迭代生成新的合成数据并构建偏好对,执行偏好优化。整体训练流程如图 1 所示。

TangoFlux在模型架构上参考了Flux,也是采用混合MMDiT和DiT block的transformer,首先是6层MMDiT block,然后跟着18层DiT block,模型的特征维度是1024,总参数量为515M。类似SD和Flux,这里也是采用了一个音频VAE(来源Stable Audio Open)将音频编码成一定长度的latents,然后用DiT来生成latents。这里的文本编码器采用FLAN-T5,除了文本特征,还用一个小的网络将音频时长编码成一个embedding,并和文本特征拼接在一起,从而实现对生成音频长度的控制。训练也是采用Flow Matching。

音频编码

使用 Stable Audio Open Evans et al. 的 VAE,它能够将 44.1kHz 的立体声音频波形编码为音频潜在表示。给定一个立体声音频 X∈ℝ2×d×s⁢r ,其中 d 是 时长duration 和 s⁢r 是采样率 sampling rate,VAE 编码 X 为潜在表示 Z∈ℝL×C ,其中 L ,C 分别是潜在序列长度和通道大小。VAE 将 latent 表示 Z 解码回原始立体声音频 X 。整个 VAE 在 TangoFlux 训练期间保持冻结。

Model Conditioning

为了实现不同长度音频的可控生成,我们采用了文本调节和持续时间调节。文本调节根据提供的描述控制生成的音频的事件,而持续时间调节指定所需的音频长度,最长可达 30 秒。

文本条件。给定音频的文本描述,我们从预训练的文本编码器FLAN-T5中获取文本编码 ct⁢e⁢x⁢t 

持续时间编码。为了生成可变长度的音频,我们首先使用一个小型神经网络将音频持续时间编码成一个 duration embedding cd⁢u⁢r 。这与文本编码 ct⁢e⁢x⁢t 连接并馈送到 TangoFlux 以控制音频输出的持续时间。

模型架构

采用混合 MMDiT 和 DiT 架构作为 TangoFlux 的主干, 首先是6层MMDiT block,然后跟着18层DiT block,模型的特征维度是1024,总参数量为515M

Flow Matching

流匹配(Flow Matching)基于连续归一化流框架。该方法通过学习一个时间相关的向量场,将来自简单先验分布(例如高斯分布)的样本映射到复杂的目标分布,从而生成目标分布的样本。

在 TTA(文本到音频)领域的先前研究中,例如 AudioBox(Vyas 等,2023)和 Voicebox(Le 等,2023),主要采用了 Lipman 等(2023)提出的最优传输条件路径(Optimal Transport conditional path)。然而,我们的方法采用了 修正流(Rectified Flows,Liu 等,2022),这是一种从噪声到目标分布的直线路径,代表了最短路径

整流流(Rectified Flows)。给定音频样本的潜在表示 x₁ 和服从正态分布 x₀ ∼ N(0, I) 的噪声样本,通过时间步 t ∈ [0, 1] 可以构建训练样本 xₜ。模型通过学习预测速度 vₜ = dxₜ/dt 来引导 xₜ 向 x₁ 演化。尽管存在多种构建传输路径 xₜ 的方法,我们采用了 Liu 等人(2022)提出的整流流(RFs)。该方法在目标分布与噪声分布之间构建直线路径作为前向过程,其定义如公式(1)所示。经验表明,当减少采样步数时,整流流具有更高的采样效率且性能下降更少(Esser 等人,2024)。我们用 θ 表示模型 u 的参数,该模型通过直接回归预测速度 u(xₜ, t; θ) 与真实速度 vₜ 的匹配,其损失函数如公式(2)所示。

推理。在推理过程中,我们从先验分布 x~0∼𝒩⁢(𝟎,𝐈) 中采样噪声,并使用常微分方程求解器根据模型在每个时间步 t 长预测的速度 vt 来计算 x1 。在此过程中,我们使用 Euler 求解器。

CLAP 排名偏好优化 (CRPO)

CLAP 排名偏好优化 (CRPO) 利用文本-音频联合嵌入模型作为代理奖励模型,根据与输入描述的相似性对生成的音频进行排名,然后构建偏好对。

我们首先设置了一个 Ta ngoFlux 架构的预训练检查点作为要对齐的基础模型,用 π0 表示。此后,CRPO 迭代地将 checkpoint πk≔u⁢(⋅;θk) 对齐到 checkpoint πk+1 中,从 k=0 开始。每个这样的对齐迭代都包括三个步骤:(i) 批量在线数据生成,(ii) 奖励估计和偏好数据集创建,以及 (iii) πk+1 通过直接偏好优化进行微调 πk 。

Main Results

表 1:跨各种指标的音频生成模型比较。Output length 表示生成的音频的持续时间。度量包括 FD 
openl3表示 Frechet 距离、 passt KL 表示 KL 散度和 CLAP score 表示对齐。所有推理时间都是在同一个 A40 GPU 上计算的。我们在 #Params 列中报告可训练参数。

表 1 在客观指标方面将 TangoFlux 与 AudioCaps 上先前的文本到音频生成模型进行了比较。表 2 报告了具有多个事件的提示(即多事件提示)的模型性能。

MinMo: A Multimodal Large Language Model for Seamless Voice Interaction

FunAudioLLM Team   Tongyi Lab, Alibaba Group

用于语音交互的语音-文本多模态模型的先前工作可以大致分为 原生 模型和 对齐 模型。原生多模态模型使用单个框架同时对语音和文本的端到端理解和生成进行建模,然而,他们面临着语音和文本序列长度之间巨大差异、语音预训练不足以及灾难性地忘记文本LLMs的挑战;对齐的多模态模型在保持文本LLMs,然而,现有模型通常在小规模语音数据上进行训练,在有限的语音任务集上进行研究,并且缺乏对丰富而细致的说话风格的指令跟踪能力的系统探索

MinMo,这是一种多模态大型语言模型,具有大约 8B 参数,可实现无缝语音交互。 解决了先前对齐多模态模型的主要局限性。在 140 万小时的不同语音数据和广泛的语音任务上,通过语音到文本对齐、文本到语音对齐、语音到语音对齐和双工交互对齐等多个阶段来训练 MinMo。 经过多阶段训练后,MinMo 在保持文本LLMs,并且还促进了全双工对话,即用户和系统之间的同时双向通信。 此外,还提出了一种新颖而简单的语音解码器,它在语音生成方面优于以前的模型。MinMo 增强的指令跟踪功能支持根据用户指令控制语音生成,包括各种细微差别,包括情绪、方言和语速,并模仿特定声音。对于 MinMo,语音到文本的延迟约为 100 毫秒,理论上全双工延迟约为 600 毫秒,实际约为 800 毫秒。

  • 最先进的 (SOTA) 性能:MinMo 在语音对话、多语言语音识别、多语言语音翻译、情感识别、说话人分析和音频事件分析等基准测试中实现了当前的 SOTA 性能,同时还确保了文本大型模型的功能基本保持不变。
  • 指令控制音频生成:MinMo 支持端到端语音交互,按照用户指示控制生成音频的情感、方言和说话风格,以及模仿特定的语音音调,生成效率超过 90%。
  • 低延迟双工语音交互:MinMo 支持全双工语音交互,可实现流畅的多轮对话并防止背景噪音打断。语音到文本的延迟约为 100 毫秒,全双工延迟理论上约为 600 毫秒,实际约为 800 毫秒。
基准测试的性能概览:演示了 MinMo 在自动语音识别 (ASR)、语音到文本翻译 (S2TT)、口语问答 (SQA) 方面的功能,包括语音到文本 (S2T) 和语音到语音 (S2S)、语音分类 (VSC)、语音情感识别 (SER)、语言识别 (LID)、年龄识别和性别检测。MinMo 在所有这些任务上都超越了以前的 SOTA 模型

Introduction  

无缝语音交互表示用户与系统进行实时、自然、相关且类似人类的语音对话。促进无缝语音交互带来了巨大的挑战:

  • 系统需要准确、全面地理解音频,包括理解内容以及语音中的副语言线索(例如,情感、韵律)以及音频事件;
  • 系统应产生自然且富有表现力的语音响应;
  • 系统应向用户提供相关且合理的响应,作为智能聊天机器人;
  • 系统应支持全双工对话(同时双向通信),即系统在说话时倾听,用户在系统说话时可以自由打断,然后系统要么继续语音,要么停止响应,倾听用户,并提供对新用户查询的响应。

近年来,无缝语音交互系统获得了巨大的发展势头,尤其是随着多模态大型语言模型的进步,例如 GPT-4o和 Moshi。这些系统不仅可以产生自然而富有表现力的语音,还可以理解文字以外的线索,包括情感语气和音频事件。当前用于语音交互的多模态语言模型可分为两大类。

第一类包括原生多模态模型,例如 Moshi  和 GLM-4-Voice 。这些模型通常使用仅解码器的 Transformer 作为主干,在单个框架内同时对语音和文本模态的理解和生成进行建模;它们通常需要使用语音和文本数据进行预训练。这些模型存在两个主要限制。首先,在语音离散化之后,语音标记序列的长度通常是文本长度的两倍以上(例如,在 Moshi 中每秒 12.5 个标记)。随着模型大小的增长,序列长度的这种差异会带来挑战,例如 175B GPT-3 。其次,与文本相比,语音数据的稀缺性导致语音-文本训练数据高度不平衡,进而导致灾难性的遗忘。

第二类包括对齐的多模态模型,集成语音功能,同时旨在保持现有预训练文本LLM。这导致中间输出仍然包含文本,如 Llama-Omni  和 Freeze-Omni  等模型所示。然而,这些基于对齐的模型通常是在有限的语音数据(LLaMA-Omni 为 200K 样本,Freeze-Omni 为 120K 小时)上进行训练的,这导致了关于大型语音数据集对模型功能的影响以及原始文本LLM可能受到影响的问题。此外,尚未对这些模型进行广泛的语音任务调查,例如语音翻译、情感识别、说话人分析、语言识别和音频事件检测。此外,这些模型缺乏对丰富而细致的说话风格的指令遵循能力的系统评估,也缺乏对全双工对话能力的开发和评估,以实现无缝语音交互。

在这项工作中,我们引入了一种新的多模态大型语言模型 MinMo,以解决现有对齐多模态模型的这些局限性。MinMo 经过超过 140 万小时的语音数据训练,包括各种任务,例如语音转文本、文本转语音和语音转语音。这种广泛的培训使 MinMo 能够在各种基准上实现最先进的 (SOTA) 性能。还采用了一些方法,有效缓解了在大规模数据集训练后,模型对原始文本语言模型(text-LLM)聊天能力的灾难性遗忘问题,同时增强了语音理解和生成能力。

还提出了一种新颖的语音解码器,在保持结构简单的同时,兼具了优异的语音生成性能。LLaMA-Omni 使用一种非自回归(NAR)流式 Transformer,它将语言模型(LLM)的输出隐藏状态作为输入,并通过连接时序分类(CTC)预测响应的离散语音标记序列。然而,这种方法的性能相比自回归语音解码器较差。Freeze-Omni 使用了三种语音解码器,包括 NAR 前缀语音解码器、NAR 语音解码器和 AR(自回归)语音解码器,使模型结构更为复杂。有别于这两种策略,我们为 MinMo 设计了一种自回归(AR)流式 Transformer,其通过固定比例将 LLM 的输出隐藏状态与语音标记混合处理。

开发了一种机制,可以有效地促进与 MinMo 的全双工相互作用。具体来说,我们实现了一个全双工预测模块,该模块利用文本LLM 的语义理解功能来决定是继续系统响应,还是让步、倾听和响应新的用户查询。对于 MinMo,语音到文本的延迟约为 100 毫秒;全双工延迟理论上约为 600 毫秒,实际时约为 800 毫秒。

Related Work

Multimodal Spoken Dialogue Models:

多种语音基础模型已被开发用于通用音频理解,但尚未系统地探索其在语音交互方面的应用。例如,Qwen2-Audio 将 Whisper 语音编码器与预训练文本语言模型(LLM)集成,并通过多任务预训练和基于指令的监督微调使 LLM 具备语音理解能力。SALMONN 是另一种用于通用音频理解的语音-文本 LLM,通过 Q-Former 将单独的语音和音频编码器与预训练文本 LLM 集成,并采用 LoRA 进行模态对齐。

由于本研究旨在开发一种端到端多模态模型以实现无缝语音交互,我们将重点比较 MinMo 与用于语音交互的语音-文本模型(或称多模态语音对话模型)。同时或受到 GPT-4o 的启发,多模态语音对话模型的开发正如火如荼地进行,以实现与用户实时语音对话的能力。(Ji et al., 2024a) 对近期的语音对话模型进行了深入综述。一些研究支持传统的回合制语音聊天(即半双工通信),但无法处理全双工语音交互(即同时双向通信)。这些模型包括协作系统和端到端框架。

PSLM (Mitsui et al., 2024) 是一种协作系统,因为它依赖 ASR 处理音频输入,这会丢弃副语言信息并导致错误传播。PSLM 同时生成语音和文本标记,从而减少语音生成延迟;然而,其响应质量较低。与 PSLM 等协作系统不同,端到端框架直接接受音频输入并生成音频输出。

Llama-Omni (Fang et al., 2024) 和 Mini-Omni (Xie & Wu, 2024) 是两个近期的端到端框架,但尚未针对全双工通信进行训练。Llama-Omni 集成了 Whisper 语音编码器、语音适配器、流式语音解码器和声码器,并以预训练文本 LLM 作为基础。其语音解码器以非自回归(NAR)方式生成与生成文本前缀对应的离散单元。该模型采用两阶段训练策略:第一阶段冻结语音编码器,仅对语音适配器和 LLM 进行自回归训练;第二阶段冻结语音编码器、语音适配器和 LLM,仅使用 CTC 损失对语音解码器进行训练。Llama-Omni 被评估在语音转文本指令执行和语音转语音指令执行任务上的表现。

Mini-Omni 同样采用 Whisper 编码器,并通过适配器进行最小化训练,以保留 LLM 的能力。该模型通过模态对齐、适配器训练和多模态微调三个阶段进行训练。Mini-Omni 同时生成文本和音频标记,并填充 N 个标记以确保首先生成对应的文本标记,从而指导音频标记的生成。

MinMo 支持全双工语音对话。现有的全双工语音聊天系统同样可以分为协作系统和端到端模型两类。在协作系统中,VITA (Fu et al., 2024) 同时运行两个模型,即生成模型和监控模型,以支持全双工通信。当生成模型正在生成系统响应时,监控模型会监控环境,并在检测到有效的用户打断后结合上下文对新的用户查询提供响应,同时生成模型暂停并切换到监控角色。值得注意的是,VITA 仍然依赖外部的 TTS 模块生成语音输出。

另一种协作系统 (Wang et al., 2024a) 则通过 LLM 接入 ASR 模块和流式 TTS 模块运行。该系统不需要模态对齐,而是对预训练的文本 LLM 进行监督微调,采用以下范式:在每个时间步,LLM 要么处理一个输入标记,要么生成一个文本标记,要么输出一个特殊的控制标记,用于在 SPEAK 和 LISTEN 状态之间进行状态转换。所有这些任务都被定义为基于单一序列化流对话的下一个标记预测。全双工对话学习基于由 GPT-4 合成的数据进行,这些数据生成了包含不同类型用户打断的对话。值得注意的是,由于其级联架构,该系统面临高达 680ms 的高延迟问题。

在端到端全双工模型中,早期的 dGSLM (Nguyen et al., 2022) 提出了一个双塔架构,用于联合处理用户语音和系统语音的音频标记流。然而,该方法存在以下几个缺点:它依赖于仅基于语音的训练,未能利用预训练文本 LLM 的能力;仅使用语义标记,未充分建模语音的声学信息;不支持在线模式。LSLM (Ma et al., 2024b) 使用仅解码器的 Transformer 生成语音标记,并通过流式 SSL 编码器处理监听标记。该模型引入了一个中断标记,用于在检测到用户尝试轮流对话时停止发言。然而,模型在生成合理响应方面表现不足。

在最近的端到端全双工模型中,Moshi、GLM-4-Voice 、SyncLM 、IntrinsicVoice 和 Omni-Flatten原生多模态模型。这些模型在单一框架中同时建模语音和文本模态的理解和生成,基于 GPT 主干,并需要使用语音和文本数据进行自监督自回归预训练。如第 1 节所述,这些原生多模态模型需要应对语音标记与文本标记之间序列长度差异显著的问题,以及语音-文本训练数据高度不平衡及其导致的灾难性遗忘。IntrinsicVoice 使用 GroupFormer 从 LLM 的隐藏状态生成 HuBERT 标记,有效地将语音序列缩短到与文本序列相当的长度。Omni-Flatten 采用分阶段的逐步后期训练策略,通过块级的单流平铺语音和文本标记来学习全双工和无文本的语音到语音交互。

与这些原生多模态模型不同,我们的 MinMo 属于对齐多模态模型类别,该类别还包括 Llama-Omni、Mini-Omni2和 Freeze-Omni 。对齐多模态模型集成了语音功能,同时旨在保留现有预训练文本 LLM 的能力。Mini-Omni2 引入了基于命令的中断机制以支持全双工对话,但仅在 ASR 任务上进行评估,并与 Whisper、VITA 和 Mini-Omni 进行比较。Freeze-Omni是一个语音到语音模型,通过冻结预训练的文本 LLM 来保留其能力。它支持流式输入语音和生成流式输出语音,使用多任务训练,并通过块级状态预测来建模全双工语音交互。

我们的 MinMo 与这些对齐多模态模型在以下方面不同:我们探索了在更大规模的语音数据集(1.4 百万小时多样化语音数据,相较于 LLaMA-Omni 的 20 万样本和 Freeze-Omni 的 12 万小时)以及更广泛的语音任务上训练 MinMo。MinMo 还通过新颖的语音解码器、增强的指令跟随能力,以及对全双工语音对话能力的系统性训练和评估,与现有的对齐多模态模型形成了差异化。

文本风格 – 可控语音合成

多模态语音对话模型相比于基于文本的对话模型的显著特征在于其能够理解和生成超越文本内容的声学信息。语音模态不仅包含内容,还包括情感、方言和语速等声学信息。一个智能的多模态语音对话模型应该能够全面理解输入语音中的声学信息(例如情感),并且能够生成带有指定情感、方言、语速的响应,甚至模仿特定的声音,从而在沟通中实现更深层次的理解和响应。

协作系统如 ParalinGPT 、E-Chat 和 Spoken-LLM 通过整合副语言特征增强对情感等声学信息的理解。这些系统可以与可控风格的文本转语音(TTS)系统结合,以生成带有特定情感、语速和音量的响应。在文本风格可控 TTS 方面取得了显著进展,例如 TextrolSpeech 、PromptTTS 、PromptTTS2、InstructTTS 和 ControlSpeech 。

与这些协作系统相比,Moshi 使用一个具有单一演员声音和超过 70 种说话风格录音的 TTS 引擎,生成训练数据以支持在端到端模型中理解和生成声学信息。GLM-4-Voice利用高质量的多轮语音对话数据,这些数据针对特定语音风格需求(如语速、情感或方言)进行定制,从而支持风格可控的语音对话。然而,据我们所知,尚无研究表明对齐的多模态模型能够支持风格可控的语音生成。

与之前的研究声称对齐的多模态模型(如 Llama-Omni 和 Freeze-Omni)仅允许语言模型控制语音的内容而非风格和韵律相反,我们在本研究中提出了一种新型的流式语音解码器,用于对齐多模态模型 MinMo,并发现该解码器不仅增强了指令跟随能力,还使 MinMo 能够生成符合用户指定情感、方言、语速以及模仿特定声音的语音。

MinMo

模型架构

语音编码器采用预训练的 SenseVoice-large 编码模块,提供了强大的语音理解能力,支持多语言语音识别、情感识别和音频事件检测。输入投影器由一个随机初始化的两层 Transformer 和一个 CNN 层组成,用于维度对齐和降采样。我们选用预训练的 Qwen2.5-7B-instruct 模型作为预训练的文本 LLM,因为其在各种基准测试中的表现卓越(Team, 2024)。此外,我们利用 CosyVoice 2的流式音频生成机制,该机制具备低延迟并提供具有竞争力的语音合成性能。

对于每批接收的五个文本标记,我们将这些标记及其对应的最终隐藏层向量同时传递到输出投影器和语音标记语言模型(Voice Token LM)。输出投影器是一个单层线性模块,随机初始化用于维度对齐。语音标记语言模型(Voice Token LM)采用预训练的 CosyVoice 2 LM 模块,并以自回归方式生成十五个语音标记,确保高效且无缝的音频合成。这些语音标记由 Token2wav 合成器模块实时处理,生成最终的音频输出。

Token2wav 合成器包括一个预训练的流匹配模型,该模型将标记转换为梅尔频谱图,以及一个预训练的声码器,将梅尔频谱图转换为波形,两者均来源于 CosyVoice 2。MinMo 通过额外的隐藏嵌入实现端到端的完整训练,这些嵌入有助于根据用户指令控制语音风格,例如情感、方言和语速等。语音生成的详细信息详见 3.2 节。

全双工预测器模块由一个单层 Transformer 和一个线性 softmax 输出层组成,两者均为随机初始化。该模块实时预测是否响应用户指令或暂时停止当前系统播报,以处理来自用户的进一步音频输入。一旦全双工预测器决定系统响应是合适的,MinMo 会生成文本输出并同步以逐标记方式生成音频标记。

Streaming Voice Decoder

语音解码器包括三个组件:输出投影器、语音标记语言模型(Voice Token LM)和流式标记到波形(Token2wav)合成器。

输出投影器对齐 LLM 的维度与语音解码器的维度。LLM 的隐藏状态包含丰富的上下文信息,但语义上可能不够明确;而采样得到的文本标记更加精确,与生成的文本一致。同时,当前用户输入的隐藏状态包含显式的指令信息。在每轮对话中,用户输入的嵌入与 LLM 最后一层输出的隐藏状态将沿特征维度拼接,形成查询嵌入。查询嵌入与五个采样文本标记的嵌入,以及 LLM 最后一层输出的隐藏状态,将沿序列维度拼接并输入到投影器中。投影器的输出被称为语义向量,这些向量代表了丰富且准确的语义信息。

在输出投影器之后,使用语音标记语言模型(Voice Token LM)以自回归方式生成语音标记。该语言模型在交替的文本和语音标记序列上运行。具体而言,我们以 5:15 的固定比例混合语义向量和语音标记,即每五个语义向量后跟随十五个语音标记。

在训练过程中,采用教师强制策略,并引入一个特殊标记,用于指示下一个语义向量应被连接。当 LLM 的文本响应完成且语义向量耗尽时,我们插入一个“语音轮次”(turn of speech)标记,提示语音标记语言模型接下来的标记应完全为语音标记。当生成“语音结束”(end of speech)标记时,语音合成过程结束。

为了从语音令牌重建波形,我们使用现成的流式 token2wav 合成器。token2wav 合成器包含一个数据块感知流匹配模型和一个 mel 到 wave 声码器,能够以 15 个令牌为块合成波形。

语音解码器的理论延迟可以按以下方式计算:

其中 dl⁢l⁢m 表示 LLM 生成一个文本令牌的计算时间, dl⁢m 表示 LM 生成一个语音令牌的时间, ds⁢y⁢n 表示 token2wav 合成器生成每个语音令牌对应的波形的时间。

Tasks and Training Data

MinMo 的训练任务包括四类,包括 Speech-to-TextText-to-SpeechSpeech-to-Speech 和 Speech-to-ControlToken 任务。表 2 列出了每个类别中的具体任务及其相应的数据量表。

Speech-to-Text 任务。此类别包含大约 120 万小时的语音-文本配对数据,包括自动语音识别 (ASR)、语音到文本翻译 (S2TT)、语言识别 (LID)、上下文偏差语音识别、语音情感识别 (SER)、音频事件检测 (AED)、说话人分析、口语平滑等任务。这些任务的训练数据以 ChatML 格式组织,如以下示例所示:

Text-to-Speech tasks。该类别的数据主要由基础语音合成数据组成,与训练 CosyVoice 2 的数据相同。它包括 170000 小时的文本语音配对数据,并支持四种语言:中文、英文、韩文和日文。此外,还有大约 1000 小时的音频生成数据由指令控制。这些说明扩展为包括由 Qwen-Max 生成的自然语言描述,利用人类标记的属性,例如情感、语速、方言和角色扮演。

Speech-to-Speech 任务。 Speech-to-Speech 数据主要通过模拟获取,包括大约 10000 小时的多轮对话语音和 100 小时的风格可控多轮对话语音。模拟 Speech-to-Speech 聊天数据的方法如下:

对于主要来源于 Alpaca 和 ShareGPT3 的文本聊天数据,我们利用 CosyVoice 的零样本上下文生成方法 将用户文本转换为用户语音。我们使用来自选定说话人的 2 小时数据对 CosyVoice 的基本模型进行微调,为目标说话人创建一个语音合成模型,称为 CosyVoice-SFT。该模型合成了助手的语音(即系统语音)。使用zero-shot上下文生成进行用户语音合成的优势在于它能够确保生成的用户语音的多样性,从而增强 MinMo 的泛化性。

为了解决合成音频和真实音频之间的差异,我们从 ASR 数据中选择合适的真实语音作为用户语音查询,并使用相应的文本作为 Qwen-Max 的输入生成响应文本,然后使用 CosyVoice-SFT 模型将其合成为辅助语音。这种方法进一步增强了模型对真实用户音频输入的鲁棒性。

为了生成涵盖不同说话风格的对话语音,我们最初使用 Qwen-Max 来创建丰富的风格可控、多轮次文本对话集合。用户查询通过 Cosyvoice 的 zero-shot generation 转换为语音。随后,我们使用 Cosyvoice 2 来生成助手的富有表现力的语音。具体来说,我们将助手的响应内容和指导提示输入到 Cosyvoice 2 中,以合成特定风格的语音。此外,使用小型、多样化和初步录制的语音语料库作为提示语音,通过零镜头生成合成表达性响应语音。前一种方法增强了模拟语音的多样性,而后者更有效地构建了各种风格的表现力。

Speech-to-ControlToken 任务。Speech-to-ControlToken 数据主要由两部分组成。第一部分是从现有的真实语音交互数据中提取的,而第二部分是使用文本对话数据进行模拟的。具体来说,现有的真实语音交互数据包括 Alimeeting 、Fisher 等资源,以及我们内部的语音交互数据,总共大约 3000 小时。模拟数据主要包括开源 MOSS 数据集 和通过合成我们内部文本对话数据的口语对话,产生了大约 1000 小时的语音聊天数据。当使用这些语音交互数据构建双工训练数据时,我们应用启发式规则在样本上自动注释双工标签,如下所示:

  • 对于助手的轮流,将用户轮到的终点作为助手轮次的起点。
  • 对于用户的轮次,将助手轮次结束后的时间间隔 T 作为用户轮次的起点,其中 T∼𝒩⁢(0.6,0.42) 。
  • 对于用户的 Back-Channel,当用户(以对话中的一个说话者为用户)无法打断另一个说话者时,我们从语音交互数据中选择实例,并将其视为用户 Back-channel 的训练样本。

模型训练

MinMo 通过四个对齐阶段逐步训练:(1) 语音到文本对齐,(2) 文本到语音对齐,(3) 语音到语音对齐,以及 (4) 双工交互对齐。通过四个对齐阶段,MinMo 获得了端到端的音频理解和生成能力,同时保留了主干文本LLM,实现了低延迟并为用户提供了无缝的语音聊天体验,类似于 GPT-4o。这四个阶段详细说明如下。

语音到文本对齐Pre-align > Full-Align > SFT[LoRA]

第一阶段使用表 2 所示的语音转文本数据,将音频模态的输入潜在空间与预训练文本LLM。此阶段包括对图 3 中的输入投影和语音编码器的逐步更新,以及使用 LoRA 更新文本 LLM。考虑到语音编码器和LLM (Qwen2.5-7B) 是预先训练的,而输入投影的参数是随机初始化的,我们使用表 2 所示的语音转文本数据子集执行预对齐训练 (Pre-align),仅更新输入投影器。这个 Pre-align 阶段有效地防止了随机初始化的参数在初始训练阶段对预训练的 Voice Encoder 产生大的梯度影响。在预对齐之后,我们使用完整的语音转文本数据来训练输入投影器和语音编码器,同时保持 LLM 参数冻结,这个过程称为完全对齐。在 Full-Align 之后,使用涵盖各种任务的大约 130 万个样本进行指令微调 (SFT)。在此阶段,LLM 使用 LoRA 进行更新,从而增强模型遵循指令的能力。Full-Align 和 SFT 阶段中使用的特定数据比例如图 4 所示。Pre-Align 阶段使用大约 1/10 的 Full-Align 数据。

文本到语音对齐

第二阶段使用文本转语音数据将文本LLM音频模态的输出潜在空间对齐。此阶段首先训练 Output Projector,然后联合训练 Output Projector 和 Voice Token LM,同时保持其他 MinMo 参数冻结。除了基本的文本转语音功能外,我们还利用端到端框架使 MinMo 能够在语音交互中遵循用户指示,从而提供更富有表现力和娱乐性的音频响应。例如,用户可以通过指令控制音频输出的情感、语速、方言口音或说话人风格。构建了大约 1000 小时的 Instruct 语音合成数据,格式如表 3 所示。

语音到语音对齐。

第三阶段使用大约 10,000 小时的配对音频数据继续训练 MinMo。与文本到语音对齐阶段一致,我们继续仅更新 Output Projector 和语音令牌 LM。语音到语音对齐的训练数据不仅包括一般的语音到语音对话,还包括具有各种设置的音频生成指令,例如采用特定的方言、语速和口语对话的情感。我们发现,即使不更新 LLM,仅通过利用与小规模指令数据集对齐的嵌入(150 小时),大型模型仍然可以学习相当有效的音频生成控制能力。

双工交互对齐。

在完成前三个训练阶段后,MinMo 获得了音频理解、音频生成和半双工语音对话的能力。在此基础上,我们进一步添加了一个全双工模块,该模块经过 4000 小时的长篇人际口语对话训练。Full Duplex Predictor 模块在此阶段专门进行训练。Full Duplex Predictor 采用 全双工预测器将LLM的隐藏嵌入作为输入,用于预测模型是否需要生成响应。全双工预测器利用LLM固有的语义理解能力来判断:1)模型是否应该回应当前用户查询,2)模型是否应该停止正在进行的语音输出以聆听用户查询并提供适当的响应。来预测模型是否需要生成响应

Experiments

根据多个基准评估 MinMo:

语音识别和翻译

在普通话、英语、日语、韩语和其他六种语言的公共测试集上评估了 MinMo 的语音到文本转录功能。

对于普通话 (ZH)、日语 (JA)、韩语 (KO) 和粤语 (YUE),我们采用字符错误率 (CER) 来评估转录性能。对于英语 (EN)、德语 (DE)、法语 (FR)、俄语 (RU)、西班牙语 (ES) 和意大利语 (IT),单词错误率 (WER) 用作评估指标。

与 Whisper Large v3 和 Qwen2-Audio相比,MinMo 在各种语言的大多数测试集上都实现了卓越的 ASR 性能

在提示符显示或不带有 LID【语言ID】 信息的 Common Voice 上进行测试时,Whisper Large v3 和 Qwen2-Audio 的平均错误率存在显著差距,这表明这两个模型强烈依赖 LID 信息。相比之下,无论是否存在语言识别,MinMo 都表现出稳健且一致的 ASR 性能。

多语言语音翻译

在 Fleurs  和 CoVoST2  测试集上评估了语音到文本的翻译能力。

与其他端到端基线相比,MinMo 在中 ↔ 英和日 ↔ 英翻译上实现了 SOTA 性能,在其他语言对上实现了顶级性能。我们将这种强劲的性能归功于广泛的语音翻译训练数据(表 2 中 451K 小时的 S2TT 训练数据)和强大的音频编码器。 值得注意的是,尽管我们只用 CoVoST2 集(不包括 Fleurs 集)来增强我们的训练数据,但我们的模型在两个测试集上保持一致的性能,表明具有高鲁棒性。

Language Identification  语言识别

使用 Fleurs 数据集,该数据集涵盖 102 种语言。MinMo 实现了 85.3% 的语言识别准确率,优于表 7 所示的所有先前模型。具体来说,零样本 Whisper-V3 经常将粤语错误地归类为中文,而 MinMo 可以准确地识别粤语。

上下文偏见语音识别

上下文偏见,或称为热词定制,允许用户根据特定的上下文或热词获得定制化的ASR(自动语音识别)结果。MinMo通过集成用于上下文偏见的高级提示增强了ASR功能。我们为对齐和SFT阶段准备了相应的训练数据,通过将热词组织到语音处理指令之前的提示中,从而实现有效的定制。评估包括热词偏见测试和一般偏见测试,如表8所示。

热词偏见测试涉及使用SeACo-Paraformer(Shi et al., 2024)提供的三个数据集,这些数据集包含用于偏见评估的热词。一般偏见测试则使用包含较少热词的数据集,用于评估对无关热词的抗干扰能力。

MinMo 在 ASR 准确性(带和不带热词)以及硬质热词的召回率方面优于竞争性基线 SeACo-Paraformer

Speech Analysis and Understanding

Speech Emotion Recognition

使用来自 EmoBox 的七个广泛使用的情绪识别数据集评估了 MinMo 的语音情感识别 (SER) 能力,包括 CREMA-D (Cao et al., 2014)、MELD (Poria et al., 2019)、IEMOCAP (Busso et al., 2008)、MSP-Podcast (Martinez-Lucas et al., 2020)、CASIA (Zhang & Jia, 2008)、MER2023 (Lian et al., 2023) 和 ESD (周 et al., 2021)。这些数据集包括中英文语言和场景,例如表演、电视剧和日常对话。我们采用未加权平均准确率 (UA)、加权平均准确率 (WA) 和宏观 F1 分数 (F1) 作为评价指标。引用了来自最近的 SER 工具包 EmoBox(马 et al., 2024a)的这些测试集的结果。我们还使用其发布的模型检查点评估了基线音频LLM 模型 SALMONN 和 Qwen-Audio。

MinMo 在该基准测试的所有任务上都优于所有基线模型,包括语言 ID、性别、年龄、情感、发声分类任务,除了在声音问题分类任务上表现优于 Qwen-Audio

Audio Event Understanding

使用 Air-Bench 基准测试,将 MinMo 的语音和音频事件理解能力与其他 Audio-LLM。结果如表 12 所示。在语音声音分类任务 (Vocal Sound) 上,MinMo 超越了所有基线模型。然而,我们发现,在更复杂的声音问答任务中,MinMo 的表现比 Qwen-Audio 差,尽管性能仍然优于其他模型。这可以归因于两个因素:首先,在语音编码器和训练范式中,MinMo 主要是为语音交互而设计的,因此一些声音问题可能会超出其范围;其次,在评估过程中,MinMo 会预测音频中发生的情况,而不是严格选择 Air-Bench 提供的选项,因此 MinMo 生成的一些正确或相似的正确响应与后处理脚本的错误选择保持一致。

Speaker Analysis  

说话人分析涉及几项对于理解音频数据并与之交互至关重要的任务,包括性别检测、年龄估计、说话人计数、说话人识别、多说话人识别和目标说话人识别。结果表明,MinMo 在性别检测和年龄估计任务上优于所有基线模型

Speech-to-Text Enhancement

Spoken Language Smoothing【口语平滑】

口语语言平滑任务以口语ASR(自动语音识别)转录文本为输入,输出正式风格的书面文本。表14展示了口语语言平滑的一些示例。为该任务,我们通过扩展为ASR转录文本的口语到书面转换而创建的SWAB数据集(Liu et al., 2025),构建了一个多领域数据集用于训练和评估。SWAB数据集源自中文和英文的会议、播客及讲座。

在为原始视频和音频生成ASR转录文本后,大约十位注释人员根据ASR转录文本创建正式风格的书面文本,同时保留原始内容。SWAB的训练集包含20,000段文本,测试集包括100段中文和英文的随机抽样段落。我们对SWAB测试集进行全面微调,并将MinMo与基于Qwen2.5-7B的模型进行比较,结果如表15所示。

在客观指标评估中,我们使用BLEU(Papineni et al., 2002)、ROUGE(Lin, 2004)和BLEURT(Sellam et al., 2020),以人工目标为参考。然而,我们注意到口语语言平滑任务具有显著的主观性和多样性,因此基于词汇匹配的客观指标可能无法充分反映模型性能。因此,我们采用人工和LLM注释来提供信实性(S-Faithful,即对原始内容的信实性)和正式性(S-Formal)的排名评估。自动化LLM评分的提示见附录A.1。

表15显示,我们的模型与Qwen2.5-7B的性能相当,表明MinMo在平滑口语语言方面具有较好的能力。

标点插入和反向文本规范化

对于标点插入 (PUNC) 和反向文本归一化 (ITN) 任务,我们使用来自 Fleurs 数据集的中文和英文数据。我们将 MinMo 与 SenseVoice-L 和 whisper-large-v3 进行比较,如表 16 所示。鉴于标点符号插入和 ITN 任务的主观性,我们使用 GPT-4 Turbo 对三个结果进行排序进行评估。附录 A.2 中提供了自动评分的任务提示。第一名获得 3 分,第二名获得 2 分,第三名获得 1 分。最终分数是所有分数的平均值。在准备测试数据时,我们使用随机选项洗牌和多轮评分,以减少使用 ChatGPT 进行评估时的不确定性。最终结果表明,MinMo 在标点插入和 ITN 的主观评价中表现更好

Voice Generation

文本到语音(TTS)

为了评估我们语音解码器的合成准确性,我们将最新的SEED测试集(Anastassiou et al., 2024)转换为ChatLM格式。在该格式中,文本以用户内容的形式呈现,并以“Copy:”命令为前缀,LLM预计会复制该文本。测试集包括2,020个中文案例和1,088个英文案例。对于中文案例,我们使用了Paraformer-zh模型(Gao et al., 2022),而英文案例则使用了Whisper-large V3(Radford et al., 2023)。鉴于LLM存在的指令跟随问题,我们在推理过程中应用了教师强制方案,以最小化输入和输出文本之间的差异。语音解码器的内容一致性通过中文的CER(字符错误率)和英文的WER(词错误率)进行评估。

我们的发现表明,即使在应用了教师强制方案的情况下,只有大约20%的测试案例的输入和输出文本与LLM完全一致。由于不一致的输入和输出可能导致语音解码器的隐藏状态混乱,因此仅包括输入和输出文本一致的测试案例来计算错误率。结果如表17所示。我们观察到,与TTS基线模型CosyVoice 2.0-SFT(Du et al., 2024b)相比,MinMo在中文测试集上表现出稍微较低的内容一致性和语音质量。在英文测试集上,MinMo在内容一致性上表现相似,但NMOS(语音质量评分)稍低。这个下降可以归因于微调的说话人不同的声学特性,这影响了识别模型和NMOS评分器。然而,这种下降不会显著影响人类的理解。因此,主观评估可能更适合语音到语音的语音聊天模型,我们将在未来的工作中进一步探讨这一点。

指令跟随语音生成

为了评估指令跟随语音生成的性能,我们开发了一个包含30个会话和122个回合的多轮中文语音到语音测试集,涉及12种指令控制类型。这些控制类型包括情感(高兴、悲伤、惊讶、愤怒、恐惧)、方言(粤语、四川话)、语速(快、慢)、角色扮演(机器人、佩佩)以及默认风格。

为了评估指令跟随语音生成的准确性,听众根据指令类型对生成的音频进行分类。如表18所示,MinMo在指令控制准确性方面优于基线模型GLM-4-Voice,特别是在方言和角色扮演方面。

Voice Chat

为了将基础模型的对话功能转移到语音模态,我们为语音转文本 (speech2text) 和语音转语音 (speech2speech) 场景构建了多轮次对话数据。speech2text 数据主要分为两部分。首先,它源自开源多轮次纯文本数据,我们使用零样本文本转语音 (TTS) 技术合成用户轮次。其次,我们使用真实的自动语音识别 (ASR) 训练数据作为聊天查询,从大型模型获取文本响应,从而为 speech2text 生成交互式训练数据。

MinMo 模型在语音转语音 (S2S) 模式下与现有基线相比具有显著优势,实现了新的最先进的 (SOTA) 结果。在语音转文本 (S2T) 模式下,它还在 Llama Question 和 Web Question 数据集上实现了 SOTA 性能。但是,MinMo 的测试结果仍然表明,与 S2T 模式相比,S2S 模式的性能明显下降。我们将其归因于这样一个事实,即测试集中的许多答案都具有丰富的文本结构和专业词汇,这对模型的文本转语音 (TTS) 功能提出了更高的要求。此外,在 S2S 评估中用于获取答案文本换语音的自动语音识别 (ASR) 模型也会在一定程度上影响 S2S 指标。

从表 20 中可以观察到,通过将额外的 speech2text 任务数据整合到 MinMo 训练中,我们能够有效地保持基础模型的对话能力。与 ASR 与纯文本基本模型相结合的性能相比,MinMo 的对话能力在很大程度上保持一致。但是,MinMo 的响应分数略低于 Ground Truth 响应的质量。我们认为这种差异可以归因于两个主要原因。首先,多个语音任务的集成和在基础模型上实现 LoRA 训练,在一定程度上削弱了原始大型语言模型 (LLM。该表显示,与 ChitChat 测试集相比,MinMo 在 Alpaca 测试集上表现出更大的性能变化。其次,MinMo 的音频理解能力还有进一步改进的空间,并且仍有可能降低 ASR 任务中的字符错误率 (CER)。

Full Duplex Spoken Dialogue

为了评估 MinMo 在全双工语音交互中的能力,我们构建了三个测试集:中文 Alimeeting 数据集、英文 Fisher 数据集和一个模拟测试集,旨在更接近真实的人机对话场景。我们从两个角度评估 MinMo 的全双工能力:预测性能和预测效率。关于预测性能,评估分为三个任务:辅助轮流、用户轮流和用户反向引导。对于轮流任务,我们采用正 F1 分数作为分析指标,并引入了偏移距离 ( K ) 来更好地分析模型的性能。对于用户反向通道任务,我们利用准确性来评估 MinMo 识别反向通道话语的能力。

MinMo 模型在人机对话数据集上表现出值得称道的结果,无论是用户轮流还是助手轮流。当 K=10 时,预测性能接近 99%。在实际人机对话的测试集中,与人机对话测试集相比,MinMo 模型在辅助轮流上的表现表现出一定程度的下降。我们认为这主要是由于真实人类对话中背景噪音、语速、停顿和其他因素的高度可变性,这可能导致模型在助理轮流任务中出现一定程度的误判。但是,对于人与人对话中的用户轮流预测,MinMo 模型仍然保持了高水平的灵敏度和预测性能,确保在用户说话时系统及时停止说话,从而避免与用户重叠语音。这种敏感性和对用户语音的尊重也解释了为什么 MinMo 模型对用户反向通道评论保持 70%-80% 的预测准确性,如表所示。这与 user turn-taking model 的调优是一致的,表明两者之间存在一定的权衡。

为了对 MinMo 双工模式进行效率分析,我们还分别对人机对话和人机对话测试集进行了测试。如表 23 所示,MinMo 在用户轮流中的平均响应延迟为 250ms。在人机测试集中观察到最快的响应速度,为 88.8 毫秒,而最具挑战性的 Alimeeting 测试集显示延迟为 448.8 毫秒。在辅助轮流方面,MinMo 的平均响应延迟在 660ms 左右,与用户轮流预测所需的响应时间相比,这要长。我们将其归因于以下事实:用户轮流涉及用户语音的开始部分,而助手轮流涉及用户轮到即将结束的部分。因此,助理轮流的上下文语义信息更加全面,从而缩短了决策所需的时间滞后。

Full Duplex System Latency

MinMo 的双工交互由四个模块组成:全双工预测器,负责双工控制,语音转文本模块(语音编码器+输入投影仪+LLM)、文本转语音标记模块(输出投影仪+语音标记 LM)和 Token2Wav 模块。表 21 显示了每个模块的延迟。以 Assistant Turn-taking 为例,当用户的实际语音结束时,双工模型通常需要 250 ms 的延迟进行评估。在 Speech-to-Text 过程中,对前 5 个文本标记的预测大约需要 150 毫秒。预测最初的 15 个语音令牌大约需要 70 毫秒,从语音令牌转换到第一个音频数据包需要额外的 130 毫秒。因此,在开发基于 MinMo 的全双工语音对话系统时,助理轮流的标准体验延迟约为 250 + 150 + 70 + 130 = 600 毫秒。上述数值估计值是在使用 L20 GPU 和 BF16 模型格式进行测试期间得出的。

总结/局限性

MinMo 在超过 140 万小时语音的广泛数据集上进行了训练,展示了各种基准(包括口语对话、多语言语音识别和情感识别)的最新性能。通过利用多阶段对齐策略,MinMo 巧妙地平衡了音频理解和生成,同时最大限度地减少了基于文本的 LLMs。一项关键创新是 MinMo 用于流式端到端音频生成的新颖对齐方法。通过利用文本模型的隐藏层表示,MinMo 的语音解码器实现了结构简单性和有竞争力的性能以及低延迟。这种方法显著增强了模型的指令遵循能力,能够生成细致入微的语音,准确反映用户指定的情感、方言和说话风格。此外,MinMo 支持全双工交互,以大约 600 毫秒的延迟提供无缝的对话体验。总之,MinMo 代表了语音交互系统领域的重大进步。它不仅解决了序列长度差异和数据不平衡的固有挑战,还为自然和富有表现力的语音交互设定了新标准,为多模态语言模型的未来发展铺平了道路。

MinMo 有一些需要解决的局限性。首先,MinMo 基于预训练的文本大模型,使用对齐方式集成音频理解和音频生成能力;文本大型模型仅参与 LoRA 更新,其遵循各种指令(例如语言和任务遵循)的能力需要改进。需要进一步探索以确定使用更多高质量的文本数据对文本大型模型进行更全面的更新是否可以增强其指令跟踪能力。其次,MinMo 的端到端音频生成存在一些长尾发音错误问题。这个问题部分是由于保留了 LLM,部分原因是端到端建模输出文本中的一些特殊符号无法有效地转换为语音。可以探索数据扩展来解决这些长尾问题。此外,由 MinMo 中的指令控制的音频生成的整体效率需要提高。这部分是由于当前指令数据的整体大小较小,并且仅使用隐藏嵌入进行端到端对齐的限制,这限制了历史信息的传输。最后,虽然 MinMo 实现了基于语义的双工模块,但它仍然需要单独的 AEC 【AEC模块用于消除语音通信中由于麦克风拾取扬声器输出信号而产生的回声。】和 VAD 模块。将来,将探索完全端到端的双工模型。

SLAM-Omni: 单阶段训练下支持可控音色的语音对话模型

近几个月来,许多端到端的语音对话系统涌现,旨在解决级联系统中交互延迟过高以及基于文本交互下副语言信息丢失的问题。然而,目前大多数语音对话模型依赖于大量的语音对话数据以及高昂的训练代价,且存在响应音色单一的弊端。

近日,上海交通大学计算机系X-LANCE实验室联合微软亚洲研究院推出了面向低资源场景下支持可控音色的语音对话模型——SLAM-Omni。该模型只需要在4张GPU上单阶段训练15小时,即可获得远超此前同等规模模型的对话能力,并且具有优越的语音质量以及生成语音-文本一致性。在更大规模数据集上的实验表明SLAM-Omni在中文对话以及多轮对话上都有不俗的表现。

语音对话系统建模

本文首先探索了主流的语音对话系统建模方案,现有端到端系统主要通过将文本作为中间输出或隐藏状态来利用预训练的大语言模型(LLM)。这些方法可以分为文本驱动建模和音频-文本联合建模两类。

文本驱动建模保留了LLM原始架构,将文本隐状态传递给语音解码器生成音频,能够有效保留LLM的知识,使用其隐藏状态作为语音解码器的输入用于音频生成,但由于只使用文本tokens进行自回归建模,难以捕捉音频的情感和语调等副语言特征。音频-文本联合建模分为交替和并行两种范式,均将音频 tokens加入自回归建模,理论上提升对非语言信息的建模能力。交替范式通过交替使用文本和音频tokens进行生成,需要大量的语音-文本交替数据并重新训练LLM。而并行范式则并行地对文本和音频tokens自回归生成。SLAM-Omni在此基础上,通过预测单层语义tokens并结合语义分组建模的方式来加速音频生成,显著降低了训练成本。

主要贡献:

  • 提出了第一个针对具有说话者解耦语义token的语音交互系统的零样本音色控制解决方案。
  • 提出语义组建模方法来加速单层语义语音标记生成和模型训练。
  • 历史文本提示是为了在SDM【Existing spoken dialogue models】 中进行高效的多轮历史建模而提出的。
  • SLAM-Omni 是第一个实现单阶段训练的语音助手,需要最少的数据和计算资源
  • 实验表明,SLAM-Omni 在文本相关任务上优于类似规模的先前模型,并且在所有现有 SDM 中在声学质量和语音文本对齐方面表现出卓越的性能。更大数据集上的结果证明了其多语言和多轮对话能力。

方法

模型概述

SLAM-Omni通过将系统提示、历史文本提示和用户语音嵌入拼接作为输入,并在Vocoder中通过语者提示来控制音色【 借鉴TTS模型 cosyvoice: 条件流匹配模型 +HifiGAN】;同时,采用语义分组建模加速自回归过程中的语音token生成。

输入语音建模

SLAM-Omni使用Whisper编码器从用户语音指令中提取音频特征(50 Hz)。Whisper作为在大规模跨语言语音数据上训练的语音识别模型,提供了精准的转录和强大的多语言支持,是SLAM-Omni实现多轮多语言对话能力的基础。我们通过降采样处理音频特征,将多个连续帧合并,并通过线性投影将其转换为与LLM嵌入维度对齐的形式。这些处理后的音频特征与文本提示嵌入一起,作为输入传递给LLM。

输出语音建模

在语音输出方面,SLAM-Omni采用并行的音频-文本联合建模,并行地自回归预测文本和音频的语义tokens。为此,我们扩展了LLM的词表,新增了音频tokens的码本,并将原始的词嵌入矩阵与新嵌入合并。在每个生成步骤中,LLM输出的logits包含了文本和音频tokens的预测分布。然而,由于文本tokens(约为3Hz)和音频语义tokens(50Hz)的频率差异,直接以相同速率生成这两种tokens会导致语音对话模型的训练和推理成本大幅增加,同时增加了实时语音生成的延迟。

为了解决这一问题,本文提出了“语义分组建模”方法每步生成多个音频tokens,从而缓解频率不匹配带来的挑战。该方法通过线性层将音频logits投影到分组logits中,并对应的在训练过程中将原语义token序列按组进行划分。通过这种方式,模型能够在自回归过程的每步中同时处理多个音频tokens,从而加速语音生成并极大地降低训练和推理的成本。模型的训练目标可以表示为文本层和音频层交叉熵损失的加权和。

可控音色建模

SLAM-Omni通过将语音内容建模为语义tokens,天然地实现了音色与语言信息的解耦,将zero-shot音色控制从TTS扩展到了语音对话系统上。借鉴TTS模型(Cosyvoice)中的技术,SLAM-Omni使用条件流匹配模型将语义tokens和语者提示信息转换为mel频谱图,并通过HiFi-GAN合成波形。此外,为了支持实时语音生成,SLAM-Omni在流匹配的Transformer架构中采用了块因果注意力机制。

多轮对话

过去的语音对话模型在多轮对话建模上通常将文本和音频tokens交替作为历史,但较长的音频token序列显著提高了训练成本,限制了对话轮次。此外,较长的历史也会影响模型的上下文学习能力,并可能导致早期对话内容的遗忘。为了解决这些问题,SLAM-Omni引入“历史文本提示”(Historical Text Prompting)的方案,仅使用文本模态来表示对话历史。在多轮对话交互中,SLAM-Omni采用模板:<系统提示> <历史文本> <输入> <响应>。其中,系统提示指定模型角色和任务,历史提示则以文本形式存储过去的对话内容。这种方式与LLM的训练模式高度契合,同时避免了长音频序列建模的负担,使得模型能够在受限的上下文窗口内处理更多的对话轮次。在推理过程中,通过Whisper提取的语音特征可以解码成输入语音的转录文本,模型输出的文本tokens则通过分词器转换为文本。每轮对话中,由此得到的问题-响应文本对会被追加到历史对话中,以便下一轮使用。如图所示,第一轮语音对话的转录被纳入历史提示中,第二轮推理时计算得到的KV键值缓存可以在第三轮及以后的对话中复用,从而提高多轮推理的效率。

单阶段训练

此前的端到端语音对话模型通常需要进行模态适配、模态对齐和有监督微调等多阶段训练,这不仅需要精细的训练策略,还涉及多个超参数的调整,带来了显著的时间和计算成本。而SLAM-Omni通过简化为单阶段微调训练,能够在较小的数据集上快速收敛,展现了高效的训练效果。在我们的实验探索中,TTS和ASR的预训练都展示了快速的损失收敛,表明我们的方法无需大规模的模态对齐预训练。同时,进一步的实验还揭示,预训练实际上可能对模型的指令跟随能力和预训练知识保留产生负面影响。

实验设置

由于大多数开源的对话数据集仅为文本格式,我们通过zero-shot TTS系统合成语音对话语料。具体而言,我们使用CosyVoice模型生成用户输入的语音,同时随机从音色库中抽取语者提示,以控制音色。对于语音响应,我们使用CosyVoice模型生成语义tokens,它们在SLAM-Omni训练过程中作为目标音频tokens使用。我们使用的训练数据集包括VoiceAssistant-400K、英语多轮数据集UltraChat和中文对话数据集Belle_train_3.5M_CN。为了确保数据质量,我们清理了数据中的书面体(如表情符号、URL等),并限制了语音问题和响应的时长,以更好地模拟自然对话场景。在SLAM-Omni的主要实验中,仅使用VoiceAssistant-400K数据集,其他数据集则用于补充实验,评估模型在多轮和多语言对话任务中的表现。

对于用户输入,采用CosyVoice-300M模型来产生相应的语音。声音音色是通过从音色库中随机采样扬声器提示来控制的,该音色库包含来自seed-tts-eval3的1007个英语和1010个中文人类音频提示。对于助理响应,我们使用 CosyVoice-300M-SFT 的文本到令牌 LLM 来生成语义令牌这些令牌在 SLAM-Omni 训练期间用作目标音频令牌

在训练和推理过程中,为确保在低资源环境下的公平比较,我们使用Qwen2-0.5B作为LLM骨干,并选择Whisper-small作为语音编解码器。在主要实验中,SLAM-Omni采用的语义分组大小为G = 3。在单阶段训练中,SLAM-Omni进行全量微调,只有Whisper编码器保持冻结。整个训练过程大约需要在4个A100 GPU上进行15小时

为了全面评估语音对话模型的语音交互能力,本文提出了一个新的评测框架,涵盖理解、推理和口语对话三个关键环节。通过设计八个测试集,我们分别从这三方面考察模型的表现。在“理解”部分,评估模型是否能够理解并跟随用户指令;在“推理”部分,通过逻辑、数学和常识问题测试模型的推理能力;而在“口语对话”部分,我们测试模型在开放式对话场景下的交互能力。评估指标包括内容质量(通过ChatGPT评分)、语音质量(通过UTMOS评分)以及语音与文本的一致性(通过WER评分)。

实验结果

实验结果表明,SLAM-Omni在低资源场景下的表现超越了同规模的语音对话模型,在语音内容、音频质量和语音-文本一致性上显著提升,特别是在UTMOS和ASR-WER评分上表现突出,显示出其在音频建模方面的优势。在ChatGPT评测中,尽管和更大规模的模型相比仍存在差距,SLAM-Omni在理解、推理和口语对话能力上显著超越了同规模的Mini-Omni系列,表明其保留了更多的预训练LLM知识和指令跟随能力。

在音频质量和语音-文本一致性上,SLAM-Omni的表现优于所有其他语音对话模型,特别是在ASR-WER指标上,表明其语音-文本对齐更加紧密。而其他模型在生成过程中容易出现生成音频与文本不对齐的情况,尤其在长内容生成时,容易出现音频中断或长时间的静默,导致其UTMOS和ASR-WER评分较低。

消融实验表明,语义分组建模显著提高了生成语音与文本的对齐度,尤其当组大小G≥3时,ASR-WER低于5%,相比之下,没有执行分组算法的模型(G=1)的ASR-WER高达18.23%。这一差距主要来源于音频和文本token之间的频率不匹配。通过减少音频序列长度,语义分组建模有效缓解了这一问题,同时减少了训练和推理成本,并加速了音频生成,提供了更流畅的用户体验。

关于训练策略的消融实验表明,传统的多阶段训练方法虽然能略微提高模型的音频-文本对齐度,但在语音交互任务上的整体表现并未显著改善。相比之下,SLAM-Omni采用单阶段训练策略,显著提高了ChatGPT评分,并保持了相当的音频质量。通过直接在语音到语音数据上进行单阶段微调,SLAM-Omni能够更好地保留预训练LLM的知识,避免了传统预训练任务带来的知识流失问题,提高了训练效率。

附录:

Pre-training Details

对于ASR和TTS预训练,专门使用VoiceAssistant-400K数据集来确保一致性并避免引入外部数据。在 ASR 预训练期间,提供语音指令作为输入,其相应的转录文本作为目标输出。相反,对于 TTS 预训练,语音响应的转录被用作输入文本,而相应的语义token被设置为预测目标。优化和学习策略与微调期间采用的策略一致,值得注意的是,在 ASR 预训练期间仅计算文本层损失,而 TTS 预训练专门关注多层音频损失作为训练目标。

曲线显示,ASR 和 TTS 任务都实现了快速收敛,证明了模型在短时间内有效“理解”和“生成”语音的能力。这一观察表明,理解和生成任务中的模态对齐本质上是简单的,需要最少的预训练工作。此外,如表 6 所强调的,直接对语音到语音任务进行训练可以产生卓越的性能,同时减轻通常与预训练相关的知识退化。

总结 

本文提出了SLAM-Omni,一种单阶段训练下支持可控音色的端到端语音对话模型。通过语义分组建模,SLAM-Omni有效地对齐了音频和文本模态,同时加速了训练和推理过程。采用有监督的语义tokens解耦说话人信息,使得SLAM-Omni实现zero-shot音色控制。为了解决长音频历史带来的问题,我们引入了历史文本提示技术,将对话历史存储为文本,并通过键值缓存提高多轮推理效率。在少量数据训练仅仅60个GPU小时下,SLAM-Omni在文本相关能力上超越了同规模的语音对话模型,并在音质和语音-文本对齐方面表现优越。

MiniCPM-o 2.6: 端侧可用的 GPT-4o 级视觉、语音、多模态实时流式大模型

➤ 项目网站 🔗https://github.com/OpenBMB/MiniCPM-o

➤ 模型权重 🔗https://huggingface.co/openbmb/MiniCPM-o-2_6

🔗https://modelscope.cn/models/OpenBMB/MiniCPM-o-2_6

➤ Demo https://minicpm-omni-webdemo-us.modelbest.cn/

MiniCPM-o 2.6部署教程 详细的部署教程请参考文档

简介

多模态大模型的蓬勃发展始于视觉和语言,其中开源社区在图像理解能力方面实现了越来越强的性能表现。然而,我们的物理世界本质上是一个并行的连续多模态信息流,而当前大多数多模态大模型缺乏处理这样信息流的能力。最近的 GPT-4o 和 Gemini 2.0 等突破性工作迈出了朝这个目标的第一步,为领域的未来发展建立了雄心勃勃且充满希望的方向。

为了促进开源社区的探索,我们推出了 MiniCPM-o 2.6,一个从 MiniCPM-V 系列升级而来的最新性能最佳的端侧多模态大模型。该模型接受图像、视频、文本和音频输入,并以端到端方式生成高质量的文本和语音输出。虽然总参数量仅有 8B,MiniCPM-o 2.6 的视觉、语音和多模态流式能力达到了 GPT-4o-202405 级别,是开源社区中模态支持最丰富、性能最佳的模型之一。其主要特性包括:

  • 领先的视觉能力。 MiniCPM-o 2.6 在 OpenCompass 榜单上(综合 8 个主流多模态评测基准)平均得分 70.2,以 8B 量级的大小在单图理解方面超越了 GPT-4o-202405、Gemini 1.5 Pro 和 Claude 3.5 Sonnet 等主流商用闭源多模态大模型。此外,它的多图和视频理解表现也优于 GPT-4V 和 Claude 3.5 Sonnet,并展现出了优秀的上下文学习能力。
  • 出色的语音能力。 MiniCPM-o 2.6 支持可配置声音的中英双语实时语音对话。MiniCPM-o 2.6 在语音理解任务(如 ASR 和 STT 等)优于 GPT-4o-realtime,并在语音对话的语义和声学评估中展现了开源社区最佳的语音生成性能。它还支持情绪/语速/风格控制、语音克隆、角色扮演等进阶能力。
  • 强大的多模态流式交互能力。 作为一项新功能,MiniCPM-o 2.6 能够接受连续的视频和音频流,并和用户进行实时语音交互。在综合评测基准 StreamingBench 中(包含实时视频理解、全模态视音频理解、多模态上下文理解三大类评测),MiniCPM-o 2.6 取得开源社区最佳水平,并超过了 GPT-4o-202408 和 Claude 3.5 Sonnet。
  • 强大的 OCR 能力及其他功能。 MiniCPM-o 2.6 进一步优化了 MiniCPM-V 2.6 的众多视觉理解能力,可以处理任意长宽比的高清图像,像素数可达 180 万(如 1344×1344像素)。在 OCRBench 上取得 25B 以下最佳水平,超过 GPT-4o-202405 等商用闭源模型。基于最新的 RLHF-VRLAIF-V 和 VisCPM 技术,该模型具备了可信的多模态行为,在 MMHal-Bench 上超过了 GPT-4o 和 Claude 3.5,并支持英语、中文、德语、法语、意大利语、韩语等30多种语言的多模态交互。
  • 卓越的效率。  除了对个人用户友好的模型大小,MiniCPM-o 2.6 还表现出最先进的视觉 token 密度(即每个视觉 token 编码的像素数量)。它仅需 640 个 token 即可编码 180 万像素图像,比大多数模型少 75%。这一特性显著优化了模型的推理速度、首 token 延迟、内存占用和功耗。因此,MiniCPM-o 2.6 可以首次支持 iPad 等终端设备上的高效多模态实时流式交互。
多模态大模型发展趋势。多模态大模型的性能持续增强,并在真实世界的流式场景中支持越来越多的模态能力。与传统视觉语言模型的线性发展不同,这种发展趋势更加多维,就像攀登深处的山峰一样,可能蕴含更多变革性的宝藏。

我们将介绍 MiniCPM-o 2.6 中所面临的主要挑战及其相应的解决方案。

🤔 如何实现多模态流式交互?

人类能够持续感知来自环境的视觉、音频和文本信息流,并以较低延迟生成语音和文本回复,但这对当前的多模态大模型来说是一个重大挑战。

💡 1. 我们将各模态的离线编码/解码器改造为支持在线模式,从而支持流式输入/输出处理。

大多数模态的编码器和解码器都是离线的,大语言模型必须等待完整的视觉/音频输入的编码完成后才能进行处理,用户也必须等待语音完整生成后才能收听。我们在时间维度上将不同模态的输入/输出流分割成小块,并以块为单位进行编码/解码以实现更低的延迟。对于语音生成来说,我们设计了一种新颖的流式注意力策略使解码器能够在接收到第一个文本块时就开始生成音频。

💡 2. 我们提出了一种全模态时分复用机制来处理并行多模态流。

借鉴通信领域的时分复用技术,我们将每个模态的信息流分割成小块(每秒一块),并将同一秒内的所有模态信息组合成一个紧凑的序列单元输入给大语言模型主干。基于这个策略,主干模型可以高效地在线处理多模态信息流。

🤔 如何实现高效的端到端声音、情感、口音和语速可控的语音对话?

大多数传统语音对话模型都是基于 ASR-LLM-TTS 流水线实现的,会丢失大量用户复杂情感和环境声音等细粒度信息。而直接使用大语言模型生成音频 token 的端到端模型在训练和推理过程中都存在计算效率低的问题,且训练时数据效率也较低。

💡 我们基于混合的端到端架构在自然语音上进行了大规模预训练。

我们同时通过连续特征和文本将大语言模型和一个轻量级语音解码器连接起来。大语言模型产生的连续特征确保语音监督信号能够以端到端方式反向传播到全部模型参数,从而支持更高的能力上限。文本连接则提供了强大的语义控制并减少了训练数据需求。为了学习丰富的细粒度语音知识,我们在自然语音数据进行了大规模预训练,然后将模型与用户指令对齐。

端到端全模态架构

我们首先介绍 MiniCPM-o 2.6 的端到端全模态整体架构。该模型基于SigLip-400M、Whisper-medium-300M、ChatTTS-200M 和 Qwen2.5-7B-Instruct,总共有 8B 参数。整体架构如下所示。

端到端语音建模

大多数现有的多模态模型依赖 ASR 和 TTS 工具搭建流水线来理解和生成语音,导致了明显的语音信息损失和比较有限的语音控制能力。我们提出一种混合连接的端到端语音建模架构,在保证模型能力上限的同时具备优秀的训练和推理效率。

音频编码

我们首先使用 Whisper 编码音频输入,然后进一步压缩其特征表示来减小后续的计算开销。默认情况下,Whisper 编码器会为每秒音频生成 50 个 token。受 LLaVA-UHD 的启发,我们在将音频 token 输入到大语言模型主干之前会进一步压缩音频 token,以提高 token 信息密度和计算效率。实验结果表明从 50 token/秒压缩到 25 token/秒时,造成的信息损失几乎可以忽略,并可提高近一倍的计算效率。

语音解码

为了实现对语音输出的精细控制,我们首先从大语言模型主干中获得连续特征作为 speech embedding,然后通过大语言模型继续生成文本。speech embedding 和生成的文本同时会输入给解码器作为生成语音梅尔谱的控制条件。MiniCPM-o 2.6 使用了初始化自 ChatTTS 的轻量级自回归语音解码器来联合建模输入的 speech embedding、文本和输出的音频 token。

语音到语音架构

我们直接通过编码后的音频特征(不使用 ASR)将音频编码器与大语言模型连接起来。大语言模型和语音解码器则以混合方式连接:(1)speech embedding 连续特征控制语音、情感、口音及其他细粒度语音特征。在训练过程中,来自语音解码器的梯度会反向传播到包含大语言模型主干和音频编码器的整个模型参数。模型通过端到端方式训练,没有使用任何中间损失和监督。(2)我们还将来自大语言模型的文本输入到语音解码器,来提供更好的语义控制和训练数据效率。

得益于端到端的架构设计,MiniCPM-o 2.6 成为首个支持端到端语音克隆的通用语音对话模型。我们发现 MiniCPM-o 2.6 在语音克隆任务中可以达到与一些专业 TTS 工具相近的性能。

端到端视觉理解

MiniCPM-o 2.6 采用 LLaVA-UHD 的自适应视觉编码方案以实现高清视觉理解,支持处理最高 180 万像素(例如 1344×1344)的任意长宽比图像。具体而言,我们先将图像划分为多个切片,使得每个切片在分辨率和长宽比方面接近 ViT 的预训练设置。为了提高计算效率,我们支持每张图像最多 9 个切片。然后我们将每个切片及原始完整图像输入给 SigLIP 以获取视觉特征。最后,我们应用 perceiver resampler 将每个图像切片的特征序列压缩为 64 个视觉 token。更多细节参见 LLaVA-UHD 和MiniCPM-V 原始论文。

全模态流式机制

本章我们介绍 MiniCPM-o 2.6 的全模态流式机制,包括:(1)改造语音编码器和解码器以支持在线流式处理,(2)使大语言模型主干能够处理并行的多模态流信息。

流式音频编码

大多数现有模型只能在整个音频输入信号完整后才开始进行音频编码,从而引入了显著的延迟。为了解决这个问题,我们将输入音频分割成多个片段,每个片段是表示一秒钟的音频的固定数量音频 token。在音频编码过程中,每个片段采用因果注意力机制进行编码仅关注自身及之前的片段,从而满足在线流式编码的需求,同时与离线整体编码相比保持了最小的信息损失。

每个小方块表示1s的音频片段

流式语音解码

大多数语音生成模型要求在开始生成音频之前,所有文本 token 都已经完整就位,如图 A 所示。虽然这种方式在离线任务中表现良好,但无法满足流式场景的需求。对于流式模型而言,我们需要在部分文本生成时就开始生成(和播放)相应音频。

为了实现流式语音生成,我们每次输入固定数量的文本 token(一个大小为 n 的片段),而解码器立即输出固定数量的音频 token(一个大小为 m 的片段)。这个过程会对下一个文本 token 和音频 token 片段重复进行,以此类推。值得注意的是,文本片段与其对应音频片段之间的并不是精确对齐的。因此在实际应用中,我们为文本 token 片段的大小保留了更大的空余以避免意外情况。

为了实现上述流式策略并尽可能减小对当前最佳语音解码器的改动,我们主要引入了两个改变:

  1. 为文本预留前 N 个位置: 我们使用语音解码器上下文中的前 N 个位置来放置 speech embedding 和生成中的文本。
  2. 引入流式因果注意力掩码: 每个新生成的音频片段只能关注到已经生成的前几个文本 token 片段和其之前的所有音频 token。

在图 A-E 中,我们展示了每当引入新文本 token 和音频 token 时,注意力掩码是如何一步一步变化的。通过控制文本和音频 token 之间的片段注意力掩码,我们使得音频能以流式方式生成和播放。

  1. (文本和音频生成的开始)图 B 中,大语言模型主干生成 speech embedding 和前 n 个文本 token(此处 n=2)。然后,我们将 <Text BOS>(1 个位置)、speech embedding(1个位置)和文本 token(n个位置)输入到语音解码器中(总共输入了 2+n 个位置),基于此,模型可以生成最多 m 个音频 token(此处 m=4),但仅关注前 2+n 个位置以及所有之前的音频 token 位置。
  2. (步骤 1 的重复)图 C 中,大语言模型生成下一段 n 个文本 token。我们将这些新文本 token 输入到语音解码器中。然后,解码器生成下一段 m 个音频 token。
  3. (文本生成结束)图 D 中,大语言模型完成所有文本 token 的生成,产生了最后的 k 个文本 token(k<=n,此处 k=2)。剩余的 k 个文本 token 被输入到语音解码器中。然后,语音解码器生成下一个m个音频 token。
  4. (音频生成结束)图 E 中,语音解码器继续生成音频 token,直到生成 <Audio EOS> token。

这里的 N、n 和 m 是超参数。在实际应用中,我们使用 N=300、n=10、m=50,以实现性能与推理速度之间的平衡。

流式视觉理解

我们将视频流表示为以 1 帧每秒(1 fps)的帧序列。我们每秒钟从输入的视觉流中采样一帧,并使用自适应高分辨率编码策略对其进行编码,然后将编码后的特征输入给大语言模型主干。

为了在效率和性能之间取得平衡,我们设计了一种简单的混合分辨率策略。具体而言,我们只对用户请求结束时的最后一帧进行高分辨率编码(例如 1344 x 896),而其他帧则使用中等分辨率(例如 448 x 448)。

全模态时分复用

为了实现对不同模态的时间对齐的流式理解,我们提出了一种全模态时分复用机制。如整体框架图所示,我们首先使用共享的时间线对齐来自多个模态的信息流。受到通信领域时分复用技术的启发,我们将每个模态的流分成小块(每秒一块),并将同一秒块内的所有模态信息聚集成一个紧凑的序列单元。大语言模型则按时间顺序处理这些多模态序列单元。

需要注意的是,MiniCPM-o 2.6 可以独立于用户提问持续感知多模态输入流,这与现有的多模态流式模型只在用户提问期间获取单帧或少数几帧图像信息是不同的。通过这种方式,MiniCPM-o 2.6 能够处理需要时序记忆和推理的任务(例如,“球在哪个杯子里?”、“我刚才擦掉了哪些字?”)并原生支持多轮流式对话。

延迟分析

我们提供了纯音频模式下首次响应延迟的具体拆解分析。首次响应延迟指从用户请求结束到模型语音开始播放的延迟。作为参考,GPT-4o 在纯语音模式下的初始响应延迟约为 1.8 秒。MiniCPM-o 2.6 在iPad Pro(M4 芯片)上的初始响应延迟分解如下表所示:

多模态系统提示词

社区在使用文本提示词方面已经积累了丰富的经验,一个好的系统提示可以定义模型的角色、增强其准确性、优化细节表现和令模型聚焦重点。

生成语音回复的端到端全模态模型则面临新的挑战。模型输出的音频特征——如声音、语调、口音和其他细微特征至关重要,但无法仅通过文本传达。为了应对这一挑战,我们提出了多模态系统提示词的概念,允许用户通过声学特征控制模型的声音使其与用户意图相符

具体来说,多模态系统提示词包括传统的文本系统提示词和用于确定模型声音的音频部分。这一设计使得用户在推理时可以灵活配置声音。用户可以通过提供一段语音样例作为音频系统提示,来完成端到端的声音克隆;还可以通过将音频系统提示留空,基于语言描述要求模型创建一种新声音(例如 “请使用低沉有磁性的声音和我说话”)。

模型训练

MiniCPM-o 2.6 采用多阶段训练以逐步学习新模态的知识,从而避免模态冲突并将各种模态能力整合到一个模型中。整体的训练阶段可以分为预训练、指令微调和偏好对齐阶段。

预训练

我们首先分别对视觉和音频进行预训练以学习每种模态,然后进行全模态预训练以对齐这些模态。

视觉预训练。 我们利用大规模图像-文本对来对齐视觉和语言模块。在此阶段,我们仅更新视觉编码模块,让模型具备基本的图像理解和 OCR 能力。然后,我们在图文交替数据上训练视觉编码器和大语言模型,使模型具备多图理解和多模态上下文学习能力。

音频预训练。 我们使用音频-文本对数据来训练连接部分的权重,以实现音频模态和主干的对齐。为了学习丰富的细粒度语音知识,我们在自然语音数据上进行大规模端到端的预训练,然后根据用户指令对模型进行对齐。

全模态预训练。 在这一阶段,我们结合来自大规模网络视频的视频和音频流,使用 OTDM 机制使模型能够从不同模态中获取和对齐丰富的知识。

全模态指令微调

该阶段使用高质量的多模态数据进行监督微调,包括视觉问答、语音理解、语音生成和多模态流式视频(带音频)理解数据。我们对模型进行全参数微调以统一模型的视觉能力、语音理解和生成能力,以及流式多模态能力,同时增强模型的指令遵循能力。

偏好对齐

最后,MiniCPM-o 2.6 采用 RLAIF-V 技术以进一步提高模型的可信度和综合能力。在这个阶段,模型使用分而治之的策略对不同的回复进行评分以构建偏好数据集,并进行直接偏好优化训练(DPO)。同时,我们还特别将相比图像幻觉更常见的视频幻觉比例降低了63%。我们也使用了 MMPR 等开源偏好数据集来多样化训练数据。

评测

我们充分评估了 MiniCPM-o 2.6 的视觉理解、语音对话和多模态流式交互能力。实验结果表明,该模型在视觉、语音和多模态流式交互能力上的整体表现与 GPT-4o-202405 相当。

MiniCPM-o 2.6 的 iPad Pro 实机演示和 web demo 演示样例:

局限性

  1. 可能不稳定的语音输出。 多模态系统提示词使得更灵活的语音控制和许多有趣的功能成为可能,但也给语音输出的稳定性带来了更多挑战。传统的语音对话模型通过全参数记忆单一输出声音,与之相比,MiniCPM-o 2.6 需要从多模态系统提示词中提取和复制声音。受到该问题影响,语音生成结果可能会存在背景噪音和无意义声音等。
  2. 长语音生成。MiniCPM-o 2.6 原生支持最长 45 秒的单次语音生成,我们通过滑动窗口技术来支持生成更长的语音。模型训练与滑动窗口推理之间的差距可能导致长语音生成过程中的不稳定现象。
  3. 多模态流式交互能力。 作为一项实验性能力,模型的多模态流式交互能力在感知、理解和推理能力上仍然有限。我们期待社区的共同努力构建更优秀和可靠的性能效果。
  4. 网页 demo 高延迟。 用户在使用托管在海外服务器上的网页 demo 时可能会遇到异常的高延迟情况。我们建议在本地部署 demo(例如 4090 GPU 可以流畅运行)或使用合适的网络连接。

参考文献

  1. MiniCPM-V: A GPT-4V Level MLLM on Your Phone. 2024.
  2. RLHF-V: Towards Trustworthy MLLMs via Behavior Alignment from Fine-grained Correctional Human Feedback. CVPR 2024.
  3. RLAIF-V: Aligning MLLMs through Open-Source AI Feedback for Super GPT-4V Trustworthiness. 2024.
  4. LLaVA-UHD: an LMM Perceiving Any Aspect Ratio and High-Resolution Images. ECCV 2024.
  5. Large Multilingual Models Pivot Zero-Shot Multimodal Learning across Languages. ICLR 2024.