Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
fa7d6e0
parakeet tdt intergration
Oct 13, 2025
f2b4938
Add TDT decoder support for Parakeet ASR models
lmaksym Feb 20, 2026
fa36657
Add expected outputs for TDT, small fixes.
ebezzam Feb 25, 2026
05e2e34
Separate CTC and TDT generate outputs.
ebezzam Feb 25, 2026
bb5ff33
Work with auto device, better init,
ebezzam Feb 25, 2026
9ec79b0
Test timestamps and expose token duration.
ebezzam Feb 26, 2026
33f128e
Add reproducer link.
ebezzam Feb 26, 2026
760b4b6
fix: align TDT training and decoding with NeMo implementation
lmaksym Feb 27, 2026
b33002f
revert: restore lasr generated files to original state
lmaksym Feb 27, 2026
48b39dd
warn: torchaudio rnnt_loss does not train duration head
lmaksym Feb 27, 2026
e9f23ab
Relax timestamp test, and test nits.
ebezzam Mar 2, 2026
e2b97aa
feat: TDT training
lmaksym Mar 3, 2026
6b9fc73
chore: for cuda detection and run without patching
lmaksym Mar 3, 2026
6c879bc
Equivalent timestamp processing as Nemo, and various nits/cleanup.
ebezzam Mar 3, 2026
149e17f
Merge branch 'parakeet-tdt' of github.com:lmaksym/transformers into p…
ebezzam Mar 3, 2026
36bfa63
Simplify durations config.
ebezzam Mar 3, 2026
2df0ccc
Update training examples.
ebezzam Mar 3, 2026
388c6d3
chore: enable parralelism
lmaksym Mar 3, 2026
08b2b55
chore: performance optimization
lmaksym Mar 4, 2026
0c4e05a
fix: formatting
lmaksym Mar 4, 2026
1ddd804
Doc and testing nits
ebezzam Mar 5, 2026
f512670
Use active mask from current step, and nits.
ebezzam Mar 6, 2026
07d8e35
Better pre-allocate.
ebezzam Mar 6, 2026
fab050a
TDT has separate pad token and blank token.
ebezzam Mar 6, 2026
c438565
Merge branch 'main' into parakeet-tdt
ebezzam Mar 6, 2026
86d980c
Regenerate lasr.
ebezzam Mar 6, 2026
895c4a0
Merge branch 'parakeet-tdt' of github.com:lmaksym/transformers into p…
ebezzam Mar 6, 2026
ab21380
Style checks and nits
ebezzam Mar 7, 2026
d0141d5
Nits, put back ctc loss test
ebezzam Mar 7, 2026
f7529d4
More standard model output.
ebezzam Mar 10, 2026
77b95d7
Style
ebezzam Mar 10, 2026
94eae66
Remove compute_loss flag and allow monkey patching to tdt loss
ebezzam Mar 23, 2026
f7d4067
Update src/transformers/models/parakeet/modular_parakeet.py
ebezzam Mar 23, 2026
f75c17b
Address various comments.
ebezzam Mar 23, 2026
5a49b65
More compatible with Transformers forward/generate approach
ebezzam Mar 24, 2026
881233f
compile option for generation and decoder cache
ebezzam Mar 24, 2026
b41a8ee
Cleaner, better conventions.
ebezzam Mar 24, 2026
897753a
Merge branch 'main' into parakeet-tdt
ebezzam Mar 24, 2026
6c914db
Update with main.
ebezzam Mar 24, 2026
756cee1
doc nits
ebezzam Mar 26, 2026
f30c536
Imitate whisper for encoder outputs as input
ebezzam Mar 26, 2026
fa95fc8
Address tests and nits.
ebezzam Mar 26, 2026
5df7f28
Inherit from GenerateMixIn for get_compiled_call
ebezzam Mar 26, 2026
cd706d4
Comment nit
ebezzam Mar 26, 2026
a47ed8a
forward cleanup
eustlb Apr 15, 2026
13b68ce
generate cleanup + separate generation file
eustlb Apr 15, 2026
72c1ad0
generate: add _supported_generation_modes
eustlb Apr 15, 2026
8e23b3d
automatic init of the loss
eustlb Apr 15, 2026
1cc39fd
modular cleanups
eustlb Apr 15, 2026
531f297
use is_encoder_decoder
eustlb Apr 15, 2026
2c0f23a
timestamp processing fully from tokens + durations
eustlb Apr 15, 2026
cef6639
convertion script update
eustlb Apr 15, 2026
fd3cf9b
test update
eustlb Apr 15, 2026
e63a5bf
make
eustlb Apr 15, 2026
f9d1a4f
Merge branch 'main' into parakeet-tdt
eustlb Apr 15, 2026
43ee7cd
test update
eustlb Apr 15, 2026
c2a0f78
test update
eustlb Apr 15, 2026
1fd7ed7
ensure correct loss computation
eustlb Apr 16, 2026
7cc9d2e
kernel loss
eustlb Apr 16, 2026
e753eab
test loss integration
eustlb Apr 16, 2026
ed3fa4d
push to hub pr
eustlb Apr 16, 2026
ab66b23
integration tests to rely fully on transcripts
eustlb Apr 16, 2026
a5ba0c6
udpate fixtures
eustlb Apr 16, 2026
48279a6
we don't need to monkey patch with numba anymore!
eustlb Apr 16, 2026
1d7680d
fix pipeline usage
eustlb Apr 16, 2026
59ddced
nit
eustlb Apr 16, 2026
31490d1
fix usage
eustlb Apr 16, 2026
d8eb1b6
Pass through tests and examples: improve kernel fallback, update with…
ebezzam Apr 17, 2026
1f1b912
Update checkpoint
ebezzam Apr 17, 2026
9ab08d1
Merge branch 'main' into parakeet-tdt
ebezzam Apr 17, 2026
fd9f8b1
Add TDT to mapping after merge.
ebezzam Apr 17, 2026
136f676
Fix lasr generate test.
ebezzam Apr 20, 2026
833d289
Output attention mask if labels provided for computing loss.
ebezzam Apr 20, 2026
a1c62a1
Apply suggestion from @ArthurZucker
ebezzam May 13, 2026
8683570
Improve ParakeetTDTDecoderCache definition and usage.
ebezzam May 13, 2026
1d4b0f4
Remove tuple parsing.
ebezzam May 13, 2026
a418eca
processor refactor
ebezzam May 13, 2026
5d0c631
Merge branch 'parakeet-tdt' of github.com:lmaksym/transformers into p…
ebezzam May 13, 2026
5c603c1
Update conversion.
ebezzam May 18, 2026
09ba99c
Merge branch 'main' into tdt_loss_kernel
ebezzam May 19, 2026
e743b2d
Modular after merge.
ebezzam May 19, 2026
8d09cb6
Don't allow all kernels.
ebezzam May 19, 2026
5176486
Merge remote-tracking branch 'origin/main' into tdt-loss-kernel
Deep-unlearning Sep 28, 2026
1cbb74f
Use the kernels-community/tdt-loss kernel for the TDT loss
Deep-unlearning Sep 28, 2026
12bbc03
Run the TDT integration loss checks before the train-mode backward
Deep-unlearning Sep 28, 2026
475304e
Fall back to PyTorch when the tdt-loss kernel cannot be loaded, fix i…
Deep-unlearning Sep 28, 2026
28b0a40
Use the kernels exchange pattern for the TDT loss
Deep-unlearning Sep 28, 2026
d6e739c
Skip the kernel checks when Hub kernels are disabled
Deep-unlearning Sep 28, 2026
3f02948
Address review: mode flags for the tdt_loss kernel mapping, keep only…
Deep-unlearning Sep 29, 2026
5bd9cac
Address review: register the tdt_loss kernel for torch.compile, move …
Deep-unlearning Oct 2, 2026
0a4ccb2
Address review: use preserve_module_forwards in test_use_kernels
Deep-unlearning Oct 2, 2026
513ea4b
Address review: split test_use_kernels into the model tester
Deep-unlearning Oct 2, 2026
8c0d977
Address review: drop the kernels-disabled skip in test_use_kernels
Deep-unlearning Oct 5, 2026
3321659
Only kernelize tdt_loss in test_use_kernels, fix the kernel Hub link
Deep-unlearning Oct 10, 2026
3d23b40
Address review: drop the kernel note in the docstring and the test ma…
Deep-unlearning Oct 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/transformers/integrations/hub_kernels.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,13 @@ def _build_kernel_mapping() -> dict:
),
},
},
"tdt_loss": {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We might have to drop the kernel for when we make use kernels true as default. best to make it toch compile friendly from the get go

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.

Good point, done. The kernel now supports torch.compile (huggingface/kernels-community#882, 02647af): fake implementations for its ops, can_torch_compile = True on the layer, and tests with torch.compile(fullgraph=True) (fp32/bf16, forward and backward match eager) and torch.library.opcheck. Here, the mapping is now Mode.TRAINING | Mode.TORCH_COMPILE (5bd9cac), like the liger loss.

Checked on GPU with a build of the new kernel: a ParakeetForTDT kernelized with Mode.TRAINING | Mode.TORCH_COMPILE and a compiled tdt_loss match eager, and the Parakeet tests pass.

"cuda": {
Mode.TRAINING | Mode.TORCH_COMPILE: LayerRepository(
repo_id="kernels-community/tdt-loss", layer_name="TDTLoss", version=1
),
},
},
}

return _KERNEL_MAPPING
Expand Down
2 changes: 2 additions & 0 deletions src/transformers/loss/loss_tdt.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@

import torch

from ..integrations import use_kernel_forward_from_hub
from ..utils import logging


logger = logging.get_logger(__name__)


@use_kernel_forward_from_hub("tdt_loss")
def tdt_loss(
token_logits: torch.Tensor,
duration_logits: torch.Tensor,
Expand Down
2 changes: 2 additions & 0 deletions src/transformers/models/parakeet/modeling_parakeet.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from ...activations import ACT2FN
from ...generation import CompileConfig, GenerationMixin, GenerationMode
from ...integrations import use_kernel_forward_from_hub, use_kernelized_func
from ...loss.loss_tdt import tdt_loss
from ...modeling_layers import GradientCheckpointingLayer
from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, CausalLMOutput
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
Expand Down Expand Up @@ -1051,6 +1052,7 @@ def __init__(self, config: ParakeetTDTConfig):
Parakeet Encoder with a TDT (Token Duration Transducer) head.
"""
)
@use_kernelized_func(tdt_loss)
class ParakeetForTDT(ParakeetTDTGenerationMixin, ParakeetForRNNT):
config: ParakeetTDTConfig

Expand Down
3 changes: 3 additions & 0 deletions src/transformers/models/parakeet/modular_parakeet.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from ... import initialization as init
from ...activations import ACT2FN
from ...generation import CompileConfig, GenerationMixin, GenerationMode
from ...integrations import use_kernelized_func
from ...loss.loss_tdt import tdt_loss
from ...modeling_layers import GradientCheckpointingLayer
from ...modeling_outputs import BaseModelOutput, BaseModelOutputWithPooling, CausalLMOutput
from ...modeling_utils import ALL_ATTENTION_FUNCTIONS, PreTrainedModel
Expand Down Expand Up @@ -900,6 +902,7 @@ def __init__(self, config: ParakeetTDTConfig):
Parakeet Encoder with a TDT (Token Duration Transducer) head.
"""
)
@use_kernelized_func(tdt_loss)
class ParakeetForTDT(ParakeetTDTGenerationMixin, ParakeetForRNNT):
config: ParakeetTDTConfig

Expand Down
52 changes: 51 additions & 1 deletion tests/models/parakeet/test_modeling_parakeet.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Imo no need to test it on this side as the kernel should test it for itself no? Meaning kernels community ensures that the loss is correct 🤔

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.

Makes sense, the kernel tests in kernels-community already check it against a PyTorch reference, a naive loop version and float64. Done in 3f02948: I removed the loss-correctness tests here and restored the integration test, keeping only test_use_kernels, which checks that use_kernels=True actually swaps tdt_loss for the kernel (inference and training) with the same loss.

Also tested against your staged build (kernels-staging/tdt-loss@pr-882) on an L4: the kernels-community tests pass (43), the Parakeet tests pass with use_kernels=True (including the slow integration test and the full test file), and the speed matches my earlier numbers (loss fwd+bwd 1285 ms → 53 ms at Parakeet size).

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,16 @@
from pathlib import Path

from transformers import is_datasets_available, is_torch_available
from transformers.testing_utils import cleanup, require_torch, require_torchaudio, slow, torch_device
from transformers.testing_utils import (
cleanup,
preserve_module_forwards,
require_kernels,
require_torch,
require_torch_gpu,
require_torchaudio,
slow,
torch_device,
)

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask
Expand Down Expand Up @@ -608,6 +617,41 @@ def create_and_check_model(self, config, inputs_dict):
(self.batch_size, self.output_seq_length, self.encoder_model_tester.hidden_size),
)

def prepare_config_and_inputs_for_loss(self):
config, input_features, attention_mask = self.prepare_config_and_inputs()
labels = ids_tensor([self.batch_size, 6], self.blank_token_id) # no blank in the labels
labels[labels == self.pad_token_id] = self.pad_token_id + 1 # nor padding
blank = torch.full((self.batch_size, 1), self.blank_token_id, device=labels.device)
inputs_dict = {
"input_features": input_features,
"attention_mask": attention_mask,
"decoder_input_ids": torch.cat([blank, labels], dim=1),
"labels": labels,
}
return config, inputs_dict

def create_and_check_use_kernels(self, config, inputs_dict):
"""`use_kernels=True` swaps `tdt_loss` for the `kernels-community/tdt-loss` kernel, with the same loss."""
model = ParakeetForTDT(config).to(torch_device).eval()
with torch.no_grad():
expected = model(**inputs_dict).loss

with preserve_module_forwards(model):
model.set_use_kernels(True)
self.parent.assertIn("forward", vars(tdt_loss), "`tdt_loss` was not kernelized")
with torch.no_grad():
loss = model(**inputs_dict).loss
torch.testing.assert_close(loss, expected, rtol=1e-4, atol=1e-4)
self.parent.assertNotIn("forward", vars(tdt_loss), "`tdt_loss` was not restored")

# Training mode also uses the kernel, which has a backward
with preserve_module_forwards(model):
model.train()
model.set_use_kernels(True)
self.parent.assertIn("forward", vars(tdt_loss), "`tdt_loss` was not kernelized in training mode")
model(**inputs_dict).loss.backward()
self.parent.assertTrue(any(p.grad is not None for p in model.parameters()), "No gradients after backward")

def prepare_config_and_inputs_for_common(self):
config, input_features, attention_mask = self.prepare_config_and_inputs()
decoder_input_ids = ids_tensor([self.batch_size, 1], self.vocab_size)
Expand Down Expand Up @@ -650,6 +694,12 @@ def test_model(self):
config_and_inputs = self.model_tester.prepare_config_and_inputs_for_common()
self.model_tester.create_and_check_model(*config_and_inputs)

@require_torch_gpu
@require_kernels
def test_use_kernels(self):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

lets make the split as in create_and_check_model / test_model then we can merge. Note that when kernels = True lands that we will temporarily disable training kernels as we need to make it compatible with the trainer

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.

Done in 513ea4b: the logic is now in ParakeetForTDTModelTester.create_and_check_use_kernels (with prepare_config_and_inputs_for_loss), and test_use_kernels just calls it, as for test_model. Thanks for the heads-up on the training kernels!

config_and_inputs = self.model_tester.prepare_config_and_inputs_for_loss()
self.model_tester.create_and_check_use_kernels(*config_and_inputs)

@unittest.skip(reason="ParakeetForTDT does not use inputs_embeds")
def test_model_get_set_embeddings(self):
pass
Expand Down
Loading