#pragma once
#include "transcribe.h"
#include <cstdint>
#include <string>
#include <vector>
struct gguf_context;
struct ggml_context;
struct ggml_tensor;
namespace transcribe::ecapa_tdnn {
constexpr int kNumStages = 5;
constexpr int kNumSeBlocks = 3;
constexpr int kRes2NetScale = 8;
constexpr int kRes2NetSubs = kRes2NetScale - 1;
struct HParams {
int32_t sample_rate = 0;
int32_t mel_n_fft = 0;
int32_t mel_hop = 0;
int32_t mel_win = 0;
int32_t mel_n_mels = 0;
std::string mel_window; std::string mel_pad_mode; float mel_log_floor = 0.0f;
float mel_top_db = 0.0f;
std::string mel_normalize;
std::vector<int32_t> channels; std::vector<int32_t> kernel_sizes; std::vector<int32_t> dilations; int32_t res2net_scale = 0;
int32_t se_channels = 0;
int32_t attention_channels = 0;
float asp_eps = 0.0f;
int32_t embedding_dim = 0;
int32_t classifier_hidden = 0;
float leaky_slope = 0.0f;
int32_t n_labels = 0;
int32_t c_block() const { return channels.empty() ? 0 : channels[0]; }
int32_t c_mfa() const { return channels.size() < kNumStages ? 0 : channels[kNumStages - 1]; }
int32_t c_chunk() const { return res2net_scale > 0 ? c_block() / res2net_scale : 0; }
int32_t n_freq() const { return mel_n_fft / 2 + 1; }
int32_t blk0_cols() const {
const int32_t n = kernel_sizes.empty() ? 0 : kernel_sizes[0] * mel_n_mels;
return (n + 31) / 32 * 32;
}
int32_t pad(int i) const {
return dilations[static_cast<size_t>(i)] * (kernel_sizes[static_cast<size_t>(i)] - 1) / 2;
}
};
struct BnAffine {
ggml_tensor * scale = nullptr;
ggml_tensor * shift = nullptr;
};
struct TdnnLayer {
ggml_tensor * w = nullptr;
ggml_tensor * b = nullptr;
BnAffine bn;
};
struct Res2Sub {
ggml_tensor * w = nullptr; ggml_tensor * b = nullptr; BnAffine bn;
};
struct SeBlock {
ggml_tensor * c1_w = nullptr; ggml_tensor * c1_b = nullptr; ggml_tensor * c2_w = nullptr; ggml_tensor * c2_b = nullptr; };
struct SeRes2NetBlock {
TdnnLayer tdnn1;
Res2Sub res2[kRes2NetSubs];
TdnnLayer tdnn2;
SeBlock se;
};
struct Weights {
ggml_tensor * mel_filters = nullptr;
ggml_tensor * blk0_w = nullptr; ggml_tensor * blk0_w_im2col = nullptr; ggml_tensor * blk0_b = nullptr; BnAffine blk0_bn;
SeRes2NetBlock blocks[kNumSeBlocks];
ggml_tensor * mfa_w[kNumSeBlocks] = { nullptr, nullptr, nullptr };
ggml_tensor * mfa_b = nullptr; BnAffine mfa_bn;
ggml_tensor * asp_wx = nullptr; ggml_tensor * asp_wm = nullptr;
ggml_tensor * asp_ws = nullptr;
ggml_tensor * asp_b = nullptr; BnAffine asp_bn;
ggml_tensor * asp_attn_w = nullptr; ggml_tensor * asp_attn_b = nullptr;
ggml_tensor * fc_w = nullptr; ggml_tensor * fc_b = nullptr;
ggml_tensor * cls_l1_w = nullptr; ggml_tensor * cls_l1_b = nullptr; ggml_tensor * cls_out_w = nullptr; ggml_tensor * cls_out_b = nullptr; };
transcribe_status read_hparams(const gguf_context * gguf, HParams & hp);
transcribe_status build_weights(ggml_context * ctx_meta, const HParams & hp, Weights & w);
}