def initialize(self, ctx): """ Initialize model. This will be called during model loading time :param context: Initial context contains model server system properties. :return: """ self.properties = ctx.system_properties self.initialized = True # load the model, refer 'c ustom handler class' above for details self.device = torch.device("cuda:" + str(self.properties.get("gpu_id")) if torch.cuda.is_available() else "cpu") model_dir = self.properties.get("model_dir") # Read model serialize/pt file model_pt_path = os.path.join(model_dir, "model.bin") # # Read model definition file # model_def_path = os.path.join(model_dir, "model.py") # if not os.path.isfile(model_def_path): # raise RuntimeError("Missing the model definition file") PRE_TRAINED_MODEL_NAME = 'dccuchile/bert-base-spanish-wwm-cased' from model import SentimentClassifier self.model = SentimentClassifier(3) self.model.to(self.device) self.tokenizer = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME) self.model.load_state_dict(torch.load(model_pt_path,map_location=torch.device(self.device))) self.initialized = True print('CARGADOOOO')
def main(*args, **kwargs): flags.DEFINE_boolean('debug', False, '') flags.DEFINE_integer('epochs', 1, '') flags.DEFINE_integer('batch_size', 8, '') flags.DEFINE_integer('seq_length', 96, '') flags.DEFINE_integer('num_workers', 8, '') flags.DEFINE_integer('seed', 62, '') flags.DEFINE_float('lr', 1e-2, '') flags.DEFINE_float('dropout_pct', 0.5, '') flags.DEFINE_string('model', 'roberta-base', '') FLAGS = flags.FLAGS seed_everything(FLAGS.seed) # logfile sh.rm('-r', '-f', 'logs') sh.mkdir('logs') params = dict(batch_size=FLAGS.batch_size, model=FLAGS.model, lr=FLAGS.lr, dropout_pct=FLAGS.dropout_pct, num_workers=FLAGS.num_workers) ## read input data_path = Path("input") train_df = pd.read_csv(data_path / "train.csv") train_df.dropna(inplace=True) test_df = pd.read_csv(data_path / "test.csv") skf = StratifiedKFold(n_splits=10, shuffle=True, random_state=FLAGS.seed) for fold, (train_idx, val_idx) in enumerate(skf.split(train_df, train_df.sentiment), start=1): print(f"Fold {fold}") train_ds = TweetDataset(train_df.iloc[train_idx], FLAGS.model, FLAGS.seq_length) val_ds = TweetDataset(train_df.iloc[val_idx], FLAGS.model, FLAGS.seq_length) model = SentimentClassifier(params, train_ds, val_ds) trainer = pl.Trainer(default_root_dir='logs', gpus=(1 if th.cuda.is_available() else 0), max_epochs=FLAGS.epochs, fast_dev_run=FLAGS.debug, logger=pl.loggers.TensorBoardLogger('logs', name='imdb', version=0)) trainer.fit(model)
from flask import Flask, render_template, request from model import SentimentClassifier clf = SentimentClassifier() app = Flask(__name__) @app.route('/', methods = ['POST', 'GET']) def index_page(): if request.method == 'POST': text = request.form['text'] prediction_message = clf.getSentiment(text) return render_template('index.html', text = text, prediction_message = prediction_message) return render_template('index.html') if __name__ == "__main__": app.run(debug = True)
print("Substituting %s:%s with %s:%s" % (key, old_args[key], key, old_args[key])) old_args[key] = args[key] # replace args args = old_args # clean up a bit args.pop("checkpoint", None) print("New args:") print(args) # Instantiating the classifier model print("Building Model") model = SentimentClassifier(args["freeze_bert"], args["dropout"]) model.cuda(args["gpu"]) # Enable gpu support for the model print("Creating criterion and optimizer objects") criterion = nn.BCEWithLogitsLoss() optimizer = optim.SGD(model.parameters(), lr=args["lr"]) # Creating dataloaders print("Creating train and val dataloaders") dataset_train = SSTDataset(filename='data/SST-2/train.tsv', maxlen=args["maxlen"]) dataset_validation = SSTDataset(filename='data/SST-2/dev.tsv', maxlen=args["maxlen"]) train_loader = DataLoader(dataset_train, batch_size=args["batch_size"],
parser = argparse.ArgumentParser() # checkpoint to use (from models/) parser.add_argument('--checkpoint', type=str, required=False) # max len of sequences parser.add_argument('--maxlen', type=int, required=False) args = parser.parse_args() args = args.__dict__ print("Passed args:") print(args) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') print("Found device: %s" % device) print("loading model...") model = SentimentClassifier() model.to(device) # Enable gpu support for the model checkpoint = torch.load(args["checkpoint"], map_location=device) model.load_state_dict(checkpoint["model_state_dict"]) model.eval() tokenizer = DistilBertTokenizer.from_pretrained("distilbert-base-uncased") print("model loaded") if not args["maxlen"]: args["maxlen"] = checkpoint["args"]["maxlen"] print("using maxlen from import checkpoint, new args:") print(args) print("connecting to redis...") redis_connection = redis.Redis(host=os.environ["REDIS_HOST"], port=os.environ["REDIS_PORT"], charset="utf-8")
import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import Dataset, DataLoader from transformers import BertTokenizer, BertModel import pandas as pd from model import SentimentClassifier from dataset import SSTDataset #Create validation set val_set = SSTDataset(filename='data/dev.tsv', maxlen=30) #Create validation dataloader val_loader = DataLoader(val_set, batch_size=64, num_workers=5) #Create the network net = SentimentClassifier() #CPU or GPU device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") #Put the network to the GPU if available net = net.to(device) #Load the state dictionary of the network net.load_state_dict(torch.load('./models/model', map_location=device)) #Takes as the input the logits of the positive class and computes the binary cross-entropy criterion = nn.BCEWithLogitsLoss() def get_accuracy_from_logits(logits, labels): #Get a tensor of shape [B, 1, 1] with probabilities that the sentiment is positive probs = torch.sigmoid(logits.unsqueeze(-1)) #Convert probabilities to predictions, 1 being positive and 0 being negative soft_probs = (probs > 0.5).long() #Check which predictions are the same as the ground truth and calculate the accuracy
neg_pred, neut_pred, pos_pred = predict(raw_tweet) response = {} response["response"] = { 'sentiment': { "positive": str(pos_pred), "neutral": str(neut_pred), "negative": str(neg_pred), }, "tweet": str(raw_tweet), "time_taken": str(time.time() - start_time), } return flask.jsonify(response) @app.route('/') def index(): return app.send_static_file('index.html') if __name__ == "__main__": MODEL = SentimentClassifier(len(CLASS_NAMES)) TOKENIZER = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME) MODEL = nn.DataParallel(MODEL) MODEL.load_state_dict( torch.load(MODEL_PATH, map_location=torch.device(DEVICE))) MODEL.to(DEVICE) MODEL.eval() app.run(host='0.0.0.0')
def get_model(args): sd = None model_args = args if args.load is not None and args.load != '': sd = torch.load(args.load) if 'args' in sd: model_args = sd['args'] if 'sd' in sd: sd = sd['sd'] ntokens = model_args.data_size concat_pools = model_args.concat_max, model_args.concat_min, model_args.concat_mean if args.model == 'transformer': model = SentimentClassifier(model_args.model, ntokens, None, None, None, model_args.classifier_hidden_layers, model_args.classifier_dropout, None, concat_pools, False, model_args) else: model = SentimentClassifier(model_args.model, ntokens, model_args.emsize, model_args.nhid, model_args.nlayers, model_args.classifier_hidden_layers, model_args.classifier_dropout, model_args.all_layers, concat_pools, False, model_args) args.heads_per_class = model_args.heads_per_class args.use_softmax = model_args.use_softmax try: args.classes = list(model_args.classes) except: args.classes = [args.label_key] try: args.dual_thresh = model_args.dual_thresh and not model_args.joint_binary_train except: args.dual_thresh = False if args.cuda: model.cuda() if args.fp16: model.half() if sd is not None: try: model.load_state_dict(sd) except: # if state dict has weight normalized parameters apply and remove weight norm to model while loading sd if hasattr(model.lm_encoder, 'rnn'): apply_weight_norm(model.lm_encoder.rnn) else: apply_weight_norm(model.lm_encoder) model.lm_encoder.load_state_dict(sd) remove_weight_norm(model) if args.neurons > 0: print('WARNING. Setting neurons %s' % str(args.neurons)) model.set_neurons(args.neurons) return model
#Save the current network's state dictionary torch.save(net.state_dict(), 'models/model') if __name__ == "__main__": #Get the parameters from arguments if used parser = ArgumentParser() parser.add_argument('-freeze_bert', action='store_true') parser.add_argument('-maxlen', type=int, default=25) parser.add_argument('-batch_size', type=int, default=32) parser.add_argument('-lr', type=float, default=2e-5) parser.add_argument('-print_every', type=int, default=100) parser.add_argument('-num_eps', type=int, default=5) args = parser.parse_args() #Instantiate the classifier model net = SentimentClassifier(args.freeze_bert) #CPU or GPU device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") #Put the network to the GPU if available net = net.to(device) #Takes as the input the logits of the positive class and computes the binary cross-entropy criterion = nn.BCEWithLogitsLoss() #Adam optimizer optimizer = optim.Adam(net.parameters(), lr=args.lr) #Create instances of training and validation set train_set = SSTDataset(filename='data/train.tsv', maxlen=args.maxlen) val_set = SSTDataset(filename='data/dev.tsv', maxlen=args.maxlen) #Create intsances of training and validation dataloaders train_loader = DataLoader(train_set, batch_size=args.batch_size, num_workers=5)
parser.add_argument('--neurons', default=-1, type=int, help='number of nenurons to extract as features') data_config, data_parser = configure_data(parser) data_parser.set_defaults(split='1.', data='data/binary_sst/train.csv') args = parser.parse_args() args.cuda = torch.cuda.is_available() train_data, val_data, test_data = data_config.apply(args) ntokens = args.data_size model = SentimentClassifier(args.model, ntokens, args.emsize, args.nhid, args.nlayers, 0.0, args.all_layers) if args.cuda: model.cuda() if args.fp16: model.half() with open(args.load_model, 'rb') as f: sd = torch.load(f) try: model.load_state_dict(sd) except: apply_weight_norm(model.encoder.rnn) model.load_state_dict(sd) remove_weight_norm(model)
df_train = pd.read_csv('train.csv') df_test = pd.read_csv('test.csv') df_train, df_val = train_test_split(df_train, test_size=0.25) BATCH_SIZE = 8 MAX_LEN = 512 train_data_loader = create_data_loader(df_train, tokenizer, MAX_LEN, BATCH_SIZE) val_data_loader = create_data_loader(df_val, tokenizer, MAX_LEN, BATCH_SIZE) test_data_loader = create_data_loader(df_test, tokenizer, MAX_LEN, BATCH_SIZE) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model = SentimentClassifier(n_classes=3) model = model.to(device) EPOCHS = 10 optimizer = AdamW(model.parameters(), lr=2e-5, correct_bias=False) total_steps = len(train_data_loader) * EPOCHS scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=0, num_training_steps=total_steps) loss_fn = nn.CrossEntropyLoss().to(device) history = defaultdict(list) best_accuracy = 0
MAX_LEN = config['num_tokens'] lr = config['lr'] df = pd.read_csv(config['csv_path']) df_train, df_test = train_test_split(df, test_size=0.1, random_state=RANDOM_SEED) df_val, df_test = train_test_split(df_test, test_size=0.5, random_state=RANDOM_SEED) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") tokenizer = RobertaTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME) train_data_loader = create_data_loader(df_train, tokenizer, MAX_LEN, BATCH_SIZE) val_data_loader = create_data_loader(df_val, tokenizer, MAX_LEN, BATCH_SIZE) test_data_loader = create_data_loader(df_test, tokenizer, MAX_LEN, BATCH_SIZE) model = SentimentClassifier(NUM_CLASSES, PRE_TRAINED_MODEL_NAME) model = model.to(device) optimizer = optim.Adam(model.parameters(), lr=lr) loss_fn = nn.CrossEntropyLoss().to(device) history = defaultdict(list) best_accuracy = 0 for epoch in tqdm(range(EPOCHS)): print(f"Epoch {epoch + 1}/{EPOCHS}") print("-" * 10) train_acc, train_loss = train_epoch( model, train_data_loader, loss_fn, optimizer, device, len(df_train) )
class ModelHandler(BaseHandler): """ A custom model handler implementation. """ def __init__(self): self.model = None self._context = None self.initialized = False self.explain = False self.target = 0 def initialize(self, ctx): """ Initialize model. This will be called during model loading time :param context: Initial context contains model server system properties. :return: """ self.properties = ctx.system_properties self.initialized = True # load the model, refer 'c ustom handler class' above for details self.device = torch.device("cuda:" + str(self.properties.get("gpu_id")) if torch. cuda.is_available() else "cpu") model_dir = self.properties.get("model_dir") # Read model serialize/pt file model_pt_path = os.path.join(model_dir, "model.bin") # # Read model definition file # model_def_path = os.path.join(model_dir, "model.py") # if not os.path.isfile(model_def_path): # raise RuntimeError("Missing the model definition file") PRE_TRAINED_MODEL_NAME = 'dccuchile/bert-base-spanish-wwm-cased' from model import SentimentClassifier self.model = SentimentClassifier(2) self.model.to(self.device) self.tokenizer = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME) self.model.load_state_dict( torch.load(model_pt_path, map_location=torch.device(self.device))) self.model = self.model.eval() self.initialized = True logger.debug( 'Transformer model from path {0} loaded successfully'.format( model_dir)) def preprocess(self, data): """ Transform raw input into model input data. :param batch: list of raw requests, should match batch size :return: list of preprocessed model input data """ # # Take the input data and make it inference ready # text = data[0].get("data") # if text is None: try: reclamo = data[0].get("body").get("data") except: reclamo = data[0].get("body") # logger.debug(data) # logger.debug(str(data)) MAX_LEN = 450 inputs = self.tokenizer.encode_plus( reclamo, add_special_tokens=True, max_length=MAX_LEN, return_token_type_ids=False, padding='max_length', truncation=True, return_attention_mask=True, return_tensors='pt', ) return { 'review_text': reclamo, 'input_ids': inputs['input_ids'].flatten(), 'attention_mask': inputs['attention_mask'].flatten() } def inference(self, model_input): """ Internal inference methods :param model_input: transformed model input data :return: list of inference output in NDArray """ # Do some inference call to engine here and return output input_ids = model_input["input_ids"].to(self.device) attention_mask = model_input["attention_mask"].to(self.device) model_output, pooled_output = self.model( input_ids=input_ids.unsqueeze(0), attention_mask=attention_mask.unsqueeze(0)) _, preds = torch.max(model_output, dim=1) probs = F.softmax(model_output, dim=1) predicted_idx = str(preds.item()) out_dic = { 'idx': [predicted_idx], 'probs': probs.detach().numpy().tolist(), 'pooled': pooled_output.detach().numpy().tolist() } out_js = json.dumps(out_dic) return [out_js] def postprocess(self, inference_output): """ Return inference result. :param inference_output: list of inference output :return: list of predict results """ # Take output from network and post-process to desired format postprocess_output = inference_output return postprocess_output
def run(): df = pd.read_csv("inputs/reviews.csv") df["sentiment"] = df.score.apply(rating_to_sentiment) df_train, df_rem = train_test_split(df, test_size=0.1, random_state=config.RANDOM_SEED) df_val, df_test = train_test_split(df_rem, test_size=0.5, random_state=config.RANDOM_SEED) train_data_loader = create_data_loader(df_train, config.TOKENIZER, config.MAX_LEN, config.BATCH_SIZE) val_data_loader = create_data_loader(df_val, config.TOKENIZER, config.MAX_LEN, config.BATCH_SIZE) test_data_loader = create_data_loader(df_test, config.TOKENIZER, config.MAX_LEN, config.BATCH_SIZE) # data = next(iter(val_data_loader)) # input_ids = data["input_ids"].to(config.DEVICE) # attention_mask = data["attention_mask"].to(config.DEVICE) # bert_model = BertModel.from_pretrained(config.BERT_NAME) model = SentimentClassifier(num_classes=len(class_labels)) if config.LOAD_MODEL == True: model.load_state_dict(torch.load("best_model_state.bin")) model = model.to(config.DEVICE) optimizer = AdamW(model.parameters(), lr=2e-5, correct_bias=False) total_steps = len(train_data_loader) * config.EPOCHS scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=0, num_training_steps=total_steps) loss_fn = nn.CrossEntropyLoss().to(config.DEVICE) history = defaultdict(list) best_accuracy = 0 for epoch in range(config.EPOCHS): print(f"Epoch {epoch + 1}/{config.EPOCHS}") print("-" * 10) train_acc, train_loss = train_fn( model, train_data_loader, loss_fn, optimizer, config.DEVICE, scheduler, len(df_train), ) print(f"Train loss {train_loss} accuracy {train_acc}") val_acc, val_loss = eval_fn(model, val_data_loader, loss_fn, config.DEVICE, len(df_val)) print(f"Val loss {val_loss} accuracy {val_acc}") print() history["train_acc"].append(train_acc) history["train_loss"].append(train_loss) history["val_acc"].append(val_acc) history["val_loss"].append(val_loss) if val_acc > best_accuracy: torch.save(model.state_dict(), "best_model_state.bin") best_accuracy = val_acc
def predict(): sentence = request.args.get("sentence") start_time = time.time() positive_prediction = sentence_prediction(sentence, model=MODEL) negative_prediction = 1 - positive_prediction response = {} response["response"] = { "positive": str(positive_prediction), "negative": str(negative_prediction), "neutral": str(neutral_prediction), "sentence": str(sentence), "time_taken": str(time.time() - start_time), } return flask.jsonify(response) if __name__ == "__main__": RANDOM_SEED = 42 np.random.seed(RANDOM_SEED) torch.manual_seed(RANDOM_SEED) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print(device) MODEL = SentimentClassifier(3) MODEL.load_state_dict(torch.load(config.MODEL_PATH, map_location='cpu')) MODEL.to(DEVICE) MODEL.eval() app.run() # oaded_state = torch.load(model_path+seq_to_seq_test_model_fname,map_location='cuda:0'