Adding logits output option in Whisper Pipeline
Author: tripathiarpan20
Pull request: yes
Labels: name: Audio

The PR adds an option to output logits in Whisper Pipeline minimally:

Example:
```python
import os
from typing import Any
import time
import subprocess
import torch
import numpy as np
from transformers import (
    WhisperFeatureExtractor,
    WhisperTokenizerFast,
    WhisperForConditionalGeneration,
    pipeline,
)
# from pyannote.audio import Pipeline
from transformers.models.whisper.tokenization_whisper import LANGUAGES

PIPELINE_URL = (
    "https://weights.replicate.delivery/default/incredibly-fast-whisper-pipe.tar"
)
PIPELINE_CACHE = "whisper-cache"

def prepare_weights():
    """Shows how to get the weights from HuggingFace Hub and then upload to Replicate google cloud bucket for faster boot time."""
    model_id = "distil-whisper/distil-large-v3"
    torch_dtype = torch.float16
    model_cache = "model_cache"
    model = WhisperForConditionalGeneration.from_pretrained(
        model_id,
        torch_dtype=torch_dtype,
        cache_dir=model_cache,
    )

    tokenizer = WhisperTokenizerFast.from_pretrained(model_id, cache_dir=model_cache)
    feature_extractor = WhisperFeatureExtractor.from_pretrained(
        model_id, cache_dir=model_cache
    )

    pipe = pipeline(
        "automatic-speech-recognition",
        model=model,
        tokenizer=tokenizer,
        feature_extractor=feature_extractor,
        model_kwargs={
            "use_flash_attention_2": True
            # "output_scores": True
         },
        torch_dtype=torch_dtype,
    )
    PIPELINE_CACHE = "whisper-cache"
    pipe.save_pretrained(
        PIPELINE_CACHE, safe_serialization=True
    )  # Then copy this dir to google cloud bucket that can later be downloaded from PIPELINE_URL

prepare_weights()

pipe = pipeline(
    task="automatic-speech-recognition",
    model=PIPELINE_CACHE,
    device='cuda:0',
)

audio = "sample_audio.mp3"
task = "translate"
language = "None"
batch_size = 24
timestamp = "word"
diarise_audio = False
hf_token = None

outputs = pipe(
    str(audio),
    chunk_length_s=30,
    batch_size=batch_size,
    generate_kwargs={
        "task": task,
        "language": None if language == "None" else language,
        "return_token_timestamps": True,
        "output_scores": True,
        "return_dict_in_generate": True
    },
    return_timestamps="word" if timestamp == "word" else True,
)

print("Voila!✨ Your file has been transcribed!")
print(outputs)
outputs['output_scores'][0].shape
```

Output:
```
Voila!✨ Your file has been transcribed!
{'text': " Now don't get me wrong, OpenAI is like the granddaddy of AI research. They've got way more GPU power than an over-caffeinated gamer at a Black Friday sale. But let's be real, while they're busy stockpiling hardware like it's the apocalypse, we're over here at BitTensor doing things a bit differently.", 'chunks': [{'text': ' Now', 'timestamp': (0.0, 0.54)}, {'text': " don't", 'timestamp': (0.54, 0.78)}, {'text': ' get', 'timestamp': (0.78, 0.88)}, {'text': ' me', 'timestamp': (0.88, 1.0)}, {'text': ' wrong,', 'timestamp': (1.0, 1.52)}, {'text': ' OpenAI', 'timestamp': (1.52, 2.18)}, {'text': ' is', 'timestamp': (2.18, 2.48)}, {'text': ' like', 'timestamp': (2.48, 2.64)}, {'text': ' the', 'timestamp': (2.64, 2.78)}, {'text': ' granddaddy', 'timestamp': (2.78, 3.34)}, {'text': ' of', 'timestamp': (3.34, 3.52)}, {'text': ' AI', 'timestamp': (3.52, 3.7)}, {'text': ' research.', 'timestamp': (3.7, 4.46)}, {'text': " They've", 'timestamp': (4.46, 5.14)}, {'text': ' got', 'timestamp': (5.14, 5.32)}, {'text': ' way', 'timestamp': (5.32, 5.54)}, {'text': ' more', 'timestamp': (5.54, 5.8)}, {'text': ' GPU', 'timestamp': (5.8, 6.06)}, {'text': ' power', 'timestamp': (6.06, 6.54)}, {'text': ' than', 'timestamp': (6.54, 6.84)}, {'text': ' an', 'timestamp': (6.84, 7.78)}, {'text': ' over', 'timestamp': (7.78, 8.04)}, {'text': '-caffeinated', 'timestamp': (8.04, 8.56)}, {'text': ' gamer', 'timestamp': (8.56, 8.9)}, {'text': ' at', 'timestamp': (8.9, 9.46)}, {'text': ' a', 'timestamp': (9.46, 9.6)}, {'text': ' Black', 'timestamp': (9.6, 9.82)}, {'text': ' Friday', 'timestamp': (9.82, 10.08)}, {'text': ' sale.', 'timestamp': (10.08, 10.76)}, {'text': ' But', 'timestamp': (10.76, 11.2)}, {'text': " let's", 'timestamp': (11.2, 11.58)}, {'text': ' be', 'timestamp': (11.58, 11.62)}, {'text': ' real,', 'timestamp': (11.62, 12.08)}, {'text': ' while', 'timestamp': (12.08, 12.26)}, {'text': " they're", 'timestamp': (12.26, 12.46)}, {'text': ' busy', 'timestamp': (12.46, 12.6)}, {'text': ' stockpiling', 'timestamp': (12.6, 13.22)}, {'text': ' hardware', 'timestamp': (13.22, 13.6)}, {'text': ' like', 'timestamp': (13.6, 13.92)}, {'text': " it's", 'timestamp': (13.92, 14.08)}, {'text': ' the', 'timestamp': (14.08, 14.16)}, {'text': ' apocalypse,', 'timestamp': (14.16, 14.9)}, {'text': " we're", 'timestamp': (14.9, 15.38)}, {'text': ' over', 'timestamp': (15.38, 15.52)}, {'text': ' here', 'timestamp': (15.52, 15.82)}, {'text': ' at', 'timestamp': (15.82, 16.22)}, {'text': ' BitTensor', 'timestamp': (16.22, 16.6)}, {'text': ' doing', 'timestamp': (16.6, 17.06)}, {'text': ' things', 'timestamp': (17.06, 17.4)}, {'text': ' a', 'timestamp': (17.4, 17.5)}, {'text': ' bit', 'timestamp': (17.5, 17.6)}, {'text': ' differently.', 'timestamp': (17.6, 18.16)}], 'output_scores': [tensor([[[-10.0772,     -inf,     -inf,  ..., -16.2759, -14.0490, -18.2150]],

        [[ -5.2273,     -inf,     -inf,  ...,  -5.6965,  -4.7519,  -6.1715]],

        [[  5.6077,     -inf,     -inf,  ...,  -1.5098,  -0.5507,  -2.9724]],

        ...,

        [[  3.6913,     -inf,     -inf,  ...,   0.5761,  -0.0342,  -0.8742]],

        [[  8.7269,     -inf,     -inf,  ...,  -1.8520,  -1.2823,  -2.8517]],

        [[ -4.9128,     -inf,     -inf,  ...,  -4.5779,  -3.1246,  -5.7994]]])]}
torch.Size([76, 1, 51866])
```


Comments:
cc @sanchit-gandhi @ylacombe 

Gentle ping @sanchit-gandhi @ylacombe 

Hey @tripathiarpan20, thanks for opening this PR! 
The [transformers pipeline](https://huggingface.co/docs/transformers/en/main_classes/pipelines#pipelines) are generally used for easy inference, and we generally refer to a more classic fine-grained usage (cf [here](https://huggingface.co/docs/transformers/model_doc/whisper#inference)) for more advanced use. 

I believe outputting logits fall into the latter case, and you can easily get `scores` with `output_scores=True`, so I'm not sure the current PR is appropriate TBH !

We also usually avoid modeling-specific code in `pt_utils`, which further reinforce the previous points!

Of course, happy to discuss this and I hope that my comment helps!


This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the [contributing guidelines](https://github.com/huggingface/transformers/blob/main/CONTRIBUTING.md) are likely to be ignored.