Skip to content
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

opencc 词库转换为 ocd2 格式 #1159

Open
wzv5 opened this issue Feb 8, 2025 · 6 comments
Open

opencc 词库转换为 ocd2 格式 #1159

wzv5 opened this issue Feb 8, 2025 · 6 comments

Comments

@wzv5
Copy link

wzv5 commented Feb 8, 2025

摘要

opencc 词库转换为 ocd2 格式

输入方案

所有方案

相关应用

所有

系统信息

所有

详细说明

由于 librime 每次创建 session(或者说每个调用输入法的进程)都会重新加载一遍 opencc 配置,没有缓存和复用机制。
如果采用当前的 txt 词库格式,加载效率较低,可能影响 session 初始化速度,同时也会影响查询速度,最好转换为更加高效的 ocd2 格式。

转换命令如下:

opencc_dict -i emoji.txt -o emoji.ocd2 -f text -t ocd2

如果在 windows 系统中转换,opencc_dict.exe 可从 librime 官方仓库的 rime-deps-xxxx-Windows-msvc-x64.7z 压缩包中找到,位于压缩包内 bin 目录下。
如果是 linux 系统,比如本项目使用的 github CI 环境,可以安装 opencc 包。

自定义配置

No response

@mirtlecn
Copy link
Collaborator

mirtlecn commented Feb 9, 2025

感谢。确实是之前没意识到的,优化方向和思路。

不过有两个问题:

  • 这个 Feature 解决了什么 bug 或者问题吗?
  • 但具体能优化多少?有没有可以量化的办法。

如果能大幅度改善性能,可以考虑去做。不过,当前的 txt 格式更加适合编辑维护。CI 生成可行,但增加维护成本。

此外,如果确实没有做缓存策略,是否在 librime 或者客户端或者去做更好?

@wzv5
Copy link
Author

wzv5 commented Feb 9, 2025

确实是在 librime 中优化更好,但我暂时不太想给官方仓库提 issue 了,之前提那个明显存在的问题都能被纠结几天,什么反证法、复现代码的,搞得我头大。

至于在不改动 librime 情况下的优化,其实有两点:

  • txt 词库,加载效率确实低
  • 简繁转换词库,这个可能问题更加严重,词库较大有10MB

这个效率问题,单次加载其实没什么,但因为没缓存,每个 session 都会加载一遍,累积起来可能就有比较严重的性能问题。
再加上 librime 是单线程运行的,只要有一个 session 在加载词库,其他所有 session 都得等着,时不时卡顿可能就是这么来的。

如果你收到卡顿反馈,可以具体问问是不是开了简繁转换,如果关掉简繁转换是不是能缓解。

@mirtlecn
Copy link
Collaborator

mirtlecn commented Feb 9, 2025

我觉得不管结果和过程如何,你能在社区上,发现和提出这些问题,就是有价值和贡献的。

可以保留开放这个 issue,有相关情况时,或者其他开发者有相关需求,我们做进一步讨论处理。

@wzv5
Copy link
Author

wzv5 commented Feb 9, 2025

Image

随手测试了一下,如果开启简繁转换,因为要加载10MB的词库,每增加一个session,算法服务就会增加10MB的内存占用,硬盘IO也能看到确实在重复加载词库文件。
如果有几十个进程,算法服务就要吃掉几百M内存,这就有点严重了。
关掉session后,算法服务占用内存会立即降下去。
本项目的 opencc 词库还不算大,影响有限,对于万象拼音这样的 opencc 大词库,影响更大。

@mirtlecn 如果你愿意给 librime 提交,可以尽管去,当作是你发现的问题也行,我无所谓的。

@wzv5
Copy link
Author

wzv5 commented Feb 9, 2025

顺便万象拼音的 @amzxyz 大佬也来看看。

在 librime 修复这个问题之前,最好还是谨慎使用 opencc 词库。

@amzxyz
Copy link

amzxyz commented Feb 9, 2025

顺便万象拼音的 @amzxyz 大佬也来看看。

在 librime 修复这个问题之前,最好还是谨慎使用 opencc 词库。

好的同文就可以转,原本保留是为了可编辑性以下是脚本,且万象已更新:

import os
import json
import subprocess

# 设置要处理的文件夹路径
input_folder = "/home/amz/Documents/输入法方案/万象拼音基础版/opencc"

# 遍历文件夹
for filename in os.listdir(input_folder):
    file_path = os.path.join(input_folder, filename)

    # 处理 TXT 文件(转换成 OCD2)
    if filename.endswith(".txt"):
        ocd2_filename = filename.replace(".txt", ".ocd2")
        ocd2_path = os.path.join(input_folder, ocd2_filename)

        # 执行 opencc_dict 进行转换
        cmd = f'opencc_dict -i "{file_path}" -o "{ocd2_path}" -f text -t ocd2'
        print(f"转换: {filename} → {ocd2_filename}")
        
        try:
            subprocess.run(cmd, shell=True, check=True)
            print(f"转换完成: {ocd2_filename}")
        except subprocess.CalledProcessError:
            print(f"转换失败: {filename}")

    # 处理 JSON 文件(修改 "type" 和 "file")
    elif filename.endswith(".json"):
        print(f"正在修改 JSON: {filename}")

        with open(file_path, "r", encoding="utf-8") as f:
            data = json.load(f)

        modified = False

        # 递归修改 JSON 内部字段
        def update_json(obj):
            nonlocal modified
            if isinstance(obj, dict):
                if "type" in obj and obj["type"] == "text":
                    obj["type"] = "ocd2"
                    modified = True
                if "file" in obj and obj["file"].endswith(".txt"):
                    obj["file"] = obj["file"].replace(".txt", ".ocd2")
                    modified = True
                for key in obj:
                    update_json(obj[key])
            elif isinstance(obj, list):
                for item in obj:
                    update_json(item)

        update_json(data)

        # 写回 JSON 文件
        if modified:
            with open(file_path, "w", encoding="utf-8") as f:
                json.dump(data, f, ensure_ascii=False, indent=4)
            print(f"已修改: {filename}")
        else:
            print(f"无需修改: {filename}")

print("所有文件处理完成。")

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

No branches or pull requests

3 participants