Apache spark Spark LDA消耗太多内存

Apache spark Spark LDA消耗太多内存,apache-spark,apache-spark-mllib,lda,Apache Spark,Apache Spark Mllib,Lda,我正在尝试使用spark mllib lda来总结我的文档语料库 我的问题设置如下 大约10万份文件 大约40万个独特的单词 100簇 我有16台服务器(每个服务器有20个内核和128GB内存) 当我使用onlinedaoptimizer执行LDA时,它给出了内存不足错误,建议我增加spark.driver.maxResultSizelike 11个任务的序列化结果的总大小(1302 MB)大于spark.driver.maxResultSize 我将spark.driver.maxResu

我正在尝试使用spark mllib lda来总结我的文档语料库

我的问题设置如下

  • 大约10万份文件
  • 大约40万个独特的单词
  • 100簇
我有16台服务器(每个服务器有20个内核和128GB内存)

当我使用
onlinedaoptimizer
执行LDA时,它给出了内存不足错误,建议我增加
spark.driver.maxResultSize
like 11个任务的序列化结果的总大小(1302 MB)大于spark.driver.maxResultSize

我将
spark.driver.maxResultSize
增加到120GB(也将
spark.driver.memory
增加到120GB),并重新运行LDA,但不缺少。 它仍然说11个任务(120.1GB)的序列化结果的总大小比spark.driver.maxResultSize要大

我尝试了另一个包含10万个独特单词的数据集,结果成功了

那么,在使用Spark mllib LDA时,如何估计内存使用情况?我在官方文档中找不到任何规范

注意:我使用了稀疏 用于构造docuemnt
RDD[(Long,vector)]
的向量传递给
LDA.run()
,但不知道spark LDA是否能够在内部正确处理稀疏格式

(编辑)我使用了Scala版本的LDA。不是Python版本

这可能是一个相关的问题,但没有给出明确的答案。

(编辑)

这是我的代码片段(gist)。

def startJob(args:RunArgs)(隐式sc:SparkContext):单位={
val src=sc.textFile(args.fname,minPartitions=args.n_partitions).map(u.split(“\t”))
.平面图{
//输入文件的格式为(用户id、产品名称、计数)
大小写数组(u,p,r,t)=>Some((u.toInt,p.toInt,r.toDouble))
案例=>无
}.persist()
//映射以将用户id或产品名称转换为唯一的sequencential id
val userid_map=src.map(u._1).distinct().zipWithIndex().collect().toMap
val productid_map=src.map(u._2).distinct().zipWithIndex().collect().toMap
val inverse_userid_map=userid_map.map(u.swap)
//broadcat将加速RDD映射操作
val b_userid_map=sc.broadcast(userid_map)
val b_productid_map=sc.broadcast(productid_map)
val b_inverse_userid_map=sc.broadcast(inverse_userid_map)
//运行图
val transformed_src=src.map{case(u,p,r)=>
(b_userid_map.value(u),b_productid_map.value(p.toInt,r)
}
println(“唯一项=%d”。格式(b_productid_map.value.size))
//准备LDA输入RDD[(长,向量)]
val documents=transformed_src.map{case(u,p,r)=>(u,(p,r))}
.groupByKey()
.map{t=>(t._1,Vectors.sparse(b_productid_map.value.size,t._2.toSeq))}.persist()
文件计数()
src.unpersist()
//在线运行LDA
val ldamodel=新的LDA()
.setK(args.k)
.setMaxIterations(参数n_iter)
.setOptimizer(“在线”)
.运行(文档)
.asInstanceOf[LocalLDAModel]
val结果=ldamodel.topicDistributions(文档)
.map{case(i,v)=>
val u=b_inverse_userid_map.value(i)
“%d,%s.”格式(u,v.toArray.mkString(“,”)
}
结果.saveAsTextFile(args.out)
}
实际上,我使用LDA对事务数据进行降维。我的数据格式为
(u、p、r)
其中,
u
是用户id,
p
是产品名称,
r
是用户
u
p
交互的编号。在本例中,用户对应于文档,产品对应于word。由于用户id和产品名称是任意字符串,所以在提交给LDA之前,我将它们转换为唯一的顺序整数


谢谢。

导致此问题的常见原因有三种,它们可以独立工作,也可以同时工作

  • 作业使用类似于
    collect
    的方法将大量数据返回给驱动程序。唉,有些SparkML代码就是这样做的。如果您不能将问题归咎于下面的(2)或(3),那么很可能是您的数据如何与
    onlinedaoptimizer
    实现交互的结果

  • 该作业涉及大量任务,每个任务都将结果返回给驱动程序,作为Spark作业管理的一部分(而不是使用类似于
    collect
    的方法)。检查SparkUI中的任务数。另请参见堆栈跟踪上的
    org.apache.spark.scheduler.TaskSetManager#canFetchMoreResults
    org.apache.spark.scheduler.TaskResultGetter#enqueueSuccessfulTask

  • 估计错误:Spark严重过度估计将要返回给驱动程序的数据的大小,并抛出此错误以防止集群的驱动程序丢失。请参阅一种测试方法,即将
    spark.driver.maxResultSize
    设置为0(无限制),然后查看发生了什么


  • 希望这有帮助

    需要注意的是,
    mllib
    LDA在训练时确实正确地处理了稀疏向量。@Mai是的,我想是这样的。仍然不知道为什么我的内存不足。你能展示一下你的代码吗?@zero323我更新了我的帖子,加入了我的代码片段。提前谢谢你的帮助。谢谢,最好是把这个放在一个问题里面。。LDA至少返回两个相对较大的本地对象
    topicsMatrix
    (#docs*#clusters)和
    DescripteTopics
    (这与(#clusters*#tokens*2)成正比)。乍一看,它不应该占120GB,但仍然占很多。