【发布时间】:2017-02-06 21:32:14
【问题描述】:
我一直在尝试使用 spark 和 mllib 来训练 word2vec 模型,但我似乎没有在大型数据集上获得分布式机器学习的性能优势。我的理解是,如果我有 w 个工人,那么,如果我创建一个具有 n 个分区的 RDD,其中 n>w 并且我尝试通过调用 Word2Vec 的 fit 函数以 RDD 作为参数来创建一个 Word2Vec 模型,那么 spark 将分发数据统一地在这些 w 个 worker 上训练单独的 word2vec 模型,并在最后使用某种 reducer 函数从这些 w 个模型创建单个输出模型。这将减少计算时间,而不是 1 个块,w 个数据块将被同时处理。权衡是可能会发生一些精度损失,具体取决于最后使用的 reducer 函数。 Spark 中的 Word2Vec 是否真的以这种方式工作?如果确实如此,我可能需要使用可配置参数。
编辑
添加提出这个问题的原因。我在 10 台工作机器上运行 java spark word2vec 代码,并在查看文档后为 executor-memory、driver memory 和 num-executors 设置合适的值,用于映射到 rdd 分区的 2.5gb 输入文本文件,然后用作mllib word2vec 模型的训练数据。培训部分花费了数小时。工作节点的数量似乎对训练时间没有太大影响。相同的代码在较小的数据文件(大约 10 MB 的数量级)上成功运行
代码
SparkConf conf = new SparkConf().setAppName("SampleWord2Vec");
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
conf.registerKryoClasses(new Class[]{String.class, List.class});
JavaSparkContext jsc = new JavaSparkContext(conf);
JavaRDD<List<String>> jrdd = jsc.textFile(inputFile, 3).map(new Function<String, List<String>>(){
@Override
public List<String> call(String s) throws Exception {
return Arrays.asList(s.split(","));
}
});
jrdd.persist(StorageLevel.MEMORY_AND_DISK());
Word2Vec word2Vec = new Word2Vec()
.setWindowSize(20)
.setMinCount(20);
Word2VecModel model = word2Vec.fit(jrdd);
jrdd.unpersist(false);
model.save(jsc.sc(), outputfile);
jsc.stop();
jsc.close();
【问题讨论】:
-
如果您分享您的代码以及有关如何运行 spark-submit 的更多详细信息,将会有所帮助。当你跑步时,你是否看到你所有的工人一直都在活动? Spark 历史 UI 将让您深入了解。您的代码可能没有性能并且您没有完全分发您的代码。 Spark ML 包括基于数据帧 API 的 JavaWord2Vec。这应该很快。
-
spark ml JavaWord2Vec(dataframes api) 是否应该比 mllib 版本 (javardd api) 更好。我放弃了 spark ml 版本,因为当我尝试迭代模型向量时它给出了一些编译错误。
-
数据帧 API 背后的催化剂优化器性能更高,应该更容易。你不会迭代,这是使用 Spark 的一种可怕的糟糕方式。 ML 允许您构建管道,这些管道实际上对您选择的列的所有值执行功能映射。同样,代码会有所帮助。
-
我已经用有问题的部分更新了问题。我已经删除了迭代模型向量的部分,但是模型训练步骤花费了太多时间。日志会打印 alpha 的值,因为它从 0.025 下降,并且进展非常缓慢。
标签: java apache-spark apache-spark-mllib word2vec