# Audio ## Week 1F ---- ## 前言 本來 Chatbot 寫得很開心 有一天主管突然跑來跟我說 「欸欸,你要不要接個 ASR 上去」 於是再度開啟我的語音處理之路 ---- ## 簡介 聲音是一種縱波 一般而言麥克風上有振膜 用來紀錄聲波的振幅 連續的振幅可以形成一個聲音 ---- ## Sample Rate 採樣率 Sample Rate 是在將聲音 從**類比訊號**轉為**數位訊號**的過程中 出現的概念 用來表示聲音訊號的取樣頻率 例如 48K 代表一秒取樣 48,000 次 ---- ## 實際應用 現在的麥克風多能錄製到 40K 以上 一般電話多為 8K 左右 但是語音辨識通常 8K 或 16K 就夠了 因此需要做 Downsampling ---- ## 語音特徵 語音辨識通常會有取特徵的動作 一般透過[傅立葉轉換](https://w.wiki/3jUY)分析**音頻** 然後計算 [FBank](https://w.wiki/7U3T) 或 [MFCC](https://w.wiki/7U3L) 之類的特徵 取完特徵就能更輕鬆的做機器學習任務 ---- ## 使用單位 語音處理通常使用 Frame 作為單位 常見的單位是 10 ms 作為一個 Frame 也有 20 ms 或 30 ms 的 因此對 16K 的聲音訊號而言 一個 10 ms 的 Frame 會有 160 個樣本點 ---- ## 資料型態 通常使用 Bit Depth 來描述樣本點的資料型態 通常為 16 Bit 也就是 2 Bytes 整數 把樣本直接存起來的檔案也可稱為 Pulse-Code Modulation, PCM 常見的 Wave 檔 (.wav) 就是加了 44 Byte Header 的 PCM ---- ## VAD 語音活性檢測 Voice Activity Detection, VAD 用來檢查現在有沒有人在講話 一般而言 VAD 的運算量比較小,而 ASR 運算量比較大 所以通常在 VAD 被觸發一段時間後才開始做 ASR 這樣可以節省計算資源 ---- ## EPD 端點偵測 End-Point Detection, EPD 與 VAD 不同的地方在於 VAD 只針對某個 Frame 是否為人聲 而 EPD 通常觀察一段連續的 VAD 狀態 用來決定是否啟動語音辨識 ---- ## ASR Automatic Speech Recognition 也稱為 Speech-To-Text, STT 傳統 ASR 通常由 聲學模型 Acoustic Model, AM 語言模型 Language Model, LM 所組成 ---- ## 聲學模型 AM 主要的目的是辨識聲音訊號的音節 就好比在辨識我們講話的注音 其結果可能像是「ㄋㄧˊ ㄏㄠˇ ㄚ」 ---- ## 語言模型 LM 則用來看這些音節的順序 可能構成哪些合理的句子 以「ㄋㄧˊ ㄏㄠˇ ㄚ」為例 LM 就會算出「你好啊」的機率比較高 而不是「泥豪阿」 ---- ## KWS 關鍵詞偵測 Keyword Spotting, KWS 是一種形式比較單純的語音辨識 只辨識特定的關鍵字,來避免語音誤動 像是 Hey Siri 與 OK Google 就是 KWS ---- ## Whisper 講了這麼多 其實 Whisper 也不是這種傳統做法 而是直接用 Transformers 訓練一個 Encoder-Decoder 模型 --- # 實做環節 ---- ## 安裝錄音套件 透過 PyAudio 套件錄音 Linux 上需要安裝以下套件 ```bash sudo apt install portaudio19-dev python3-pyaudio ``` ---- ## 從麥克風錄音 ```python= import pyaudio recorder = pyaudio.PyAudio() stream = recorder.open( format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=160, ) # 10ms = 1 Frame, 5s = 5000ms = 500 Frames frames = [stream.read(160) for _ in range(500)] ``` ---- ## 存成音檔 透過 Python 內建的 `wave` 套件存成音檔 ```python= import wave with wave.open("output.wav", "wb") as wf: wf.setnchannels(1) wf.setsampwidth(2) # 16 Bits = 2 Bytes wf.setframerate(16000) wf.writeframes(b"".join(frames)) ``` ---- ## VAD 實做 透過 [webrtcvad](https://github.com/wiseman/py-webrtcvad) 套件可以輕鬆達成 每次輸入必須是一個完整的 Frame ```python= import webrtcvad vad = webrtcvad.Vad() vad.set_mode(1) sample_rate = 16000 frame = b"\x00\x00" * 160 # 2 Bit x 1 Frame print(vad.is_speech(frame, sample_rate)) ``` ---- ## ASR 實做 透過 [Faster Whisper](https://github.com/guillaumekln/faster-whisper) 輕鬆調用 ASR 模型 ```python= from faster_whisper import WhisperModel model = WhisperModel( "large-v2", device="cuda", compute_type="int8_float16", # 8-Bit Quantization ) segments, info = model.transcribe("audio.mp3") print(f"Language: {info.language}") print(f"Lang Prob: {info.language_probability}") for seg in segments: print(f"[{seg.start:.2f}s -> {seg.end}s] {seg.text}") ``` ---- ## 實做 EPD 一般而言會需要一個 VAD Buffer 長度大概 80 到 120 個 Frames 當這個 Buffer 假設有 80% 都是觸發狀態 代表發現聲音的開始端點 ---- ## 聲音 Buffer 在進入 ASR 之前 通常會有一個 5 秒的 Buffer 用來存聲音訊號 在 EPD 觸發之後,把這個 Buffer 送入 ASR 避免在 EPD 之前有漏字的狀況 ---- ## EPD 狀態變換 進入 ASR 階段後持續計算 VAD Buffer 如果 Buffer 只剩 20% 是觸發狀態就結束 ASR 所以會有三個狀態:未觸發 > 觸發 > 完成 ---- ## Demo 完整程式碼放在 [GitHub](https://github.com/penut85420/WhisperDemo) 上 --- # Other ---- ## ChatGPT & Mathjax ChatGPT 解釋 Mathjax [成功的例子](https://chat.openai.com/share/2e55b9e2-f058-41a2-a86e-4e3501e323ea) | [失敗的例子](https://chat.openai.com/share/774ebb9d-37f5-4237-8712-eb9ce80d020f) ChatGPT 的 Mathjax 真的強 [Example 1](https://chat.openai.com/share/826a0a6c-81dd-4d2a-90ef-938aeed39771) | [Example 2]( https://chat.openai.com/share/49c67b19-689d-4bda-b58b-78f935ea3044) ---- ## VSCode Math Plugin 使用 [Markdown+Math](https://marketplace.visualstudio.com/items?itemName=goessner.mdmath) 插件 可以在 VSCode 裡面渲染 Mathjax 語法 目的是將數學公式放入 [Slides](https://slides.com/) 所以需要設定小括號 ```jsonld= { "mdmath.delimiters": "brackets" } ``` ---- ## Qubby AI [Qubby AI](https://liff.line.me/2000331789-JpGBrD7B) 蠻歡樂的應用 有山道猴子的 AI 虛擬形象
{"title":"Week 1F - Audio","slideOptions":"{\"transition\":\"slide\"}","description":"地獄貓旅行團第 31 週心得分享","contributors":"[{\"id\":\"c7cbb212-2c41-4dfa-8d85-f8e7fa769bf1\",\"add\":4849,\"del\":746}]"}
    478 views
   Owned this note