DKPro 核心管道的可重用版本

Reusable version of DKPro Core pipeline

我已将 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 秒。我认为这是因为正在为每个请求重新创建管道。

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

创建单个 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 核心开发人员之一。