Skip to content

feat: add Falcon3 training chat template with generation markers - #6691

Closed
RudrenduPaul wants to merge 1 commit into
huggingface:mainfrom
RudrenduPaul:feat/falcon3-training-chat-template
Closed

RudrenduPaul wants to merge 1 commit into
huggingface:mainfrom
RudrenduPaul:feat/falcon3-training-chat-template

Conversation

@RudrenduPaul

@RudrenduPaul RudrenduPaul commented Aug 9, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds a training-compatible chat template for Falcon3 (e.g. tiiuae/Falcon3-7B-Instruct), following the same pattern as the other model families added in #5471: Llama 3 (#5493), Qwen2.5 (#5522), Phi-3 (#5526), and DeepSeek-V3 (#5527).

Files added:

  • trl/chat_templates/falcon3.jinja — exact copy of the official Falcon3 tokenizer template (sourced from tiiuae/Falcon3-7B-Instruct)
  • trl/chat_templates/falcon3_training.jinja — training variant with {% generation %} / {% endgeneration %} markers wrapping assistant output for assistant-only loss masking in SFT. Falcon3's template branches on whether tools is set (two separate loops), so the markers are added in both the tools branch and the plain branch.
  • scripts/generate_tiny_models/for_causal_lm/llama_for_causal_lm_falcon3.py — tiny-model generator script (see note below)

Changes to existing files:

  • trl/chat_template_utils.py: loads both templates, registers Falcon3 in get_training_chat_template(), updates docstring
  • trl/chat_templates/README.md: documents falcon3.jinja / falcon3_training.jinja
  • tests/test_chat_template_utils.py: adds a Falcon3 tokenizer to TestGetTrainingChatTemplate, and to TestSupportsToolCalling::test_does_not_support_tool_calling (Falcon3's default, no-tools= branch has no elif message['role'] == 'tool' clause at all and never reads message.tool_calls, so both are silently dropped — same category as Cohere2/Llava)

Prefix preservation: Not needed. supports_tool_calling() returns False for Falcon3's original template (verified locally against the real tiiuae/Falcon3-7B-Instruct tokenizer — the default render path drops tool content, same as the basic Llama 3 / Phi-3 / Cohere2 cases already in the codebase), so the prefix-preservation check is skipped, matching the "no structural fix needed" precedent from #5493 and #5526.

⚠️ Test fixture note: Falcon3 is a LlamaForCausalLM under the hood (config.json: architectures: ["LlamaForCausalLM"]), but there's no existing trl-internal-testing tiny-model fixture with Falcon3's tokenizer/chat template (only tiny-FalconMambaForCausalLM, a different architecture, exists for "Falcon"). I wrote llama_for_causal_lm_falcon3.py following the exact recipe of llama_for_causal_lm_3.py, and referenced the resulting fixture (trl-internal-testing/tiny-LlamaForCausalLM-Falcon3) in the new test parametrize entries — same approach used for other new-model fixtures in #5471 (e.g. the Qwen3.5 discussion). I don't have push access to the trl-internal-testing org, so those 14 parametrized tests will 404 until a maintainer runs the script and pushes the fixture; everything else (ruff, full test collection, and the rest of the existing suite) is green.

I validated the template correctness directly against the real tiiuae/Falcon3-7B-Instruct tokenizer (not the tiny fixture) locally: exact-match dispatch, byte-identical rendering before/after patching across all the scenarios covered by TestGetTrainingChatTemplate (single-turn, multi-turn, tool calls, tools with/without system message, enable_thinking=False), and correct assistant-token masks (stop token trained, multi-turn mask transitions == 3).

Before submitting

AI writing disclosure

  • AI-assisted: some parts were suggested or improved by AI (Claude Code), but the PR was written and reviewed by a human.

Who can review?

@qgallouedec (opened #5471)


Note

Low Risk
Changes are additive Jinja templates, docs, and test parametrization; no core training or auth paths are modified. CI may fail until the Hub tiny fixture is published.

Overview
Adds Falcon3 (tiiuae/Falcon3-*-Instruct) to TRL’s training chat-template pipeline, matching other families in #5471.

New assets: falcon3.jinja (official template copy) and falcon3_training.jinja, which wraps assistant output in {% generation %} / {% endgeneration %} in both the tools and no-tools branches so SFT assistant-only masking works. get_training_chat_template() dispatches on the Falcon3 template; the README documents behavior (plain path drops tool calls/responses unless tools is passed).

Tests & fixture: trl-internal-testing/tiny-LlamaForCausalLM-Falcon3 is wired into TestGetTrainingChatTemplate and TestSupportsToolCalling::test_does_not_support_tool_calling (no-tools branch silently drops tools, like Cohere2/Llava). A llama_for_causal_lm_falcon3.py script generates that tiny Llama-backed fixture from Falcon3’s tokenizer.

Reviewed by Cursor Bugbot for commit f64ea19. Bugbot is set up for automated code reviews on this repo. Configure here.

Adds a training-compatible chat template for tiiuae/Falcon3-*-Instruct
with {% generation %} / {% endgeneration %} markers around assistant
output (both the tools and no-tools branches), enabling
return_assistant_tokens_mask=True for SFT assistant-only loss masking.

Also adds the tiny-model generator script needed to create the test
fixture (Falcon3 is a LlamaForCausalLM under the hood), since no
matching trl-internal-testing fixture currently exists.
@qgallouedec

Copy link
Copy Markdown
Member

Thanks for the thorough work, I checked, and falcon3.jinja is byte-identical to the shipped template (1B/7B/10B), dispatch and masks are correct, and rendering is unchanged before/after patching. The code is solid.

That said: we haven't seen community demand for Falcon3, and it's an old model now. Every registry entry is a pinned string we have to maintain and test, so we only grow it where there are real users. Realistically this is unlikely to be merged as-is. I'll leave it open a while to see if traction shows up.

In the meantime, if you want to keep it ready:

  • Update docs/source/chat_templates.md, missing here. Add "Falcon3" to the Supported model families list and a ### falcon3_training.jinja section (between deepseekv3_training.jinja and gemma_training.jinja). Your feat: add OLMo 3 training chat template with generation markers #6690 does this; CI doesn't catch it.

  • De-duplicate the tools branch in falcon3_training.jinja; the tool_calls block and eos_token emit are copied into both arms. Hoisting only the header out keeps it single-copy:

    {%- elif message['role'] == 'assistant' %}
        {%- if message.content %}
            {{- '<|assistant|>\n' }}
        {%- endif %}
        {%- generation %}
        {%- if message.content %}
            {{- message['content'] }}
        {%- endif %}
        {%- if message.tool_calls %}
            {{- '\n<tool_call>\n' }}
            {{- message.tool_calls|tojson(indent=2) }}
            {{- '\n</tool_call>' }}
        {%- endif %}
        {{- eos_token + '\n' }}
        {%- endgeneration %}
    {%- endif %}

    Byte-identical to your version across 32 cases, including content: None with tool calls.

  • Leave the tiny-model fixture alone; I'd rather not push tiny-LlamaForCausalLM-Falcon3 to the org until we know we're merging. The generator script looks right, so it's one command if this moves forward. The 14 failing tests are expected, not yours to fix.

Heads-up: this, #6689 and #6690 all edit the same docstring paragraph and README blocks, so whichever lands first will force a rebase on the others.

@qgallouedec

Copy link
Copy Markdown
Member

Closing as said in my last comment: no traction for Falcon3 since, so we're not adding it to the registry. Thanks again for the clean work @RudrenduPaul

@qgallouedec qgallouedec closed this Oct 5, 2026
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.

2 participants