大模型翻译能力评测
1. 背景介绍
随着自然语言处理技术的飞速发展,机器翻译已经成为一个重要的研究领域。近年来,基于大模型的语言模型在机器翻译任务上取得了显著的进展。这些大模型通常具有数亿甚至数千亿的参数,能够更好地理解和生成自然语言。
但是,现在市面上可用的大模型成百上千,每个模型又都有各自的功能特性和适用场景,我们应该如何评估不同模型的翻译效果呢?解决方案可能多种多样,本文尝试采用 WMT 数据集 + BLEU 评分的机制,来相对完善地评估几个大模型的翻译能力。
首先,简单补充一些基础知识:
WMT 数据集
WMT(Workshop on Machine Translation)数据集是一系列用于机器翻译的基准数据集,它由每年举办的WMT会议提供。WMT会议是机器翻译领域的重要国际会议,自2006年起每年举行,旨在推动机器翻译技术的发展。
WMT 数据集包含了多种语言对的翻译数据,这些数据通常来自于新闻文章、议会记录、书籍以及其他公开可用的文本资源。这些数据集被广泛用于训练、评估和比较不同的机器翻译系统。其中一些知名的语言对包括英语-法语、英语-德语、英语-西班牙语等。WMT 提供了比较权威的基准数据,可供我们来评估不同模型的翻译准确率。
BLEU 评分
BLEU(Bilingual Evaluation Understudy)评分是一种用于评估机器翻译输出质量的自动评价指标。 BLEU由IBM在2002年提出,目的是为了提供一个快速、客观且成本较低的方法来评估翻译系统的性能。BLEU评分已经成为机器翻译领域最广泛使用的评价标准之一。
BLEU 通过计算匹配度(Precision)、修饰(Modified)、几何平均、最终评分等流程,最终生成一个 [0,1] 范围内的 score,其中1表示完美的匹配,即机器翻译的输出与参考翻译完全一致。我们通过不同大模型之间评分的相对值,就可以评估出翻译能力的差异。
有了这些基础知识,我们就可以来实现具体的评测程序了。
下面的程序采用 LangChain 框架,以英译中场景为例,介绍翻译评测的具体实现流程。
2. 实现流程
加载语料数据集
首先安装 datasets 库:
pip install datasets
然后我们实现一个 DataSetLoader
,用于加载 WMT 的语料数据集。wmt19 这个仓库下就包含了英汉互译的数据集。 我们假定英文为原始语言,中文为目标翻译语言。
from datasets import load_dataset
class DataSetLoader:
"""数据集加载器"""
def __init__(self):
"""初始化方法"""
# 加载英译汉数据集
self.ds = load_dataset('wmt19', 'zh-en')
print("加载[en-zh]数据集完成")
def get_origin_content(self, idx: int) -> str:
"""获取原始内容"""
return self.ds['train'][idx]['translation']['en']
def get_ref_trans(self, idx: int) -> str:
"""获取参考翻译"""
return self.ds['train'][idx]['translation']['zh']
BLEU 评分计算
接下来,我们定义一个 BleuScoreCaculator
组件,用于计算 BLEU 分数。这里直接使用 nltk.translate 包即可(需要安装):
from nltk.translate.bleu_score import sentence_bleu
class BleuScoreCaculator:
"""BLEU分数计算器"""
@staticmethod
def calc_score(references, hypothesis) -> float:
"""计算BLEU分数"""
return sentence_bleu(references, hypothesis, weights=(1,))
分词处理
除此之外,为了避免不同分词规则所造成的影响,我们再开发一个分词组件,按照统一的规则,对文本进行分词。分词库采用应用广泛的 jieba 即可:
from typing import List
import jieba
class Tokenizer:
"""分词器"""
@staticmethod
def clean_and_tokenize(text: str) -> List[str]:
"""
清理文本并分词
:param text: 原始文本
:return: 分词列表
"""
# 去除多余空格和标点符号
trimmed = text.replace('\n', ' ').replace(' ', ' ').strip()
# 使用 jieba 进行分词
return list(jieba.cut(trimmed))
翻译评测
所有的基础组件已经准备就绪了,下面就可以开始完成核心的翻译评测功能。
我们采用 LangChain 框架,构造标准化的处理流程 Chain。采用一下三个候选模型:
- glm-4-plus
- gpt-4o
- qwen-32b
这三个都是当前业界功能非常强大的模型,那么他们的翻译能力到底孰优孰劣呢?我们写代码看一下:
import json
from typing import List, Dict, Any
import dotenv
from langchain_community.chat_models import ChatZhipuAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from bleu import BleuScoreCaculator
from loader import DataSetLoader
from tokenizer import Tokenizer
if __name__ == '__main__':
# 加载环境变量
dotenv.load_dotenv()
# 对比3个LLM: glm-4-plus、gpt-4o和qwen-32b
chat_glm_4_plus = ChatZhipuAI(model="glm-4-plus", temperature=0.1)
chat_gpt_4o = ChatOpenAI(model="gpt-4o", temperature=0.1)
chat_qwen_32b = ChatOpenAI(model="qwen-32b", temperature=0.1)
# 构造prompt
query = """
待翻译内容:
{content}
原始语言:
{origin_lang}
翻译成的目标语言:
{target_lang}
特别注意:直接生成翻译好的文本即可,无需任何额外信息!
"""
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个翻译专家,请根据用户需要翻译文本"),
("human", query)
])
prompt = prompt.partial(origin_lang="英语", target_lang="汉语")
# 构造Chain
glm_4_plus_chain = prompt | chat_glm_4_plus | StrOutputParser()
gpt_4o_chain = prompt | chat_gpt_4o | StrOutputParser()
qwen_32b_chain = prompt | chat_qwen_32b | StrOutputParser()
print("翻译评测开始\n\n")
# 创建数据集加载器
loader = DataSetLoader()
# 创建分词器
tokenizer = Tokenizer()
# 创建BLEU分数计算器
calculator = BleuScoreCaculator()
count = 20 # 评测20条数据,可以视具体情况调整
glm_4_plus_total_score: float = 0
gpt_4o_total_score: float = 0
qwen_32b_total_score: float = 0
result: List[Dict[str, Any]] = []
for i in range(count):
# 执行翻译
print(f"\n==========第{i + 1}组==========\n")
origin = loader.get_origin_content(i)
print(f"[原始内容]: {origin}\n")
ref_trans = loader.get_ref_trans(i)
print(f"[参考翻译]: {ref_trans}\n")
glm_4_plus_trans = glm_4_plus_chain.invoke({"content": origin})
print(f"[glm-4-plus 翻译结果]: {glm_4_plus_trans}\n")
gpt_4o_trans = gpt_4o_chain.invoke({"content": origin})
print(f"[gpt_4o 翻译结果]: {gpt_4o_trans}\n")
qwen_32b_trans = qwen_32b_chain.invoke({"content": origin})
print(f"[qwen-32b 翻译结果]: {qwen_32b_trans}\n")
# 分词处理
ref_tokens = tokenizer.clean_and_tokenize(ref_trans)
glm_4_plus_trans_tokens = tokenizer.clean_and_tokenize(glm_4_plus_trans)
gpt_4o_trans_tokens = tokenizer.clean_and_tokenize(gpt_4o_trans)
qwen_32b_trans_tokens = tokenizer.clean_and_tokenize(qwen_32b_trans)
# 计算BLEU分数
glm_4_plus_trans_score = calculator.calc_score([ref_tokens], glm_4_plus_trans_tokens)
print(f"[glm-4-plus BLEU分数]: {glm_4_plus_trans_score}\n")
gpt_4o_trans_score = calculator.calc_score([ref_tokens], gpt_4o_trans_tokens)
print(f"[gpt_4o BLEU分数]: {gpt_4o_trans_score}\n")
qwen_32b_trans_score = calculator.calc_score([ref_tokens], qwen_32b_trans_tokens)
print(f"[qwen-32b BLEU分数]: {qwen_32b_trans_score}\n")
glm_4_plus_total_score += glm_4_plus_trans_score
gpt_4o_total_score += gpt_4o_trans_score
qwen_32b_total_score += qwen_32b_trans_score
# 保存结果
single_result = {
"origin": origin,
"ref_trans": ref_trans,
"glm_4_plus_trans": glm_4_plus_trans,
"gpt_4o_trans": gpt_4o_trans,
"qwen_32b_trans": qwen_32b_trans,
"glm_4_plus_trans_score": glm_4_plus_trans_score,
"gpt_4o_trans_score": gpt_4o_trans_score,
"qwen_32b_trans_score": qwen_32b_trans_score,
}
result.append(single_result)
print(f"\n{json.dumps(result)}\n")
print("翻译评测完成\n\n")
# 保存结果
with open("./trans_result.json", "w") as f:
json.dump(result, f, ensure_ascii=False, indent=4)
print("[glm-4-plus BLEU平均分]: ", glm_4_plus_total_score / count)
print("[gpt-4o BLEU平均分]: ", gpt_4o_total_score / count)
print("[qwen-32b BLEU平均分]: ", qwen_32b_total_score / count)
3. 总结
我们测试了20条数据集,最终结果如下:
[glm-4-plus BLEU平均分]: 0.6133968696381211
[gpt-4o BLEU平均分]: 0.5818961018843368
[qwen-32b BLEU平均分]: 0.580947364126585
生成的结果 json 文件格式如下:
[{
"origin": "For geo-strategists, however, the year that naturally comes to mind, in both politics and economics, is 1989.",
"ref_trans": "然而,作为地域战略学家,无论是从政治意义还是从经济意义上,让我自然想到的年份是1989年。",
"glm_4_plus_trans": "对于地缘战略家来说,无论是在政治还是经济上,自然而然会想到的年份是1989年。",
"gpt_4o_trans": "对于地缘战略家来说,无论在政治还是经济方面,自然而然想到的年份是1989年。",
"qwen_32b_trans": "然而,对于地缘战略家来说,无论是政治还是经济,自然想到的一年是1989年。",
"glm_4_plus_trans_score": 0.5009848620501905,
"gpt_4o_trans_score": 0.42281285383122796,
"qwen_32b_trans_score": 0.528516067289035
}]
可以看出,针对中文翻译,这3个大模型的 BLEU 相差不大,而且都超过了 0.5,基本可以认为翻译质量较好,能够传达原文的基本意思,错误较少,流畅性较好。其中分数最高的是 glm-4-plus,大概率是因为智谱 AI 针对中文语料做了很多 fine-tuning 和优化的工作,因为在机器翻译领域,数据是非常重要的关键因素。
本文仅采用了20条数据进行评测,结果可能存在一些偏差,而且不同的测试数据也会对结果产生影响,可以结合特定业务场景调整参数。重要的是,这里提供了一种相对客观的评估方式,可以直观地评测不同大模型的翻译效果,可以作为业务应用和技术选型的有力依据。