#pragma once
#include "transcribe.h"
#include <cstdint>
#include <string>
#include <vector>
struct gguf_context;
struct ggml_context;
struct ggml_tensor;
namespace transcribe::sortformer {
struct SortformerHParams {
int32_t max_speakers = 4; int32_t frame_hop = 0;
int32_t enc_n_layers = 0;
int32_t enc_d_model = 0;
int32_t enc_n_heads = 0;
int32_t enc_d_ff = 0;
int32_t enc_conv_kernel = 0;
int32_t enc_subsampling_factor = 0;
int32_t enc_subsampling_channels = 0;
int32_t enc_feat_in = 0;
int32_t enc_pos_emb_max_len = 0;
std::string enc_conv_norm_type;
int32_t tf_n_layers = 0;
int32_t tf_d_model = 0;
int32_t tf_n_heads = 0;
int32_t tf_d_ff = 0;
std::string tf_activation; bool tf_pre_ln = false;
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;
int32_t stream_chunk_len = 0;
int32_t stream_spkcache_len = 0;
int32_t stream_fifo_len = 0;
int32_t stream_spkcache_update_period = 0;
int32_t tf_head_dim() const { return tf_n_heads > 0 ? tf_d_model / tf_n_heads : 0; }
};
struct SortformerTfBlock {
ggml_tensor * norm1_w = nullptr; ggml_tensor * norm1_b = nullptr; ggml_tensor * attn_q_w = nullptr; ggml_tensor * attn_q_b = nullptr; ggml_tensor * attn_k_w = nullptr;
ggml_tensor * attn_k_b = nullptr;
ggml_tensor * attn_v_w = nullptr;
ggml_tensor * attn_v_b = nullptr;
ggml_tensor * attn_o_w = nullptr;
ggml_tensor * attn_o_b = nullptr;
ggml_tensor * norm2_w = nullptr; ggml_tensor * norm2_b = nullptr; ggml_tensor * ff_in_w = nullptr; ggml_tensor * ff_in_b = nullptr; ggml_tensor * ff_out_w = nullptr; ggml_tensor * ff_out_b = nullptr; };
struct SortformerWeights {
ggml_tensor * enc_proj_w = nullptr; ggml_tensor * enc_proj_b = nullptr;
std::vector<SortformerTfBlock> tf_blocks;
ggml_tensor * fc1_w = nullptr; ggml_tensor * fc1_b = nullptr; ggml_tensor * single_spk_head_w = nullptr; ggml_tensor * single_spk_head_b = nullptr; ggml_tensor * spk_head_w = nullptr; ggml_tensor * spk_head_b = nullptr; };
transcribe_status read_sortformer_hparams(const gguf_context * gguf, SortformerHParams & hp);
transcribe_status build_sortformer_weights(ggml_context * ctx_meta,
const SortformerHParams & hp,
SortformerWeights & weights,
const char * tensor_prefix = nullptr);
}