如何從代碼角度對比評價HTK和KALDI的設計和可讀性?

假設語言都沒有障礙


從語言角度講,HTK是基於面向過程的方式用C語言開發的,Kaldi是C++基於面向對象開發的。HTK的C代碼的優點是簡單高效,缺點包括一切面向過程的缺點,以及需要使用自己定製的內存管理模塊、數據結構等等。Kaldi代碼本應包括C++面向對象的各種優點,不過可能因為很多作者不熟悉面向對象,以及沒有辦法採用嚴格開發管理的方式,其實不少代碼(比如nnet1的Nnet class)具有了壞的面向對象的很多缺點……比如有時候過度包裝,有時候相反的把面向對象寫成了面向過程……反而更難擴展。

代碼擴展的難易度其實還跟原本編寫的質量有關,比如HTK的HAdapt模塊,很多採用了static的函數內共享變數,擴展起來就很麻煩。如果單純比較神經網路部分,HTK支持通用結構的神經網路,所以我們自己的經驗是比較容易擴展。Kaldi的nnet1實現的非常局限,從演算法層面修改支持不同的神經網路模型時候很麻煩,而且對Nnet類的繼承等等有很多問題。這也許是因為繼承和動態綁定跟Kaldi工具的設計思路有矛盾(一個小的變化就要對應一個新的工具,所以即使存在合適的Nnet派生類也需要把所有相關的binary重複實現一遍……)。nnet2和nnet3據說work的很好,但是包含了很多作者自己發明的演算法、trick等等,作為作者之外的人很難了解每個公式的作用和效果,所以很難實現擴展;這點我自己認為HTK做的要好一些,具體演算法公式的實現上盡量基於廣泛接受的(或至少是有文檔的演算法)版本。

單純從閱讀理解代碼的角度,我覺得還是各有優劣。HTK的代碼歷史比較久,很多很經典、穩定的代碼都有快30年了,讀起來確實不很容易。而且HTK的文檔更多是介紹演算法和工具使用。Kaldi的代碼本應該好讀不少,但個人的感覺是因為有些類的關係設計的有點奇怪,實際上閱讀理解的時候也並不順暢。但Kaldi的在線文檔是包含了比較詳細的類圖和借口函數說明的,這點也許對理解代碼有幫助。說到底,畢竟兩個工具包的開發都不是嚴格的現代軟體工程的產物,所以具體的質量取決於某部分代碼的具體作者的實現情況。

最後我覺得還有個設計思路的區別其實對兩者的代碼也有很大影響。HTK的設計思路有點類似emacs,有若干個嚴格設計過的工具,每個工具通過複雜的配置可以實現相關的所有功能,而對應的配置和演算法可以通過查閱HTKBook獲得。Kaldi的設計思路某種程度上有點像VI,做了很多小的工具,通過公共的讀寫借口設計讓不同工具容易協作,所以每個工具對應的main函數很好讀,不需要詳細的文檔說明;但這樣也增加了對腳本以及演算法理解的難度。


請問您是實現了HTK 的神經網路模塊嗎


推薦閱讀:

語音識別、二維碼,誰才是移動互聯網真正的入口?
語音識別中的Lattice這個概念怎麼理解?
語音識別技術的干擾因素有哪些?
做好嘈雜環境的語音識別,目前難點主要在哪裡?
如何理解小米MIX2的雙ADC高清錄音?

TAG:語音識別 | 開源 |