def load(cls, db_path, db_type, int_features=False): """ Creates Predictor by loading from a database :param db_path see load_from_db :param db_type see load_from_db :param int_features bool indicating if int_features are present """ meta = load_from_db(db_path, db_type) init_net = GetNet(meta, predictor_constants.PREDICT_INIT_NET_TYPE) net = prepare_prediction_net(db_path, db_type) parameters = GetBlobs(meta, predictor_constants.PARAMETERS_BLOB_TYPE) return cls(net, parameters, init_net, int_features)
def test_wordblstm_export_to_caffe2( self, export_num_words, export_num_dict_feat, num_word_classes, test_num_words, test_num_dict_feat, num_predictions, test_num_chars, ): for WORD_CONFIG in WORD_CONFIGS: config = self._get_config(WordTaggingTask_Deprecated.Config, WORD_CONFIG) metadata = self._get_metadata(0, num_word_classes) py_model = create_model(config.model, config.features, metadata) exporter = create_exporter( config.exporter, config.features, config.labels, metadata ) with tempfile.NamedTemporaryFile( delete=False, suffix=".{}".format(".predictor") ) as pred_file: output_names = exporter.export_to_caffe2(py_model, pred_file.name) workspace.ResetWorkspace() pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) for _i in range(num_predictions): test_inputs = self._get_rand_input( config.features, BATCH_SIZE, W_VOCAB_SIZE, DICT_VOCAB_SIZE, CHAR_VOCAB_SIZE, test_num_words, test_num_dict_feat, test_num_chars, ) self._feed_c2_input( workspace, test_inputs, exporter.input_names, metadata.feature_itos_map, ) workspace.RunNetOnce(pred_net) c2_out = [list(workspace.FetchBlob(o_name)) for o_name in output_names] py_model.eval() py_outs = py_model(*test_inputs) context = {SEQ_LENS: test_inputs[-1]} target = None pred, score = py_model.get_pred(py_outs, target, context) np.testing.assert_array_almost_equal( torch.transpose(score, 1, 2).contiguous().view(-1).detach().numpy(), np.array(c2_out).flatten(), )
def test_wordblstm_export_to_caffe2(self, export_num_words, num_word_classes, test_num_words, num_predictions): for WORD_CONFIG in WORD_CONFIGS: config = self._get_config(WordTaggingTask.Config, WORD_CONFIG) tensorizers, data = _NewTask._init_tensorizers(config) word_labels = [ SpecialTokens.PAD, SpecialTokens.UNK, "NoLabel", "person" ] tensorizers["labels"].vocab = Vocabulary(word_labels) tensorizers["tokens"].vocab = Vocabulary(WORD_VOCAB) py_model = _NewTask._init_model(config.model, tensorizers) dummy_test_input = self._get_rand_input_intent_slot( BATCH_SIZE, W_VOCAB_SIZE, test_num_words) exporter = ModelExporter( ModelExporter.Config(), py_model.get_export_input_names(tensorizers), dummy_test_input, py_model.vocab_to_export(tensorizers), py_model.get_export_output_names(tensorizers), ) with tempfile.NamedTemporaryFile( delete=False, suffix=".{}".format(".predictor")) as pred_file: exporter.export_to_caffe2(py_model, pred_file.name) workspace.ResetWorkspace() pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) for _i in range(num_predictions): test_inputs = self._get_rand_input_intent_slot( BATCH_SIZE, W_VOCAB_SIZE, test_num_words) self._feed_c2_input(workspace, test_inputs, exporter.input_names, exporter.vocab_map) workspace.RunNetOnce(pred_net) word_output_names = [ "{}:{}".format("word_scores", class_name) for class_name in word_labels ] py_model.eval() py_outs = py_model(*test_inputs) context = {"seq_lens": test_inputs[-1]} target = None pred, score = py_model.get_pred(py_outs, target, context) c2_word_out = [] for o_name in word_output_names: c2_word_out.extend(list(workspace.FetchBlob(o_name))) np.testing.assert_array_almost_equal( torch.transpose(score, 1, 2).contiguous().view(-1).detach().numpy(), np.array(c2_word_out).flatten(), )
def load_model(pathname): workspace.ResetWorkspace(root_folder) pathname = os.path.join(root_folder, "donkey_model_protos.lmdb") LMDB_MAP_SIZE = 1 << 29 env = lmdb.open(root_folder, map_size=LMDB_MAP_SIZE) with env.begin(write=False) as txn: for key, value in txn.cursor(): if key == ":NET": nd = caffe_pb2.NetDef() nd.SerializeFromString(value) predict_net = pe.prepare_prediction_net(pathname, "minidb") return predict_net
def test_seq_nn_export_to_caffe2( self, export_num_words, export_num_dict_feat, num_doc_classes, num_word_classes, test_num_words, test_num_dict_feat, num_predictions, test_num_chars, test_num_seq, ): config = self._get_config(SeqNNTask_Deprecated.Config, SEQ_NN_CONFIG) metadata = self._get_seq_metadata(num_doc_classes, 0) py_model = create_model(config.model, config.features, metadata) exporter = create_exporter( config.exporter, config.features, config.labels, metadata ) with tempfile.NamedTemporaryFile( delete=False, suffix=".{}".format(".predictor") ) as pred_file: print(pred_file.name) output_names = exporter.export_to_caffe2(py_model, pred_file.name) workspace.ResetWorkspace() pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) for _i in range(num_predictions): test_inputs = self._get_seq_nn_rand_input( config.features, BATCH_SIZE, W_VOCAB_SIZE, DICT_VOCAB_SIZE, CHAR_VOCAB_SIZE, test_num_words, test_num_dict_feat, test_num_chars, test_num_seq, ) self._feed_c2_input( workspace, test_inputs, exporter.input_names, metadata.feature_itos_map ) workspace.RunNetOnce(pred_net) c2_out = [list(workspace.FetchBlob(o_name)) for o_name in output_names] py_model.eval() py_outs = py_model(*test_inputs) # Do log_softmax since we do that before exporting predictor nets py_outs = F.log_softmax(py_outs, 1) np.testing.assert_array_almost_equal( py_outs.view(-1).detach().numpy(), np.array(c2_out).flatten() )
def create_predictor(config, model_file=None): workspace_id = str(uuid.uuid4()) workspace.SwitchWorkspace(workspace_id, True) predict_net = predictor_exporter.prepare_prediction_net( filename=model_file or config.export_caffe2_path, db_type=CAFFE2_DB_TYPE ) task = config.task feature_config = task.features featurizer = create_featurizer(task.featurizer, feature_config) return lambda input: _predict( workspace_id, feature_config, predict_net, featurizer, input )
def test_seq_nn_export_to_caffe2( self, export_num_words, num_doc_classes, test_num_words, num_predictions, test_num_seq, ): config = self._get_config(SeqNNTask.Config, SEQ_NN_CONFIG) tensorizers, data = _NewTask._init_tensorizers(config) doc_labels = [SpecialTokens.UNK, "cu:other", "cu:address_Person"] tensorizers["labels"].vocab = Vocabulary(doc_labels) tensorizers["tokens"].vocab = Vocabulary(WORD_VOCAB) py_model = _NewTask._init_model(config.model, tensorizers) dummy_test_input = self._get_seq_nn_rand_input(BATCH_SIZE, W_VOCAB_SIZE, test_num_words, test_num_seq) exporter = ModelExporter( ModelExporter.Config(), py_model.get_export_input_names(tensorizers), dummy_test_input, py_model.vocab_to_export(tensorizers), py_model.get_export_output_names(tensorizers), ) with tempfile.NamedTemporaryFile( delete=False, suffix=".{}".format(".predictor")) as pred_file: output_names = exporter.export_to_caffe2(py_model, pred_file.name) workspace.ResetWorkspace() pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) for _i in range(num_predictions): test_inputs = self._get_seq_nn_rand_input(BATCH_SIZE, W_VOCAB_SIZE, test_num_words, test_num_seq) self._feed_c2_input(workspace, test_inputs, exporter.input_names, exporter.vocab_map) workspace.RunNetOnce(pred_net) c2_out = [ list(workspace.FetchBlob(o_name)) for o_name in output_names ] py_model.eval() py_outs = py_model(*test_inputs) # Do log_softmax since we do that before exporting predictor nets py_outs = F.log_softmax(py_outs, 1) np.testing.assert_array_almost_equal( py_outs.view(-1).detach().numpy(), np.array(c2_out).flatten())
def load(cls, db_path, db_type): """ Creates DiscreteActionPredictor by loading from a database :param db_path see load_from_db :param db_type see load_from_db """ previous_workspace = workspace.CurrentWorkspace() workspace_id = str(uuid.uuid4()) workspace.SwitchWorkspace(workspace_id, True) net = prepare_prediction_net(db_path, db_type) meta = load_from_db(db_path, db_type) inputs = GetBlobs(meta, predictor_constants.INPUTS_BLOB_TYPE) outputs = GetBlobs(meta, predictor_constants.OUTPUTS_BLOB_TYPE) parameters = GetBlobs(meta, predictor_constants.PARAMETERS_BLOB_TYPE) workspace.SwitchWorkspace(previous_workspace) return cls(net, inputs, outputs, parameters, workspace_id)
def check_save_load( self, model, expected_num_params, expected_num_inputs, expected_num_outputs, check_equality=True, ): pem, ws = model.get_predictor_export_meta_and_workspace() self.assertEqual(expected_num_params, len(pem.parameters)) for p in pem.parameters: self.assertTrue(ws.HasBlob(p)) self.assertEqual(expected_num_inputs, len(pem.inputs)) self.assertEqual(expected_num_outputs, len(pem.outputs)) input_prototype = model.input_prototype() with tempfile.TemporaryDirectory() as tmpdirname: db_path = os.path.join(tmpdirname, "model") logger.info("DB path: ", db_path) db_type = "minidb" with ws._ctx: save_to_db(db_type, db_path, pem) # Load the model from DB file and run it net = prepare_prediction_net(db_path, db_type) input_tensors = _flatten_named_tuple(input_prototype) input_names = model.input_blob_names() self.assertEqual(len(input_tensors), len(input_names)) for name, tensor in zip(input_names, input_tensors): workspace.FeedBlob(name, tensor.numpy()) workspace.RunNet(net) output_arrays = [ workspace.FetchBlob(b) for b in model.output_blob_names() ] output = model(input_prototype) output_tensors = _flatten_named_tuple(output) self.assertEqual(len(output_arrays), len(output_tensors)) if check_equality: for a, t in zip(output_arrays, output_tensors): # FXIME: PyTorch and Caffe2 has slightly different operator implementation; # assert_array_equal would fail in some cases :( npt.assert_allclose(t.detach().numpy(), a, atol=1e-6)
def create_predictor(config: PyTextConfig, model_file: Optional[str] = None) -> Predictor: """ Create a simple prediction API from a training config and an exported caffe2 model file. This model file should be created by calling export on a trained model snapshot. """ workspace_id = str(uuid.uuid4()) workspace.SwitchWorkspace(workspace_id, True) predict_net = predictor_exporter.prepare_prediction_net( filename=model_file or config.export_caffe2_path, db_type=CAFFE2_DB_TYPE) task = config.task feature_config = task.features featurizer = create_featurizer(task.featurizer, feature_config) return lambda input: _predict(workspace_id, feature_config, predict_net, featurizer, input)
def create_predictor(config: PyTextConfig, model_file: Optional[str] = None) -> Predictor: """ Create a simple prediction API from a training config and an exported caffe2 model file. This model file should be created by calling export on a trained model snapshot. """ workspace_id = str(uuid.uuid4()) workspace.SwitchWorkspace(workspace_id, True) predict_net = predictor_exporter.prepare_prediction_net( filename=model_file or config.export_caffe2_path, db_type=CAFFE2_DB_TYPE) new_task = NewTask.from_config(config.task) input_tensorizers = { name: tensorizer for name, tensorizer in new_task.data.tensorizers.items() if tensorizer.is_input } return lambda input: _predict(workspace_id, predict_net, new_task.model, input_tensorizers, input)
def check_save_load( self, model, expected_num_params, expected_num_inputs, expected_num_outputs ): pem, ws = model.get_predictor_export_meta_and_workspace() self.assertEqual(expected_num_params, len(pem.parameters)) for p in pem.parameters: self.assertTrue(ws.HasBlob(p)) self.assertEqual(expected_num_inputs, len(pem.inputs)) self.assertEqual(expected_num_outputs, len(pem.outputs)) input_prototype = model.input_prototype() with tempfile.TemporaryDirectory() as tmpdirname: db_path = os.path.join(tmpdirname, "model") logger.info("DB path: ", db_path) db_type = "minidb" with ws._ctx: save_to_db(db_type, db_path, pem) # Load the model from DB file and run it net = prepare_prediction_net(db_path, db_type) input_tensors = _flatten_named_tuple(input_prototype) input_names = model.input_blob_names() self.assertEqual(len(input_tensors), len(input_names)) for name, tensor in zip(input_names, input_tensors): workspace.FeedBlob(name, tensor.numpy()) workspace.RunNet(net) output_arrays = [workspace.FetchBlob(b) for b in model.output_blob_names()] output = model(input_prototype) output_tensors = _flatten_named_tuple(output) self.assertEqual(len(output_arrays), len(output_tensors)) for a, t in zip(output_arrays, output_tensors): # FXIME: PyTorch and Caffe2 has slightly different operator implementation; # assert_array_equal would fail in some cases :( npt.assert_allclose(t.detach().numpy(), a, atol=1e-6)
def test_get_predictor_export_meta_and_workspace(self): model = Model() pem, ws = model.get_predictor_export_meta_and_workspace() self.assertEqual(3, len(pem.parameters)) # 2 params + 1 const for p in pem.parameters: self.assertTrue(ws.HasBlob(p)) self.assertEqual(2, len(pem.inputs)) self.assertEqual(4, len(pem.outputs)) input_prototype = model.input_prototype() with tempfile.TemporaryDirectory() as tmpdirname: db_path = os.path.join(tmpdirname, "model") logger.info("DB path: ", db_path) db_type = "minidb" with ws._ctx: save_to_db(db_type, db_path, pem) # Load the model from DB file and run it net = prepare_prediction_net(db_path, db_type) state_features = input_prototype.state.float_features.numpy() action_features = input_prototype.action.float_features.numpy() workspace.FeedBlob("state:float_features", state_features) workspace.FeedBlob("action:float_features", action_features) workspace.RunNet(net) net_sum = workspace.FetchBlob("sum") net_mul = workspace.FetchBlob("mul") net_plus_one = workspace.FetchBlob("plus_one") net_linear = workspace.FetchBlob("linear") model_sum, model_mul, model_plus_one, model_linear = model( input_prototype) npt.assert_array_equal(model_sum.numpy(), net_sum) npt.assert_array_equal(model_mul.numpy(), net_mul) npt.assert_array_equal(model_plus_one.numpy(), net_plus_one) npt.assert_array_equal(model_linear.detach().numpy(), net_linear)
def create_predictor( config: PyTextConfig, model_file: Optional[str] = None, db_type: str = CAFFE2_DB_TYPE, task: Optional[NewTask] = None, cache_size: int = 0, ) -> Predictor: """ Create a simple prediction API from a training config and an exported caffe2 model file. This model file should be created by calling export on a trained model snapshot. """ workspace_id = str(uuid.uuid4()) workspace.SwitchWorkspace(workspace_id, True) predict_net = predictor_exporter.prepare_prediction_net( filename=model_file or PathManager.get_local_path(config.export_caffe2_path), db_type=db_type, ) new_task = task or NewTask.from_config(config.task) input_tensorizers = { name: tensorizer for name, tensorizer in new_task.data.tensorizers.items() if tensorizer.is_input } def predict_fn(input): return _predict(workspace_id, predict_net, new_task.model, input_tensorizers, input) if cache_size < 0: return lru_cache(maxsize=None)(predict_fn) elif cache_size > 0: return lru_cache(maxsize=cache_size)(predict_fn) else: return predict_fn
def _test_task_export_to_caffe2(self, task_class, config): task = task_class.from_config(config.task) py_model = task.model with tempfile.NamedTemporaryFile( delete=False, suffix=".{}".format("predictor") ) as pred_file: print(pred_file.name) output_names = task.export(py_model, pred_file.name) print(output_names) workspace.ResetWorkspace() pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) test_inputs = py_model.arrange_model_inputs( next(iter(task.data.batches(Stage.TEST)))[1] ) ModelExporterTest._feed_c2_input( workspace, test_inputs, # get_export_input_names only implemented for document classification task.model.get_export_input_names(task.data.tensorizers), task.model.vocab_to_export(task.data.tensorizers), ) workspace.RunNetOnce(pred_net) c2_out = [list(workspace.FetchBlob(o_name)) for o_name in output_names] py_model.eval() py_outs = py_model(*test_inputs) # Do softmax since we do log softmax before exporting predictor nets # We do exp on caffe2 output instead, because log of numbers that are # very close to 0 gives different result in pytorch and caffe2 py_outs = F.softmax(py_outs, 1) np.testing.assert_array_almost_equal( py_outs.view(-1).detach().numpy(), np.exp(np.array(c2_out).transpose()).flatten(), )
def test_get_predictor_export_meta_and_workspace_full(self): model = Model() state_normalization_parameters = { i: NormalizationParameters(feature_type=CONTINUOUS) for i in range(1, 5) } action_normalization_parameters = { i: NormalizationParameters(feature_type=CONTINUOUS) for i in range(5, 9) } extractor = PredictorFeatureExtractor( state_normalization_parameters=state_normalization_parameters, action_normalization_parameters=action_normalization_parameters, normalize=False, ) output_transformer = TestOutputTransformer() pem, ws = model.get_predictor_export_meta_and_workspace( feature_extractor=extractor, output_transformer=output_transformer ) # model has 2 params + 1 const. extractor has 1 const. output_transformer has 1 const. self.assertEqual(5, len(pem.parameters)) for p in pem.parameters: self.assertTrue(ws.HasBlob(p)) self.assertEqual(3, len(pem.inputs)) self.assertEqual(5, len(pem.outputs)) self.assertEqual( { "output/string_weighted_multi_categorical_features.lengths", "output/string_weighted_multi_categorical_features.keys", "output/string_weighted_multi_categorical_features.values.lengths", "output/string_weighted_multi_categorical_features.values.keys", "output/string_weighted_multi_categorical_features.values.values", }, set(pem.outputs), ) input_prototype = model.input_prototype() with tempfile.TemporaryDirectory() as tmpdirname: db_path = os.path.join(tmpdirname, "model") logger.info("DB path: {}".format(db_path)) db_type = "minidb" with ws._ctx: save_to_db(db_type, db_path, pem) # Load the model from DB file and run it net = prepare_prediction_net(db_path, db_type) state_features = input_prototype.state.float_features action_features = input_prototype.action.float_features float_features_values = ( torch.cat((state_features, action_features), dim=1).reshape(-1).numpy() ) float_features_keys = np.arange(1, 9) float_features_lengths = np.array([8], dtype=np.int32) workspace.FeedBlob("input/float_features.keys", float_features_keys) workspace.FeedBlob("input/float_features.values", float_features_values) workspace.FeedBlob("input/float_features.lengths", float_features_lengths) workspace.RunNet(net) model_sum, model_mul, model_plus_one, model_linear = model(input_prototype) lengths = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.lengths" ) keys = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.keys" ) values_lengths = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.values.lengths" ) values_keys = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.values.keys" ) values_values = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.values.values" ) N = 1 npt.assert_array_equal(np.ones(N, dtype=np.int32), lengths) npt.assert_array_equal(np.zeros(N, dtype=np.int64), keys) npt.assert_array_equal([1] * N, values_lengths) npt.assert_array_equal( np.array([b"TestAction"], dtype=np.object), values_keys ) npt.assert_array_equal( model_linear.detach().numpy().reshape(-1), values_values )
def test_get_predictor_export_meta_and_workspace_with_feature_extractor( self): model = Model() state_normalization_parameters = { i: NormalizationParameters(feature_type=CONTINUOUS) for i in range(1, 5) } action_normalization_parameters = { i: NormalizationParameters(feature_type=CONTINUOUS) for i in range(5, 9) } extractor = PredictorFeatureExtractor( state_normalization_parameters=state_normalization_parameters, action_normalization_parameters=action_normalization_parameters, normalize=False, ) pem, ws = model.get_predictor_export_meta_and_workspace( feature_extractor=extractor) # model has 2 params + 1 const. extractor has 1 const. self.assertEqual(4, len(pem.parameters)) for p in pem.parameters: self.assertTrue(ws.HasBlob(p)) self.assertEqual(3, len(pem.inputs)) self.assertEqual(4, len(pem.outputs)) input_prototype = model.input_prototype() with tempfile.TemporaryDirectory() as tmpdirname: db_path = os.path.join(tmpdirname, "model") logger.info("DB path: ", db_path) db_type = "minidb" with ws._ctx: save_to_db(db_type, db_path, pem) # Load the model from DB file and run it net = prepare_prediction_net(db_path, db_type) state_features = input_prototype.state.float_features action_features = input_prototype.action.float_features float_features_values = (torch.cat( (state_features, action_features), dim=1).reshape(-1).numpy()) float_features_keys = np.arange(1, 9) float_features_lengths = np.array([8], dtype=np.int32) workspace.FeedBlob("input/float_features.keys", float_features_keys) workspace.FeedBlob("input/float_features.values", float_features_values) workspace.FeedBlob("input/float_features.lengths", float_features_lengths) workspace.RunNet(net) net_sum = workspace.FetchBlob("sum") net_mul = workspace.FetchBlob("mul") net_plus_one = workspace.FetchBlob("plus_one") net_linear = workspace.FetchBlob("linear") model_sum, model_mul, model_plus_one, model_linear = model( input_prototype) npt.assert_array_equal(model_sum.numpy(), net_sum) npt.assert_array_equal(model_mul.numpy(), net_mul) npt.assert_array_equal(model_plus_one.numpy(), net_plus_one) npt.assert_allclose(model_linear.detach().numpy(), net_linear, rtol=1e-4)
def test_get_predictor_export_meta_and_workspace_full(self): model = Model() state_normalization_parameters = { i: NormalizationParameters(feature_type=CONTINUOUS) for i in range(1, 5) } action_normalization_parameters = { i: NormalizationParameters(feature_type=CONTINUOUS) for i in range(5, 9) } extractor = PredictorFeatureExtractor( state_normalization_parameters=state_normalization_parameters, action_normalization_parameters=action_normalization_parameters, normalize=False, ) output_transformer = TestOutputTransformer() pem, ws = model.get_predictor_export_meta_and_workspace( feature_extractor=extractor, output_transformer=output_transformer) # model has 2 params + 1 const. extractor has 1 const. output_transformer has 1 const. self.assertEqual(5, len(pem.parameters)) for p in pem.parameters: self.assertTrue(ws.HasBlob(p)) self.assertEqual(3, len(pem.inputs)) self.assertEqual(5, len(pem.outputs)) self.assertEqual( { "output/string_weighted_multi_categorical_features.lengths", "output/string_weighted_multi_categorical_features.keys", "output/string_weighted_multi_categorical_features.values.lengths", "output/string_weighted_multi_categorical_features.values.keys", "output/string_weighted_multi_categorical_features.values.values", }, set(pem.outputs), ) input_prototype = model.input_prototype() with tempfile.TemporaryDirectory() as tmpdirname: db_path = os.path.join(tmpdirname, "model") logger.info("DB path: {}".format(db_path)) db_type = "minidb" with ws._ctx: save_to_db(db_type, db_path, pem) # Load the model from DB file and run it net = prepare_prediction_net(db_path, db_type) state_features = input_prototype.state.float_features action_features = input_prototype.action.float_features float_features_values = (torch.cat( (state_features, action_features), dim=1).reshape(-1).numpy()) float_features_keys = np.arange(1, 9) float_features_lengths = np.array([8], dtype=np.int32) workspace.FeedBlob("input/float_features.keys", float_features_keys) workspace.FeedBlob("input/float_features.values", float_features_values) workspace.FeedBlob("input/float_features.lengths", float_features_lengths) workspace.RunNet(net) model_sum, model_mul, model_plus_one, model_linear = model( input_prototype) lengths = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.lengths") keys = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.keys") values_lengths = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.values.lengths" ) values_keys = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.values.keys" ) values_values = workspace.FetchBlob( "output/string_weighted_multi_categorical_features.values.values" ) N = 1 npt.assert_array_equal(np.ones(N, dtype=np.int32), lengths) npt.assert_array_equal(np.zeros(N, dtype=np.int64), keys) npt.assert_array_equal([1] * N, values_lengths) npt.assert_array_equal(np.array([b"TestAction"], dtype=np.object), values_keys) npt.assert_array_equal(model_linear.detach().numpy().reshape(-1), values_values)
def test_joint_export_to_caffe2( self, export_num_words, export_num_dict_feat, num_doc_classes, num_word_classes, test_num_words, test_num_dict_feat, num_predictions, test_num_chars, ): config = self._get_config(JointTextTask.Config, JOINT_CONFIG) metadata = self._get_metadata(num_doc_classes, num_word_classes) py_model = create_model(config.model, config.features, metadata) exporter = create_exporter(config.exporter, config.features, config.labels, metadata) with tempfile.NamedTemporaryFile( delete=False, suffix=".{}".format(".predictor")) as pred_file: exporter.export_to_caffe2(py_model, pred_file.name) workspace.ResetWorkspace() pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) for _i in range(num_predictions): test_inputs = self._get_rand_input( config.features, BATCH_SIZE, W_VOCAB_SIZE, DICT_VOCAB_SIZE, CHAR_VOCAB_SIZE, test_num_words, test_num_dict_feat, test_num_chars, ) self._feed_c2_input(workspace, test_inputs, exporter.input_names, metadata.feature_itos_map) workspace.RunNetOnce(pred_net) doc_output_names = [ "{}:{}".format("doc_scores", class_name) for class_name in metadata.label_names[0] ] word_output_names = [ "{}:{}".format("word_scores", class_name) for class_name in metadata.label_names[1] ] py_model.eval() logits = py_model(*test_inputs) context = {SEQ_LENS: test_inputs[-1]} target = None (d_pred, w_pred), (d_score, w_score) = py_model.get_pred(logits, target, context) c2_doc_out = [] for o_name in doc_output_names: c2_doc_out.extend(list(workspace.FetchBlob(o_name))) np.testing.assert_array_almost_equal( d_score.view(-1).detach().numpy(), np.array(c2_doc_out).flatten()) c2_word_out = [] for o_name in word_output_names: c2_word_out.extend(list(workspace.FetchBlob(o_name))) np.testing.assert_array_almost_equal( torch.transpose(w_score, 1, 2).contiguous().view(-1).detach().numpy(), np.array(c2_word_out).flatten(), )
# save the model to a file. Use minidb as the file format pe.save_to_db("minidb", os.path.join(sys.argv[2], "mnist_model.minidb"), pe_meta) print("Deploy model saved to: " + sys.argv[2] + "/mnist_model.minidb") # Grab and display the last data batch used before we scratch the workspace. This purely for our convenience... blob = workspace.FetchBlob("data") # reset the workspace, to make sure the model is actually loaded workspace.ResetWorkspace(sys.argv[2]) # verify that all blobs from training are destroyed. print("The blobs in the workspace after reset: {}".format(workspace.Blobs())) # load the predict net predict_net = pe.prepare_prediction_net( os.path.join(sys.argv[2], "mnist_model.minidb"), "minidb") # verify that blobs are loaded back print("The blobs in the workspace after loading the model: {}".format( workspace.Blobs())) # feed the previously saved data to the loaded model workspace.FeedBlob("data", blob) # predict workspace.RunNetOnce(predict_net) softmax = workspace.FetchBlob("softmax") print("Shape of softmax: ", softmax.shape)
# In[19]: # we retrieve the last input data out and use it in our prediction test before we scratch the workspace blob = workspace.FetchBlob("data") pyplot.figure() _ = visualize.NCHW.ShowMultiple(blob) # reset the workspace, to make sure the model is actually loaded workspace.ResetWorkspace(root_folder) # verify that all blobs are destroyed. print("The blobs in the workspace after reset: {}".format(workspace.Blobs())) # load the predict net predict_net = pe.prepare_prediction_net(os.path.join(root_folder, "mnist_model.minidb"), "minidb") # verify that blobs are loaded back print("The blobs in the workspace after loading the model: {}".format(workspace.Blobs())) # feed the previously saved data to the loaded model workspace.FeedBlob("data", blob) # predict workspace.RunNetOnce(predict_net) softmax = workspace.FetchBlob("softmax") # the first letter should be predicted correctly pyplot.figure() _ = pyplot.plot(softmax[0], 'ro') pyplot.title('Prediction for the first image')
def DISABLED_test_doc_export_to_caffe2_with_logits( self, num_doc_classes, test_num_words, test_num_dict_feat, num_predictions, test_num_chars, ): for config in DOC_CONFIGS_WITH_EXPORT_LOGITS: config = self._get_config(DocumentClassificationTask.Config, config) metadata = self._get_metadata(num_doc_classes, 0) py_model = create_model(config.model, config.features, metadata) exporter = create_exporter(config.exporter, config.features, config.labels, metadata) with tempfile.NamedTemporaryFile(delete=False, suffix=".predictor") as pred_file: print(pred_file.name) output_names = exporter.export_to_caffe2( py_model, pred_file.name) workspace.ResetWorkspace() pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) for _i in range(num_predictions): pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) test_inputs = self._get_rand_input( config.features, BATCH_SIZE, W_VOCAB_SIZE, DICT_VOCAB_SIZE, CHAR_VOCAB_SIZE, test_num_words, test_num_dict_feat, test_num_chars, ) self._feed_c2_input( workspace, test_inputs, exporter.input_names, metadata.feature_itos_map, ) workspace.RunNetOnce(pred_net) c2_out = [ list(workspace.FetchBlob(o_name)) for o_name in output_names ] py_model.eval() py_outs = py_model(*test_inputs) np.testing.assert_array_almost_equal( py_outs.view(-1).detach().numpy(), np.array(c2_out[-1]).flatten()) # Do log_softmax since we do that before exporting predictor nets py_outs = F.log_softmax(py_outs, 1) np.testing.assert_array_almost_equal( py_outs.view(-1).detach().numpy(), np.array(c2_out[:-1]).flatten())
def load(cls, db_path, db_type, *args, **kwargs): ws = Workspace() with ws._ctx: net = prepare_prediction_net(db_path, db_type) # TODO: reconstruct pem if so the predictor can be saved back return cls(pem=None, ws=ws, predict_net=net)
def load(cls, db_path, db_type, *args, **kwargs): ws = Workspace() with ws._ctx: net = prepare_prediction_net(db_path, db_type) # TODO: reconstruct pem if so the predictor can be saved back return cls(pem=None, ws=ws, predict_net=net)
def CreateCaffeNetFromCaffe2Net(caffe2Net, caffeNet): with myutils.NamedCudaScope(0): workspace.ResetWorkspace("/opt/yolov3caffe2") predict_net = prepare_prediction_net(caffe2Net, "minidb") net_proto = predict_net.Proto() print(net_proto) img = cv2.imread('/opt/tmp.jpg') b, g, r = cv2.split(img) rgb_img = cv2.merge([r, g, b]) sized = cv2.resize(rgb_img, (224, 224), interpolation=cv2.INTER_CUBIC) npar = np.array(sized) pp = np.ascontiguousarray(np.transpose(npar, [2, 0, 1])).reshape( 1, 3, sized.shape[0], sized.shape[1]).astype(np.float32) / 255.0 workspace.CreateNet(predict_net, overwrite=True) workspace.FeedBlob('gpu_0/data', pp) workspace.RunNet(predict_net.Proto().name) # # print(net_proto) # # print predict_net.Proto() fp = open(caffeNet, 'w') fp.write("name: \"ResNetCaffe\"\n") fp.write("input: \"gpu_0/data\"\n") fp.write('input_dim: 1\n') fp.write('input_dim: 3\n') fp.write('input_dim: 224\n') fp.write('input_dim: 224\n') fp.write('\n') conv_id = 0 bn_id = 0 pool_id = 0 relu_id = 0 softmax_id = 0 sum_id = 0 fc_id = 0 def writeConv(): fp.write("layer {\n") fp.write(" type: \"Convolution\"\n") fp.write(" name: \"layer-conv_{}\"\n".format(conv_id)) fp.write(" bottom: \"{}\"\n".format(op.input[0])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write(" convolution_param {\n") blob = workspace.FetchBlob(op.output[0]) num_output = blob.shape[1] fp.write(" num_output: {}\n".format(num_output)) for arg in op.arg: if arg.name == "kernel": fp.write(" kernel_size: {}\n".format(arg.i)) if arg.name == "pad": fp.write(" pad: {}\n".format(arg.i)) if arg.name == "stride": fp.write(" stride: {}\n".format(arg.i)) if len(op.input) == 3: fp.write(" bias_term: true\n") else: fp.write(" bias_term: false\n") fp.write(" }\n") fp.write("}\n") def writeBN(): fp.write("layer {\n") fp.write(" type: \"BatchNorm\"\n") fp.write(" name: \"layer-bn_{}\"\n".format(bn_id)) fp.write(" bottom: \"{}\"\n".format(op.input[0])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write(" batch_norm_param {\n") fp.write(" use_global_stats: true\n") fp.write(" }\n") fp.write("}\n") #Scale fp.write("layer {\n") fp.write(" type: \"Scale\"\n") fp.write(" name: \"layer-scale_{}\"\n".format(bn_id)) fp.write(" bottom: \"{}\"\n".format(op.output[0])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write(" scale_param {\n") fp.write(" bias_term: true\n") fp.write(" }\n") fp.write("}\n") def wrieteSoftMax(): fp.write("layer {\n") fp.write(" type: \"Softmax\"\n") fp.write(" name: \"layer-softmax_{}\"\n".format(0)) fp.write(" bottom: \"{}\"\n".format(op.input[0])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write("}\n") def writeRelu(): fp.write("layer {\n") fp.write(" type: \"ReLU\"\n") fp.write(" name: \"layer-relu_{}\"\n".format(relu_id)) fp.write(" bottom: \"{}\"\n".format(op.input[0])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write("}\n") def wrieteFC(): fp.write("layer {\n") fp.write(" type: \"InnerProduct\"\n") fp.write(" name: \"layer-FC_{}\"\n".format(fc_id)) fp.write(" bottom: \"{}\"\n".format(op.input[0])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write(" inner_product_param {\n") blob = workspace.FetchBlob(op.output[0]) num_output = blob.shape fp.write(" num_output: {}\n".format(num_output[1])) fp.write(" }\n") fp.write("}\n") def wrieteSum(): fp.write("layer {\n") fp.write(" type: \"Eltwise\"\n") fp.write(" name: \"layer-Eltwise_{}\"\n".format(sum_id)) fp.write(" bottom: \"{}\"\n".format(op.input[0])) fp.write(" bottom: \"{}\"\n".format(op.input[1])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write("}\n") def writeMaxPool(): fp.write("layer {\n") fp.write(" type: \"Pooling\"\n") fp.write(" name: \"layer-pool_{}\"\n".format(pool_id)) fp.write(" bottom: \"{}\"\n".format(op.input[0])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write(" pooling_param {\n") for arg in op.arg: if arg.name == "kernel": fp.write(" kernel_size: {}\n".format(arg.i)) if arg.name == "stride": fp.write(" stride: {}\n".format(arg.i)) fp.write(" pool: MAX\n") fp.write(" }\n") fp.write("}\n") def writeAveragePool(): fp.write("layer {\n") fp.write(" type: \"Pooling\"\n") fp.write(" name: \"layer-avpool_{}\"\n".format(pool_id)) fp.write(" bottom: \"{}\"\n".format(op.input[0])) fp.write(" top: \"{}\"\n".format(op.output[0])) fp.write(" pooling_param {\n") for arg in op.arg: if arg.name == "kernel": fp.write(" kernel_size: {}\n".format(arg.i)) if arg.name == "stride": fp.write(" stride: {}\n".format(arg.i)) fp.write(" pool: AVE\n") fp.write(" }\n") fp.write("}\n") for op in net_proto.op: if op.type == "Conv": writeConv() conv_id += 1 elif op.type == "FC": wrieteFC() fc_id += 1 elif op.type == "SpatialBN": writeBN() bn_id += 1 elif op.type == "Relu": writeRelu() relu_id += 1 elif op.type == "Sum": wrieteSum() sum_id += 1 elif op.type == "MaxPool": writeMaxPool() pool_id += 1 elif op.type == "Softmax": wrieteSoftMax() elif op.type == "AveragePool": writeAveragePool() pool_id += 1 else: print("Unknow layertype:{}, model convert failed.".format( op.type)) exit() fp.close()
def initCaffeWeigthsWithCaffe2Weigths(caffe2Net, caffeNet, caffeModel): with myutils.NamedCudaScope(0): workspace.ResetWorkspace("/opt/yolov3caffe2") predict_net = prepare_prediction_net(caffe2Net, "minidb") net_proto = predict_net.Proto() print(net_proto) img = cv2.imread('/opt/tmp.jpg') b, g, r = cv2.split(img) rgb_img = cv2.merge([r, g, b]) sized = cv2.resize(rgb_img, (224, 224), interpolation=cv2.INTER_CUBIC) npar = np.array(sized) pp = np.ascontiguousarray(np.transpose(npar, [2, 0, 1])).reshape( 1, 3, sized.shape[0], sized.shape[1]).astype(np.float32) / 255.0 workspace.CreateNet(predict_net, overwrite=True) workspace.FeedBlob('gpu_0/data', pp) workspace.RunNet(predict_net.Proto().name) net = caffe.Net(caffeNet, caffe.TEST) params = net.params bn_id = 0 conv_id = 0 fc_id = 0 for op in net_proto.op: if op.type == "Conv": param_layer_name = "layer-conv_{}".format(conv_id) conv_param = params[param_layer_name] conv_weight = conv_param[0].data conv_blob = workspace.FetchBlob(op.input[1]) conv_param[0].data[...] = np.reshape(conv_blob, conv_weight.shape) if len(op.input) == 3: conv_bias = conv_param[1].data bias_blob = workspace.FetchBlob(op.input[2]) conv_param[1].data[...] = np.reshape( bias_blob, conv_bias.shape) conv_id += 1 elif op.type == "SpatialBN": bn_layer_name = "layer-bn_{}".format(bn_id) scale_layer_name = "layer-scale_{}".format(bn_id) bn_param = params[bn_layer_name] scale_param = params[scale_layer_name] running_mean = bn_param[0].data running_var = bn_param[1].data scale_weight = scale_param[0].data scale_bias = scale_param[1].data scale_blob = workspace.FetchBlob(op.input[1]) bias_blob = workspace.FetchBlob(op.input[2]) mean_blob = workspace.FetchBlob(op.input[3]) var_blob = workspace.FetchBlob(op.input[4]) bn_param[0].data[...] = np.reshape(mean_blob, running_mean.shape) bn_param[1].data[...] = np.reshape(var_blob, running_var.shape) bn_param[2].data[...] = np.array([1.0]) scale_param[0].data[...] = np.reshape(scale_blob, scale_weight.shape) scale_param[1].data[...] = np.reshape(bias_blob, scale_bias.shape) bn_id += 1 elif op.type == "FC": """ weight = fc_param[0].data bias = fc_param[1].data fc_param[1].data[...] = np.reshape(buf[start:start+bias.size], bias.shape); start = start + bias.size fc_param[0].data[...] = np.reshape(buf[start:start+weight.size], weight.shape); start = start + weight.size """ layer_name = "layer-FC_{}".format(fc_id) layer_param = params[layer_name] weight = layer_param[0].data bias = layer_param[1].data weight_blob = workspace.FetchBlob(op.input[1]) bias_blob = workspace.FetchBlob(op.input[2]) layer_param[0].data[...] = np.reshape(weight_blob, weight.shape) layer_param[1].data[...] = np.reshape(bias_blob, bias.shape) fc_id += 1 else: print "Layey name:{}, type:{}, has no weights, skipping this layer".format( op.name, op.type) print("Save converted caffe model to {}".format(caffeModel)) net.save(caffeModel)
def test_contextual_intent_slot_export_to_caffe2(self, test_num_words, num_predictions, test_num_seq): config = self._get_config(IntentSlotTask.Config, CONTEXTUAL_INTENT_SLOT_CONFIG) tensorizers, data = _NewTask._init_tensorizers(config) doc_labels = ["__UNKNOWN__", "cu:other", "cu:address_Person"] word_labels = ["__UNKNOWN__", "NoLabel", "person"] tensorizers["word_labels"].vocab = Vocabulary(word_labels) tensorizers["doc_labels"].vocab = Vocabulary(doc_labels) tensorizers["tokens"].vocab = Vocabulary(WORD_VOCAB) tensorizers["seq_tokens"].vocab = Vocabulary(WORD_VOCAB) py_model = _NewTask._init_model(config.model, tensorizers) dummy_test_input = self._get_rand_input_intent_slot( BATCH_SIZE, W_VOCAB_SIZE, test_num_words, test_num_seq) exporter = ModelExporter( ModelExporter.Config(), py_model.get_export_input_names(tensorizers), dummy_test_input, py_model.vocab_to_export(tensorizers), py_model.get_export_output_names(tensorizers), ) with tempfile.NamedTemporaryFile( delete=False, suffix=".{}".format(".predictor")) as pred_file: print(pred_file.name) exporter.export_to_caffe2(py_model, pred_file.name) workspace.ResetWorkspace() pred_net = pe.prepare_prediction_net(pred_file.name, CAFFE2_DB_TYPE) for _i in range(num_predictions): test_inputs = self._get_rand_input_intent_slot( BATCH_SIZE, W_VOCAB_SIZE, test_num_words, test_num_seq) self._feed_c2_input(workspace, test_inputs, exporter.input_names, exporter.vocab_map) workspace.RunNetOnce(pred_net) doc_output_names = [ "{}:{}".format("doc_scores", class_name) for class_name in doc_labels ] word_output_names = [ "{}:{}".format("word_scores", class_name) for class_name in word_labels ] py_model.eval() logits = py_model(*test_inputs) context = {SEQ_LENS: test_inputs[-1]} target = None (d_pred, w_pred), (d_score, w_score) = py_model.get_pred(logits, target, context) c2_doc_out = [] for o_name in doc_output_names: c2_doc_out.extend(list(workspace.FetchBlob(o_name))) c2_word_out = [] for o_name in word_output_names: c2_word_out.extend(list(workspace.FetchBlob(o_name))) np.testing.assert_array_almost_equal( d_score.view(-1).detach().numpy(), np.array(c2_doc_out).flatten()) np.testing.assert_array_almost_equal( torch.transpose(w_score, 1, 2).contiguous().view(-1).detach().numpy(), np.array(c2_word_out).flatten(), )
def test_get_predictor_export_meta_and_workspace_with_feature_extractor(self): model = Model() state_normalization_parameters = { i: NormalizationParameters(feature_type=CONTINUOUS) for i in range(1, 5) } action_normalization_parameters = { i: NormalizationParameters(feature_type=CONTINUOUS) for i in range(5, 9) } extractor = PredictorFeatureExtractor( state_normalization_parameters=state_normalization_parameters, action_normalization_parameters=action_normalization_parameters, normalize=False, ) pem, ws = model.get_predictor_export_meta_and_workspace( feature_extractor=extractor ) # model has 2 params + 1 const. extractor has 1 const. self.assertEqual(4, len(pem.parameters)) for p in pem.parameters: self.assertTrue(ws.HasBlob(p)) self.assertEqual(3, len(pem.inputs)) self.assertEqual(4, len(pem.outputs)) input_prototype = model.input_prototype() with tempfile.TemporaryDirectory() as tmpdirname: db_path = os.path.join(tmpdirname, "model") logger.info("DB path: ", db_path) db_type = "minidb" with ws._ctx: save_to_db(db_type, db_path, pem) # Load the model from DB file and run it net = prepare_prediction_net(db_path, db_type) state_features = input_prototype.state.float_features action_features = input_prototype.action.float_features float_features_values = ( torch.cat((state_features, action_features), dim=1).reshape(-1).numpy() ) float_features_keys = np.arange(1, 9) float_features_lengths = np.array([8], dtype=np.int32) workspace.FeedBlob("input/float_features.keys", float_features_keys) workspace.FeedBlob("input/float_features.values", float_features_values) workspace.FeedBlob("input/float_features.lengths", float_features_lengths) workspace.RunNet(net) net_sum = workspace.FetchBlob("sum") net_mul = workspace.FetchBlob("mul") net_plus_one = workspace.FetchBlob("plus_one") net_linear = workspace.FetchBlob("linear") model_sum, model_mul, model_plus_one, model_linear = model(input_prototype) npt.assert_array_equal(model_sum.numpy(), net_sum) npt.assert_array_equal(model_mul.numpy(), net_mul) npt.assert_array_equal(model_plus_one.numpy(), net_plus_one) npt.assert_allclose(model_linear.detach().numpy(), net_linear, rtol=1e-4)
def __init__(self): self.predict_net = predictor_exporter.prepare_prediction_net( filename=MODEL_FILE, db_type=MODEL_DB_TYPE)
parameters=[str(b) for b in deploy_model.params], inputs=["data"], outputs=["softmax"], ) pe.save_to_db("minidb", os.path.join(root_folder, "mnist_model.minidb"), pe_meta) print("Deploy model saved to:" + root_folder + "/mnist_model.minidb") blob = workspace.FetchBlob("data") plt.figure() plt.title("Batch of Testing Data") _ = visualize.NCHW.ShowMultiple(blob) workspace.ResetWorkspace(root_folder) print("The blobs in the workspace after reset: {}".format(workspace.Blobs())) predict_net = pe.prepare_prediction_net( os.path.join(root_folder, "mnist_model.minidb"), "minidb") print("The blobs in the workspace after loading the model: {}".format( workspace.Blobs())) workspace.FeedBlob("data", blob) workspace.RunNetOnce(predict_net) softmax = workspace.FetchBlob("softmax") print("Shape of softmax: {}".format(softmax.shape)) curr_pred, curr_conf = max(enumerate(softmax[0]), key=operator.itemgetter(1)) print("Prediction: {}".format(curr_pred)) print("Confidence: {}".format(curr_conf)) plt.figure() plt.title("Prediction for the first image") plt.ylabel("Confidence") plt.xlabel("Label") _ = plt.plot(softmax[0], 'ro') plt.show()
#!/usr/bin/env python3 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved import re import numpy as np from caffe2.python import workspace from caffe2.python.predictor import predictor_exporter # Load Caffe2 model predict_net = predictor_exporter.prepare_prediction_net( filename="atis_joint_model.c2", db_type="minidb" ) # Pre-processing helper method def tokenize(text): # Split by whitespace, force lowercase tokens = [] token_ranges = [] def add_token(text, start, end): token = text[start:end] if token: tokens.append(token) token_ranges.append((start, end)) start = 0 text = text for sep in re.finditer(r"\s+", text):