This commit is contained in:
Xuan Son Nguyen
2026-08-01 16:13:06 +02:00
parent 511cc2fa0d
commit bfc0714ad3
4 changed files with 28 additions and 13 deletions
+1 -12
View File
@@ -1308,18 +1308,7 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
} else if (ex == LLAMA_EXAMPLE_TOKENIZE) {
params.parse_special = true; // parse special tokens by default, like the old tokenize tool
} else if (ex == LLAMA_EXAMPLE_TTS) {
params.n_ctx = 4096;
params.n_batch = 4096;
params.embedding = true; // the talker backbone's hidden states are read via llama_get_embeddings_ith
params.out_file = "output.wav";
params.tts_lang = "english";
// reference defaults (qwen_tts Qwen3TTSForConditionalGeneration.generate()):
// top_k=50, top_p=1.0, temperature=0.9, repetition_penalty=1.05 over the whole
// generated history -- without the penalty, runs degenerate into immediate
// no-speech (EOS) or endless non-terminating tails
params.sampling.top_k = 50;
params.sampling.top_p = 1.0f;
params.sampling.temp = 0.9f;
params.out_file = "output.wav";
params.sampling.penalty_repeat = 1.05f;
params.sampling.penalty_last_n = -1;
}
+1
View File
@@ -1025,6 +1025,7 @@ bool llm_arch_supports_sm_tensor(const llm_arch & arch) {
case LLM_ARCH_MINIMAX_M3:
case LLM_ARCH_MISTRAL4:
case LLM_ARCH_KIMI_LINEAR:
case LLM_ARCH_QWEN3TTS:
return false;
default:
return true;
+1 -1
View File
@@ -97,7 +97,7 @@ public:
return 1;
}
const std::string lang = inp->lang ? inp->lang : "english";
const std::string lang = (inp->lang && inp->lang[0]) ? inp->lang : "english";
const llama_token c_lang = find_special_token(vocab, ("<|codec_language_" + lang + "|>").c_str());
if (c_lang == LLAMA_TOKEN_NULL) {
LOG_ERR("mtmd_helper_gen_audio: unknown language '%s'\n", lang.c_str());
+25
View File
@@ -16,6 +16,22 @@
* For contributors: please keep this code simple and easy to understand. Do not add unnecessary complexity. The goal is to have a simple CLI for testing TTS support.
*/
struct tts_timings {
int64_t t_start_us = ggml_time_us();
int64_t t_last_us = t_start_us;
void report(int n_frames) {
const int64_t t_now_us = ggml_time_us();
if (t_now_us - t_last_us < 2000000) {
return;
}
t_last_us = t_now_us;
const double t_elapsed_s = (t_now_us - t_start_us) / 1e6;
const double fps = t_elapsed_s > 0 ? n_frames / t_elapsed_s : 0.0;
LOG_INF("frames generated: %d, speed: %.2f frames/s\n", n_frames, fps);
}
};
static void print_usage(int, char ** argv) {
LOG("\nexample usage:\n");
LOG("\n %s -m backbone.gguf -mm mmproj.gguf -p \"text to speak\" -o output.wav", argv[0]);
@@ -45,6 +61,9 @@ int main(int argc, char ** argv) {
return 1;
}
// always enable embd, so that we can pass hidden states to the audio generation helper
params.embedding = true;
llama_backend_init();
llama_numa_init(params.numa);
@@ -88,10 +107,12 @@ int main(int argc, char ** argv) {
inp.top_k = params.sampling.top_k;
inp.top_p = params.sampling.top_p;
inp.out_type = MTMD_HELPER_GEN_AUDIO_OUTTYPE_WAV;
const int64_t t_prompt_start_us = ggml_time_us();
if (gen.set_input(&inp) != 0) {
LOG_ERR("set_input failed\n");
return 1;
}
LOG_INF("prompt eval took %.2f seconds\n", (ggml_time_us() - t_prompt_start_us) / 1e6);
// codec_0 (backbone) EOS token: ordinary LLM sampling concern, kept out of the
// model-agnostic audio-generation helper
@@ -115,6 +136,9 @@ int main(int argc, char ** argv) {
int n_frames = 0;
llama_token sampled = sample_codec0();
const float * h_state = llama_get_embeddings_ith(lctx, -1);
tts_timings timings;
for (; n_frames < max_new && sampled != codec_eos_tok; n_frames++) {
const float * h_next = nullptr;
if (gen.step(sampled, h_state, &h_next) != 0) {
@@ -123,6 +147,7 @@ int main(int argc, char ** argv) {
}
h_state = h_next;
sampled = sample_codec0();
timings.report(n_frames + 1);
}
int32_t sample_rate = 0;