PaddleNLP Distinct 文本多样性指标:从原理到源码级实践指南

发布时间:2026/9/24 1:20:24

PaddleNLP Distinct 文本多样性指标:从原理到源码级实践指南 人工智能大模型预训练微调LoRARLHF强化学习分布式训练【免费下载链接】PaddleNLPEasy-to-use and powerful LLM and SLM library with awesome model zoo.项目地址https://gitcode.com/gh_mirrors/pa/PaddleNLP点击查看免费下载本文聚焦 PaddleNLP 中用于评估生成文本多样性的Distinct指标先讲清去重 n-gram 占比的核心算法原理再逐段剖析 paddlenlp/metrics/distinct.py 的类实现与状态维护机制最后通过完整可运行的示例演示普通评估对象与paddle.metric.Metric两种接入方式。读完你既能独立计算对话、生成任务的多样性分数也能将Distinct无缝接入 PaddleNLP 训练与评估流程。一、为什么需要 Distinct衡量生成文本的多样性在文本生成对话、摘要、机器翻译任务中模型容易陷入安全但重复的输出——例如反复使用高频词汇和固定搭配。传统的 BLEU、ROUGE 等指标衡量的是与参考答案的重合度无法反映生成内容本身的多样性。Distinct正是为此设计的指标它通过统计生成文本中不同的 n-gram 数量占比来量化文本多样性不同 n-gram 数量越多说明文本越丰富、越不重复。从源码 docstring 可以看到该算法依据 Li 等人发表于 2016 年的论文A Diversity-Promoting Objective Function for Neural Conversation ModelsarXiv:1510.03055该工作首次将 Distinct-1 / Distinct-2 作为对话系统多样性评估的标准化指标引入此后被广泛沿用。Distinct定义于 paddlenlp/metrics/distinct.py对外通过 paddlenlp/metrics/init.py 的from .distinct import Distinct导出因此可直接from paddlenlp.metrics import Distinct使用。二、算法原理去重 n-gram 占比假设生成的候选句子以 token 列表表示Distinct的计算过程分为两步滑窗切分 n-gram从句子第一个 token 开始以步长 1 滑动窗口切出长度为n_size的连续 token 序列相邻 token 之间以空格连接成一个整体串计算去重占比用不同 n-gram 的种类数除以n-gram 总数得到最终分数。用源码中add_inst的逻辑表达即为score len(diff_ngram_set) / total_ngram_count分数取值范围为(0, 1]。分数越高文本中重复的 n-gram 越少多样性越好。默认n_size2即统计不同的 bigram 占比对应论文中的 Distinct-2当n_size1时即 Distinct-1不同的 unigram / 单词占比。以[The, cat, The, cat, on, the, mat]为例手工推导 Distinct-2 的计算过程如下滑窗位置bigram 内容0–1The cat1–2cat The2–3The cat重复3–4cat on4–5on the5–6the mat共 6 个 bigram去重后仅剩 5 个不同 bigramThe cat 出现了两次因此 Distinct 分数为5 / 6 ≈ 0.8333。这一结果与仓库中的单元测试 tests/metrics/test_distinct.py 断言的0.8333333333333334完全一致可作为你验证环境正确性的基准用例。三、源码级解析Distinct 类的设计与实现Distinct继承自paddle.metric.Metric位于 paddlenlp/metrics/distinct.py整个类体量很小但状态维护、增量更新、指标聚合的逻辑非常清晰适合作为自定义评估指标的参考模板。3.1 构造与内部状态def __init__(self, n_size2, trans_funcNone, namedistinct): super(Distinct, self).__init__() self._name name self.diff_ngram set() # 去重后的 n-gram 集合 self.count 0.0 # n-gram 总计数 self.n_size n_size self.trans_func trans_func类内部维护两个核心状态self.diff_ngram一个 Pythonset保存所有出现过的 n-gram 串利用集合天然去重的特性无需手动判重self.count累计的 n-gram 总数浮点数。通过集合大小 / 总计数的比值即可在任意时刻给出多样性分数且支持多条句子增量累加——这正是它能在评估循环中逐 batch 更新状态的原理。3.2 增量更新add_instdef add_inst(self, cand): for i in range(0, len(cand) - self.n_size 1): ngram .join(cand[i : (i self.n_size)]) self.count 1 self.diff_ngram.add(ngram)add_inst接收一条已经分词好的候选 token 列表cand用滑窗取出长度为n_size的连续 token以空格 .join拼成字符串作为 n-gram 的唯一标识这保证了不同 token 组合不会被误判为同一个 n-gram每取一个 n-gram 就把count加 1同时将其加入去重集合。滑窗循环边界为len(cand) - n_size 1保证句子长度不足n_size时不会产出任何 n-gram此时count保持为 0。3.3 批量接入updatedef update(self, output, *args): if isinstance(output, paddle.Tensor): output output.numpy() assert self.trans_func is not None, ( The update method requires user to provide trans_func when initializing Distinct. ) cand_list self.trans_func(output) for cand in cand_list: self.add_inst(cand)update是paddle.metric.Metric标准接口负责把模型输出喂给指标先将paddle.Tensor转为numpy.ndarray方便在纯 Python 层做后处理再调用用户提供的trans_func把网络输出转换为字符串列表的列表即多条已分词候选句最后逐条调用add_inst更新状态。值得注意的是update内部有硬性断言以 Metric 方式使用时必须提供trans_func否则直接抛异常。3.4 汇总、重置与命名accumulate()返回len(self.diff_ngram) / self.count即最终 Distinct 分数score()与accumulate()完全等价便于在普通对象场景下取分数reset()将diff_ngram重置为空集合、count归零用于开启新一轮评估name()返回指标名默认为distinct配合 Trainer / 日志系统展示指标名称。需要留意一个边界若从未调用add_inst或所有句子长度都小于n_sizecount为 0此时accumulate()会触发除零异常实际使用时应保证输入句子长度不小于n_size。四、参数详解Distinct(n_size2, trans_funcNone, namedistinct)的参数含义如下参数类型默认值说明n_sizeint2计算几元语法1 为 unigram、2 为 bigram越大越关注短语级多样性trans_funccallableNone将模型输出numpy 数组转换为字符串列表的列表的函数以paddle.metric.Metric方式使用时必填输入为 numpy 数组namestrdistinct指标实例名称出现在日志与评估报告中关于trans_func的约定它的输入是update传入的numpy.ndarray模型 logits输出必须是list[list[str]]形式——外层列表对应 batch 中的每条样本内层列表是这条样本已分词的 token 序列。trans_func的典型实现是对 logits 取argmax得到 token id再借助 Tokenizer 的convert_ids_to_tokens与convert_tokens_to_string还原出自然语言 token 列表。五、两种使用方式从快速验证到训练评估文档给出了两种接入方式均已在 paddlenlp/metrics/distinct.py 的 docstring 中提供可运行示例。5.1 方式一作为普通评估对象适合离线评测直接构造Distinct()逐条调用add_inst喂入已分词候选句最后调用score()取分数。from paddlenlp.metrics import Distinct distinct Distinct() cand [The, cat, The, cat, on, the, mat] # update the states distinct.add_inst(cand) print(distinct.score()) # 0.8333333333333334多条句子可以连续调用add_inst累加状态跨句合并统计去重 n-gram 占比评估完一轮后调用reset()清空状态即可开始下一轮。5.2 方式二作为 paddle.metric.Metric 实例适合嵌入训练 / 评估流程通过partial把 Tokenizer 绑定进trans_func模型输出的 logits 通过update批量喂入最后用accumulate()取指标值。需要先安装并准备bert-base-uncased分词器BertTokenizer.from_pretrained会从模型中心下载对应词表。import numpy as np from functools import partial import paddle from paddlenlp.transformers import BertTokenizer from paddlenlp.metrics import Distinct def trans_func(logits, tokenizer): Transform the network output logits to string list. # [batch_size, seq_len] token_ids np.argmax(logits, axis-1).tolist() cand_list [] for ids in token_ids: tokens tokenizer.convert_ids_to_tokens(ids) strings tokenizer.convert_tokens_to_string(tokens) cand_list.append(strings.split()) return cand_list paddle.seed(2021) tokenizer BertTokenizer.from_pretrained(bert-base-uncased) distinct Distinct(trans_funcpartial(trans_func, tokenizertokenizer)) batch_size, seq_len, vocab_size 4, 16, tokenizer.vocab_size logits paddle.rand([batch_size, seq_len, vocab_size]) distinct.update(logits.numpy()) print(distinct.accumulate()) # 1.0该示例在完全随机的 logits 上得到 1.0 的满分因为随机概率分布下 16 个位置的 token id 几乎不会出现重复的 bigram。在实际训练中将distinct.update放进评估循环、按 epoch 结束时reset()即可持续观测生成多样性。六、测试用例指标正确性的回归保障仓库在 tests/metrics/test_distinct.py 中提供了针对该指标的单元测试import unittest from paddlenlp.metrics import Distinct class TestDistinct(unittest.TestCase): def test_metrics(self): distinct Distinct() cand [The, cat, The, cat, on, the, mat] distinct.add_inst(cand) self.assertEqual(distinct.score(), 0.8333333333333334)该用例直接断言了第二节手工推导的 5/6 结果从普通对象调用 分数计算两个层面锁定了算法实现的正确性任何对滑窗边界或去重逻辑的误改都会被该用例捕获。这也是验证你自己环境中 PaddleNLP 安装正确性的最快途径运行python -m unittest tests.metrics.test_distinct或直接执行该文件即可。七、在 PaddleNLP 指标体系中的定位Distinct是 paddlenlp/metrics/init.py 统一导出的一组评估指标之一与它并列的还有BLEU机器翻译质量、Rouge1/Rouge2/RougeL摘要质量、Perplexity语言模型困惑度、MRR检索排序以及ChunkEvaluator、SpanEvaluator序列标注等。它们的共同点是均继承自paddle.metric.Metric遵循update → reset → accumulate/score的统一生命周期因此可以在同一套 Trainer 评估框架中自由组合。相比BLEU等需要参考答案的重合度指标Distinct是无参考的生成质量指标衡量的是生成内容本身的丰富度两者互补使用能更全面地刻画生成模型的表现。八、实践建议与注意事项n_size 的选择对话 / 开放生成通常报告 Distinct-1 与 Distinct-2 两个值分别反映词汇级与短语级多样性n_size越大对长距离重复的敏感度越高但对短句会因 n-gram 样本过少而失真。保证句子长度句子 token 数必须不小于n_size否则该句不产生任何 n-gram且全空输入会导致accumulate除零。分词一致性trans_func输出的 token 需与训练时 Tokenizer 的分词方式保持一致因为 n-gram 以空格拼接的 token 串为标识不同的分词粒度会直接影响去重结果。与 BLEU 的差异BLEU是带参考的匹配精度Distinct是无参考的多样性度量二者不能互相替代评估生成任务时应同时报告。通过本文你已掌握Distinct的算法本质、源码实现细节、参数语义与两种接入方式可以直接将其用于对话模型、生成模型的多样性质控或作为自定义 PaddleNLP 评估指标的实现范本。赞分享人工智能大模型预训练微调LoRARLHF强化学习分布式训练【免费下载链接】PaddleNLPEasy-to-use and powerful LLM and SLM library with awesome model zoo.项目地址https://gitcode.com/gh_mirrors/pa/PaddleNLP点击查看免费下载相关推荐PaddleNLP Funnel Transformer 模型实战指南从 API 参考到源码级原理解析PaddleNLP Funnel Transformer 模型实战指南从 API 参考到源码级原理解析 导读 Funnel Transformer 是 Pad人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLPPaddleNLP 文本生成评测指标 RougeL / RougeN 源码级解析从 LCS 算法到 DuReader 实战PaddleNLP 文本生成评测指标 RougeL / RougeN 源码级解析从 LCS 算法到 DuReader 实战 RougeRecall Orie人工智能大模型预训练微调LoRARLHF强化学习分布式训练模型推理服务推理引擎模型量化模型压缩本地部署NLP变分自编码器VAE实战指南从原理到多样化样本生成变分自编码器VAE实战指南从原理到多样化样本生成 变分自编码器VAE是深度学习领域中强大的生成模型能够学习数据分布并生成多样化的新样本。作为机器学习ye文档教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/24 1:20:24

从HK32F030到PY32F002A:国产M0+ MCU低成本迁移实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 1:20:24

提升降aigc率实用指南:高效规避AI生成内容风险的可行方法解析

每次找到心仪的外国文献,却被付费墙冷冷地挡在外面,是不是感觉科研的热情瞬间被浇灭?作为学生党,我太懂这种无力感了。但好消息是,通过几个合法且免费的“通道”和技巧,我们完全能实现“文献自由”。今天分…

2026/9/24 2:15:26

【C++三方组件】Google Test:C++单元测试的事实标准

【C三方组件】Google Test:C单元测试的事实标准 【摘要】:main 里手写 if 断言再肉眼比对输出的年代,被 TEST() 宏终结——Google Test 用「宏注册 自动发现 独立运行」把测试变成一等代码。How 实测 TEST/EXPECT/ASSERT 断言语义、TEST_F …

2026/9/24 2:15:26

ACA Easy Auth 双轨:不改代码接 Bearer 与收口

一句话摘要:Azure Container Apps 用 Entra Easy Auth 做网关验签,调用方先加 Bearer、保留旧头;不改业务代码则双轨期匿名也会通。 目录 前言 一、先做决策:双轨还是立刻 Return401 二、架构:验签在 sidecar,业务容器不验 JWT 三、只读盘点与对接命令

2026/9/24 2:15:26

快消统仓统配系统怎么选?多品牌仓配整合要点

统仓共配指多货主共用仓库、共用运力、共用数据系统的集约化履约模式,本质是一次供应链模式重构,软件只是承载模式的工具。本文面向区域大商与经销商经营者、供应链及仓配管理者,提供四样内容:一套可落地的选型维度、多品牌仓配整…

2026/9/24 2:15:26

AI辅助科研:赋能学术创新与效率提升的新路径解析

每次找到心仪的外国文献,却被付费墙冷冷地挡在外面,是不是感觉科研的热情瞬间被浇灭?作为学生党,我太懂这种无力感了。但好消息是,通过几个合法且免费的“通道”和技巧,我们完全能实现“文献自由”。今天分…

2026/9/23 12:07:00

GAMP 5 基于风险的计算机化系统验证:软件分类与审计追踪实践

简介:《A Risk-Based Approach to Compliant GxP Computerized Systems》即业内熟知的GAMP 5指南,面向制药企业质量与IT合规人员、验证工程师及计算机化系统管理者,用于解决GxP法规环境下系统合规性难以科学落地的问题。文档以风险管理为主线…

2026/9/23 12:06:55

安全托管MSSP实战:从静态防御到人机协同的攻防运营与应急响应

简介:这份PPT围绕互联网业务安全托管服务展开,面向企业安全负责人、IT运维人员及关注MSSP/MSS选型的读者,重点回应传统安全过度依赖人工、碎片化静态防御难以对抗产业化攻击等痛点。资源共1个pptx文件,包体约30.63MB,以…

2026/9/24 0:00:21

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为…

2026/9/24 0:00:21

单细胞注释实战:基于Scanpy的标记基因与参考映射流程解析

简介:一份基于单细胞RNA测序数据的细胞类型注释算法研究Python毕业设计源码,针对计算机相关专业正在做毕设或需要项目实战的学习者,可用于课程设计与期末大作业。项目代码完整、经导师指导评审通过,可直接运行,覆盖数据…

2026/9/24 0:00:21

C#源生成器实战:用增量生成器替代反射,告别AOT崩溃

第一次在项目里被反射卡住,是在一个老旧的WinForms模块里:几十个类依赖PropertyChanged通知,运行时反射读属性、发通知,每次启动慢半拍不说,一上.NET Native/AOT裁剪模式几乎全面崩盘。后来我把这段逻辑全部改成C#源生…

2026/9/22 16:34:32

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/22 20:01:30

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/22 13:25:41

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码