1. 程式人生 > 實用技巧 >AIBigKaldi(二)| Kaldi的I/O機制

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 modetext mode)。不需要準確地追溯一個檔案到底是binary的還是text的。

一個binary的Kaldi檔案以字串"\0B"開頭,而text檔案不需要檔案頭(header)。

典型的讀寫過程如下:

包含Kaldi物件的檔案需要宣告它們是包含二進位制資料還是文字資料。

二進位制Kaldi檔案將以字串“ \ 0B”開頭;由於文字檔案不能包含“ \ 0”,因此它們不需要標題。

5 總結

瞭解了kaldi的輸入輸出機制後,開始進行資料準備工作。

下期預告

AIBigKaldi(三)|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大道理”,選擇“關注”公眾號

—————————————————————

—————————————————————

投稿吧 | 留言吧