6

現在、UMBC Webbase Corpus (400 ファイルで約 30 GB のテキスト) で Word2Vec ベクトルのセットをトレーニングしようとしています。

100 GB 以上のマシンでも、メモリ不足の状況に陥ることがよくあります。アプリケーション自体で Spark を実行します。少し調整しようとしましたが、10 GB を超えるテキスト データに対してこの操作を実行できません。私の実装の明確なボトルネックは、以前に計算された RDD の結合であり、メモリ不足の例外が発生する場所です。

おそらく、これよりもメモリ効率の高い実装を思いついた経験があるでしょう。

 object SparkJobs {
  val conf = new SparkConf()
    .setAppName("TestApp")
    .setMaster("local[*]")
    .set("spark.executor.memory", "100g")
    .set("spark.rdd.compress", "true")

  val sc = new SparkContext(conf)


  def trainBasedOnWebBaseFiles(path: String): Unit = {
    val folder: File = new File(path)

    val files: ParSeq[File] = folder.listFiles(new TxtFileFilter).toIndexedSeq.par


    var i = 0;
    val props = new Properties();
    props.setProperty("annotators", "tokenize, ssplit");
    props.setProperty("nthreads","2")
    val pipeline = new StanfordCoreNLP(props);

    //preprocess files parallel
    val training_data_raw: ParSeq[RDD[Seq[String]]] = files.map(file => {
      //preprocess line of file
      println(file.getName() +"-" + file.getTotalSpace())
      val rdd_lines: Iterator[Option[Seq[String]]] = for (line <- Source.fromFile(file,"utf-8").getLines) yield {
          //performs some preprocessing like tokenization, stop word filtering etc.
          processWebBaseLine(pipeline, line)    
      }
      val filtered_rdd_lines = rdd_lines.filter(line => line.isDefined).map(line => line.get).toList
      println(s"File $i done")
      i = i + 1
      sc.parallelize(filtered_rdd_lines).persist(StorageLevel.MEMORY_ONLY_SER)

    })

    val rdd_file =  sc.union(training_data_raw.seq)

    val starttime = System.currentTimeMillis()
    println("Start Training")
    val word2vec = new Word2Vec()

    word2vec.setVectorSize(100)
    val model: Word2VecModel = word2vec.fit(rdd_file)

    println("Training time: " + (System.currentTimeMillis() - starttime))
    ModelUtil.storeWord2VecModel(model, Config.WORD2VEC_MODEL_PATH)  
  }}
}
4

2 に答える 2

1

Sarvesh がコメントで指摘しているように、1 台のマシンにはおそらくデータが多すぎます。より多くのマシンを使用してください。通常、1 GB のファイルを処理するには 20 ~ 30 GB のメモリが必要です。この (非常に大雑把な) 見積もりでは、30 GB の入力に対して 600 ~ 800 GB のメモリが必要になります。(データの一部を読み込むことで、より正確な見積もりを得ることができます。)

より一般的なコメントとして、 and の使用を避けることをお勧めしrdd.unionますsc.parallelize。代わりsc.textFileにワイルドカードを使用して、すべてのファイルを単一の RDD にロードします。

于 2015-02-05T20:22:07.243 に答える