【问题标题】:Reusable version of DKPro Core pipelineDKPro Core 管道的可重用版本
【发布时间】:2016-05-03 15:27:42
【问题描述】:

我已将 DKPro Core 设置为 Web 服务,以获取输入并提供标记化的输出。服务本身设置为 Jersey 资源:

@Path("/")
public class MyResource
{

  public MyResource()
  {
    // Nothing here
  }

  @GET
  public String generate(@QueryParam("q") final String input)
  {
    try
    {
      final JCasIterable en = iteratePipeline(
        createReaderDescription(StringReader.class, StringReader.PARAM_DOCUMENT_TEXT, input, StringReader.PARAM_LANGUAGE, "en")
       ,createEngineDescription(StanfordSegmenter.class)
       ,createEngineDescription(StanfordPosTagger.class)
       ,createEngineDescription(StanfordParser.class)
       ,createEngineDescription(StanfordNamedEntityRecognizer.class)
      );

      final StringBuilder sb = new StringBuilder();
      for (final JCas jCas : en)
      {
        for (final Token token : select(jCas, Token.class))
        {
          sb.append('[');
          sb.append(token.getCoveredText());
          sb.append(' ');
          sb.append(token.getPos().getPosValue());
          sb.append(']');
        }
      }
      return sb.toString();
    }
    catch (final Exception e)
    {
      throw new RuntimeException("Problem", e);
    }
  }
}

一切正常,但速度很慢,每次输入需要 7-10 秒。我认为这是因为正在为每个请求重新创建管道。

如何修改此代码以将管道创建移至构造函数并减少单个请求的负载?请注意,可能有多个同时请求,因此任何不是线程安全的都需要在请求中。

【问题讨论】:

    标签: nlp stanford-nlp uima dkpro-core


    【解决方案1】:

    创建单个 CAS:

    JCas jcas = JCasFactory.createJCas();
    

    填写 CAS

    jcas.setDocumentText("This is a test");
    jcas.setDocumentLanguage("en");
    

    使用

    创建一次管道(并保留引擎以供进一步的请求)
    AnalysisEngine engine = createEngine(
       createEngineDescription(...),
       createEngineDescription(...),
       ...);
    

    如果你一直隐式创建引擎,它必须一遍又一遍地加载模型等。

    将管道应用到 CAS

    SimplePipeline.runPipeline(jcas, engine);
    

    如果您想进一步加快处理速度,请为自己创建一个 CAS 池并在多个请求中重复使用它们 - 从头开始​​创建 CAS 需要一些时间。

    有些组件可能是线程安全的,有些则不是。这在很大程度上取决于底层第三方库的实现。但 DKPro Core 中的包装器也没有明确构建为线程安全的。例如,在默认配置中,根据文档语言加载和使用模型。如果您使用来自多个线程的分析引擎的同一实例,这将导致问题。

    同样,您应该考虑创建一个预先实例化的管道池。不过,您将需要相当多的内存,因为每个实例都将加载自己的模型。有一些实验性功能可以在同一组件的实例之间共享模型,但没有进行太多测试。请注意,第三方工具也可能以非线程安全的方式实现了他们的模型。 DKPro Core 中的模型共享,请参阅this discussion on the mailing list

    披露:我是 DKPro Core 开发人员之一。

    【讨论】:

    • 如果我只创建一个 JCas,然后尝试更改文本,那么我会收到异常 org.apache.uima.cas.CASRuntimeException: Data for Sofa feature setLocalSofaData() has already been set. 我该如何解决这个问题?
    • 创建一个新问题
    猜你喜欢
    • 1970-01-01
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多