| 568 | int64_t rows, |
| 569 | int64_t cols, |
| 570 | const std::string & name) { |
| 571 | if (rows <= 0 || cols <= 0 || static_cast<int64_t>(values.size()) != rows * cols) { |
| 572 | throw std::runtime_error("Vevo2 L2 row normalization shape mismatch: " + name); |
| 573 | } |
| 574 | for (int64_t row = 0; row < rows; ++row) { |
| 575 | double sum = 0.0; |
| 576 | const int64_t base = row * cols; |
| 577 | for (int64_t col = 0; col < cols; ++col) { |
| 578 | const float value = values[static_cast<size_t>(base + col)]; |
| 579 | sum += static_cast<double>(value) * static_cast<double>(value); |
| 580 | } |
| 581 | const double norm = std::sqrt(sum); |
| 582 | if (norm == 0.0) { |
| 583 | throw std::runtime_error("Vevo2 L2 row normalization found zero norm: " + name); |
| 584 | } |
| 585 | const float inv = static_cast<float>(1.0 / norm); |
| 586 | for (int64_t col = 0; col < cols; ++col) { |
| 587 | values[static_cast<size_t>(base + col)] *= inv; |
| 588 | } |
| 589 | } |
| 590 | return values; |
| 591 | } |
| 592 | |
| 593 | std::pair<std::vector<float>, std::vector<float>> load_whisper_stats( |
| 594 | const engine::assets::TensorSource & source, |
| 595 | int64_t whisper_dim) { |
| 596 | auto mean = source.require_f32("mean", {whisper_dim}); |
| 597 | auto std = source.require_f32("std", {whisper_dim}); |
| 598 | source.release_storage(); |
| 599 | return {std::move(mean), std::move(std)}; |
| 600 | } |
no test coverage detected