#pragma once
#include "transcribe.h"
#include <cstdint>
#include <string>
#include <vector>
struct gguf_context;
struct ggml_context;
struct ggml_tensor;
namespace transcribe::medasr {
struct MedAsrHParams {
int32_t enc_n_layers = 0;
int32_t enc_hidden = 0; int32_t enc_n_heads = 0;
int32_t enc_n_kv_heads = 0; int32_t enc_head_dim = 0;
int32_t enc_intermediate = 0; std::string enc_hidden_act; int32_t enc_conv_kernel = 0; float enc_conv_resid_w0 = 0.0f; float enc_conv_resid_w1 = 0.0f; float enc_ff_resid_w0 = 0.0f; float enc_ff_resid_w1 = 0.0f; float enc_layer_norm_eps = 1e-6f;
int32_t enc_max_pos_emb = 0;
float enc_batch_norm_momentum = 0.01f;
float enc_rope_theta = 10000.0f;
std::string enc_rope_type;
int32_t enc_num_mel_bins = 0; int32_t enc_sub_kernel = 0; int32_t enc_sub_stride = 0; int32_t enc_sub_channels = 0; int32_t enc_sub_n_layers = 0;
int32_t ctc_vocab_size = 0;
int32_t ctc_blank_id = 0;
std::string fe_type; int32_t fe_sample_rate = 0;
int32_t fe_num_mels = 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; std::string fe_pad_mode; std::string fe_mel_norm; float fe_log_clamp_min = 1e-5f;
float fe_mel_lower_hz = 125.0f;
float fe_mel_upper_hz = 7500.0f;
};
transcribe_status read_medasr_hparams(const gguf_context * gguf, MedAsrHParams & hp);
struct MedAsrSubsampling {
ggml_tensor * dense0_w = nullptr; ggml_tensor * dense0_b = nullptr; ggml_tensor * conv0_w = nullptr; ggml_tensor * conv0_b = nullptr; ggml_tensor * conv1_w = nullptr; ggml_tensor * conv1_b = nullptr; ggml_tensor * dense1_w = nullptr; ggml_tensor * dense1_b = nullptr; };
struct MedAsrBlock {
ggml_tensor * norm_ff1_w = nullptr;
ggml_tensor * ff1_up_w = nullptr; ggml_tensor * ff1_down_w = nullptr;
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_o_w = nullptr;
ggml_tensor * norm_conv_w = nullptr;
ggml_tensor * conv_pw1_w = nullptr; ggml_tensor * conv_dw_w = nullptr; ggml_tensor * conv_bn_scale = nullptr; ggml_tensor * conv_bn_bias = nullptr; ggml_tensor * conv_pw2_w = nullptr;
ggml_tensor * norm_ff2_w = nullptr;
ggml_tensor * ff2_up_w = nullptr;
ggml_tensor * ff2_down_w = nullptr;
ggml_tensor * norm_post_w = nullptr;
};
struct MedAsrCtcHead {
ggml_tensor * proj_w = nullptr; ggml_tensor * proj_b = nullptr; };
struct MedAsrWeights {
ggml_tensor * frontend_mel_filterbank = nullptr; ggml_tensor * frontend_window = nullptr;
MedAsrSubsampling subsampling;
std::vector<MedAsrBlock> blocks;
ggml_tensor * enc_out_norm_w = nullptr; MedAsrCtcHead ctc_head;
std::vector<std::vector<float>> fused_bn_scale_storage;
std::vector<std::vector<float>> fused_bn_bias_storage;
};
transcribe_status build_medasr_weights(ggml_context * ctx_meta, const MedAsrHParams & hp, MedAsrWeights & weights);
transcribe_status fuse_batch_norm(const gguf_context * gguf_data,
ggml_context * ctx_meta,
const MedAsrHParams & hp,
MedAsrWeights & weights);
}