平台开发中,欢迎参与测试。你可以在 QQ群:1046115671 中与我们交流,或是直接在社区发帖。

    机器翻译填充功能开发进度

    • 孙锡源
      楼主

      折腾了好久好久,终于完美破解了谷歌的速率限制和解决了 API 返回的译文相较于网页端质量较低的问题。

      目前单个 IP 平均每秒可以翻译 100 条语句。之所以能做到这一点,是因为新的机翻引擎会自动将多条语句合并到一个 HTTP 请求中提交,经由谷歌翻译后再拆解以与原文逐一匹配。实际上 100 条是一个保守值,因为目前会一次提交 4000 个字符,最近几次测试看每次大概可以 200 多条的样子,但是考虑“话别说太满”,所以还是除以二,按保守值算吧。

      其次是之前预想的本地术语库纠正机制经过测试,运行的比较完美。

      以下随便贴几个翻译的数据(其中每个条目的索引是原始语句,source 中是经过术语库预处理的原文,target 是译文,glossaries 是该原文匹配上的术语):

      {
        "There are one or more required or recommended plugins to install, update or activate.": {
          "source": "There are one or more required or recommended plugins to install, <code>#9687</code> or <code>#22896</code>.",
          "target": "需要安装一个或多个必需或推荐的插件,更新或启用。",
          "glossaries": {
            "22896": "启用",
            "9687": "更新"
          }
        },
        "Please contact the administrator of this site for help.": {
          "source": "Please contact the administrator of this <code>#43063</code> for help.",
          "target": "请联系此站点的管理员寻求帮助。",
          "glossaries": {
            "43063": "站点"
          }
        },
        "This plugin needs to be updated to be compatible with your theme.": {
          "source": "This <code>#43249</code> needs to be updated to be compatible with <code>#16195</code> <code>#56116</code>.",
          "target": "此插件需要更新以与您的主题兼容。",
          "glossaries": {
            "43249": "插件",
            "56116": "主题",
            "16195": "您的"
          }
        },
        "The remote plugin package does not contain a folder with the desired slug and renaming did not work.": {
          "source": "The remote <code>#48813</code> package does not contain a folder with the desired <code>#54859</code> and renaming did not work.",
          "target": "远程插件包不包含具有所需别名的文件夹,重命名不起作用。",
          "glossaries": {
            "48813": "插件",
            "54859": "别名"
          }
        }
      }

      目前看都能比较好的纠正术语。

      目前还差自动从记忆库筛选准确的翻译建议数据这一机制,应该明天可以解决。

      之后会封装一个“预翻译”的功能按钮,暂时仅供翻译管理员使用,需要经过一段时间的测试和调优后才能批量应用到整个仓库上。

      按目前的进度看,本周应该是可以完成这一块的工作的。

  • 倡萌
    管理员

    非常棒!采用机器翻译填充可以大大加快翻译进度!

    我想知道“预翻译”点击以后,是否可以批量应用于该项目所有未翻译字段。

    • 孙锡源
      楼主

      这个预翻译设想中就是以项目为单位的,不是以每个原文为单位,点击后的效果就是你说的“批量应用于该项目所有未翻译的字段”。

      此外,因为目前在产品层面规划的是所有与翻译相关的模块都是依赖的 GlotPress(比如官方文档和应用市场的插件、主题的介绍),所以所有的翻译也都可以使用这个预翻译特性。

      • 倡萌
        管理员

        回复 @ 孙锡源:对于在 GlotPress 翻译文档,这个有点不理解,我担心的是文档里面的结构和链接,因为官方文档都是一个个系列的,层次结构有些复杂。

        我们这个机制是采集发布了文档,然后通过 GlotPress 翻译好以后将同步到我们平台的文档中?

        • 孙锡源
          楼主

          回复 @ 倡萌:这个我尝试详细介绍一下目前的想法。

          问题一:官方文档层次结构复杂,不好关联

          这个可以通过一个 Post Meta 字段,在每篇文档中指定该文档所关联的翻译项目,同时可以按文档目录拼接命名来避免项目名重复的问题,比如说:开发文档_REST-API_介绍

          问题二:翻译的运作的机制

          这个设想中就和应用市场的插件、主题自述文件的翻译是一样的。

          目前开发了一个全局的 i18n 库,WordPress 官方的 i18n 库是以 mo 文件为索引目标的,但是 litepress.cn 中的这个 i18n 库是以翻译平台中的项目为索引目标。

          也就是说可以在整个平台的任意地方调用翻译平台的翻译数据,我举个例子:

          比如一篇文档来说,他有一个段落:hello word。这个时候在代码上可以写:i18n::translate( '翻译平台的项目名', 'hello word' );,这时候 i18n 库就会自动去翻译平台在这个项目下搜 hello word 的译文再返回回来。

          了解了这个机制后后面应该就清晰明了了。我们只需要在文档输出时给原文加一个过滤器,把每个段落的原文都去调用 i18n 库查以下译文,之后把存在译文的段落替换掉原文输出。

          也就是说,其实不存在“通过 GlotPress 翻译好以后将同步到我们平台的文档中”这个概念,因为翻译是实时调用的,文档平台中存储的始终只有英文原文,翻译只存在于翻译平台中。

          问题三:翻译采集的流程

          大概是这样的:机器采集后将原文入文档平台,之后文档平台会通过异步队列将创建翻译项目的请求提交给翻译平台(其中包含了项目名、原文数据等),翻译平台收到请求后就创建项目,而因为创建请求是文档平台提起 ,所以文档平台就可以通过自己掌握的数据,按前面说的使用一个 Post Meta 字段来与翻译平台的这个项目联动了。

          效果

          设想中,这一套机制,可以实现按块更新、文档中点击翻译、翻译效果实时预览。

          按块更新

          这是说的,当官方文档的原文存在更新时,我们只需要把新的原文无脑的入文档平台即可,这时候文档平台再去翻译平台请求更新新的原文,对于没变过的段落,翻译平台会自动跳过,对于变过的字段翻译平台会自动采用新的(这就是一般的导入原文操作,不需要特别开发)。这个时候对于文档平台来说,它在输出时那些没更新过的段落,依然可以从翻译平台调取到翻译数据,而更新过的则没有了。

          这一切呈现给译者的就是:哪个段落更新了,哪个段落的译文就消失了,需要重新在文档上点击翻译,不过仅仅是翻译这个段落,不需要像传统方式那样重译整篇文章。

          文档中点击翻译

          因为翻译是由 GlotPress 管理的,所以只需要提供一个外部 API,让用户可以通过 API 贡献翻译即可(已经有了,是wordpress.com 开发的)。也就说,虽然翻译是在 GlotPress 中的,但是译者可以在文档中点击某个段落,唤起一个窗口,这个窗口会自动通过 API 与翻译平台联动。

          此时在从译者的角度看,他就是在文档上直接点击某个段落贡献翻译了,可以在完全参考上下文的基础上给出最佳翻译。

          翻译效果实时预览

          这个的实现其实就是依赖于前面说的翻译调用机制(通过 litepress.cn 的 i18n 的模块而不是把译文直接写在文档里)。

          对于普通用户,文档平台会为他们调用“当前”翻译。

          对于译者,则会调用“当前”翻译+机器生成的模糊的翻译+由这个译者提交的“等待”翻译。

          此时站在译者角度看,他就是随时贡献随时可以查看效果了,同时也可以参照机器生成的模糊翻译。

          当然,我们面临的始终不是一个译者,而可能是多个人合作一个项目,这个时候这一套机制的优势就能体现出来了:我们可以在前端为每个译者输出他自己的翻译的同时在 GlotPress 上从多个译者提交的翻译版本中选出最优的设置为 “当前”翻译,以交付给普通用户。

          结尾

          其实我觉得这一些机制,比较好的体现了我之前一直说的“成体系”,这样可以很好的进行多模块联动以提供意想不到的效果,这一些基础设施奠定了我们与其他尝试做“中国社区”、“中国市场”的人的不同,他们只是搭建了一个网站,而不是一个成体系的平台,所谓的画皮不画骨。

          当然这里只是举了其中一个应用例子,还有我们之前探讨的翻译贡献自动得优惠券这应该也是一个多模块联动的应用例子。

          此外,这个规划是很早之前想的,不是一定不变的“确定方案”,所以有觉得不妥的地方可以再探讨。

        • 倡萌
          管理员

          回复 @ 孙锡源:很棒的思路,同时佩服你们的技术和执行力!

        • 孙锡源
          楼主

          回复 @ 倡萌:愧不敢当欸,就技术来讲,这些仔细想想其实都没啥技术含量,国内任何一个团队想做的话也都能做。

          我个人愿意一直在这上面投入精力,主要是感觉人的生命并没有什么意义,现在所恐惧和所爱慕的,都会随着死亡的到来而消逝,在宇宙的尺度看,我如蜉蝣一般的朝生暮死。

          我所能追求的仅仅是在有生之年能像毛主席所说的:“做个奇男子”,潇潇洒洒的好好体验这短暂的生命,按自己的想法去创造,去做自己认为有意义的事情,而不是终日受困于某些体制与规则,以至于蹉跎一生,至死时再嗟叹不已。

          这要求我在年轻时在人类社会中必须达到一定的高度,否则我必然会被社会机器卷入其中,作为一个螺丝钉不留痕迹地了却此生。这就好像:小孩子努力考大学,大学毕业了找个好工作,然后买房、结婚生子,然后再让自己的孩子在这一套体制下继续这一切,而自己则开始等待死亡的到来,周而复始,一代又一代。

          而想要在年轻时达到一定的高度,就一定不能贪恋于金钱,金钱在这一时期的属性只能是“生活保障品”,拿时间去兑换其他资源会比金钱的回报率更大。所以我最初做了这个项目,这个项目会作为我人生的跳板中的一个,经过一个又一个跳板的加速后,我最终会得到我想要的,但是唯一不确定的是——这究竟需要多久?

  • 正在查看 1 条回复
    • 哎呀,回复话题必需登录。