Skip to content

feat(script_translator): learn new phrases automatically from segmentations #1014

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 10, 2025

Conversation

bgzhao66
Copy link

@bgzhao66 bgzhao66 commented May 18, 2025

Feature

feat(script_translator): learn new phrases automatically from segmentations

  • separate new phrases by segmentations rather than using the sentence
    as a whole, while committing into user_dictionary

  • join adjacent segments if the result is no longer than core_word_length

  • ignore the phrases which are longer than max_word_length

Examples

在整句輸入時,通過斷句(由光標或選詞等產生)學習新詞,而不是學習整句作為新詞,然後寫入用戶詞典。
例如: 在下表中,句子中的符號‘|’,表示斷句的位置;且參數max_word_lengthcore_word_length,分別配置為7和4.

學習的新詞 整句輸入時的斷句 記錄的詞數
去畫 一旦嘗試|去|畫|示意圖 3
和式 總是比把除數寫成|和式|要更方便些 2 (忽略 1)
它|是我的一個東西 2
要做的就是簡化|它 2
有歧義 這是|有歧義| 的一句話 3
他們是 我知道|他們|是|可愛的人 3

說明

  1. 斷句產生的多個相鄰片段(segment),如果合併後長度不超過 core_word_length,將會合併成一個詞;其餘每個片段(segment)生成一個詞。
  2. 產生的詞,如果長度不超過 max_word_length ,則記錄到用戶詞典中,尤其是作為學到的新詞;否則,只更新其構成元素(elements)的權重。
  3. 產生的詞彙,通過音節或codes數,計算詞長。
  4. 參數core_word_length生效的取值,不超過參數max_word_length的取值。
  5. 該功能默認關閉。若配置參數core_word_length為大於0的值時,從斷句片段學習新詞的功能開啟,否則維持原來行為方式;若配置max_word_length 為大於0 的值時,將按長度過濾新生成的用戶詞彙,否則維持原來行為方式。

Unit test

  • Done

Manual test

  • Done

Code Review

  1. Unit and manual test pass
  2. GitHub Action CI pass
  3. At least one contributor reviews and votes
  4. Can be merged clean without conflicts
  5. PR will be merged by rebase upstream base

Additional Info

Benguang added 4 commits May 17, 2025 15:31
…ations

 * separate new phrases by segmentations rather than using the sentence
   as a whole, while committing into user_dictionary

 * join adjacent segments if the result is no longer than core_word_length

 * ignore the phrases which are longer than max_word_length
@bgzhao66 bgzhao66 marked this pull request as draft May 27, 2025 12:07
@bgzhao66 bgzhao66 marked this pull request as ready for review May 27, 2025 12:07
@bgzhao66
Copy link
Author

@lotem This may be a useful feature. Please check if it is needed generally.

@lotem
Copy link
Member

lotem commented Jun 4, 2025

還沒細看。

我最初對分詞的構想是,空格確認可以看作分詞的標誌。
把空格確認上屏的一段文字當作用戶詞記錄。
「語句流」模式,則是以空格確認爲界分詞。
不管是不是語法意義上的詞,至少空格對應的是語流中的一處停頓。
但是數字選重則不一定,因爲:遇到字不對,必須要選,此處不一定是詞的邊界。

所舉的例子,固然用分段學習的策略更好;我認爲需要觀察反例,因爲不可避免的選字,而學到不完整的片段。

@bgzhao66
Copy link
Author

bgzhao66 commented Jun 7, 2025

fluency editor模式下,如果整句輸入方式,即一次性輸入整句的拼音,然後空格上屏,如果其中有推測不符合預期,再回過頭來進一步通過光標斷句和人工選詞調整,回顧式調整的方式,此時中間鍵入的空格似乎是被看作為了選詞動作(kSelected),只有最後空格被看作了確認(kConfirmed)。這裡的處理邏輯,應該是和express editor類似的。而新學習詞彙或短語的邊界,原始行為應該是通過確認或當前語言不可識別字符來標記的。

@bgzhao66
Copy link
Author

bgzhao66 commented Jun 7, 2025

根據嘗試fluency和express editor的體驗,底層基於script_translator處理詞彙合併或新詞學習的邏輯應該是相同的;而且也都分為逐詞輸入方式和整句輸入方式。逐詞輸入的方式(包括短語),RIME處理已經可堪稱完美了;當前主要考慮,整句輸入方式。

  1. 漢語的核心詞彙,通常為二、三、或四字詞,最長七個字以包括七言古詩的詩句。自動記錄更長的整句、短語或詞彙,就沒有必要了。

  2. 整句輸入時,最流暢的方式可能是,直接輸入整個句子的音節,引擎能以高正確率推斷出所使應使用的字詞。類似那些在線輸入法的使用方式。
    如果有些字詞沒有正確推斷出來,則需要通過斷句或選詞干預調整推斷選詞。目前通過長度控制是否繼續合併人工選詞;如果能夠區分是否為光標斷句,而光標斷句內人工選詞自動合併,以控制用戶期望引擎學習的新詞、短語或片段,可能就更好了。

  3. 如果能提高整句輸入時推測的準確率,即使記錄的詞彙或短語有不完整片段,也應該是可接受的。

  4. 最後,用戶可以配置是否打開這個功能。

在整句輸入方式下,要高正確率推測出預期中的字詞,並且在推測失敗的情況下,能夠提供光標斷句和人工選詞干預的機制,這確實是一個極為困難的任務。即使目前那些基於大語言模型的主流在線輸入法,也很難做到完全準確的推斷出用戶預期的字詞,而且在沒有準確推斷出正確字詞的情況下,它們也不能如同RIME引擎一樣,可提供讓用戶能夠通過光標斷句或人工選詞干預的能力。

@lotem
Copy link
Member

lotem commented Jun 9, 2025

值得研究。
@rime/engine

這個值得做,也是我曾經想做的。
餘下的就是具體實現,請羣裏的編程算法高手再把把關。

另一個思路是不認新詞,而記錄用戶輸入的字級二元關係,早先寫過,效果似乎也不錯。

@lotem lotem requested a review from a team June 9, 2025 07:48
@lotem
Copy link
Member

lotem commented Jun 27, 2025

呼喚 @rime/engine 小夥伴們,誰有興趣來鑑定鑑定?

@ksqsf
Copy link
Member

ksqsf commented Jun 27, 2025

贊同「從句子中得到詞語」的想法:

  1. 所有收集到的「片段」,均來自用戶實際輸入,因此假設用戶會再次輸入類似的句子,下次就還能用到。
  2. 這裏的 tradeoff 是,片段應該多長?起始點和終止點在哪裏?
  3. 考慮到「選字點」表示之前組句失敗,因此起始點和終止點放在選字點附近是合理的。
  4. 再考慮到用戶實際輸入的習慣(這裏指我自己的習慣),詞的邊界往往也會選字。
  5. 假設新詞邊界一定有一次選字,選字點是 $s_1, s_2, ..., s_{10}$,其中有一些是邊界(比如說 $s_3, s_7$),那麼只要把這些邊界內的 segment 合併起來( $[s_1..s_3], [s_4..s_7], [s_8..s_{10}]$ )就是“新詞”。

一些疑問:

  1. 沒理解錯的話,組詞使用的是貪心算法。使用相同的參數,這句話
    若嘗試|去|畫|示意圖
    看起來會學習到「若嘗試去」和「畫示意圖」?不過這個結果看起來也沒什麼問題。但我在想是不是順便把「去畫」也學習上會比較好?

    另外我做了一些測試。設置 core_word_length=2max_word_length=10,然後輸入 zi ji guan lian,首選是「自己關聯」,然後我依次選了「字」、「級」和「關聯」,成功造出了「字級」這個詞,但無論我如何重複這個過程,或直接選「字級」和「關聯」,都無法造出「字級關聯」這整個詞,這是符合預期的嗎?

  2. 另外感覺選項名有點難以理解,兩個選項似乎都是某種上界。max_word_length 是否可以看作與本 PR 核心功能無關的正交功能?

  3. (也許還可以和 commit history 結合。)

@bgzhao66
Copy link
Author

bgzhao66 commented Jun 30, 2025

一些疑問:

  1. 沒理解錯的話,組詞使用的是貪心算法。使用相同的參數,這句話
    若嘗試|去|畫|示意圖
    看起來會學習到「若嘗試去」和「畫示意圖」?不過這個結果看起來也沒什麼問題。但我在想是不是順便把「去畫」也學習上會比較好?

更新的PR,採用滑動窗口拼接新詞,將產生所有可能符合長度條件新詞。這樣
若嘗試|去|畫|示意圖
將學習到「若嘗試去」「去畫」「畫示意圖」

另外我做了一些測試。設置 core_word_length=2max_word_length=10,然後輸入 zi ji guan lian,首選是「自己關聯」,然後我依次選了「字」、「級」和「關聯」,成功造出了「字級」這個詞,但無論我如何重複這個過程,或直接選「字級」和「關聯」,都無法造出「字級關聯」這整個詞,這是符合預期的嗎?

參數 core_word_length, 控制由選詞拼接而成新詞的長度上限。所以當core_word_length=2時,將會合併「字級」。此時會因為「字級」頻率遠低於其同碼詞「自己」,所以將產生“無論如何重複“這個過程,都無法造出「字級關聯」這個整詞的表象。
這是符合預期的行為。

在更新後PR中,若core_word_length=4將會同時合併出「字級」「級關聯」「字級關聯」等詞彙。

  1. 另外感覺選項名有點難以理解,兩個選項似乎都是某種上界。max_word_length 是否可以看作與本 PR 核心功能無關的正交功能?

更新的PR,使core_word_length功能和max_word_length功能正交,可單獨開啟。

  • 功能默認關閉。
  • 配置正值core_word_length時,打開從片段學習新詞的功能,採用滑動窗口機制。
  • 配置正值max_word_length時,打開學詞的新詞用戶長度上限控制;超過新詞只更新構成元素,不記錄該詞。
  • 若這兩個參數都配置了正值,則core_word_length實際取值將不超過max_word_length

參數名core_word_length意為這些不超過該長度的詞為「核心詞彙」,需要從選詞合併。有些詞彙未經過選詞而由引擎推斷產生,那麼這些詞彙長度可以超過「核心詞彙」,因其可由引擎推斷產生(其表現為一個單一的片段),故不看作是核心詞彙。

新產生的用戶詞彙,無論是否核心詞彙,其長度均不可超過「最大詞彙長度」,由配置max_word_length控制。

  1. (也許還可以和 commit history 結合。)

@lotem
Copy link
Member

lotem commented Jul 1, 2025

优秀啊。

忽然想到我曾写死一段两字词、三字词逐字选择后造词、不给字调频的特判逻辑。

  * concatenate adjacent segments resulting in new words of length no
    more than core_word_length

  * ensure functionalities of core_word_length and max_word_length orthogonal
Copy link
Member

@ksqsf ksqsf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

试用了一段时间,感觉不错,推动一下合并这个功能。

@lotem
Copy link
Member

lotem commented Jul 10, 2025

⿱艸㞢佬的肯定!

@lotem lotem merged commit fee05a5 into rime:master Jul 10, 2025
10 checks passed
@lotem
Copy link
Member

lotem commented Jul 10, 2025

感謝 @bgzhao66 改進的算法。
我還沒試……最近時間不夠。
粗略瀏覽了代碼,非常漂亮,給我的感覺靠譜。

大家都可以建議建議,哪些方案適合用這個算法。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants