noch inator commited on
Commit
c8d039e
·
verified ·
1 Parent(s): e62c1bd

Fixed some model loading errors in train function

Browse files
Files changed (1) hide show
  1. ThoughtVectors.py +140 -106
ThoughtVectors.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import random
2
  import math
3
  import torch
@@ -440,20 +441,8 @@ class ThoughtVectors:
440
 
441
  if model and os.path.exists(model):
442
  print("loading model...")
443
- checkpoint = torch.load(model, map_location=self.device)
444
- self.sp.Load(checkpoint['spm_model_path'])
445
- self.vocab_size = self.sp.GetPieceSize()
446
- self.encoder = ThoughtEncoder(
447
- vocab_size=self.vocab_size, d_model=d_model, max_thoughts=max_thoughts,
448
- nhead=encoder_nhead, num_layers=encoder_layers, dropout=dropout,
449
- termination_threshold=termination_threshold, max_len=self.max_len
450
- ).to(self.device)
451
- self.decoder = ThoughtDecoder(
452
- vocab_size=self.vocab_size, d_model=d_model, num_layers=decoder_layers,
453
- nhead=decoder_nhead, dropout=dropout, max_len=self.max_len
454
- ).to(self.device)
455
- self.encoder.load_state_dict(checkpoint['encoder_state_dict'])
456
- self.decoder.load_state_dict(checkpoint['decoder_state_dict'])
457
  print(f"Loaded pre-existing model from {model}")
458
  else:
459
  print("building models")
@@ -507,100 +496,122 @@ class ThoughtVectors:
507
  patience_counter = 0
508
 
509
  print("Beginning training")
510
- for epoch in range(num_epochs):
511
- total_train_loss = 0.0
512
- num_train_batches = (len(train_lazy_data) + batch_size - 1) // batch_size
513
-
514
- for i in range(0, len(train_lazy_data), batch_size):
515
- raw_batch = train_lazy_data[i:i + batch_size]
516
- tokenized_batch = [
517
- [[self.sp.bos_id()] + self.sp.EncodeAsIds(s) + [self.sp.eos_id()] for s in group]
518
- for group in raw_batch
519
- ]
520
- group_batch = group_collate_fn(tokenized_batch)
521
-
522
- batch_loss = 0.0
523
- with autocast('cuda'):
524
- for group_tensor in group_batch:
525
- if group_tensor.shape[1] <= self.max_len and group_tensor.numel() > 0:
526
- group_tensor = group_tensor.to(self.device)
527
- force_single_vector = random.random() < single_vector_prob
528
- thought_vectors = self.encoder(group_tensor, force_single_vector)
529
- output_logits = self.decoder(thought_vectors, group_tensor[:, :-1])
530
-
531
- # Masked loss
532
- mask = (group_tensor[:, 1:] != self.sp.pad_id()).float()
533
- loss = criterion(output_logits.reshape(-1, self.vocab_size),
534
- group_tensor[:, 1:].reshape(-1))
535
- loss = (loss * mask.reshape(-1)).sum() / mask.sum().clamp(min=1.0)
536
- if not force_single_vector:
537
- loss += length_penalty * thought_vectors.shape[1]
538
- batch_loss += loss / accum_steps
539
-
540
- scaler.scale(batch_loss).backward()
541
- total_train_loss += batch_loss.item() * accum_steps
542
- if (i // batch_size + 1) % accum_steps == 0:
543
- scaler.step(optimizer)
544
- scaler.update()
545
- optimizer.zero_grad()
546
- torch.cuda.empty_cache()
547
-
548
- print(f"Batch {i // batch_size + 1}/{num_train_batches} - Loss: {batch_loss.item():.4f}")
549
- # Debugging
550
- print(f" Input: {self.sp.DecodeIds(group_tensor[0].tolist())}")
551
- print(f"Output: {self.sp.DecodeIds(output_logits.argmax(-1)[0].tolist())}\n\n")
552
-
553
- avg_train_loss = total_train_loss / num_train_batches if num_train_batches > 0 else float('inf')
554
-
555
- # Validation with test_lazy_data
556
- if test_lazy_data is not None:
557
- self.encoder.eval()
558
- self.decoder.eval()
559
- total_val_loss = 0.0
560
- num_val_batches = (len(test_lazy_data) + batch_size - 1) // batch_size
561
- print(f"Starting validation with {num_val_batches} batches")
562
 
563
- with torch.no_grad():
564
- for i in range(0, len(test_lazy_data), batch_size):
565
- raw_batch = test_lazy_data[i:i + batch_size]
566
- tokenized_batch = [
567
- [[self.sp.bos_id()] + self.sp.EncodeAsIds(s) + [self.sp.eos_id()] for s in group]
568
- for group in raw_batch
569
- ]
570
- group_batch = group_collate_fn(tokenized_batch)
571
-
572
- batch_val_loss = 0.0
 
573
  for group_tensor in group_batch:
574
  if group_tensor.shape[1] <= self.max_len and group_tensor.numel() > 0:
575
  group_tensor = group_tensor.to(self.device)
576
- thought_vectors = self.encoder(group_tensor)
 
577
  output_logits = self.decoder(thought_vectors, group_tensor[:, :-1])
578
- val_loss = criterion(output_logits.reshape(-1, self.vocab_size),
579
- group_tensor[:, 1:].reshape(-1))
580
- val_loss += length_penalty * thought_vectors.shape[1]
581
- batch_val_loss += val_loss.item()
582
- total_val_loss += batch_val_loss
583
- print(f"VAL batch loss: {batch_val_loss:.4f}")
584
- print(f" Input: {self.sp.DecodeIds(group_tensor[0].tolist())}")
585
- print(f"Output: {self.sp.DecodeIds(output_logits.argmax(-1)[0].tolist())}\n\n")
586
- avg_val_loss = total_val_loss / num_val_batches if num_val_batches > 0 else float('inf')
587
- else:
588
- avg_val_loss = avg_train_loss
589
-
590
- print(f"Epoch {epoch + 1}/{num_epochs} - Train Loss: {avg_train_loss:.4f} - Val Loss: {avg_val_loss:.4f}\n\n")
591
-
592
- if avg_val_loss < best_val_loss:
593
- best_val_loss = avg_val_loss
594
- patience_counter = 0
595
- self.save(save_path, spm_model_prefix, clean=False)
596
- else:
597
- patience_counter += 1
598
- if patience_counter >= patience:
599
- print(f"Early stopping triggered after {epoch + 1} epochs.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
600
  break
601
-
602
- scheduler.step()
603
-
 
 
 
 
 
 
 
604
  print(f"Best model saved to {save_path}")
605
 
606
  def encode(self, text: Union[str, List[str]], force_single_vector: bool = False) -> torch.Tensor:
@@ -802,10 +813,33 @@ class ThoughtVectors:
802
 
803
 
804
  if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
805
  tv = ThoughtVectors()
806
  tv.train(
807
- group_data="train.csv",
808
- test_data="val.csv",
 
809
  num_epochs=1000,
810
  batch_size=128,
811
  accum_steps=1,
@@ -813,7 +847,7 @@ if __name__ == "__main__":
813
  weight_decay=2e-5,
814
  length_penalty=0.001,
815
  single_vector_prob=0.1,
816
- save_path="thought_vectors_prototype.tar",
817
  spm_model_prefix="spm",
818
  vocab_size=8192,
819
  d_model=512,
@@ -827,7 +861,7 @@ if __name__ == "__main__":
827
  termination_threshold=0.8,
828
  patience=5
829
  )
830
- loaded_tv = ThoughtVectors.load("thought_vectors_prototype.tar")
831
  thought_vectors = loaded_tv.encode("AI is smart")
832
  generated_text_greedy = loaded_tv.decode(thought_vectors, temperature=0.7, beam_width=0)
833
  generated_text_beam = loaded_tv.decode(thought_vectors, beam_width=5)
 
1
+ # thought_vectors.py
2
  import random
3
  import math
4
  import torch
 
441
 
442
  if model and os.path.exists(model):
443
  print("loading model...")
444
+ loaded_instance = self.load(model)
445
+ self.__dict__.update(loaded_instance.__dict__) # actually update self
 
 
 
 
 
 
 
 
 
 
 
 
446
  print(f"Loaded pre-existing model from {model}")
447
  else:
448
  print("building models")
 
496
  patience_counter = 0
497
 
498
  print("Beginning training")
499
+ try:
500
+ for epoch in range(num_epochs):
501
+ total_train_loss = 0.0
502
+ num_train_batches = (len(train_lazy_data) + batch_size - 1) // batch_size
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
503
 
504
+ # training
505
+ for i in range(0, len(train_lazy_data), batch_size):
506
+ raw_batch = train_lazy_data[i:i + batch_size]
507
+ tokenized_batch = [
508
+ [[self.sp.bos_id()] + self.sp.EncodeAsIds(s) + [self.sp.eos_id()] for s in group]
509
+ for group in raw_batch
510
+ ]
511
+ group_batch = group_collate_fn(tokenized_batch)
512
+
513
+ batch_loss = 0.0
514
+ with autocast('cuda'):
515
  for group_tensor in group_batch:
516
  if group_tensor.shape[1] <= self.max_len and group_tensor.numel() > 0:
517
  group_tensor = group_tensor.to(self.device)
518
+ force_single_vector = random.random() < single_vector_prob
519
+ thought_vectors = self.encoder(group_tensor, force_single_vector)
520
  output_logits = self.decoder(thought_vectors, group_tensor[:, :-1])
521
+
522
+ # Masked loss
523
+ mask = (group_tensor[:, 1:] != self.sp.pad_id()).float()
524
+ loss = criterion(output_logits.reshape(-1, self.vocab_size),
525
+ group_tensor[:, 1:].reshape(-1))
526
+ loss = (loss * mask.reshape(-1)).sum() / mask.sum().clamp(min=1.0)
527
+ if not force_single_vector:
528
+ loss += length_penalty * thought_vectors.shape[1]
529
+ batch_loss += loss / accum_steps
530
+
531
+ scaler.scale(batch_loss).backward()
532
+ total_train_loss += batch_loss.item() * accum_steps
533
+ if (i // batch_size + 1) % accum_steps == 0:
534
+ scaler.step(optimizer)
535
+ scaler.update()
536
+ optimizer.zero_grad()
537
+ torch.cuda.empty_cache()
538
+
539
+ print(f"Batch {i // batch_size + 1}/{num_train_batches} - Loss: {batch_loss.item():.4f}")
540
+ # Debugging
541
+ print(f" Input: {self.sp.DecodeIds(group_tensor[0].tolist())}")
542
+ print(f"Output: {self.sp.DecodeIds(output_logits.argmax(-1)[0].tolist())}\n\n")
543
+
544
+ avg_train_loss = total_train_loss / num_train_batches if num_train_batches > 0 else float('inf')
545
+
546
+ # Validation
547
+ if test_lazy_data is not None:
548
+ self.encoder.eval()
549
+ self.decoder.eval()
550
+ total_val_loss = 0.0
551
+ num_val_batches = (len(test_lazy_data) + batch_size - 1) // batch_size
552
+ print(f"Starting validation with {num_val_batches} batches")
553
+
554
+ with torch.no_grad():
555
+ for i in range(0, len(test_lazy_data), batch_size):
556
+ raw_batch = test_lazy_data[i:i + batch_size]
557
+ tokenized_batch = [
558
+ [[self.sp.bos_id()] + self.sp.EncodeAsIds(s) + [self.sp.eos_id()] for s in group]
559
+ for group in raw_batch
560
+ ]
561
+ group_batch = group_collate_fn(tokenized_batch)
562
+
563
+ batch_val_loss = 0.0
564
+ for group_tensor in group_batch:
565
+ if group_tensor.shape[1] <= self.max_len and group_tensor.numel() > 0:
566
+ group_tensor = group_tensor.to(self.device)
567
+ thought_vectors = self.encoder(group_tensor)
568
+ output_logits = self.decoder(thought_vectors, group_tensor[:, :-1])
569
+ val_loss = criterion(output_logits.reshape(-1, self.vocab_size),
570
+ group_tensor[:, 1:].reshape(-1))
571
+ val_loss += length_penalty * thought_vectors.shape[1]
572
+ batch_val_loss += val_loss.item()
573
+ total_val_loss += batch_val_loss
574
+ print(f"VAL batch loss: {batch_val_loss:.4f}")
575
+ print(f" Input: {self.sp.DecodeIds(group_tensor[0].tolist())}")
576
+ print(f"Output: {self.sp.DecodeIds(output_logits.argmax(-1)[0].tolist())}\n\n")
577
+ avg_val_loss = total_val_loss / num_val_batches if num_val_batches > 0 else float('inf')
578
+ else:
579
+ avg_val_loss = avg_train_loss
580
+
581
+ print(f"Epoch {epoch + 1}/{num_epochs} - Train Loss: {avg_train_loss:.4f} - Val Loss: {avg_val_loss:.4f}\n\n")
582
+
583
+ if avg_val_loss < best_val_loss:
584
+ best_val_loss = avg_val_loss
585
+ patience_counter = 0
586
+ self.save(save_path, spm_model_prefix, clean=False)
587
+ else:
588
+ self.load(save_path)
589
+ self.save(save_path, spm_model_prefix, clean=True)
590
+ patience_counter += 1
591
+ if patience_counter >= patience:
592
+ print(f"Early stopping triggered after {epoch + 1} epochs.")
593
+ break
594
+
595
+ scheduler.step()
596
+ # Allow saving model on keyboard interrupt
597
+ except KeyboardInterrupt:
598
+ while True:
599
+ saving = input("Would you like to save the best (b), current (c), or no (n) model?")
600
+ saving = saving.strip().lower
601
+ if saving == "best" or saving == "b":
602
+ self.load(save_path)
603
+ self.save(save_path, spm_model_prefix, clean=True)
604
  break
605
+ elif saving == "current" or saving == "c" or saving == "curr":
606
+ self.save(save_path, spm_model_prefix, clean=True)
607
+ break
608
+ elif saving == "n" or saving == "no" or saving == "":
609
+ self.save(save_path, spm_model_prefix, clean=True)
610
+ os.remove(save_path)
611
+ break
612
+ else:
613
+ print("invalid input, type 'b' 'c' or 'n'")
614
+
615
  print(f"Best model saved to {save_path}")
616
 
617
  def encode(self, text: Union[str, List[str]], force_single_vector: bool = False) -> torch.Tensor:
 
813
 
814
 
815
  if __name__ == "__main__":
816
+ def process_train(input_file):
817
+ data = []
818
+ with open(input_file, 'r', encoding='utf-8') as f_in:
819
+ reader = csv.reader(f_in)
820
+ for row in reader:
821
+ sentence1 = row[0].strip()
822
+ data.append([sentence1])
823
+
824
+ return data
825
+
826
+ def process_test(input_file):
827
+ data = []
828
+ with open(input_file, 'r', encoding='utf-8') as f_in:
829
+ reader = csv.reader(f_in)
830
+ for row in reader:
831
+ sentence1 = row[0].strip()
832
+ data.append([sentence1])
833
+ return data
834
+
835
+ data = process_train("SNLItrain.csv")
836
+ val = process_test("SNLIval.csv")
837
+
838
  tv = ThoughtVectors()
839
  tv.train(
840
+ group_data=data,
841
+ test_data=val,
842
+ model="thought_vectors_prototype-0.1.tar",
843
  num_epochs=1000,
844
  batch_size=128,
845
  accum_steps=1,
 
847
  weight_decay=2e-5,
848
  length_penalty=0.001,
849
  single_vector_prob=0.1,
850
+ save_path="thought_vectors_prototype-0.2.tar",
851
  spm_model_prefix="spm",
852
  vocab_size=8192,
853
  d_model=512,
 
861
  termination_threshold=0.8,
862
  patience=5
863
  )
864
+ loaded_tv = ThoughtVectors.load("thought_vectors_prototype-0.2.tar")
865
  thought_vectors = loaded_tv.encode("AI is smart")
866
  generated_text_greedy = loaded_tv.decode(thought_vectors, temperature=0.7, beam_width=0)
867
  generated_text_beam = loaded_tv.decode(thought_vectors, beam_width=5)