1

我正在尝试将 POJO 模型导入苏打水。我目前正在通过使用以下方法编译模型来导入模型:

javac -cp /opt/bitnami/commons/pojo.jar -J-Xmx2g -J-XX:MaxPermSize=256m /opt/bitnami/commons/GBM_model_python_1642760589977_1.java

在此之后,我使用 hex.genmodel.GenModel 加载它,如下所示:

val classLocation = new File("/opt/bitnami/commons/").toURL
valLocation = Array[java.net.URL](classLocation)
val classLoader = new URLClassLoader(Location,classOf[GenModel].getClassLoader)
val cls = Class.forName("GBM_model_python_1642760589977_1", true, classLoader)
val model: GenModel = cls.newInstance().asInstanceOf[GenModel]

问题是在进行预测时,我遇到了 URLClassLoader 的问题:

val easyModel = new EasyPredictModelWrapper(model)
classLoader.close()
val header = model.getNames 
val outputType = easyModel.getModelCategory 

val predictionRdd = testData.rdd.map(row => {
  val r = new RowData
  header.indices.foreach(idx => r.put(header(idx), row.getDouble(idx).asInstanceOf[AnyRef]))
  val prediction = easyModel.predictMultinomial(r)
  prediction
  })

抛出异常:

org.apache.spark.SparkException: Task not serializable
Caused by: java.io.NotSerializableException: java.net.URLClassLoader
Serialization stack:

我不知道为什么,因为我认为 URLClassLoader 没有被使用。我试图用classLoader.close()它来解决它,但它没有用。

我的问题是:有没有更简单的方法将 POJO 模型导入苏打水?如果是这样,这是理想的方式,现在我正在本地编译模型,但我需要将它们保存在 S3 中......有没有办法加载模型而不必在本地编译它,比如将它保存在内存中或其他东西? 如何解决序列化问题?

4

1 回答 1

0

您正在尝试在运行时编译 POJO,然后将其分发给执行程序。出于某种原因 - 您的代码也在分发 URLClassloader(与 POJO 无关,POJO 本身是可序列化的) - URLClassloader 不可序列化。

我认为这种方法通常无法正常工作,因为如果您在驱动程序上编译类并对其进行序列化 - 它在执行程序上将不可用。

更好的方法是在提交作业时将类放在其他 Spark jar 中的类路径上。

于 2022-02-22T23:20:31.647 回答