"vscode:/vscode.git/clone" did not exist on "3d3a277fbe7ec2fa9bd5642b0bd375bfccb05d18"
Unverified Commit 902ea211 authored by guoshzhao's avatar guoshzhao Committed by GitHub
Browse files

Benchmarks: Add Benchmark - Add CNN model benchmarks. (#59)

* Benchmarks: Add Benchmark - Add CNN model benchmarks.
parent ce3ed24a
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
"""Model benchmark example for resnet101.
Commands to run:
python3 examples/benchmarks/pytorch_cnn_resnet101.py (Single GPU)
python3 -m torch.distributed.launch --use_env --nproc_per_node=8 examples/benchmarks/pytorch_cnn_resnet101.py \
--distributed (Distributed)
"""
import argparse
from superbench.benchmarks import Platform, Framework, BenchmarkRegistry
from superbench.common.utils import logger
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'--distributed', action='store_true', default=False, help='Whether to enable distributed training.'
)
args = parser.parse_args()
# Specify the model name and benchmark parameters.
model_name = 'resnet101'
parameters = '--batch_size 1 --image_size 224 --precision float32 --num_warmup 8 --num_steps 64 --run_count 2'
if args.distributed:
parameters += ' --distributed_impl ddp --distributed_backend nccl'
# Create context for resnet101 benchmark and run it for 64 steps.
context = BenchmarkRegistry.create_benchmark_context(
model_name, platform=Platform.CUDA, parameters=parameters, framework=Framework.PYTORCH
)
benchmark = BenchmarkRegistry.launch_benchmark(context)
if benchmark:
logger.info(
'benchmark: {}, return code: {}, result: {}'.format(
benchmark.name, benchmark.return_code, benchmark.result
)
)
...@@ -6,5 +6,6 @@ ...@@ -6,5 +6,6 @@
from superbench.benchmarks.model_benchmarks.model_base import ModelBenchmark from superbench.benchmarks.model_benchmarks.model_base import ModelBenchmark
from superbench.benchmarks.model_benchmarks.pytorch_bert import PytorchBERT from superbench.benchmarks.model_benchmarks.pytorch_bert import PytorchBERT
from superbench.benchmarks.model_benchmarks.pytorch_gpt2 import PytorchGPT2 from superbench.benchmarks.model_benchmarks.pytorch_gpt2 import PytorchGPT2
from superbench.benchmarks.model_benchmarks.pytorch_cnn import PytorchCNN
__all__ = ['ModelBenchmark', 'PytorchBERT', 'PytorchGPT2'] __all__ = ['ModelBenchmark', 'PytorchBERT', 'PytorchGPT2', 'PytorchCNN']
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
"""Module of the Pytorch CNN models."""
import time
import torch
from torchvision import models
from superbench.common.utils import logger
from superbench.benchmarks import BenchmarkRegistry, Precision
from superbench.benchmarks.model_benchmarks.model_base import Optimizer
from superbench.benchmarks.model_benchmarks.pytorch_base import PytorchBase
from superbench.benchmarks.model_benchmarks.random_dataset import TorchRandomDataset
class PytorchCNN(PytorchBase):
"""The CNN benchmark class."""
def __init__(self, name, parameters=''):
"""Constructor.
Args:
name (str): benchmark name.
parameters (str): benchmark parameters.
"""
super().__init__(name, parameters)
self._supported_precision = [Precision.FLOAT32, Precision.FLOAT16]
self._optimizer_type = Optimizer.SGD
self._loss_fn = torch.nn.CrossEntropyLoss()
def add_parser_arguments(self):
"""Add the CNN-specified arguments."""
super().add_parser_arguments()
self._parser.add_argument('--model_type', type=str, required=True, help='The cnn benchmark to run.')
self._parser.add_argument('--image_size', type=int, default=224, required=False, help='Image size.')
self._parser.add_argument('--num_classes', type=int, default=1000, required=False, help='Num of class.')
def _generate_dataset(self):
"""Generate dataset for benchmarking according to shape info.
Return:
True if dataset is created successfully.
"""
self._dataset = TorchRandomDataset(
[self._args.sample_count, 3, self._args.image_size, self._args.image_size],
self._world_size,
dtype=torch.long
)
if len(self._dataset) == 0:
logger.error('Generate random dataset failed - model: {}'.format(self._name))
return False
return True
def _create_model(self, precision):
"""Construct the model for benchmarking.
Args:
precision (Precision): precision of model and input data, such as float32, float16.
"""
try:
self._model = getattr(models, self._args.model_type)()
self._model = self._model.to(dtype=getattr(torch, precision.value))
if self._gpu_available:
self._model = self._model.cuda()
except BaseException as e:
logger.error(
'Create model with specified precision failed - model: {}, precision: {}, message: {}.'.format(
self._name, precision, str(e)
)
)
return False
self._target = torch.LongTensor(self._args.batch_size).random_(self._args.num_classes)
if self._gpu_available:
self._target = self._target.cuda()
return True
def _train_step(self, precision):
"""Define the training process.
Args:
precision (Precision): precision of model and input data, such as float32, float16.
Return:
The step-time list of every training step.
"""
duration = []
curr_step = 0
while True:
for idx, sample in enumerate(self._dataloader):
start = time.time()
sample = sample.to(dtype=getattr(torch, precision.value))
if self._gpu_available:
sample = sample.cuda()
self._optimizer.zero_grad()
output = self._model(sample)
loss = self._loss_fn(output, self._target)
loss.backward()
self._optimizer.step()
end = time.time()
curr_step += 1
if curr_step > self._args.num_warmup:
# Save the step time of every training/inference step, unit is millisecond.
duration.append((end - start) * 1000)
if self._is_finished(curr_step, end):
return duration
def _inference_step(self, precision):
"""Define the inference process.
Args:
precision (Precision): precision of model and input data,
such as float32, float16.
Return:
The latency list of every inference operation.
"""
duration = []
curr_step = 0
with torch.no_grad():
self._model.eval()
while True:
for idx, sample in enumerate(self._dataloader):
start = time.time()
sample = sample.to(dtype=getattr(torch, precision.value))
if self._gpu_available:
sample = sample.cuda()
self._model(sample)
if self._gpu_available:
torch.cuda.synchronize()
end = time.time()
curr_step += 1
if curr_step > self._args.num_warmup:
# Save the step time of every training/inference step, unit is millisecond.
duration.append((end - start) * 1000)
if self._is_finished(curr_step, end):
return duration
# Register CNN benchmarks.
# Reference: https://pytorch.org/vision/stable/models.html
# https://github.com/pytorch/vision/tree/master/torchvision/models
MODELS = [
'alexnet', 'densenet121', 'densenet169', 'densenet201', 'densenet161', 'googlenet', 'inception_v3', 'mnasnet0_5',
'mnasnet0_75', 'mnasnet1_0', 'mnasnet1_3', 'mobilenet_v2', 'mobilenet_v3_large', 'mobilenet_v3_small', 'resnet18',
'resnet34', 'resnet50', 'resnet101', 'resnet152', 'resnext50_32x4d', 'resnext101_32x8d', 'wide_resnet50_2',
'wide_resnet101_2', 'shufflenet_v2_x0_5', 'shufflenet_v2_x1_0', 'shufflenet_v2_x1_5', 'shufflenet_v2_x2_0',
'squeezenet1_0', 'squeezenet1_1', 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn', 'vgg19_bn', 'vgg19'
]
for model in MODELS:
if hasattr(models, model):
BenchmarkRegistry.register_benchmark('pytorch-' + model, PytorchCNN, parameters='--model_type ' + model)
else:
logger.warning('model missing in torchvision.models - model: {}'.format(model))
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
"""Tests for CNN model benchmarks."""
from tests.helper import decorator
from superbench.benchmarks import BenchmarkRegistry, Platform, Framework, BenchmarkType, ReturnCode
from superbench.benchmarks.model_benchmarks.pytorch_cnn import PytorchCNN
@decorator.cuda_test
@decorator.pytorch_test
def test_pytorch_cnn_with_gpu():
"""Test pytorch cnn benchmarks with GPU."""
run_pytorch_cnn(
models=['resnet50', 'resnet101', 'resnet152', 'densenet169', 'densenet201', 'vgg11', 'vgg13', 'vgg16', 'vgg19'],
parameters='--batch_size 1 --image_size 224 --num_classes 5 --num_warmup 2 --num_steps 4 \
--model_action train inference',
check_metrics=[
'steptime_train_float32', 'throughput_train_float32', 'steptime_train_float16', 'throughput_train_float16',
'steptime_inference_float32', 'throughput_inference_float32', 'steptime_inference_float16',
'throughput_inference_float16'
]
)
@decorator.pytorch_test
def test_pytorch_cnn_no_gpu():
"""Test pytorch cnn benchmarks with CPU."""
run_pytorch_cnn(
models=['resnet50'],
parameters='--batch_size 1 --image_size 224 --num_classes 5 --num_warmup 2 --num_steps 4 \
--model_action train inference --precision float32 --no_gpu',
check_metrics=[
'steptime_train_float32', 'throughput_train_float32', 'steptime_inference_float32',
'throughput_inference_float32'
]
)
def run_pytorch_cnn(models=[], parameters='', check_metrics=[]):
"""Run pytorch cnn benchmarks."""
for model in models:
context = BenchmarkRegistry.create_benchmark_context(
model, platform=Platform.CUDA, parameters=parameters, framework=Framework.PYTORCH
)
assert (BenchmarkRegistry.is_benchmark_context_valid(context))
benchmark = BenchmarkRegistry.launch_benchmark(context)
# Check basic information.
assert (benchmark)
assert (isinstance(benchmark, PytorchCNN))
assert (benchmark.name == 'pytorch-' + model)
assert (benchmark.type == BenchmarkType.MODEL)
# Check predefined parameters of resnet101 model.
assert (benchmark._args.model_type == model)
# Check parameters specified in BenchmarkContext.
assert (benchmark._args.batch_size == 1)
assert (benchmark._args.image_size == 224)
assert (benchmark._args.num_classes == 5)
assert (benchmark._args.num_warmup == 2)
assert (benchmark._args.num_steps == 4)
# Check Dataset.
assert (len(benchmark._dataset) == benchmark._args.sample_count * benchmark._world_size)
# Check results and metrics.
assert (benchmark.run_count == 1)
assert (benchmark.return_code == ReturnCode.SUCCESS)
for metric in check_metrics:
assert (len(benchmark.raw_data[metric]) == benchmark.run_count)
assert (len(benchmark.raw_data[metric][0]) == benchmark._args.num_steps)
assert (len(benchmark.result[metric]) == benchmark.run_count)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment