| # 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. |
| |
| from __future__ import print_function |
| import sys, os |
| curr_path = os.path.dirname(os.path.abspath(os.path.expanduser(__file__))) |
| sys.path.append(os.path.join(curr_path, "../../../amalgamation/python/")) |
| from mxnet_predict import Predictor, load_ndarray_file |
| |
| import ctypes |
| import numpy as np |
| import mxnet as mx |
| import mxnet.ndarray as nd |
| from mxnet.ndarray import NDArray |
| from mxnet import gluon |
| from mxnet.test_utils import assert_almost_equal, download_model |
| from mxnet.contrib.amp import amp |
| from mxnet.base import NDArrayHandle, py_str |
| sys.path.insert(0, os.path.join(curr_path, '../unittest')) |
| from common import setup_module, with_seed, teardown |
| |
| @with_seed() |
| def test_predictor_with_dtype(): |
| prefix = 'test_predictor_simple_dense' |
| symbol_file = "%s-symbol.json" % prefix |
| param_file = "%s-0000.params" % prefix |
| |
| input1 = np.random.uniform(size=(1, 3)) |
| input1 = input1.astype(np.float16) |
| |
| block = mx.gluon.nn.HybridSequential() |
| block.add(mx.gluon.nn.Dense(7)) |
| block.add(mx.gluon.nn.Dense(3)) |
| block.cast(np.float16) |
| block.hybridize() |
| block.initialize(ctx=mx.gpu(0)) |
| tmp = mx.nd.array(input1, dtype=np.float16, ctx=mx.gpu(0)) |
| out1 = block.forward(tmp) |
| block.export(prefix) |
| |
| predictor = Predictor(open(symbol_file, "r").read(), |
| open(param_file, "rb").read(), |
| {"data": input1.shape}, |
| dev_type="gpu", |
| dev_id=0, |
| type_dict={"data": input1.dtype}) |
| predictor.forward(data=input1) |
| predictor_out1 = predictor.get_output(0) |
| |
| assert_almost_equal(out1.asnumpy(), predictor_out1, rtol=1e-5, atol=1e-6) |
| |
| def compare_module_cpredict(result_sym, result_arg_params, result_aux_params, monitor_callback=False): |
| # Dummmy inputs |
| input1 = np.ones((1, 3, 224, 224)) |
| input1 = input1.astype(np.float32) |
| nd_dict = {} |
| def pred_mon_callback(name, arr): |
| nd_dict[name] = arr |
| mod = mx.mod.Module(result_sym, data_names=["data"], label_names=["softmax_label"], context=mx.gpu()) |
| mod.bind(data_shapes=[['data', (1, 3, 224, 224)]], label_shapes=[['softmax_label', (1,)]], for_training=False) |
| mod.set_params(result_arg_params, result_aux_params) |
| mod.forward(mx.io.DataBatch(data=[mx.nd.array(input1, ctx=mx.gpu())], |
| label=[mx.nd.ones((1,), ctx=mx.gpu())])) |
| prefix = "test_predictor_amp" |
| mod.save_checkpoint(prefix, 0, remove_amp_cast=False) |
| sym_file = "{}-symbol.json".format(prefix) |
| params_file = "{}-0000.params".format(prefix) |
| predictor = Predictor(open(sym_file, "r").read(), |
| open(params_file, "rb").read(), |
| {'data': (1, 3, 224, 224), |
| 'softmax_label': (1,)}, |
| dev_type="gpu", |
| dev_id=0) |
| if monitor_callback: |
| predictor.set_monitor_callback(pred_mon_callback, monitor_all=True) |
| predictor.forward(data=input1, softmax_label=mx.nd.ones((1,)).asnumpy()) |
| predictor_out1 = predictor.get_output(0) |
| if monitor_callback: |
| assert len(nd_dict) > 0, "Callback not called" |
| assert_almost_equal(mod.get_outputs()[0].asnumpy(), predictor_out1, atol=1e-1, rtol=1e-1) |
| |
| |
| @with_seed() |
| def test_predictor_amp(): |
| dir_path = os.path.dirname(os.path.realpath(__file__)) |
| model_path = os.path.join(dir_path, 'model') |
| if not os.path.isdir(model_path): |
| os.mkdir(model_path) |
| prefix, epoch = download_model("imagenet1k-resnet-18", dst_dir=model_path) |
| |
| sym, arg_params, aux_params = mx.model.load_checkpoint(prefix, epoch) |
| |
| |
| # Convert model to mixed precision model, params in FP32 |
| result_sym, result_arg_params, result_aux_params = amp.convert_model(sym, |
| arg_params, |
| aux_params, |
| target_dtype="float16", |
| target_dtype_ops=["Convolution"]) |
| compare_module_cpredict(result_sym, result_arg_params, result_aux_params) |
| |
| # Convert model to mixed precision model, params in FP16 |
| result_sym, result_arg_params, result_aux_params = amp.convert_model(sym, |
| arg_params, |
| aux_params, |
| target_dtype="float16", |
| target_dtype_ops=["Convolution"], |
| cast_optional_params=True) |
| compare_module_cpredict(result_sym, result_arg_params, result_aux_params, monitor_callback=True) |
| |
| |
| if __name__ == '__main__': |
| import nose |
| nose.runmodule() |