From fd8942eff016f9394bb8339af3d6669bd719815e Mon Sep 17 00:00:00 2001 From: Yu-Zhewen Date: Tue, 14 Nov 2023 16:11:36 +0000 Subject: [PATCH] update bilinear upsampling results --- README.md | 8 +-- models/base.py | 5 +- models/segmentation/camvid.py | 7 ++- .../segmentation}/utils.py | 14 ++--- models/utils.py | 4 +- transpose_conv_approximation_example.py | 62 ------------------- 6 files changed, 23 insertions(+), 77 deletions(-) rename {conv_transp_approx => models/segmentation}/utils.py (91%) delete mode 100644 transpose_conv_approximation_example.py diff --git a/README.md b/README.md index 64d5ad3..0062621 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,10 @@ bash scripts/run_quantization.sh | yolov8n | [ultralytics](https://github.com/ultralytics/ultralytics) | 37.1 | 37.1 | 0.0 | 0.0 | 35.1 | ### camvid (val, mIOU) -| Model | Source | Float32 | Fixed16 | Fixed8 | BFP8 (Layer) | BFP8 (Channel) | -|-------|-------------------------------------------------|---------|---------|--------|--------------|----------------| -| unet | [nncf](https://github.com/openvinotoolkit/nncf) | 71.95 | 71.95 | 61.02 | 71.60 | 71.85 | -| unet-approx | [nncf](https://github.com/openvinotoolkit/nncf) | 71.67 | - | - | - | - | +| Model | Source | Float32 | Fixed16 | Fixed8 | BFP8 (Layer) | BFP8 (Channel) | +|---------------|-------------------------------------------------|---------|---------|--------|--------------|----------------| +| unet | [nncf](https://github.com/openvinotoolkit/nncf) | 71.95 | 71.95 | 61.02 | 71.60 | 71.85 | +| unet-bilinear | [nncf](https://github.com/openvinotoolkit/nncf) | 71.67 | 71.67 | 60.62 | 71.40 | 71.75 | ### cityscapes (val, mIOU) | Model | Source | Float32 | Fixed16 | Fixed8 | BFP8 (Layer) | BFP8 (Channel) | diff --git a/models/base.py b/models/base.py index 6a94db2..78b590c 100644 --- a/models/base.py +++ b/models/base.py @@ -28,5 +28,8 @@ def onnx_exporter(self): def forward(self, x): return self.model(x) - from models.utils import replace_modules + def replace_modules(self, replace_dict): + from models.utils import replace_modules + replace_modules(self.model, replace_dict) + from models.utils import generate_onnx_files \ No newline at end of file diff --git a/models/segmentation/camvid.py b/models/segmentation/camvid.py index 19234d9..45c9279 100644 --- a/models/segmentation/camvid.py +++ b/models/segmentation/camvid.py @@ -8,6 +8,7 @@ from collections import OrderedDict from models.base import TorchModelWrapper +from models.segmentation.utils import apply_conv_transp_approx from PIL import Image from torch.utils import data @@ -18,7 +19,7 @@ def __init__(self, model_name, input_size=(1, 3, 368, 480), num_classes=12): self.num_classes = num_classes super().__init__(model_name) - def load_model(self, eval=True): + def load_model(self, eval=True, approx_transpose_conv=True): assert self.model_name == 'unet' self.model = UNet(input_size_hw=self.input_size[2:], in_channels=self.input_size[1], n_classes=self.num_classes) @@ -27,6 +28,10 @@ def load_model(self, eval=True): # remove 'module.' prefix state_dict = {k.replace('module.', ''): v for k, v in state_dict.items()} self.model.load_state_dict(state_dict) + + if approx_transpose_conv: + apply_conv_transp_approx(self.model) + if torch.cuda.is_available(): self.model = self.model.cuda() diff --git a/conv_transp_approx/utils.py b/models/segmentation/utils.py similarity index 91% rename from conv_transp_approx/utils.py rename to models/segmentation/utils.py index d068bf8..d707436 100644 --- a/conv_transp_approx/utils.py +++ b/models/segmentation/utils.py @@ -1,9 +1,10 @@ +import math import torch + +from models.utils import replace_modules from torch import nn -import math -CONV_TRANSP_MODULES = ( - nn.ConvTranspose1d, nn.ConvTranspose2d, nn.ConvTranspose3d) +CONV_TRANSP_MODULES = (nn.ConvTranspose1d, nn.ConvTranspose2d, nn.ConvTranspose3d) class ConvTranspApproxLayer(nn.Module): def __init__(self, parent_module, upsampling_mode, kernel_approx_strategy): @@ -62,12 +63,11 @@ def forward(self, x): return x - -def apply_conv_transp_approx(model_wrapper, upsampling_mode, kernel_approx_strategy): +def apply_conv_transp_approx(model, upsampling_mode="bilinear", kernel_approx_strategy="average"): replace_dict = {} - for name, module in model_wrapper.named_modules(): + for name, module in model.named_modules(): if isinstance(module, CONV_TRANSP_MODULES): new_module = ConvTranspApproxLayer( parent_module=module, upsampling_mode=upsampling_mode, kernel_approx_strategy=kernel_approx_strategy) replace_dict[module] = new_module - model_wrapper.replace_modules(replace_dict) + replace_modules(model, replace_dict) \ No newline at end of file diff --git a/models/utils.py b/models/utils.py index c074f2c..7d9b4dd 100644 --- a/models/utils.py +++ b/models/utils.py @@ -5,8 +5,8 @@ import torch.nn as nn -def replace_modules(self, replace_dict): - for name, module in self.model.named_modules(): +def replace_modules(model, replace_dict): + for name, module in model.named_modules(): for subname, submodule in module.named_children(): if submodule in replace_dict.keys(): new_submodule = replace_dict[submodule] diff --git a/transpose_conv_approximation_example.py b/transpose_conv_approximation_example.py deleted file mode 100644 index 12804b9..0000000 --- a/transpose_conv_approximation_example.py +++ /dev/null @@ -1,62 +0,0 @@ -import argparse -import copy -import os -import pathlib -import random -import torch - -from models import initialize_wrapper -from quantization.utils import QuantMode, quantize_model -from conv_transp_approx.utils import apply_conv_transp_approx - -def main(): - parser = argparse.ArgumentParser(description='Transpose Convolution Approximation Example') - parser.add_argument('--dataset_name', default="camvid", type=str, - help='dataset name') - parser.add_argument('--dataset_path', metavar='DIR', default="~/dataset/ILSVRC2012_img", - help='path to dataset') - parser.add_argument('--model_name', metavar='ARCH', default='unet', - help='model architecture') - - parser.add_argument('-j', '--workers', default=4, type=int, metavar='N', - help='number of data loading workers') - parser.add_argument('-b', '--batch-size', default=16, type=int, metavar='N', - help='mini-batch size') - parser.add_argument('--gpu', default=None, type=int, - help='GPU id to use.') - - parser.add_argument('--output_path', default=None, type=str, - help='output path') - - - args = parser.parse_args() - if args.output_path == None: - args.output_path = os.getcwd() + "/output" - pathlib.Path(args.output_path).mkdir(parents=True, exist_ok=True) - print(args) - - if args.gpu is not None: - torch.cuda.set_device(args.gpu) - - random.seed(0) - torch.manual_seed(0) - - model_wrapper = initialize_wrapper(args.dataset_name, args.model_name, - os.path.expanduser(args.dataset_path), args.batch_size, args.workers) - - # TEST 1 - print("FLOAT32 Inference") - model_wrapper.inference("test") - model_wrapper.generate_onnx_files(os.path.join(args.output_path, "fp32")) - - - # TEST 12 - apply_conv_transp_approx(model_wrapper=model_wrapper, upsampling_mode="bilinear", kernel_approx_strategy="average") - print("FLOAT32 Inference Conv Transpose Approximation") - model_wrapper.inference("test") - # FIXME: if we use generate_onnx_files here the onnx saved model does not contain the changes made by apply_conv_transp_approx - model_wrapper.onnx_exporter(os.path.join(args.output_path, "fp32_approx", f"{args.model_name}_f32.onnx")) - -if __name__ == '__main__': - main() -