想像一下,你正在機場候機,突然來了一通重要的商務電話,而你身處的背景有嘈雜的交談聲、飛機起飛的噪音、甚至還有機場廣播。這個時候打電話就很尷尬,生怕對方聽不清自己的聲音。
現在,英偉達推出了一款名為2Hz的產品,讓你接起電話并開始講話時,噪聲突然消失,電話那頭的人聽不到任何干擾聲音。接下來論智將對這一技術詳細介紹,首先通過下面的視頻了解下這款產品的效果吧:
兩年前,我們決定創建一種技術,當人與人溝通交流時,能完全屏蔽背景噪聲,讓溝通的過程更愉悅、智能。從那時開始,這個問題就一直成為我們關注的重點。
在這篇文章中,我們會了解,為什么噪聲抑制這么難、想創建實時的低延遲噪聲抑制系統都需要些什么、以及深度學習是如何幫助我們提高噪聲消除的質量的。
目前的噪聲抑制技術
首先,我們要知道什么是噪聲抑制。在這篇文章中,噪聲抑制表示,當你與他人通話時,消除來自你所處背景中的噪聲,同時也會消除對方背景中的噪聲,如下圖所示:
噪聲抑制是雙向的
傳統的噪聲抑制方法
傳統的噪聲抑制技術通常用于一些設備的邊緣,例如手機、筆記本電腦、會議系統等等。這種方法看起來很直接,因為設備的邊緣是最先捕捉到用戶聲音的位置。一旦捕捉到聲音,設備會將雜音過濾掉,傳遞到對話的另一端。
十年前,手機通話的體驗還非常差。但現在,越來越多的手機會配有多個麥克風,可以幫助抑制環境噪聲。
如下圖所示,現在的手機通常有兩個甚至多個麥克風,最新一代的iPhone有4個。第一個麥克風在手機前面下部,最靠近用戶的嘴巴,可以直接捕捉用戶聲音。手機設計師將第二個麥克風設計得盡量遠離第一個麥克風,通常在手機背部的下方。
pixel 2016,黃色區域是麥克風的位置
這兩個麥克風都能捕捉到背景聲音,不過第一個能捕捉到更多人類聲音,第二個收到的人類聲音更少。之后通過軟件處理,生成一種接近清晰的人聲。
這種方法聽起來很簡單,但事實上失敗的次數也很多。例如,當通話者沒有說話時,麥克風接收到的全是噪音。或者說話者在打電話過程中會不斷晃動手機等等,這種情況就難以處理了。
此外,兩個或兩個以上的麥克風設計會給生產廠商增加難度,音頻/硬件/軟件工程師們必須在工業設計和語音質量上做取舍。
目前,手機已經能在嘈雜的環境中表現得不錯了,雖然現在的噪聲抑制技術還不夠完美,但是的確在用戶體驗上有了極大提升。
當使用分離的麥克風時,尺寸因素又成為了一大問題,如圖所示,第一個和第二個麥克風之間的距離必須符合最小距離要求,只有這樣才能既讓用戶聽得清,也能讓手機捕捉到清晰的人聲。
但是,直板似的手機不是唯一的通訊設備。可穿戴設備(智能手表、附著在胸部的麥克風等)、筆記本電腦、平板電腦和智能語音助手等都和手機的設計有所不同。用戶會從設備的任意角度、距離進行通話。在大多數情況下,很難有通用的噪聲抑制技術。
從多麥克風設計轉移到單一麥克風設計
多麥克風的設計有幾點重要的缺點:
它對尺寸有一定要求,只能用于手機或頭戴設備上;
多麥克風的設計會導致音頻路徑非常復雜,需要更多硬件和代碼的支持。除此之外,第二個麥克風打孔的位置也對工業生成有較高要求;
音頻只能在設備邊緣處理,所以算法可能無法支持過于復雜的計算。
那么是否有一種方法,可以將多個麥克風合成一個,將所有的后期處理都交給軟件?從而硬件設計更簡單,也更高效。
傳統的數字信號處理(DSP)算法嘗試持續尋找噪聲模式,逐幀處理音頻。這些算法在特定案例中表現得很好,但是無法擴展到日常場景中。
基礎噪聲的類型有兩類:靜止和非靜止的,如下圖所示:
白噪聲(靜止)和Chirp噪聲(非靜止)的聲譜圖
我們可以將靜止的噪聲想象成一直重復、但和人類語音不同的聲音。傳統的DSP算法(自適應過濾)在消除這類噪聲時很有效。
而非靜止噪聲的模式非常復雜,和人類聲音的模型很相似,難以區分。它們的信號很短,并且出現的速度很快(類似在鍵盤上打字)。
如果想同時解決以上兩種噪聲,可能就要突破傳統數字信號處理技術了。我們認為,深度學習是解決這一問題的重要方式,所以提出了2Hz。
用深度學習分離背景中的噪聲
2015年,Yong Xu等人曾發表論文,提出用深度學習進行噪聲抑制。Yong提出一種回歸方法,通過學習為每個音頻率生成比例掩碼。生成的比例掩碼完全與人聲分離,并且可以刪除外部噪聲。雖然這種方法還不夠完美,也算一個很好的基礎了。
在接下來的幾年時間里,很多不同方法相繼出現,高級別的方法幾乎相同,它們常常分為三步:
數據收集:將純凈的語音和噪音混合,生成大量合成的嘈雜數據集;
訓練:將數據集輸入到DNN中,得出清晰的語音輸出。
推理:創建掩碼,將人聲與噪聲分離開。
在2Hz中,我們嘗試了多種DNN,最終得出了唯一的DNN架構,可以在多種場景下得出可靠的結果。平均MOS分數上升了1.4,是目前最佳成績。
能否實現實時DNN?
延遲是實時對話中的重要問題。人類可以忍受的上限為200毫秒的延遲,否則的話就會影響通話效果。
影響端到端延遲的因素有三個:網絡、計算和編解碼器。通常網絡延遲是主要因素。編解碼器的延遲根據不同模式可能會有5—80毫秒的延遲,但是目前所用的編解碼器已經非常高效了。而計算的延遲則有多方面因素。
計算延遲讓DNN更具挑戰性。如果你想用DNN處理每一幀,結果很可能會造成嚴重的延遲。計算延遲取決于以下幾點因素:
計算平臺的能力
我們不可能在一臺頭戴設備中運行大型DNN,因為有CPU和電源的限制。所以想做到實時處理非常困難,除非平臺有一臺加速器,可以快速進行矩陣相乘,并且還不那么費電。
DNN架構
DNN的速度取決于有多少個超參數、DNN的層數,以及節點進行的什么操作。如果你想生成高質量結果,那么DNN就不能太小。
音頻采樣率
DNN的表現取決于音頻采樣率,采樣率越高,得到的超參數就越多。
如何測試噪聲抑制算法?
測試聲音是否得到改善也是一個難題,因為人耳很難分辨細微的差別。可是,目前也沒有公開的針對噪聲抑制效果的基準,所以對結果進行比較比較有挑戰性。
大多數論文采用PESQ、MOS和STOI衡量結果。你提供一個原始聲音音頻和經過處理的音頻,算法會生成一個分數。
ETSI Room
另一種更專業的發方法是進行主觀音頻測試,在不同標準體上測試看它們能否符合標準。
EGPP通訊組織創建了ETSI Room,如果你想將算法應用到實際中,就必須在設備中安裝這一裝置。
這一設置能完美地將噪聲分離。它其中有一個智能機器人,內置的揚聲器會模擬聲音,另外在一定距離之外還有麥克風。
這一設備能讓測試者用周圍的揚聲器模擬不同噪聲,從機器人的揚聲器里發出人聲,最終用算法處理捕捉到的音頻。這一切都能自動進行。
輸出噪聲和輸入噪聲
假設現在你正在和團隊參加電話會議,總共有4人。所以潛在的噪聲就有4種,每個人都有可能制造背景噪聲。
傳統來說,噪聲抑制都在邊緣設備上,也就是僅限于麥克風。你從麥克風中得到信號,一直噪聲,然后對信號進行上采樣。
由于單一麥克風的DNN方法只需要一個源流,你可以將它放置在任意地方。假設現在你想過濾掉麥克風的信號(輸出噪聲)和聽到的揚聲器中的信號(輸入噪聲)。我們創建了APP——Krisp,它可以處理兩種噪聲:
以下視頻演示了非靜止噪聲是如何被DNN過濾掉的:
對輸入噪聲抑制來說,問題變得越來越復雜了。你需要處理算法不常見的聲音和人聲變體。例如,你的團隊可能會用到會議設備,或者離設備距離較遠。或者遠程的人是從車里打的電話,帶來更多環境噪聲。另外,可能會有幾個人同事說話的情況,這樣又該怎樣判定哪些是噪聲呢?
有時聽到手機鈴聲響起,他應該算是噪聲還是鈴聲?
轉向云計算
了解了噪聲抑制技術所需要的條件,而算法又是完全基于軟件的,那么它可以遷移到云上嗎?如下圖所示:
在云上進行噪聲抑制有多種優點
答案是肯定的。首先,基于云的噪聲抑制技術能在多種設備上運行,另外,它能進行雙向甚至多向工作。在過去,這是不可能的事,因為傳統方法需要多個麥克風。然而,深度學習技能支持單個麥克風,也能用云進行計算。
現在,最大的問題就是算法的可擴展性了。
GPU vs CPU
如果我們想讓算法足夠服務真實的因特網語音(VoIP)負載,我們就需要了解算法是如何工作的。
目前的大型VoIP設備可以支持10K—100K的流。有很多因素會影響媒體服務器可以支持的音頻流,其中最主要的因素就是服務器平臺。如下圖所示,基于云的媒體服務器和經過優化的裸機服務器相比,裸機服務器明顯勝出:
服務器必須價格實惠,才能讓消費者看到優勢。我們首先用CPU對2Hz做了實驗,單個CPU核可以處理最多10個平行流。
之后,我們在GPU上做了實驗,結果非常驚人。一個英偉達1080ti在沒有優化的情況下可以擴展到1000個流,經過優化最大可以達到3000個流。
用CUDA進行批處理
讓我們來研究下,為什么GPU能比CPU強這么多。
CPU供應商們一直以來將大量的時間和精力用于優化和加速單線程架構,用算法和各種技術盡可能縮短單線程的時間。因為大多數應用都只需要一個線程,所以CPU制造者只需要發展結構即可讓應用發揮最大性能。
而GPU供應商需要對很多平行任務進行優化,大量平行都需要3D圖形處理。
批處理(Batching)就是在GPU中平行處理的意思,你講一批數據輸入進GPU中,經過平行處理后再返回,這是音頻流處理的理想工具:
這里,我們用英偉達的CUDA庫直接在英偉達GPU上運行這一過程。下方的代碼表示CUDA的矩陣相乘過程。
void kernelVectorMul(RealPtr dst, ConstRealPtr src1, ConstRealPtr src2, constsize_t n)
{
constsize_t i = threadIdx.x + blockIdx.x * blockDim.x;
if (i < n)
dst[i] = src1[i] * src2[i];
}
voidUtils::vectorMul(RealPtr dst, ConstRealPtr src1, ConstRealPtr src2, constsize_t n)
{
dim3 gridSize(n / getDeviceMaxThreadsX() + 1, 1, 1);
dim3 blockSize(getDeviceMaxThreadsX(), 1, 1);
kernelVectorMul <<< gridSize, blockSize >>> (dst, src1, src2, n);
}
voidUtils::vectorMul(Vector& dst, constVector& src1, constVector& src2)
{
vectorMul(dst.getData(), src1.getData(), src2.getData(), dst.getSize());
}
voidUtils::matrixMulRowByRow(Matrix& dst, constMatrix& src1, constMatrix& src2)
{
vectorMul(dst.getData(), src1.getData(), src2.getData(), dst.getSize());
}
下面是用CUDA進行快速傅里葉變換的過程。
FFT::StatusType FFT::computeBackwardBatched(ComplexTypePtr src, RealTypePtr dst)
{
StatusType s = cufftExecC2R(backward_handle_, reinterpret_cast
dim3 gridSize((getBatchSize() * getForwardDataSize()) / thr_max_ + 1, 1, 1);
dim3 blockSize(thr_max_, 1, 1);
float val = getForwardDataSize();
kernelDivide <<< gridSize, blockSize >>> (dst, val, getBatchSize() * getForwardDataSize());
return s;
}
FFT::StatusType FFT::computeBackwardBatched(ComplexVector& src, Vector& dst)
{
return computeBackwardBatched(src.getData(), dst.getData());
}
-
英偉達
+關注
關注
22文章
3748瀏覽量
90842 -
深度學習
+關注
關注
73文章
5493瀏覽量
120983
原文標題:英偉達用深度學習消除背景噪聲
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論