AI填詞能(二):ChatGPT(等)的真正用途是…

在這個「研究用AI填廣東歌詞」的項目沒有更新超過一年瀕臨爛尾之際,出現新的思路把project大幅簡化,讓重新啟動有了方向。

與其直接指示ChatGPT(或其他AI模型)把合音的字填上歌詞(之前的實驗效果並不理想,不知現在進步幾多了),其實中文字有限數,放在歌詞中合音而不太罕見的更是有限數,可以先做一個「從所有可能的合音字隨機抽取」的程式,然後再實驗以各種方法調整選取每個字的機率,逐漸令這個填詞程式更加有用。

簡而言之,執行這個程式只需要幾個步驟:

  1. 找一個有所有中文字粵語讀音的字典,包含每個字的聲母、韻母和聲調;
  2. 輸入一句句子每個字的聲調(或其代表),每一個字電腦都在字典中隨機選取一個合音的字;
  3. 設計某些機制指派每個可能的字被選取的機會率,讓更好或更適合的字詞更有機會被選取。

粵音字典數據庫

有沒有一個可以下載的數據庫,包含所有中文字的粵語讀音呢?其實只要Google就有。找到的是「開放粵語字典」,當中有各種不同的字典,有不同注音方法和檔案格式。我最後採用的是教院繁體字典的csv檔案版本。


數據庫共有6577字,我需要的只是「繁體」和「拼音」兩欄。留意有些字有多過一個讀音,這裡需要轉化使每個「字+粵音」的配搭成獨立一行。去除重複,變成了6888行的表格。之後所有要填的詞,都從這6888個「字+粵音」裡選取了。

之後便是從粵音一欄分裂出聲母、韻母和聲調,這裡岔開一筆技術討論,這裡牽涉一種令人聞風喪膽、名為regular expression的語法,要不是有ChatGPT,單是想如何寫這一句語法,已經難過寫完一首歌詞了。這裡和非技術人士分享一下這句有如火星文一樣的程式碼(後來發現這句火星文也不能滿足所以情況,但那些特殊處理這裡就略去了):

cantonese_long[['initial', 'final', 'tone']] = cantonese_long['jyut'].str.extract(r'^([^aeiouy]*)([aeiouy][^0-9]*)([0-9]+)$')

雖云粵語有九聲,但某幾個聲調在粵語歌詞中其實相通,例如第三聲的字,填第五或第八聲也同樣合音。這裡用上廣東歌詞研究大師黃志華先生提出、近年大為普及的「0243」框架,把每聲調對應0/2/4/3的值,如下:

  • 0:第四聲
  • 2:第六、九聲
  • 4:第三、五、八聲
  • 3:第一、二、六、七聲

當然可以使用其他框架,例如「394052」,不過這是後話了。

這樣完成了第一部份,得出完整的字典資料庫。

歌詞資料庫

去到這裡其實已經可以直接跳到隨機選取用字填詞了,只不過如果每個可用的字機會均等,填出來的東西根本「九唔搭八」,如果歌詞中常用的字比較容易被電腦抽出來,似乎會出現比較make sense的輸出。

第一個嘗試是以一堆歌詞做基礎,計算這些歌詞中每一個字出現的頻率,以此指派每個字獲選機率。初步試一個較小的dataset,選取了最近五年(2020-2024)入選本Blog年度20大的所有粵語歌(一共88首),每首歌詞開一個文字檔,然後用Python讀取這88個檔案,計算每個字的出現次數。注意:由於要準確計算頻率,重複的段落(例如副歌)要真的在檔案重複而不能像以前「Repeat *」之類了事。這一段程式怎寫,當然是交給ChatGPT了。

之後把歌詞資料庫和字典資料庫合併,就可以進行下一步「選字程式」了。

題外話,這88首歌中出現最多的是這十個字:


選字程式

來到最後一步。第一個版本具體的運作是:一次輸入一句(其實字數不限,一個字到1000個字也一樣),每個字用相應的「0243」代碼代表,電腦便逐個字先篩選資料庫中合音的字,再從中按之前計算的機會率抽取一個字,輸出的便是一句和輸入的「0243」代碼合音的句子。

我們也可以設定這個程序重複N次,一次給我N句讓我從中挑選。

例子一:「愛上跳舞太開心」(乜又係你?) → 「4444433」

例子二:「應該放開時請放開」(最近鄭秀文唱紅了) → 「33430343」



現階段出來的字當然毫無章法,但總算用程式完成了整個概念,至少現在填詞時也可以以此作「腦力激盪」,讓電腦一次給我一堆可行的字詞選擇,而不需像以前,例如一句有兩個字「xx」要想填甚麼進去時要人腦scan所有可能的用字。

下一步

表面上一個這樣簡單的程式,執行的時候已經發現有很多問題,留待下一版(或數版)處理:

  • 你可能會留意到上面截圖有些字好像不合音,那其實是同一個字有多過一個讀音,例如上面截圖出現的「長」字,可以是「長度」的tsoeng4或「長官」的dzoeng2。而在現時88首歌的歌詞資料庫中,「長」字出現52次,但程式暫時未分辨那52次分別是屬於哪個讀音;
  • 雖然字典數據庫中有事六千幾百個字,但歌詞還是有些字原來是在字典中沒有的(暫時有63個),主要是廣東話口語用字,需要一些程序把那些字和它們的讀音加進最後選字程式可用的字庫裡;
  • 一開始測試用88首歌詞當然不夠,用字頻率可能還未夠代表性,也有可能有些字還沒有在任何歌出現過以致暫時不會被選(這88首歌一共用上了2240個不同的字,也就是有超過2/3的字還沒出現);
  • 如前所述,隨機抽取的字眼雖然合音但像胡言亂語,如何樣電腦提供的字詞更有紋路更可用於歌詞,還需研究;
  • 最後當然還未加入押韻機制,理論上可進一步收窄用字範圍,而程式上很容易處理(韻母匹配便可),但還是在往後版本處理了。

後記

第一個版本就是這麼簡單,其實也根本用不上甚麼先進AI模型,只是一個純粹的數據科學項目,有相當Python技術的基本上一個週末(甚至幾個小時)就寫到出來,對我來說,ChatGPT或Copilot的作用就是大大加快了寫程式的效率,免卻花時間Google和到Stack Overflow爬文的手續,每次一小段程式問AI如何寫,得出來的代碼結構一般良好,只需稍加修改便能使用。這效率的大幅提升可謂「量變帶來質變」的效果,本來因為耗時甚多而一再拖延,現在因為有AI幫助一直保持進度,更反過來增加繼續下去的興趣和動力。

留言