ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于 Angel 参数服务器的分布式 LDA 主题模型:F+LDA 采样、分布式训练与实战配置

基于 Angel 参数服务器的分布式 LDA 主题模型:F+LDA 采样、分布式训练与实战配置 人工智能机器学习分布式训练图计算后端【免费下载链接】angelA Flexible and Powerful Parameter Server for large-scale machine learning项目地址https://gitcode.com/gh_mirrors/an/angel点击查看免费下载本文以 Angel 仓库中的 LDALatent Dirichlet Allocation主题模型实现为主线系统讲解 LDA 的贝叶斯生成过程、Collapsed Gibbs SamplingCGS与 FLDA 采样算法、C_w/C_d 两大计数矩阵在 Worker 与 PS 之间的划分与同步机制并结合仓库源码给出可复现的输入格式、参数配置、模型输出格式与训练/预测完整流程。读完本文你将掌握如何在 Angel 上完成一次从数据预处理、分布式训练到主题推断结果落盘的 LDA 全链路实践。1. LDA 模型与贝叶斯生成过程1.1 模型定义LDA 是一种广泛使用的主题模型技术本质是一个贝叶斯概率生成模型用于从文档集合中挖掘隐藏的主题模式常用于降维与文本分析。给定一个语料库C它由一组文档{D_1, ..., D_M}构成每个文档D_i由一组词构成D_i (t_1, t_2, ..., t_{N_i})。词是词汇表V的基本单元LDA 需要人为指定主题个数K。在 LDA 中每个文档被建模为K个隐主题上的随机混合分布θ_d每个主题被建模为V维词分布φ_k。1.2 生成过程LDA 对语料库中每个文档的生成过程建模先从狄利克雷分布Dir(α)中采样出一个K维主题分布θ_d其中α是狄利克雷分布的超参数向量对于文档d中的每个词t_dn先从多项分布Mult(θ_d)中采样出该词的主题z_dn再从多项分布Mult(φ_z_dn)中采样出单词w_dn ∈ V。可以看到LDA 将「文档—主题」与「主题—词」两层混合结构显式建模为概率分布训练的目标就是从观测到的词序列反推出这两组隐分布。1.3 推断目标若用Z {z_d}_{d1}^D表示所有词的主题分配用Φ [φ_1 ... φ_V]表示V × K的主题-词矩阵用Θ [θ_1 ... θ_D]表示所有文档主题分布构成的矩阵则 LDA 训练就是在给定观测变量Z词序列与超参数的条件下推断隐变量(Θ, Φ, Z)的后验分布。由于Θ、Φ与Dirichlet先验共轭可以解析地积分掉从而只需迭代地对每个词的主题z_dn进行采样——这正是 Gibbs Sampling 类方法的理论基础。2. 采样算法从 CGS 到 FLDA2.1 Collapsed Gibbs SamplingCGS求解 LDA 的常用推断技术是 Gibbs Sampling一种基于 MCMC 的后验采样方法。目前常见的 Gibbs 变体包括 Collapsed Gibbs SamplingCGS、SparseLDA、AliasLDA、FLDA、LightLDA 与 WarpLDA 等。Angel 团队通过实验与分析认为FLDA 最适合在 Angel 上进行 LDA 训练仓库中文文档 lda_on_angel.md 与英文文档 lda_on_angel_en.md 均明确记载了这一结论。利用分布间的共轭性质CGS 将Θ与Φ通过积分消去得到z_dn的封闭式条件概率p(z_dn k | t_dn w, Z_¬dn, C_¬dn) ∝ (C_wk^¬dn β) / (C_k^¬dn Vβ) · (C_dk^¬dn α)其中C_wk表示词w被分配到主题k的次数主题-词计数矩阵C_wC_dk表示文档d中分配到主题k的词次数文档-主题计数矩阵C_dC_k表示主题k的总计数¬dn表示剔除当前词t_dn的计数α、β为超参数V为词汇表大小。2.2 FLDA稀疏性与 F 树FLDA 将上述条件概率分解为两部分C_dk · (C_wk β) / (C_k Vβ)α · (C_wk β) / (C_k Vβ)由于文档-主题矩阵C_d是稀疏的第一部分只需遍历其非零元素即可完成采样第二部分则借助F 树进行查找将复杂度降低到O(logK)。综合来看FLDA 的单次采样复杂度为O(K_d)其中K_d是文档-主题矩阵中非零元素的个数。相比朴素 CGS 的O(K)FLDA 通过「稀疏遍历 树结构加速」显著降低了采样开销这也是它在分布式环境下通信与计算开销可控的关键。2.3 源码印证Sampler 与 F 树实现在 Angel 仓库中F 树由 FTree.java 实现注释明确标注为Binary index tree内部维护float[] tree数组采用将长度补齐到 2 的幂后自底向上累加建树的方式支持O(logK)的区间查找与概率累加。采样器 Sampler.java 中持有FTree tree、psum、tidx、nk、wk等数组nk记录各主题的总计数wk记录当前词的主题计数在sample(PartitionKey, PartCSRResult)中对每个词的每个 token 调用buildFTree()重建当前词的 F 树再依据分解后的两部分概率完成主题采样最后以Int2IntOpenHashMap形式累积对C_w的更新。这些实现与文档中 FLDA 的算法描述完全对应。3. Angel 上的分布式训练框架3.1 矩阵划分策略LDA 训练中涉及两个较大的计数矩阵主题-词矩阵C_w与文档-主题矩阵C_d。Angel 的分布式策略如下架构图见 docs/img/lda_ps.pngC_d文档-主题矩阵划分到不同 Worker各 Worker 持有自己负责的文档及其主题计数采样计算在本地进行C_w主题-词矩阵划分到不同 PSParameter Server作为全局共享模型参数按分区partition分散存储在多个 PS 节点上。每一轮迭代中Worker 从 PS 上拉取自身需要的C_w分区用于主题采样迭代结束时将本轮对C_w的增量更新发回 PS 节点。这种「Worker 算、PS 存」的模式正是 Angel 参数服务器的核心范式。3.2 模型矩阵定义在 LDAModel.scala 中LDA 模型被定义为以下 PS 矩阵矩阵名常量行×列行类型说明word_topicWORD_TOPIC_MATV × KT_INT_SPARSE主题-词计数矩阵C_w即Φ的计数形式topicTOPIC_MAT1 × KT_LONG_DENSE各主题的总计数nk不保存到磁盘vocabularyVOCABULARY_MAT1 × taskNumT_INT_DENSE各任务上报的最大词 ID用于推导真实词汇表大小不保存其中word_topic的列数固定为K行数按分区动态确定训练任务会扫描全部文档的最大词 ID 并上报到vocabulary矩阵从而确定真实V见下文训练流程。从源码可以看到word_topic采用稀疏整型行正是为了压缩大规模词汇表下的存储与网络传输开销。3.3 训练链路的源码实现LDA 的完整训练链路为LDARunner → LDATrainTask → LDALearner → SamplerLDARunnerLDARunner.scalatrain()中依次调用startPSServer()启动 PS、loadModel(new LDAModel(conf))注册模型矩阵、runTask(classOf[LDATrainTask])提交训练任务、waitForCompletion()等待完成预测模式则走LDAPredictTask。Runner 同时负责设置输入格式BalanceInputFormat每个 Worker 仅 1 个 Task与 Worker/PS 的 JVM 堆内存/堆外内存参数。LDATrainTaskLDATrainTask.scala逐行解析文档通过calcuateVocabularyNum扫描所有文档的最大词 ID 并写回vocabulary矩阵从而校正真实词汇表大小V随后把文档流构建为 CSR 结构CSRTokens创建LDALearner并依次执行initialize()与train(epoch)最后按配置保存word_topic、doc_topic等输出。LDALearnerLDALearner.scala核心调度器。scheduleWithFetch通过 PSF 函数GetPartFunc按分区预取word_topic行采样完成后通过UpdatePartFunc回推增量并用tMat.increment更新主题总计数nkdocLLH与likelihood分别计算文档部分与词部分的 log-likelihood作为每轮迭代的收敛观测指标。SamplerSampler.java真正执行 FLDA 采样见 2.3 节。值得注意的是scheduleWithFetch采用了「流水线」式的预取策略先发出min(threadNum, 分区数)个分区请求每当一个分区拉取完成并交给空闲采样线程后立即发出下一个分区的请求从而在计算与网络传输之间重叠充分利用 Worker 内的多线程并行度线程数由angel.worker.thread.num控制。3.4 定期 reset 与容错一致性在 LDALearner.scala 的train()循环中每迭代 4 轮执行一次reset(epoch)将topic与word_topic矩阵清零后由各 Worker 重新上报主题分配scheduleReset。源码注释说明其原因当某个 PS 节点故障并被 Angel 重新调度时若不清零重建word_topic与 Worker 本地的主题分配会产生数据不一致。这一机制保证了长时间训练下模型状态的一致性也是大规模分布式训练中值得借鉴的容错细节。4. 输入数据格式LDA 训练的输入数据按行组织每行一个文档。根据实际解析实现 Document.java第 3741 行先按\t切分出文档 ID 与词序列再按空格切分词 ID标准格式为docIdTABwid_0 wid_1 ... wid_n即文档 ID 与词 ID 序列之间以\t分隔词 ID 之间以空格分隔。仓库内置示例数据 data/nips/nips.doc 即为该格式的真实样例例如首行1 2 39 42 42 42 77 95 96 ...注意英文文档 lda_on_angel_en.md 中描述词 ID 以逗号,分隔这与仓库中 Document.java 的实际解析逻辑空格分隔不一致实践中请以源码实现与中文文档 lda_on_angel.md 为准即「文档 ID \t 空格分隔的词 ID 序列」。重要前提Angel LDA 要求输入中的词语已经完成编号编号最好从 0 开始且连续内部由calcuateVocabularyNum取所有文档的最大词 ID 推导真实V词到编号的映射关系需要用户自行维护。5. 参数配置详解5.1 数据参数参数说明angel.train.data.path训练输入数据路径HDFS 路径angel.save.model.path训练模型保存路径angel.predict.data.path预测输入数据路径angel.predict.out.path预测结果输出路径angel.load.model.path预测时加载的模型路径即训练时的模型保存路径5.2 算法参数参数说明默认值取自源码ml.epoch.num算法迭代轮数LDAModel 中读取默认 10MLConf.scala 全局默认 30ml.lda.word.num词个数词汇表大小 V1训练时会被实际扫描到的最大词 ID 覆盖ml.lda.topic.num主题个数 KLDAModel 默认 1LDARunner 默认 10angel.worker.thread.numWorker 内部并行线程数LDARunner 默认 2MLConf 全局默认 1文档中写作ml.worker.thread.num实际键名见 MLConf.scala 第 56 行ml.lda.alpha狄利克雷超参数 α50.0 / Kml.lda.beta狄利克雷超参数 β0.01α、β 的默认值可在 LDAModel.scala 与 LDARunner.scala 中看到conf.getFloat(ALPHA, 50.0F / numTopics)、conf.getFloat(BETA, 0.01F)。α 随主题数自适应缩放β 通常取较小的平滑值。5.3 输出配置参数说明默认值save.doc.topic是否保存 doc-topic 矩阵falsesave.word.topic是否保存 word-topic 矩阵true预测必需save.doc.topic.distribution是否保存 doc-topic 概率分布falsesave.topic.word.distribution是否保存 topic-word 概率分布false此外 LDAModel 还定义了ml.lda.doc.num文档数与ml.lda.token.numtoken 总数等内部参数。资源相关的通用参数如angel.workergroup.numberWorker 数、angel.ps.numberPS 数、angel.worker.task.number每个 Worker 的任务数LDA 固定为 1也在此环节配置。5.4 预测注意事项预测时给定的主题个数ml.lda.topic.num必须与训练时相同预测时需要给定最大 word IDml.lda.word.num或给一个较大的值保证能覆盖预测数据中的所有词 ID预测通过LDAPredictTask加载word_topic模型后对未观测文档执行固定轮数的主题推断initForInferenceinference推断结果写入angel.predict.out.path下的doc_topic或doc_topic_distribution文件。6. 训练与预测本地示例与执行入口仓库提供了完整的本地运行示例 LDALocalExample.java支持 train / predict 两种模式// 数据集内置 NIPS 语料 trainInput data/nips/nips.doc; // 词汇表与主题数 int V 12420; int K 100; // 数据与部署模式 conf.set(AngelConf.ANGEL_DEPLOY_MODE, LOCAL); conf.set(AngelConf.ANGEL_ACTION_TYPE, train); // 或 predict conf.set(AngelConf.ANGEL_TRAIN_DATA_PATH, trainInput); conf.set(AngelConf.ANGEL_SAVE_MODEL_PATH, LOCAL_FS TMP_PATH /model/LDA); // 资源 conf.setInt(AngelConf.ANGEL_WORKERGROUP_NUMBER, 1); conf.setInt(AngelConf.ANGEL_WORKER_TASK_NUMBER, 1); conf.setInt(AngelConf.ANGEL_PS_NUMBER, 1); // LDA 算法参数 conf.setInt(LDAModel.WORD_NUM(), V); conf.setInt(LDAModel.TOPIC_NUM(), K); conf.setInt(MLConf.ML_EPOCH_NUM(), 10); conf.setBoolean(LDAModel.SAVE_DOC_TOPIC(), true); conf.setBoolean(LDAModel.SAVE_WORD_TOPIC(), true);predict 模式则设置ANGEL_PREDICT_DATA_PATH、ANGEL_LOAD_MODEL_PATH指向训练保存路径与ANGEL_PREDICT_PATH随后runner.predict(conf)完成推断。在真实分布式环境YARN中则以angel-submit脚本提交并通过angel.app.submit.class指定 Runner、以--angel.train.data.path、--angel.save.model.path、--angel.workergroup.number、--angel.ps.number等参数组装任务具体提交方式可参考 daw_on_angel.md 等文档中的angel-submit用法。7. 模型输出格式说明训练结束后模型以多个子目录/文件的形式保存在angel.save.model.path下格式均为 libsvm 风格doc-topic 矩阵doc_topic/目录每行一个文档第一个元素是文档 ID后面的每个key:value表示该文档中有多少个词value被分配给了主题key。由于 Angel 采用 Gibbs 采样求解 LDA本质即为每个词赋予主题可据此估计每个文档的主题分布。doc.topic.distributiondoc_topic_distribution/每行一个文档第一个元素是文档 ID后面的每个key:value表示每个主题的概率概率由 doc-topic 计数经 α 平滑计算(tk α) / (num K·α)。仅列出非零赋值的主题概率其余主题概率相等可自行补齐。word-topic 矩阵word_topic/目录每行一个词第一个元素是 word ID后面的每个key:value表示在该词的所有出现中主题key被分配到的词次数value。word-topic 是预测时必需的参数如需预测请务必保存若某些词没有主题分配信息说明该词在整个文档集中没有出现。topic.word.distributiontopic_word_distribution/每行一个主题第一个元素是 topic ID后面的每个key:value表示每个主题在词集合上的概率分布同样只给出非零赋值的概率。上述输出逻辑分别对应 LDALearner.scala 中的saveDocTopic、saveDocTopicDistribution、saveWordTopic、saveWordTopicDistribution四个方法其写盘过程均先写临时文件再 rename 落盘保证输出原子性。8. 性能表现原文档给出了 Angel 上 LDA 的一组基准实验数据来自 lda_on_angel_en.md测试数据PubMED 语料资源规模Worker 20 个PS 20 个Angel vs Spark迭代 100 轮的训练时间Angel 约 15 分钟Spark 大于 300 分钟。该数据反映了 FLDA 采样 参数服务器架构在分布式主题模型训练上的优势O(K_d)的稀疏采样复杂度显著降低了单轮计算量而矩阵按分区在 PS 上的存储与预取流水线减少了通信瓶颈。需要说明的是这是一组特定数据集与资源配置下的实测结果实际效果会随数据规模、主题数与集群环境变化。9. 参考资料lda_on_angel_en.md本文所依据的英文原文档lda_on_angel.md中文原文档含更完整的输出格式与预测说明warp_lda_on_angel.mdWarpLDA 变体MH 采样、O(1) 复杂度的补充说明LDAModel.scala模型矩阵与超参数定义LDALearner.scala训练调度、预取流水线与似然计算Sampler.java 与 FTree.javaFLDA 采样器与 F 树实现Document.java 与 CSRTokens.java输入解析与 CSR 语料结构LDALocalExample.java本地训练/预测示例MLConf.scala通用算法参数键定义算法原型论文Lele Yu, Bin Cui, Ce Zhang, Yingxia Shao.LDA*: A Robust and Large-scale Topic Modeling System, VLDB, 2017。赞分享人工智能机器学习分布式训练图计算后端【免费下载链接】angelA Flexible and Powerful Parameter Server for large-scale machine learning项目地址https://gitcode.com/gh_mirrors/an/angel点击查看免费下载相关推荐Gensim 分布式计算实战指南基于 Pyro4 集群加速 LSA 与 LDA 主题模型训练Gensim 分布式计算实战指南基于 Pyro4 集群加速 LSA 与 LDA 主题模型训练 导读 当语料规模达到数百万篇文档时在单机上训练 LSALat人工智能NLP机器学习深度学习如何快速实现大规模LDA主题模型基于Angel分布式框架的完整指南如何快速实现大规模LDA主题模型基于Angel分布式框架的完整指南 在处理海量文本数据时传统LDALatent Dirichlet Allocation人工智能机器学习分布式训练图计算后端大规模LDA主题模型训练实战Angel参数服务器助力文本挖掘效率提升20倍大规模LDA主题模型训练实战Angel参数服务器助力文本挖掘效率提升20倍 想要在海量文本数据中发现隐藏的主题模式吗Angel作为灵活强大的参数服务器为大人工智能机器学习分布式训练图计算后端上一篇VideoSrtGolang驱动的智能字幕生成方案3分钟搞定专业字幕制作下一篇告别AppImage管理烦恼3分钟学会用AppImageLauncher打造完美Linux桌面体验 创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表