我們檢查了每一筆機器翻譯。出錯的正是檢查本身。
語言
在發布翻譯套件之前,我們先拿一個小型範例應用程式測試:將六種格式(JSON、Flutter ARB、Android、Apple .strings、gettext 和 Markdown)中的 70 個字串,翻譯成德文、俄文、日文、阿拉伯文和西班牙文,並使用我們自己機器上運行的 27 億參數開放模型。每個翻譯字串在寫入前都會經過檢查。350 個字串中有 4 個被拒絕。這 4 次拒絕全都是誤判。
檢查項目
會破壞應用程式的翻譯比沒有翻譯更糟,因此每個字串必須保留其佔位符(%1$s、{name}、{{count}})、標籤、換行符號和 URL;必須使用目標語言的文字系統;不得為空、過長或保留英文;且複數形式必須涵蓋該語言具備的所有類別。未通過檢查的字串會標明問題後重新請求翻譯,若再次失敗則予以排除,讓應用程式對該字串顯示英文。
四次拒絕
- 德文的「Backups」翻譯為「Backups」。檢查機制判定其未翻譯。德文確實使用這個英文詞。單一相同詞通常是正確的;兩個或更多相同詞則不然,這便是現在的規則。
- 一行俄文和一行日文含有電子郵件地址未通過文字系統檢查:因為
[email protected]使用拉丁字母書寫,導致西里爾字母或日文假名/漢字的比例低於 60%。現在地址視同佔位符處理:必須原樣保留,且不計入字母比例。 - 一個日文複數訊息回傳為
{count, plural, =0{連續記錄なし} other{{count}日連続}}。分支{連續記録なし}沒有空格,因此佔位符模式將其誤認為名為 連続記録なし 的變數。現在複數訊息中的分支大括號視為結構,且佔位符名稱必須為 ASCII。
修正檢查機制後,第二次執行僅向模型請求那四個字串,因為其餘內容已存在於翻譯記憶庫中,並在 45 秒內寫入全部 350 個字串。
預期會失敗卻沒失敗的部分
複數形式正是粗糙翻譯容易出錯的地方:英文有 one 和 other,俄文有 one、few、many 和 other,阿拉伯文有六種分類,日文則只有一種形式。我們要求模型嚴格使用目標語言的分類,並檢查每個形式的佔位符。模型為俄文寫出了「1 день, 2 дня, 5 дней」,並寫出了阿拉伯文的全部六種形式。所有 Android 複數形式在五种語言中皆一次通過,所有複數訊息也通過檢查,除了那個被我們的檢查機制誤判的日文訊息。
檢查機制無法捕捉的問題
接著,我們將範例中的 22 個網頁字串翻譯成 Polyglot 支援的全部 42 種語言:924 個字串中有 924 個通過檢查。通讀這些翻譯時,有一條特別顯眼。在高棉文中,「You are offline」被翻譯成了一句表示「你上線了」的話。它是語法正確、使用正確文字且無遺漏的高棉文,因此通過了所有檢查。檢查機制能捕捉導致應用程式出錯的問題;但錯誤的語意需要一位懂該語言的人來把關。
重點整理
對機器輸出進行自動檢查,需要真實的輸出作為測試對象。使用虛構翻譯的單元測試通過了;但當真實模型撰寫真實的日文時,幾分鐘內就發現了漏洞。Polyglot 隨附這些已修正的檢查機制,以及針對四種情況的測試。