voice_audio_multi/tests/community_models/nemotron_transcribe/policy_test.cpp
Fabio c36510c21e
Some checks failed
Linux Build / Linux cpu (push) Has been cancelled
Linux Build / Linux cpu-clang (push) Has been cancelled
Linux Build / Linux vulkan (push) Has been cancelled
mac-build / macOS CPU (push) Has been cancelled
Nix Build / Nix (cpu) (push) Has been cancelled
Nix Build / Nix (vulkan) (push) Has been cancelled
windows-build / Windows CPU (push) Has been cancelled
Initial import: audio.cpp with Orange Pi documentation
2026-11-04 19:05:22 +01:00

107 lines
6.2 KiB
C++

#include "engine/community_models/nemotron_transcribe/encoder.h"
#include "engine/community_models/nemotron_transcribe/frontend.h"
#include "engine/community_models/nemotron_transcribe/assets.h"
#include "engine/community_models/nemotron_transcribe/session.h"
#include "engine/framework/runtime/errors.h"
#include <cmath>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <utility>
namespace model = engine::models::nemotron_transcribe;
void require(bool value, const char * message) {
if (!value) throw std::runtime_error(message);
}
template <typename F>
void invalid_audio(F action) {
try { action(); }
catch (const engine::runtime::InvalidRequestError &) { return; }
throw std::runtime_error("malformed input must produce a client error");
}
int main() {
try {
for (const auto & entry : std::vector<std::pair<std::string, std::string>>{
{"zh", "Chinese"}, {"zh-CN", "Chinese"}, {"ZH_cn", "Chinese"}, {" zh ", "Chinese"},
{"en-US", "English"}, {"pt_BR", "Portuguese"}, {"ja-JP", "Japanese"},
{"sv-SE", "Swedish"}, {"fil-PH", "Filipino"}, {"tl", "Filipino"},
{"nb-NO", "Norwegian"}, {"no", "Norwegian"}, {"fa", "Persian"}}) {
require(model::language_name(entry.first) == entry.second, "language tags must resolve to source-language names");
}
for (const auto & value : {"", "auto", "Chinese", "Mandarin", "und", "zz-ZZ", "zh-Hans-CN", "-CN", " Custom name "})
require(model::language_name(value) == value, "custom or unknown language names must remain unchanged");
require(model::is_near_silent({}), "empty native sample sequence");
require(model::is_near_silent(std::vector<float>(16000, 0.0F)), "digital silence");
require(model::is_near_silent(std::vector<float>(16000, 1e-6F)), "low energy noise floor");
require(!model::is_near_silent(std::vector<float>(16000, 1e-4F)), "RMS protects quiet delivery");
auto click = std::vector<float>(16000, 0.0F);
click[8000] = 0.001F;
require(!model::is_near_silent(click), "peak at threshold must pass through");
click[8000] = -0.001F;
require(!model::is_near_silent(click), "negative peak at threshold must pass through");
click[8000] = std::numeric_limits<float>::quiet_NaN();
require(!model::is_near_silent(click), "non-finite audio must reach frontend validation");
click[8000] = std::numeric_limits<float>::infinity();
require(!model::is_near_silent(click), "infinite audio must reach frontend validation");
model::EncoderConfig config;
const auto windows = model::plan_encoder_windows(360000, config);
int64_t frames = 0;
for (const auto & window : windows) {
require(window.core_frames > 0 && window.core_frames <= 500, "bounded native encoder windows");
frames += window.core_frames;
}
require(windows.size() == 90 && frames == 45000, "one-hour geometry must cover every frame exactly once");
engine::runtime::AudioBuffer mono{16000, 1, std::vector<float>(160, 0.1F)};
require(!model::normalize_input_audio(mono), "matched input must not allocate or resample");
engine::runtime::AudioBuffer stereo{48000, 2, std::vector<float>(960)};
for (size_t i = 0; i < 480; ++i) {
stereo.samples[2 * i] = 0.1F;
stereo.samples[2 * i + 1] = 0.2F;
}
require(std::abs(model::validate_input_audio(stereo) - 0.01) < 1e-12,
"duration uses per-channel frames in the original rate");
const auto converted = model::normalize_input_audio(stereo);
require(converted && converted->channels == 1 && converted->sample_rate == 16000 &&
converted->samples.size() == 160, "48 kHz stereo must become 16 kHz mono");
require(std::isfinite(converted->samples[80]) && std::abs(converted->samples[80] - 0.15F) < 0.01F,
"channel averaging must preserve the signal scale");
invalid_audio([&] { model::validate_input_audio(stereo, 0.009); });
invalid_audio([&] { model::validate_input_audio({0, 1, {0.1F}}); });
invalid_audio([&] { model::validate_input_audio({16000, 0, {0.1F}}); });
invalid_audio([&] { model::validate_input_audio({16000, 2, {0.1F}}); });
invalid_audio([&] { model::normalize_input_audio({16000, 1, {std::numeric_limits<float>::infinity()}}); });
using Storage = engine::assets::TensorStorageType;
const std::vector<engine::assets::TensorMetadata> experts{
{"blk.1.ffn_up_exps.weight", "IQ4_NL", {128, 1856, 2688}},
{"blk.1.ffn_down_exps.weight", "IQ4_NL", {128, 2688, 1856}}};
const auto native = model::estimate_transcribe_weight_bytes(experts, Storage::Native);
require(model::estimate_transcribe_weight_bytes(experts, Storage::Native, 8) == native / 16,
"offload residency must price eight slots rather than 128 experts");
const auto expanded = model::estimate_transcribe_weight_bytes(experts, Storage::F32);
require(expanded == size_t(2) * 128 * 1856 * 2688 * 4 && expanded > 6 * native,
"F32 residency must reflect expanded routed expert banks");
require(model::estimate_transcribe_weight_bytes({{"odd", "F16", {8, 17}}}, Storage::Q8_0) == 8 * 17 * 4,
"unaligned Q8 rows must price the framework's F32 fallback");
require(model::estimate_transcribe_weight_bytes({{"ctc.test", "F16", {8, 32}}}, Storage::F16) == 8 * 32 * 4,
"CTC parameters stay F32");
bool rejected = false;
try { model::transcribe_weight_type("q4_k"); }
catch (const std::runtime_error &) { rejected = true; }
require(rejected, "unadvertised session storage must be rejected");
rejected = false;
try { model::estimate_transcribe_weight_bytes({{"huge", "F32", {
std::numeric_limits<int64_t>::max(), std::numeric_limits<int64_t>::max()}}}, Storage::F32); }
catch (const std::runtime_error &) { rejected = true; }
require(rejected, "resource estimate overflow must fail before allocation");
} catch (const std::exception & error) {
std::cerr << error.what() << '\n';
return 1;
}
std::cout << "Nemotron Transcribe silence and window policy checks passed\n";
}