code: def create_masked_lm_predictions(tokens, masked_lm_prob, max_predictions_per_seq, vocab_list):
      
      cand_indices = []
      for (i, token) in enumerate(tokens):
          if token == "[CLS]" or token == "[SEP]":
              continue
          cand_indices.append(i)
  
      num_to_mask = min(max_predictions_per_seq,
                        max(1, int(round(len(tokens) * masked_lm_prob))))
      shuffle(cand_indices)
      mask_indices = sorted(sample(cand_indices, num_to_mask))
      masked_token_labels = []
      for index in mask_indices:
          # 80% of the time, replace with [MASK]
          if random() < 0.8:
              masked_token = "[MASK]"
          else:
              # 10% of the time, keep original
              if random() < 0.5:
                  masked_token = tokens[index]
              # 10% of the time, replace with random word
              else:
                  masked_token = choice(vocab_list)
          masked_token_labels.append(tokens[index])
          # Once we've saved the true label for that token, we can overwrite it with the masked version
          tokens[index] = masked_token
  
      return tokens, mask_indices, masked_token_labels
docs: Creates the predictions for the masked LM objective. This is mostly copied from the Google BERT repo, but
      with several refactors to clean it up and remove a lot of unnecessary variables.