AIBigKaldi(二)| Kaldi的I/O機制
本文來自公眾號“AI大道理”。
作為傳統語音識別神器,kaldi擁有自己一套獨特的輸入輸出機制。
先來感受一下吧。
feats="ark,s,cs:apply-cmvn $cmvn_opts --utt2spk=ark:$sdata/JOB/utt2spk scp:$sdata/JOB/cmvn.scp scp:$sdata/JOB/feats.scp ark:- | add-deltas $delta_opts ark:- ark:- |"
咋一看,這是什麼鳥語?花香!
1 檔案I/O機制
Kaldi採用一種擴充套件的檔名進行輸入輸出。
讀取檔案的檔名稱為rxfilename,寫入的檔名稱為wxfilename。
xfilenames,是一個字串,表示由Input類進行解析的擴充套件檔名稱,代表讀。
wxfilenames,是一個字串,表示由Ouput類進行解析的擴充套件檔名稱,代表寫。
特點:
-
在rxfilename/wxfilename 處採用“-”來表示標準輸入輸出。
-
rxfilename/wxfilename可以使用管道命令,比如先用gunzip將壓縮檔案解壓,再輸入到Kaldi程式中,即可在檔案輸入路徑處填入“gunzip -c foo.gz|”。
-
rxfilename/wxfilename後可以通過“:”來描述偏移量,如“foo:1045” 表示從foo檔案偏移1045個位元組開始讀取。
-
使用–binary=true/false來控制是否使用二進位制輸出。預設是true。
rxfilename |
“-” or “” |
表示標準輸入 |
“command |” |
命令通過管道作為輸入,解析的時候去掉”|”,將剩下的command通過popen()交由shell處理 |
|
“/some/filename:12345” |
檔案有偏移 |
|
/some/filename” |
不滿足上面三種形式的當做普通檔案解析 |
|
wxfilename |
“-” or “” |
標準輸出 |
“|command” |
輸出經由管道傳給command,同樣通過呼叫popen()函式交由shell |
|
“/some/filename” |
不是以上兩種形式的當作普通檔案解析 |
檔案讀寫機制
檔案的讀寫採用 Input/Output 類。
Input 類的介面 |
建構函式:Input (const std::string &rxfilename, bool *contents_binary=NULL) 和 Input () |
bool Open (const std::string &rxfilename, bool *contents_binary=NULL) |
|
bool OpenTextMode (const std::string &rxfilename) |
|
bool IsOpen () |
|
int32 Close () |
|
std::istream & Stream () |
|
解構函式~Input () |
|
Output 類的介面 |
建構函式 Output (const std::string &filename, bool binary, bool write_header=true)和Output () |
bool Open (const std::string &wxfilename, bool binary, bool write_header) |
|
bool IsOpen () |
|
std::ostream & Stream () |
|
bool Close () |
|
解構函式 ~Output () |
2 表格I/O機制
對於一系列資料的集合,Kaldi 採用表格形式來表示。
表格中,以沒有空格的字串為索引。
Kaldi 中,稱從表格檔案中讀取的一個字串為 rspecifier, 寫入表格檔案的一個字串為wspecifier。
Table類需要一個傳遞給建構函式或Open方法的字串。如果傳遞給TableWriter類,則此字串稱為wspecifier。
傳遞給RandomAccessTableReader或SequentialTableReader類,則稱為rspecifier。
有兩種表格檔案格式:archive (.ark)和 script (.scp)。
其中:
scp標準格式 |
<key><rxfilename>1 |
rxfilename的形式 |
檔案路徑 /some/filename |
管道 gunzip -c /usr/data/file_010001.wav.gz | |
|
檔案範圍 foo.ark:89142[0:51,89:100]123456 |
|
ark標準格式 |
token1 [something]token2 [something]token3 [something] ....1 |
rspecifier和wspecifiers的選項說明
選項 |
功能 |
|
rspecifier |
“o” |
(一次)斷言每一個條目只讀取一次 |
“p” |
(靜默)指示程式碼忽略錯誤並僅提供它可以提供的資料; 無效資料被視為不存在。 |
|
“s” |
(排序)指示正在讀取的存檔中的鍵按排序字串順序排列的程式碼。 |
|
“cs” |
(called-sorted)指示對HasKey()和Value()的呼叫將按字串順序排列。 “cs”表示使用者斷言程式可能正在迭代的ark檔案本身已經排序。 |
|
“no” |
“o”的反義詞 |
|
“np” |
“p”的反義詞 |
|
“ns” |
“s”的反義詞 |
|
“ncs” |
“cs”的反義詞 |
|
wspecifiers |
“b” |
(二進位制)表示以二進位制模式寫入 |
“t” |
(文字)表示以文字模式寫入。 |
|
“f” |
(重新整理)表示在每次寫入操作後重新整理流。 |
|
“nf” |
(無重新整理)表示在每次寫入操作後不重新整理流 |
|
“p” |
表示靜默模式,它影響“scp:”wspecifiers,其中scp檔案缺少某些條目:“p”選項將導致它靜默地不為這些檔案寫任何內容,並且不報告任何錯誤。 |
rspecifier用法 |
含義 |
ark:foo.ark |
Read from archive foo.ark |
scp:foo.scp |
Read as specified in foo.scp(音訊檔案列表) |
ark:- |
Read archive from stdin |
ark:gunzip –c foo.gz |
Read archive from foo.gz |
ark,s,cs:- |
Read archive (sorted) from stdin... |
wspecifier用法 |
含義 |
ark:foo.ark |
Write to archive “foo.ark” |
scp:foo.scp |
Write to files using mapping in foo.scp(特徵列表) |
ark:- |
Write archive to stdout |
ark,t:|gzip –c>foo.gz |
Write text-form archive to foo.gz |
ark,t:- |
Write text-form archive to stdout |
ark,scp:foo.ark,foo.scp |
Write archive and scp file |
表格(Table)讀寫
對於表格檔案(scp,ark),Kaldi 定義了專門的表格讀寫器。
表格讀寫器是關於 Holder 類的模板類。
Holder 是一些輔助類,負責告訴表格讀寫器,物件的型別是什麼,應該如何讀寫。
表格讀寫器有四個類:RandomAccessTableReader 、 SequentialTableReader 、
TableWriter 、 RandomAccessTableReaderMapped 。
Sequential 表示序列化訪問,即支援使用迭代器遍歷;Random 表示隨機訪問某幾個。
讀寫的時候,需要提供 wspecifiers/rspecifiers 給讀寫器。
3 命令列I/O機制
命令列 I/O 是指在 shell 上呼叫編譯好的 Kaldi 工具的方法。
命令列I/O機制例項
功能 |
檢視音訊檔案的時長 |
命令 |
wav-to-duration‘scp:echo“utt1 data/0000.wav" | 'ark,t:- |
解析 |
scp: 定義了輸入是一個列表表單 echo 將表單內容列印到標準輸入中 | 管道符號,告訴讀宣告符從標準輸入中獲取這個列表表單 ark 寫宣告符定義了輸出是一個文字型別的存檔檔案 t: (文字)表示以文字模式寫入 - 標準輸入符號告訴宣告符將輸出列印到命令列螢幕上 |
功能 |
讀取cmvn.scp和feats.scp並輸出歸一化後的特徵值。 |
命令 |
feats="ark,s,cs:apply-cmvn $cmvn_opts --utt2spk=ark:$sdata/JOB/utt2spk scp:$sdata/JOB/cmvn.scp scp:$sdata/JOB/feats.scp ark:- | add-deltas $delta_opts ark:- ark:- |" |
解析 |
ark,s,cs:輸入的檔案為ark格式,且約定按索引排序(s),並保證可執行程式按排序的順序讀取元素(cs) apply-cmvn 可執行檔案 cmvn_opts和 –utt2spk都是該可執行檔案的指令 [options] 的一部分, –utt2spk 指定utt2spk檔案的路徑 ark: 表示要輸入的是ark格式檔案 scp: 表示要輸入的是scp格式檔案 ark:- 以ark二進位制格式對資料進行標準輸出 | 管道符號,告訴讀宣告符從標準輸入中獲取這個列表表單,傳給下一個可執行程式 add-deltas 可執行程式 ark:- ark:- 一個表示標準輸入,一個表示標準輸出 |
4 程式碼級I/O機制
/kaldi-trunk/src/util資料夾下的kaldi-io.h 是Kaldi的I/O機制相關類的宣告。
物件(Object)讀寫機制
Kaldi中定義的類有一個通用的I/O介面。
標準的介面如下:
註解:
返回的是void
型別,不能接一連串的istream
或者ostream
。
binary
引數是一個標誌位,表明要讀寫的是binary
資料還是text
資料。
Kaldi進行讀操作的程式碼需要知道用哪種模式(binary mode
和 text mode
)。不需要準確地追溯一個檔案到底是binary的還是text的。
一個binary的Kaldi檔案以字串"\0B"
開頭,而text檔案不需要檔案頭(header
)。
典型的讀寫過程如下:
包含Kaldi物件的檔案需要宣告它們是包含二進位制資料還是文字資料。
二進位制Kaldi檔案將以字串“ \ 0B”開頭;由於文字檔案不能包含“ \ 0”,因此它們不需要標題。
5 總結
瞭解了kaldi的輸入輸出機制後,開始進行資料準備工作。
下期預告
AIBigKaldi(三)|Kaldi資料準備
往期精選
AI大語音(十四)——區分性訓練
AI大語音(十三)——DNN-HMM
AI大語音(十二)——WFST解碼器(下)
AI大語音(十一)——WFST解碼器(上)
AI大語音(十)——N-gram語言模型
AI大語音(九)——基於GMM-HMM的連續語音識別系統
AI大語音(八)——GMM-HMM聲學模型
AI大語音(七)——基於GMM的0-9語音識別系統
AI大語音(六)——混合高斯模型(GMM)
AI大語音(五)——隱馬爾科夫模型(HMM)
AI大語音(四)——MFCC特徵提取
AI大語音(三)——傅立葉變換家族
AI大語音(二)——語音預處理
AI大語音(一)——語音識別基礎
——————
淺談則止,細緻入微AI大道理
掃描下方“AI大道理”,選擇“關注”公眾號
—————————————————————
—————————————————————