From 51a7fcdbdedf637419b8a5a457653b94c36d8e92 Mon Sep 17 00:00:00 2001 From: Jambay Kinley Date: Fri, 8 Sep 2023 04:25:59 +0000 Subject: [PATCH 1/2] use p.run and automatic tmpdir --- .../passes/inc/test_inc_quantization.py | 98 ++++++++-------- .../passes/onnx/pipeline/test_step_utils.py | 9 +- test/unit_test/passes/onnx/test_conversion.py | 19 ++-- .../passes/onnx/test_insert_beam_search.py | 12 +- .../passes/onnx/test_mixed_precision.py | 12 +- .../passes/onnx/test_model_optimizer.py | 12 +- .../passes/onnx/test_optimum_conversion.py | 18 ++- .../unit_test/passes/onnx/test_perf_tuning.py | 26 ++--- .../onnx/test_pre_post_processing_op.py | 46 ++++---- .../onnx/test_transformer_optimization.py | 20 ++-- .../openvino/test_openvino_conversion.py | 38 +++---- .../openvino/test_openvino_quantization.py | 105 +++++++++--------- .../test_quantization_aware_training.py | 25 ++--- .../passes/pytorch/test_sparsegpt.py | 60 +++++----- .../pytorch/test_torch_trt_conversion.py | 86 +++++++------- .../vitis_ai/test_vitis_ai_quantization.py | 46 ++++---- 16 files changed, 280 insertions(+), 352 deletions(-) diff --git a/test/unit_test/passes/inc/test_inc_quantization.py b/test/unit_test/passes/inc/test_inc_quantization.py index 357b467cd0..ae01c578d6 100644 --- a/test/unit_test/passes/inc/test_inc_quantization.py +++ b/test/unit_test/passes/inc/test_inc_quantization.py @@ -3,7 +3,6 @@ # Licensed under the MIT License. # -------------------------------------------------------------------------- import platform -import tempfile from pathlib import Path import pytest @@ -15,62 +14,57 @@ from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx.conversion import OnnxConversion from olive.passes.onnx.inc_quantization import IncDynamicQuantization, IncQuantization, IncStaticQuantization -from olive.systems.local import LocalSystem @pytest.mark.skipif( platform.system() == "Windows", reason="Skip test on Windows. neural-compressor import is hanging on Windows." ) -def test_inc_quantization(): - with tempfile.TemporaryDirectory() as tempdir: - # setup - ov_model = get_onnx_model(tempdir) - local_system = LocalSystem() - data_dir = Path(tempdir) / "data" - data_dir.mkdir(exist_ok=True) - config = {"data_dir": data_dir, "dataloader_func": create_dataloader} - output_folder = str(Path(tempdir) / "quantized") - - # create IncQuantization pass - p = create_pass_from_dict(IncQuantization, config, disable_search=True) - # execute - quantized_model = local_system.run_pass(p, ov_model, None, output_folder) - # assert - assert quantized_model.model_path.endswith(".onnx") - assert Path(quantized_model.model_path).exists() - assert Path(quantized_model.model_path).is_file() - assert "QLinearConv" in [node.op_type for node in quantized_model.load_model().graph.node] - - # clean - del p - # create IncDynamicQuantization pass - p = create_pass_from_dict(IncDynamicQuantization, config, disable_search=True) - # execute - quantized_model = local_system.run_pass(p, ov_model, None, output_folder) - # assert - assert quantized_model.model_path.endswith(".onnx") - assert Path(quantized_model.model_path).exists() - assert Path(quantized_model.model_path).is_file() - assert "DynamicQuantizeLinear" in [node.op_type for node in quantized_model.load_model().graph.node] - - # clean - del p - # create IncStaticQuantization pass - p = create_pass_from_dict(IncStaticQuantization, config, disable_search=True) - # execute - quantized_model = local_system.run_pass(p, ov_model, None, output_folder) - # assert - assert quantized_model.model_path.endswith(".onnx") - assert Path(quantized_model.model_path).exists() - assert Path(quantized_model.model_path).is_file() - assert "QLinearConv" in [node.op_type for node in quantized_model.load_model().graph.node] - - -def get_onnx_model(tempdir): - local_system = LocalSystem() +def test_inc_quantization(tmpdir): + ov_model = get_onnx_model(tmpdir) + data_dir = Path(tmpdir) / "data" + data_dir.mkdir(exist_ok=True) + config = {"data_dir": data_dir, "dataloader_func": create_dataloader} + output_folder = str(Path(tmpdir) / "quantized") + + # create IncQuantization pass + p = create_pass_from_dict(IncQuantization, config, disable_search=True) + # execute + quantized_model = p.run(ov_model, None, output_folder) + # assert + assert quantized_model.model_path.endswith(".onnx") + assert Path(quantized_model.model_path).exists() + assert Path(quantized_model.model_path).is_file() + assert "QLinearConv" in [node.op_type for node in quantized_model.load_model().graph.node] + + # clean + del p + # create IncDynamicQuantization pass + p = create_pass_from_dict(IncDynamicQuantization, config, disable_search=True) + # execute + quantized_model = p.run(ov_model, None, output_folder) + # assert + assert quantized_model.model_path.endswith(".onnx") + assert Path(quantized_model.model_path).exists() + assert Path(quantized_model.model_path).is_file() + assert "DynamicQuantizeLinear" in [node.op_type for node in quantized_model.load_model().graph.node] + + # clean + del p + # create IncStaticQuantization pass + p = create_pass_from_dict(IncStaticQuantization, config, disable_search=True) + # execute + quantized_model = p.run(ov_model, None, output_folder) + # assert + assert quantized_model.model_path.endswith(".onnx") + assert Path(quantized_model.model_path).exists() + assert Path(quantized_model.model_path).is_file() + assert "QLinearConv" in [node.op_type for node in quantized_model.load_model().graph.node] + + +def get_onnx_model(tmpdir): torch_hub_model_path = "chenyaofo/pytorch-cifar-models" pytorch_hub_model_name = "cifar10_mobilenetv2_x1_0" - torch.hub.set_dir(tempdir) + torch.hub.set_dir(tmpdir) pytorch_model = PyTorchModel( model_loader=lambda torch_hub_model_path: torch.hub.load(torch_hub_model_path, pytorch_hub_model_name), model_path=torch_hub_model_path, @@ -79,10 +73,10 @@ def get_onnx_model(tempdir): onnx_conversion_config = {} p = create_pass_from_dict(OnnxConversion, onnx_conversion_config, disable_search=True) - output_folder = str(Path(tempdir) / "onnx") + output_folder = str(Path(tmpdir) / "onnx") # execute - onnx_model = local_system.run_pass(p, pytorch_model, None, output_folder) + onnx_model = p.run(pytorch_model, None, output_folder) return onnx_model diff --git a/test/unit_test/passes/onnx/pipeline/test_step_utils.py b/test/unit_test/passes/onnx/pipeline/test_step_utils.py index 8aa0d6f341..2540045bbd 100644 --- a/test/unit_test/passes/onnx/pipeline/test_step_utils.py +++ b/test/unit_test/passes/onnx/pipeline/test_step_utils.py @@ -3,7 +3,6 @@ # Licensed under the MIT License. # -------------------------------------------------------------------------- import json -import tempfile from pathlib import Path from test.unit_test.passes.onnx.test_pre_post_processing_op import ( convert_superresolution_model, @@ -11,7 +10,6 @@ ) from olive.passes.onnx.pipeline.step_utils import parse_steps -from olive.systems.local import LocalSystem class CustomizedParam: @@ -19,13 +17,12 @@ def __init__(self, params: dict): self.params = params -def test_step_parser(): +def test_step_parser(tmpdir): from onnxruntime_extensions.tools.pre_post_processing import TokenizerParam pytorch_model = get_superresolution_model() - with tempfile.TemporaryDirectory() as tempdir: - input_model = convert_superresolution_model(pytorch_model, tempdir, LocalSystem()) - model = input_model.load_model() + input_model = convert_superresolution_model(pytorch_model, tmpdir) + model = input_model.load_model() step_config = Path(__file__).parent / "step_config.json" with step_config.open() as f: diff --git a/test/unit_test/passes/onnx/test_conversion.py b/test/unit_test/passes/onnx/test_conversion.py index d16ffa2273..78bf50c343 100644 --- a/test/unit_test/passes/onnx/test_conversion.py +++ b/test/unit_test/passes/onnx/test_conversion.py @@ -1,4 +1,3 @@ -import tempfile from pathlib import Path from test.unit_test.utils import get_hf_model_with_past, get_pytorch_model @@ -6,21 +5,17 @@ from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx.conversion import OnnxConversion -from olive.systems.local import LocalSystem @pytest.mark.parametrize("input_model", [get_pytorch_model(), get_hf_model_with_past()]) -def test_onnx_conversion_pass(input_model): +def test_onnx_conversion_pass(input_model, tmpdir): # setup - local_system = LocalSystem() - p = create_pass_from_dict(OnnxConversion, {}, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "onnx") + output_folder = str(Path(tmpdir) / "onnx") - # The conversion need torch version > 1.13.1, otherwise, it will complain - # Unsupported ONNX opset version: 18 - onnx_model = local_system.run_pass(p, input_model, None, output_folder) + # The conversion need torch version > 1.13.1, otherwise, it will complain + # Unsupported ONNX opset version: 18 + onnx_model = p.run(input_model, None, output_folder) - # assert - assert Path(onnx_model.model_path).exists() + # assert + assert Path(onnx_model.model_path).exists() diff --git a/test/unit_test/passes/onnx/test_insert_beam_search.py b/test/unit_test/passes/onnx/test_insert_beam_search.py index 4be0ba562c..b5fd885068 100644 --- a/test/unit_test/passes/onnx/test_insert_beam_search.py +++ b/test/unit_test/passes/onnx/test_insert_beam_search.py @@ -1,16 +1,13 @@ -import tempfile from pathlib import Path from test.unit_test.utils import get_onnx_model from olive.model import CompositeOnnxModel from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx.insert_beam_search import InsertBeamSearch -from olive.systems.local import LocalSystem -def test_insert_beam_search_pass(): +def test_insert_beam_search_pass(tmpdir): # setup - local_system = LocalSystem() input_models = [] input_models.append(get_onnx_model()) input_models.append(get_onnx_model()) @@ -21,8 +18,7 @@ def test_insert_beam_search_pass(): ) p = create_pass_from_dict(InsertBeamSearch, {}, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "onnx") + output_folder = str(Path(tmpdir) / "onnx") - # execute - local_system.run_pass(p, composite_model, None, output_folder) + # execute + p.run(composite_model, None, output_folder) diff --git a/test/unit_test/passes/onnx/test_mixed_precision.py b/test/unit_test/passes/onnx/test_mixed_precision.py index 026f9f2492..6575a2ba10 100644 --- a/test/unit_test/passes/onnx/test_mixed_precision.py +++ b/test/unit_test/passes/onnx/test_mixed_precision.py @@ -1,19 +1,15 @@ -import tempfile from pathlib import Path from test.unit_test.utils import get_onnx_model from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx.mixed_precision import OrtMixedPrecision -from olive.systems.local import LocalSystem -def test_ort_mixed_precision_pass(): +def test_ort_mixed_precision_pass(tmpdir): # setup - local_system = LocalSystem() input_model = get_onnx_model() p = create_pass_from_dict(OrtMixedPrecision, {}, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "onnx") + output_folder = str(Path(tmpdir) / "onnx") - # execute - local_system.run_pass(p, input_model, None, output_folder) + # execute + p.run(input_model, None, output_folder) diff --git a/test/unit_test/passes/onnx/test_model_optimizer.py b/test/unit_test/passes/onnx/test_model_optimizer.py index 6178008a78..0d8e917c7d 100644 --- a/test/unit_test/passes/onnx/test_model_optimizer.py +++ b/test/unit_test/passes/onnx/test_model_optimizer.py @@ -2,22 +2,18 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. # -------------------------------------------------------------------------- -import tempfile from pathlib import Path from test.unit_test.utils import get_onnx_model from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx import OnnxModelOptimizer -from olive.systems.local import LocalSystem -def test_onnx_model_optimizer_pass(): +def test_onnx_model_optimizer_pass(tmpdir): # setup - local_system = LocalSystem() input_model = get_onnx_model() p = create_pass_from_dict(OnnxModelOptimizer, {}, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "onnx") + output_folder = str(Path(tmpdir) / "onnx") - # execute - local_system.run_pass(p, input_model, None, output_folder) + # execute + p.run(input_model, None, output_folder) diff --git a/test/unit_test/passes/onnx/test_optimum_conversion.py b/test/unit_test/passes/onnx/test_optimum_conversion.py index ab4b06a31f..3ce7a941b3 100644 --- a/test/unit_test/passes/onnx/test_optimum_conversion.py +++ b/test/unit_test/passes/onnx/test_optimum_conversion.py @@ -1,4 +1,3 @@ -import tempfile from pathlib import Path from test.unit_test.utils import get_optimum_model_by_hf_config, get_optimum_model_by_model_path @@ -6,17 +5,16 @@ from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx.optimum_conversion import OptimumConversion -from olive.systems.local import LocalSystem @pytest.mark.parametrize("input_model", [get_optimum_model_by_hf_config(), get_optimum_model_by_model_path()]) -def test_optimum_conversion_pass(input_model): +def test_optimum_conversion_pass(input_model, tmpdir): # setup - local_system = LocalSystem() - p = create_pass_from_dict(OptimumConversion, {}, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = Path(tempdir) - onnx_model = local_system.run_pass(p, input_model, None, output_folder) - # assert - assert Path(onnx_model.model_path).exists() + output_folder = Path(tmpdir) + + # execute + onnx_model = p.run(input_model, None, output_folder) + + # assert + assert Path(onnx_model.model_path).exists() diff --git a/test/unit_test/passes/onnx/test_perf_tuning.py b/test/unit_test/passes/onnx/test_perf_tuning.py index da66bf8517..022d57c463 100644 --- a/test/unit_test/passes/onnx/test_perf_tuning.py +++ b/test/unit_test/passes/onnx/test_perf_tuning.py @@ -2,7 +2,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. # -------------------------------------------------------------------------- -import tempfile from pathlib import Path from test.unit_test.utils import get_onnx_model from unittest.mock import patch @@ -11,24 +10,21 @@ from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx import OrtPerfTuning -from olive.systems.local import LocalSystem @pytest.mark.parametrize("config", [{"input_names": ["input"], "input_shapes": [[1, 1]]}, {}]) -def test_ort_perf_tuning_pass(config): +def test_ort_perf_tuning_pass(config, tmpdir): # setup - local_system = LocalSystem() input_model = get_onnx_model() p = create_pass_from_dict(OrtPerfTuning, config, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "onnx") + output_folder = str(Path(tmpdir) / "onnx") - # execute - local_system.run_pass(p, input_model, None, output_folder) + # execute + p.run(input_model, None, output_folder) @patch("olive.model.ONNXModel.get_io_config") -def test_ort_perf_tuning_pass_with_dynamic_shapes(mock_get_io_config): +def test_ort_perf_tuning_pass_with_dynamic_shapes(mock_get_io_config, tmpdir): mock_get_io_config.return_value = { "input_names": ["input"], "input_shapes": [["input_0", "input_1"]], @@ -38,13 +34,11 @@ def test_ort_perf_tuning_pass_with_dynamic_shapes(mock_get_io_config): "output_types": ["float32", "float32"], } - local_system = LocalSystem() input_model = get_onnx_model() p = create_pass_from_dict(OrtPerfTuning, {}, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "onnx") + output_folder = str(Path(tmpdir) / "onnx") - with pytest.raises(TypeError) as e: - # execute - local_system.run_pass(p, input_model, None, output_folder) - assert "ones() received an invalid combination of arguments" in str(e.value) + with pytest.raises(TypeError) as e: + # execute + p.run(input_model, None, output_folder) + assert "ones() received an invalid combination of arguments" in str(e.value) diff --git a/test/unit_test/passes/onnx/test_pre_post_processing_op.py b/test/unit_test/passes/onnx/test_pre_post_processing_op.py index f109ac7268..063d981ca3 100644 --- a/test/unit_test/passes/onnx/test_pre_post_processing_op.py +++ b/test/unit_test/passes/onnx/test_pre_post_processing_op.py @@ -1,16 +1,13 @@ -import tempfile from pathlib import Path from olive.model import ONNXModel, PyTorchModel from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx.append_pre_post_processing_ops import AppendPrePostProcessingOps from olive.passes.onnx.conversion import OnnxConversion -from olive.systems.local import LocalSystem -def test_pre_post_processing_op(): +def test_pre_post_processing_op(tmpdir): # setup - local_system = LocalSystem() p = create_pass_from_dict( AppendPrePostProcessingOps, {"tool_command": "superresolution", "tool_command_args": {"output_format": "png"}}, @@ -18,15 +15,14 @@ def test_pre_post_processing_op(): ) pytorch_model = get_superresolution_model() - with tempfile.TemporaryDirectory() as tempdir: - input_model = convert_superresolution_model(pytorch_model, tempdir, local_system) - output_folder = str(Path(tempdir) / "onnx") + input_model = convert_superresolution_model(pytorch_model, tmpdir) + output_folder = str(Path(tmpdir) / "onnx") - # execute - local_system.run_pass(p, input_model, None, output_folder) + # execute + p.run(input_model, None, output_folder) -def test_pre_post_pipeline(): +def test_pre_post_pipeline(tmpdir): config = { "pre": [ {"ConvertImageToBGR": {}}, @@ -108,23 +104,21 @@ def test_pre_post_pipeline(): ) assert p is not None - local_system = LocalSystem() pytorch_model = get_superresolution_model() - with tempfile.TemporaryDirectory() as tempdir: - input_model = convert_superresolution_model(pytorch_model, tempdir, local_system) - input_model_graph = input_model.get_graph() - assert input_model_graph.node[0].op_type == "Conv" - output_folder = str(Path(tempdir) / "onnx_pre_post") + input_model = convert_superresolution_model(pytorch_model, tmpdir) + input_model_graph = input_model.get_graph() + assert input_model_graph.node[0].op_type == "Conv" + output_folder = str(Path(tmpdir) / "onnx_pre_post") - # execute - model = local_system.run_pass(p, input_model, None, output_folder) - assert model is not None - assert isinstance(model, ONNXModel) - graph = model.get_graph() + # execute + model = p.run(input_model, None, output_folder) + assert model is not None + assert isinstance(model, ONNXModel) + graph = model.get_graph() - # assert the first node is ConvertImageToBGR - assert graph.node[0].op_type == "DecodeImage" - assert graph.node[0].domain == "com.microsoft.extensions" + # assert the first node is ConvertImageToBGR + assert graph.node[0].op_type == "DecodeImage" + assert graph.node[0].domain == "com.microsoft.extensions" def get_superresolution_model(): @@ -188,8 +182,8 @@ def load_pytorch_model(model_path: str) -> nn.Module: return pytorch_model -def convert_superresolution_model(pytorch_model, tempdir, local_system): +def convert_superresolution_model(pytorch_model, tmpdir): onnx_conversion_pass = create_pass_from_dict(OnnxConversion, {"target_opset": 15}, disable_search=True) - onnx_model = local_system.run_pass(onnx_conversion_pass, pytorch_model, None, str(Path(tempdir) / "onnx")) + onnx_model = onnx_conversion_pass.run(pytorch_model, None, str(Path(tmpdir) / "onnx")) return onnx_model diff --git a/test/unit_test/passes/onnx/test_transformer_optimization.py b/test/unit_test/passes/onnx/test_transformer_optimization.py index f88a779bf0..6db18a33cd 100644 --- a/test/unit_test/passes/onnx/test_transformer_optimization.py +++ b/test/unit_test/passes/onnx/test_transformer_optimization.py @@ -2,7 +2,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. # -------------------------------------------------------------------------- -import tempfile from copy import deepcopy from pathlib import Path from test.unit_test.utils import get_onnx_model @@ -13,7 +12,6 @@ from olive.hardware import DEFAULT_CPU_ACCELERATOR, DEFAULT_GPU_CUDA_ACCELERATOR, DEFAULT_GPU_TRT_ACCELERATOR from olive.passes.onnx import OrtTransformersOptimization from olive.passes.onnx.common import get_external_data_config -from olive.systems.local import LocalSystem def test_fusion_options(): @@ -39,19 +37,17 @@ def test_fusion_options(): assert vars(olive_fusion_options) == vars(ort_fusion_options) -def test_ort_transformer_optimization_pass(): +def test_ort_transformer_optimization_pass(tmpdir): # setup - local_system = LocalSystem() input_model = get_onnx_model() config = {"model_type": "bert"} config = OrtTransformersOptimization.generate_search_space(DEFAULT_CPU_ACCELERATOR, config, disable_search=True) p = OrtTransformersOptimization(DEFAULT_CPU_ACCELERATOR, config, True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "onnx") + output_folder = str(Path(tmpdir) / "onnx") - # execute - local_system.run_pass(p, input_model, None, output_folder) + # execute + p.run(input_model, None, output_folder) @pytest.mark.parametrize("use_gpu", [True, False]) @@ -59,8 +55,7 @@ def test_ort_transformer_optimization_pass(): @pytest.mark.parametrize( "accelerator_spec", [DEFAULT_CPU_ACCELERATOR, DEFAULT_GPU_CUDA_ACCELERATOR, DEFAULT_GPU_TRT_ACCELERATOR] ) -def test_invalid_ep_config(use_gpu, fp16, accelerator_spec): - local_system = LocalSystem() +def test_invalid_ep_config(use_gpu, fp16, accelerator_spec, tmpdir): input_model = get_onnx_model() config = {"model_type": "bert", "use_gpu": use_gpu, "float16": fp16} config = OrtTransformersOptimization.generate_search_space(accelerator_spec, config, disable_search=True) @@ -79,6 +74,5 @@ def test_invalid_ep_config(use_gpu, fp16, accelerator_spec): ) if not is_pruned: - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "onnx") - local_system.run_pass(p, input_model, None, output_folder) + output_folder = str(Path(tmpdir) / "onnx") + p.run(input_model, None, output_folder) diff --git a/test/unit_test/passes/openvino/test_openvino_conversion.py b/test/unit_test/passes/openvino/test_openvino_conversion.py index f13021c0f8..14742ab07e 100644 --- a/test/unit_test/passes/openvino/test_openvino_conversion.py +++ b/test/unit_test/passes/openvino/test_openvino_conversion.py @@ -2,51 +2,45 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. # -------------------------------------------------------------------------- -import tempfile from pathlib import Path from test.unit_test.utils import get_pytorch_model, get_pytorch_model_dummy_input from olive.passes.olive_pass import create_pass_from_dict from olive.passes.openvino.conversion import OpenVINOConversion -from olive.systems.local import LocalSystem -def test_openvino_conversion_pass(): +def test_openvino_conversion_pass(tmpdir): # setup - local_system = LocalSystem() input_model = get_pytorch_model() dummy_input = get_pytorch_model_dummy_input(input_model) openvino_conversion_config = {"extra_config": {"example_input": dummy_input}} p = create_pass_from_dict(OpenVINOConversion, openvino_conversion_config, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "openvino") + output_folder = str(Path(tmpdir) / "openvino") - # execute - openvino_model = local_system.run_pass(p, input_model, None, output_folder) + # execute + openvino_model = p.run(input_model, None, output_folder) - # assert - assert Path(openvino_model.model_path).exists() - assert (Path(openvino_model.model_path) / "ov_model.bin").is_file() - assert (Path(openvino_model.model_path) / "ov_model.xml").is_file() + # assert + assert Path(openvino_model.model_path).exists() + assert (Path(openvino_model.model_path) / "ov_model.bin").is_file() + assert (Path(openvino_model.model_path) / "ov_model.xml").is_file() -def test_openvino_conversion_pass_no_example_input(): +def test_openvino_conversion_pass_no_example_input(tmpdir): # setup - local_system = LocalSystem() input_model = get_pytorch_model() openvino_conversion_config = { "input_shape": [1, 1], } p = create_pass_from_dict(OpenVINOConversion, openvino_conversion_config, disable_search=True) - with tempfile.TemporaryDirectory() as tempdir: - output_folder = str(Path(tempdir) / "openvino") + output_folder = str(Path(tmpdir) / "openvino") - # execute - openvino_model = local_system.run_pass(p, input_model, None, output_folder) + # execute + openvino_model = p.run(input_model, None, output_folder) - # assert - assert Path(openvino_model.model_path).exists() - assert (Path(openvino_model.model_path) / "ov_model.bin").is_file() - assert (Path(openvino_model.model_path) / "ov_model.xml").is_file() + # assert + assert Path(openvino_model.model_path).exists() + assert (Path(openvino_model.model_path) / "ov_model.bin").is_file() + assert (Path(openvino_model.model_path) / "ov_model.xml").is_file() diff --git a/test/unit_test/passes/openvino/test_openvino_quantization.py b/test/unit_test/passes/openvino/test_openvino_quantization.py index 4e8f729a5c..e9e5a03d13 100644 --- a/test/unit_test/passes/openvino/test_openvino_quantization.py +++ b/test/unit_test/passes/openvino/test_openvino_quantization.py @@ -2,7 +2,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. # -------------------------------------------------------------------------- -import tempfile from pathlib import Path import pytest @@ -17,70 +16,66 @@ from olive.passes.olive_pass import create_pass_from_dict from olive.passes.openvino.conversion import OpenVINOConversion from olive.passes.openvino.quantization import OpenVINOQuantization -from olive.systems.local import LocalSystem @pytest.mark.parametrize("data_source", ["dataloader_func", "data_config"]) -def test_openvino_quantization(data_source): +def test_openvino_quantization(data_source, tmpdir): # setup - with tempfile.TemporaryDirectory() as tempdir: - ov_model = get_openvino_model(tempdir) - local_system = LocalSystem() - data_dir = Path(tempdir) / "data" - data_dir.mkdir(exist_ok=True) - config = { - "engine_config": {"device": "CPU"}, - "algorithms": [ - { - "name": "DefaultQuantization", - "params": {"target_device": "CPU", "preset": "performance", "stat_subset_size": 500}, - } - ], - } - if data_source == "dataloader_func": - config.update( - { - "dataloader_func": create_dataloader, - "data_dir": data_dir, - } - ) - elif data_source == "data_config": - config.update( - { - "data_config": DataConfig( - components={ - "load_dataset": { - "name": "cifar10_dataset", - "type": "cifar10_dataset", - "params": {"data_dir": data_dir}, - } + ov_model = get_openvino_model(tmpdir) + data_dir = Path(tmpdir) / "data" + data_dir.mkdir(exist_ok=True) + config = { + "engine_config": {"device": "CPU"}, + "algorithms": [ + { + "name": "DefaultQuantization", + "params": {"target_device": "CPU", "preset": "performance", "stat_subset_size": 500}, + } + ], + } + if data_source == "dataloader_func": + config.update( + { + "dataloader_func": create_dataloader, + "data_dir": data_dir, + } + ) + elif data_source == "data_config": + config.update( + { + "data_config": DataConfig( + components={ + "load_dataset": { + "name": "cifar10_dataset", + "type": "cifar10_dataset", + "params": {"data_dir": data_dir}, } - ) - } - ) - p = create_pass_from_dict( - OpenVINOQuantization, - config, - disable_search=True, - accelerator_spec=AcceleratorSpec("cpu", "OpenVINOExecutionProvider"), + } + ) + } ) - output_folder = str(Path(tempdir) / "quantized") + p = create_pass_from_dict( + OpenVINOQuantization, + config, + disable_search=True, + accelerator_spec=AcceleratorSpec("cpu", "OpenVINOExecutionProvider"), + ) + output_folder = str(Path(tmpdir) / "quantized") - # execute - quantized_model = local_system.run_pass(p, ov_model, None, output_folder) + # execute + quantized_model = p.run(ov_model, None, output_folder) - # assert - assert Path(quantized_model.model_path).exists() - assert (Path(quantized_model.model_path) / "ov_model.bin").is_file() - assert (Path(quantized_model.model_path) / "ov_model.xml").is_file() - assert (Path(quantized_model.model_path) / "ov_model.mapping").is_file() + # assert + assert Path(quantized_model.model_path).exists() + assert (Path(quantized_model.model_path) / "ov_model.bin").is_file() + assert (Path(quantized_model.model_path) / "ov_model.xml").is_file() + assert (Path(quantized_model.model_path) / "ov_model.mapping").is_file() -def get_openvino_model(tempdir): - local_system = LocalSystem() +def get_openvino_model(tmpdir): torch_hub_model_path = "chenyaofo/pytorch-cifar-models" pytorch_hub_model_name = "cifar10_mobilenetv2_x1_0" - torch.hub.set_dir(tempdir) + torch.hub.set_dir(tmpdir) pytorch_model = PyTorchModel( model_loader=lambda torch_hub_model_path: torch.hub.load(torch_hub_model_path, pytorch_hub_model_name), model_path=torch_hub_model_path, @@ -95,10 +90,10 @@ def get_openvino_model(tempdir): disable_search=True, accelerator_spec=AcceleratorSpec("cpu", "OpenVINOExecutionProvider"), ) - output_folder = str(Path(tempdir) / "openvino") + output_folder = str(Path(tmpdir) / "openvino") # execute - openvino_model = local_system.run_pass(p, pytorch_model, None, output_folder) + openvino_model = p.run(pytorch_model, None, output_folder) return openvino_model diff --git a/test/unit_test/passes/pytorch/test_quantization_aware_training.py b/test/unit_test/passes/pytorch/test_quantization_aware_training.py index bd7d8e4547..07a9e16487 100644 --- a/test/unit_test/passes/pytorch/test_quantization_aware_training.py +++ b/test/unit_test/passes/pytorch/test_quantization_aware_training.py @@ -2,28 +2,23 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. # -------------------------------------------------------------------------- -import tempfile from pathlib import Path from test.unit_test.utils import create_dataloader, get_pytorch_model from olive.passes.olive_pass import create_pass_from_dict from olive.passes.pytorch import QuantizationAwareTraining -from olive.systems.local import LocalSystem -def test_quantization_aware_training_pass_default(): +def test_quantization_aware_training_pass_default(tmpdir): # setup + input_model = get_pytorch_model() + config = { + "train_dataloader_func": create_dataloader, + "checkpoint_path": str(Path(tmpdir) / "checkpoint"), + } - with tempfile.TemporaryDirectory() as tempdir: - local_system = LocalSystem() - input_model = get_pytorch_model() - config = { - "train_dataloader_func": create_dataloader, - "checkpoint_path": str(Path(tempdir) / "checkpoint"), - } + p = create_pass_from_dict(QuantizationAwareTraining, config, disable_search=True) + output_folder = str(Path(tmpdir) / "onnx") - p = create_pass_from_dict(QuantizationAwareTraining, config, disable_search=True) - output_folder = str(Path(tempdir) / "onnx") - - # execute - local_system.run_pass(p, input_model, None, output_folder) + # execute + p.run(input_model, None, output_folder) diff --git a/test/unit_test/passes/pytorch/test_sparsegpt.py b/test/unit_test/passes/pytorch/test_sparsegpt.py index 2791c8ccb4..065daf532e 100644 --- a/test/unit_test/passes/pytorch/test_sparsegpt.py +++ b/test/unit_test/passes/pytorch/test_sparsegpt.py @@ -2,46 +2,42 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. # -------------------------------------------------------------------------- -import tempfile from pathlib import Path from olive.data.template import huggingface_data_config_template from olive.model import PyTorchModel from olive.passes.olive_pass import create_pass_from_dict from olive.passes.pytorch import SparseGPT -from olive.systems.local import LocalSystem -def test_sparsegpt(): +def test_sparsegpt(tmpdir): # setup - with tempfile.TemporaryDirectory() as tempdir: - local_system = LocalSystem() - model_name = "sshleifer/tiny-gpt2" - task = "text-generation" - input_model = PyTorchModel(hf_config={"model_name": model_name, "task": task}) - dataset = { - "data_name": "ptb_text_only", - "subset": "penn_treebank", - "split": "train", - "component_kwargs": { - "pre_process_data": { - "dataset_type": "corpus", - "text_cols": ["sentence"], - "corpus_strategy": "join-random", - "source_max_len": 1024, - "max_samples": 1, - "random_seed": 42, - } - }, - } - data_config = huggingface_data_config_template(model_name=model_name, task=task, **dataset) - config = { - "sparsity": [2, 4], - "data_config": data_config, - } + model_name = "sshleifer/tiny-gpt2" + task = "text-generation" + input_model = PyTorchModel(hf_config={"model_name": model_name, "task": task}) + dataset = { + "data_name": "ptb_text_only", + "subset": "penn_treebank", + "split": "train", + "component_kwargs": { + "pre_process_data": { + "dataset_type": "corpus", + "text_cols": ["sentence"], + "corpus_strategy": "join-random", + "source_max_len": 1024, + "max_samples": 1, + "random_seed": 42, + } + }, + } + data_config = huggingface_data_config_template(model_name=model_name, task=task, **dataset) + config = { + "sparsity": [2, 4], + "data_config": data_config, + } - p = create_pass_from_dict(SparseGPT, config, disable_search=True) - output_folder = str(Path(tempdir) / "sparse") + p = create_pass_from_dict(SparseGPT, config, disable_search=True) + output_folder = str(Path(tmpdir) / "sparse") - # execute - local_system.run_pass(p, input_model, None, output_folder) + # execute + p.run(input_model, None, output_folder) diff --git a/test/unit_test/passes/pytorch/test_torch_trt_conversion.py b/test/unit_test/passes/pytorch/test_torch_trt_conversion.py index d8a3756432..caea52cac3 100644 --- a/test/unit_test/passes/pytorch/test_torch_trt_conversion.py +++ b/test/unit_test/passes/pytorch/test_torch_trt_conversion.py @@ -3,7 +3,6 @@ # Licensed under the MIT License. # -------------------------------------------------------------------------- import sys -import tempfile from pathlib import Path from unittest.mock import MagicMock, patch @@ -15,7 +14,6 @@ from olive.model import PyTorchModel from olive.passes.olive_pass import create_pass_from_dict from olive.passes.pytorch import TorchTRTConversion -from olive.systems.local import LocalSystem class MockTRTLinearLayer(torch.nn.Module): @@ -38,7 +36,7 @@ def mocked_torch_zeros(*args, **kwargs): # replace device in kwargs with "cpu" @patch("torch.zeros", side_effect=mocked_torch_zeros) def test_torch_trt_conversion_success( - mock_torch_zeros, mock_torch_nn_module_to, mock_tensor_data_to_device, mock_torch_cuda_is_available + mock_torch_zeros, mock_torch_nn_module_to, mock_tensor_data_to_device, mock_torch_cuda_is_available, tmpdir ): # setup # mock trt utils since we don't have tensorrt and torch-tensorrt installed @@ -49,50 +47,50 @@ def test_torch_trt_conversion_success( # we don't want to import trt_utils because of missing tensorrt and torch-tensorrt # add mocked trt_utils to sys.modules sys.modules["olive.passes.pytorch.trt_utils"] = mock_trt_utils - with tempfile.TemporaryDirectory() as tempdir: - local_system = LocalSystem() - model_name = "hf-internal-testing/tiny-random-OPTForCausalLM" - task = "text-generation" - model_type = "opt" - input_model = PyTorchModel(hf_config={"model_name": model_name, "task": task}) - # torch.nn.Linear submodules per layer in the original model - original_submodules = list( - sparsegpt_utils.get_layer_submodules( - sparsegpt_utils.get_layers(input_model.load_model(), model_type)[0], submodule_types=[torch.nn.Linear] - ).keys() - ) + model_name = "hf-internal-testing/tiny-random-OPTForCausalLM" + task = "text-generation" + model_type = "opt" + input_model = PyTorchModel(hf_config={"model_name": model_name, "task": task}) + # torch.nn.Linear submodules per layer in the original model + original_submodules = list( + sparsegpt_utils.get_layer_submodules( + sparsegpt_utils.get_layers(input_model.load_model(), model_type)[0], submodule_types=[torch.nn.Linear] + ).keys() + ) - dataset = { - "data_name": "ptb_text_only", - "subset": "penn_treebank", - "split": "train", - "component_kwargs": { - "pre_process_data": { - "dataset_type": "corpus", - "text_cols": ["sentence"], - "corpus_strategy": "join-random", - "source_max_len": 100, - "max_samples": 1, - "random_seed": 42, - } - }, - } - data_config = huggingface_data_config_template(model_name=model_name, task=task, **dataset) - config = { - "data_config": data_config, - } + dataset = { + "data_name": "ptb_text_only", + "subset": "penn_treebank", + "split": "train", + "component_kwargs": { + "pre_process_data": { + "dataset_type": "corpus", + "text_cols": ["sentence"], + "corpus_strategy": "join-random", + "source_max_len": 100, + "max_samples": 1, + "random_seed": 42, + } + }, + } + data_config = huggingface_data_config_template(model_name=model_name, task=task, **dataset) + config = { + "data_config": data_config, + } - p = create_pass_from_dict(TorchTRTConversion, config, disable_search=True) - output_folder = str(Path(tempdir) / "sparse") + p = create_pass_from_dict(TorchTRTConversion, config, disable_search=True) + output_folder = str(Path(tmpdir) / "sparse") - # execute - model = local_system.run_pass(p, input_model, None, output_folder) + # execute + model = p.run(input_model, None, output_folder) + + # assert + pytorch_model = model.load_model() + layers = sparsegpt_utils.get_layers(pytorch_model, model_type) + for layer in layers: + for submodule_name in original_submodules: + # check that the submodule is replaced with MockTRTLinearLayer + assert isinstance(get_attr(layer, submodule_name), MockTRTLinearLayer) - pytorch_model = model.load_model() - layers = sparsegpt_utils.get_layers(pytorch_model, model_type) - for layer in layers: - for submodule_name in original_submodules: - # check that the submodule is replaced with MockTRTLinearLayer - assert isinstance(get_attr(layer, submodule_name), MockTRTLinearLayer) # cleanup del sys.modules["olive.passes.pytorch.trt_utils"] diff --git a/test/unit_test/passes/vitis_ai/test_vitis_ai_quantization.py b/test/unit_test/passes/vitis_ai/test_vitis_ai_quantization.py index fd1a3299e8..3c4c253c34 100644 --- a/test/unit_test/passes/vitis_ai/test_vitis_ai_quantization.py +++ b/test/unit_test/passes/vitis_ai/test_vitis_ai_quantization.py @@ -3,7 +3,6 @@ # Licensed under the MIT License. # -------------------------------------------------------------------------- import os -import tempfile from pathlib import Path from test.unit_test.utils import get_onnx_model @@ -12,7 +11,6 @@ from olive.passes.olive_pass import create_pass_from_dict from olive.passes.onnx.vitis_ai_quantization import VitisAIQuantization -from olive.systems.local import LocalSystem class RandomDataReader(CalibrationDataReader): @@ -36,26 +34,24 @@ def dummy_calibration_reader(data_dir=None, batch_size=1, *args, **kwargs): return RandomDataReader() -def test_vitis_ai_quantization_pass(): - with tempfile.TemporaryDirectory() as tempdir: - # setup - local_system = LocalSystem() - input_model = get_onnx_model() - dummy_user_script = str(Path(tempdir) / "dummy_user_script.py") - dummy_data = str(Path(tempdir) / "dummy_data") - with open(dummy_user_script, "w") as f: - f.write(" ") - if not os.path.exists(dummy_data): - os.mkdir(dummy_data) - - config = {"user_script": dummy_user_script, "data_dir": dummy_data, "dataloader_func": dummy_calibration_reader} - output_folder = str(Path(tempdir) / "vitis_ai_quantized") - - # create VitisAIQuantization pass - p = create_pass_from_dict(VitisAIQuantization, config, disable_search=True) - # execute - quantized_model = local_system.run_pass(p, input_model, None, output_folder) - # assert - assert quantized_model.model_path.endswith(".onnx") - assert Path(quantized_model.model_path).exists() - assert Path(quantized_model.model_path).is_file() +def test_vitis_ai_quantization_pass(tmpdir): + # setup + input_model = get_onnx_model() + dummy_user_script = str(Path(tmpdir) / "dummy_user_script.py") + dummy_data = str(Path(tmpdir) / "dummy_data") + with open(dummy_user_script, "w") as f: + f.write(" ") + if not os.path.exists(dummy_data): + os.mkdir(dummy_data) + + config = {"user_script": dummy_user_script, "data_dir": dummy_data, "dataloader_func": dummy_calibration_reader} + output_folder = str(Path(tmpdir) / "vitis_ai_quantized") + + # create VitisAIQuantization pass + p = create_pass_from_dict(VitisAIQuantization, config, disable_search=True) + # execute + quantized_model = p.run(input_model, None, output_folder) + # assert + assert quantized_model.model_path.endswith(".onnx") + assert Path(quantized_model.model_path).exists() + assert Path(quantized_model.model_path).is_file() From 4ff96db13146934b5f61997a896fa907636347f9 Mon Sep 17 00:00:00 2001 From: Jambay Kinley Date: Fri, 8 Sep 2023 04:33:50 +0000 Subject: [PATCH 2/2] update qlora pass test --- test/unit_test/passes/pytorch/test_qlora.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/unit_test/passes/pytorch/test_qlora.py b/test/unit_test/passes/pytorch/test_qlora.py index 820f08833e..4fd4e9b2af 100644 --- a/test/unit_test/passes/pytorch/test_qlora.py +++ b/test/unit_test/passes/pytorch/test_qlora.py @@ -9,7 +9,6 @@ from olive.model import PyTorchModel from olive.passes.olive_pass import create_pass_from_dict from olive.passes.pytorch import QLoRA -from olive.systems.local import LocalSystem def patched_find_all_linear_names(model): @@ -21,7 +20,6 @@ def patched_find_all_linear_names(model): @patch("olive.passes.pytorch.qlora.QLoRA.find_all_linear_names", side_effect=patched_find_all_linear_names) def test_qlora(patched_model_loading_args, patched_find_all_linear_names, tmpdir): # setup - local_system = LocalSystem() model_name = "hf-internal-testing/tiny-random-OPTForCausalLM" task = "text-generation" input_model = PyTorchModel(hf_config={"model_name": model_name, "task": task}) @@ -59,5 +57,5 @@ def test_qlora(patched_model_loading_args, patched_find_all_linear_names, tmpdir output_folder = str(Path(tmpdir) / "qlora") # execute - out = local_system.run_pass(p, input_model, None, output_folder) + out = p.run(input_model, None, output_folder) assert Path(out.get_local_resource("adapter_path")).exists()