Skip to content

feat(tokenizer): add bounded L0 exact-match encode cache - #270

Open
jiannan-17 wants to merge 1 commit into
vllm-project:mainfrom
jiannan-17:feat/tokenizer-l0-cache
Open

feat(tokenizer): add bounded L0 exact-match encode cache#270
jiannan-17 wants to merge 1 commit into
vllm-project:mainfrom
jiannan-17:feat/tokenizer-l0-cache

Conversation

@jiannan-17

Copy link
Copy Markdown

Purpose

Refs #269.

Adds CachedTokenizer to reuse encode() results for identical inputs. Each cache is tied to a deterministic tokenizer with fixed configuration and returns owned clones of the full Encoding.

  • LRU eviction with entry and estimated-byte limits; oversized results and errors are not cached. Uses lru with default features disabled.
  • Tokenization and result cloning run outside the cache lock.
  • Hit/miss, eviction and oversized counters; gauges track total occupancy across live caches.

Batch encoding, decoding and metadata calls pass through. This PR adds the library wrapper; request-path integration and CLI options follow separately.

Test Plan

Tests cover encoding metadata, eviction, byte accounting, batch bypass and concurrent gauge updates using mocks and a checked-in BPE fixture.

cargo test --lib tokenizer
cargo test --test tokenizer_cache_integration
cargo test --test tokenizer_cache_metrics
cargo test --test tokenizer_integration
cargo fmt --check
cargo clippy --all-targets
cargo bench --bench tokenizer_cache_benchmark -- --warm-up-time 1 --measurement-time 3

Test Result

83 tests pass. Formatting passes; Clippy reports no warnings in changed files.

TinyLlama tokenizer on Apple M4 Pro, Criterion 0.5, 100 samples. Point estimates below exclude returned-encoding and per-miss cache destruction.

Input Uncached Cache hit Cache miss
30 B 2.73 µs 139 ns 2.86 µs
201 B 7.72 µs 395 ns 8.25 µs
638 B 51.76 µs 1.30 µs 53.88 µs
4 KB 333 µs 7.73 µs 334 µs
16 KB 1.51 ms 29.81 µs 1.51 ms

The 90% hit workload is 7.1× faster than uncached. Concurrent all-hit throughput peaks at 4 threads and drops to ~2.0M encodes/s at 8; sharding is deferred.

A 16 KB input retains an estimated 257,025 bytes per entry. These estimates are not RSS bounds. Router end-to-end performance is not measured.


PR checklist
  • Purpose and related issue
  • Test commands
  • Test results

Add CachedTokenizer, a wrapper around Arc<dyn Tokenizer> that memoizes
successful encode() results keyed by the exact input string. Hits return
an owned clone of the full Encoding, so token IDs, token strings, offsets
and masks are preserved.

The cache is bounded by entry count and estimated retained bytes with LRU
eviction (lru crate, default features disabled). Results larger than
max_entry_bytes are returned but not stored. A single parking_lot::Mutex
guards the LRU; tokenization on a miss and the Encoding clone on a hit run
outside the lock. encode_batch(), decode and metadata methods delegate to
the wrapped tokenizer, and errors are never cached. The wrapped tokenizer
must be deterministic with a fixed configuration.

Hit, miss, eviction and oversized counters are exported under
vllm_tokenizer_cache_*. The entries and bytes gauges hold the total
occupancy of every live cache: each instance applies its change to a
process-wide aggregate and publishes the totals while holding its own
lock, and clear() and Drop subtract its share.

Tests use the mock tokenizer and a checked-in byte-level BPE fixture
(tests/fixtures/tokenizer/byte_level_bpe.json); gauge semantics are
covered with a capturing metrics recorder. A criterion benchmark compares
hit, miss, mixed and concurrent workloads against uncached encoding.

Construction is library-level only; request-path integration and CLI
flags are left for a follow-up.

Refs vllm-project#269, vllm-project#244
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-11T23:11:02.141348Z c947a5f Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@jiannan-17
jiannan-17 marked this pull request as draft September 11, 2026 23:05
@jiannan-17
jiannan-17 marked this pull request as ready for review September 11, 2026 23:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant