[rl] Pin renderers 0.1.11, render with TorchTitan's tokenizer, take the renderer's typed config directly - #4444
Conversation
0d1de2a to
bfdb125
Compare
…he renderer's typed config directly renderers 0.1.11 makes transformers optional and accepts a bring-your-own tokenizer. RL now renders with TorchTitan's HuggingFaceTokenizer (wrapped in RendererTokenizer to satisfy renderers.OffsetTokenizer) instead of loading transformers.AutoTokenizer, and the controller reads pad_id off its own tokenizer instead of renderer._tokenizer. TorchTitan's RendererConfig wrapper is removed. Controller.Config.renderer is the library's own typed pydantic config (Qwen3RendererConfig(enable_thinking=False), GptOssRendererConfig(reasoning_effort="low"), ...), so a wrong option fails when the recipe is constructed instead of being silently dropped (pytorch#4365), and TorchTitan mirrors no renderer fields. build_renderer(tokenizer, config) is the one TorchTitan-side seam. A renderer that ships in TorchTitan (Muse Glimmer) has a TorchTitanRendererConfig that names its renderer class, and build_renderer constructs it directly, so nothing is written into renderers' registry. AutoRendererConfig and DefaultRendererConfig are rejected with the reason: the former depends on an exact model-ID match that local asset paths do not reliably preserve; the latter needs Hugging Face-compatible apply_chat_template semantics, which TorchTitan's template rendering does not provide. Renderer options are set in the recipe (tyro.conf.Suppress, like model_spec); the 8 redundant --renderer.enable-thinking CLI flags in the integration tests are removed. Configurable.to_dict learns pydantic model_dump so the wandb config stays JSON. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
bfdb125 to
390eb7e
Compare
| "--async-loop.num-samples-per-prompt 2", | ||
| "--trainer.training.max_context_length 1024", | ||
| "--trainer.training.num_tokens_per_microbatch_per_dp_rank 2048", | ||
| "--renderer.enable-thinking False", |
There was a problem hiding this comment.
Can we still pass CLI to disable thinking? Maybe this config can not be set by CLI because the base render class doesn't have this field, so we can not pass it.
I explicitly added enable-thinking=False for these CI tests because CI machine are easy to OOM (with 24GB memory), Can monitor if the CI works fine after removing it?
|
Thanks for raising this. The silent drop is what actually impacted the work in #4145. The Muse Glimmer recipe sets enable_thinking=True but that renderer has no such field so it was dropped and the recipe read one way and ran another. Typed configs kill that whole class of bug. One caveat from the same experience: they catch a wrong name, not wrong behavior, so our renderer bugs all passed unit tests and only showed up in a real rollout. Here is Qwen3, which takes the create_renderer path. Is the TorchTitanRendererConfig path covered anywhere? A short rollout on the Muse Glimmer recipe would cover it. |
0c92da9 to
390eb7e
Compare
| elif hasattr(val, "model_dump"): # pydantic, e.g. renderer configs | ||
| return _convert(val.model_dump()) |
There was a problem hiding this comment.
This is supposed to work with only native configs; o/w it'd be bloated eventually.
| ) -> None: | ||
| """Build runtime dependencies after the worker actor is spawned.""" | ||
| self._renderer = renderer_config.build(tokenizer_path=hf_assets_path) | ||
| tokenizer = HuggingFaceTokenizer(tokenizer_path=hf_assets_path) |
There was a problem hiding this comment.
this doesn't sound right -- it should be from tokenizer config build.
| TORCHTITAN_CONFIG_FORMAT, | ||
| TORCHTITAN_WORKER_CLS, | ||
| ) | ||
| from torchtitan.experiments.rl.renderer import build_renderer |
| return create_renderer(tokenizer=renderer_tokenizer, config=config) | ||
|
|
||
|
|
||
| class RendererTokenizer: |
There was a problem hiding this comment.
Maybe
| class RendererTokenizer: | |
| class RendererTokenizerWrapper: |
to not confuse with HuggingFaceTokenier's functionality
| renderer_cls: ClassVar[type[Renderer]] | ||
|
|
||
|
|
||
| def build_renderer( |
There was a problem hiding this comment.
Instead of this, we should have a Renderer class and Renderer.Config in torchtitan and build from there. HuggingFaceTokenizer is the example https://github.com/pytorch/torchtitan/blob/main/torchtitan/components/tokenizer.py#L94
What's the benefit? Well the main one is it can be swapped to be other renderer impl.
|
|
||
| import dataclasses | ||
|
|
||
| from renderers import Qwen3RendererConfig |
There was a problem hiding this comment.
I think this is because Prime-rl "happens" to be using similar way of configuring, but the "proper" and robust way to use something in other library is to build our own wrapper class.
There was a problem hiding this comment.
TLDR:
model_name-> config_typeSummary
TitanRL uses
renderersto turn chat messages into token ids and parse completions back. Until now we wrapped it in our ownRendererConfig:Problems:
build()forwarded knobs by name-matching against the renderer's config and dropped the rest. Whenrenderersreplacedpreserve_all_thinkingwiththinking_retention, the knob went inert with no error; two in-tree recipes were already hitting the same thing (enable_thinkingon gpt-oss and Muse Glimmer, which have no such option).build()loadedtransformers.AutoTokenizereven though TorchTitan already has the tokenizer, and the controller then reached intorenderer._tokenizerforpad_id.Solutions:
renderers==0.1.11accepts a bring-your-own tokenizer and drops the transformers dependency:Recipes hold the library's typed config directly: We don't have a wrapper anymore. We don't try to redirect 'qwen3
to the right config, e.g.renderer=RendererConfig(name="qwen3", enable_thinking=False)`. Instead, we do:We load our own tokenizer:
build_rendererpairs that config with TorchTitan's tokenizer, through a small adapter (RendererTokenizer) that exposes the interfacerenderersexpects.We skip registration of new renderers*: Muse Glimmer's renderer lives in TorchTitan, so the renderer's registry cannot find it. We skip the need for the renderers registry that maps config -> renderer class. Check
TorchTitanRendererConfig.Validation