• LPCNet: Realtime Neural Vocoder
    • 簡要介紹
    • 背景和動機
    • 網路分解
      • 數據準備和訓練
      • LPC 計算
      • 特徵
        • 特徵使用
        • 特徵提取
      • DualFC 輸出層
      • 採樣過程
      • 量化和預加重
      • 雜訊注入
      • 矩陣稀疏化
      • Embedding 以及計算簡化
    • 性能評估
      • 計算複雜度
      • 合成語音質量
    • 總結
      • 個人感想
    • 參考文獻

簡要介紹

LPCNet 是一個 數字信號處理(DSP) 和 神經網路(NN)巧妙結合應用於語音合成中 vocoder 的工作,可以在普通的CPU上實時合成高質量語音。傳統上,基於 DSP 的 vocoder 速度很快,但是合成的語音質量不是太好,而基於 NN 的 vocoder 語音質量更高,但通常複雜度太高,無法實時。

返回大綱

背景和動機

首先從語音產生機理的 source-filter 模型說起,這是上世紀70年代的東西,也是 LPC10、CELP、MELP 等 codec 的理論基礎。這個模型把語音產生過程分解為類似信源、信道兩個獨立的模塊。信源部分就是聲帶震動,發清音時沒有震動就用白雜訊建模,發濁音時喉嚨有震動就用脈衝串建模;信道部分就是發不同音時口腔、鼻腔、舌頭、嘴脣這些配合形成的通道,可以用一個全極點的 LPC 濾波器建模。這個模型非常簡單,但是語音質量不太好。

然後是 WaveNet,它是 DeepMind 2016年提出的,不對語音做任何先驗假設,而是用神經網路從數據中學習分佈,它不直接預測語音樣本值,而是通過一個採樣過程來生成語音。它的語音質量非常好比之前所有基於參數的 vocoder 都要好,但是它生成語音太慢,大約需要幾十 GFLOPS,主要原因是為了獲得足夠大的感受野卷積層做得太深太複雜。因此 DeepMind 和 Google Brain 提出 WaveRNN 用 RNN 建模提升效率,並且 RNN 的權重採用稀疏矩陣進一步降低運算量,儘管如此,WaveRNN 還是大約需要 10 GFLOPS, 這相比基於 DSP 的 codec 而言大約高兩個數量級。

最後來到 LPCNet, 作者 Jean-Marc Valin 也是 Opus Codec 的作者,是個編解碼和信號處理的高手,他可能相信信號處理與神經網路結合纔是更好的路,2017年就做了一個結合信號處理和神經網路做語音降噪的工作 RNNoise

他覺得類比 source-filter 模型, 全神經網路的做法既要讓 NN 建模 source 又要建模 filter 很難也很浪費,因為 filter 部分用 DSP 實現其實非常簡潔高效,有經典的 Levinson-Durbin 演算法,但是使用 NN 實現卻可能非常複雜。因此他以 WaveRNN 為基礎顯式加入 LPC filter 模塊來降低神經網路部分的複雜度。一個直覺的想法是 WaveRNN 需要為整個採樣值建模,那麼如果我將這個採樣值分解成線性非線性兩部分,線性部分通過基於 DSP 的線性預測給出,神經網路僅需建模變化相對較小的非線性殘餘部分,這會是個更簡單的任務,更少的神經元便可以勝任。 下面我們將詳細分析 LPCNet 的細節。

返回大綱

網路分解

LPCNet 的主體網路結構如下圖所示,這裡忽略了 pcm 到 μ-law 的編碼轉換。因為特徵提取以幀 (10ms, 160 樣點)為單位進行,而語音生成是以樣點為單位進行,因此 LPCNet 網路可以分解為兩個子網路: Frame rate networkSample rate network,外加一個計算 LPC 的模塊。

網路的核心設計在 Sample rate network 部分,Frame rate network 主要為 Sample rate network 提供一個條件向量的輸入,這個條件向量一幀計算一次,並在該幀時間內保持不變。LPC 計算模塊則從輸入特徵中計算線性預測參數 LPC,LPC 也是一幀計算一次,並在幀內保持不變。返回大綱

數據準備和訓練

網路使用 CE 準則訓練, 在 softmax 位置評估預測 e_t 分佈和真實分佈的交叉熵。測試時輸入僅包含 features,訓練時輸入還包含  p_t,  s_{t-1},  e_{t-1} ,輸出參考為 e_t 。這部分數據準備使用了原始語音 s_t , 利用 features 計算出來的 LPC 產生線性預測 p_t , 而 e_t = s_t - p_t 既是輸入(延時)也是輸出參考。

特別注意:儘管訓練時有原始語音 s_t , 這裡 p_t 的計算仍然使用從特徵中恢復的 LPC 而不是直接從 s_t 中估計的 LPC,這樣處理能減少訓練和測試的 mismatch。

訓練和測試還有一個 mismatch: 因為訓練時使用了原始語音,測試時僅有特徵輸入,通過零初始化的歷史語音樣值循環生成激勵樣值和語音樣值,顯然不一致,因此對輸入語音做加噪處理以緩解 mismatch,雜訊怎麼加也比較重要,後文雜訊注入部分介紹。另一個可以嘗試的方法是 Scheduled Sampling

此外為了增加訓練數據的多樣性(能量分佈更多樣),讓原始語音反覆經過一些隨機的二階 IIR 濾波器(零極點均在單位圓內的最小相位系統),這些濾波器的 gain 是隨機的,濾波器的傳輸函數為:

 H(z) = frac { 1 + b_1 z^{-1} + b_2 z^{-2}} {1 + a_1 z^{-1} + a_2 z^{-2}}

其中 a_1,  a_2,  b_1,  b_2 均服從 	ext{U}(0,  0.75) 分佈(這樣零極點可嚴格在單位圓內)。

GRU 為 RNN 的一種變體,其方程如下:

	ext{GRU}_A 的輸入 	extbf x_t = [s_{t-1}; p_t; e_{t-1}; f]	ext{GRU}_B 的輸入 	extbf x_t = [h_t^A; f] ,注意到兩個 GRU 都用到 f 的條件。

訓練時將 pitch 處理成 64 維 embedding,然後接在原來的特徵後,構成 102 維特徵(原特徵為 38維,實際上 18 到 36 維的 BFE 互相關係數直接置零了並沒用,暫不確定這是代碼遺留問題還是有意加上這些無意義的維度),因此第一個卷積層使用 128 個 filter, 第二個卷積層使用 102 個 filter, 以便和輸入的 102 維一致; 作為網路輸入的 μ-law 樣值都首先處理成 128 維 embedding,輸出分佈直接與 μ-law 對應,8 bit 對應一個 256 維的分佈,所以輸出層大小為 256。 條件向量 f 也是 128 維;embedding 維度的選擇不是很清楚,可能是作者試出來的。

返回大綱

LPC 計算

語音採樣率很高(比如 16 KHz), 相鄰樣本點有很強的相關性,通常假設語音採樣值是一個自回歸過程,也即當前時刻樣本值可以近似由若干相鄰歷史時刻的樣本值線性表示,誤差可建模為高斯白雜訊。可以參見前文的 source-filter 模型,二者正好是一個相反的過程,也即把殘差信號當作激勵源通過由 LPC 係數構成的全極點濾波器便可以恢復原始語音.

x[n] = sum_{k=1}^p a_k x[n-k] + v[n]

v[n] sim mathcal{N}(0, sigma^2)

由歷史數據和線性預測係數 LPC ( a_k ),就可以迭代預測了,那麼關鍵就在於如何計算 a_k 。這都是上世紀七八十年代的成熟理論,也可以不用細究。主要原理如下:

線性預測值為  widehat{x}[n] = sum_{k=1}^p a_k x[n-k] ,根據相關性原理,最優線性預測參數時,殘差 d[n] = x[n] - widehat{x}[n] 應當和 x[n-k] (k = 1,2,...,p) 不相關。

mathbb{E} { d[n]  x[n-k]} = 0  , (k = 1,2,...,p)

因此,很容易得到一個線性方程,也叫normal equations.

矩陣求逆就可以得到最優解,不過矩陣求逆複雜為O( p^3 ),注意到到 mathbf{R}_{xx} 是Toeplitz矩陣,因此有快速演算法也就是著名的Levinson-Durbin演算法將複雜度降為O( p^2 ).

可以看到,求解 LPC 主要需要求解自相關函數,若給定一幀語音數據,可以直接近似估計自相關函數。但是對於聲碼器,輸入是一幀的特徵,因此需要從特徵中計算自相關函數。實際上從特徵中計算 LPC 並不太準確,因為特徵本身相比原始語音已經丟失了一些信息。但是從最終結果看並沒有什麼影響,這也正是神經網路的強大之處。

返回大綱

特徵

特徵使用

論文中稱使用 20 維特徵,包括:

  • 18 BFCC, Bark-Frequency Cepstral Coefficients
  • 2 pitch parameter (pitch, correlation)

BFCC 和 語音識別常用的 MFCC 類似,都是利用人類聽覺特性,儘管 Bark scale 是根據人耳對響度感知實驗確定的刻度,而 Mel scale 是根據人耳對音高感知實驗確定的刻度,二者最終分的頻帶很類似,都是低頻解析度高,高頻解析度低,和線性頻率對應關係都近似對數關係,因此我覺得這個工作中 BFCC 替換成 MFCC 特徵應該也可以。該工作並沒有嚴格使用 Bark Frequency, 而是使用了和 Opus 編碼器一樣的頻帶轉換,作者稱 Bark Frequency 低頻帶寬太窄,會導致樣本太少參數估計不準。下圖中共用了 22 個頻帶,最高頻到 20KHz, 對於 16KHz 採樣的語音,最高頻只需到 8KHz 即可,因此去掉高頻段的 4 個頻帶,剩下 18 個頻帶。

代碼中準備了 55 維特徵,包括:

  • 18 BFCC
  • 18 Bark-Frequency Energy (BFE) 互相關係數,為 x[n] 和 x[n?T] ( T 為 pitch) 對應BFE的互相關係數,這部分特徵並沒有真正使用,代碼中直接置零,可能是之前代碼遺留的冗餘
  • pitch
  • gain (和 correlation function 有關,for removing doubling pitch)
  • log(e) (e 為 LPC residual)
  • 16 LPC ( LPC 從 BFCC 計算獲得,首先 BFCC 通過 IDCT 然後 EXP 恢復成 BFE, 然後通過線性插值得到線性頻譜(功率譜),然後 IFFT 得到自相關函數,最後通過 Levinson Durbin 演算法計算 LPC )

網路測試時使用了前 38 維特徵,因為最後的 17 維和 LPC 有關的特徵可以通過 BFCC 計算得到;網路訓練時則使用了全部 55 維特徵,以便更快訓練。不過無論訓練還是測試,代碼中並沒有真正使用 18 個 BFE 互相關係數,因此真正使用的特徵正如論文所述 20 維。

特徵提取

單獨考慮聲碼器,特徵從原始語音中提取。

  • BFCC 通過如下過程獲得(和 MFCC 提取非常一致,二者僅在頻帶劃分有差異)
    • 波形數據通過 FFT 到頻譜
    • 頻譜按 Bark 頻率分成 18 個頻帶,計算每個頻帶內的能量(通過三角窗加權,也可以理解為三角濾波獲取頻譜包絡)
    • Log 壓縮動態範圍得到倒譜
    • DCT 去相關得到最終的 BFCC
  • pitch 參數通過一個基於互相關函數的 open-loop search 獲得

整體考慮一個合成系統時,特徵從前端模型中預測獲得,前端模型以文本為輸入,輸出預測的語音特徵。這裡又有個 mismatch, 前文提到單純聲碼器部分的訓練和測試的 mismatch 採用了雜訊注入以緩解。 這裡的 mismatch 可能用前端模型預測的語音特徵(而不是真實語音提取的特徵)來訓練聲碼器會更好,細節我不清楚,論文中也未涉及完整語音合成系統的前端模型和聲碼器對接的問題。

返回大綱

DualFC 輸出層

作者稱使用 DualFC 層相比 FC 層在同等參數下最終生成語音效果會略好些,他的直覺是確定一個數值在 μ-law 的某個量化區間裏需要兩次比較,而每個 FC 可實現一次比較。可視化權重也發現這個直覺 make sense。

DualFC 的輸出通過 softmax 激活函數產生概率分佈,然後從這個分佈中採樣激勵信號(或線性預測殘差), 激勵信號加上線性預測信號就得到最終的輸出信號。返回大綱

採樣過程

直接採樣會引入太多雜訊,引入一個常數 c 來控制採樣過程,總體思路是給濁音的採樣更多確定性,噹噹前幀為濁音有 pitch 時,給概率大的候選更大的權重,相當於冷卻和降低隨機性。 0 < g_p < 1 為 pitch correlation, T = 0.002 砍掉概率太小的候選。

返回大綱

量化和預加重

量化編碼方面本文和WaveNet都使用了 8-bit μ-law,而 WaveRNN 使用 16-bit pcm。pcm 是線性線性編碼均勻量化,優點是解碼簡單,缺點是壓縮到 8-bit 時量化雜訊很大,因此通常都用 16-bit。常見的 wav 格式文件就是採用 pcm16 量化編碼。 8-bit μ-law 考慮了語音樣值的統計分佈,發現語音樣值其實主要集中在 0 附近幅值較小的地方,且幅值越大概率越小,這很好理解,比如常見的高斯分佈和拉普拉斯分佈都有這樣的特點。因此,一方面考慮語音的統計分佈後,給幅值小的地方更多比特更小的量化誤差,幅值大的地方更少比特更大的量化誤差可以整體最優;另一方面,人類對於雜訊的感知可能主要是對信噪比敏感,因此讓量化雜訊正比於信號幅度也很合理,這正好可以推導出對數特性的壓縮曲線。8-bit μ-law 只有 256 個可能值,因此作為神經網路的輸出層更為簡單。

非均勻量化本質上是先通過一個非線性函數映射到另一空間,然後在映射的空間中做均勻量化,下圖是兩種常見的非均勻量化 μ-law 和 A-law 的映射函數。

下圖是 μ-law 量化編碼時具體採用的折線近似,這裡僅考慮大於零的情況,另一半以原點中心對稱可得。( 註:下圖中分成 8 段用 3 bit, 然後每段再細分為 16 段用 4 bit, 符號 1 bit, 共 8 bit)

本文還採用了預加重濾波來提升高頻能量,傳輸函數為 E(z) = 1 - alpha z^{-1} , 相當於 x[n] = x[n] - alpha x[n-1] ,是個高通濾波器。採用預加重的理由是語音信號能量通常集中在低頻段,那麼分頻帶考慮信噪比時就會出現高頻段信噪比太小,量化雜訊在高頻處過於顯著,因此事先提升一下高頻能量,最後合成完語音後再用 E^{-1}(z) 壓一壓高頻能量, 這可以顯著降低合成語音的感知雜訊。

返回大綱

雜訊注入

為了緩解聲碼器訓練和測試的 mismatch,訓練時往輸入語音裏注入雜訊,作者發現如果僅僅往輸入語音里加噪,而使用乾淨的參考激勵訓練,生成語音會不太自然;輸入語音加噪後,線性預測和激勵都基於加噪的語音重新計算,使得網路輸入和參考激勵都同步引入雜訊效果更好。作者也發現在 μ-law 域加噪更好。如下圖所示。

更新:作者更新了代碼,目前的雜訊注入方式有些改變,直接對 e_t 的 μ-law 進行加噪。如下圖所示:

返回大綱

矩陣稀疏化

這部分主要是 WaveRNN 的工作, 其作者發現 RNN 裏同等參數量時權重用大而稀疏的矩陣會比小而稠密的矩陣好,因此初期正常訓練一定 iter 後,就開始每隔一定 iter 讓 weight 乘以一個二值 mask 強制稀疏化,並且訓練越往後非零權重數量越少。權重稀疏化原則上根據稀疏度設置硬閾值砍掉小權重,不過考慮到計算和存儲效率,稀疏化以 16x1 或 4x4 的分塊為單位(要麼去掉整個分塊要麼保留整個分塊)。本文作者做的改動是一直保留對角位置的權重。稀疏化的主要目的是降低測試時計算複雜度(增加了訓練複雜度),因此本工作中僅對 	ext{GRU}_A 的 3 個和循環相關的矩陣 	extbf W^{(u)}, 	extbf W^{(r)}, 	extbf W^{(h)} 做稀疏化(因為 	ext{GRU}_B 比較小可不做)。

返回大綱

Embedding 以及計算簡化

這部分主要是為了加速合成語音,是在測試階段,權重都訓練好固定了。那麼計算最大開銷就在 sample rate 的 GRU 環節。作者的思路是對非循環部分都預先計算好。顯然 μ-law 的輸入 s_{t-1}, p_t, e_{t-1} 都只有 256 種可能,因此作者先將 μ-law Embedding 轉成 128 維,然後把 256 個可能 embeding 和 GRU 中相關 非循環 矩陣相乘結果存儲,這樣合成時就可以通過查找表完成該部分計算。同時條件向量 f 也是一幀僅需計算一次,因此在幀內也可以把 f 和 GRU 裏對應矩陣相乘結果存儲復用。

返回大綱

性能評估

計算複雜度

顯然合成語音時的計算量主要在 Sample Rate Network 裏的兩個 GRU 部分(因為 Frame Rate Network 一幀才計算一次)。假設一個 weight 涉及 2 次運算(乘法和加法各一次),因此 LPCNet Inference 複雜度約為:

C = (3dN_{A}^2 + 3N_B(N_A + N_B) + 2N_B Q) cdot  2F_s

N_A, N_B 分別為  	ext{GRU}_A, 	ext{GRU}_B 神經元數, d 為稀疏矩陣的density (也即非零值)比例,僅 	ext{GRU}_A 採用稀疏矩陣, 	ext{GRU}_B 比較小採用稠密矩陣。非循環部分已經預先計算好了,因此僅考慮循環部分計算量。Q為輸出層大小,Fs為採樣率。

實驗中取 N_A = 384,  N_B = 16,  d = 0.1,  F_s = 16000, Q = 256 , 其餘計算量預估再加 0.5 GFLOPS, 這樣整個聲碼器計算量約為2.8 GFLOPS。FFTNet (聲稱比原始 WaveNet 計算複雜度低)約 16 GFLOPS, WaveRNN 約 10 GFLOPS, SampleRNN 約 50 GFLOPS。

返回大綱

合成語音質量

作者提到 LPCNet 可以應用於 speaker-dependentspeaker-independent 場景,作者挑戰了更難的 speaker-independent 語音合成。這裡 speaker-independent 具體含義我不太清楚。 不過根據本人實驗,單說話人效果非常好;男女混合多說話人訓練的模型傾向於平均模型,合成的語音有些含糊不清。另外一個有趣的實驗現象是用一個女生的語音訓練了單說話人模型,用另外一個女生的數據測試也能合成非常自然的語音,不確定是否是偶然現象。

作者的實驗中訓練語料使用了 4 小時 NTT Multi-Lingual Speech Database for Telephonometry,評價準則採用 MUSHRA-like listening test。

MUSHRA-like Listening Test: 兩男兩女說的 8 句話,分別讓 100 個人聽然後打分,分數越高說明語音質量越好,滿分為 100。黑線為原始 PCM16 的 Reference, 綠線為 μ-law 的 Reference,可見 μ-law 壓縮後語音質量幾乎沒有下降。

紅線和藍線分別是 LPCNet 和 WaveRNN 的合成語音,橫軸是 	ext{GRU}_A 的等價神經元數 (N_A = sqrt d N_A) ,越大模型越複雜。對比測試了三個不同大小的網路,分別對應 	ext{GRU}_A 的神經元數 N_A =192, 384, 640, 對應等價神經元數為 N_A = 61, 122, 203, 同時 WaveRNN 測試了同等複雜度的網路。可見同等複雜度下 LPCNet 比 WaveRNN 合成語音質量更高。

返回大綱

總結

本文展示了通過結合傳統線性預測技術顯著提高神經網路聲碼器合成效率的嘗試。此外,本文的其他貢獻還包括:信號 embedding, 改進的採樣機制,μμ-law 量化前預加重濾波。作者認為這個模型可以應用到 Text-to-Speech、Speech Compression(低比特率編碼)、Time Stretching(變速不變調)、Packet Loss Concealment(丟包補償)等領域。因為本文使用的線性預測模塊還沒有包含長時預測部分( 線性預測 widehat x[n] 除了包含 x[n-i], i = 1,2,...,p 還加入 x[n-T], x[n-2T] 等 ),作者下一步也會探索把長時預測部分結合進來進一步減小網路複雜度。

個人感想

  • 從這篇工作來看,DSP + NN 的門檻非常高,首先必須對 DSP 非常熟纔可能有相關 insight, 其次更重要的是要有非常強的工程能力處理好各種細節將結合的優勢真正凸顯(可能還要加上堅定的信念去優化細節),普通人還是老老實實調調參做端到端吧。
  • 其實 DSP + NN 在語音識別中倒是並不陌生,MFCC 就是 DSP 部分,簡單穩定優雅,似乎也一直很難被端到端神經網路超越。本文給我的啟示是:魯棒語音識別中的 MFCC 模塊從能效比角度考慮是否必須保留? 也即如果某個前端模型相比傳統 MFCC 性能有優勢,是否可以通過把該前端增加的複雜度轉移到後端聲學模型中讓 MFCC 前端繼續保持優勢? 那麼魯棒語音識別前端的優化該何去何從?
  • 有些場景只看性能無需考慮效率,因此複雜的 WaveNet 或複雜的語音識別前端仍然有其價值。

返回大綱

參考文獻

LPCNet Demo

LPCNet paperWaveRNN paperSource Filter Model
推薦閱讀:
相關文章