OpenAI Whisper論文筆記

OpenAI Whisper論文筆記

OpenAI 收集了 68 萬小時的有標簽的語音數據,通過多任務、多語言的方式訓練了一個 seq2seq (語音到文本)的 Transformer 模型,自動語音識別(ASR)能力達到商用水準。本文為李沐老師論文精讀的學習筆記。本文的模型權重,推理代碼及 API 均以開源,相關博客也介紹了一些有趣的例子。

Paper:https://cdn.openai.com/papers/whisper.pdf

Code:https://github.com/openai/whisper

Blog:https://openai.com/blog/whisper

在互聯網上,可獲取的帶標注的語音數據有很多,如電影及其字幕,歌曲及其歌詞等。語音數據似乎很容易通過爬蟲收集。但是,目前并沒有(公開的)大規模語音數據集。這是因為這些帶標注的語音數據的版權問題很難處理。即使某些公司通過收集這些數據訓練了大語音模型,也不會聲明自己的數據是爬去自存在版權問題的作品,更不會將數據公開。在 Whisper 文章中,同樣沒有詳細說明數據來源,只是介紹了數據清洗和篩選的方法。

本文標題為 Robust Speech Recognition via Large-Scale Weak Supervision ,其中 Large-Scale 是 OpenAI 的 “傳統藝能”,也是最近學術界的一個火熱方向。即“大力出奇跡”,大模型、大數據的訓練。Weak Supervision 是指本文所用數據雖然是有標注的,但并不是為了訓練模型專門進行的人工標注,所以是質量較低的標注,故稱為 “弱監督”。

摘要

在摘要部分,作者指明,本文通過擴大語音識別弱監督數據的規模,達到 68 萬小時,并在大規模數據上進行多語言、多任務的訓練。得到了一個泛化性能很好的模型。該模型在常見語音識別數據集上,不需要微調,直接以 zero-shot 的方式進行測試,結果與在這些數據集上訓練過的語音識別模型性能相當。

導言

最近的語音識別方面的進展是使用無標簽的數據進行自監督預訓練。如 Wav2Vec,收集了大量無標簽的語音數據,通過對比學習的方式預訓練語音編碼器。在編碼器預訓練完成之后,再在標準的語音識別數據集上微調,得到的結果優于只在語音識別訓練集訓練的模型。自監督預訓練使用到的無標簽語音數據規模最多已經達到 100 萬小時。

考慮在 NLP 領域常見的兩類預訓練方式:BERT,Transformer 編碼器類 和 GPT,Transformer 解碼器類。BERT 中,預測掩碼掉的單詞和預測下一個句子是為了訓練編碼器理解自然語言而構造的預訓練任務,它們不是現實中真正要用的 NLP 任務。因此,BERT 類預訓練方法需要在對應下游任務上進行微調。GPT 類的預訓練任務標準的語言模型,預測句子的下一個單詞。這種方式可以通過構造 prompt,實現 zero-shot 測試,無需微調。然而,在語音識別領域,這種方式預測的是下一幀音頻,而非語音識別結果,故而也必須微調一個解碼器。總之,在語音識別領域,如果沒有文本標簽,很難實現無需微調的預訓練。(Wav2Vec-U 在無監督語音識別訓練方面取得了一些相關進展,不需要微調。)

在語音識別領域,自監督預訓練的方式可以訓練一個不錯的編碼器,但是預訓練階段沒有標簽,無法訓練解碼器。因此在實際用于語音識別之前,還需要在有標簽數據上進行微調,比較麻煩,并且容易造成過擬合。一個理想的語音識別系統,應當不需要根據不同的場景進行微調,即應該實現開箱即用。

既然需要有標簽數據,那么在語音識別人工標注數據集上訓練,不就能訓練出無需微調的語音識別系統了嗎?遺憾的是,目前人工標注的語音識別數據集規模都比較小,七個數據集加起來也只有 5000 小時左右。一個自然的思路是,在數據的質量和數量之間進行權衡。既然高質量的人工標注成本較高,得到的數據集規模較小,那么是否可以放寬對標注質量的要求,使用電影-字幕,歌曲-歌詞等自然帶標注的語音識別數據,從而擴大數據規模呢?本文的思路就是這樣。

本文收集了 68 萬小時的語音識別數據,除了數據的規模大幅上升之外,數據的多樣性也更加豐富。在這 68 萬小時的語音數據中,有 11.7 萬小時涵蓋了除英語外的其他 96 中語言,有 12.5 萬小時是其他語言到英語的翻譯數據。

方法

數據處理

數據部分是本文最核心的貢獻。由于數據夠多,模型夠強,本文模型直接預測原始文本,而不經過任何標準化(standardization)。從而模型的輸出就是最終識別結果,而無需經過反向的文本歸一化(inverse text normalization)后處理。所謂文本歸一化包括如將所有單詞變小寫,所有簡寫展開,所有標點去掉等操作,而反向文本歸一化就是上述操作的反過程。在 Whisper 中,這些操作統統不用,因為數據足夠多,可以覆蓋所有的情況。

在本文收集的語音數據中,包含了不同環境、不同語言、不同說話人等多樣的數據,這有助于訓練出文件的語音識別系統。然而,文本標簽的多樣性對模型的學習是一種阻礙。為了解決這個問題,本文使用了幾種自動過濾方法,來提高文本標簽的質量。

  • 首先,收集自互聯網的語音識別數據,很有可能文本標簽就是來自現有的語音識別系統的識別結果。之前有研究工作表明,在訓練數據中混有機器生成的標簽數據會損害模型的性能。為此,本文根據機器識別結果的一些特點,過濾掉了這些數據。
  • 另外,本文對數據中語音所屬語言和文本所屬語言進行檢測。如果文本是非英語的其他語言,則要求語音也必須是同種語言;如果文本是英語,則語音可以是任何語言(因為本文方法中有一個其他語言到英語的翻譯任務)。
  • 本文用一個語音識別模型在收集的數據上進行測試,發現在一些錯誤率極高的數據中,存在音頻信息不完整、字幕聲音不匹配等低質量數據,這些數據同樣會被過濾掉。

另外,可能在收集的數據中含有標準語音識別數據集中的內容,為了避免對測試結果產生影響,這部分數據同樣需要去掉。

最后,將音頻切分為 30s 的片段,配上對應文本,得到訓練數據。

模型

Whisper 使用的模型改動不大,就是 Transformer 第一次提出時的 encoder-decoder 架構。

Whisper 的輸出側是聲音信號,聲音信號的預處理是將音頻文件重采樣到 16000 Hz,并計算出 80 通道的梅爾頻譜,計算時窗口大小為 25ms,步長為 10ms。然后將數值歸一化到 -1 到 1 之間,作為輸入數據。可以認為是對于每一個時間點,提取了一個 80 維的特征。之前數據處理部分提到每個音頻悲切氛圍 30s 的片段,這里步長為 10,所以每 30 秒有 3000 個時間點。綜上,對于一個 30 秒的音頻數據,我們提取到形狀為 3000x80 的特征。對應到 NLP 中,可以理解為句子長度為 3000,每個詞的詞嵌入維度為 80。

3000x80 的輸入數據首先通過兩個 1D 卷積層,得到 1500x80 的特征。后面的處理就是標準的 Transformer encoder-decoder結構了。將這個特征送入到 Transformer encoder 中,提取處的特征作為交叉注意力輸入送給 decoder。decoder 每次預測下一個 token,其輸入是對應多任務學習的一些預設 token 和 prompt。

在這里插入圖片描述

多任務

語音識別系統除了識別出語音中的語言文本(轉錄)之外,還需要做一些其他的任務。比如是否有人在說話(voice activity detection, VAD)、誰在說話(speaker diarization),和反向文本歸一化等。通常,在語音識別系統中,這些任務分別由不同的模型來處理,但在本文中,這通通由 Whisper 一個模型完成。多個語音任務由同一個模型完成,有利有弊。好處是 all-in-one 的模型聽起來比較 fancy,比較符合我們對于語音識別系統的期待。壞處是多個任務中如果某幾個性能相對較差,整個模型難以調試。而且,如果需求只是做某一個比較簡單的任務(如 VAD),一般來說一個簡單的模型就可以勝任,但是 Whisper 需要跑起整個大模型。

Whisper 模型共處理四個任務,如圖左上所示。一是給定英文語音,轉錄成英文文本;二是給定其他語言語音,轉錄并翻譯成英文文本;三是給定其他語言語音,轉錄成該語言文本;四是給定只有背景音樂的音頻,識別出無人說話。

所有這些任務都由解碼器預測的 token 序列表示,從而使得一個模型能夠處理多個任務。這幾個任務及模型輸出 token 的關系可以從圖中下方的圖示中的 token 序列看出:在 START OF TRANSCRIPT token 之后,如果當前無人說話,則識別為 NO SPEECH 。如果有人說話,則識別出當前語音所屬的語言 LANGUAGE TAG 。然后有兩種可能的任務 TRANSCRIBE 還是翻譯任務 TRANSLATE ,這兩種任務又分為兩種形式:帶時間戳的和不帶時間戳的,分別穿插或不穿插時間戳 token ,預測出文本 token。最后到達 EOT token,整個流程結束。

實驗(選)

注意 Whisper 是沒有在人工標注的語音識別數據集上訓練的,即 zero-shot 的設定。而對比的方法都是在這些數據集上訓練過的,因此,要達到與它們持平的性能也是不容易的。

語音識別常用的評估指標是詞錯誤率(Word Error Rate, WER)。即預測結果和目標結果的編輯距離除以句長。

由于不同的數據集有不同的標注格式,如大小寫、括號、數字間的逗號等。為了保證公平的對比,在測試 Whisper 性能時會進行手動的 text normalizer,來對齊測試數據集。當然,這在實際使用中是不需要的。

英文語音識別

下圖展示了不同語音識別模型在 LibriSpeech dev-clean 上的性能(橫軸)和在多個數據集上的平均性能(縱軸)。LibriSpeech 是一個比較干凈、比較簡單的數據集,因此相對于其他數據集,各模型在 LibriSpeech 數據集上的性能更好。可以看到,雖然很多有監督方法在該數據集上訓練之后能夠得到很低的錯誤率(~1.6%),但這些模型在多個數據集上測試的平均錯誤率卻非常高(>20%),很可能是這些有監督方法過擬合了 LibriSpeech 數據集。而 Whisper 雖然在 LibriSpeech 上錯誤率沒有特別低,但是在多數據集測試中錯誤率也不錯。這足以說明 Whisper 優秀的泛化性能。

在這里插入圖片描述

多語言語音識別

下表是各模型在多語言語音識別數據集上的性能。可以看到,在小數據集 MLS 上,Whisper 表現更好;而在更大的 VoxPopuli 上,在訓練集上訓練過的有監督方法性能更好。
在這里插入圖片描述

下圖是不同語言的語音識別錯誤率隨訓練數據量的變化。可以看到,整體上隨著訓練數據的增多, 錯誤率是會下降的。另外,觀察到在相同訓練數據量的情況下, ZHKO,即中文、韓文等語言的錯誤率相對較高。這可能有兩個原因,一是東亞語言與世界主流的英語、法語等差別較大,無法從多語言聯合訓練中受益,二是 Whisper 的 tokenizer 對于這類語言也不太友好。
在這里插入圖片描述

多語言/多任務聯合訓練與僅英語訓練對比

藍線表示全部使用英語數據進行訓練,橙線表示多語言、多任務聯合訓練的結果。可以看到,隨著訓練數據量的增加,多語言、多任務聯合訓練對英語本身的語音識別性能也是有幫助的。

在這里插入圖片描述

總結

Whisper 通過弱監督預訓練的方式,再加上大規模、多樣性、多語言的訓練數據,不需要自監督(self-supervised)和自訓練(self-training),即可取得很好的性能。并且在處理任何語音識別任務時也不需要微調,可以以 zero-shot 的方式工作,大大提高了語音識別系統的穩健性。

筆者認為,Whisper 的意義在于指明了只要有大規模數據,通過一個簡單的 Transformer encoder–decoder 架構就能訓練出可靠的語音識別模型。并且開源了他們的訓練權重。它的缺點也很明顯,目前 Whisper 對推理基本無優化,Large 模型需要約 10 G 顯存,速度也比較慢。不過在未來,肯定會有一系列工作從算法上或者從工程上來優化 Whisper 的推理部署。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532364.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532364.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532364.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql 工具 08s01_Mysql管理必備工具Maatkit詳解之十四(mk-kill)

mk-kill - 顧名思義,殺mysql線程。安裝方法查看這里。在一個OLTP的生產環境,一般不會讓sql執行過長的時間,特別是myisam這樣表鎖的引擎,如果出現長時間執行的sql一般是誤操作,要不就是出現問題了。出現這種情況&#x…

【經典簡讀】知識蒸餾(Knowledge Distillation) 經典之作

【經典簡讀】知識蒸餾(Knowledge Distillation) 經典之作 轉自:【經典簡讀】知識蒸餾(Knowledge Distillation) 經典之作 作者:潘小小 知識蒸餾是一種模型壓縮方法,是一種基于“教師-學生網絡思想”的訓練方法,由于其簡單&#xf…

深度學習三大謎團:集成、知識蒸餾和自蒸餾

深度學習三大謎團:集成、知識蒸餾和自蒸餾 轉自:https://mp.weixin.qq.com/s/DdgjJ-j6jHHleGtq8DlNSA 原文(英):https://www.microsoft.com/en-us/research/blog/three-mysteries-in-deep-learning-ensemble-knowledge…

在墻上找垂直線_墻上如何快速找水平線

在裝修房子的時候,墻面的面積一般都很大,所以在施工的時候要找準水平線很重要,那么一般施工人員是如何在墻上快速找水平線的呢?今天小編就來告訴大家幾種找水平線的方法。一、如何快速找水平線1、用一根透明的軟管,長度…

百度地圖mysql打點_關于百度地圖連接MYSQL的問題,謝謝啦!

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓大家好,剛使用百度地圖API,請教大家一個問題,謝啦!我需要從我的數據庫中取出字段為"city"的所有數據,然后通過bdGEO()函數在地圖上標注這些城市,我是…

PyTorch中的torch.nn.Parameter() 詳解

PyTorch中的torch.nn.Parameter() 詳解 今天來聊一下PyTorch中的torch.nn.Parameter()這個函數,筆者第一次見的時候也是大概能理解函數的用途,但是具體實現原理細節也是云里霧里,在參考了幾篇博文,做過幾個實驗之后算是清晰了&am…

Vision Transformer(ViT)PyTorch代碼全解析(附圖解)

Vision Transformer(ViT)PyTorch代碼全解析 最近CV領域的Vision Transformer將在NLP領域的Transormer結果借鑒過來,屠殺了各大CV榜單。本文將根據最原始的Vision Transformer論文,及其PyTorch實現,將整個ViT的代碼做一…

hdfs的副本數為啥增加了_HDFS詳解之塊大小和副本數

1.HDFSHDFS : 偽分布式(學習)NNDNSNNsbin/start-dfs.sh(開啟hdfs使用的腳本)bin/hdfs dfs -ls (輸入命令加前綴bin/hdfs dfs)2.block(塊)dfs.blocksize : 134217728(字節) / 128M 官網默認一個塊的大小128M*舉例理解塊1個文件 130M,默認一個塊的大小128M…

Linux下的ELF文件、鏈接、加載與庫(含大量圖文解析及例程)

Linux下的ELF文件、鏈接、加載與庫 鏈接是將將各種代碼和數據片段收集并組合為一個單一文件的過程,這個文件可以被加載到內存并執行。鏈接可以執行與編譯時,也就是在源代碼被翻譯成機器代碼時;也可以執行于加載時,也就是被加載器加…

mysql gender_Mysql第一彈

1、創建數據庫pythoncreate database python charsetutf8;2、設計班級表結構為id、name、isdelete,編寫創建表的語句create table classes(id int unsigned auto_increment primary key not null,name varchar(10),isdelete bit default 0);向班級表中插入數據pytho…

python virtualenv nginx_Ubuntu下搭建Nginx+supervisor+pypy+virtualenv

系統:Ubuntu 14.04 LTS搭建python的運行環境:NginxSupervisorPypyVirtualenv軟件說明:Nginx:通過upstream進行負載均衡Supervisor:管理python進程Pypy:用Python實現的Python解釋器PyPy is a fast, complian…

如何設置mysql表中文亂碼_php mysql表中文亂碼問題如何解決

為避免mysql中出現中文亂碼,建議在創建數據庫時指定編碼格式:復制代碼 代碼示例:create database zzjz CHARACTER SET gbk COLLATE gbk_chinese_ci;create table zz_employees (employeeid int unsigned not null auto_increment primary key,name varch…

java 按鈕 監聽_Button的四種監聽方式

Button按鈕設置點擊的四種監聽方式注:加粗放大的都是改變的代碼1.使用匿名內部類的形式進行設置使用匿名內部類的形式,直接將需要設置的onClickListener接口對象初始化,內部的onClick方法會在按鈕被點擊的時候執行第一個活動的java代碼&#…

java int轉bitmap_Java Base64位編碼與String字符串的相互轉換,Base64與Bitmap的相互轉換實例代碼...

首先是網上大神給的類package com.duanlian.daimengmusic.utils;public final class Base64Util {private static final int BASELENGTH 128;private static final int LOOKUPLENGTH 64;private static final int TWENTYFOURBITGROUP 24;private static final int EIGHTBIT …

linux查看java虛擬機內存_深入理解java虛擬機(linux與jvm內存關系)

本文轉載自美團技術團隊發表的同名文章https://tech.meituan.com/linux-jvm-memory.html一, linux與進程內存模型要理解jvm最重要的一點是要知道jvm只是linux的一個進程,把jvm的視野放大,就能很好的理解JVM細分的一些概念下圖給出了硬件系統進程三個層面內存之間的關系.從硬件上…

java 循環stringbuffer_java常用類-----StringBuilder和StringBuffer的用法

一、可變字符常用方法package cn.zxg.PackgeUse;/*** 測試StringBuilder,StringBuffer可變字符序列常用方法*/public class TestStringBuilder2 {public static void main(String[] args) {StringBuilder sbnew StringBuilder();for(int i0;i<26;i){char temp(char)(ai);sb.…

java function void_Java8中你可能不知道的一些地方之函數式接口實戰

什么時候可以使用 Lambda&#xff1f;通常 Lambda 表達式是用在函數式接口上使用的。從 Java8 開始引入了函數式接口&#xff0c;其說明比較簡單&#xff1a;函數式接口(Functional Interface)就是一個有且僅有一個抽象方法&#xff0c;但是可以有多個非抽象方法的接口。 java8…

java jvm內存地址_JVM--Java內存區域

Java虛擬機在執行Java程序的過程中會把它所管理的內存劃分為若干個不同的數據區域&#xff0c;如圖&#xff1a;1.程序計數器可以看作是當前線程所執行的字節碼的行號指示器&#xff0c;通俗的講就是用來指示執行哪條指令的。為了線程切換后能恢復到正確的執行位置Java多線程是…

java情人節_情人節寫給女朋友Java Swing代碼程序

馬上又要到情人節了&#xff0c;再不解風情的人也得向女友表示表示。作為一個程序員&#xff0c;示愛的時候自然也要用我們自己的方式。這里給大家上傳一段我在今年情人節的時候寫給女朋友的一段簡單的Java Swing代碼&#xff0c;主要定義了一個對話框&#xff0c;讓女友選擇是…

java web filter鏈_filter過濾鏈:Filter鏈是如何構建的?

在一個Web應用程序中可以注冊多個Filter程序&#xff0c;每個Filter程序都可以針對某一個URL進行攔截。如果多個Filter程序都對同一個URL進行攔截&#xff0c;那么這些Filter就會組成一個Filter鏈(也叫過濾器鏈)。Filter鏈用FilterChain對象來表示&#xff0c;FilterChain對象中…