Skip to content

fix(tokenizer): register deepseek_v32 config alias for DeepSeek-V3.2-Exp - #1069

Merged
ajcasagrande merged 3 commits into
ai-dynamo:mainfrom
waynel96:siweili/deepseek-v32-tokenizer-alias
Jul 22, 2026
Merged

fix(tokenizer): register deepseek_v32 config alias for DeepSeek-V3.2-Exp#1069
ajcasagrande merged 3 commits into
ai-dynamo:mainfrom
waynel96:siweili/deepseek-v32-tokenizer-alias

Conversation

@waynel96

@waynel96 waynel96 commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

What

DeepSeek-V3.2-Exp ships config.json with model_type: "deepseek_v32" and
no auto_map. On transformers releases without native deepseek_v32
support (which our >=4.56 floor still admits), the AutoConfig lookup that
AutoTokenizer performs internally fails, and tokenizer loading aborts at
"Configure Profiling" before any benchmark traffic. --tokenizer-trust-remote-code
cannot help: with no auto_map, there is no remote config class to import.

The serving engine (vLLM/SGLang) loads the model fine — only the AIPerf client crashes.

Fixes #1047

How

Register a narrow DeepseekV3Config alias under model_type "deepseek_v32"
before loading the tokenizer (V3.2 reuses the V3 config schema; vLLM and SGLang
do the same via AutoConfig.register). The shim is:

  • Idempotent & best-effort: a no-op once the model type is known (native
    support on newer transformers, or a prior call), and silent if the base
    config class is unavailable so loading reaches its normal error path.
  • Narrowly scoped to deepseek_v32 only (kimi_k2 ships an auto_map;
    deepseek_v3/deepseek_v2 are already in transformers).
  • Self-limiting: native support landed upstream in Add deepseek 3.2 exp huggingface/transformers#41251,
    so this covers only the older releases in our supported range that predate it.

Testing

New unit tests in tests/unit/common/test_tokenizer_deepseek_v32.py (5 tests):
registration / no-op / error-swallow cases, a real-transformers round-trip,
and a _load_from_hub hook check.

Verified end-to-end against the real deepseek-ai/DeepSeek-V3.2-Exp
tokenizer files on real transformers==5.5.4, driving AIPerf's own
Tokenizer.from_pretrained:

State Result
fix disabled (pre-fix behavior) TokenizerError: ... AttributeError: 'PreTrainedConfig' object has no attribute 'max_position_embeddings' — reproduces #1047
fix enabled (this PR) loads LlamaTokenizer; encodes/decodes correctly

No regressions: 250 tokenizer + 2048 tests/unit/common + 59 property tests pass.
Doc note added to docs/reference/tokenizer-auto-detection.md.

Summary by CodeRabbit

  • Bug Fixes
    • Improved tokenizer loading for DeepSeek-V3.2-Exp on older installations by adding a best-effort compatibility alias for the model type so configuration lookups succeed.
  • Tests
    • Added unit tests covering alias registration, idempotent no-op when native support exists, graceful error handling, and end-to-end config resolution during tokenizer hub loading.
  • Documentation
    • Updated tokenizer auto-detection reference with a new “Model Compatibility Shims” section explaining the scenario and expected behavior (including limitations of remote code trust).

@copy-pr-bot

copy-pr-bot Bot commented Jun 26, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the fix label Jun 26, 2026
@github-actions

github-actions Bot commented Jun 26, 2026

Copy link
Copy Markdown

Try out this PR

Quick install:

pip install --upgrade --force-reinstall git+https://github.com/ai-dynamo/aiperf.git@725ed3c3b2e721e362edc6e62e69ed364a3150f1

Recommended with virtual environment (using uv):

uv venv --python 3.12 && source .venv/bin/activate
uv pip install --upgrade --force-reinstall git+https://github.com/ai-dynamo/aiperf.git@725ed3c3b2e721e362edc6e62e69ed364a3150f1

Last updated for commit: 725ed3cBrowse code

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b45f45ae-26ec-41a8-bba5-ee1cff08c76c

📥 Commits

Reviewing files that changed from the base of the PR and between 0424f8d and 06e415e.

📒 Files selected for processing (3)
  • docs/reference/tokenizer-auto-detection.md
  • src/aiperf/common/tokenizer.py
  • tests/unit/common/test_tokenizer_deepseek_v32.py
✅ Files skipped from review due to trivial changes (1)
  • docs/reference/tokenizer-auto-detection.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/unit/common/test_tokenizer_deepseek_v32.py
  • src/aiperf/common/tokenizer.py

Walkthrough

Adds a best-effort deepseek_v32 alias during tokenizer loading, documents the compatibility shim, and adds tests for registry behavior and hook invocation.

Changes

DeepSeek V3.2 tokenizer shim

Layer / File(s) Summary
Shim registration and load hook
src/aiperf/common/tokenizer.py, docs/reference/tokenizer-auto-detection.md
Adds _ensure_deepseek_v32_config_registered(), calls it from _load_from_hub, and documents the deepseek_v32 compatibility shim behavior.
Shim behavior tests
tests/unit/common/test_tokenizer_deepseek_v32.py
Adds tests for alias registration, native-support no-op behavior, error swallowing, idempotent resolution, and _load_from_hub hook invocation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sniffed a config in the frost,
and found a shim where hope was lost.
A hop, a tweak, a tiny spree—
now deepseek_v32 loads happily.
Thump-thump! The tests all sang with glee.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately names the main tokenizer alias fix for DeepSeek-V3.2-Exp.
Linked Issues check ✅ Passed The changes add the requested deepseek_v32 config fallback and tests, matching #1047's tokenizer-loading objective.
Out of Scope Changes check ✅ Passed The docs and tests support the alias fix and no unrelated code changes are apparent.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/aiperf/common/tokenizer.py (1)

415-416: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Broad except Exception is appropriate here.

The blanket catch (Ruff BLE001) is justified for this best-effort shim: registration must never block tokenizer loading, and the docstring documents the silent-fallthrough contract. KeyboardInterrupt/SystemExit still propagate, and this is synchronous code, so cancellation semantics don't apply. Consider a # noqa: BLE001 with a short rationale to keep the linter quiet.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/aiperf/common/tokenizer.py` around lines 415 - 416, Keep the broad
exception handling in the tokenizer alias registration shim, but explicitly mark
the `except Exception as e` in `tokenizer.py` with a `# noqa: BLE001` and a
short rationale so Ruff does not flag the intentional best-effort fallback.
Refer to the alias registration block around the `deepseek_v32` shim and
preserve the existing debug logging and silent-fallthrough behavior.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/aiperf/common/tokenizer.py`:
- Around line 415-416: Keep the broad exception handling in the tokenizer alias
registration shim, but explicitly mark the `except Exception as e` in
`tokenizer.py` with a `# noqa: BLE001` and a short rationale so Ruff does not
flag the intentional best-effort fallback. Refer to the alias registration block
around the `deepseek_v32` shim and preserve the existing debug logging and
silent-fallthrough behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c1924124-019a-4ab0-a994-ccf3e9ecec8c

📥 Commits

Reviewing files that changed from the base of the PR and between 55aa21c and 0424f8d.

📒 Files selected for processing (3)
  • docs/reference/tokenizer-auto-detection.md
  • src/aiperf/common/tokenizer.py
  • tests/unit/common/test_tokenizer_deepseek_v32.py

@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

DeepSeek-V3.2-Exp ships config.json with model_type "deepseek_v32" and no
auto_map. On transformers releases without native deepseek_v32 support (our
>=4.56 floor still admits these), the AutoConfig lookup that AutoTokenizer
performs internally fails and tokenizer loading aborts before any benchmark
traffic. --tokenizer-trust-remote-code cannot help because, with no auto_map,
there is no remote config class to import.

Register a narrow DeepseekV3Config alias under model_type "deepseek_v32"
before loading the tokenizer (V3.2 reuses the V3 config schema; vLLM and
SGLang do the same). The shim is idempotent and best-effort: a no-op when
transformers already knows the model type natively, and silent when the
base config class is unavailable so loading reaches its normal error path.
Native support landed upstream in huggingface/transformers#41251; this
covers the older releases in our supported range that predate it.

Fixes ai-dynamo#1047

Signed-off-by: Siwei Li <siweili@amazon.com>
@waynel96
waynel96 force-pushed the siweili/deepseek-v32-tokenizer-alias branch from 0424f8d to 06e415e Compare June 26, 2026 23:03
@waynel96
waynel96 marked this pull request as ready for review June 27, 2026 02:33
Comment thread src/aiperf/common/tokenizer.py
@ilana-n ilana-n self-assigned this Jul 6, 2026

@ajcasagrande ajcasagrande left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this against origin/main and did not find any blocking correctness issues.

What I validated:

  • The shim registers only deepseek_v32, returns without overriding native transformer support, and runs before all AutoTokenizer.from_pretrained(...) load branches.
  • The new unit tests pass (tests/unit/common/test_tokenizer_deepseek_v32.py: 5 passed).
  • A runtime probe against the real deepseek-ai/DeepSeek-V3.2-Exp tokenizer shows the pre-shim AutoConfig.for_model("deepseek_v32") failure, then successful alias registration and LlamaTokenizer load through AIPerf's Tokenizer.from_pretrained.
  • A real aiperf profile invocation against the in-repo mock server with --tokenizer deepseek-ai/DeepSeek-V3.2-Exp --tokenizer-trust-remote-code completed successfully.

Overall assessment: the fix is narrow, well-covered, and matches the stated compatibility goal. Nice job keeping it best-effort and self-disabling for future native support.

@ajcasagrande
ajcasagrande enabled auto-merge (squash) July 8, 2026 20:51
@waynel96

waynel96 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review and approval, @ajcasagrande!

Flagging the 4 red Windows checks — they look unrelated to this change:

  • The failures are in the dependency-install and ZMQ real-transport / component-integration steps (the Windows jobs ran ~30 min and were cancelled on timeout), not in the tokenizer code or the new unit tests.
  • This PR only touches src/aiperf/common/tokenizer.py, its test file, and one docs page — nothing platform-, ZMQ-, or dependency-related.
  • The same commit passed all Windows builds when the PR first opened (2026-06-26); the code hasn't changed since, so this looks like CI-infra flakiness rather than a regression here.

Could you re-run the Windows jobs when you get a chance? I don't have permission to trigger it from my fork. Happy to rebase on main or push an empty commit to re-trigger CI instead if you'd prefer — whatever's easiest.

@ajcasagrande
ajcasagrande merged commit 7a65068 into ai-dynamo:main Jul 22, 2026
27 checks passed
ajcasagrande pushed a commit that referenced this pull request Aug 4, 2026
…Exp (#1069)

Signed-off-by: Siwei Li <siweili@amazon.com>
Co-authored-by: Siwei Li <siweili@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

4 participants