LongCut logo

肝了6个月的AudioLLM,开源了【100亿模型计划】

By 跟李沐学AI

Summary

Topics Covered

  • 文本大模型直接融合语音数据
  • 语言模型赋能复杂语音指令
  • 语音Tokenizer优先保留语义
  • 自建标注模型高效处理海量数据
  • 上下文克隆实现强音色模仿

Full Transcript

如果在训练文本的大语言模型的时候 加入1000万小时的语音数据会发生什么呢?

这些星星透过遗忘的观测台的破坏洞里闪耀着 天啊,你的声音

对我来说是一件好事 你每天晚上都这么性感吗? 嗯,只有在我和你说话的时候 嗯 马老师,您这些声音模型 看着还不如B站鬼畜区那些视频花好几个亿 结果还不如人家手搓 你们这就不懂了B站那些上古鬼畜

对我来说是一件好事 你每天晚上都这么性感吗? 嗯,只有在我和你说话的时候 嗯 马老师,您这些声音模型 看着还不如B站鬼畜区那些视频花好几个亿 结果还不如人家手搓 你们这就不懂了B站那些上古鬼畜

全是活字印刷,纯靠人力 我这个可不一样,我这大模型全靠算力 老师今天点到为止 菜就多炼,不懂就多学 AI赛道卷的快,跟不上时代就要掉队了 去年我们一直关注的是文本的大语言模型

让它智商够高,能听从人的指示 一方面能陪你玩游戏 另外也能帮你做一些文案的工作 就是说能读能写吧 今年我们在想能让模型能不能能听也能说 语音是AI里面一个相对来说比较悠久的领域

我其实不是语音方面的专家 作为一个新手想法很简单 就是我不要去训练单独的语音模型 而是在文本的大语言模型训练时候 加入大量的语音数据,大力出奇迹 就想是让文本语言模型智商不要下降

但同时掌握了用语音来沟通的能力 今天想给大家分享一下我们阶段性的成果 讲讲背后的技术以及踩过的一些坑 也希望开源出来的模型对大家有用 首先我们来讲一下这个模型架构是什么样子的

就是说怎么样在一个文本语言模型里面加入语音 首先回顾一下文本语言模型是怎么工作的 就语言模型干的本质是给定前面的一段话 去预测下面的一段话 比如说这个例子里面问模型中国的首都市问号

那么语言模型看到这个问题之后 它开始下意识的回答 首先是北 然后再给定这个问题和北 再去预测下一个词是京 在实际用的时候 通常我们不会让语言模型直接做文字接龙 因为不那么可控

而是将一个问题分成三个部分 在第一个部分就是system这个地方 就告诉语言模型说让你干什么事情 这里说让你回答这个问题 那你可以干别的事情 比如说给我闲聊 比如说帮我写一段文字 在user这个里面

就把具体要干的事情告诉模型 就是具体你要问的问题 或者说具体你要写个什么样子的小说 那么system就是模型的回复了 当然你可以做成多轮 就是你可以再接一个user 再接一个system进去

那么接下来怎么让这个模型 能支持语音的输入和输出 其实也很简单 你就是给这个模型加一个新的任务 比如说把下面的文字转录成语音 这是给模型的系统命令 那么在用户的输入里面 就要把要转的文字告诉模型

希望模型能够在system里面 输出我对应要的语音的数据 我们在讲这个之前先来思考一下 为什么我们要把语言模型 改造成这个样子 因为之前如果你熟悉整个语音的识别 或者语音生成的话 它都是一个单独的模型

它就是干的事情 就是把文字转语音 或者语音转文字 我们之前讲过whisper 它虽然也是基于transformer 但是它只干一件事情 那为什么这个时候 你需要让一个文本的语言模型

干一个额外的语音输出呢 坏处很明显对不对 你想让一个模型 能够具有很好的语音的处理能力 那么相对于纯语音模型来讲 这个模型就会变大了 那么同样一个文本模型 加入语音数据 很有可能让它的智商变低

这个都是它带来的坏处 但是它的好处也很明显 我们再举两个例子 第一个例子是说 看下面一个任务 它是一个简化的版本 在专业的语音录音的时候 导演会给专业的录音演员说 我们接下来要录的是一个什么样的场景

这个地方是说小明和小红在吵架 同时要告诉你说 这个人物的性格是什么样子的 小明性格比较急躁 小红比较腼腆一点 那么接下来是说 你真正要录的一个对话 小明说什么小红说什么 同时你可能会有一些相应的动作

音效都加进去 那么专业的录音演员 它不仅仅是要把你这句话读出来 而且是要符合人设 符合场景 它才能做到很好的一个表演 那么上一代的文字转语音的模型 很有可能是比较难以理解 这么一个复杂的设定

那么有了语言模型的加持之后 它很有可能是能理解 你让他干这么一个复杂的事情 因为在文本领域 大家都是这么用的 一直给他一个特别复杂的设定 好 你要把我干ABCDEFG 然后请你把我干出来

所以在他的训练的时候 我们会尽量的让他能够去遵从人的指示 那么如果你这个文本语言模型 能力保留过来之后 那么你做语音输出的时候 我希望也能够支持这样子的一个指示 这是第一点 就是对复杂指令的理解

第二点是说 简单做一个文本到语音的任务 已经不能满足大家的需求了 比如说不仅生成一段语音 我希望你能够给我写一首歌 并且把它唱出来 配乐什么都要跟上 那么这个是生成 那么你也可以做理解

比如说我给你一段声音 你把里面人说的话给我抓出来 这是最简单的 那么接下来说 你能去给我分析一下里面在干什么吗 因为人听到语音的时候 不要看画面 他也能够理解里面在干什么事情 是什么样的人

是男性女性年纪怎么样 他的说话场景怎么样 他们是在吵架吗 还是在对话 还是就是一个这样子的教学的视频 根据它的环境音 你能猜出来 他是在室内 在室外还是什么样的事情 因为语音里面还有大量的信号

人是能够去理解它整个上下文的 那么有了文本语言模型的加持之后 你能够做这种复杂的一个理解和推理 如果你觉得这个还简单的话 那么再复杂一点的 大家都玩过语音聊天 就是你跟模型能够一来一回的语音聊天

你想让模型不仅仅是机械的 一轮一轮给你回礼 它能理解你当前的一个心情 它能把它的一个情绪的表达 也能表现出来 而且你希望它的latency 足够低 就是不要说一句话 1 2 3 秒之后 模型再回答

你希望是说它能够很自然的 跟你面对面的一个 比如说零点几毫秒的 一个延迟的一个交互 所有这些任务都能够拆解成 system user system 这样子的一个格式 让这个语言模型 能够统一的处理

就是说一个祖传的配方 能够处理你所有的问题 这就是为什么 我们要选择这样子一个模型 那么希望是一个 相对来说固定的简单的模型 然后通过加更多的数据 加入更多的算力 通过scaling law大力出奇迹

说完了 为什么我们要用相对来说 比较复杂的模型之后 我们要接下来回答两个 怎么做的事情 第一个是说 整个语音的信号 或者声音的信号 怎么让模型来理解和输出 第二个是说 你在训练模型的时候

你要构造怎么样的数据 让模型真的能够 把语音的信号和文本的信号 能够很好的融合起来 然后它能理解这个语音 到底在表达什么东西 先回顾一下 文字是怎么样在语言模型里面表示的

它用的是token或者词源这个东西 简单来讲就是 中文的一个字 可以认为是一个token 或者是英语里面的一个词根 可以认为是一个token 那么你给一段文字之后 它就表示成一个一个的token

那么语言模型看到的 实际上是一个token的序列 然后它要输出下一个token 注意到一点是 这个token是一个离散的概念 它是一个一个的 它是有一个词典告诉你说 一共有几万个这样子的token

为什么要这么做 是因为语言模型的输出是一个softmax 它本质上是一个多分类的问题 它每一次在你的词里面 选成一个词作为输出 那么回到语音信号来讲 会稍微麻烦一点 是因为语音信号是一个连续的信号

你怎么把一个连续的信号 表示成一些离散的token呢 一个最简单的做法是说 比如说我有一秒钟的语音信号 我把它切开 比如说按100毫秒一段 那么切成10段 那么然后你做一个假设 这个世界上的这些声音

其实在细的力度上 它其实是不断的在重复的 比如说你的中文也就是那么多音组成的 所以我能挑出一些代表性的常见的这一些 然后把一个100毫秒的语音的片段 找到它最近似的一个这样子的模板来表示

打个简单的比方说 我们这里选取了45个这样子的片段 作为我的模板 然后来了一段1秒钟的语音信号之后 我就把它切成10个小片段 每一个片段找出这个45个模板里面 跟它最相近的那一个 用那一个模板来表示

那么这一秒钟的语音信号 我就会表示成一个长度为10的一个序列 每个序列里面只是一个编号就行了 就是说第一个100毫秒是用的第5个 那么语言模型就能像处理文本的一样 去处理语音的信号

不管是它作为输入还是输出 因为它都是一个个的token 当然事情也不会那么的简单 因为语音的信号不是那么容易被表示的 比如说我们来看一组数字 假设一个小时的语音信号

我用128kbps的MP3来存储的话 那么大概就是60兆的样子 128已经算是中等的水平了 因为你要听歌的话 可能要192甚至320 或者甚至是无损的压缩 所以128K已经是一个质量一般般的MP3了

但如果你用token来表示的话 比如说你选择了是64000个token 这个数字已经接近实际中 我们使用的一个词典的大小了 然后一秒钟的音频 我们用24个token来表示

这个也是一个大家常见的表示手法 那么你用这个方式来编码 这一段语音的时候 你会发现一秒钟那就是24个token 那么每个token 因为你只要记它是第几个token 你不用管token里面是什么东西

所以你就是log2(64K) 那么一秒钟的audio 你就会只用384个bit就能表示 那么一个小时的audio 这个时候就压到只有0.16兆 那等于是在之前的128KB的MP3上

又做了一个375倍的一个压缩 那你想一想这么压出来的质量 肯定是糊的一塌糊涂对不对 怎么样做好一个tokenizer 是一个非常关键的一个技术 那么这个地方问大家一个问题 就是在那么严重的压缩的情况下

肯定是丢掉了绝大部分的东西的情况下 那么你是要优先保留住 这段声音里面的声学的信号 比如说我说话这个音调 使得你要去做生成的时候 能把我这个音调还原出来 还是尽量保持它的语意的信号

就是我说话里面到底在说什么东西 大家可以想三秒钟 1 2 3 我们的发现是应该优先保持语意的信号 就声学上的信号 其实有一点点就行了 比如说我说话的风格 其实你保留了一些些就行了

然后在后面再通过别的手段 能够还原出来 但语意的信号其实是千变万化的 比如说我们讲话同一个声音 可能在不同场景里面 说的东西会不一样 所以尽量的保持语意的信号 就是说你这个语意的token里面

包含了大量的语意的信息 使得模型能够将这个语音 和这个文本的token 他们的语意信息在很早的时候 能够联系起来 所以从来达到一个模型能流利的 在文本和语音之间互换的一个能力

这一期我们不会在语音的token上 讲得特别的深入 有兴趣的小伙伴可以看一下 我们发布的代码 以及说这里面一些的技术细节 比如说这个页面对比了 我们自己训练的tokenizer 对比别人是怎么样子

所以这里最重点是说 你需要把语音信号做很好的表达和压缩 你才能够保证后面的任务 你生成的或者处理的语音信号 是让你满意的 我们有了将声音表示成token 进入模型之后 接下来要关注的是怎么样

模型能够很好的理解和生成这些声音 首先想一下我们要干什么 如果是声音转文字 或者文字转声音 本质上是在做模态之间的一个转换 所以就是语言模型能够将一个东西的 语音的表示和文字的表示 它能够做一个映射

因为我们已经用的是文本的大语言模型了 它的文本能力已经很强了 这个时候我们可以考虑的是 将语音的语意尽量的映射回文本 使得能够利用上文本语言模型 在文本这个语音空间大量的一个能力 你可能会问说

如果我做实时的语音助手 听上去好像是我说一句话 模型回一句话 是不是直接在语音的空间做呢 实际上在现在的技术来讲 我们其实还是会回到这个文本的语音空间 为什么是因为我说我做一个语音助手

那么我的人设是什么 什么东西该做 什么东西不该做 其实是用文字来控制的 另外在实时的互动的时候 很有可能你也是在文本空间 比如说我现在问今天天气怎么样 那么模型可能会在文本的空间去搜一下

然后把结果返回来之后 再映射回你的语音的一个信号 所以核心就是模型需要打通文本和语音之间 而不是在语音上自己圈一套新的东西出来 简单来说对于我 模型能理解它的文字表示哪一个token

和它语音表示哪一个token 知道只是一个概念 在不同的表达里面的两种表示 那么有了这个目标之后 我们就可以去说要什么样的数据 以及数据怎么样表达 首先要什么样的数据 我觉得数据反正是越多越好

这里有意思的一点是大家猜一猜 我们也有没有用这种B站或者是YouTube的数据 答案是我们并没有用 不是因为它这个数据不好 这数据应该挺好的 但是那个网站说了你不允许你去爬

所以为了尽量的避免可能带来的版权的问题 我们的做法是要么选择买 当然价格不能太贵 要么就是在那些允许抓取的网页里面找一找 有没有这种音频文件 所以这样带来一个问题说 你抓取的数据自然可能非常的差

你可能要删掉90%的数据才能够留下那么一点点 所以为了凑齐那么1000万小时的训练数据 你可能要抓取一个亿的数据才能够满足你的需求 那么有了数据之后怎么样进模型训练呢 这里给一个简单的例子 比如说你听这一段语音的对话

然后在模型训练的时候 我们会表达成这样子一个东西 在系统层面告诉你说 声学上这个声音声学上的特征 语义上在聊什么东西 这里面有哪些人 这些人说话的一个特点 这个是系统层面的一个表达

就是对这个场景的一个描述 接下来你聊的这个文字是作为一个用户的输入 然后模型把它的音频作为一个输出 那么在这个任务里面 我们就希望模型能够根据我给你的整个场景的描述 和要生成哪些文字

你能够输出到真实的符合场景的一个语音的输出 那现在你可能会问说 这些标是怎么样打出来的 如果你是一名学生做一个研究的话 我的推荐可能就是把你的语音给OpenAI的GPT 或者Google的Gemini

让他们给你打标就行了 但我们做不了这个事情有两个原因 第一个原因是说 人家明令禁止你去调他们模型的输出 再去训练额外的模型 第二个还是成本太贵了 其实我要处理的数据根本就不值一千万

可能是上亿的数据丢进去 那么我这点API的代价我是承受不来的 我们的做法是这样的 就同样的模型架构训练一个额外的语音理解模型 这样大家应该能想象出来 这个语音模型它的数据进去什么样子

我们在做语音生成的时候告诉你是说这个场景是什么 用户告诉你我要说哪些话 然后你输出你的语音 那么现在是反过来 我告诉你说接下来用户给你一段语音 请你分析它的场景 它里面有哪些人 这些人是什么样子的

他们在说什么东西 以及说人当时的情绪状态之类的东西 然后用户给了你的语音之后 你就输出所有东西 等价是说你的生成模型反过来 你把生成模型出来的东西做成用户的输入

然后生成模型整个system prompt 就是对场景的描述 以及用户给你那一个说话的内容 这次做成你的system的输出 就有点像打个比方 我要教一个徒弟 我想让他有拳脚功夫 但我一次要教不来

我先教两个徒弟 第一个徒弟会打拳 第二个徒弟会踢腿 然后让他们两个天天打 打着打着他们两个共同进步 使得最后的最后 我希望你们两个最后都能够学会拳脚功 所以觉不觉得我们之前的故事就圆回来了

接下来我们看一下这个训练出来的模型 实际使用是什么样的体验 这个模型的代码发布在 boson-ai-hicks-audio的repo下面 下面有些链接 比如说不安装的话 可以去这个playground玩一玩 或者有个huggingface的playground huggingface这个虽然是要跑在GPU上 但是每个人好像每天有三分钟的免费的 你可以点一下

他可以调huggingface自己的GPU给你跑一下 the sun rises in the east and sets in the west 当然我们这个频道肯定是要自己动手来用的

所以我们就直接跳转到下面的安装 如果你有GPU版的PyTorch就直接安装就行了 直接用下面的安装 如果你没有的话呢 可以推荐用一下NVIDIA提供的这个Docker 你本地只要装了NVIDIA驱动

装了Docker就能跑 就省去了装CUDA那一套和PyTorch那一套的麻烦 我们用的机器还是三年前装过的那台3090 首先先Git clone这个repo 我们直接运行PyTorch这个Docker

注意这里我把自己的home目录map到Docker里面这个home下面 经过漫长的等待下载解压之后 我们现在可以进去了 然后进入到我们刚刚clone好的repo下面直接安装 又是个漫长的等待

因为大家写包就是各种依赖一直乱写 所以导致他们之间的错综关系的复杂 安装完之后 我们回到readme这个页面 复制一段代码来运行 这里有一些样例 这个样例的意思是用Belinda这个人的声音

然后温度是0.3 如果你想要稳定一点的输出 就用温度低一点 如果你想要各种表现力很丰富的 你可以温度高一点 然后这是你要生成的文本 跟我们之前在Playground看的其实是一个东西

然后它生成的东西会在这个地方 复制三天运行 又是一个漫长的等待 因为要下载模型 下载模型之后 因为我们有GPU 所以它默认会在GPU上运行 可以看一下GPU的使用率 然后就可以听一下生成的声音是什么样子了 The sun rises in the east and sets in the west

This simple fact has been observed by humans for thousands of years 我们仔细来看一下 它其实干的事情是在一个example

voice prompt下面 把Berlinda这个人他的文字和语音找出来 他的文字作为上一轮用户的输入 他的语音作为上一轮系统的输出 然后你再给一个文字的时候 他就能输出这个人的声音一致的一个语音

我们之前展示的所有的语音片段都是这样生成的 在主页还有一个更离谱的是 把一个人的声音从一个语言转成另外一个语言 Any good places that I should go?

杰文啊,我下个星期要去首尔 哦,首尔啊? 要去多久啊? 哦,你要去首尔 那我们要呆多久啊? 到这里你是不是大概能猜出来 为什么这个模型它的声音的克隆能力有那么强

即使这些声音基本上都是在B站或者YouTube 这种视频数据上找出来的 模型可能没有大规模见过 因为它没有用过B站和YouTube视频 我们抓取那些纯音频的数据

可能在统计分布上跟这些数据差别还是挺大的 其实有两点原因 第一点当然是说你见过那么多数据 所以什么样的声音你可能多多少少都见过 第二点是说你看这个数据构造的方法 就是我们在做声音克隆的时候

我们是把整个提供克隆这个声音 做成上一轮的用户输入和系统的输出 在训练数据中间 因为你这个训练数据是有一段的连续性 你是很多轮在里面 那么给定之前轮数的对话 那么接下来的对话应该在语意上

整个场景上是有一定连续性的 所以模型能够在你提供的用来克隆这个声音里面 去抓取它的整个场景信息 人说话了一个特点 但还一定的语意信息 然后根据这个信息 在你新提供的文字上面 把它做一定的匹配一定的延续

所以这也提示的是说 你要生成某一个场景的文字的时候 你最好找到类似场景的那个人说话的一些语音的信息 比如说他是要吵架 他是在放松 他在大笑 这个是更合适一些 对人来说也是这样 对吧

你提供一个人一本正经说话的声音 然后你要模仿这个人的声音去做talk show 那肯定更难一些 但如果你找不到那么完全匹配怎么办 那其实还有一个补救方法是说 你可以修改整个系统的信息

因为在系统里面提供你需要克隆出来的声音的场景是什么样子 然后希望模型能够从你提供的声音 和你提供的系统的指示里面去合起来 合成你需要的一个东西 这也是这种多模态的语音文本大语言模型

做Proper Engineer应该怎么做吧 好的 这就是这一期的全部内容了 这也算一个新的方向 我们分享一下在创业之中遇到的有意思的问题 做过的有意思的工作 学到有意思的东西 希望给大家有所帮助 如果你喜欢这样的内容的也欢迎一键三连 最后欢迎大家去试一试我们开源的模型 希望给大家带来快乐 谢谢大家

Loading...

Loading video analysis...