def rerank(self, query: str, results: Dict, searchable_attributes: List[str] = None) -> None:
        """the main reranking method

        Args:
            query (str): _description_
            results (Dict): _description_
            searchable_attributes (List[str], optional): _description_. Defaults to None.

        Raises:
            TypeError: _description_
            RuntimeError: _description_
        """
        self.results = results
        self.searchable_attributes = searchable_attributes

        if not isinstance(results, (dict, defaultdict)):
            raise TypeError(f"expected a dict or defaultdict, received {type(results)}")

        if len(results[ResultsFields.hits]) == 0:
            logger.warning("empty results for re-ranking. returning doing nothing...")
            return 

        if self.model is None:
            self.load_model()

        self.format_results(results)

        # we need to create the pairs of data to score over
        # if searchable attributes is None, then we do all non _ fields, 
        # otherwise search over the searchable attributes
        if self.searchable_attributes is None:
            self.searchable_attributes = self.formatted_results.searchable_fields

        # first stage of formatting converts results dict to dataframe
        self.inputs_df = self.formatted_results.format_for_model(self.formatted_results.results_df, self.searchable_attributes, query=query)
        
        # second stage (optionally) add more rows by splitting the content into sub-chunks and
        # performing the apprpriate filling in of other values
        if self.split_params is not None:
            _n = len(self.inputs_df)
            self.inputs_df = self.explode_nested_content_field(self.inputs_df)
            logger.info(f"chunking field content, went from length {_n} to {len(self.inputs_df)}")
        
        # final stage creates list of lists of strings to go straight to the model
        self.model_inputs = self._prepare_inputs(self.inputs_df)

        if not _verify_model_inputs(self.model_inputs):
            raise RuntimeError(f"incorrect model inputs, expected list of lists but recevied {type(self.model_inputs)} and {type(self.model_inputs[0])}")

        self.scores = self.model.predict(self.model_inputs)
        self.scores = _convert_cross_encoder_output(self.scores)

        self.inputs_df[ResultsFields.reranker_score] = self.scores
        self.inputs_df[ResultsFields.hybrid_score_multiply] = np.clip(self.inputs_df[ResultsFields.original_score], 1e-3, np.inf)*np.clip(self.inputs_df[ResultsFields.reranker_score], 1e-3, np.inf)
        self.inputs_df[ResultsFields.hybrid_score_add] = self.inputs_df[ResultsFields.original_score] + self.inputs_df[ResultsFields.reranker_score]

        self.get_reranked_results()
the main reranking method

        Args:
            query (str): _description_
            results (Dict): _description_
            searchable_attributes (List[str], optional): _description_. Defaults to None.

        Raises:
            TypeError: _description_
            RuntimeError: _description_
        
src/marqo/s2_inference/reranking/cross_encoders.py