最近在github上看到了一个项目,是小牛翻译开源的文言文-现代文平行语料,一共有967257个句对,地址在下面:
https://github.com/NiuTrans/Classical-Modern
于是我突发奇想,何不用它来训练一个文言文-现代文互相翻译的模型呢?
效果演示
来看看最终的翻译效果,先看一句舔狗经典语录:
现代文:
昨天在工地扛沙袋,我一下子扛了三袋,工友们问我为什么这么能扛?我眼泪瞬间就下来了,是啊,为什么我这么能扛,就是扛不住想你。
翻译成文言文:
昨于工地荷沙囊,余忽肩三囊,工友问何以如此?吾泣须臾而下,为也,何吾之能负,负之不胜念。
再来看一下朱自清《背影》中经典的一段话:
现代文:
他往车外看了看,说:“我买几个橘子去。你就在此地,不要走动。”我看那边月台的栅栏外有几个卖东西的等着顾客。走到那边月台,须穿过铁道,须跳下去又爬上去。父亲是一个胖子,走过去自然要费事些。我本来要去的,他不肯,只好让他去。我看见他戴着黑布小帽,穿着黑布大马褂,深青布棉袍,蹒跚地走到铁道边,慢慢探身下去,尚不大难。可是他穿过铁道,要爬上那边月台,就不容易了。他用两手攀着上面,两脚再向上缩;他肥胖的身子向左微倾,显出努力的样子。这时我看见他的背影,我的泪很快地流下来了。
翻译成文言文:
车外顾曰:买橘数枚去,君在此,勿动也。余视其月台栅外有卖物数人待客。至其边月台,须穿铁道,须跳下复上。父为肥子,行自费。吾本将之,不肯,故许之。见著乌布小帽,乌布大马皂,深青布袍,乃至铁道侧,徐探其身,尚不难。然穿铁道,欲上其月台,未易也。以两手攀之,两足复上缩,肥身左微倾,有足力状。见其背影,余泪遽下。
可以看出效果还是非常不错的,而文言文翻译成现代文的效果也非常不错。
也来看个例子,节选自陶渊明的《桃花源记》:
文言文:
晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。
林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。
翻译成现代文:
晋太元年间,武陵人捕鱼为生。沿着溪水行走,忘记了路途的远近。忽然遇到桃花林,两岸数百步,其中没有杂树,芳草鲜美,落花缤纷。打鱼人觉得很奇怪,又往前走,想探寻那树林。
树林尽头水源,就见到一座山,山有小口,仿佛有光。就舍弃船,从洞口进去,起初非常狭窄,才通人,又走了几十步,豁然开朗。土地平旷,房屋庄严,有良田、美池、桑竹之类。田间小路相通,鸡犬相闻,其中往来种作,男女衣着,都和外面的人一样,黄发小孩,都怡然自得。
这下广大中学生语文再也不用愁了。可惜我当年咋就没这好东西呢,不然语文也不会考那么差。
训练方法
训练方法非常简单,正好之前写过一个聊天机器人的训练教程,这次可以拿来直接用:
https://godweiyang.com/2021/07/24/chatbot
训练代码在下面:
https://github.com/godweiyang/chatbot
和训练聊天机器人唯一的不同就是训练数据,这里需要处理一下文言文-现代文语料,将其拆分成训练集和验证集,这里我写了个简单的脚本拆分整合了一下。
import os
trgs = os.listdir("Classical-Modern/target")
f3 = open("data/train/train.src", "w")
f4 = open("data/train/train.trg", "w")
f5 = open("data/dev/dev.src", "w")
f6 = open("data/dev/dev.trg", "w")
cnt1 = 0
cnt2 = 0
for trg in trgs:
src = trg[:-2]
f1 = open(f"Classical-Modern/source/{src}", "r")
f2 = open(f"Classical-Modern/target/{trg}", "r")
for line in f1:
if cnt1 < 3000:
f5.write(line.strip() + "\n")
else:
f3.write(line.strip() + "\n")
cnt1 += 1
for line in f2:
if cnt2 < 3000:
f6.write(line.strip() + "\n")
else:
f4.write(line.strip() + "\n")
cnt2 += 1
f1.close()
f2.close()
print(cnt1)
f3.close()
f4.close()
f5.close()
f6.close()
然后就可以直接用和训练聊天机器人相同的方法训练了,这里不再赘述,我在8张A100显卡上训练了短短一两个小时效果就已经很不错了。