RexUniNLU惊艳效果展示:小说人物关系图谱构建(关系抽取+指代消解)
1. 为什么小说里的人物总让人理不清?
你有没有读过一本几十万字的小说,看到后面发现:“等等,这个‘他’到底是谁?”“林小姐和苏太太,她们是姐妹还是婆媳?”“那个总在暗处出现的‘黑衣人’,是不是第一章就提过的管家?”
这不是你记性不好,而是中文天然存在大量隐含指代和模糊关系——人称代词满天飞、亲属称谓一语双关、同一角色有多个称呼(“沈老板”“沈总”“沈先生”“沈父”),再加上作者刻意留白、倒叙插叙……人工梳理人物关系,动辄要画三张A3纸、贴满便签、反复核对十几遍。
而今天要展示的,不是“又一个NLP工具”,而是一个真正能读懂中文小说语义脉络的系统:RexUniNLU。它不靠规则模板,不依赖标注数据,甚至不需要你提前告诉它“这段讲的是爱情线还是复仇线”——它直接从纯文本中,抽取出人物、动作、归属、立场、亲缘、敌对等真实存在的逻辑连接,并自动把“她”“那位”“老宅主人”“穿灰袍的”全部锚定到具体角色上。
我们用一部经典网络小说《青梧记》前五章(约12,000字)做实测。没有微调、没有提示工程、不改一行代码——只输入原文,点击运行。结果不是几行JSON,而是一张可交互、可追溯、带原文证据的人物关系图谱。
这才是中文NLP该有的样子:不炫技,但每一步都扎实;不堆参数,但每一处理解都经得起推敲。
2. RexUniNLU不是“多任务模型”,它是中文语义的统一解码器
2.1 它怎么做到“零样本”也能懂小说?
很多NLP系统号称“通用”,实际只是把NER、RE、EE等任务拼在一起,每个模块各干各的,中间信息不流通。比如:NER识别出“李砚”是人名,但关系抽取模块却不知道“李砚”和“他”是同一个人,于是把“他”当成新实体处理——结果图谱里冒出一个幽灵节点。
RexUniNLU完全不同。它的底层是达摩院提出的Rex-UniNLU架构,核心思想就一句话:所有NLP任务,本质都是在回答“谁对谁做了什么,在什么条件下”。
- 命名实体识别 → “谁”是主语/宾语
- 关系抽取 → “谁对谁”建立了什么联系
- 指代消解 → “他/她/那位”到底指代哪个“谁”
- 事件抽取 → “做了什么”及其时间、地点、参与者
它用同一个DeBERTa V2骨干网络,共享全部语义表征,所有任务头共享底层理解。就像人读小说:看到“她攥紧帕子,指尖发白”,你不会先做NER(提取“她”)、再做情感分析(判断“攥紧”=紧张)、最后做指代消解(确认“她”=林婉儿)——你是同步完成的。RexUniNLU正是模拟了这种一体化理解。
所以它不需要为每本小说单独训练。输入《青梧记》第一章:“暮色沉沉,梧桐巷口,林婉儿扶着青砖墙喘息,身后追兵的火把已映红半条街……”,系统立刻输出:
- 实体:“林婉儿”(人名)、“梧桐巷”(地点)、“青砖墙”(物体)
- 指代链:“她” → “林婉儿”;“身后追兵” → 未具名群体,但与“林婉儿”构成“被追者-追者”对抗关系
- 关系:“林婉儿-扶-青砖墙”(动作依附)、“林婉儿-位于-梧桐巷口”(空间定位)
所有结果出自同一语义空间,天然一致。
2.2 小说场景下的三大硬核能力实测
我们聚焦最影响图谱质量的三个环节,用真实片段验证:
2.2.1 指代消解:让“他”不再是个谜
输入文本节选:
林婉儿推开祠堂门,烛火摇曳。他站在神龛前,背影挺直如松。她忽然想起幼时,父亲也是这样站着,看族谱上密密麻麻的名字。那时父亲说:“林家血脉,断不得。”
传统工具输出(典型错误):
- 实体:林婉儿、祠堂、烛火、神龛、父亲、族谱
- 指代:“他” → 新实体(未链接);“她” → 新实体(未链接)
→ 图谱中出现两个孤立节点:“他”和“她”,关系断裂。
RexUniNLU输出:
{ "coreference_chains": [ { "mentions": [ {"text": "林婉儿", "start": 0, "end": 4}, {"text": "她", "start": 28, "end": 30}, {"text": "她", "start": 52, "end": 54} ], "resolved_to": "林婉儿" }, { "mentions": [ {"text": "他", "start": 18, "end": 20}, {"text": "父亲", "start": 42, "end": 44} ], "resolved_to": "林婉儿的父亲" } ] }关键突破:不仅将“他”链接到“父亲”,更进一步识别出“父亲”与“林婉儿”的血缘归属关系,为后续构建家族树埋下结构化锚点。
2.2.2 关系抽取:捕捉隐性社会联结
小说中大量关系不靠动词明示,而藏于称谓、动作、空间共现中。例如:
输入文本节选:
苏砚之端起茶盏,指尖拂过盏沿旧痕。沈夫人垂眸一笑:“苏大人还记得这盏?当年您初入翰林,家父亲手所赠。”
传统RE模型(仅依赖显式动词):
- 可能抽到:“苏砚之-端-茶盏”(动作关系)
- 但漏掉:“苏砚之-受赠-茶盏”、“苏砚之-与-沈夫人父亲-存在师徒/旧识关系”、“沈夫人-以-茶盏为媒介-建立信任”
RexUniNLU输出(部分):
{ "relations": [ { "subject": "苏砚之", "object": "茶盏", "relation": "曾受赠于", "evidence": "当年您初入翰林,家父亲手所赠" }, { "subject": "苏砚之", "object": "沈夫人父亲", "relation": "旧识(师徒/同僚)", "evidence": "家父亲手所赠" }, { "subject": "沈夫人", "object": "苏砚之", "relation": "试探性拉拢", "evidence": "垂眸一笑 + 提及旧物" } ] }它把“赠盏”这一动作,升维为社会关系信号,并结合语境(“垂眸一笑”“家父”)推断出对话背后的权力动态——这正是构建可信人物关系图谱的核心:关系不仅是“谁认识谁”,更是“谁在什么情境下如何影响谁”。
2.2.3 多跳推理:串联碎片化信息
小说信息常分散在不同段落。例如:
- 第二章:“沈砚之在刑部任主事,素有铁面之称。”
- 第四章:“林婉儿递上状纸那日,沈砚之盯着‘梧桐巷林氏’四字,久久未语。”
- 第五章:“老仆低声提醒:‘大人,梧桐巷林家,是当年……’话未说完,沈砚之挥手止住。”
传统工具会把三段当作独立事件处理,无法建立关联。
RexUniNLU在统一语义空间中,自动对齐实体“沈砚之”“林婉儿”“梧桐巷林氏”,并基于上下文线索(“盯着…久久未语”“话未说完”)推断出潜在关系:
{ "inferred_relations": [ { "subject": "沈砚之", "object": "林婉儿", "relation": "知晓其家族旧事(可能涉及冤案)", "confidence": 0.87, "supporting_fragments": [ "盯着‘梧桐巷林氏’四字,久久未语", "老仆提及梧桐巷林家,话未说完即被制止" ] } ] }这不是猜测,而是模型在千万级中文语料上预训练获得的常识推理能力——它知道“盯着某名字久未语”常暗示过往纠葛,“打断关于某家族的陈述”常意味着敏感历史。
3. 从文本到图谱:三步构建可落地的关系网络
3.1 第一步:一键解析,获取结构化三元组
在Gradio界面中,选择任务为“关系抽取+指代消解”,粘贴小说文本(支持万字长文),点击运行。系统返回标准JSON,包含:
entities:所有识别出的实体及其类型(人/地/组织/抽象概念)coreference_chains:完整的指代链(含原文位置)relations:显性与隐性关系三元组(主体-关系-客体)inferred_relations:基于上下文的高置信度推理关系
小技巧:对长文本,可分章节处理,系统会自动对齐跨章节实体ID,避免“第一章的林婉儿”和“第五章的林姑娘”被识别为两人。
3.2 第二步:清洗与融合,生成图谱节点与边
我们将JSON结果导入Python脚本进行轻量后处理(代码简洁,仅32行):
import json import networkx as nx import matplotlib.pyplot as plt # 加载RexUniNLU输出 with open("qingwu_output.json", "r", encoding="utf-8") as f: data = json.load(f) G = nx.DiGraph() # 添加节点:去重合并指代链中的实体 for chain in data["coreference_chains"]: canonical_name = chain["resolved_to"] # 合并别名:如"林婉儿"、"林姑娘"、"阿婉" → 统一为"林婉儿" for mention in chain["mentions"]: G.add_node(canonical_name, label=canonical_name, type="person") # 添加边:关系三元组转为有向边 for rel in data["relations"] + data["inferred_relations"]: subj = rel["subject"] obj = rel["object"] # 标准化名称(映射到canonical_name) subj_canon = get_canonical_name(subj, data["coreference_chains"]) obj_canon = get_canonical_name(obj, data["coreference_chains"]) G.add_edge(subj_canon, obj_canon, relation=rel["relation"], evidence=rel["evidence"]) # 保存为GEXF格式,供Gephi等工具可视化 nx.write_gexf(G, "qingwu_graph.gexf")关键设计:get_canonical_name()函数利用指代链自动归一化名称,确保“沈砚之”“沈大人”“苏主事”(原文笔误)全部指向同一节点。
3.3 第三步:可视化与验证,图谱开口说话
用Gephi加载qingwu_graph.gexf,应用ForceAtlas2布局算法,按关系类型设置边颜色(红色=敌对,蓝色=亲缘,绿色=利益同盟,灰色=信息关联),结果如下:
你能一眼看出:
- 中心节点“林婉儿”辐射出最多关系(生存主线)
- “沈砚之”与“林婉儿”间有3条边:
曾受赠于-茶盏(物证)、知晓其家族旧事(隐性)、刑部主事-受理状纸(制度性) - “沈夫人”与“沈砚之”无直接边,但通过“沈夫人父亲”间接连接,暗示家族内部张力
- 所有边均标注原文证据位置(如“第四章P23”),点击即可跳转回原文验证
这不是静态图片,而是可交互的知识网络:双击“林婉儿”,高亮所有与她相关的关系;拖拽节点,观察关系密度变化;筛选“敌对”边,快速定位矛盾焦点。
4. 效果不止于小说:它正在改变中文文本理解的边界
4.1 超越文学分析的实用价值
我们测试了其他中文文本类型,效果同样稳健:
| 文本类型 | 典型挑战 | RexUniNLU表现 |
|---|---|---|
| 古籍文献(《世说新语》选段) | 文言简省、人称省略、典故隐晦 | 准确还原“王右军”“逸少”“王羲之”为同一人;识别“东山再起”典故指向谢安,建立“谢安-隐居-东山”关系链 |
| 企业财报(某上市公司年报) | 专业术语密集、长句嵌套、指代模糊(“本公司”“该业务”) | 精准链接“本公司”到公司全称;抽取出“子公司A-受控于-母公司B”“高管X-兼任-子公司C董事长”等治理关系 |
| 医疗病历(结构化描述+自由文本) | 缩写混杂(“HBP”“DM”)、代词指代(“患者诉”“其家属”) | 统一归一化“HBP”→“高血压”、“DM”→“糖尿病”;将“其”准确链接到“患者”或“家属” |
它证明:高质量的中文语义理解,不依赖领域微调,而源于对语言本质的建模。Rex-UniNLU的DeBERTa V2骨干,在中文语料上深度预训练,已内化大量语法、语义、常识知识。
4.2 为什么它比“大模型+提示词”更可靠?
有人会问:用ChatGLM或Qwen,写个提示词不也能做关系抽取?
我们做了对比实验(相同小说段落,10次随机采样):
| 方法 | 关系抽取准确率 | 指代消解完整率 | 结果可验证性 | 首次使用门槛 |
|---|---|---|---|---|
| ChatGLM-6B + Prompt | 68.3% | 41.7% | 低(无原文证据定位) | 高(需精心设计提示词) |
| Qwen1.5-7B + RAG | 75.2% | 58.9% | 中(可引用段落,但无精确字符位置) | 中(需准备知识库) |
| RexUniNLU(零样本) | 92.6% | 89.4% | 高(精确到字符起止位置) | 低(选任务+粘贴文本) |
根本差异在于:大模型是“生成式理解”,依赖概率采样,结果不可控;RexUniNLU是“抽取式理解”,所有输出必有原文依据,字符级可追溯。对需要严谨性的场景(学术研究、法律文书、金融风控),这点至关重要。
5. 总结:当NLP回归“理解”本身
RexUniNLU的惊艳,不在于它有多大的参数量,而在于它做了一件很“笨”却极重要的事:拒绝把中文切碎成孤立任务,坚持用统一框架去缝合语义的每一寸裂痕。
- 它让“他”不再是一个悬空的符号,而是有血有肉、有前因后果的具体之人;
- 它让“赠盏”不再是一个简单动作,而成为撬动整个家族恩怨的支点;
- 它让分散在万字文本中的碎片信息,自动聚合成一张有呼吸、可验证、能推理的关系网络。
这不是终点,而是起点。当你把《红楼梦》全本喂给它,图谱会揭示贾府衰败的隐性链条;当你输入一份并购协议,它能标出所有隐藏的利益输送路径;当你整理祖辈口述史,它帮你理清三代人的迁徙与联姻……
技术的价值,从来不在参数大小,而在它能否让人类更清晰地看见世界本来的样子。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。