45 lines
1.8 KiB
C++
45 lines
1.8 KiB
C++
// Code Predictor (Qwen3-TTS) inference, extrait de
|
|
// /opt/Kazeia/kazeia-tts-decoder-ggml/src/cp_runner.cpp et exposé en API
|
|
// utilisable depuis tts_orchestrate. Architecture : transformer qwen3 5 couches,
|
|
// hidden 1024, GQA 16/8, head_dim 128, RMS eps 1e-6, RoPE NEOX theta=1e6.
|
|
// q_norm/k_norm AVANT RoPE (gotcha critique).
|
|
//
|
|
// Forward autoregressif RVQ : 15 passes pour produire CB1..CB15 depuis
|
|
// (hidden_Talker[1024], cb0_emb[1024]). Approche "recompute" (T<=16 -> coût
|
|
// quadratique négligeable, pas de KV cache manuel).
|
|
#pragma once
|
|
#include "sampler.h"
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
|
|
struct ggml_context;
|
|
struct ggml_tensor;
|
|
|
|
struct CPState {
|
|
ggml_context * weights_ctx = nullptr;
|
|
std::unordered_map<std::string, ggml_tensor*> tensors; // weights par nom
|
|
std::vector<float> heads; // [15, 2048, 1024] f32
|
|
std::vector<float> codec_embs; // [15, 2048, 1024] f32
|
|
int n_threads = 4;
|
|
// Sampler HF-style (rep_penalty + top_k + top_p + temperature). Par défaut = greedy
|
|
// (top_k=1 -> argmax). Pour TTS prod, configurer en {temp=0.9, top_k=50, rep_penalty=1.05}
|
|
// ce qui matche Python subtalker_*.
|
|
Sampler sampler = { /*temp=*/0.0f, /*top_k=*/1, /*top_p=*/1.0f, /*rep_penalty=*/1.0f,
|
|
/*rep_window=*/16, /*rng_state=*/1u, {} };
|
|
};
|
|
|
|
// Charge cp_f16.gguf + cp_heads.bin + cp_codec_embs.bin. Retourne false en cas d'échec.
|
|
bool cp_load(CPState& s, const char* gguf_path, const char* heads_path, const char* embs_path);
|
|
|
|
// Libère les ressources.
|
|
void cp_free(CPState& s);
|
|
|
|
// Prédit CB1..CB15 (15 codes int32) depuis le hidden state du Talker et l'embed de CB0.
|
|
// hidden : float[1024]
|
|
// cb0_emb: float[1024]
|
|
// out_codes : int32_t[15] (CB1..CB15)
|
|
void cp_predict(CPState& s, const float* hidden, const float* cb0_emb, int32_t* out_codes);
|
|
|