As exceções de NPE ocorrem quando previstas por meio da API JAVA.
java.lang.NullPointerException: null
em ml.dmlc.xgboost4j.java.Booster.predict(Booster.java:309)
em ml.dmlc.xgboost4j.java.Booster.predict(Booster.java:375)
em com.tuhu.predict.predict.BaseModelPredict.predict(BaseModelPredict.java:71)
em com.tuhu.predict.predict.XgboostFindPageModelPredict.predict(XgboostFindPageModelPredict.java:53)
em com.tuhu.predict.service.impl.MlpFindPageFeatureServiceImpl.featureProcess(MlpFindPageFeatureServiceImpl.java:65)
em com.tuhu.predict.api.controller.MlpFindPageController.recommendPredict(MlpFindPageController.java:49)
em com.tuhu.predict.api.controller.MlpFindPageController$$FastClassBySpringCGLIB$$f694b9ff.invoke(
em org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
em org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
em org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
em org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
em org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
em org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47)
em org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
em org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
em org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
em org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
em org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
em org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
em com.tuhu.springcloud.common.annotation.AbstractControllerLogAspect.doAround(AbstractControllerLogAspect.java:104)
em sun.reflect.NativeMethodAccessorImpl.invoke0(Método Nativo)
em sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
em sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
em java.lang.reflect.Method.invoke(Method.java:498)
em org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
em org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
em org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
em org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:174)
em org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
em org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
em org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
em com.tuhu.predict.api.controller.MlpFindPageController$$EnhancerBySpringCGLIB$$$560ed775.recommendPredict(
em sun.reflect.NativeMethodAccessorImpl.invoke0(Método Nativo)
em sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
em sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
em java.lang.reflect.Method.invoke(Method.java:498)
em org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
em org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
em org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
em org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
em org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
em org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
em org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
em org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
em org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
em org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
em javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
em org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
em javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em com.tuhu.soter.starter.filter.SoterDefaultFilter.doFilter(SoterDefaultFilter.java:79)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em com.tuhu.boot.logback.filter.LogFilter.doFilter(LogFilter.java:54)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158)
em org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126)
em org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111)
em org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
em org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em com.tuhu.boot.common.filter.HeartbeatFilter.doFilter(HeartbeatFilter.java:42)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em com.tuhu.boot.common.filter.MDCFilter.doFilter(MDCFilter.java:47)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
em org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
em org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
em org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
em org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
em org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
em org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
em org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
em org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
em org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
em org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
em org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
em org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
em org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:677)
em org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
em org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
em org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
em org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
em org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
em org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
em java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
em java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
em org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
em java.lang.Thread.run(Thread.java:748)
Como o modelo é treinado por meio do Python Sklearn, ocorrem incompatibilidades posteriormente. Para economizar tempo, a equipe de algoritmos moveu o modelo XGB treinado pelo Sklearn uma camada sobre o pacote Python XgBoost.
Qual versão do XGBoost você está usando? Anteriormente, corrigimos um bug em que o pacote jvm não lança uma exceção corretamente quando a previsão falha e continua com um buffer de previsão vazio.
Qual versão do XGBoost você está usando? Anteriormente, corrigimos um bug em que o pacote jvm não lança uma exceção corretamente quando a previsão falha e continua com um buffer de previsão vazio.
A versão 1.0 da plataforma de algoritmo da empresa é usada e a versão 0.9.0 do projeto de algoritmo é usada devido a problemas de compatibilidade de versão. Os colegas do algoritmo usaram Python para converter o arquivo de modelo 1.0 para 0.9.0. Eu me pergunto se isso é causado por essa transformação
Eu sugiro esperar por 1.2 (https://github.com/dmlc/xgboost/issues/5734) e tentar novamente, temos algumas correções de bugs importantes nesta versão. Também sugiro usar a mesma versão xgboost ou posterior para previsão. O modelo binário do XGBoost é compatível com versões anteriores, seguindo em frente, o modelo baseado em JSON é recomendado.
Eu bati o mesmo problema com 1.2.0. Então o problema ainda está aqui.
Eu também tenho o mesmo problema.
Eu usei xgboost4j para criar o modelo.
existe uma solução alternativa?
Este é um grande problema para mim, ele falhou em trabalhos de produção.
@ranInc Você está usando a versão mais recente do XGBoost? Até agora, não sabemos a causa exata desse problema. Iremos resolvê-lo da melhor forma possível e, como não há garantia de quando o problema poderá ser resolvido, sugiro que você investigue uma alternativa enquanto isso.
@ranInc Você pode nos ajudar fornecendo um pequeno programa de exemplo que nós (desenvolvedores) podemos executar em nossa própria máquina.
Estou executando o 1.2.0, o jar mais recente no repositório maven.
A alternativa para mim é voltar ao saprk 2.4.5 e usar o xgboost 0.9 - e é isso que estou fazendo agora.
Por exemplo: vou tentar identificar o modelo/dados específicos que estão causando a falha do trabalho mais tarde.
Oi,
Encontrei o modelo/dados específicos.
Estou anexando neste comentário.
xgb1.2_bug.zip
é assim que você recria o bug (lembre-se de que se você não fizer a repartição aqui, funciona - então tem algo a ver com a quantidade de dados ou tipo de dados em cada partição):
from pyspark.ml.pipeline import PipelineModel
from pyspark.sql import SparkSession
from pyspark.sql.dataframe import DataFrame
df = spark.read.parquet("/tmp/6620294785024229130_features").repartition(200).persist()
df.count()
model = PipelineModel.read().load("/tmp/6620294785024229130_model_xg_only")
predictions = model.transform(df)
predictions.persist()
predictions.count()
predictions.show()
Você tem alguma ideia de quando isso pode ser resolvido?
Isso me impede de usar o spark 3.0 ...
@ranInc Ainda não. Avisaremos quando conseguirmos corrigir o bug. Além disso, você pode postar o código em Scala? Acho que nunca apoiamos oficialmente o uso do PySpark com o XGBoost.
import org.apache.spark.ml.{Pipeline, PipelineModel}
val df = spark.read.parquet("/tmp/6620294785024229130_features").repartition(200).persist()
df.count()
val model = PipelineModel.read.load("/tmp/6620294785024229130_model_xg_only")
val predictions = model.transform(df)
predictions.persist()
predictions.count()
predictions.show()
Outro ponteiro,
parece que o problema é devido a todos os recursos enviados para serem previstos serem zeros/ausentes.
Acho que ninguém está trabalhando nisso?
Isso basicamente significa que o xgboost não funciona no spark 3.
Sim, desculpe, nossas mãos estão bastante cheias agora. Em algum momento, abordaremos essa questão. Peço respeitosamente sua paciência. Obrigado.
@ranInc Eu tive algum tempo hoje, então tentei executar o script que você forneceu aqui. Eu reproduzi o erro java.lang.NullPointerException
.
Estranhamente, a versão de desenvolvimento mais recente ( master
branch) não trava da mesma maneira. Em vez disso, produz erro
Exceção no encadeamento "principal" org.apache.spark.SparkException: Trabalho abortado devido a falha de estágio: Tarefa 0 no estágio 7.0 falhou 1 vez, falha mais recente: Tarefa perdida 0.0 no estágio 7.0 (TID 11, d04389c5babb, driver executor): ml.dmlc.xgboost4j.java.XGBoostError: [00:36:10] /workspace/src/learner.cc:1179: Falha na verificação: learner_model_param_.num_feature >= p_fmat->Info().num_col_ (1 vs. 2) : O número de colunas não corresponde ao número de recursos no booster.
Vou investigar mais.
Acho que a mensagem de erro faz sentido agora, sua entrada tem mais recursos do que o modelo de previsão.
Antes, o pacote jvm continuará após a falha do xgboost, resultando em um buffer de previsão vazio. Eu adicionei um guarda de verificação recentemente.
Apenas certifique-se de que o número de colunas em seu conjunto de dados de treinamento seja maior ou igual ao seu conjunto de dados de previsão.
Oi,
O modelo foi criado usando a mesma quantidade de recursos.
No spark, ele usa uma coluna de vetor e não várias colunas.
Em qualquer caso, o tamanho do vetor é sempre o mesmo, para ajuste e previsão - 100% de certeza disso.
Isso tem algo a ver com linhas com todos os recursos zero/ausentes.
Você pode ver que, se filtrar do dataframe as linhas com todos os recursos zero - funciona muito bem.
@ranInc Você pode postar o programa Scala completo que gerou o modelo? A mensagem de erro parece sugerir que seu modelo foi treinado com um único recurso.
Acho que não vai ajudar muito pois o código é muito genérico e tem alguns transformadores propiciatórios,
O código em si é principalmente pyspark e não scala.
A melhor maneira de ver que o número de recursos não é um problema é apenas filtrar as linhas com todos os recursos zero e usar o modelo - isso funciona sem problemas.
Você também pode manter todas as linhas e reparticionar o dataframe para usar uma partição, e isso também funciona.
@ranInc Eu filtrei as linhas com zero e ainda estou enfrentando o mesmo erro ( java.lang.NullPointerException
):
...
df.na.drop(minNonNulls = 1)
...
Esta não é a maneira correta de fazer isso?
Acho que não vai ajudar muito pois o código é muito genérico e tem alguns transformadores propiciatórios
Quero ver quantos recursos estão sendo usados no treinamento e no tempo de previsão. A mensagem de erro
ml.dmlc.xgboost4j.java.XGBoostError: [00:36:10] /workspace/src/learner.cc:1179: Falha na verificação: learner_model_param_.num_feature >= p_fmat->Info().num_col_ (1 vs. 2) : O número de colunas não corresponde ao número de recursos no booster.
sugere que o modelo foi treinado com um único recurso e a previsão está sendo feita com dois recursos.
No momento, só tenho acesso ao quadro de dados e ao modelo serializado que você carregou. Não tenho informações sobre o que aconteceu no treinamento do modelo e o que deu errado, o que me impede de solucionar o problema ainda mais. Se o seu programa tem alguma informação proprietária, é possível produzir um exemplo limpo?
import org.apache.spark.ml.linalg.{SparseVector, Vector}
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions.{callUDF, col}
.......
val isVectorAllZeros = (col: Vector) => {
col match {
case sparse: SparseVector =>
if(sparse.indices.isEmpty){
true
}else{
false
}
case _ => false
}
}
spark.udf.register("isVectorAllZeros", isVectorAllZeros)
df = df.withColumn("isEmpty",callUDF("isVectorAllZeros",
col("features_6620294785024229130"))).where("isEmpty == false")
você também pode apenas re-particionar o dataframe assim:
....
df = df.repartition(1)
....
Mas tenho 100% de certeza de que usou a mesma quantidade de recursos.
Como você garantiu isso, se o VectorAssembler causa um número variável de recursos?
VectorAssembler sempre cria a mesma quantidade de recursos, ele só precisa de nomes de colunas para pegar.
O próprio código é usado para criar milhares de modelos, então é bem genérico e basicamente obtém uma lista de nomes para usar.
Talvez eu possa executar a criação do modelo novamente e enviar o dataframe usado para o modelo - ou qualquer outro dado necessário.
Isso levará tempo para mim e se você usar o que eu mostrei antes, você verá que o modelo funciona bem com 2 recursos.
@ranInc Deixe-me fazer mais uma pergunta: é correto dizer que os dados de exemplo têm uma coluna esparsa (VectorAssembler) que possui no máximo dois recursos ?
Não.
VectorAssembler é um Trasformer que pega várias colunas e as coloca em uma coluna Vector.
Os vetores são sempre usados para ajustar e prever modelos no spark.
O dataframe de exemplo aqui tem uma coluna de vetor.
Algumas linhas são esparsas, outras densas - todas têm dois recursos.
@ranInc Portanto, todas as linhas têm dois recursos, alguns valores estão ausentes e outros não. Entendi. Vou tentar sua sugestão sobre como filtrar linhas vazias.
Como você deve ter adivinhado, sou bastante novo no ecossistema Spark, portanto, o esforço de depuração pode ser bastante difícil. No momento, precisamos de mais desenvolvedores que saibam mais sobre a programação Spark e Scala em geral. Se você conhece pessoalmente alguém que gostaria de nos ajudar a melhorar o pacote JVM do XGBoost, por favor nos avise.
@ranInc Tentei filtrar linhas vazias de acordo com sua sugestão:
Programa A: script de exemplo, sem filtrar linhas vazias
import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.{Pipeline, PipelineModel}
import org.apache.spark.ml.linalg.{SparseVector, Vector}
import org.apache.spark.sql.functions.{callUDF, col}
object Main extends App {
val spark = SparkSession
.builder()
.appName("XGBoost4J-Spark Pipeline Example")
.getOrCreate()
val df = spark.read.parquet("/home/ubuntu/data/6620294785024229130_features").repartition(200).persist()
df.show()
val model = PipelineModel.read.load("/home/ubuntu/data/6620294785024229130_model_xg_only")
val predictions = model.transform(df)
predictions.persist()
predictions.count()
predictions.show()
}
Programa B: Exemplo com filtragem de linha vazia
import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.{Pipeline, PipelineModel}
import org.apache.spark.ml.linalg.{SparseVector, Vector}
import org.apache.spark.sql.functions.{callUDF, col}
object Main extends App {
val spark = SparkSession
.builder()
.appName("XGBoost4J-Spark Pipeline Example")
.getOrCreate()
val isVectorAllZeros = (col: Vector) => {
col match {
case sparse: SparseVector => (sparse.indices.isEmpty)
case _ => false
}
}
spark.udf.register("isVectorAllZeros", isVectorAllZeros)
val df = spark.read.parquet("/home/ubuntu/data/6620294785024229130_features").repartition(200).persist()
.withColumn("isEmpty", callUDF("isVectorAllZeros", col("features_6620294785024229130")))
.where("isEmpty == false")
df.show()
val model = PipelineModel.read.load("/home/ubuntu/data/6620294785024229130_model_xg_only")
val predictions = model.transform(df)
predictions.persist()
predictions.count()
predictions.show()
}
java.lang.NullPointerException
. Pouco antes do NPE, o seguinte aviso é exibido no log de execução do Spark:WARNING: /xgboost/src/learner.cc:979: Number of columns does not match number of features in booster. Columns: 0 Features: 1
master
mais recente, commit 42d31d9dcb6f7c1cb7d0545e9ab3a305ecad0816), tanto o Programa A quanto o Programa B falham com o seguinte erro:[12:44:57] /home/ubuntu/xgblatest/src/learner.cc:1179: Check failed: learner_model_param_.num_feature >= p_fmat->Info().num_col_ (1 vs. 2) : Number of columns does not match number of features in booster.
Stack trace:
[bt] (0) /tmp/libxgboost4j14081654332866852928.so(dmlc::LogMessageFatal::~LogMessageFatal()+0x79) [0x7f7ef62c4e19] [bt] (1) /tmp/libxgboost4j14081654332866852928.so(xgboost::LearnerImpl::ValidateDMatrix(xgboost::DMatrix*, bool) const+0x20b) [0x7f7ef63f5f0b]
[bt] (2) /tmp/libxgboost4j14081654332866852928.so(xgboost::LearnerImpl::Predict(std::shared_ptr<xgboost::DMatrix>, bool, xgboost::HostDeviceVector<float>*, unsigned int, bool, bool, bool, bool, bool)+0x3c3) [0x7f7ef6400233]
[bt] (3) /tmp/libxgboost4j14081654332866852928.so(XGBoosterPredict+0xec) [0x7f7ef62caa3c] [bt] (4) /tmp/libxgboost4j14081654332866852928.so(Java_ml_dmlc_xgboost4j_java_XGBoostJNI_XGBoosterPredict+0x47) [0x7f7ef62befd7]
[bt] (5) [0x7f80908a8270]
o que é estranho porque, de acordo com @ranInc , o modelo foi treinado com dados com dois recursos.
1.2.0-SNAPSHOT
da fonte (commit 71197d1dfa27c80add9954b10284848c1f165c40). Desta vez, tanto o Programa A quanto o Programa B falham com o erro de incompatibilidade de recurso ( learner_model_param_.num_feature >= p_fmat->Info().num_col_ (1 vs. 2) : Number of columns does not match number of features in booster
).1.2.0-SNAPSHOT
foi inesperada e me deixou bastante nervoso. Em particular, a mensagem de aviso de 1.2.0WARNING: /xgboost/src/learner.cc:979: Number of columns does not match number of features in booster. Columns: 0 Features: 1
não é encontrado na versão 1.2.0 da base de código C++. Em vez disso, o aviso é encontrado na ramificação release_1.0.0
:
https://github.com/dmlc/xgboost/blob/ea6b117a5737f5beb2533fc89b3f3fcd72ecc04e/src/learner.cc#L972 -L982
Então, isso significa que o arquivo JAR 1.2.0 no Maven Central tem libxgboost4j.so
de 1.0.0 ?? 🤯 😱
libxgboost4j.so
que na verdade é 1.0.0 (!!!). Para descobrir, baixe xgboost4j_2.12-1.2.0.jar
do Maven Central e extraia o arquivo libxgboost4j.so
. Em seguida, execute o seguinte script Python para verificar a versão do arquivo de biblioteca:import ctypes
lib = ctypes.cdll.LoadLibrary('./libxgboost4j.so')
major = ctypes.c_int()
minor = ctypes.c_int()
patch = ctypes.c_int()
lib.XGBoostVersion(ctypes.byref(major), ctypes.byref(minor), ctypes.byref(patch))
print((major.value, minor.value, patch.value)) # prints (1, 0, 2), indicating version 1.0.2
learner_model_param_.num_feature == 1
). Talvez os dados de treinamento tivessem um recurso 100% vazio? @ranIncVocê quer que eu pegue o dataframe usado para criar o modelo?
Se eu conseguir pegá-lo, acho que posso criar um código scala simples que cria o modelo.
@ranInc Minha suspeita é que um dos dois recursos nos dados de treinamento consistia inteiramente em valores ausentes, definindo learner_model_param_.num_feature
como 1. Então, sim, ver os dados de treinamento será muito útil.
Tudo bem, acho que vou ter pronto até amanhã.
Criado #6426 para acompanhar o problema de libxgboost4j.so
incompatíveis. Aqui (#5957) vamos manter a discussão sobre por que learner_model_param_.num_feature
está sendo definido como 1.
Parece que você está errado, os dados de treinamento não têm valores ausentes.
no código de exemplo aqui, em vez de retransmitir a repartição para reproduzir a falha, usei apenas uma linha (que tem apenas zero recursos) para previsão.
import ml.dmlc.xgboost4j.scala.spark.XGBoostRegressor
import org.apache.spark.ml.Pipeline
import org.apache.spark.sql.SparkSession
import org.apache.spark.ml.PipelineModel
import org.apache.spark.sql.DataFrame
val df = spark.read.parquet("/tmp/6620294785024229130_only_features_creation").persist()
df.count()
val regressor = new XGBoostRegressor()
.setFeaturesCol("features_6620294785024229130")
.setLabelCol("label_6620294785024229130")
.setPredictionCol("prediction")
.setMissing(0.0F)
.setMaxDepth(3)
.setNumRound(100)
.setNumWorkers(1)
val pipeline = new Pipeline().setStages(Array(regressor))
val model = pipeline.fit(df)
val pred = spark.read.parquet("/tmp/6620294785024229130_features").persist()
pred.count()
pred.where("account_code == 4011593987").show()
model.transform(pred.where("account_code == 4011593987")).show()
Comentários muito úteis
Tudo bem, acho que vou ter pronto até amanhã.