renderers 0.1.11.dev1__tar.gz → 0.1.11.dev3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/PKG-INFO +31 -17
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/README.md +25 -15
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/docs/renderer-config.md +2 -7
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/pyproject.toml +21 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/__init__.py +13 -15
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/_version.py +2 -2
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/base.py +221 -212
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/client.py +10 -36
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/deepseek_v3.py +7 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/default.py +2 -3
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/gemma4.py +8 -8
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/glm45.py +7 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/glm5.py +7 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/gpt_oss.py +7 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/hy3.py +45 -14
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/inkling.py +8 -8
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/kimi_k2.py +7 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/kimi_k25.py +13 -12
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/laguna_s21.py +2 -3
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/laguna_xs2.py +57 -12
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/llama_3.py +7 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/minimax_m2.py +22 -9
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/nemotron3.py +7 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/prime_qwen3.py +17 -8
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/qwen3.py +7 -5
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/qwen35.py +9 -9
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/qwen3_vl.py +10 -10
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_load_tokenizer.py +16 -11
- renderers-0.1.11.dev3/tests/test_offsetless_tokenizers.py +223 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_renderer_config.py +0 -26
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/uv.lock +14 -1
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/.github/workflows/publish-dev.yml +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/.github/workflows/publish.yml +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/.github/workflows/style.yml +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/.github/workflows/test.yml +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/.gitignore +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/.pre-commit-config.yaml +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/LICENSE +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/examples/README.md +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/examples/sglang/multiturn_generate_sglang.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/examples/sglang/online_multiturn_sglang.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/examples/tinker/multiturn_generate_tinker.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/examples/transformers/multiturn_generate_transformers.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/examples/vllm/multiturn_generate_vllm.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/configs.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/deepseek_r1.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/parsers.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/parsing.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/qwen36.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/renderers/qwen38.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/conftest.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_bridge.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_build_helpers.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_client.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_deepseek_r1.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_disabled_thinking_stability.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_gemma4.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_glm_tool_name_validation.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_gpt_oss_harmony_parity.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_hy3.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_incremental.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_inkling.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_is_content.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_kimi_k25_tool_schema.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_laguna_m1.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_laguna_s21.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_laguna_xs21.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_llama_3.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_message_indices.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_message_tool_names.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_multimodal.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_nemotron3_parity.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_nemotron3_ultra.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_parse_response.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_parse_response_robustness.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_parsers.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_preserve_thinking.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_prime_qwen3_parity.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_qwen35_size_coverage.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_qwen38.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_render_ids.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_renderer_config_parity.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_roundtrip.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_sampled_mask.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_tokens_per_message.py +0 -0
- {renderers-0.1.11.dev1 → renderers-0.1.11.dev3}/tests/test_tool_arg_type_preservation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: renderers
|
|
3
|
-
Version: 0.1.11.
|
|
3
|
+
Version: 0.1.11.dev3
|
|
4
4
|
Summary: Chat template renderers — deterministic message-to-token conversion for LLM training
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -11,7 +11,11 @@ Requires-Dist: openai-harmony>=0.0.4
|
|
|
11
11
|
Requires-Dist: openai>=1.108.1
|
|
12
12
|
Requires-Dist: prime-pydantic-config>=0.3.0.dev83
|
|
13
13
|
Requires-Dist: tiktoken
|
|
14
|
-
|
|
14
|
+
Provides-Extra: multimodal
|
|
15
|
+
Requires-Dist: pillow>=12.2.0; extra == 'multimodal'
|
|
16
|
+
Requires-Dist: transformers>=4.50.0; extra == 'multimodal'
|
|
17
|
+
Provides-Extra: transformers
|
|
18
|
+
Requires-Dist: transformers>=4.50.0; extra == 'transformers'
|
|
15
19
|
Description-Content-Type: text/markdown
|
|
16
20
|
|
|
17
21
|
# renderers
|
|
@@ -26,13 +30,30 @@ Standalone on PyPI, and portable across training and inference stacks (transform
|
|
|
26
30
|
uv add renderers
|
|
27
31
|
```
|
|
28
32
|
|
|
33
|
+
The base install supports text renderers with a bring-your-own tokenizer. Add
|
|
34
|
+
the Hugging Face integration for the tokenizer-loading helpers, or the complete
|
|
35
|
+
media stack for image/audio rendering:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
uv add 'renderers[transformers]'
|
|
39
|
+
uv add 'renderers[multimodal]'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
A BYO tokenizer must expose `encode`, `decode`, `convert_tokens_to_ids`, and
|
|
43
|
+
token IDs such as `eos_token_id`. Character offsets are optional: tokenizers
|
|
44
|
+
supporting `return_offsets_mapping=True` also receive precise per-token
|
|
45
|
+
`is_content` attribution; without offsets, renderers return `is_content=[]`.
|
|
46
|
+
`DefaultRenderer` additionally requires `apply_chat_template`. This includes
|
|
47
|
+
text-only Inkling training: `InklingRenderer` loads its Transformers processor
|
|
48
|
+
only when image or audio content is actually rendered.
|
|
49
|
+
|
|
29
50
|
## At a glance
|
|
30
51
|
|
|
31
52
|
```python
|
|
32
|
-
from transformers import AutoTokenizer
|
|
33
53
|
from renderers import create_renderer
|
|
54
|
+
from renderers.base import load_tokenizer
|
|
34
55
|
|
|
35
|
-
tok =
|
|
56
|
+
tok = load_tokenizer("Qwen/Qwen3-8B") # renderers[transformers]
|
|
36
57
|
r = create_renderer(tok) # → Qwen3Renderer (auto-resolved)
|
|
37
58
|
|
|
38
59
|
prompt_ids = r.render_ids(
|
|
@@ -92,17 +113,10 @@ r = create_renderer(tok) # AutoRendererConfig is the implicit def
|
|
|
92
113
|
|
|
93
114
|
Auto-detect matches `tokenizer.name_or_path` against `MODEL_RENDERER_MAP` by **exact match**. Prefix matching is intentionally off — same architecture can ship different chat templates (base vs instruct, fine-tune renames). Fine-tunes must pass an explicit typed config (e.g. `Qwen3RendererConfig()`). Unknown text-only names fall back to `DefaultRenderer`, unless `AutoRendererConfig(thinking_retention=...)` was set; the default renderer cannot implement that bridge policy.
|
|
94
115
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
pool = create_renderer_pool("Qwen/Qwen3-8B", size=16)
|
|
101
|
-
with pool.checkout() as r:
|
|
102
|
-
ids = r.render_ids(messages)
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Each slot owns its own tokenizer copy. Construction fans out across a thread pool so a 32-slot pool doesn't serially eat ~10–15s of `from_pretrained` calls at startup.
|
|
116
|
+
Without the `transformers` extra, exact-match registered models still
|
|
117
|
+
auto-resolve. For an unknown name, renderers cannot safely probe `AutoConfig`
|
|
118
|
+
to distinguish a text model from an unknown VLM; pass an explicit typed config
|
|
119
|
+
such as `DefaultRendererConfig()` for a known text-only model.
|
|
106
120
|
|
|
107
121
|
## Why use a renderer
|
|
108
122
|
|
|
@@ -125,7 +139,7 @@ Each break fragments a rollout into multiple training samples — every fragment
|
|
|
125
139
|
|
|
126
140
|
## Typed renderer configs
|
|
127
141
|
|
|
128
|
-
Each renderer accepts a typed pydantic config at construction. Some fields mirror chat-template kwargs; others configure renderer-only behavior such as image caching, parsers, or Harmony preamble construction. `create_renderer`
|
|
142
|
+
Each renderer accepts a typed pydantic config at construction. Some fields mirror chat-template kwargs; others configure renderer-only behavior such as image caching, parsers, or Harmony preamble construction. `create_renderer` takes one positional `config` argument and an optional keyword-only `chat_template_kwargs` mapping:
|
|
129
143
|
|
|
130
144
|
```python
|
|
131
145
|
from renderers import (
|
|
@@ -175,7 +189,7 @@ Fallback for unsupported text-only models. Wraps `apply_chat_template` and accep
|
|
|
175
189
|
|
|
176
190
|
## Roadmap
|
|
177
191
|
|
|
178
|
-
- **VLM expansion.** `ImagePart` support exists for Qwen3-VL, Qwen3.5-family, Gemma 4, and Kimi K2.5 / K2.6 multimodal templates. Remaining work: audio/video support, broader VLM coverage, and more RL validation. Gemma 4 image preprocessing requires a Transformers release that provides `Gemma4Processor`.
|
|
192
|
+
- **VLM expansion.** `ImagePart` support exists for Qwen3-VL, Qwen3.5-family, Gemma 4, and Kimi K2.5 / K2.6 multimodal templates. Install `renderers[multimodal]` for Pillow and the Hugging Face processors. Remaining work: audio/video support, broader VLM coverage, and more RL validation. Gemma 4 image preprocessing requires a Transformers release that provides `Gemma4Processor`.
|
|
179
193
|
- **Patched chat templates.** Some shipped templates re-tokenize history or normalize JSON in ways that break token identity. Plan: a `use_patched` opt-in per renderer that renders the same surface form while avoiding known-bad patterns. (Auto-stripping thinking from past turns is *not* one of these — that's intended template behaviour the renderer reproduces; use `thinking_retention` to override it.)
|
|
180
194
|
|
|
181
195
|
## Testing
|
|
@@ -10,13 +10,30 @@ Standalone on PyPI, and portable across training and inference stacks (transform
|
|
|
10
10
|
uv add renderers
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
The base install supports text renderers with a bring-your-own tokenizer. Add
|
|
14
|
+
the Hugging Face integration for the tokenizer-loading helpers, or the complete
|
|
15
|
+
media stack for image/audio rendering:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
uv add 'renderers[transformers]'
|
|
19
|
+
uv add 'renderers[multimodal]'
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
A BYO tokenizer must expose `encode`, `decode`, `convert_tokens_to_ids`, and
|
|
23
|
+
token IDs such as `eos_token_id`. Character offsets are optional: tokenizers
|
|
24
|
+
supporting `return_offsets_mapping=True` also receive precise per-token
|
|
25
|
+
`is_content` attribution; without offsets, renderers return `is_content=[]`.
|
|
26
|
+
`DefaultRenderer` additionally requires `apply_chat_template`. This includes
|
|
27
|
+
text-only Inkling training: `InklingRenderer` loads its Transformers processor
|
|
28
|
+
only when image or audio content is actually rendered.
|
|
29
|
+
|
|
13
30
|
## At a glance
|
|
14
31
|
|
|
15
32
|
```python
|
|
16
|
-
from transformers import AutoTokenizer
|
|
17
33
|
from renderers import create_renderer
|
|
34
|
+
from renderers.base import load_tokenizer
|
|
18
35
|
|
|
19
|
-
tok =
|
|
36
|
+
tok = load_tokenizer("Qwen/Qwen3-8B") # renderers[transformers]
|
|
20
37
|
r = create_renderer(tok) # → Qwen3Renderer (auto-resolved)
|
|
21
38
|
|
|
22
39
|
prompt_ids = r.render_ids(
|
|
@@ -76,17 +93,10 @@ r = create_renderer(tok) # AutoRendererConfig is the implicit def
|
|
|
76
93
|
|
|
77
94
|
Auto-detect matches `tokenizer.name_or_path` against `MODEL_RENDERER_MAP` by **exact match**. Prefix matching is intentionally off — same architecture can ship different chat templates (base vs instruct, fine-tune renames). Fine-tunes must pass an explicit typed config (e.g. `Qwen3RendererConfig()`). Unknown text-only names fall back to `DefaultRenderer`, unless `AutoRendererConfig(thinking_retention=...)` was set; the default renderer cannot implement that bridge policy.
|
|
78
95
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
pool = create_renderer_pool("Qwen/Qwen3-8B", size=16)
|
|
85
|
-
with pool.checkout() as r:
|
|
86
|
-
ids = r.render_ids(messages)
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Each slot owns its own tokenizer copy. Construction fans out across a thread pool so a 32-slot pool doesn't serially eat ~10–15s of `from_pretrained` calls at startup.
|
|
96
|
+
Without the `transformers` extra, exact-match registered models still
|
|
97
|
+
auto-resolve. For an unknown name, renderers cannot safely probe `AutoConfig`
|
|
98
|
+
to distinguish a text model from an unknown VLM; pass an explicit typed config
|
|
99
|
+
such as `DefaultRendererConfig()` for a known text-only model.
|
|
90
100
|
|
|
91
101
|
## Why use a renderer
|
|
92
102
|
|
|
@@ -109,7 +119,7 @@ Each break fragments a rollout into multiple training samples — every fragment
|
|
|
109
119
|
|
|
110
120
|
## Typed renderer configs
|
|
111
121
|
|
|
112
|
-
Each renderer accepts a typed pydantic config at construction. Some fields mirror chat-template kwargs; others configure renderer-only behavior such as image caching, parsers, or Harmony preamble construction. `create_renderer`
|
|
122
|
+
Each renderer accepts a typed pydantic config at construction. Some fields mirror chat-template kwargs; others configure renderer-only behavior such as image caching, parsers, or Harmony preamble construction. `create_renderer` takes one positional `config` argument and an optional keyword-only `chat_template_kwargs` mapping:
|
|
113
123
|
|
|
114
124
|
```python
|
|
115
125
|
from renderers import (
|
|
@@ -159,7 +169,7 @@ Fallback for unsupported text-only models. Wraps `apply_chat_template` and accep
|
|
|
159
169
|
|
|
160
170
|
## Roadmap
|
|
161
171
|
|
|
162
|
-
- **VLM expansion.** `ImagePart` support exists for Qwen3-VL, Qwen3.5-family, Gemma 4, and Kimi K2.5 / K2.6 multimodal templates. Remaining work: audio/video support, broader VLM coverage, and more RL validation. Gemma 4 image preprocessing requires a Transformers release that provides `Gemma4Processor`.
|
|
172
|
+
- **VLM expansion.** `ImagePart` support exists for Qwen3-VL, Qwen3.5-family, Gemma 4, and Kimi K2.5 / K2.6 multimodal templates. Install `renderers[multimodal]` for Pillow and the Hugging Face processors. Remaining work: audio/video support, broader VLM coverage, and more RL validation. Gemma 4 image preprocessing requires a Transformers release that provides `Gemma4Processor`.
|
|
163
173
|
- **Patched chat templates.** Some shipped templates re-tokenize history or normalize JSON in ways that break token identity. Plan: a `use_patched` opt-in per renderer that renders the same surface form while avoiding known-bad patterns. (Auto-stripping thinking from past turns is *not* one of these — that's intended template behaviour the renderer reproduces; use `thinking_retention` to override it.)
|
|
164
174
|
|
|
165
175
|
## Testing
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# Renderer config
|
|
2
2
|
|
|
3
|
-
`renderers.RendererConfig` is the typed input to `create_renderer
|
|
4
|
-
|
|
5
|
-
construction time.
|
|
3
|
+
`renderers.RendererConfig` is the typed input to `create_renderer`. It pins the
|
|
4
|
+
renderer choice and its config at construction time.
|
|
6
5
|
|
|
7
6
|
```python
|
|
8
7
|
from renderers import create_renderer, Qwen35RendererConfig
|
|
@@ -77,10 +76,6 @@ r = create_renderer(
|
|
|
77
76
|
tokenizer,
|
|
78
77
|
chat_template_kwargs={"enable_thinking": False},
|
|
79
78
|
)
|
|
80
|
-
pool = create_renderer_pool(
|
|
81
|
-
"Qwen/Qwen3-8B",
|
|
82
|
-
chat_template_kwargs={"enable_thinking": False},
|
|
83
|
-
)
|
|
84
79
|
```
|
|
85
80
|
|
|
86
81
|
Renderers resolves auto configs before applying `chat_template_kwargs`, so the
|
|
@@ -19,11 +19,6 @@ dependencies = [
|
|
|
19
19
|
"openai>=1.108.1",
|
|
20
20
|
"tiktoken",
|
|
21
21
|
"jinja2",
|
|
22
|
-
# Keep this floor compatible with prime-rl's transformers pin. Inkling's
|
|
23
|
-
# tokenizer and text-only renderer work on older releases; image/audio
|
|
24
|
-
# processing fails lazily with an upgrade message when InklingProcessor is
|
|
25
|
-
# unavailable (native support starts in transformers 5.14).
|
|
26
|
-
"transformers>=4.50.0",
|
|
27
22
|
# Used by GptOssRenderer to render and parse harmony tokens. Vendoring
|
|
28
23
|
# OpenAI's reference implementation keeps us byte-identical with vLLM
|
|
29
24
|
# (which also uses it) and saves us mirroring a 330-line Jinja template.
|
|
@@ -42,6 +37,25 @@ dependencies = [
|
|
|
42
37
|
"prime-pydantic-config>=0.3.0.dev83",
|
|
43
38
|
]
|
|
44
39
|
|
|
40
|
+
[project.optional-dependencies]
|
|
41
|
+
# Tokenizer loading uses Hugging Face. Text-only renderers can instead be
|
|
42
|
+
# constructed with a compatible BYO tokenizer and do not import this
|
|
43
|
+
# dependency. Character offsets are optional.
|
|
44
|
+
transformers = [
|
|
45
|
+
# Keep this floor compatible with prime-rl's transformers pin. Inkling's
|
|
46
|
+
# tokenizer and text-only renderer work on older releases; image/audio
|
|
47
|
+
# processing fails lazily with an upgrade message when InklingProcessor is
|
|
48
|
+
# unavailable (native support starts in transformers 5.14).
|
|
49
|
+
"transformers>=4.50.0",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
# Image/audio renderers also need Pillow to resolve media inputs. Keep this as
|
|
53
|
+
# a separate convenience extra so tokenizer-only users do not pull it in.
|
|
54
|
+
multimodal = [
|
|
55
|
+
"pillow>=12.2.0",
|
|
56
|
+
"transformers>=4.50.0",
|
|
57
|
+
]
|
|
58
|
+
|
|
45
59
|
[tool.hatch.version]
|
|
46
60
|
source = "vcs"
|
|
47
61
|
# Tags look like ``renderers-v0.1.8`` (prefix matches the publish.yml
|
|
@@ -90,6 +104,8 @@ dev = [
|
|
|
90
104
|
"torch>=2.11.0",
|
|
91
105
|
"torchvision>=0.26.0",
|
|
92
106
|
"ty>=0.0.1a29,<0.0.22",
|
|
107
|
+
# Optional for consumers, but required by tokenizer/parity/VLM tests.
|
|
108
|
+
"transformers>=4.50.0",
|
|
93
109
|
]
|
|
94
110
|
|
|
95
111
|
[tool.uv]
|
|
@@ -7,6 +7,7 @@ except ImportError:
|
|
|
7
7
|
__version__ = "0+unknown"
|
|
8
8
|
|
|
9
9
|
from renderers.base import (
|
|
10
|
+
ChatTemplateTokenizer,
|
|
10
11
|
Content,
|
|
11
12
|
ContentPart,
|
|
12
13
|
ImagePart,
|
|
@@ -14,6 +15,7 @@ from renderers.base import (
|
|
|
14
15
|
Message,
|
|
15
16
|
MultiModalData,
|
|
16
17
|
MultimodalRenderer,
|
|
18
|
+
OffsetTokenizer,
|
|
17
19
|
ParsedResponse,
|
|
18
20
|
ParsedToolCall,
|
|
19
21
|
PlaceholderRange,
|
|
@@ -21,9 +23,9 @@ from renderers.base import (
|
|
|
21
23
|
RenderedTokens,
|
|
22
24
|
RenderedTrainingSample,
|
|
23
25
|
Renderer,
|
|
24
|
-
RendererPool,
|
|
25
26
|
TextPart,
|
|
26
27
|
ThinkingPart,
|
|
28
|
+
Tokenizer,
|
|
27
29
|
ToolCall,
|
|
28
30
|
ToolCallFunction,
|
|
29
31
|
ToolCallParseStatus,
|
|
@@ -33,7 +35,6 @@ from renderers.base import (
|
|
|
33
35
|
build_training_sample,
|
|
34
36
|
build_trajectory_step,
|
|
35
37
|
create_renderer,
|
|
36
|
-
create_renderer_pool,
|
|
37
38
|
extract_message_tool_names,
|
|
38
39
|
is_multimodal,
|
|
39
40
|
reject_assistant_in_extension,
|
|
@@ -74,17 +75,13 @@ from renderers.configs import (
|
|
|
74
75
|
RendererConfig,
|
|
75
76
|
)
|
|
76
77
|
|
|
77
|
-
# Concrete renderer classes are lazy-loaded so that consumers needing
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
# import DefaultRenderer`` and ``renderers.DefaultRenderer`` both work
|
|
85
|
-
# transparently. ``create_renderer`` doesn't depend on these eager
|
|
86
|
-
# imports — ``renderers.base._populate_registry`` lazy-imports the
|
|
87
|
-
# concrete classes itself when a renderer is instantiated.
|
|
78
|
+
# Concrete renderer classes are lazy-loaded so that consumers needing only the
|
|
79
|
+
# config layer (``RendererConfig`` discriminated union) don't import every
|
|
80
|
+
# renderer module. Renderer tokenizer annotations use the local ``Tokenizer``
|
|
81
|
+
# protocols, so resolving a text renderer remains safe when the optional
|
|
82
|
+
# ``transformers`` dependency is absent. ``__getattr__`` (PEP 562) resolves the
|
|
83
|
+
# names on first attribute access, while ``renderers.base._populate_registry``
|
|
84
|
+
# handles lazy registration for ``create_renderer``.
|
|
88
85
|
_LAZY_RENDERERS: dict[str, str] = {
|
|
89
86
|
"DeepSeekR1Renderer": "renderers.deepseek_r1",
|
|
90
87
|
"DeepSeekV3Renderer": "renderers.deepseek_v3",
|
|
@@ -134,6 +131,7 @@ def __dir__() -> list[str]:
|
|
|
134
131
|
__all__ = [
|
|
135
132
|
"AutoRendererConfig",
|
|
136
133
|
"BaseRendererConfig",
|
|
134
|
+
"ChatTemplateTokenizer",
|
|
137
135
|
"Content",
|
|
138
136
|
"ContentPart",
|
|
139
137
|
"DeepSeekR1Renderer",
|
|
@@ -184,6 +182,7 @@ __all__ = [
|
|
|
184
182
|
"Nemotron3RendererConfig",
|
|
185
183
|
"Nemotron3UltraRenderer",
|
|
186
184
|
"Nemotron3UltraRendererConfig",
|
|
185
|
+
"OffsetTokenizer",
|
|
187
186
|
"OverlongPromptError",
|
|
188
187
|
"ParsedResponse",
|
|
189
188
|
"ParsedToolCall",
|
|
@@ -205,9 +204,9 @@ __all__ = [
|
|
|
205
204
|
"RenderedTrainingSample",
|
|
206
205
|
"Renderer",
|
|
207
206
|
"RendererConfig",
|
|
208
|
-
"RendererPool",
|
|
209
207
|
"TextPart",
|
|
210
208
|
"ThinkingPart",
|
|
209
|
+
"Tokenizer",
|
|
211
210
|
"ToolCall",
|
|
212
211
|
"ToolCallFunction",
|
|
213
212
|
"ToolCallParseStatus",
|
|
@@ -219,7 +218,6 @@ __all__ = [
|
|
|
219
218
|
"build_trajectory_step",
|
|
220
219
|
"config_from_name",
|
|
221
220
|
"create_renderer",
|
|
222
|
-
"create_renderer_pool",
|
|
223
221
|
"extract_message_tool_names",
|
|
224
222
|
"is_multimodal",
|
|
225
223
|
"reject_assistant_in_extension",
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.1.11.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1, 11, '
|
|
21
|
+
__version__ = version = '0.1.11.dev3'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 11, 'dev3')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|