Repository: ggerganov/whisper.cpp
File: src/whisper.cpp (C++)

Code before:
            }
            prompt_tokens.resize(n_needed);
            params.prompt_tokens   = prompt_tokens.data();
            params.prompt_n_tokens = prompt_tokens.size();
        }
        if (params.prompt_tokens && params.prompt_n_tokens > 0) {
            if (params.carry_initial_prompt) {
                if (prompt_past0.empty()) {
                    prompt_past0.assign(params.prompt_tokens, params.prompt_tokens + params.prompt_n_tokens);
                }
            } else {
                for (int i = 0; i < params.prompt_n_tokens; ++i) {
                    prompt_past1.push_back(params.prompt_tokens[i]);
                }
                std::rotate(prompt_past1.begin(), prompt_past1.end() - params.prompt_n_tokens, prompt_past1.end());
            }
        }
    }

    // overwrite audio_ctx, max allowed is hparams.n_audio_ctx
    if (params.audio_ctx > whisper_n_audio_ctx(ctx)) {
        WHISPER_LOG_ERROR("%s: audio_ctx is larger than the maximum allowed (%d > %d)\n", __func__, params.audio_ctx, whisper_n_audio_ctx(ctx));
        return -5;
    }
    state->exp_n_audio_ctx = params.audio_ctx;

    // these tokens determine the task that will be performed
    std::vector<whisper_token> prompt_init = { whisper_token_sot(ctx), };

    if (whisper_is_multilingual(ctx)) {
        const int lang_id = whisper_lang_id(params.language);
        state->lang_id = lang_id;
        prompt_init.push_back(whisper_token_lang(ctx, lang_id));
        if (params.translate) {
            prompt_init.push_back(whisper_token_translate(ctx));
        } else {
            prompt_init.push_back(whisper_token_transcribe(ctx));
        }
    }

    // first release distilled models require the "no_timestamps" token
    {
        const bool is_distil = ctx->model.hparams.n_text_layer == 2 && ctx->model.hparams.n_vocab != 51866;
        if (is_distil && !params.no_timestamps) {
            WHISPER_LOG_WARN("%s: using first release distilled models - forcing no_timestamps\n", __func__);
            params.no_timestamps = true;
        }
    }

    if (params.no_timestamps) {
        prompt_init.push_back(whisper_token_not(ctx));

Review comment (suggestion):
If I am following this logic correctly, I think there is a problem in the first iteration:

- When `carry_initia_prompt == true`, here we have `prompt_past0` non-empty and `prompt_past1` empty
- But later on line 7067, we check `seek != seek_start` which would be `false` (this is the first iter)
- So as a result I think the first iter will run without any prompt

If I am correct, I think the fix is to remove the `seek != seek_start` check.

Code after:
            if (n_needed < 0) {
                prompt_tokens.resize(-n_needed);
                n_needed = whisper_tokenize(ctx, params.initial_prompt, prompt_tokens.data(), prompt_tokens.size());
            }
            prompt_tokens.resize(n_needed);
            params.prompt_tokens   = prompt_tokens.data();
            params.prompt_n_tokens = prompt_tokens.size();
        }
        if (params.prompt_tokens && params.prompt_n_tokens > 0) {
            if (params.carry_initial_prompt) {
                if (prompt_past0.empty()) {
                    const int max_tokens = std::max(1, max_prompt_ctx - 1);

                    if (params.prompt_n_tokens > max_tokens) {
                        WHISPER_LOG_WARN("%s: initial prompt is too long (%d tokens), will use only the last %d tokens\n",
                                        __func__, params.prompt_n_tokens, max_tokens);
                    }

                    const int n_tokens = std::min(params.prompt_n_tokens, max_tokens);
                    prompt_past0.assign(params.prompt_tokens + (params.prompt_n_tokens - n_tokens), params.prompt_tokens + params.prompt_n_tokens);
                }
            } else {
                for (int i = 0; i < params.prompt_n_tokens; ++i) {
                    prompt_past1.push_back(params.prompt_tokens[i]);
                }
                std::rotate(prompt_past1.begin(), prompt_past1.end() - params.prompt_n_tokens, prompt_past1.end());
            }
        }
    }

    // overwrite audio_ctx, max allowed is hparams.n_audio_ctx
    if (params.audio_ctx > whisper_n_audio_ctx(ctx)) {
        WHISPER_LOG_ERROR("%s: audio_ctx is larger than the maximum allowed (%d > %d)\n", __func__, params.audio_ctx, whisper_n_audio_ctx(ctx));
        return -5;
    }
    state->exp_n_audio_ctx = params.audio_ctx;

    // these tokens determine the task that will be performed
    std::vector<whisper_token> prompt_init = { whisper_token_sot(ctx), };

    if (whisper_is_multilingual(ctx)) {
        const int lang_id = whisper_lang_id(params.language);
        state->lang_id = lang_id;
        prompt_init.push_back(whisper_token_lang(ctx, lang_id));
        if (params.translate) {
            prompt_init.push_back(whisper_token_translate(ctx));
        } else {
            prompt_init.push_back(whisper_token_transcribe(ctx));
        }
    }