Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

[MXNET-716][MIRROR #12723] Scala Benchmark Extension pack #12758

Merged
merged 2 commits into from
Oct 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions scala-package/examples/scripts/benchmark/run_text_charrnn_bm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

set -e

hw_type=cpu
if [ "$1" = "gpu" ]
then
hw_type=gpu
fi

platform=linux-x86_64

if [ "$OSTYPE" == "darwin"* ]
then
platform=osx-x86_64
fi

MXNET_ROOT=$(cd "$(dirname $0)/../../../.."; pwd)
CLASS_PATH=$MXNET_ROOT/scala-package/assembly/$platform-$hw_type/target/*:$MXNET_ROOT/scala-package/examples/target/*:$MXNET_ROOT/scala-package/examples/target/classes/lib/*:$MXNET_ROOT/scala-package/infer/target/*

MODEL_NAME=$2

RUNS=$3

# model dir
MODEL_PATH_PREFIX=$4
# input image
DATA_PATH=$5

# feel free to change the starter sentence
STARTER_SENTENCE="The joke"

java -Xmx8G -Dmxnet.traceLeakedObjects=false -cp $CLASS_PATH \
org.apache.mxnetexamples.benchmark.ScalaInferenceBenchmark \
--example $MODEL_NAME \
--count $RUNS \
--model-prefix $MODEL_PATH_PREFIX \
--data-path $DATA_PATH \
--starter-sentence "$STARTER_SENTENCE"

Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,38 @@ You may need to run ```chmod u+x run_image_inference_bm.sh``` before running thi
batch_inference_latency p99 4241, batch_inference_p50 4241, batch_inference_average 4241.00
```

More examples to be added soon.
* *Object Detection Example*
<br> The following shows an example of running SSDClassifier under the benchmark script. The script takes in the number of iterations for inference calls, the batch size for batch inference calls, the model path, input file, and input directory.
For more details to run SSDClassifierExample as a standalone file, refer to the [README](https://github.com/apache/incubator-mxnet/blob/master/scala-package/examples/src/main/scala/org/apache/mxnetexamples/infer/objectdetector/README.md) for SSDClassifierExample.
You may need to run ```chmod u+x run_image_inference_bm.sh``` before running this script.
```bash
cd <Path-To-MXNET-Repo>/scala-package/examples/scripts/infer/objectdetector
./get_ssd_data.sh
cd <Path-To-MXNET-Repo>/scala-package/examples/scripts/benchmark
./run_image_inference_bm.sh cpu ObjectDetectionExample 100 10 ../infer/models/resnet50_ssd/resnet50_ssd_model ../infer/images/dog.jpg ../infer/images/
```
Upon running this script, you might see an output like this :
```
[main] INFO org.apache.mxnetexamples.benchmark.CLIParserBase -
single_inference_latency p99 1663, single_inference_p50 729, single_inference_average 755.17
...

INFO org.apache.mxnetexamples.benchmark.CLIParserBase -
batch_inference_latency p99 4241, batch_inference_p50 4241, batch_inference_average 4241.00
```

* *Text Generation through RNNs*
<br>The following shows an example of running TestCharRnn under the benchmark script. The script takes in the number of iterations for inference calls, the model path and the input text file.
For more details to run TestCharRnn as a standalone file, refer to the [README](https://github.com/apache/incubator-mxnet/blob/master/scala-package/examples/src/main/scala/org/apache/mxnetexamples/rnn/README.md) for TextCharRnn.
You may need to run ```chmod u+x run_text_charrnn_bm.sh``` before running this script.
```bash
wget https://s3.us-east-2.amazonaws.com/mxnet-scala/scala-example-ci/RNN/obama.zip
unzip obama.zip
cd <Path-To-MXNET-Repo>/scala-package/examples/scripts/benchmark
./run_text_charrnn_bm.sh cpu CharRnn 100 <path-to-model>/obama <path-to-model>/obama.txt
```
Upon running this script, you might see an output like this :
```
[main] INFO org.apache.mxnetexamples.benchmark.CLIParserBase -
single_inference_latency p99 4097, single_inference_p50 2560, single_inference_average 2673.720000
```
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ package org.apache.mxnetexamples.benchmark
import org.apache.mxnetexamples.InferBase
import org.apache.mxnetexamples.infer.imageclassifier.ImageClassifierExample
import org.apache.mxnet._
import org.apache.mxnetexamples.infer.objectdetector.SSDClassifierExample
import org.apache.mxnetexamples.rnn.TestCharRnn
import org.kohsuke.args4j.{CmdLineParser, Option}
import org.slf4j.LoggerFactory

Expand Down Expand Up @@ -89,10 +91,11 @@ object ScalaInferenceBenchmark {
val times: Seq[Long] = inferenceTimes
val p50 = percentile(50, times)
val p99 = percentile(99, times)
val p90 = percentile(90, times)
val average = times.sum / (times.length * 1.0)

logger.info("\n%s_p99 %d, %s_p50 %d, %s_average %1.2f".format(metricsPrefix,
p99, metricsPrefix, p50, metricsPrefix, average))
logger.info("\n%s_p99 %d, %s_p90 %d, %s_p50 %d, %s_average %1.2f".format(metricsPrefix,
p99, metricsPrefix, p90, metricsPrefix, p50, metricsPrefix, average))

}

Expand All @@ -113,6 +116,18 @@ object ScalaInferenceBenchmark {
val parsedVals = new CmdLineParser(imParser).parseArgument(args.toList.asJava)
new ImageClassifierExample(imParser)
}
case "ObjectDetectionExample" => {
val imParser = new org.apache.mxnetexamples.infer.objectdetector.CLIParser
baseCLI = imParser
val parsedVals = new CmdLineParser(imParser).parseArgument(args.toList.asJava)
new SSDClassifierExample(imParser)
}
case "CharRnn" => {
val imParser = new org.apache.mxnetexamples.rnn.CLIParser
baseCLI = imParser
val parsedVals = new CmdLineParser(imParser).parseArgument(args.toList.asJava)
new TestCharRnn(imParser)
}
case _ => throw new Exception("Invalid example name to run")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
*/

package org.apache.mxnetexamples.infer.objectdetector
// scalastyle:off
import java.awt.image.BufferedImage

import org.apache.mxnetexamples.benchmark.CLIParserBase
// scalastyle:on
import java.io.File

import org.apache.mxnet._
Expand All @@ -27,6 +31,8 @@ import org.slf4j.LoggerFactory
import scala.collection.JavaConverters._
import java.nio.file.{Files, Paths}

import org.apache.mxnetexamples.InferBase

import scala.collection.mutable.ListBuffer

// scalastyle:off
Expand All @@ -37,15 +43,6 @@ import scala.collection.mutable.ListBuffer
* @see <a href="https://github.com/apache/incubator-mxnet/tree/master/scala-package/examples/src/main/scala/org/apache/mxnetexamples/infer/objectdetector" target="_blank">Instructions to run this example</a>
*/
// scalastyle:on
class SSDClassifierExample {
@Option(name = "--model-path-prefix", usage = "the input model directory and prefix of the model")
private val modelPathPrefix: String = "/model/ssd_resnet50_512"
@Option(name = "--input-image", usage = "the input image")
private val inputImagePath: String = "/images/dog.jpg"
@Option(name = "--input-dir", usage = "the input batch of images directory")
private val inputImageDir: String = "/images/"
}

object SSDClassifierExample {

private val logger = LoggerFactory.getLogger(classOf[SSDClassifierExample])
Expand Down Expand Up @@ -111,7 +108,7 @@ object SSDClassifierExample {
}

def main(args: Array[String]): Unit = {
val inst = new SSDClassifierExample
val inst = new CLIParser
val parser : CmdLineParser = new CmdLineParser(inst)
parser.parseArgument(args.toList.asJava)
val mdprefixDir = inst.modelPathPrefix
Expand Down Expand Up @@ -193,4 +190,64 @@ object SSDClassifierExample {
exist
}

}
}

class CLIParser extends CLIParserBase {
@Option(name = "--model-path-prefix", usage = "the input model directory and prefix of the model")
val modelPathPrefix: String = "/model/ssd_resnet50_512"
@Option(name = "--input-image", usage = "the input image")
val inputImagePath: String = "/images/dog.jpg"
@Option(name = "--input-dir", usage = "the input batch of images directory")
val inputImageDir: String = "/images/"
}

class SSDClassifierExample(CLIParser: CLIParser)
extends InferBase {
override def loadModel(context: Array[Context]): Any = {
val dType = DType.Float32
val inputShape = Shape(1, 3, 512, 512)
val inputDescriptors = IndexedSeq(DataDesc("data", inputShape, dType, "NCHW"))
new ObjectDetector(CLIParser.modelPathPrefix, inputDescriptors, context)
}
override def loadSingleData(): Any = {
val img = ImageClassifier.loadImageFromFile(CLIParser.inputImagePath)
img
}

override def runSingleInference(loadedModel: Any, input: Any): Any = {
val detector = loadedModel.asInstanceOf[ObjectDetector]
val imgInput = input.asInstanceOf[BufferedImage]
detector.imageObjectDetect(imgInput)
}

override def loadInputBatch(inputPaths: Any): Any = {
val batchFile = inputPaths.asInstanceOf[List[String]]
ImageClassifier.loadInputBatch(batchFile)
}

override def loadBatchFileList(batchSize: Int): List[Any] = {
val dir = new File(CLIParser.inputImageDir)
require(dir.exists && dir.isDirectory,
"input image directory: %s not found".format(CLIParser.inputImageDir))
val output = ListBuffer[List[String]]()
var batch = ListBuffer[String]()
for (imgFile: File <- dir.listFiles()){
batch += imgFile.getPath
if (batch.length == batchSize) {
output += batch.toList
batch = ListBuffer[String]()
}
}
if (batch.length > 0) {
output += batch.toList
}
output.toList
}

override def runBatchInference(loadedModel: Any, input: Any): Any = {
val model = loadedModel.asInstanceOf[ObjectDetector]
val imgInput = input.asInstanceOf[Traversable[BufferedImage]]
val output = model.imageBatchObjectDetect(imgInput, Some(5))
output
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@
package org.apache.mxnetexamples.rnn

import org.apache.mxnet._
import org.apache.mxnetexamples.InferBase
import org.apache.mxnetexamples.benchmark.CLIParserBase
import org.kohsuke.args4j.{CmdLineParser, Option}
import org.slf4j.LoggerFactory

import scala.collection.JavaConverters._

/**
* Follows the demo, to test the char rnn:
* https://github.com/dmlc/mxnet/blob/master/example/rnn/char-rnn.ipynb
*/
* Follows the demo, to test the char rnn:
* https://github.com/dmlc/mxnet/blob/master/example/rnn/char-rnn.ipynb
*/
object TestCharRnn {

private val logger = LoggerFactory.getLogger(classOf[TrainCharRnn])
Expand Down Expand Up @@ -83,7 +86,7 @@ object TestCharRnn {
}

def main(args: Array[String]): Unit = {
val stcr = new TestCharRnn
val stcr = new CLIParser
val parser: CmdLineParser = new CmdLineParser(stcr)
try {
parser.parseArgument(args.toList.asJava)
Expand All @@ -99,11 +102,63 @@ object TestCharRnn {
}
}

class TestCharRnn {
class CLIParser extends CLIParserBase {
@Option(name = "--data-path", usage = "the input train data file")
private val dataPath: String = "./data/obama.txt"
val dataPath: String = "./data/obama.txt"
@Option(name = "--model-prefix", usage = "the model prefix")
private val modelPrefix: String = "./model/obama"
val modelPrefix: String = "./model/obama"
@Option(name = "--starter-sentence", usage = "the starter sentence")
private val starterSentence: String = "The joke"
val starterSentence: String = "The joke"
}

class TestCharRnn(CLIParser: CLIParser) extends InferBase {

private var vocab : Map[String, Int] = null

override def loadModel(context: Array[Context]): Any = {
val batchSize = 32
val buckets = List(129)
val numHidden = 512
val numEmbed = 256
val numLstmLayer = 3
val (_, argParams, _) = Model.loadCheckpoint(CLIParser.modelPrefix, 75)
this.vocab = Utils.buildVocab(CLIParser.dataPath)
val model = new RnnModel.LSTMInferenceModel(numLstmLayer, vocab.size + 1,
numHidden = numHidden, numEmbed = numEmbed,
numLabel = vocab.size + 1, argParams = argParams, dropout = 0.2f)
model
}

override def loadSingleData(): Any = {
val revertVocab = Utils.makeRevertVocab(vocab)
revertVocab
}

override def runSingleInference(loadedModel: Any, input: Any): Any = {
val model = loadedModel.asInstanceOf[RnnModel.LSTMInferenceModel]
val revertVocab = input.asInstanceOf[Map[Int, String]]
// generate a sequence of 1200 chars
val seqLength = 1200
val inputNdarray = NDArray.zeros(1)
// Feel free to change the starter sentence
var output = CLIParser.starterSentence
val randomSample = true
var newSentence = true
val ignoreLength = output.length()

for (i <- 0 until seqLength) {
if (i <= ignoreLength - 1) Utils.makeInput(output(i), vocab, inputNdarray)
else Utils.makeInput(output.takeRight(1)(0), vocab, inputNdarray)
val prob = model.forward(inputNdarray, newSentence)
newSentence = false
val nextChar = Utils.makeOutput(prob, revertVocab, randomSample)
if (nextChar == "") newSentence = true
if (i >= ignoreLength) output = output ++ nextChar
}
output
}

override def loadBatchFileList(batchSize: Int): List[Any] = null
override def loadInputBatch(source: Any): Any = null
override def runBatchInference(loadedModel: Any, input: Any): Any = null
}
Loading