XGBoost4J同步问题?

时间:2016-05-16 06:17:13

标签: xgboost

我们正在使用XGboost4J进行ML预测。我们使用restful webservice开发了预测器,以便在平台内各种组件可以调用ML预测器。例如,从产品名称和描述中找出产品类别树。

只是以我们实施的基本方式描绘代码。

//这是完成的 initialize方法,对于每个模型,都加载了一个单独的Booster对象。

 Class Predictor{
      private Booster xgboost;
       //init call from Serivice initialization while injecting Predictor
       public void init(final String modelFile, final Integer numThreads){
        if (!(new File(modelFile).exists())) {
            throw new IOException("Modelfile " + modelFile + " does not exist");
        }

        // we use a util class Params to handle parameters as example
        final Iterable<Entry<String, Object>> param = new Params() {
                {
                    put("nthread", numThreads);
                }
            };
          xgboost = new Booster(param, modelFile);
     }

        //Predict method   
        public String predict(final String predictionString){
                 final String dummyLabel = "-1";
                final String x_n = dummyLabel + "\t" + x_n_libsvm_idxStr;
                final DataLoader.CSRSparseData spData = XGboostSparseData.format(x_n);
                final DMatrix x_n_dmatrix = new DMatrix(spData.rowHeaders,
                        spData.colIndex, spData.data, DMatrix.SparseType.CSR);

                final float[][] predict = xgboost.predict(x_n_dmatrix);
                // Then there is conversion logic of predict to predicted model result          which returns predictions
                  String prediction = getPrediction(predict);
                  return  prediction
        }
    }

以上预测变量类是在webservices Services类中注入的单例 所以对于每个服务调用线程调用

 service.predict(predictionString);

当多个并发线程调用预测方法Boosters方法同步时,tomcat容器中存在问题

private synchronized float[][] pred(DMatrix data, boolean outPutMargin, long treeLimit, boolean predLeaf) throws XGBoostError {
        byte optionMask = 0;
        if(outPutMargin) {
            optionMask = 1;
        }

        if(predLeaf) {
            optionMask = 2;
        }

        float[][] rawPredicts = new float[1][];
        ErrorHandle.checkCall(XgboostJNI.XGBoosterPredict(this.handle, data.getHandle(), optionMask, treeLimit, rawPredicts));
        int row = (int)data.rowNum();
        int col = rawPredicts[0].length / row;
        float[][] predicts = new float[row][col];

        for(int i = 0; i < rawPredicts[0].length; ++i) {
            int r = i / col;
            int c = i % col;
            predicts[r][c] = rawPredicts[0][i];
        }

        return predicts;
    }

这个创建的线程由于synchronized块而等待和锁定,这导致Web服务无法扩展。

我们尝试从XGboost4J源代码和已编译的jar中删除synchronized,但它在前1-2分钟内崩溃。堆转储在对XgboostJNI执行本机调用时显示其在下面的行崩溃

 ErrorHandle.checkCall(XgboostJNI.XGBoosterPredict(this.handle, data.getHandle(), optionMask, treeLimit, rawPredicts));

任何人都知道使用Java实现Xgboost4J的高可伸缩Web服务方法的更好方法吗?

1 个答案:

答案 0 :(得分:1)