- 人工智能
- 大模型
- 微调
- 模型推理服务
【免费下载链接】PaddleFormers
PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.
导读
本文围绕 PaddleFormers 仓库中modules/text/language_model/slda_novel这一基于小说领域语料训练的主题模型模块展开,系统讲解 Sentence-LDA(SLDA)与 LDA 的核心区别、模块提供的两个推理 API 的用法与返回结构,并结合仓库源码剖析其「分词 → 句子切分 → 采样推理 → 主题分布输出」的完整调用链与底层采样实现(Metropolis-Hastings / Gibbs)。读完本文,你将掌握如何加载该 PaddleHub 模块推断一段小说文本的主题分布、查看每个主题的代表性关键词,并理解这些结果在源码层面是如何计算出来的。
一、模型概述:从 LDA 到 SLDA
主题模型(Topic Model)是一种以无监督学习方式对文档的隐含语义结构进行聚类的统计模型。其中 SLDA(Sentence-LDA)是主题模型的一种,它是对经典 LDA 主题模型的扩展:
- LDA假设每个单词对应一个主题(topic);
- SLDA假设每个句子对应一个主题。
这一粒度差异让 SLDA 更适合小说、新闻、网页等「以句子承载语义单元」的文本:同一句话中的多个词共享同一个主题标签,句子之间的主题可以不同,从而在保留主题连贯性的同时降低建模单元的数量、提升推理速度。
modules/text/language_model/slda_novel模块基于百度自建的小说领域数据集训练,属于 PaddleHub 的nlp/semantic_model类型模块(见 module.py 中的@moduleinfo声明)。该模块由第三方开发者 DesmonDay 贡献,版本号为 1.0.0。
在仓库中,与slda_novel同构的模块还有slda_news、slda_webpage、slda_weibo(分别位于 modules/text/language_model 下),它们共享同一套代码骨架,区别仅在于训练语料领域与模型文件不同。
二、安装与依赖
根据 README.md 的依赖声明,使用该模块需要满足:
paddlepaddle >= 1.8.2paddlehub >= 1.8.0
此外,由于模块默认使用hub.Module(name="lac")加载 LAC 分词器(见 tokenizer.py 与 module.py),实际运行时还需要能够加载 PaddleHub 的lac模块用于中文分词。
三、快速开始:推理一段小说的主题分布
模块对外提供两个核心 API:infer_doc_topic_distribution(推断文档主题分布)与show_topic_keywords(展示主题关键词)。以下代码示例完整继承自 README.md,可直接复制运行:
import paddlehub as hub slda_novel = hub.Module(name="slda_novel") topic_dist = slda_novel.infer_doc_topic_distribution("妈妈告诉女儿,今天爸爸过生日,放学后要早点回家一起庆祝") # [{'topic id': 222, 'distribution': 0.5}, {'topic id': 362, 'distribution': 0.5}] keywords = slda_novel.show_topic_keywords(topic_id=222) # {'回来': 0.044502306717752, # '回去': 0.036457065533017245, # '回家': 0.029136327306669554, # '明天': 0.028762575780517493, # '休息': 0.022904260192395567, # '晚上': 0.021970839714261954, # '时间': 0.020756626422891028, # '好好': 0.019726413882856498, # '电话': 0.017195445214734463, # '吃饭': 0.01521839547511471}从结果可以看到:
- 输入文档被推断出 2 个主题(topic id 222 与 362,各占 0.5 的概率分布);
- 主题 222 下的前 10 个关键词集中在「回家、回去、回来、吃饭、电话」等日常家庭生活语义上,与输入文本「爸爸过生日、放学回家庆祝」的语境高度吻合,直观体现了主题模型在小说语料上的语义聚类能力。
四、API 详解
4.1 infer_doc_topic_distribution(document)
用于推理出文档的主题分布。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| document | str | 输入文档(一段文本) |
返回
- results(list):包含主题分布下各个主题 ID 和对应的概率分布。其中,list 的基本元素为 dict,dict 的 key 为
topic id,value 为对应主题的distribution(概率)。
4.2 show_topic_keywords(topic_id, k=10)
用于展示出每个主题下对应的关键词,可配合推理主题分布的 API 使用。
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| topic_id | int | 主题 ID |
| k | int | 需要知道对应主题的前 k 个关键词,默认值为 10 |
返回
- results(dict):返回对应主题的前 k 个关键词,以及各个关键词在该主题下的出现概率。
4.3 边界与异常处理
从 module.py 的源码实现可以观察到两类边界行为:
- 空分词结果:若输入文档经分词后没有任何词命中词表(
tokens == []),infer_doc_topic_distribution直接返回空列表[]; - 主题 ID 越界:
show_topic_keywords会先校验0 <= topic_id < num_topics,越界时通过 logger 输出"%d is out of range!"错误日志;k会被截断为min(k, len(self.topic_words[topic_id])),避免索引越界。
五、源码级原理:一条从文本到主题分布的完整调用链
5.1 模块初始化
TopicModel(继承自hub.Module)在_initialize中完成以下加载动作(module.py):
- 将模型目录指向
novel/,配置文件名为slda.conf; - 构造
InferenceEngine(self.model_dir, self.conf_file)加载主题模型; - 加载
vocab_info.txt词表,并实例化LACTokenizer(依赖 lac 模块); - 从模型中读取词表、配置、每个主题下的词频列表
topic_words与主题词频总和topic_sum_table; - 对每个主题下的词按词频降序排序,供
show_topic_keywords直接取前 k 个。
需要说明的是,模块初始化时默认使用LACTokenizer(代码中保留了SimpleTokenizer的注释实现)。两者的差异见 tokenizer.py:
- SimpleTokenizer:基于词表的前向最大匹配(FMM)分词器,只能识别词表内词汇,代码注释明确指出它「仅用于主题模型 demo,不适用于真实业务场景」;
- LACTokenizer:调用 LAC 模块做词法分析(
lac.lexical_analysis(...)),再将分词结果统一转小写并仅保留命中词表的词,超出词表的词会被过滤(对应推理引擎中的 OOV 处理)。
5.2 句子切分与文档构建
infer_doc_topic_distribution内部将分词后的 token 列表按每 5 个 token 一组切分成多个「句子」(module.py),随后构造SLDADoc并交给推理引擎:
sent = [] for i in range(len(tokens)): sent.append(tokens[i]) if len(sent) % 5 == 0: sentences.append(sent) sent = [] if len(sent) > 0: sentences.append(sent)这正是 SLDA「以句子为建模单元」的体现:每个句组对应一个主题标签。SLDADoc继承自LDADoc,其数据结构定义在 document.py:
Token(topic, id):LDA 的基本存储单元(词);Sentence(topic, tokens):SLDA 的基本存储单元(句子及其所属主题);LDADoc/SLDADoc:推理结果的存储结构,维护topic_sum(单轮采样各主题计数)与accum_topic_sum(多轮累计计数)。
5.3 推理引擎与采样器
InferenceEngine.infer(inference_engine.py)完成随机种子固定、文档初始化与迭代采样:
- 支持两种采样器类型:
GibbsSampling(Gibbs 采样)与MetropolisHastings(MH 采样),默认使用 MH 采样(SamplerType.MetropolisHastings); - 对 SLDA 文档执行
slda_infer(doc, 20, 50):burn_in_iter = 20,total_iter = 50,即前 20 轮为预热期(burn-in)不累计,后 30 轮的结果累计到accum_topic_sum; - 最终通过
doc.sparse_topic_dist()得到稀疏格式的主题分布(默认按概率降序),返回形如{'topic id': 222, 'distribution': 0.5}的结果列表。
MH 采样器的实现细节位于 sampler.py:
- 在初始化阶段为每个词构造 Vose 别名表(alias table)以支持 O(1) 的按分布采样,并构造 β 先验的别名表;
- 对每个句子执行
__sample_sentence,迭代mh_steps = 2轮 MH 步骤,每一步分别通过「文档提议(doc proposal)」与「词提议(word proposal)」两个阶段提出新主题,并按接受率(proportion_new * proposal_old) / (proportion_old * proposal_new)决定接受或拒绝; __proportional_function对 SLDA 采用「句子主题计数 + α 先验」乘以「句子内每个词的 词-主题计数 + β」的乘积形式,体现了 SLDA 将整句绑定到单一主题的建模约束。
5.4 主题关键词的概率计算
show_topic_keywords返回的概率并不是词的多项分布参数,而是基于模型词频表的频率估计(module.py):
prob = self.topic_words[topic_id][i].count / (self.topic_sum_table[topic_id] + EPS) # EPS = 1e-8即「该词在该主题下的出现次数 / 该主题下所有词的出现总次数」(加 1e-8 防止除零),这解释了 README 示例中关键词概率均为小于 1 的频率值。
六、模型配置与文件结构
虽然模型文件(novel/目录下的词表、词-主题计数文件、slda.conf)不随仓库源码分发,但配置结构可以从 config.py 与 model.py 中完整还原:
ModelType
| 取值 | 含义 |
|---|---|
| LDA = 0 | 词粒度主题模型 |
| SLDA = 1 | 句子粒度主题模型(本模块类型) |
ModelConfig 字段
| 字段 | 说明 |
|---|---|
| type | 模型类型(LDA / SLDA) |
| num_topics | 主题数量 |
| alpha | 文档-主题 Dirichlet 先验参数 |
| beta | 主题-词 Dirichlet 先验参数 |
| word_topic_file | 词-主题计数模型文件名 |
| vocab_file | 词表文件名 |
TopicModel.load_model(model.py)会解析词表文件与词-主题计数文件:每一行形如term_id topic_id:count topic_id:count ...,程序按空格切分并校验 term_id、topic_id 的范围与计数的合法性,累加得到每个主题的总词频topic_sum,并按词组织成稀疏的word_topic字典结构;加载完成后会打印Model Info: #num_topics=... #vocab_size=... alpha=... beta=...日志。
七、使用限制与注意事项
- 推理型模块:从仓库结构看,该模块只提供推理能力(
infer_doc_topic_distribution/show_topic_keywords),不包含训练代码;模型为离线预训练产物,训练与原始实现可参考 Familia 开源项目(README 中给出的查看代码入口)。 - 分词依赖:默认分词依赖 PaddleHub 的 lac 模块,首次加载会自动下载;分词结果中不在模型词表内的词(OOV)会被过滤,因此输入文本若大量使用生僻词或领域外词汇,可能影响主题推断质量。
- 句子粒度语义:SLDA 假设每个句子对应一个主题,若输入文本极短或单句过长,主题分布会相应简化(模块以 5 个 token 为粒度组织句子单元)。
- 随机性:推理过程引入了随机采样,但
InferenceEngine在每次infer前调用fix_random_seed()固定随机种子,保证同一输入在相同环境下的推理结果可复现。 - 版本前提:README 声明的依赖版本(paddlepaddle >= 1.8.2、paddlehub >= 1.8.0)对应模块发布时的运行环境,实际使用时请结合当前 PaddlePaddle / PaddleHub 版本的兼容性进行安装验证。
八、延伸阅读
- 模块完整实现:module.py、inference_engine.py、sampler.py、document.py、model.py、tokenizer.py、config.py
- 同系列领域模块:slda_news、slda_webpage、slda_weibo
- 主题模型在语言模型中的其他实践,可参见 modules/text/language_model 目录下的 lda 系列模块
- 人工智能
- 大模型
- 微调
- 模型推理服务
【免费下载链接】PaddleFormers
PaddleFormers is an easy-to-use library of pre-trained large language model zoo based on PaddlePaddle.
相关推荐
如何用浏览器扩展打造高效Markdown阅读环境:终极配置指南
如何用浏览器扩展打造高效Markdown阅读环境:终极配置指南 在数字化阅读时代,你是否经常需要查看Markdown文档却不想安装复杂的编辑器?Markdown
人工智能大模型微调模型推理服务PaddleFormers 中 SLDA 网页主题模型模块:Sentence-LDA 原理、API 使用与源码解析
PaddleFormers 中 SLDA 网页主题模型模块:Sentence LDA 原理、API 使用与源码解析 本文围绕 PaddleFormers 仓库中
人工智能大模型微调模型推理服务终极B站抢票指南:免费开源工具biliTickerBuy完整使用教程
终极B站抢票指南:免费开源工具biliTickerBuy完整使用教程 还在为B站会员购热门漫展门票一票难求而烦恼吗?手动操作总是慢人一步,错失心仪的门票?bil
人工智能大模型微调模型推理服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考