BPE timestamp extraction example
State: closed | Pull request: no
Labels: name: feature

**Is your feature request related to a problem? Please describe.**

Not a problem, just seeking some guidance on how to replicate the timestamp extraction code featured within the [Offline_ASR](https://github.com/NVIDIA/NeMo/blob/main/tutorials/asr/Offline_ASR.ipynb) notebook. Currently experiencing difficulties adapting the code from that notebook to my use-case (BPE tokenisation).

**Describe the solution you'd like**

Code from the Offline_ASR notebook, with BPE-centric adaptations.

**Describe alternatives you've considered**

As above.

Minimal example below, adapted and tweaked from original Offline_ASR notebook:
```
import nemo.collections.asr as nemo_asr
import numpy as np

def get_space_timestamps(output):
    # get timestamps for space symbols - char log probs across time sequences
    probs = output.y_sequence.detach().cpu().numpy()
    spaces = []
    state = ''
    idx_state = 0

    if np.argmax(probs[0]) == 1:
        # tokenizer dependant; retrieve the "space" token index
        state = 'space'

    for idx in range(1, probs.shape[0]):
        current_char_idx = np.argmax(probs[idx])
        # and not blank
        if state == 'space' and current_char_idx != 128:
            spaces.append([idx_state, idx-1])
            state = ''
        if state == '':
            if current_char_idx == 1:
                state = 'space'
                idx_state = idx

    if state == 'space':
        spaces.append([idx_state, len(pred)-1])

    return spaces

def format_word_timestamps(transcript, space_timestamps, offset, time_stride):
    # split the transcript into words
    words = transcript.split()

    # cut words, assign timestamp
    formatted_words = []
    pos_prev = 0
    for j, spot in enumerate(space_timestamps):
        pos_end = offset + (spot[0]+spot[1])/2*time_stride
        # format words as records
        formatted_words.append(
            {'word': words[j], 'start': pos_prev, 'end': pos_end})
        pos_prev = pos_end

    return formatted_words

# load model
asr_model = nemo_asr.models.ASRModel.from_pretrained("stt_en_conformer_ctc_large")
time_stride = asr_model.cfg.preprocessor.window_size # shipped with model config?
offset = -0.18 # taken from notebook

# retrieve transcript and logprobs
output = asr_model.transcribe(paths2audio_files=['path/to/audio_file.wav'],
                              return_hypotheses=True)[0] # take first

spaces = get_space_timestamps(output)
# [[55, 55], [75, 75], [122, 124]]

time_formatted_words = format_word_timestamps(output.text, spaces, offset, time_stride)
# formats a very small portion of transcript: 
# [{'word': 'in', 'start': 0, 'end': 1.195},
#  {'word': 'this', 'start': 1.195, 'end': 1.695},
#  {'word': 'type', 'start': 1.695, 'end': 2.895}]
```
**Additional context**

I feel like I'm probably doing something really silly here, some additional information comparing Quartznet example vocab/alignments and Conformer vocab/alignments:

```
# transcript
"in this type of system when people get their jobs because of a favor or because of somebody that they know not meaning that this in itself is corrupt that they're incompetent but they're beholdent on a system of favoritism of connectedness"

# stt_en_conformer_ctc_large - 128
conformer_vocab = ['<unk>', '▁', '##s', '##t', '##e', '##a', '##i', '##d', '##o', '##m', '##l', 'a', 'the', '##n', '##p', '##y', '##u', '##er', '##h', '##re', '##c', '##r', 'i', 's', '##ing',
 "##'", 'to', '##k', '##g', 'and', '##f', '##an', '##ed', '##w', 'of', 'w', 'in', 'you', '##or', '##v', 'f', 'b', '##in', '##b', '##ar', '##en', '##ve', '##es', 'it', 'that',
 '##al', '##ll', 'be', 'co', 'he', '##le', '##ch', 'do', 'we', '##ly', '##it', 'g', '##ent', '##ur', '##on', '##ic', 'c', 'on', '##un', '##th', 'ha', 'was', 't', 'is', 'for',
 'ma', '##ri', 'know', 're', '##ra', 'th', '##us', '##ce', 'but', 'go', '##ro', 'mo', 'st', 'me', 'they', 'so', 'yeah', 'ca', '##ir', 'have', 'like', 'di', 'ho', '##ion', 'with',
 'lo', 'not', 'no', 'de', 'ne', 'pa', '##ation', 'this', 'what', 'some', 'uh', 'pro', 'my', '##j', 'his', 'ex', 'just', 'um', 'po', 'la', 'think', 'she', '##ough', 'from', '##q', 'out', '##x', '##z']

# example alignments - 447
conformer_alignments = [128, 128, 128, 128, 128, 36, 128, 128, 128, 128, 128, 107, 128, 128, 128, 128, 128, 128, 128, 72, 128, 15, 128, 14, 4, 4, 128, 34, 128, 128, 128, 128, 128, 23, 128, 128, 15, 2, 128, 3, 128, 4, 9, 128, 128, 128, 128, 128, 128, 128, 35, 18, 45, 128, 128, 1, 14, 4, 4, 8, 14, 55, 128, 128, 61, 4, 128, 3, 128, 128, 12, 128, 93, 128, 128, 1, 113, 128, 8, 128, 43, 128, 128, 2, 128, 128, 128, 128, 128, 52, 128, 128, 20, 128, 5, 81, 4, 4, 128, 128, 128, 34, 128, 128, 128, 11, 128, 128, 128, 128, 40, 128, 128, 5, 128, 39, 128, 128, 38, 128, 128, 128, 1, 128, 128, 38, 128, 128, 128, 52, 128, 128, 20, 128, 5, 81, 4, 4, 128, 128, 128, 128, 128, 128, 34, 128, 128, 128, 128, 128, 128, 128, 128, 128, 109, 128, 128, 128, 43, 8, 128, 7, 15, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 49, 128, 128, 128, 128, 128, 89, 128, 128, 128, 128, 77, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 101, 128, 128, 128, 128, 128, 88, 128, 128, 31, 128, 24, 128, 128, 49, 128, 128, 128, 128, 107, 128, 128, 128, 128, 128, 128, 36, 128, 128, 48, 128, 128, 128, 2, 4, 10, 10, 30, 128, 128, 128, 73, 128, 128, 53, 128, 21, 128, 128, 21, 21, 16, 14, 3, 3, 128, 49, 128, 128, 128, 128, 89, 128, 25, 19, 128, 128, 36, 128, 128, 128, 20, 8, 8, 9, 128, 14, 128, 4, 128, 3, 128, 128, 62, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 83, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 89, 128, 128, 25, 19, 128, 128, 128, 128, 128, 52, 128, 128, 128, 18, 8, 8, 10, 7, 7, 128, 128, 62, 128, 128, 128, 128, 128, 67, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 11, 128, 128, 128, 128, 23, 128, 15, 2, 128, 3, 128, 4, 128, 9, 128, 128, 128, 128, 128, 128, 34, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 40, 128, 5, 5, 39, 128, 128, 38, 128, 60, 128, 128, 128, 6, 2, 2, 128, 128, 9, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 34, 128, 128, 128, 128, 53, 128, 13, 128, 128, 13, 128, 4, 20, 3, 128, 128, 32, 128, 13, 128, 47, 2, 128, 128, 128, 128, 128, 128, 128]

# quartznet - 28
quartznet_vocab = [' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', "'"]

# quartznet alignments - 889
quartznet_alignments = [28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 9, 14, 28, 28, 28, 28, 28, 0, 28, 20, 8, 9, 28, 19, 28, 28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 28, 28, 28, 28, 20, 28, 25, 28, 16, 5, 28, 28, 28, 28, 0, 0, 15, 6, 0, 0, 0, 0, 0, 0, 0, 28, 28, 28, 28, 28, 28, 19, 28, 25, 28, 19, 28, 28, 28, 28, 28, 20, 28, 5, 28, 13, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 8, 5, 14, 28, 0, 0, 0, 0, 0, 0, 28, 16, 5, 15, 16, 16, 12, 5, 28, 28, 0, 0, 0, 0, 0, 7, 5, 20, 28, 0, 0, 0, 0, 20, 8, 5, 9, 18, 28, 28, 0, 0, 0, 0, 28, 28, 10, 28, 15, 28, 2, 28, 28, 19, 19, 28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 2, 5, 28, 28, 28, 28, 28, 3, 1, 21, 19, 5, 5, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 28, 28, 28, 28, 28, 6, 28, 1, 28, 28, 28, 28, 22, 28, 15, 28, 18, 18, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 0, 15, 18, 0, 0, 0, 0, 0, 0, 28, 28, 2, 5, 28, 28, 28, 28, 3, 28, 1, 21, 19, 5, 5, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 28, 19, 19, 15, 13, 5, 5, 28, 28, 2, 28, 15, 4, 28, 28, 28, 25, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 8, 1, 20, 0, 0, 0, 0, 0, 0, 0, 20, 8, 5, 25, 28, 0, 0, 0, 0, 0, 0, 11, 11, 14, 15, 28, 23, 28, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 15, 20, 0, 0, 0, 0, 0, 0, 28, 13, 28, 5, 1, 1, 28, 14, 28, 9, 28, 14, 7, 28, 28, 0, 0, 20, 8, 1, 20, 0, 0, 0, 0, 0, 0, 0, 20, 8, 9, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 14, 28, 0, 0, 0, 28, 28, 9, 20, 28, 28, 28, 28, 28, 28, 19, 28, 5, 28, 12, 28, 6, 28, 28, 28, 0, 0, 28, 9, 19, 28, 0, 0, 0, 0, 0, 28, 28, 3, 28, 15, 28, 18, 28, 28, 18, 18, 21, 28, 16, 28, 20, 28, 28, 28, 28, 28, 28, 28, 5, 4, 28, 0, 0, 0, 0, 0, 0, 28, 28, 22, 28, 5, 28, 18, 18, 28, 28, 25, 28, 28, 0, 28, 9, 14, 28, 28, 28, 28, 28, 28, 28, 3, 28, 15, 28, 13, 28, 28, 16, 28, 5, 28, 28, 28, 20, 28, 5, 28, 14, 20, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 21, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 20, 8, 5, 25, 28, 28, 18, 18, 28, 28, 28, 28, 28, 28, 28, 0, 0, 28, 28, 28, 2, 28, 5, 28, 28, 28, 28, 28, 8, 28, 15, 28, 12, 28, 28, 4, 4, 28, 9, 28, 14, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 28, 28, 28, 28, 28, 19, 28, 25, 28, 19, 19, 28, 28, 28, 20, 28, 5, 28, 13, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 28, 6, 28, 1, 28, 28, 28, 28, 22, 28, 15, 18, 18, 28, 9, 28, 28, 28, 28, 20, 28, 9, 28, 19, 28, 28, 28, 28, 28, 28, 28, 13, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 6, 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 3, 28, 15, 14, 28, 28, 28, 14, 28, 5, 28, 3, 28, 28, 20, 28, 5, 28, 4, 28, 28, 28, 28, 14, 28, 5, 28, 19, 28, 19, 28, 28, 28, 28, 28]
```

Any help much appreciated!