Esempio n. 1
0
 def _create_flexflow_layers(self):
     self._my_onnx_model = ONNXModelKeras(self._onnx_model, self._ffconfig,
                                          self._ffmodel)
     input_dict = {}
     for input_tensor in self._input_tensors:
         key = "input_" + str(input_tensor.key)
         input_dict[key] = input_tensor.ffhandle
     self._output_tensor = self._my_onnx_model.apply(
         self._ffmodel, input_dict)
def top_level_task(test_type=1):
    ffconfig = FFConfig()
    print("Python API batchSize(%d) workersPerNodes(%d) numNodes(%d)" %
          (ffconfig.batch_size, ffconfig.workers_per_node, ffconfig.num_nodes))
    ffmodel = FFModel(ffconfig)

    dims1 = [ffconfig.batch_size, 784]
    input1 = ffmodel.create_tensor(dims1, DataType.DT_FLOAT)

    num_samples = 60000

    if test_type == 1:
        onnx_model = ONNXModel("mnist_mlp_pt.onnx")
        t = onnx_model.apply(ffmodel, {"input.1": input1})
    else:
        onnx_model = ONNXModelKeras("mnist_mlp_keras.onnx", ffconfig, ffmodel)
        t = onnx_model.apply(ffmodel, {"input_1": input1})

    ffoptimizer = SGDOptimizer(ffmodel, 0.01)
    ffmodel.optimizer = ffoptimizer
    ffmodel.compile(loss_type=LossType.LOSS_SPARSE_CATEGORICAL_CROSSENTROPY,
                    metrics=[
                        MetricsType.METRICS_ACCURACY,
                        MetricsType.METRICS_SPARSE_CATEGORICAL_CROSSENTROPY
                    ])
    label = ffmodel.label_tensor

    (x_train, y_train), (x_test, y_test) = mnist.load_data()

    x_train = x_train.reshape(60000, 784)
    x_train = x_train.astype('float32')
    x_train /= 255
    y_train = y_train.astype('int32')
    y_train = np.reshape(y_train, (len(y_train), 1))

    dataloader_input = ffmodel.create_data_loader(input1, x_train)
    dataloader_label = ffmodel.create_data_loader(label, y_train)

    ffmodel.init_layers()

    epochs = ffconfig.epochs

    ts_start = ffconfig.get_current_time()

    ffmodel.fit(x=dataloader_input, y=dataloader_label, epochs=epochs)

    ts_end = ffconfig.get_current_time()
    run_time = 1e-6 * (ts_end - ts_start)
    print("epochs %d, ELAPSED TIME = %.4fs, THROUGHPUT = %.2f samples/s\n" %
          (epochs, run_time, num_samples * epochs / run_time))

    perf_metrics = ffmodel.get_perf_metrics()
    accuracy = perf_metrics.get_accuracy()
    if accuracy < ModelAccuracy.MNIST_MLP.value:
        assert 0, 'Check Accuracy'
Esempio n. 3
0
class BaseModel(object):
    def __init__(self, inputs, onnx_model):
        self._ffconfig = ff.FFConfig()
        self._ffconfig.parse_args()
        print("Python API batchSize(%d) workersPerNodes(%d) numNodes(%d)" %
              (self._ffconfig.get_batch_size(),
               self._ffconfig.get_workers_per_node(),
               self._ffconfig.get_num_nodes()))
        self._ffmodel = None
        self._onnx_model = onnx_model

        for node in onnx_model.graph.node:
            print(node)

        for input in onnx_model.graph.initializer:
            print(input.name, input.dims, len(input.dims))

        # for input in onnx_model.graph.input:
        #   print(input)

        self._input_tensors = []
        for key in inputs:
            input_tensor = inputs[key]
            t = Tensor(ffconfig=self._ffconfig,
                       key=key,
                       shape=input_tensor.shape,
                       dtype=input_tensor.dtype)
            self._input_tensors.append(t)

        self._loss = None
        self._label_type = None
        self._metrics = []
        self._label_type = ff.DataType.DT_FLOAT
        self._my_onnx_model = None
        self._output_tensor = None
        self._full_input_tensors = []
        self._full_label_tensor = 0
        self._num_samples = 0
        self._input_dataloaders = []
        self._input_dataloaders_dim = []
        self._label_dataloader = 0
        self._label_dataloader_dim = 0

        global tracing_id
        self.__tracing_id = tracing_id
        tracing_id += 1

    def compile(self,
                optimizer,
                loss=None,
                metrics=None,
                loss_weights=None,
                weighted_metrics=None,
                run_eagerly=None,
                comp_mode=None,
                **kwargs):
        if loss_weights != None:
            assert 0, "loss_weights is not supported"
        if weighted_metrics != None:
            assert 0, "weighted_metrics is not supported"
        if run_eagerly != None:
            assert 0, "run_eagerly is not supported"

        assert loss != None, "loss is None"
        if loss == 'categorical_crossentropy':
            self._loss = ff_keras_losses.CategoricalCrossentropy()
        elif loss == 'sparse_categorical_crossentropy':
            self._loss = ff_keras_losses.SparseCategoricalCrossentropy()
            self._label_type = ff.DataType.DT_INT32
        elif loss == 'mean_squared_error':
            self._loss = ff_keras_losses.MeanSquaredError()
        else:
            assert 0, 'Unsupported loss'

        assert metrics != None, "metrics is None"
        assert isinstance(metrics, list) == True, 'Metrics should be a list'
        for metric in metrics:
            if metric == 'accuracy':
                self._metrics.append(ff_keras_metrics.Accuracy())
            elif metric == 'categorical_crossentropy':
                self._metrics.append(
                    ff_keras_metrics.CategoricalCrossentropy())
            elif metric == 'sparse_categorical_crossentropy':
                self._metrics.append(
                    ff_keras_metrics.SparseCategoricalCrossentropy())
            elif metric == 'mean_squared_error':
                self._metrics.append(ff_keras_metrics.MeanSquaredError())
            elif metric == 'root_mean_squared_error':
                self._metrics.append(ff_keras_metrics.RootMeanSquaredError())
            elif metric == 'mean_absolute_error':
                self._metrics.append(ff_keras_metrics.MeanAbsoluteError())
            else:
                assert 0, 'Unsupported metric'

        self._ffmodel = ff.FFModel(self._ffconfig)
        self._create_input_tensors()
        self._create_flexflow_layers()

        layers = self._ffmodel.get_layers()
        for l in layers:
            print(l, layers[l])

        if isinstance(optimizer, tf_keras_optimizer.Optimizer) == True:
            if isinstance(optimizer, tf_keras_optimizer.SGD) == True:
                self._ffoptimizer = ff_keras_optimizer.SGD(
                    learning_rate=optimizer.learning_rate.numpy(),
                    momentum=optimizer.momentum.numpy(),
                    nesterov=optimizer.nesterov)
            elif isinstance(optimizer, tf_keras_optimizer.Adam) == True:
                self._ffoptimizer = ff_keras_optimizer.Adam(
                    learning_rate=optimizer.learning_rate.numpy(),
                    beta_1=optimizer.beta_1.numpy(),
                    beta_2=optimizer.beta_2.numpy(),
                    epsilon=optimizer.epsilon.numpy())
            else:
                assert 0, "Unsupported optimizer"
        elif type(optimizer) == str:
            if optimizer == 'SGD':
                self._ffoptimizer = ff_keras_optimizer.SGD()
            elif optimizer == 'Adam':
                self._ffoptimizer = ff_keras_optimizer.Adam()
            else:
                assert 0, "Unsupported optimizer"
        else:
            assert 0, "Unsupported optimizer"

        self._create_optimizer()
        metrics_type = []
        for metric in self._metrics:
            metrics_type.append(metric.type)
        self._ffmodel.compile(optimizer=self._ffoptimizer.ffhandle,
                              loss_type=self._loss.type,
                              metrics=metrics_type,
                              comp_mode=comp_mode)
        self._create_label_tensor()

    #TODO: finish API
    def fit(self,
            x=None,
            y=None,
            batch_size=None,
            epochs=1,
            verbose=1,
            callbacks=None,
            validation_split=0.0,
            validation_data=None,
            shuffle=True,
            class_weight=None,
            sample_weight=None,
            initial_epoch=0,
            steps_per_epoch=None,
            validation_steps=None,
            validation_batch_size=None,
            validation_freq=1,
            max_queue_size=10,
            workers=1,
            use_multiprocessing=False):
        if batch_size != None:
            assert self._ffconfig.get_batch_size(
            ) == batch_size, "batch size is not correct use -b to set it"
        if validation_split != 0.0:
            assert 0, "validation_split is not supported"
        if validation_data != None:
            assert 0, "validation_data is not supported"
        if shuffle != True:
            assert 0, "shuffle is not supported"
        if class_weight != None:
            assert 0, "class_weight is not supported"
        if sample_weight != None:
            assert 0, "sample_weight is not supported"
        if initial_epoch != 0:
            assert 0, "initial_epoch is not supported"
        if steps_per_epoch != None:
            assert 0, "steps_per_epoch is not supported"
        if validation_steps != None:
            assert 0, "validation_steps is not supported"
        if validation_batch_size != None:
            assert 0, "validation_batch_size is not supported"
        if validation_freq != 1:
            assert 0, "validation_freq is not supported"
        if max_queue_size != 10:
            assert 0, "max_queue_size is not supported"
        if workers != 1:
            assert 0, "workers is not supported"
        if use_multiprocessing != False:
            assert 0, "use_multiprocessing is not supported"

        assert self._output_tensor != None, "tensor is not init"
        if (isinstance(x, list) == False):
            input_tensors = [x]
        else:
            input_tensors = x
        label_tensor = y
        self._verify_tensors(input_tensors, label_tensor)
        self._create_data_loaders(input_tensors, label_tensor)
        self._ffmodel.init_layers()
        self._train(epochs, callbacks, eval=False)

    def _create_label_tensor(self):
        label_ffhandle = self._ffmodel.get_label_tensor()
        self._label_tensor = Tensor(
            ffconfig=self._ffconfig,
            batch_shape=(self._ffconfig.get_batch_size(), 1),
            dtype=self._label_type)
        self._label_tensor.ffhandle = label_ffhandle

    def _create_input_tensors(self):
        idx = 0
        for input_tensor in self._input_tensors:
            self._input_tensors[idx].create_ff_tensor(self._ffmodel)
            idx += 1

    def _create_flexflow_layers(self):
        self._my_onnx_model = ONNXModelKeras(self._onnx_model, self._ffconfig,
                                             self._ffmodel)
        input_dict = {}
        for input_tensor in self._input_tensors:
            key = "input_" + str(input_tensor.key)
            input_dict[key] = input_tensor.ffhandle
        self._output_tensor = self._my_onnx_model.apply(
            self._ffmodel, input_dict)

    def _create_optimizer(self):
        assert self._ffoptimizer != None, "optimizer is not set"
        if (isinstance(self._ffoptimizer, ff_keras_optimizer.SGD)
                == True) or (isinstance(self._ffoptimizer,
                                        ff_keras_optimizer.Adam) == True):
            self._ffoptimizer.create_ffhandle(self._ffmodel)
        else:
            assert 0, "unknown optimizer"

    def _verify_tensors(self, input_arrays, label_array):
        assert len(input_arrays) == len(
            self._input_tensors), "check len of input tensors"
        # TODO: move check shape into another function
        for np_array, t in zip(input_arrays, self._input_tensors):
            np_shape = np_array.shape
            assert len(np_shape) == t.num_dims, "check input shape"
            for i in range(1, len(np_shape)):
                assert np_shape[i] == t.batch_shape[i], "check input dims"
            assert np_array.dtype == t.dtype_str, "check input dtype"

        np_shape = label_array.shape
        assert len(
            np_shape) == self._label_tensor.num_dims, "check label shape"
        for i in range(1, len(np_shape)):
            assert np_shape[i] == self._label_tensor.batch_shape[
                i], "check label dims"
        assert label_array.dtype == self._label_tensor.dtype_str

    def __create_single_data_loader(self, batch_tensor, full_array):
        array_shape = full_array.shape
        num_dim = len(array_shape)
        print("dataloader type:", full_array.dtype)
        if (full_array.dtype == "float32"):
            datatype = ff.DataType.DT_FLOAT
        elif (full_array.dtype == "int32"):
            datatype = ff.DataType.DT_INT32
        else:
            assert 0, "unsupported datatype"

        if (num_dim == 2):
            full_tensor = Tensor(
                ffconfig=self._ffconfig,
                batch_shape=[self._num_samples, array_shape[1]],
                dtype=datatype)
        elif (num_dim == 4):
            full_tensor = Tensor(ffconfig=self._ffconfig,
                                 batch_shape=[
                                     self._num_samples, array_shape[1],
                                     array_shape[2], array_shape[3]
                                 ],
                                 dtype=datatype)
        else:
            assert 0, "unsupported dims"

        full_tensor.create_ff_tensor(self._ffmodel)
        full_tensor.ffhandle.attach_numpy_array(self._ffconfig, full_array)
        dataloader = ff.SingleDataLoader(self._ffmodel, batch_tensor.ffhandle,
                                         full_tensor.ffhandle,
                                         self._num_samples, datatype)
        full_tensor.ffhandle.detach_numpy_array(self._ffconfig)

        return full_tensor, dataloader

    def _create_data_loaders(self, x_trains, y_train):
        # Todo: check all num_samples, should be the same
        input_shape = x_trains[0].shape
        self._num_samples = input_shape[0]

        assert len(self._input_tensors) != 0, "input_tensor is not set"
        assert self._label_tensor != 0, "label_tensor is not set"

        idx = 0
        for x_train in x_trains:
            full_tensor, dataloader = self.__create_single_data_loader(
                self._input_tensors[idx], x_train)
            self._full_input_tensors.append(full_tensor)
            self._input_dataloaders.append(dataloader)
            self._input_dataloaders_dim.append(len(input_shape))
            idx += 1
        full_tensor, dataloader = self.__create_single_data_loader(
            self._label_tensor, y_train)
        self.__full_label_tensor = full_tensor
        self._label_dataloader = dataloader
        self._label_dataloader_dim = len(input_shape)

    def _train(self, epochs, callbacks, eval=False):
        if callbacks != None:
            for callback in callbacks:
                callback.set_model(self)

        if callbacks != None:
            for callback in callbacks:
                callback.on_train_begin()

        ts_start = self._ffconfig.get_current_time()
        epoch = 0
        epoch_flag = True
        self.__tracing_id += 1
        while (epoch < epochs) and (epoch_flag == True):
            if callbacks != None:
                for callback in callbacks:
                    callback.on_epoch_begin(epoch)

            for dataloader in self._input_dataloaders:
                dataloader.reset()
            self._label_dataloader.reset()
            self._ffmodel.reset_metrics()
            iterations = self._num_samples / self._ffconfig.get_batch_size()

            for iter in range(0, int(iterations)):
                if callbacks != None:
                    for callback in callbacks:
                        callback.on_batch_begin(iter)

                for dataloader in self._input_dataloaders:
                    dataloader.next_batch(self._ffmodel)
                self._label_dataloader.next_batch(self._ffmodel)

                self._ffconfig.begin_trace(self.__tracing_id)
                self._ffmodel.forward()
                # for layer in self._layers:
                #   layer.ffhandle.forward(self._ffmodel)
                if eval == False:
                    self._ffmodel.zero_gradients()
                    self._ffmodel.backward()
                    self._ffmodel.update()
                else:
                    self._ffmodel.compute_metrics()
                self._ffconfig.end_trace(self.__tracing_id)

                if callbacks != None:
                    for callback in callbacks:
                        callback.on_batch_end(iter)

            if callbacks != None:
                for callback in callbacks:
                    early_stop = callback.on_epoch_end(epoch)
                    if early_stop == True:
                        print("Accuracy reaches, now early stop, epoch: %d" %
                              (epoch))
                        epoch_flag = False

            epoch += 1

        ts_end = self._ffconfig.get_current_time()
        run_time = 1e-6 * (ts_end - ts_start)
        print(
            "epochs %d, ELAPSED TIME = %.4fs, interations %d, samples %d, THROUGHPUT = %.2f samples/s\n"
            % (epochs, run_time, int(iterations), self._num_samples,
               self._num_samples * epochs / run_time))

        if callbacks != None:
            for callback in callbacks:
                callback.on_train_end()
def top_level_task(test_type=1):
    ffconfig = FFConfig()
    alexnetconfig = NetConfig()
    print(alexnetconfig.dataset_path)
    print("Python API batchSize(%d) workersPerNodes(%d) numNodes(%d)" %
          (ffconfig.batch_size, ffconfig.workers_per_node, ffconfig.num_nodes))
    ffmodel = FFModel(ffconfig)

    dims_input = [ffconfig.batch_size, 3, 32, 32]
    input = ffmodel.create_tensor(dims_input, DataType.DT_FLOAT)

    if test_type == 1:
        onnx_model = ONNXModel("cifar10_cnn_pt.onnx")
        t = onnx_model.apply(ffmodel, {"input.1": input})
    else:
        onnx_model = ONNXModelKeras("cifar10_cnn_keras.onnx", ffconfig,
                                    ffmodel)
        t = onnx_model.apply(ffmodel, {"input_1": input})

    ffoptimizer = SGDOptimizer(ffmodel, 0.01)
    ffmodel.optimizer = ffoptimizer
    ffmodel.compile(loss_type=LossType.LOSS_SPARSE_CATEGORICAL_CROSSENTROPY,
                    metrics=[
                        MetricsType.METRICS_ACCURACY,
                        MetricsType.METRICS_SPARSE_CATEGORICAL_CROSSENTROPY
                    ])
    label = ffmodel.label_tensor

    num_samples = 10000

    (x_train, y_train), (x_test, y_test) = cifar10.load_data(num_samples)

    x_train = x_train.astype('float32')
    x_train /= 255
    full_input_array = x_train
    print(full_input_array.__array_interface__["strides"])

    y_train = y_train.astype('int32')
    full_label_array = y_train

    dataloader_input = ffmodel.create_data_loader(input, full_input_array)
    dataloader_label = ffmodel.create_data_loader(label, full_label_array)

    num_samples = dataloader_input.num_samples

    ffmodel.init_layers()

    epochs = ffconfig.epochs

    ts_start = ffconfig.get_current_time()

    ffmodel.fit(x=dataloader_input, y=dataloader_label, epochs=epochs)

    ts_end = ffconfig.get_current_time()
    run_time = 1e-6 * (ts_end - ts_start)
    print("epochs %d, ELAPSED TIME = %.4fs, THROUGHPUT = %.2f samples/s\n" %
          (epochs, run_time, num_samples * epochs / run_time))

    perf_metrics = ffmodel.get_perf_metrics()
    accuracy = perf_metrics.get_accuracy()
    if accuracy < ModelAccuracy.CIFAR10_CNN.value:
        assert 0, 'Check Accuracy'