#pragma once
#include "transcribe.h"
#include "transcribe-mel.h"
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
struct gguf_context;
struct ggml_context;
struct ggml_tensor;
namespace transcribe::whisper {
struct WhisperHParams {
int32_t enc_n_layers = 0;
int32_t enc_d_model = 0;
int32_t enc_n_heads = 0;
int32_t enc_ffn_dim = 0;
int32_t enc_num_mel_bins = 0;
int32_t enc_max_source_positions = 0; std::string enc_activation;
int32_t dec_n_layers = 0;
int32_t dec_d_model = 0; int32_t dec_n_heads = 0;
int32_t dec_ffn_dim = 0;
int32_t dec_max_target_positions = 0;
int32_t dec_vocab_size = 0;
std::string dec_activation;
bool dec_tie_word_embeddings = true;
bool dec_scale_embedding = false;
int32_t decoder_start_token_id = -1; int32_t no_timestamps_token_id = -1; int32_t sot_token_id = -1; int32_t transcribe_token_id = -1; int32_t translate_token_id = -1; int32_t prev_sot_token_id = -1;
std::vector<int32_t> suppress_tokens; std::vector<int32_t> begin_suppress_tokens;
std::string fe_type;
int32_t fe_num_mels = 0;
int32_t fe_sample_rate = 0;
int32_t fe_n_fft = 0;
int32_t fe_win_length = 0;
int32_t fe_hop_length = 0;
std::string fe_window;
std::string fe_normalize;
float fe_dither = 0.0f;
float fe_pre_emphasis = 0.0f;
float fe_f_min = 0.0f;
float fe_f_max = 0.0f;
std::string fe_pad_mode; bool fe_center = true;
std::string fe_mel_norm; int32_t fe_chunk_length = 0; int32_t fe_n_samples = 0; int32_t fe_nb_max_frames = 0;
bool cap_lang_detect = false;
bool cap_translate = false;
bool cap_timestamps = false;
int32_t enc_head_dim() const { return enc_n_heads > 0 ? enc_d_model / enc_n_heads : 0; }
int32_t dec_head_dim() const { return dec_n_heads > 0 ? dec_d_model / dec_n_heads : 0; }
};
transcribe_status read_whisper_hparams(const gguf_context * gguf,
WhisperHParams & hp);
struct WhisperFrontend {
ggml_tensor * mel_filterbank = nullptr; ggml_tensor * window = nullptr; };
struct WhisperEncStem {
ggml_tensor * conv0_w = nullptr; ggml_tensor * conv0_b = nullptr; ggml_tensor * conv1_w = nullptr; ggml_tensor * conv1_b = nullptr; };
struct WhisperEncTop {
ggml_tensor * pos_emb_w = nullptr; ggml_tensor * final_norm_w = nullptr; ggml_tensor * final_norm_b = nullptr; };
struct WhisperEncBlock {
ggml_tensor * norm_attn_w = nullptr;
ggml_tensor * norm_attn_b = nullptr;
ggml_tensor * attn_q_w = nullptr;
ggml_tensor * attn_q_b = nullptr;
ggml_tensor * attn_k_w = nullptr; ggml_tensor * attn_v_w = nullptr;
ggml_tensor * attn_v_b = nullptr;
ggml_tensor * attn_out_w = nullptr;
ggml_tensor * attn_out_b = nullptr;
ggml_tensor * norm_ffn_w = nullptr;
ggml_tensor * norm_ffn_b = nullptr;
ggml_tensor * ffn_fc1_w = nullptr;
ggml_tensor * ffn_fc1_b = nullptr;
ggml_tensor * ffn_fc2_w = nullptr;
ggml_tensor * ffn_fc2_b = nullptr;
};
struct WhisperDecTop {
ggml_tensor * token_embd_w = nullptr; ggml_tensor * pos_emb_w = nullptr; ggml_tensor * final_norm_w = nullptr;
ggml_tensor * final_norm_b = nullptr;
};
struct WhisperDecBlock {
ggml_tensor * norm_self_w = nullptr;
ggml_tensor * norm_self_b = nullptr;
ggml_tensor * self_q_w = nullptr;
ggml_tensor * self_q_b = nullptr;
ggml_tensor * self_k_w = nullptr; ggml_tensor * self_v_w = nullptr;
ggml_tensor * self_v_b = nullptr;
ggml_tensor * self_out_w = nullptr;
ggml_tensor * self_out_b = nullptr;
ggml_tensor * norm_cross_w = nullptr;
ggml_tensor * norm_cross_b = nullptr;
ggml_tensor * cross_q_w = nullptr;
ggml_tensor * cross_q_b = nullptr;
ggml_tensor * cross_k_w = nullptr; ggml_tensor * cross_v_w = nullptr;
ggml_tensor * cross_v_b = nullptr;
ggml_tensor * cross_out_w = nullptr;
ggml_tensor * cross_out_b = nullptr;
ggml_tensor * norm_ffn_w = nullptr;
ggml_tensor * norm_ffn_b = nullptr;
ggml_tensor * ffn_fc1_w = nullptr;
ggml_tensor * ffn_fc1_b = nullptr;
ggml_tensor * ffn_fc2_w = nullptr;
ggml_tensor * ffn_fc2_b = nullptr;
};
struct WhisperWeights {
WhisperFrontend frontend;
WhisperEncStem enc_stem;
WhisperEncTop enc_top;
std::vector<WhisperEncBlock> enc_blocks;
WhisperDecTop dec_top;
std::vector<WhisperDecBlock> dec_blocks;
};
transcribe_status build_whisper_weights(ggml_context * ctx_meta,
const WhisperHParams & hp,
WhisperWeights & weights);
transcribe_status install_mel_from_buffers(
const WhisperHParams & hp,
std::vector<float> filterbank,
std::vector<float> window,
std::optional<transcribe::MelFrontend> & out_mel);
}