docs: def build_to_target_size_from_token_counts(cls,
                                                 target_size,
                                                 token_counts,
                                                 min_val,
                                                 max_val,
                                                 num_iterations=4):
          """Builds a SubwordTextTokenizer that has `vocab_size` near `target_size`.
  
          Uses simple recursive binary search to find a minimum token count that most
          closely matches the `target_size`.
  
          Args:
            target_size: Desired vocab_size to approximate.
            token_counts: A dictionary of token counts, mapping string to int.
            min_val: An integer; lower bound for the minimum token count.
            max_val: An integer; upper bound for the minimum token count.
            num_iterations: An integer; how many iterations of refinement.
  
          Returns:
            A SubwordTextTokenizer instance.
  
          Raises:
            ValueError: If `min_val` is greater than `max_val`.
          """
          if min_val > max_val:
              raise ValueError("Lower bound for the minimum token count "
                               "is greater than the upper bound.")
  
          def bisect(min_val, max_val):
              """Bisection to find the right size."""
              present_count = (max_val + min_val) // 2
              logger.info("Trying min_count %d" % present_count)
              subtokenizer = cls()
              subtokenizer.build_from_token_counts(token_counts, present_count, num_iterations)
              logger.info("min_count %d attained a %d vocab_size", present_count,
                          subtokenizer.vocab_size)
  
              # If min_val == max_val, we can't do any better than this.
              if subtokenizer.vocab_size == target_size or min_val >= max_val:
                  return subtokenizer
  
              if subtokenizer.vocab_size > target_size:
                  other_subtokenizer = bisect(present_count + 1, max_val)
              else:
                  other_subtokenizer = bisect(min_val, present_count - 1)
  
              if other_subtokenizer is None:
                  return subtokenizer
  
              if (abs(other_subtokenizer.vocab_size - target_size) <
                      abs(subtokenizer.vocab_size - target_size)):
                  return other_subtokenizer
              return subtokenizer
  
          return bisect(min_val, max_val)