#pragma once
#include "transcribe.h"
#include "ggml.h"
#include "ggml-backend.h"
#include <cstdint>
#include <vector>
struct transcribe_session;
namespace transcribe::causal_lm {
struct BlockView {
ggml_tensor * norm_attn_w = nullptr; ggml_tensor * norm_ffn_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 * attn_q_norm = nullptr; ggml_tensor * attn_k_norm = nullptr; ggml_tensor * ffn_gate_up_w = nullptr; ggml_tensor * ffn_down_w = nullptr; ggml_tensor * ffn_scale = nullptr; };
struct BlockParams {
int n_heads = 0;
int n_kv_heads = 0;
int head_dim = 0;
int max_position = 0; float rms_eps = 0.0f;
float rope_theta = 0.0f;
};
struct KvCache {
ggml_tensor * self_k = nullptr;
ggml_tensor * self_v = nullptr;
ggml_context * ctx = nullptr;
ggml_backend_buffer_t buffer = nullptr;
int n_ctx = 0;
int n = 0; int head = 0; int n_batch = 1;
void free();
};
bool kv_init(KvCache & cache,
ggml_backend_t backend,
int n_ctx,
int n_kv_heads,
int head_dim,
int n_layer,
ggml_type kv_type);
bool kv_init_batched(KvCache & cache,
ggml_backend_t backend,
int n_ctx,
int n_kv_heads,
int head_dim,
int n_layer,
int n_batch,
ggml_type kv_type);
struct BlockOpts {
bool use_flash = true;
bool slice_last_before_ffn = false;
int kv_batch_slot = 0;
int kv_n_batch = 1;
};
ggml_tensor * block_prefill(
ggml_context * ctx,
ggml_cgraph * gf,
ggml_tensor * x,
const BlockView & view,
const BlockParams & params,
KvCache & kv_cache,
int layer_idx,
int T_seq,
ggml_tensor * mask, ggml_tensor * positions, BlockOpts opts = {});
ggml_tensor * block_step(
ggml_context * ctx,
ggml_cgraph * gf,
ggml_tensor * x, const BlockView & view,
const BlockParams & params,
KvCache & kv_cache,
int layer_idx,
int max_n_kv,
ggml_tensor * mask, ggml_tensor * position, ggml_tensor * kv_idx, bool use_flash);
ggml_tensor * block_step_n(
ggml_context * ctx,
ggml_cgraph * gf,
ggml_tensor * x, const BlockView & view,
const BlockParams & params,
KvCache & kv_cache,
int layer_idx,
int T_seq,
int max_n_kv,
ggml_tensor * mask, ggml_tensor * positions, ggml_tensor * kv_idx, bool use_flash);
ggml_tensor * block_step_batched(
ggml_context * ctx,
ggml_cgraph * gf,
ggml_tensor * x, const BlockView & view,
const BlockParams & params,
KvCache & kv_cache,
int layer_idx,
int max_n_kv,
int n_batch,
ggml_tensor * mask, ggml_tensor * position, ggml_tensor * kv_idx, bool use_flash);
ggml_tensor * block_prefill_batched(
ggml_context * ctx,
ggml_cgraph * gf,
ggml_tensor * x, const BlockView & view,
const BlockParams & params,
KvCache & kv_cache,
int layer_idx,
int T_seq,
int n_batch,
ggml_tensor * mask, ggml_tensor * positions, ggml_tensor * kv_idx, bool use_flash);
struct GateUpEntry {
ggml_tensor * gate_w;
ggml_tensor * up_w;
ggml_tensor ** gate_up_w_out;
};
struct PackedGateUpHandles {
ggml_context * ctx = nullptr;
ggml_backend_buffer_t buffer = nullptr;
void free();
};
bool pack_gate_up(ggml_backend_t backend,
int hidden,
int intermediate,
const std::vector<GateUpEntry> & entries,
PackedGateUpHandles & out_handles,
const char * error_tag = "causal_lm");
struct StepBatchedIO {
ggml_tensor * input_ids = nullptr; ggml_tensor * positions = nullptr; ggml_tensor * kv_idx = nullptr; ggml_tensor * mask = nullptr; ggml_tensor * argmax = nullptr; ggml_cgraph * graph = nullptr;
};
struct StepBatchedState {
std::vector<char> valid;
std::vector<int32_t> next_tok;
std::vector<int> n_past;
};
struct StepLoopStats {
int n_steps = 0;
int64_t step_us = 0;
};
transcribe_status run_batched_step_loop(
transcribe_session * session,
ggml_backend_sched_t sched,
const StepBatchedIO & io,
int n_batch,
int max_n_kv,
int32_t eos_id,
int max_new,
const StepBatchedState & state,
std::vector<std::vector<int32_t>> & generated,
StepLoopStats * stats = nullptr,
std::vector<char> * truncated_out = nullptr);
}