【LDA】用MPI优化GibbsLDA++-0.2

MPI 是“Message Passing Interface”的缩写,通常用来做单机多线程的并发编程。

1. GibbsLDA++中训练框架大致如下:

循环:训练过程迭代N次
{
     循环:遍历每一个训练样本(指doc)
     {
           循环:遍历训练样本中的每一个word
           {
                  循环:gibbs采样过程,遍历每一个topic
                  {
                         会更新:
                         doc-topic矩阵、
                         word-topic矩阵、
                         doc-topic的边缘分布向量、
                         word-topic的边缘分布向量
                         当前word在topic上的分布向量
                  }
           }
     }
}

LDA的训练过程主要通过gibbs采样过程来完成。在内存中会存储:(1)所有训练样本;(2)doc-topic矩阵、word-topic矩阵、几个topic相关的分布向量等。整个训练过程由上面嵌套的四重循环组成。当训词典不大且练样本集合不大的时候,gibbs采样是一个cpu消耗集中的项目,而不是内存占用的项目。也就是说cpu是整个训练的瓶颈。

2. 尝试用openmp来实现训练过程的单机并行化

主要是利用openmp利用单机cpu上的多个核心,将循环依照核心的数目来进行划分,例如:将一重循环划分为较小的两重循环,分别放在cpu的两个核心上进行运算,再将得到的结果进行合并。这样使用需要有个要求:数据独立性。即划分为两个循环之后,这两个循环内部不会对同一个变量或者内存区域进行修改,如果有的话,就会产生“竞争”关系,就会因为写内存的时机不同、程序运行出不同的结果。

2.1 在最内层循环用openmp

主要是计算“当前word在topic上的分布向量”的时候,遍历topic,这时候word在topic上的分布向量可以依据topic的不同拆分成不同的区域,相互并不干扰。代码如下:

#pragma omp parallel for num_threads(2)
    for (int k = 0; k < K; k++)
	{
		p[k] = (nw[w][k] + beta) / (nwsum[k] + Vbeta) *
		    (nd[m][k] + alpha) / (ndsum[m] + Kalpha);
    }

上面代码用“#pragma omp parallel for num_threads(2)”指定该循环在两个核心上运算。

用GibbsLDA++自带的训练样本为例,实验结果如下:

没用MPI的,gibbs采样时间消耗:62.657s

用MPI的,gibbs采样时间消耗:94.626s

用MPI的,效率反而更低了!

现在能想到的原因,大概是针对K(topic个数)的循环太小了(实验中K的取值是100),且处于最内层循环,被调用的次数最多。这会引起大量的、拆分K循环给2个cpu的操作,这些操作也有性能损耗,且损耗大于了拆分后独立运行的收益,造成性能下降。

2.2 在第二层循环(遍历训练样本)中用openmp

第二层循环是遍历训练样本,在这一层循环用openmp实际上是对训练样本进行划分,并分别训练。代码如下:

#pragma omp parallel for num_threads(2)
		for (int m = 0; m < M; m++)
		{
			for (int n = 0; n < ptrndata->docs[m]->length; n++)
			{
				int topic = sampling(m, n);
				z[m][n] = topic;
			}
		}

这样修改,gibbs采样的运行时间就降低很多了,结果如下:

没用MPI的,gibbs采样时间消耗:62.657s

用MPI的,gibbs采样时间消耗:40.068s

降低了1/3的训练时间。

不过这样做会有数据依赖的问题:将第二层循环切分为两个并行的循环的话,这两个并行的小循环,最内层循环都会对word做gibbs采样,即都会读取和更新doc-topic和word-topic矩阵、以及那些边缘分布。从这个角度讲,算法运行出来的结果应该是不正确的结果。不过,换另外的角度想:

(1)对数据进行并行化,也就是将doc集合进行划分,那么doc-topic矩阵和doc边缘分布相对也划分成多份,互不干扰。不过word-topic矩阵以及当前word在每个topic上的分布的向量,会有相互之间的干扰。

(2)word-topic矩阵的内容,每个word不同,更新的区域不同,当并行循环计算的word不同的时候,也不会受到影响;当并行循环计算的word相同的时候,刚好需要累加计算结果,也OK

(3)word在每个topic上的分布的向量,这个结果会收到影响。例如:如果将训练数据划分为两份,这两份中分别找到两个word(通常是不同的),用来更新上面的向量,而这个向量的写操作如果不受保护的话,会写“混”了。不过,如果全局都是这种写混的状态的话....结果也说不准

(4)Gibbs采样是概率算法,已经验证过,即便是参数相同,每次运行的结果也不同。

完。

转载请注明出处:http://blog.csdn.net/xceman1997/article/details/46582637

时间: 2024-08-24 20:56:13

【LDA】用MPI优化GibbsLDA++-0.2的相关文章

【LDA】修正 GibbsLDA++-0.2 中的两个内存问题

周末这两天在家用LDA做个小实验.在LDA的众多实现的工具包中,GibbsLDA 是应用最广泛的,包括c++版本.java版本等.GibbsLDA++ 是它的C++版本的实现,目前最新版本是0.2版.在实际使用过程中,发现这个实现版本有内存使用问题.我花了一些时间定位到了问题,贴出来供大家参考. 问题1:数组内存访问越界 在model.cpp中,用到了两个矩阵nw和nd,分别存储word-topic关系和document-topic关系.这两个矩阵的大小分别是V * K和 M * K,其中,V是

服务器优化3.0

1.更新内核yum update kernelyum update kernel-develyum update kernel-firmwareyum update kernel-headers 2.历史记录数vim /etc/profileTMOUT=300HISTTIMEFORMAT="%F %T whoami "HISTSIZE=4000HISTFILESIZE=4000source /etc/profile 3.配置ip地址vim /etc/sysconfig/network-

hive sql 优化 - 2.0

hive 优化 1.需要计算的指标真的需要从数据仓库的公共明细自行汇总吗?2.真的需要扫描那么多的分区么?3.尽量不要使用 select * from table这样的方式4.输入文件不要是大量的小文件 group by引起的倾斜优化: R:group by引起的倾斜主要是输入数据行按照group by列分布不均匀引起的. S:优化方案: set hive.map.aggr = true set hive.groupby.skewindata=true count distinct优化 eg:

linux服务器优化2.0版

1.服务器修改IP             vim /etc/sysconfig/network-scripts/ifcfg-eth1 2.修改dns服务器            vim /etc/resolv.conf 3.关闭selinux              vim /etc/selinux/config 4.修改主机名iZ118z08q6wZ   vim /etc/sysconfig/network 5.禁用control-alt-delete   vim /etc/init/co

linux服务器优化1.0版

1.服务器修改IP             vim /etc/sysconfig/network-scripts/ifcfg-eth1 2.修改dns服务器            vim /etc/resolv.conf 3.关闭selinux              vim /etc/selinux/config 4.修改主机名iZ118z08      vim /etc/sysconfig/network 5.禁用control-alt-delete   vim /etc/init/con

【LDA】动手实现LDA

这段时间对LDA比较感兴趣,尝试在工作中使用它.平时做想法的快速验证,都用的是"GibbsLDA++-0.2",一个c实现版本的LDA.这两天用c++ stl自己写了一个单机版的LDA,初衷如下: 1. "GibbsLDA++-0.2"虽说号称是最popular的LDA工具包,不过依然有明显的bug,参考"[LDA]修正 GibbsLDA++-0.2 中的两个内存问题". 2. "GibbsLDA++-0.2"基本上使用纯c写

主题模型 利用gibbslda做数据集主题抽样

Gibbslda有很多版本,我所用的版本为C++版(下载地址http://gibbslda.sourceforge.net/),平台是linux,博主试过windows上运行,有两个主要问题很烦-,一个是path,一个是平台太大.最后还是投入了ubuntu的怀抱,感觉配置好g++环境后速度还不错.由于系统版本等原因,不同的情况下可能会出现或多或少的问题,在做lda抽取的过程中,参考了几个博客,地址如下,我在这里做了一个总结,基本上应该避免了网上教程从来都不能使用的毛病.所以如果按照博主的过程出现

DeskPRO.v3.0.0.Enterprise.PHP.NULL 1CD(3维建模 CAM (计算机辅助制造)软件, 致力于尽可能快地建立3维立体模型并将 之转变成CNC数控机床能用的数据)

DDS产品: FEMtools.v3.3.Win32 1CD(振动灵敏度分析软件) FEMtools.v3.3.Win64 1CD Network Analysis Inc产品: Sinda/G.Application.Suite.v2.6 Working-ISO 1CD(有限差分析器软件) ECS产品: FemFat v4.7C 1CD(用于对部件进行疲劳测试的软件.它可为部件的安全使用提供快速可信的解决方案,并可结合NASTRAN,ABAQUS,ANSYS,I-DEAS,MEDINA,PAT

Apache Spark 2.2.0 中文文档 - SparkR (R on Spark) | ApacheCN

SparkR (R on Spark) 概述 SparkDataFrame 启动: SparkSession 从 RStudio 来启动 创建 SparkDataFrames 从本地的 data frames 来创建 SparkDataFrames 从 Data Sources(数据源)创建 SparkDataFrame 从 Hive tables 来创建 SparkDataFrame SparkDataFrame 操作 Selecting rows(行), columns(列) Groupin