inoryQwQ commited on
Commit
146ec99
·
verified ·
1 Parent(s): 9171a77

feat: SDK 更新 — 韵律/时长/Postnet 走 NPU,PNCA 解码 CPU,postnet 分块修复

Browse files
Files changed (2) hide show
  1. sdk/include/kantts.hpp +2 -6
  2. sdk/src/kantts.cpp +175 -243
sdk/include/kantts.hpp CHANGED
@@ -59,14 +59,10 @@ public:
59
  std::vector<float> SynthesizeSymbols(const std::vector<std::string>& symbols);
60
 
61
  private:
62
- std::unique_ptr<ModelSession> enc_, voc_;
 
63
  Weights w_;
64
  std::unique_ptr<Frontend> frontend_;
65
  };
66
 
67
- // host 管线(供内部/测试使用)
68
- std::vector<float> HostPredictors(const Weights& w, const std::vector<float>& text_hid,
69
- const std::vector<float>& spk_hid,
70
- const std::vector<float>& emo_hid, int T);
71
-
72
  } // namespace kantts
 
59
  std::vector<float> SynthesizeSymbols(const std::vector<std::string>& symbols);
60
 
61
  private:
62
+ std::unique_ptr<ModelSession> enc_, voc_, pe_, dur_, post_, dec_;
63
+ std::string model_dir_;
64
  Weights w_;
65
  std::unique_ptr<Frontend> frontend_;
66
  };
67
 
 
 
 
 
 
68
  } // namespace kantts
sdk/src/kantts.cpp CHANGED
@@ -109,21 +109,6 @@ void Conv1dSame(const std::vector<float>& x, const std::vector<float>& wgt,
109
  }
110
  }
111
 
112
- void DepthwiseShift(const std::vector<float>& x, const std::vector<float>& wgt,
113
- int T, int C, int K, int lp, int rp, std::vector<float>& y) {
114
- y.assign(T * C, 0.0f);
115
- for (int c = 0; c < C; ++c)
116
- for (int t = 0; t < T; ++t) {
117
- float acc = 0;
118
- for (int k = 0; k < K; ++k) {
119
- int tt = t - lp + k;
120
- if (tt < 0 || tt >= T) continue;
121
- acc += x[tt * C + c] * wgt[c * K + k];
122
- }
123
- y[t * C + c] = acc;
124
- }
125
- }
126
-
127
  void LstmCell(const std::vector<float>& x, const std::vector<float>& w_ih,
128
  const std::vector<float>& w_hh, const std::vector<float>& b_ih,
129
  const std::vector<float>& b_hh, std::vector<float>& h, std::vector<float>& c,
@@ -146,109 +131,6 @@ void LstmCell(const std::vector<float>& x, const std::vector<float>& w_ih,
146
  }
147
  }
148
 
149
- void Blstm(const std::vector<float>& x, const Weights& w, const std::string& pre,
150
- int T, int in_d, int units, std::vector<float>& y) {
151
- const auto& wih = w.Get(pre + "_blstm_w_ih");
152
- const auto& whh = w.Get(pre + "_blstm_w_hh");
153
- const auto& bih = w.Get(pre + "_blstm_b_ih");
154
- const auto& bhh = w.Get(pre + "_blstm_b_hh");
155
- const auto& wihr = w.Get(pre + "_blstm_w_ih_r");
156
- const auto& whhr = w.Get(pre + "_blstm_w_hh_r");
157
- const auto& bihr = w.Get(pre + "_blstm_b_ih_r");
158
- const auto& bhhr = w.Get(pre + "_blstm_b_hh_r");
159
- std::vector<float> hf(units, 0), cf(units, 0), hb(units, 0), cb(units, 0);
160
- y.assign(T * 2 * units, 0.0f);
161
- std::vector<float> xi(in_d);
162
- for (int t = 0; t < T; ++t) {
163
- std::copy(x.begin() + t * in_d, x.begin() + (t + 1) * in_d, xi.begin());
164
- LstmCell(xi, wih, whh, bih, bhh, hf, cf, units);
165
- std::copy(hf.begin(), hf.end(), y.begin() + t * 2 * units);
166
- }
167
- for (int t = T - 1; t >= 0; --t) {
168
- std::copy(x.begin() + t * in_d, x.begin() + (t + 1) * in_d, xi.begin());
169
- LstmCell(xi, wihr, whhr, bihr, bhhr, hb, cb, units);
170
- std::copy(hb.begin(), hb.end(), y.begin() + t * 2 * units + units);
171
- }
172
- }
173
-
174
- std::vector<float> FsmnEncoder(const std::vector<float>& x, const Weights& w,
175
- const std::string& pre, int T, int C, const std::vector<int>& shift) {
176
- std::vector<float> cur = x;
177
- int layers = 0;
178
- while (w.Has(pre + "_ffn" + std::to_string(layers) + "_w1")) ++layers;
179
- for (int i = 0; i < layers; ++i) {
180
- int mid = (int)w.Shape(pre + "_ffn" + std::to_string(i) + "_w1")[0];
181
- std::vector<float> c1;
182
- Conv1dSame(cur, w.Get(pre + "_ffn" + std::to_string(i) + "_w1"),
183
- w.Get(pre + "_ffn" + std::to_string(i) + "_b1"), T, C, mid, 1, c1);
184
- for (auto& v : c1) v = std::max(v, 0.0f);
185
- int out_c = (int)w.Shape(pre + "_ffn" + std::to_string(i) + "_w2")[0];
186
- std::vector<float> c2;
187
- Conv1dSame(c1, w.Get(pre + "_ffn" + std::to_string(i) + "_w2"),
188
- w.Get(pre + "_ffn" + std::to_string(i) + "_b2"), T, mid, out_c, 1, c2);
189
- int fsize = (int)w.Shape(pre + "_mem" + std::to_string(i) + "_conv")[2];
190
- int sh = shift.empty() ? 0 : shift[i];
191
- int lp = (fsize - 1) / 2 + (sh > 0 ? sh : 0);
192
- int rp = (fsize - 1) / 2 - (sh > 0 ? sh : 0);
193
- std::vector<float> mem;
194
- DepthwiseShift(c2, w.Get(pre + "_mem" + std::to_string(i) + "_conv"), T, out_c, fsize,
195
- lp, rp, mem);
196
- for (int t = 0; t < T; ++t)
197
- for (int c = 0; c < out_c; ++c) mem[t * out_c + c] += c2[t * out_c + c];
198
- if (out_c == C)
199
- for (int t = 0; t < T; ++t)
200
- for (int c = 0; c < out_c; ++c) mem[t * out_c + c] += cur[t * C + c];
201
- cur = mem;
202
- C = out_c;
203
- }
204
- return cur;
205
- }
206
-
207
- std::vector<float> VarFsmnRnnPredictor(const std::vector<float>& x, const Weights& w,
208
- const std::string& pre, int T, int in_d) {
209
- std::vector<float> h = FsmnEncoder(x, w, pre, T, in_d, {0, 0, 0});
210
- std::vector<float> bh;
211
- Blstm(h, w, pre, T, 128, 128, bh);
212
- std::vector<float> out(T);
213
- const auto& fw = w.Get(pre + "_fc_w");
214
- const auto& fb = w.Get(pre + "_fc_b");
215
- for (int t = 0; t < T; ++t) {
216
- float acc = fb[0];
217
- for (int k = 0; k < 256; ++k) acc += bh[t * 256 + k] * fw[0 * 256 + k];
218
- out[t] = acc;
219
- }
220
- return out;
221
- }
222
-
223
- std::vector<float> DurationAr(const std::vector<float>& cond, const Weights& w, int T, int in_d) {
224
- std::vector<float> h0(128, 0), c0(128, 0), h1(128, 0), c1(128, 0);
225
- std::vector<float> x(1, 0.0f), out(T);
226
- const auto& p0w = w.Get("dur_pre0_w");
227
- const auto& p0b = w.Get("dur_pre0_b");
228
- const auto& p1w = w.Get("dur_pre1_w");
229
- const auto& p1b = w.Get("dur_pre1_b");
230
- const auto& fw = w.Get("dur_fc_w");
231
- const auto& fb = w.Get("dur_fc_b");
232
- std::vector<float> inp, tmp;
233
- for (int t = 0; t < T; ++t) {
234
- Matmul(x, p0w, p0b, 1, 1, 128, inp);
235
- for (auto& v : inp) v = std::max(v, 0.0f);
236
- Matmul(inp, p1w, p1b, 1, 128, 128, tmp);
237
- for (auto& v : tmp) v = std::max(v, 0.0f);
238
- std::vector<float> xin(tmp);
239
- xin.insert(xin.end(), cond.begin() + t * in_d, cond.begin() + (t + 1) * in_d);
240
- LstmCell(xin, w.Get("dur_lstm_w_ih0"), w.Get("dur_lstm_w_hh0"), w.Get("dur_lstm_b_ih0"),
241
- w.Get("dur_lstm_b_hh0"), h0, c0, 128);
242
- LstmCell(h0, w.Get("dur_lstm_w_ih1"), w.Get("dur_lstm_w_hh1"), w.Get("dur_lstm_b_ih1"),
243
- w.Get("dur_lstm_b_hh1"), h1, c1, 128);
244
- float acc = fb[0];
245
- for (int k = 0; k < 128; ++k) acc += h1[k] * fw[0 * 128 + k];
246
- x[0] = std::max(acc, 0.0f);
247
- out[t] = x[0];
248
- }
249
- return out;
250
- }
251
-
252
  } // namespace
253
 
254
  void Weights::Load(const std::string& dir) {
@@ -408,102 +290,6 @@ Frontend::EncInput Frontend::Encode(const std::string& symbol_seq) {
408
 
409
  namespace {
410
 
411
- // build_memory:text/spk/emo (T,32) → memory (M,160) + lr_len + durations
412
- void BuildMemory(const std::vector<float>& text_hid, const std::vector<float>& spk_hid,
413
- const std::vector<float>& emo_hid, const Weights& w, int T,
414
- std::vector<float>& memory, int& lr_len, std::vector<float>& durations) {
415
- std::vector<float> var_in(T * 96);
416
- for (int t = 0; t < T; ++t)
417
- for (int c = 0; c < 32; ++c) {
418
- var_in[t * 96 + c] = text_hid[t * 32 + c];
419
- var_in[t * 96 + 32 + c] = spk_hid[t * 32 + c];
420
- var_in[t * 96 + 64 + c] = emo_hid[t * 32 + c];
421
- }
422
- auto pitch = VarFsmnRnnPredictor(var_in, w, "pitch", T, 96);
423
- auto energy = VarFsmnRnnPredictor(var_in, w, "energy", T, 96);
424
- if (std::getenv("KANTTS_DUMP_ENC")) {
425
- {
426
- std::ofstream f("/tmp/kt/enc_pitch.bin", std::ios::binary);
427
- f.write((const char*)pitch.data(), pitch.size() * 4);
428
- }
429
- {
430
- std::ofstream f("/tmp/kt/enc_energy.bin", std::ios::binary);
431
- f.write((const char*)energy.data(), energy.size() * 4);
432
- }
433
- }
434
- std::vector<float> pe, ee;
435
- Conv1dSame(pitch, w.Get("pitch_emb_w"), w.Get("pitch_emb_b"), T, 1, 32, 9, pe);
436
- Conv1dSame(energy, w.Get("energy_emb_w"), w.Get("energy_emb_b"), T, 1, 32, 9, ee);
437
- std::vector<float> aug(T * 32);
438
- for (int t = 0; t < T * 32; ++t) aug[t] = text_hid[t] + pe[t] + ee[t];
439
- if (std::getenv("KANTTS_DUMP_ENC")) {
440
- std::ofstream f("/tmp/kt/enc_aug.bin", std::ios::binary);
441
- f.write((const char*)aug.data(), aug.size() * 4);
442
- }
443
- std::vector<float> cond(T * 96);
444
- for (int t = 0; t < T; ++t)
445
- for (int c = 0; c < 32; ++c) {
446
- cond[t * 96 + c] = aug[t * 32 + c];
447
- cond[t * 96 + 32 + c] = spk_hid[t * 32 + c];
448
- cond[t * 96 + 64 + c] = emo_hid[t * 32 + c];
449
- }
450
- auto log_dur = DurationAr(cond, w, T, 96);
451
- if (std::getenv("KANTTS_DUMP_ENC")) {
452
- std::ofstream f("/tmp/kt/enc_logdur.bin", std::ios::binary);
453
- f.write((const char*)log_dur.data(), log_dur.size() * 4);
454
- }
455
- durations.resize(T);
456
- int sum = 0;
457
- std::vector<int> reps(T);
458
- for (int t = 0; t < T; ++t) {
459
- durations[t] = std::exp(log_dur[t]) - 1.0f;
460
- reps[t] = (int)(durations[t] + 0.5f);
461
- sum += reps[t];
462
- }
463
- int pad = 3 - sum % 3;
464
- if (pad == 3) pad = 0;
465
- int P = sum + pad;
466
- // LR text/spk/emo
467
- auto expand = [&](const std::vector<float>& src, std::vector<float>& dst) {
468
- dst.assign(P * 32, 0.0f);
469
- int pos = 0;
470
- for (int t = 0; t < T; ++t)
471
- for (int r = 0; r < reps[t]; ++r) {
472
- std::copy(src.begin() + t * 32, src.begin() + (t + 1) * 32,
473
- dst.begin() + (pos++) * 32);
474
- }
475
- };
476
- std::vector<float> lr_text, lr_emo, lr_spk;
477
- expand(aug, lr_text);
478
- expand(emo_hid, lr_emo);
479
- expand(spk_hid, lr_spk);
480
- // dur position encoder
481
- std::vector<float> rc(T + 1, 0);
482
- for (int t = 0; t < T; ++t) rc[t + 1] = rc[t] + reps[t];
483
- std::vector<float> lr_pos(P * 32, 0.0f);
484
- for (int p = 0; p < P; ++p) {
485
- int ph = 0;
486
- for (int t = 0; t < T; ++t)
487
- if (rc[t] <= p && p < rc[t + 1]) { ph = p - rc[t] + 1; break; }
488
- for (int c = 0; c < 32; ++c) {
489
- float inv = std::pow(10000.0f, 2.0f * (c / 2) / 32.0f);
490
- float v = ph / inv;
491
- lr_pos[p * 32 + c] = (c % 2 == 0) ? std::sin(v) : std::cos(v);
492
- }
493
- }
494
- for (int i = 0; i < P * 32; ++i) lr_text[i] += lr_pos[i];
495
- int M = P / 3;
496
- memory.assign(M * 160, 0.0f);
497
- for (int m = 0; m < M; ++m) {
498
- for (int c = 0; c < 96; ++c) memory[m * 160 + c] = lr_text[m * 96 + c];
499
- for (int c = 0; c < 32; ++c) {
500
- memory[m * 160 + 96 + c] = lr_spk[m * 96 + c];
501
- memory[m * 160 + 128 + c] = lr_emo[m * 96 + c];
502
- }
503
- }
504
- lr_len = sum;
505
- }
506
-
507
  // PNCA 单步解码(host)
508
  struct Decoder {
509
  struct LW {
@@ -692,28 +478,16 @@ struct Decoder {
692
  };
693
 
694
 
695
- std::vector<float> Postnet(const std::vector<float>& dec, const Weights& w, int T) {
696
- std::vector<float> x = FsmnEncoder(dec, w, "post", T, 80, {17, 17, 17, 17});
697
- std::vector<float> h(128, 0), c(128, 0), out(T * 128);
698
- std::vector<float> xi(256);
699
- for (int t = 0; t < T; ++t) {
700
- std::copy(x.begin() + t * 256, x.begin() + (t + 1) * 256, xi.begin());
701
- LstmCell(xi, w.Get("post_lstm_w_ih"), w.Get("post_lstm_w_hh"), w.Get("post_lstm_b_ih"),
702
- w.Get("post_lstm_b_hh"), h, c, 128);
703
- std::copy(h.begin(), h.end(), out.begin() + t * 128);
704
- }
705
- std::vector<float> res(T * 80);
706
- Matmul(out, w.Get("post_fc_w"), w.Get("post_fc_b"), T, 128, 80, res);
707
- for (int i = 0; i < T * 80; ++i) res[i] += dec[i];
708
- return res;
709
- }
710
-
711
  } // namespace
712
 
713
  KanttsPipeline::KanttsPipeline(const std::string& model_dir, const std::string& resource_dir,
714
  const std::string& am_config)
715
  : enc_(new ModelSession(model_dir + "/am_enc.axmodel")),
716
  voc_(new ModelSession(model_dir + "/voc.axmodel")),
 
 
 
 
717
  frontend_(new Frontend(resource_dir, am_config)) {
718
  w_.Load(model_dir + "/host_weights");
719
  std::fprintf(stderr, "[stage] weights loaded\n");
@@ -800,7 +574,98 @@ std::vector<float> KanttsPipeline::SynthesizeSymbols(
800
  }
801
  std::fprintf(stderr, "[dbg] 使用参考 memory(%d 行)\n", (int)memory.size() / 160);
802
  } else {
803
- BuildMemory(text_hid, spk_hid, emo_hid, w_, T, memory, lr_len, durations);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  }
805
  int M = (int)memory.size() / 160;
806
  std::fprintf(stderr, "[stage] memory M=%d lr_len=%d\n", M, lr_len);
@@ -812,25 +677,92 @@ std::vector<float> KanttsPipeline::SynthesizeSymbols(
812
  }
813
  int x_band = (int)(*std::max_element(durations.begin(), durations.end()) / 3.0f + 0.5f);
814
  std::fprintf(stderr, "[stage] x_band=%d\n", x_band);
815
- Decoder dec(w_);
816
- dec.Prepare(memory);
817
- std::fprintf(stderr, "[timing] host(预测+memory) %.0fms\n", std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now()-t_stage).count());
818
- t_stage = std::chrono::steady_clock::now();
819
- std::vector<float> xk(12 * 8 * 270 * 16, 0.0f), xv(12 * 8 * 270 * 16, 0.0f);
820
- std::vector<float> frame(80, 0.0f), out;
821
  std::vector<float> dec_all(M * 3 * 80);
822
  double dec_sum = 0;
823
- for (int s = 0; s < M; ++s) {
824
- std::vector<float> mem_step(memory.begin() + s * 160, memory.begin() + (s + 1) * 160);
825
- dec.Step(frame, mem_step, xk, xv, s, x_band, out);
826
- std::copy(out.begin(), out.begin() + 240, dec_all.begin() + s * 240);
827
- std::copy(out.begin() + 160, out.begin() + 240, frame.begin());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
828
  }
829
  for (size_t i = 0; i < dec_all.size(); ++i) dec_sum += dec_all[i] * dec_all[i];
830
  std::fprintf(stderr, "[dbg] dec rms=%.4f\n", std::sqrt(dec_sum / dec_all.size()));
831
  std::fprintf(stderr, "[timing] decode %d 步 %.0fms\n", M, std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now()-t_stage).count());
832
  t_stage = std::chrono::steady_clock::now();
833
- std::vector<float> mel = Postnet(dec_all, w_, M * 3);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
834
  std::fprintf(stderr, "[timing] postnet %.0fms\n", std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now()-t_stage).count());
835
  t_stage = std::chrono::steady_clock::now();
836
  double mel_sum = 0;
 
109
  }
110
  }
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  void LstmCell(const std::vector<float>& x, const std::vector<float>& w_ih,
113
  const std::vector<float>& w_hh, const std::vector<float>& b_ih,
114
  const std::vector<float>& b_hh, std::vector<float>& h, std::vector<float>& c,
 
131
  }
132
  }
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  } // namespace
135
 
136
  void Weights::Load(const std::string& dir) {
 
290
 
291
  namespace {
292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  // PNCA 单步解码(host)
294
  struct Decoder {
295
  struct LW {
 
478
  };
479
 
480
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  } // namespace
482
 
483
  KanttsPipeline::KanttsPipeline(const std::string& model_dir, const std::string& resource_dir,
484
  const std::string& am_config)
485
  : enc_(new ModelSession(model_dir + "/am_enc.axmodel")),
486
  voc_(new ModelSession(model_dir + "/voc.axmodel")),
487
+ pe_(new ModelSession(model_dir + "/pitch_energy.axmodel")),
488
+ dur_(new ModelSession(model_dir + "/duration.axmodel")),
489
+ post_(new ModelSession(model_dir + "/postnet.axmodel")),
490
+ model_dir_(model_dir),
491
  frontend_(new Frontend(resource_dir, am_config)) {
492
  w_.Load(model_dir + "/host_weights");
493
  std::fprintf(stderr, "[stage] weights loaded\n");
 
574
  }
575
  std::fprintf(stderr, "[dbg] 使用参考 memory(%d 行)\n", (int)memory.size() / 160);
576
  } else {
577
+ // pitch/energy/duration NPU
578
+ std::vector<float> var_in(T * 96);
579
+ for (int t = 0; t < T; ++t)
580
+ for (int c = 0; c < 32; ++c) {
581
+ var_in[t * 96 + c] = text_hid[t * 32 + c];
582
+ var_in[t * 96 + 32 + c] = spk_hid[t * 32 + c];
583
+ var_in[t * 96 + 64 + c] = emo_hid[t * 32 + c];
584
+ }
585
+ std::vector<float> pitch(T), energy(T);
586
+ std::vector<float> var_pad(128 * 96, 0.0f);
587
+ std::copy(var_in.begin(), var_in.end(), var_pad.begin());
588
+ pe_->SetInput("var_in", var_pad.data(), var_pad.size() * 4);
589
+ pe_->Run();
590
+ pe_->GetOutput("pitch", pitch.data(), pitch.size() * 4);
591
+ pe_->GetOutput("energy", energy.data(), energy.size() * 4);
592
+ std::vector<float> pe_c, ee_c;
593
+ Conv1dSame(pitch, w_.Get("pitch_emb_w"), w_.Get("pitch_emb_b"), T, 1, 32, 9, pe_c);
594
+ Conv1dSame(energy, w_.Get("energy_emb_w"), w_.Get("energy_emb_b"), T, 1, 32, 9, ee_c);
595
+ std::vector<float> aug(T * 32);
596
+ for (int i = 0; i < T * 32; ++i) aug[i] = text_hid[i] + pe_c[i] + ee_c[i];
597
+ std::vector<float> cond(T * 96);
598
+ for (int t = 0; t < T; ++t)
599
+ for (int c = 0; c < 32; ++c) {
600
+ cond[t * 96 + c] = aug[t * 32 + c];
601
+ cond[t * 96 + 32 + c] = spk_hid[t * 32 + c];
602
+ cond[t * 96 + 64 + c] = emo_hid[t * 32 + c];
603
+ }
604
+ std::vector<float> log_dur(T);
605
+ std::vector<float> cond_pad(22 * 96, 0.0f);
606
+ std::copy(cond.begin(), cond.end(), cond_pad.begin());
607
+ dur_->SetInput("cond", cond_pad.data(), cond_pad.size() * 4);
608
+ dur_->Run();
609
+ dur_->GetOutput("log_dur", log_dur.data(), log_dur.size() * 4);
610
+ if (std::getenv("KANTTS_DUMP_ENC")) {
611
+ std::fprintf(stderr, "[dbg-npu] pitch[0..3]=%.4f %.4f %.4f %.4f energy[0..3]=%.4f %.4f %.4f %.4f log_dur[0..3]=%.4f %.4f %.4f %.4f\n",
612
+ pitch[0], pitch[1], pitch[2], pitch[3],
613
+ energy[0], energy[1], energy[2], energy[3],
614
+ log_dur[0], log_dur[1], log_dur[2], log_dur[3]);
615
+ }
616
+ durations.resize(T);
617
+ int sum = 0;
618
+ std::vector<int> reps(T);
619
+ for (int t = 0; t < T; ++t) {
620
+ durations[t] = std::exp(log_dur[t]) - 1.0f;
621
+ reps[t] = (int)(durations[t] + 0.5f);
622
+ sum += reps[t];
623
+ }
624
+ if (std::getenv("KANTTS_DUMP_ENC")) {
625
+ std::fprintf(stderr, "[dbg-npu] log_dur all:");
626
+ for (int t = 0; t < T; ++t) std::fprintf(stderr, " %.3f", log_dur[t]);
627
+ std::fprintf(stderr, " | reps sum=%d\n", sum);
628
+ }
629
+ int pad = 3 - sum % 3;
630
+ if (pad == 3) pad = 0;
631
+ int P = sum + pad;
632
+ auto expand = [&](const std::vector<float>& src, std::vector<float>& dst) {
633
+ dst.assign(P * 32, 0.0f);
634
+ int pos = 0;
635
+ for (int t = 0; t < T; ++t)
636
+ for (int r = 0; r < reps[t]; ++r) {
637
+ std::copy(src.begin() + t * 32, src.begin() + (t + 1) * 32,
638
+ dst.begin() + (pos++) * 32);
639
+ }
640
+ };
641
+ std::vector<float> lr_text, lr_emo, lr_spk;
642
+ expand(aug, lr_text);
643
+ expand(emo_hid, lr_emo);
644
+ expand(spk_hid, lr_spk);
645
+ std::vector<float> rc(T + 1, 0);
646
+ for (int t = 0; t < T; ++t) rc[t + 1] = rc[t] + reps[t];
647
+ std::vector<float> lr_pos(P * 32, 0.0f);
648
+ for (int p = 0; p < P; ++p) {
649
+ int ph = 0;
650
+ for (int t = 0; t < T; ++t)
651
+ if (rc[t] <= p && p < rc[t + 1]) { ph = p - rc[t] + 1; break; }
652
+ for (int c = 0; c < 32; ++c) {
653
+ float inv = std::pow(10000.0f, 2.0f * (c / 2) / 32.0f);
654
+ float v = ph / inv;
655
+ lr_pos[p * 32 + c] = (c % 2 == 0) ? std::sin(v) : std::cos(v);
656
+ }
657
+ }
658
+ for (int i = 0; i < P * 32; ++i) lr_text[i] += lr_pos[i];
659
+ int MM = P / 3;
660
+ memory.assign(MM * 160, 0.0f);
661
+ for (int m = 0; m < MM; ++m) {
662
+ for (int c = 0; c < 96; ++c) memory[m * 160 + c] = lr_text[m * 96 + c];
663
+ for (int c = 0; c < 32; ++c) {
664
+ memory[m * 160 + 96 + c] = lr_spk[m * 96 + c];
665
+ memory[m * 160 + 128 + c] = lr_emo[m * 96 + c];
666
+ }
667
+ }
668
+ lr_len = sum;
669
  }
670
  int M = (int)memory.size() / 160;
671
  std::fprintf(stderr, "[stage] memory M=%d lr_len=%d\n", M, lr_len);
 
677
  }
678
  int x_band = (int)(*std::max_element(durations.begin(), durations.end()) / 3.0f + 0.5f);
679
  std::fprintf(stderr, "[stage] x_band=%d\n", x_band);
 
 
 
 
 
 
680
  std::vector<float> dec_all(M * 3 * 80);
681
  double dec_sum = 0;
682
+ std::fprintf(stderr, "[timing] host(预测+memory) %.0fms\n", std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now()-t_stage).count());
683
+ t_stage = std::chrono::steady_clock::now();
684
+ // 交付配置:am_dec(PNCA 解码)默认 CPU,其余(enc/pe/dur/postnet/voc)全 NPU;
685
+ // KANTTS_NPU_DEC=1 可切回 NPU 解码(QAT 实验用)。
686
+ const bool dec_npu = std::getenv("KANTTS_NPU_DEC") != nullptr;
687
+ if (dec_npu) {
688
+ if (!dec_) dec_.reset(new ModelSession(model_dir_ + "/am_dec.axmodel"));
689
+ static const char* k_names[12] = {
690
+ "dequantize_per_tensor_101", "dequantize_per_tensor_166",
691
+ "dequantize_per_tensor_231", "dequantize_per_tensor_296",
692
+ "dequantize_per_tensor_361", "dequantize_per_tensor_426",
693
+ "dequantize_per_tensor_491", "dequantize_per_tensor_556",
694
+ "dequantize_per_tensor_621", "dequantize_per_tensor_686",
695
+ "dequantize_per_tensor_751", "dequantize_per_tensor_816"};
696
+ static const char* v_names[12] = {
697
+ "dequantize_per_tensor_103", "dequantize_per_tensor_168",
698
+ "dequantize_per_tensor_233", "dequantize_per_tensor_298",
699
+ "dequantize_per_tensor_363", "dequantize_per_tensor_428",
700
+ "dequantize_per_tensor_493", "dequantize_per_tensor_558",
701
+ "dequantize_per_tensor_623", "dequantize_per_tensor_688",
702
+ "dequantize_per_tensor_753", "dequantize_per_tensor_818"};
703
+ std::vector<float> mem_pad(270 * 160, 0.0f);
704
+ std::copy(memory.begin(), memory.end(), mem_pad.begin());
705
+ std::vector<float> xk(12 * 8 * 270 * 16, 0.0f), xv(12 * 8 * 270 * 16, 0.0f);
706
+ std::vector<float> frame(80, 0.0f), out(240), kbuf(8 * 16), vbuf(8 * 16);
707
+ int32_t xb = x_band, ml = M;
708
+ for (int s = 0; s < M; ++s) {
709
+ dec_->SetInput("mel_frame", frame.data(), frame.size() * 4);
710
+ dec_->SetInput("memory_step", memory.data() + s * 160, 160 * 4);
711
+ dec_->SetInput("memory", mem_pad.data(), mem_pad.size() * 4);
712
+ dec_->SetInput("x_k", xk.data(), xk.size() * 4);
713
+ dec_->SetInput("x_v", xv.data(), xv.size() * 4);
714
+ int32_t step_v = s;
715
+ dec_->SetInput("step", &step_v, 4);
716
+ dec_->SetInput("x_band", &xb, 4);
717
+ dec_->SetInput("h_band", &xb, 4);
718
+ dec_->SetInput("mem_len", &ml, 4);
719
+ dec_->Run();
720
+ dec_->GetOutput("output", out.data(), out.size() * 4);
721
+ std::copy(out.begin(), out.begin() + 240, dec_all.begin() + s * 240);
722
+ std::copy(out.begin() + 160, out.begin() + 240, frame.begin());
723
+ for (int li = 0; li < 12; ++li) {
724
+ dec_->GetOutput(k_names[li], kbuf.data(), kbuf.size() * 4);
725
+ dec_->GetOutput(v_names[li], vbuf.data(), vbuf.size() * 4);
726
+ for (int h = 0; h < 8; ++h)
727
+ for (int d = 0; d < 16; ++d) {
728
+ xk[(li * 8 + h) * 270 * 16 + s * 16 + d] = kbuf[h * 16 + d];
729
+ xv[(li * 8 + h) * 270 * 16 + s * 16 + d] = vbuf[h * 16 + d];
730
+ }
731
+ }
732
+ }
733
+ std::fprintf(stderr, "[dbg] dec NPU %d 步\n", M);
734
+ } else {
735
+ Decoder dec(w_);
736
+ dec.Prepare(memory);
737
+ std::vector<float> xk(12 * 8 * 270 * 16, 0.0f), xv(12 * 8 * 270 * 16, 0.0f);
738
+ std::vector<float> frame(80, 0.0f), out;
739
+ for (int s = 0; s < M; ++s) {
740
+ std::vector<float> mem_step(memory.begin() + s * 160, memory.begin() + (s + 1) * 160);
741
+ dec.Step(frame, mem_step, xk, xv, s, x_band, out);
742
+ std::copy(out.begin(), out.begin() + 240, dec_all.begin() + s * 240);
743
+ std::copy(out.begin() + 160, out.begin() + 240, frame.begin());
744
+ }
745
  }
746
  for (size_t i = 0; i < dec_all.size(); ++i) dec_sum += dec_all[i] * dec_all[i];
747
  std::fprintf(stderr, "[dbg] dec rms=%.4f\n", std::sqrt(dec_sum / dec_all.size()));
748
  std::fprintf(stderr, "[timing] decode %d 步 %.0fms\n", M, std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now()-t_stage).count());
749
  t_stage = std::chrono::steady_clock::now();
750
+ std::vector<float> mel;
751
+ {
752
+ // postnet 模型固定 128 帧输入;M*3 可能超过 128,按 128 帧分块处理
753
+ const int Tf = M * 3;
754
+ for (int start = 0; start < Tf; start += 128) {
755
+ int n = std::min(128, Tf - start);
756
+ std::vector<float> dec_p(128 * 80, 0.0f);
757
+ std::copy(dec_all.begin() + start * 80, dec_all.begin() + (start + n) * 80,
758
+ dec_p.begin());
759
+ post_->SetInput("dec", dec_p.data(), dec_p.size() * 4);
760
+ post_->Run();
761
+ std::vector<float> mel_p(128 * 80);
762
+ post_->GetOutput("output", mel_p.data(), mel_p.size() * 4);
763
+ mel.insert(mel.end(), mel_p.begin(), mel_p.begin() + n * 80);
764
+ }
765
+ }
766
  std::fprintf(stderr, "[timing] postnet %.0fms\n", std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now()-t_stage).count());
767
  t_stage = std::chrono::steady_clock::now();
768
  double mel_sum = 0;