2023年3月3日 星期五

非常擬真的文字轉聲音服務(TTS)

Azure Speech服務除了可以將語音轉為文字,當然也可以從文字輸出語音。

我們看執行的結果:(有聲音)

上面這個影片當中,你會同時看到文字轉語音和語音轉文字,一開始的時候,我們讓電腦說出:

請透過語音下達指令…, 直到說 ‘我要離開’

執行的是底下這段程式碼:

await Speak(speechConfig, "請透過語音下達指令..., 直到說 '我要離開'");

而Speak方法的內容如下:

        async static Task Speak(SpeechConfig speechConfig, string text)
        {
            // Configure speech synthesis
            speechConfig.SpeechSynthesisLanguage = "zh-TW";
            speechConfig.SpeechSynthesisVoiceName = "zh-TW-HsiaoChenNeural"; //女生 
            speechConfig.SpeechSynthesisVoiceName = "zh-TW-YunJheNeural"; //男生 
            using SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer(speechConfig);

            // Synthesize spoken output
            SpeechSynthesisResult speak = await speechSynthesizer.SpeakTextAsync(text);
            if (speak.Reason != ResultReason.SynthesizingAudioCompleted)
            {
                Console.WriteLine(speak.Reason);
            }
            // Print the response
            Console.WriteLine("\n說了:" + text);
        }

關鍵是 SpeechSynthesizer 物件,我們可以透過該物件的SpeakTextAsync()方法,把要說的文字傳入,即可直接從標準的喇叭設備,來進行語音輸出。

要採用哪一種語音,可以透過 speechConfig的SpeechSynthesisVoiceName屬性來設定:

speechConfig.SpeechSynthesisVoiceName = "zh-TW-YunJheNeural"

完整的語音清單可以參考底下文件:
https://github.com/MicrosoftDocs/azure-docs.zh-tw/blob/master/articles/cognitive-services/Speech-Service/language-support.md

你會發現,透過C# SDK,要輸出類似真人的語音,也是非常簡單的。

完整的程式碼在GitHub, 可以透過底下方式取得:

git clone https://github.com/isdaviddong/STT_example.git

非常厲害的語音轉文字(語音識別, STT)服務

在Azure的cognitive services當中,也有非常厲害的語音轉文字(語音識別)服務,從底下的這個 Console程式中你可以發現,語音服務幾乎完整的辨識筆者講的話,甚至速度加快也可以,中英文夾雜也可以:

要使用此服務相當簡單,同樣在Azure Portal上申請即可:

申請完成之後,取得 key 和 location,即可透過 .net SDK來開發。

例如,如果你想做一個語音助理,希望寫程式來識別用戶說的話,其實程式碼可能只有類似底下這幾行:


using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CognitiveServices.Speech;
using Microsoft.CognitiveServices.Speech.Audio;

namespace STT_example
{
    class Program
    {
        async static Task FromMic(SpeechConfig speechConfig)
        {
            using var audioConfig = AudioConfig.FromDefaultMicrophoneInput();
            using var recognizer = new SpeechRecognizer(speechConfig, "zh-tw", audioConfig);

            Console.WriteLine("嗨~ 請透過語音下達指令..., 直到說 '我要離開' ");
            var text = "";
            while (!text.Contains("離開"))
            {
                var result = await recognizer.RecognizeOnceAsync();
                text = result.Text;
                Console.WriteLine($"\n識別語音 = '{text}' 。\n(如果要結束,請說 '我要離開')");
            }
            Console.WriteLine("\n\n 掰掰~ ");
        }

        static void Main(string[] args)
        {
            // Set console encoding to unicode
            Console.InputEncoding = Encoding.Unicode;
            Console.OutputEncoding = Encoding.Unicode;

            var speechConfig = SpeechConfig.FromSubscription(
                "___your__key____", "___localtion___");
            FromMic(speechConfig).GetAwaiter().GetResult();
        }
    }
}

請注意到此程式碼中使用到了 Microsoft.CognitiveServices.Speech 套件。

讀者可透過從筆者的 GitHub下載此範例:

git clone https://github.com/isdaviddong/STT_example.git

我們再次來看執行的結果(有聲音):

有沒有發現很有趣?

語音服務幾乎完整的辨識筆者講的話,甚至速度加快也可以,中英文夾雜也可以。

由於我在程式碼(19行)中撰寫了一個loop,因此程式會持續辨識我說的每一句話,直到我說出 ‘離開’ 這個關鍵字,系統辨識到之後就跳出迴圈。

主要的語音辨識類別是 SpeechRecognizer這個物件,其中的 RecognizeOnceAsync() 方法,會依照我們設定的 config profile,來抓取音源,此例中為預設麥克風 – 程式碼第20行的FromDefaultMicrophoneInput()。

在建立SpeechRecognizer物件時,透過 “zh-tw” 清楚的指定來源的音訊為台灣華語會更有效的加強辨識度。

你有沒有發現,現在的語音識別,在AI加持的狀況下,已經不可同日而語。如果你看到語音輸出會更覺得驚艷,現在的語音已經幾乎讓你分不出是否為真人!

若進一步搭配 ChatGPT 的話,個人語音助理的時代還會遠嗎?

2023年2月27日 星期一

使用Azure Cloud Shell

Cloud Shell是雲端的CLI環境,你可以從Azure Portal上直接啟動該環境:
圖片

這麼做的好處是,你即便在本機電腦(筆電)上沒有安裝AZ CLI,也可以透過網頁即可以命令列模式來管理雲端的資源。

另外,使用雲端版本的CLI還有一些額外的好處,諸如:

  1. 無須登入(az login…),因為你使用Cloud Shell的時候,本來就有登入Azure Portal。
  2. 無須安裝其餘CLI工具或SDK,諸如 git, dotnet , python, docker, kubectl…這些內建通通都有。甚至,還有網頁(陽春)版的VS Code!!!

底下影片介紹如何操作Cloud Shell,第一次進入的時候,會讓你選擇一個Azure 儲存體(Storage),並且選擇Linux或Windows環境:

所以,Cloud Shell內建就有Windows與Linux雙模式,你可以透過左上角的選項切換:

圖片

其實,Cloud Shell本身就是一個儲存體,你可以在該環境中建立資料夾,新增檔案,除非你刪除或無法存取該訂閱,否則這些資源都會保留在雲端儲存體中:
圖片

一般來說,如果要對雲端的Azure資源進行操作,我們常常會直接在Cloud Shell中,下CLI或Power Shell/Bash指令,省去在用戶端還需要安裝 CLI 並且做 az login 動作的麻煩。

有操作Azure的開發或維運人員,是一定得要試試看這個好工具的。

2023年2月24日 星期五

使用AI服務擷取文章重點

在Azure Cognitive Services 服務當中,文字分析(Text Analysis)服務可以針對用戶上傳的文字進行剖析,例如『文字情緒分析』、『關鍵字詞擷取』、『文字摘要』…等。這些服務都以rest api的形式出現,你只需要先取得呼叫API所需的金鑰與端點即可。

底下影片展示如何從 Azure Portal 建立『文字分析服務』,並且找到金鑰與端點:

有了金鑰與端點後,就可以透過程式碼來呼叫其功能。

例如其中的『擷取文章摘要』,是文字分析服務中剛推出沒多久的新功能,可以針對一篇文章、一段文字,抓取其中的重點。

呼叫的endpoint如下:

POST {Endpoint}/language/:analyze-text?api-version=2022-10-01-preview

除了header要傳遞key(金鑰)之外,body要符合底下json格式:

{
  "displayName": "Document ext Summarization Task Example",
  "analysisInput": {
    "documents": [
      {
        "id": "1",
        "language": "zh",
        "text": "(要分析的文章)"
      }
    ]
  },
  "tasks": [
    {
      "kind": "ExtractiveSummarization",
      "taskName": "Document Extractive Summarization Task 1",
      "parameters": {
        "sentenceCount": 3
      }
    }
  ]
}

其中的 text 參數是要分析的文章內容,而 sentenceCount參數則可填入數字,是你想要摘要出的重點個數。

例如,假設我們要針對底下這篇文章,進行摘要:

LUIS全名是Language Understanding Intelligent Services,顧名思義,是一個提供語句理解能力的雲端服務。請留意,LUIS並非去分析語句含意(這是Text Analytics的功能),而是去拆解並嘗試依照句型來判斷一個句子,進而歸納出用戶的意圖(intents),並抓取出句子當中的關鍵entities。而這個功能,對於我們的Caht bot而言,非常的重要。

由於Bot的文字輸入介面很自由,用戶往往可以很隨興的打字輸入,你根本無法限制用戶輸入什麼,以什麼句型方式輸入。而且人很有趣,只要沒有限制,就會竭盡所能地嘗試。此外,也非常有可能因為typo之類的輸入錯誤,導致一個句子在輸入上就有錯別字或是不完整。這些因素,使得Chat Bot開發人員無法只是抓一句話中的特定關鍵字來識別用戶的企圖與目的,而必須進一步使用語意分析與斷字處理。

凡此種種,都讓NLP(自然語言處理)的難度比想像中來的高。你只要開放一個文字聊天機器人,就會有人亂打一些有的沒的,然後Bot沒理解出他的意思,他就笑這個Bot很笨。(這樣很有成就感?)因此,就有對談需求的Bot來說,首要目標之一就是理解用戶輸入的內容,而LUIS則是我們實現這個功能的重點工具。

我們可以修改上面的 text 屬性,把文章置入,成為底下這樣的 JSON, 作為 rest api呼叫的body:

{
  "displayName": "Document 1",
  "analysisInput": {
    "documents": [
      {
        "id": "1",
        "language": "zh",
        "text": " LUIS全名是Language Understanding Intelligent Services,顧名思義,是一個提供語句理解能力的雲端服務。請留意,LUIS並非去分析語句含意(這是Text Analytics的功能),而是去拆解並嘗試依照句型來判斷一個句子,進而歸納出用戶的意圖(intents),並抓取出句子當中的關鍵entities。而這個功能,對於我們的Caht bot而言,非常的重要。
            
 由於Bot的文字輸入介面很自由,用戶往往可以很隨興的打字輸入,你根本無法限制用戶輸入什麼,以什麼句型方式輸入。而且人很有趣,只要沒有限制,就會竭盡所能地嘗試。此外,也非常有可能因為typo之類的輸入錯誤,導致一個句子在輸入上就有錯別字或是不完整。這些因素,使得Chat Bot開發人員無法只是抓一句話中的特定關鍵字來識別用戶的企圖與目的,而必須進一步使用語意分析與斷字處理。

  凡此種種,都讓NLP(自然語言處理)的難度比想像中來的高。你只要開放一個文字聊天機器人,就會有人亂打一些有的沒的,然後Bot沒理解出他的意思,他就笑這個Bot很笨。(這樣很有成就感?)因此,就有對談需求的Bot來說,首要目標之一就是理解用戶輸入的內容,而LUIS則是我們實現這個功能的重點工具。

 "
      }
    ]
  },
  "tasks": [
    {
      "kind": "ExtractiveSummarization",
      "taskName": "Task 1",
      "parameters": {
        "sentenceCount": 3
      }
    }
  ]
}

不過,當我們這麼呼叫時,你會發現,postman回傳的並非分析結果,而是回傳一個類似底下這樣的URL:

https://testanaeastus2023.cognitiveservices.azure.com/language/analyze-text/jobs/654d01f6-4920-4b9e-86ef-bd84520b065e?api-version=2022-10-01-preview

因為,這個『文章摘要』的AI服務,是採用非同步的方式運行:
圖片

上面的這個回傳網址,會以非同步方式,回傳分析好的結果。因此,我們可以透過 postman, 再次以http get方式呼叫,結果如下:
圖片

你會發現,果然擷取出三個重點:

  • LUIS全名是Language Understanding Intelligent Services,顧名思義,是一個提供語句理解能力的雲端服務。
  • 由於Bot的文字輸入介面很自由,用戶往往可以很隨興的打字輸入,你根本無法限制用戶輸入什麼,以什麼句型方式輸入。
  • 因此,就有對談需求的Bot來說,首要目標之一就是理解用戶輸入的內容,而LUIS則是我們實現這個功能的重點工具。

整個操作的影片如下:

透過這個功能,未來閱讀大量文章,就可以讓AI幫你自動歸納重點了。

2023年2月22日 星期三

使用Azure APIM 中的 Polices微調API的行為

最近這幾年,愈來愈多的網站改以前後端完全分離的架構來開發,而微服務盛行,許多後端應用、AI服務、甚或是商業邏輯,都改以WebAPI的方式來實作,更別說為數眾多的手機行動裝置App也需要以呼叫後端API的方式與伺服器端溝通,來完成各種功能。

因此,API開發成為最近幾年的顯學,API First也在許多場合被提起。Azure的APIM服務,就在這樣的情況下誕生了。

使用APIM服務

Azure APIM可以幫我們把企業內部的多組API打散或重新包裝,改以同一個endpoint對外,好讓使用者更方便使用,讓管理者更方便控制與管理。

另外,採用APIM還有一個好處,我們可以隔開用戶和真正的API,這樣除了可以保護後端真正的API,也可以在用戶透過APIM呼叫後端真正的API前,可以對往來(與回覆)的數據做一些加工處理,已達成我們需要的安全性或是API行為的改變,也更容易統一的進行全縣控制…等。

建立APIM

底下影片示範如何建立APIM服務,請注意APIM服務的建立,會花比較長的時間,可能會長達半小時以上:

完成之後,就可以建立好APIM服務了。

建立API集合

建立好APIM服務之後,接著可以在Azure Portal中,建立API集合,前面說過,我們會把實際上開發好的API,先整理成API集合,然後再包裝成產品(Product),釋出給客戶。

底下的說明,我們將示範如何將現有的API(在具備spec definition的狀況下),整理成待會要釋出的產品。我們以底下這組微軟官方的測試API為例:
https://conferenceapi.azurewebsites.net?format=json

如果你點選上面這個網址,會發現,它出現的是json格式的API規格:
圖片

這是標準的 swagger 2.0規則,一般我們撰寫WebAPI之類的後端API服務,都可以透過工具自動產生這些規格文件。若具備這些規格文件。

你可以直接將API透過Import的方式匯入,請看底下操作影片:

從上面的影片當中,你會看到,我們利用 swagger 的json規格定義,把上面的微軟測試API,重新透過APIM封裝,建立另出了一組 endpoint 。

你可以發現API中有一個 GetSpeakers 方法,當我們運行(呼叫)這個方法,會以JSON格式回傳研討會的所有講師(是的,這是一個舉辦研討會的API)。

你可以重複上面的動作,將企業內開發的不同API,個別整理成一組組的集合,以便於未來透過產品功能上架。

APIM Policies

Policies 是我們使用 APIM 一個很重要的原因。

由於APIM隔開了API的 consumer 和 provider,因此,位於中間的APIM可以在真實的API被呼叫的前後,做些手腳,在不改變API原始程式碼的狀況下,微調API的行為與回傳的結果。

這功能非常好用,舉例來說,我們可以在不改變原始程式碼的狀況下,讓API實現以下功能:

  1. 紀錄呼叫log
  2. 限制流量(以避免爆量)
  3. 改變傳入或傳出的封包內容
  4. 以mock方式建立假的或臨時性的API
    (例如後端真正的API尚未開發完成,但希望能夠便於廠商測試)
  5. Retry
    (發生暫時性失效的時候,可以自動重試)

以上都是非常常用的 policy,底下網址可以看到預設狀況下,APIM支援的policies:
https://learn.microsoft.com/en-us/azure/api-management/api-management-policies

具體的配置,是透過XML方式來實作:

<policies>
    <inbound>
        <cross-domain />
        <base />
        <find-and-replace from="xyz" to="abc" />
    </inbound>
</policies>

APIM提供了一個環境,讓我們得以針對API來配置上面這樣的XML指令,以便於調整API的行為。(例如上面是把API傳輸內容中任何的xyz換成abc)

底下的影片,展示如何把API當中原本呼叫時有的伺服器資訊移除,以避免使用者得知API的開發技術,降低資安風險:

從上面展示的影片你可以看到,透過APIM,我們可以在不改變程式碼的狀況下,微幅調整API的行為甚至傳遞內容,是一個非常好用的技巧。

2023年2月21日 星期二

使用Computer Vision中的OCR文字辨識功能

OCR(Optical Character Recognition)指的是識別圖片中的文字,如果你先前已經成功使用Computer Vision API做影像識別(Image Analysis),那使用Computer Vision API做OCR肯定也難不倒你。

請參考同樣的文件:
https://westus.dev.cognitive.microsoft.com/docs/services/computer-vision-v3-2/operations/56f91f2e778daf14a499f20d

你會發現,ORC的API與先前我們介紹過的影像分析幾乎一模一樣,唯一差別是要給定的endpoint URL,最後的結尾是『ocr』。設定如下:

圖片

另外,如果要辨識中文,建議要給定language這個queryString參數,值為『zh-Hant』。

有這些資訊就夠了,我們一樣透過postman來測試,關鍵的資訊如下:

關鍵資訊
endpoint https://你的endpoint.cognitiveservices.azure.com/vision/v3.2/ocr?language=zh-Hant
Ocp-Apim-Subscription-Key(http Header) 你的key
Http body {“url”:“要辨識的圖片url”}

透過這些,我們就可以嘗試辨識了。透過Rest API將要辨識的有像位置(url)傳遞過去,辨識的結果會以JSON回傳。

操作影片如下:

影片中,辨識的文件是底下這張圖:

該圖片的網址為:
https://i.imgur.com/PWQDiRj.png

你也可以自行試試看,你會發現,中文的辨識度其實非常高,幾乎正確的辨識出每一組文字。

回傳的物件是JSON格式,由於圖片上的文字可能有橫有直,辨識出的結果會是以 Regions, Lines, Words, Text 為結構回傳:

圖片

透過 computer Vision 中的 ocr API,取得圖片上的文字變得非常輕鬆。

tags: 電子書 - Azure Cognitive Services

熱門文章