#pragma once
#include "transcribe.h"
#include <cstdint>
#include <string>
#include <vector>
struct gguf_context;
struct ggml_context;
struct ggml_tensor;
namespace transcribe::moonshine {
struct MoonshineHParams {
int32_t enc_n_layers = 0;
int32_t enc_d_model = 0;
int32_t enc_n_heads = 0;
int32_t enc_n_kv_heads = 0; int32_t enc_ffn_dim = 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_n_kv_heads = 0;
int32_t dec_ffn_dim = 0; int32_t dec_max_position_embeddings = 0; int32_t dec_vocab_size = 0;
std::string dec_activation; bool dec_tie_word_embeddings = true;
int32_t bos_token_id = -1; int32_t eos_token_id = -1; int32_t pad_token_id = -1; int32_t decoder_start_token_id = -1;
float partial_rotary_factor = 0.9f;
float rope_theta = 10000.0f;
bool attention_bias = false;
int32_t pad_head_dim_multiple = 0;
std::vector<int32_t> conv_channels; std::vector<int32_t> conv_kernel_sizes; std::vector<int32_t> conv_strides; int32_t conv_groupnorm_num_groups = 1;
float conv_groupnorm_eps = 1e-5f;
std::string fe_type; int32_t fe_sample_rate = 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; }
int32_t enc_head_dim_padded() const {
const int32_t hd = enc_head_dim();
const int32_t m = pad_head_dim_multiple;
if (m <= 0 || hd <= 0) {
return hd;
}
return ((hd + m - 1) / m) * m;
}
int32_t dec_head_dim_padded() const {
const int32_t hd = dec_head_dim();
const int32_t m = pad_head_dim_multiple;
if (m <= 0 || hd <= 0) {
return hd;
}
return ((hd + m - 1) / m) * m;
}
int32_t enc_head_dim_rot() const {
const int32_t hd = enc_head_dim();
const int32_t r = static_cast<int32_t>(static_cast<float>(hd) * partial_rotary_factor);
return r & ~int32_t{ 1 };
}
int32_t dec_head_dim_rot() const {
const int32_t hd = dec_head_dim();
const int32_t r = static_cast<int32_t>(static_cast<float>(hd) * partial_rotary_factor);
return r & ~int32_t{ 1 };
}
};
transcribe_status read_moonshine_hparams(const gguf_context * gguf, MoonshineHParams & hp);
struct MoonshineEncStem {
ggml_tensor * conv0_w = nullptr; ggml_tensor * conv1_w = nullptr; ggml_tensor * conv1_b = nullptr; ggml_tensor * conv2_w = nullptr; ggml_tensor * conv2_b = nullptr; ggml_tensor * gn_w = nullptr; ggml_tensor * gn_b = nullptr; };
struct MoonshineEncTop {
ggml_tensor * final_norm_w = nullptr; };
struct MoonshineEncBlock {
ggml_tensor * norm_attn_w = nullptr;
ggml_tensor * attn_q_w = nullptr;
ggml_tensor * attn_k_w = nullptr;
ggml_tensor * attn_v_w = nullptr;
ggml_tensor * attn_out_w = nullptr;
ggml_tensor * norm_ffn_w = 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 MoonshineDecTop {
ggml_tensor * token_embd_w = nullptr; ggml_tensor * final_norm_w = nullptr; };
struct MoonshineDecBlock {
ggml_tensor * norm_self_w = nullptr;
ggml_tensor * self_q_w = nullptr;
ggml_tensor * self_k_w = nullptr;
ggml_tensor * self_v_w = nullptr;
ggml_tensor * self_out_w = nullptr;
ggml_tensor * norm_cross_w = nullptr;
ggml_tensor * cross_q_w = nullptr;
ggml_tensor * cross_k_w = nullptr;
ggml_tensor * cross_v_w = nullptr;
ggml_tensor * cross_out_w = nullptr;
ggml_tensor * norm_ffn_w = 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 MoonshineWeights {
MoonshineEncStem enc_stem;
MoonshineEncTop enc_top;
std::vector<MoonshineEncBlock> enc_blocks;
MoonshineDecTop dec_top;
std::vector<MoonshineDecBlock> dec_blocks;
};
transcribe_status build_moonshine_weights(ggml_context * ctx_meta,
const MoonshineHParams & hp,
MoonshineWeights & weights);
}