OutOfMemoryError с классификатором Mallet CRF

Классификатор часто дает сбой OutOfMemoryError. Пожалуйста, предложите.

У нас есть конвейер UIMA, который вызывает 5 банок модели (на основе CRF молотка) около 30 МБ каждый. -Xms настроен на 2G, а -Xmx установлен на 4G.

Существуют ли какие-либо рекомендации/отметки для определения размера кучи? Пожалуйста, укажите, есть ли какие-либо рекомендации для многопоточной среды.

Я попытался применить исправление https://code.google.com/p/cleartk/issues/detail?id=408, это не решило проблему.

Дамп кучи показывает, что 42% размера кучи — это char[], а 15% — это String.

java.lang.OutOfMemoryError: Java heap space
    at cc.mallet.types.IndexedSparseVector.setIndex2Location(IndexedSparseVector.java:109)
    at cc.mallet.types.IndexedSparseVector.dotProduct(IndexedSparseVector.java:157)
    at cc.mallet.fst.CRF$TransitionIterator.<init>(CRF.java:1856)
    at cc.mallet.fst.CRF$TransitionIterator.<init>(CRF.java:1835)
    at cc.mallet.fst.CRF$State.transitionIterator(CRF.java:1776)
    at cc.mallet.fst.MaxLatticeDefault.<init>(MaxLatticeDefault.java:252)
    at cc.mallet.fst.MaxLatticeDefault.<init>(MaxLatticeDefault.java:197)
    at cc.mallet.fst.MaxLatticeDefault$Factory.newMaxLattice(MaxLatticeDefault.java:494)
    at cc.mallet.fst.MaxLatticeFactory.newMaxLattice(MaxLatticeFactory.java:11)
    at cc.mallet.fst.Transducer.transduce(Transducer.java:124)
    at org.cleartk.ml.mallet.MalletCrfStringOutcomeClassifier.classify(MalletCrfStringOutcomeClassifier.java:90)

Модель создана на основе MalletCrfStringOutcomeDataWriter.

AnalysisEngineFactory.createEngineDescription(DataChunkAnnotator.class,
        CleartkSequenceAnnotator.PARAM_IS_TRAINING, true, DirectoryDataWriterFactory.PARAM_OUTPUT_DIRECTORY,
        options.getModelsDirectory(), DefaultSequenceDataWriterFactory.PARAM_DATA_WRITER_CLASS_NAME, MalletCrfStringOutcomeDataWriter.class)

Код аннотатора выглядит следующим образом.

if (this.isTraining()) {
        List<DataAnnotation> namedEntityMentions = JCasUtil.selectCovered(jCas, DataAannotation.class, sentence);
        List<String> outcomes = this.chunking.createOutcomes(jCas, tokens, namedEntityMentions);
        this.dataWriter.write(Instances.toInstances(outcomes, featureLists));
      } else {
        List<String> outcomes = this.classifier.classify(featureLists);
        this.chunking.createChunks(jCas, tokens, outcomes);
      }

Спасибо


person Tilak    schedule 19.11.2015    source источник


Ответы (1)


Вы можете либо попробовать:

  1. увеличить Xmx
  2. углубитесь в анализ кучи: все строки резервируются char[], поэтому знание таких чисел, как 42% и 15%, бесполезно - вам следует выяснить, какая часть вашей программы выделяет эти строки.
  3. Поскольку похоже, что ошибка возникает в строке:
    List<String> outcomes = this.classifier.classify(featureLists);
    вы можете начать оттуда: попробуйте выяснить, что находится в featureLists, каков его размер и т. д., и посмотрите, что делает метод classify, и если вы можете «помочь» ему стать более эффективным с точки зрения памяти. Например, сократите использование String и замените его на StringBuilder и append (просто пример).
person Nir Alfasi    schedule 19.11.2015