TokenDagger

repository·main·Indexed 19 days ago

https://github.com/m4thyou/tokendagger

A high-performance implementation of OpenAI's TikToken designed as a drop-in replacement. It is optimized for large-scale text and code processing, offering 2x throughput and 4x faster code tokenization. The library provides a Python interface via the Tokenizer and Encoding classes, supporting batch encoding and decoding using a ThreadPoolExecutor, and includes factory functions like load_tokenizer and create_tokenizer.

Tokens
2.5K
Snippets
11
Records
13
Agent score
65%

What's inside tokendagger

  1. Run performance and compatibility tests

    main

    To verify TokenDagger against TikToken or run benchmarks, you can use the provided test scripts. You must have the original tiktoken installed for comparison tests. Use the --tokenizer flag to specify the tokenizer type (e.g., llama or mistral).

    # Build the project
    make clean && make
    
    # Install tiktoken for comparison
    pip3 install tiktoken
    
    # Run compatibility tests
    python3 tests/test_tokendagger_vs_tiktoken.py --tokenizer llama
    python3 tests/test_tokendagger_vs_tiktoken.py --tokenizer mistral
    
    # Run performance benchmarks
    python3 tests/performance_benchmark.py --tokenizer llama
    python3 tests/performance_benchmark.py --tokenizer mistral
    
    # Run code-specific performance benchmarks
    python3 tests/code_performance_benchmark.py --tokenizer llama
  2. Perform a development installation

    main

    If you are developing or building from source, follow these steps to set up the environment. Note that libpcre2-dev is a required system dependency for the optimized regex engine.

    git clone git@github.com:M4THYOU/TokenDagger.git
    sudo apt install libpcre2-dev
    git submodule update --init --recursive
    sudo apt update && sudo apt install -y python3-dev
  3. Use TokenDagger as a drop-in replacement for tiktoken

    main

    TokenDagger is designed to be a drop-in replacement for the tiktoken library. To switch, install tokendagger and change your import statement from import tiktoken to import tokendagger as tiktoken. The Encoding class and its parameters remain compatible.

    import tokendagger as tiktoken
    
    # The usage remains identical to tiktoken
    tokenizer = tiktoken.Encoding(
        name=name,
        pat_str=pattern,
        mergeable_ranks=vocab,
        special_tokens=special_tokens,
    )
  4. Encode and Decode in batches

    main

    For high-performance processing of multiple strings, use the batch methods which utilize a ThreadPoolExecutor for parallel execution.

    • encode_batch(text: Sequence[str], num_threads: int = 8, ...): Returns a list of lists of token IDs.
    • decode_batch(tokens: Sequence[Sequence[int]], num_threads: int = 8, errors: str = "replace"): Returns a list of decoded strings.
    texts = ["hello", "world", "token dagger"]
    
    # Parallel encoding
    batch_tokens = tokenizer.encode_batch(texts, num_threads=4)
    
    # Parallel decoding
    strings = tokenizer.decode_batch(batch_tokens, errors="replace")
  5. Use factory functions to create Tokenizers

    main

    TokenDagger provides several convenience functions to instantiate a Tokenizer:

    • load_tokenizer(name, vocab_file, pattern, special_tokens_file=None): Loads a tokenizer from JSON files.
    • create_tokenizer(name, pattern, vocab, special_tokens=None): Creates a tokenizer from in-memory data.
    • Encoding(name, *, pat_str, mergeable_ranks, special_tokens=None): A specialized factory function for tiktoken-compatible data structures.
    from tokendagger import load_tokenizer, Encoding
    
    # From files
    tok = load_tokenizer("my-tok", "vocab.json", r"<regex>", "special.json")
    
    # From tiktoken-style dicts
    tok = Encoding(
        name="tiktoken-style",
        pat_str=r"<regex>",
        mergeable_ranks={b"abc": 123}
    )
  6. Tokenizer utility properties and methods

    main

    The Tokenizer class provides several utility methods to inspect the vocabulary:

    • n_vocab (property): Returns the total vocabulary size.
    • special_tokens() (method): Returns a list of special token strings.
    • special_tokens_set (property): Returns a set of special token strings.
    • is_special_token(token: int) (method): Returns True if the provided token ID is a special token.
  7. Use TokenDagger public API for tokenization

    main

    TokenDagger provides a high-performance Python interface for tokenization via the Tokenizer and Encoding classes. You can initialize a tokenizer using create_tokenizer or load a pre-configured one using load_tokenizer. All errors raised by the library are of type TokenDaggerError.

    from tokendagger import create_tokenizer, load_tokenizer, Tokenizer, Encoding, TokenDaggerError
    
    # Example usage pattern (conceptual based on exported symbols):
    # tokenizer = create_tokenizer(model_name='gpt-4')
    # encoding = tokenizer.get_encoding()
    # tokens = tokenizer.encode("Hello world")
  8. Decode tokens to strings or bytes

    main

    Use decode() to convert a sequence of token IDs back into a UTF-8 string, or decode_bytes() to get the raw bytes.

    • decode(tokens: Sequence[int], errors: str = "replace"): Converts tokens to a string. The errors parameter accepts 'replace', 'ignore', or 'strict' (standard Python error handling modes).
    • decode_bytes(tokens: Sequence[int]): Converts tokens directly to bytes.
    tokens = [104, 101, 108, 108, 111]
    
    # To string
    text = tokenizer.decode(tokens)
    
    # To bytes
    raw_bytes = tokenizer.decode_bytes(tokens)
  9. Encode text with Tokenizer.encode()

    main

    Use encode() to convert a string into a list of token IDs. This method supports handling special tokens via allowed_special and disallowed_special parameters.

    • allowed_special: Can be set to "all" to allow all registered special tokens, or a specific set of strings. If not specified, defaults to an empty set.
    • disallowed_special: Can be set to "all" to raise an error if any special token (not in allowed_special) is found in the text. If a disallowed token is encountered, a ValueError is raised.
    # Encode text allowing specific special tokens
    tokens = tokenizer.encode("hello <|endoftext|>", allowed_special={"<|endoftext|>"})
    
    # Encode text and raise error if any special tokens are present
    tokens = tokenizer.encode("hello <|endoftext|>", disallowed_special="all")
  10. Initialize the Tokenizer

    main

    The Tokenizer class is the primary high-level interface for TokenDagger. It is designed to be compatible with OpenAI's tiktoken API. You can initialize it using in-memory data (vocabulary, mergeable ranks, or special tokens) or by loading from JSON files.

    Initialization Options:

    • In-memory: Provide vocab (list of dicts), mergeable_ranks (dict mapping bytes to int), or special_tokens (dict mapping str to int).
    • Files: Provide vocab_file and/or special_tokens_file (JSON format).
    • TikToken Compatibility: Use pat_str instead of pattern and mergeable_ranks instead of vocab to match the tiktoken format.
    from tokendagger import Tokenizer
    
    # Example: Initialize with in-memory data
    tokenizer = Tokenizer(
        name="my-tokenizer",
        pattern=r"""<your_regex>""",
        vocab=[{"rank": 0, "token_bytes": [104], "token_string": "h"}],
        special_tokens={"<|endoftext|>": 100000}
    )
  11. Handle TokenDaggerError

    main

    Most failures within the tokenizer (such as C++ extension errors or encoding failures) raise a TokenDaggerError. This is the base exception for the library. You should catch this when performing operations that rely on the underlying C++ CoreBPE engine.

    from tokendagger import Tokenizer, TokenDaggerError
    
    try:
        tokens = tokenizer.encode("some text")
    except TokenDaggerError as e:
        print(f"Tokenizer operation failed: {e}")