Packages

fnord

0.9.20

AI code archaeology

Current section

Files

Jump to
fnord lib ai pretend_tokenizer.ex
Raw

lib/ai/pretend_tokenizer.ex

defmodule AI.PretendTokenizer do
@moduledoc """
OpenAI's tokenizer uses regexes that are not compatible with Erlang's regex
engine. There are a couple of modules available on hex, but all of them
require a working python installation, access to rustc, a number of external
dependencies, and some env flags set to allow it to compile.
Rather than impose that on end users, this module guesstimates token counts
based on OpenAI's assertion that 1 token is approximately 4 characters.
Callers must take that into account when selecting their chunk size,
including some amount of buffer to account for the inaccuracy of this
approximation.
"""
@type input :: String.t()
@type chunk_size :: non_neg_integer() | AI.Model.t()
@type reduction_factor :: float()
@type chunked_input :: [String.t()]
@spec chunk(input, chunk_size, reduction_factor) :: chunked_input
def chunk(input, %AI.Model{context: tokens}, reduction_factor) do
chunk(input, tokens, reduction_factor)
end
def chunk(input, chunk_size, reduction_factor) do
target = trunc(chunk_size * 4 * reduction_factor)
size = target - rem(target, 4)
input
|> String.graphemes()
|> Enum.chunk_every(size)
|> Enum.map(&Enum.join/1)
end
def guesstimate_tokens(input) do
(String.length(input) / 4)
|> ceil()
end
def over_max_for_openai_embeddings?(input) do
guesstimate_tokens(input) > 300_000
end
end