Support batched torch Tensors in ASTFeatureExtractor
Author: psu-om
Pull request: no
Labels: name: Feature request

### Feature request

The current ASTFeatureExtractor allows batches as inputs, however only as `Union[np.ndarray, list[np.ndarray], list[list[float]]]`. If I input a torch Tensor into the ASTFeatureExtractor, it fails with the error I put on the bottom. I don't see a reason why batched Tensor should not be allowed as input, especially since the feature extraction could run on the GPU (i think). Not being able to input tensors is quiet confusing in my opinion. Am I missing something?

```
---> [30](vscode-notebook-cell:?execution_count=22&line=30)     inputs = feature_extractor(batch, sampling_rate=16_000, return_tensors="pt")
     31     logits = model(**inputs).logits
     32     probs = torch.nn.functional.softmax(logits, dim=-1)

File ~/projects/leon/ai-training/.venv/lib/python3.13/site-packages/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py:219, in ASTFeatureExtractor.__call__(self, raw_speech, sampling_rate, return_tensors, **kwargs)
    216     raw_speech = [raw_speech]
    218 # extract fbank features and pad/truncate to max_length
--> [219](https://file+.vscode-resource.vscode-cdn.net/home/psu/projects/leon/ai-training/notebooks/~/projects/leon/ai-training/.venv/lib/python3.13/site-packages/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py:219) features = [self._extract_fbank_features(waveform, max_length=self.max_length) for waveform in raw_speech]
    221 # convert into BatchFeature
    222 padded_inputs = BatchFeature({"input_values": features})

File ~/projects/leon/ai-training/.venv/lib/python3.13/site-packages/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py:119, in ASTFeatureExtractor._extract_fbank_features(self, waveform, max_length)
    117 if is_speech_available():
    118     waveform = torch.from_numpy(waveform).unsqueeze(0)
--> [119](https://file+.vscode-resource.vscode-cdn.net/home/psu/projects/leon/ai-training/notebooks/~/projects/leon/ai-training/.venv/lib/python3.13/site-packages/transformers/models/audio_spectrogram_transformer/feature_extraction_audio_spectrogram_transformer.py:119)     fbank = ta_kaldi.fbank(
    120         waveform,
    121         sample_frequency=self.sampling_rate,
    122         window_type="hanning",
    123         num_mel_bins=self.num_mel_bins,
    124     )
    125 else:
    126     waveform = np.squeeze(waveform)

File ~/projects/leon/ai-training/.venv/lib/python3.13/site-packages/torchaudio/compliance/kaldi.py:591, in fbank(waveform, blackman_coeff, channel, dither, energy_floor, frame_length, frame_shift, high_freq, htk_compat, low_freq, min_duration, num_mel_bins, preemphasis_coefficient, raw_energy, remove_dc_offset, round_to_power_of_two, sample_frequency, snip_edges, subtract_mean, use_energy, use_log_fbank, use_power, vtln_high, vtln_low, vtln_warp, window_type)
    542 r"""Create a fbank from a raw audio signal. This matches the input/output of Kaldi's
    543 compute-fbank-feats.
    544 
   (...)    587     where m is calculated in _get_strided
    588 """
    589 device, dtype = waveform.device, waveform.dtype
--> [591](https://file+.vscode-resource.vscode-cdn.net/home/psu/projects/leon/ai-training/notebooks/~/projects/leon/ai-training/.venv/lib/python3.13/site-packages/torchaudio/compliance/kaldi.py:591) waveform, window_shift, window_size, padded_window_size = _get_waveform_and_window_properties(
    592     waveform, channel, sample_frequency, frame_shift, frame_length, round_to_power_of_two, preemphasis_coefficient
    593 )
    595 if len(waveform) < min_duration * sample_frequency:
    596     # signal is too short
    597     return torch.empty(0, device=device, dtype=dtype)

File ~/projects/leon/ai-training/.venv/lib/python3.13/site-packages/torchaudio/compliance/kaldi.py:142, in _get_waveform_and_window_properties(waveform, channel, sample_frequency, frame_shift, frame_length, round_to_power_of_two, preemphasis_coefficient)
    139 window_size = int(sample_frequency * frame_length * MILLISECONDS_TO_SECONDS)
    140 padded_window_size = _next_power_of_2(window_size) if round_to_power_of_two else window_size
--> [142](https://file+.vscode-resource.vscode-cdn.net/home/psu/projects/leon/ai-training/notebooks/~/projects/leon/ai-training/.venv/lib/python3.13/site-packages/torchaudio/compliance/kaldi.py:142) assert 2 <= window_size <= len(waveform), "choose a window size {} that is [2, {}]".format(
    143     window_size, len(waveform)
    144 )
    145 assert 0 < window_shift, "`window_shift` must be greater than 0"
    146 assert padded_window_size % 2 == 0, (
    147     "the padded `window_size` must be divisible by two." " use `round_to_power_of_two` or change `frame_length`"
    148 )

AssertionError: choose a window size 400 that is [2, 16]
```



### Motivation

a) In my scenario, I load the audio from somewhere else using torchcodec before I use the feature extractor. I need move the tensor back to cpu and convert it to a numpy array in order to input it. This is overhead.
b) Calculating the spectogram could run on the gpu, but is not used.
c) I think it is confusing and there is not a good error message. It seems like other people are also running into this issue: #10631

### Your contribution

I would be happy to help out and create a PR.

Comments:
cc @eustlb @ebezzam