docstr: text_vecs (bs, max_ctxt_size):
  cand_vecs (bs, max_num_gold_mentions, 1, max_cand_size):
  text_encs (batch_num_mentions, embed_size): Pre-encoded mention vectors, masked before input
  cand_encs (num_ents_to_match [batch_num_total_ents/all_ents], embed_size): Pre-encoded candidate vectors, masked before input
docstr_tok: ["text_vecs","(","bs",",","max_ctxt_size",")",":","cand_vecs","(","bs",",","max_num_gold_mentions",",","1",",","max_cand_size",")",":","text_encs","(","batch_num_mentions",",","embed_size",")",":","Pre-encoded","mention","vectors",",","masked","before","input","cand_encs","(","num_ents_to_match","[","batch_num_total_ents\/all_ents","]",",","embed_size",")",":","Pre-encoded","candidate","vectors",",","masked","before","input"]
code: def score_candidate(
      self,
      text_vecs,
      cand_vecs,
      text_encs=None,  # pre-computed mention encoding
      cand_encs=None,  # pre-computed candidate encoding.
      gold_mention_bounds=None,
      gold_mention_bounds_mask=None,
      num_cand_mentions=50,
      mention_threshold=-4.5,
      get_mention_scores=True,
      hard_negs=False,  # (if training) passed in a subset of hard negatives
      hard_negs_mask=None,  # (if hard negs training) mask for gold candidate mentions on all inputs (pos + negs)
  ):
      """
      text_vecs (bs, max_ctxt_size):
      cand_vecs (bs, max_num_gold_mentions, 1, max_cand_size):
      text_encs (batch_num_mentions, embed_size): Pre-encoded mention vectors, masked before input
      cand_encs (num_ents_to_match [batch_num_total_ents/all_ents], embed_size): Pre-encoded candidate vectors, masked before input
      """
      """
          Compute context representations and/or get mention scores
          """
      if text_encs is None or get_mention_scores:
          # embedding_ctxt: (bs, num_gold_mentions/num_pred_mentions, embed_size)
          context_outs = self.encode_context(
              text_vecs,
              gold_mention_bounds=gold_mention_bounds,
              gold_mention_bounds_mask=gold_mention_bounds_mask,
              num_cand_mentions=num_cand_mentions,
              topK_threshold=mention_threshold,
              get_mention_scores=get_mention_scores,
          )
  
      mention_logits = None
      mention_bounds = None
      if get_mention_scores:
          mention_logits = context_outs["all_mention_logits"]
          mention_bounds = context_outs["all_mention_bounds"]
  
      if text_encs is None:
          if gold_mention_bounds is None:
              # (all_batch_pred_mentions, embed_size)
              embedding_ctxt = context_outs["mention_reps"][
                  context_outs["mention_masks"]
              ]
          else:
              # (all_batch_pred_mentions, embed_size)
              embedding_ctxt = context_outs["mention_reps"][
                  gold_mention_bounds_mask
              ]
      else:
          # Context encoding is given, do not need to re-compute
          embedding_ctxt = text_encs
  
      """
          Compute candidate representations
          """
      if cand_encs is None:
          # Train time: Compute candidates in batch and compare in-batch negatives
          # cand_vecs: (bs, num_gold_mentions, 1, cand_width) -> (batch_num_gold_mentions, cand_width)
          cand_vecs = cand_vecs[gold_mention_bounds_mask].squeeze(1)
          # (batch_num_gold_mentions, embed_dim)
          embedding_cands = self.encode_candidate(cand_vecs)
      else:
          # (batch_num_gold_mentions, embed_dim)
          embedding_cands = cand_encs
  
      """
          Do inner-product search, or obtain scores on hard-negative entities
          """
      if hard_negs:
          assert hard_negs_mask is not None
          # (num_mention_in_batch, embed_dim)
          embedding_ctxt = embedding_ctxt[hard_negs_mask]
          embedding_cands = embedding_cands[hard_negs_mask]
          embedding_ctxt = embedding_ctxt.unsqueeze(
              1
          )  # num_mention_in_batch x 1 x embed_size
          embedding_cands = embedding_cands.unsqueeze(
              2
          )  # num_mention_in_batch x embed_size x 1
          scores = torch.bmm(
              embedding_ctxt, embedding_cands
          )  # num_mention_in_batch x 1 x 1
          scores = torch.squeeze(scores)
          # (num_mention_in_batch,)
          return scores, mention_logits, mention_bounds
      else:
          # matmul across all cand_encs (in-batch, if cand_encs is None, or across all cand_encs)
          # (all_batch_pred_mentions, num_cands)
          # similarity score between ctxt i and cand j
          all_scores = embedding_ctxt.mm(embedding_cands.t())
  
          return all_scores, mention_logits, mention_bounds
  
imports: import os
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from tqdm import tqdm
  from collections import OrderedDict
  from pytorch_transformers.modeling_bert import BertPreTrainedModel, BertConfig, BertModel
  from pytorch_transformers.tokenization_bert import BertTokenizer
  from elq.common.ranker_base import BertEncoder, get_model_obj
  from blink.common.optimizer import get_bert_optimizer
  from elq.biencoder.allennlp_span_utils import batched_span_select, batched_index_select
  from elq.biencoder.utils import batch_reshape_mask_left
label_desc: Use image node_id 8 for calling the BiEncoderRanker obj's underlying member method code with example usage: obj.score_candidate(text_vecs, cand_vecs, text_encs, cand_encs, gold_mention_bounds, gold_mention_bounds_mask, num_cand_mentions, mention_threshold, get_mention_scores, hard_negs, hard_negs_mask) and returns: scores,  mention_logits,  mention_bounds, all_scores,  mention_logits,  mention_bounds