Skip to content

Commit cc414c4

Browse files
hmellorclaudeeustlb
authored
Allow untokenized output from apply_transcription_request (#49944)
* Allow untokenized output from `apply_transcription_request` Add a `tokenize` argument to the chat-template-based ASR processors so that inference engines, which run the processor themselves, can get the formatted prompts. Also make VibeVoice-ASR's `extract_speaker_dict` keep the complete segments of truncated output instead of raising. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> * doc nit --------- Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: eustlb <94853470+eustlb@users.noreply.github.com>
1 parent c5c5c55 commit cc414c4

11 files changed

Lines changed: 147 additions & 29 deletions

File tree

‎src/transformers/models/audioflamingo3/processing_audioflamingo3.py‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,9 @@ def apply_transcription_request(
183183
self,
184184
audio: str | list[str] | AudioInput,
185185
prompt: str | list[str] | None = None,
186+
tokenize: bool = True,
186187
**kwargs: Unpack[AudioFlamingo3ProcessorKwargs],
187-
) -> BatchFeature:
188+
) -> BatchFeature | list[str]:
188189
"""
189190
Prepare inputs for automatic speech recognition without manually writing the default transcription prompt.
190191
@@ -195,12 +196,18 @@ def apply_transcription_request(
195196
prompt (`str` or `list[str]`, *optional*):
196197
Custom prompt(s) to include in the user turn. A list must be the same length as the batch. When `None`,
197198
each sample uses `"Transcribe the input speech."`.
199+
tokenize (`bool`, *optional*, defaults to `True`):
200+
Whether to tokenize the prompts and process the audio. If `False`, the audio is not loaded and
201+
the prompts are returned as strings with unexpanded audio placeholders. Passing them with the
202+
audio to the processor, `processor(text=prompts, audio=audio)`, gives the same outputs as
203+
`tokenize=True`.
198204
**kwargs:
199205
Additional keyword arguments forwarded to [`~AudioFlamingo3Processor.apply_chat_template`] (for example
200206
`text_kwargs`, `audio_kwargs`, ...).
201207
202208
Returns:
203-
[`BatchFeature`]: Processor outputs ready to be passed to [`AudioFlamingo3ForConditionalGeneration.generate`].
209+
[`BatchFeature`] or `list[str]`: One prompt per audio when `tokenize=False`, otherwise processor
210+
outputs ready to be passed to [`AudioFlamingo3ForConditionalGeneration.generate`].
204211
205212
"""
206213

@@ -246,7 +253,7 @@ def apply_transcription_request(
246253

247254
return self.apply_chat_template(
248255
conversations,
249-
tokenize=True,
256+
tokenize=tokenize,
250257
add_generation_prompt=True,
251258
return_dict=True,
252259
**kwargs,

‎src/transformers/models/canary/processing_canary.py‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ def apply_transcription_request(
114114
source_language: str | list[str] = "en",
115115
target_language: str | list[str] | None = None,
116116
punctuation: bool = True,
117+
tokenize: bool = True,
117118
**kwargs: Unpack[CanaryProcessorKwargs],
118-
) -> BatchFeature:
119+
) -> BatchFeature | list[str]:
119120
r"""
120121
Prepare inputs for transcription or translation without manually writing the chat template.
121122
@@ -130,11 +131,17 @@ def apply_transcription_request(
130131
(transcription); set it to a different language for speech-to-text translation.
131132
punctuation (`bool`, *optional*, defaults to `True`):
132133
Whether to request punctuation and capitalization in the output.
134+
tokenize (`bool`, *optional*, defaults to `True`):
135+
Whether to tokenize the prompts and process the audio. If `False`, the audio is not loaded and
136+
the prompts are returned as strings with unexpanded audio placeholders. Passing them with the
137+
audio to the processor, `processor(text=prompts, audio=audio)`, gives the same outputs as
138+
`tokenize=True`.
133139
**kwargs:
134140
Additional keyword arguments forwarded to [`~CanaryProcessor.apply_chat_template`].
135141
136142
Returns:
137-
[`BatchFeature`]: Processor outputs ready to be passed to
143+
[`BatchFeature`] or `list[str]`: One prompt per audio when `tokenize=False`, otherwise processor
144+
outputs ready to be passed to
138145
[`CanaryForConditionalGeneration.generate`].
139146
"""
140147
audio_items = make_list_of_audio_chat_template(audio)
@@ -163,7 +170,7 @@ def apply_transcription_request(
163170

164171
return self.apply_chat_template(
165172
conversations,
166-
tokenize=True,
173+
tokenize=tokenize,
167174
add_generation_prompt=True,
168175
return_dict=True,
169176
**kwargs,

‎src/transformers/models/fun_asr_nano/modular_fun_asr_nano.py‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ def apply_transcription_request(
118118
language: str | list[str] | None = None,
119119
prompt: str | list[str] | None = None,
120120
keywords: str | list[str] | list[list[str]] | None = None,
121+
tokenize: bool = True,
121122
**kwargs: Unpack[FunAsrNanoProcessorKwargs],
122-
) -> BatchFeature:
123+
) -> BatchFeature | list[str]:
123124
"""Prepare inputs for ASR using the checkpoint's structured transcription chat template.
124125
125126
Args:
@@ -134,12 +135,18 @@ def apply_transcription_request(
134135
keywords (`str`, `list[str]`, or `list[list[str]]`, *optional*):
135136
Hotwords to bias recognition. A string or flat list is shared across the batch; a nested list
136137
supplies separate hotwords for each audio sample.
138+
tokenize (`bool`, *optional*, defaults to `True`):
139+
Whether to tokenize the prompts and process the audio. If `False`, the audio is not loaded and
140+
the prompts are returned as strings with unexpanded audio placeholders. Passing them with the
141+
audio to the processor, `processor(text=prompts, audio=audio)`, gives the same outputs as
142+
`tokenize=True`.
137143
**kwargs:
138144
Additional keyword arguments forwarded to [`~FunAsrNanoProcessor.apply_chat_template`]
139145
and the underlying processor call (for example `text_kwargs`, `audio_kwargs`, ...).
140146
141147
Returns:
142-
[`BatchFeature`]: Processor outputs ready to be passed to
148+
[`BatchFeature`] or `list[str]`: One prompt per audio when `tokenize=False`, otherwise processor
149+
outputs ready to be passed to
143150
[`FunAsrNanoForConditionalGeneration.generate`].
144151
"""
145152
audio_items = list(make_list_of_audio_chat_template(audio))
@@ -167,7 +174,7 @@ def apply_transcription_request(
167174

168175
return self.apply_chat_template(
169176
conversations,
170-
tokenize=True,
177+
tokenize=tokenize,
171178
add_generation_prompt=True,
172179
return_dict=True,
173180
**kwargs,

‎src/transformers/models/fun_asr_nano/processing_fun_asr_nano.py‎

Lines changed: 10 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/transformers/models/glmasr/modular_glmasr.py‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ def apply_transcription_request(
9393
self,
9494
audio: str | list[str] | AudioInput,
9595
prompt: str | list[str] | None = None,
96+
tokenize: bool = True,
9697
**kwargs: Unpack[GlmAsrProcessorKwargs],
97-
) -> BatchFeature:
98+
) -> BatchFeature | list[str]:
9899
"""
99100
Prepare inputs for automatic speech recognition without manually writing the default transcription prompt.
100101
@@ -105,12 +106,18 @@ def apply_transcription_request(
105106
prompt (`str` or `list[str]`, *optional*):
106107
Custom prompt(s) to include in the user turn. A list must be the same length as the batch. When `None`,
107108
each sample uses `"Transcribe the input speech."`.
109+
tokenize (`bool`, *optional*, defaults to `True`):
110+
Whether to tokenize the prompts and process the audio. If `False`, the audio is not loaded and
111+
the prompts are returned as strings with unexpanded audio placeholders. Passing them with the
112+
audio to the processor, `processor(text=prompts, audio=audio)`, gives the same outputs as
113+
`tokenize=True`.
108114
**kwargs:
109115
Additional keyword arguments forwarded to [`~GlmAsrProcessor.apply_chat_template`] (for example
110116
`text_kwargs`, `audio_kwargs`, ...).
111117
112118
Returns:
113-
[`BatchFeature`]: Processor outputs ready to be passed to [`GlmAsrForConditionalGeneration.generate`].
119+
[`BatchFeature`] or `list[str]`: One prompt per audio when `tokenize=False`, otherwise processor
120+
outputs ready to be passed to [`GlmAsrForConditionalGeneration.generate`].
114121
115122
"""
116123

@@ -156,7 +163,7 @@ def apply_transcription_request(
156163

157164
return self.apply_chat_template(
158165
conversations,
159-
tokenize=True,
166+
tokenize=tokenize,
160167
add_generation_prompt=True,
161168
return_dict=True,
162169
**kwargs,

‎src/transformers/models/glmasr/processing_glmasr.py‎

Lines changed: 10 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/transformers/models/moss_transcribe_diarize/modular_moss_transcribe_diarize.py‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,9 @@ def apply_transcription_request(
442442
audio: str | list[str] | AudioInput,
443443
prompt: str | list[str] | None = None,
444444
keywords: str | list[str] | list[list[str]] | None = None,
445+
tokenize: bool = True,
445446
**kwargs: Unpack[MossTranscribeDiarizeProcessorKwargs],
446-
) -> BatchFeature:
447+
) -> BatchFeature | list[str]:
447448
"""
448449
Prepare inputs for transcription / diarization without manually writing the chat template.
449450
@@ -458,6 +459,11 @@ def apply_transcription_request(
458459
Hotwords/domain terms (e.g. proper nouns) to bias transcription toward the correct spelling. A
459460
string or flat list of strings is shared across the batch; a nested list supplies separate
460461
keywords per audio sample.
462+
tokenize (`bool`, *optional*, defaults to `True`):
463+
Whether to tokenize the prompts and process the audio. If `False`, the audio is not loaded and
464+
the prompts are returned as strings with unexpanded audio placeholders. Passing them with the
465+
audio to the processor, `processor(text=prompts, audio=audio)`, gives the same outputs as
466+
`tokenize=True`.
461467
**kwargs:
462468
Additional keyword arguments forwarded to [`~MossTranscribeDiarizeProcessor.apply_chat_template`].
463469
"""
@@ -482,7 +488,7 @@ def apply_transcription_request(
482488

483489
return self.apply_chat_template(
484490
conversations,
485-
tokenize=True,
491+
tokenize=tokenize,
486492
add_generation_prompt=True,
487493
return_dict=True,
488494
**kwargs,
@@ -496,6 +502,9 @@ def parse_timestamp(value: str) -> float:
496502
"""
497503
return sum(float(part) * 60**i for i, part in enumerate(reversed(value.strip().split(":"))))
498504

505+
def _decode_complete_segments(self, *args, **kwargs):
506+
raise AttributeError("Not needed for MossTranscribeDiarize")
507+
499508
def extract_speaker_dict(self, text: str | list[str]) -> list[dict] | str | list[list[dict] | str]:
500509
"""
501510
Extract speaker/timestamp segments from raw output, returning original text on failure.

‎src/transformers/models/moss_transcribe_diarize/processing_moss_transcribe_diarize.py‎

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/transformers/models/qwen3_asr/processing_qwen3_asr.py‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,9 @@ def apply_transcription_request(
442442
audio: AudioInput | list[AudioInput],
443443
language: str | list[str] | None = None,
444444
prompt: str | list[str] | None = None,
445+
tokenize: bool = True,
445446
**kwargs: Unpack[Qwen3ASRProcessorKwargs],
446-
) -> BatchFeature:
447+
) -> BatchFeature | list[str]:
447448
"""
448449
Prepare inputs for automatic speech recognition without manually writing the chat template.
449450
@@ -462,12 +463,18 @@ def apply_transcription_request(
462463
Context/hotwords to include as the system prompt, e.g. domain-specific words or
463464
phrases to bias the transcription towards. A list must be the same length as the
464465
audio batch. When `None`, the system prompt is left empty.
466+
tokenize (`bool`, *optional*, defaults to `True`):
467+
Whether to tokenize the prompts and process the audio. If `False`, the audio is not loaded and
468+
the prompts are returned as strings with unexpanded audio placeholders. Passing them with the
469+
audio to the processor, `processor(text=prompts, audio=audio)`, gives the same outputs as
470+
`tokenize=True`.
465471
**kwargs:
466472
Additional keyword arguments forwarded to [`~Qwen3ASRProcessor.apply_chat_template`]
467473
and the underlying processor call (for example `text_kwargs`, `audio_kwargs`, ...).
468474
469475
Returns:
470-
[`BatchFeature`]: Processor outputs ready to be passed to
476+
[`BatchFeature`] or `list[str]`: One prompt per audio when `tokenize=False`, otherwise processor
477+
outputs ready to be passed to
471478
[`Qwen3ASRForConditionalGeneration.generate`].
472479
"""
473480
audio_items = list(make_list_of_audio_chat_template(audio))
@@ -494,7 +501,7 @@ def apply_transcription_request(
494501
messages.append({"role": "assistant", "content": [{"type": "text", "text": prefill}]})
495502
return self.apply_chat_template(
496503
conversations,
497-
tokenize=True,
504+
tokenize=tokenize,
498505
return_dict=True,
499506
continue_final_message=True,
500507
**kwargs,

0 commit comments

Comments
 (0)