2016-05-16 11 views
1

MLの予測にXGboost4Jを使用しています。プラットフォーム内でさまざまなコンポーネントがML予測子を呼び出すことができるように、安らかなWebサービスを使用して予測子を開発しました。例えば、製品のタイトルおよび説明から、製品カテゴリツリーを見つけることができる。XGBoost4J同期の問題?

私たちが実装した基本的な方法でコードを描いています。

//これは の初期化メソッドで行われます。すべてのモデルに対して、1つのシングルトンブースターオブジェクトがロードされています。予測因子のクラスの上

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 
     } 
    } 

はシングルトンWebサービスのサービスクラスに注入され ので、すべてのサービスを呼び出すためのスレッド呼び出しの

service.predict(predictionString); 

複数の並行スレッドの呼び出しは、メソッドブースター方法は

を同期している予測する際に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; 
    } 

この作成されたスレッドは、同期ブロックと同期のためにロックを待機します。結果として、スケーラブルではないWebサービスになっています。

XGboost4Jソースコードから同期を取り除き、コンパイルしたjarを試しましたが、最初の1-2分でクラッシュしました。

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

誰でもJavaを使用・アプローチ高度にスケーラブルなWebサービスのためのXgboost4Jを実現するためのより良い方法を知っているXgboostJNIにネイティブコールをしながら行の下でそのクラッシュを示すヒープダンプ?

答えて