From 0a41206e1f2f6649fca2d7a14a214e959e699175 Mon Sep 17 00:00:00 2001 From: tzhouam Date: Wed, 23 Sep 2026 23:01:22 +0800 Subject: [PATCH] Add Omni MiniCPM-o GGUF whole-session CPU and Radeon paths --- .../experiments/probe_omni_minicpmo_cpp.py | 158 ++++++ .../results/e2e_expansion_20260923/README.md | 4 +- .../evidence/minicpmo_omni_cpp/README.md | 64 +++ .../evidence/minicpmo_omni_cpp/cpu_output.wav | Bin 0 -> 107564 bytes .../minicpmo_omni_cpp/cpu_report.json | 153 ++++++ .../llama_cpp_omni_bounded.patch | 156 ++++++ ...pmo-1-478e965280734397918e5b3687e11006.log | 469 +++++++++++++++++ ...pmo-2-7fa1ace55f734e678e7e76f56d6bdf9d.log | 19 + ...pmo-1-fec5accd5f8b463f8e62252d7a31c927.log | 479 +++++++++++++++++ ...pmo-2-53637554493b4b38af27b722dc48ad51.log | 1 + .../minicpmo_omni_cpp/low_budget_report.json | 45 ++ .../minicpmo_omni_cpp/radeon_output.wav | Bin 0 -> 124844 bytes .../minicpmo_omni_cpp/radeon_report.json | 153 ++++++ .../evidence/summary/README.md | 10 +- vllm_omni/config/pipeline_registry.py | 6 +- vllm_omni/engine/backends/__init__.py | 4 + vllm_omni/engine/backends/minicpmo_cpp.py | 496 ++++++++++++++++++ .../models/minicpmo_4_5/pipeline.py | 18 + 18 files changed, 2228 insertions(+), 7 deletions(-) create mode 100644 benchmarks/edge_harness/experiments/probe_omni_minicpmo_cpp.py create mode 100644 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/README.md create mode 100644 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/cpu_output.wav create mode 100644 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/cpu_report.json create mode 100644 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/llama_cpp_omni_bounded.patch create mode 100755 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_cpu/minicpmo-1-478e965280734397918e5b3687e11006.log create mode 100755 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_cpu/minicpmo-2-7fa1ace55f734e678e7e76f56d6bdf9d.log create mode 100755 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_radeon/minicpmo-1-fec5accd5f8b463f8e62252d7a31c927.log create mode 100755 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_radeon/minicpmo-2-53637554493b4b38af27b722dc48ad51.log create mode 100644 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/low_budget_report.json create mode 100644 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/radeon_output.wav create mode 100644 benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/radeon_report.json create mode 100644 vllm_omni/engine/backends/minicpmo_cpp.py diff --git a/benchmarks/edge_harness/experiments/probe_omni_minicpmo_cpp.py b/benchmarks/edge_harness/experiments/probe_omni_minicpmo_cpp.py new file mode 100644 index 000000000..2df3f1acb --- /dev/null +++ b/benchmarks/edge_harness/experiments/probe_omni_minicpmo_cpp.py @@ -0,0 +1,158 @@ +#!/usr/bin/env python3 +"""Run a pinned audio+image→text+speech MiniCPM-o GGUF request through Omni. + +The single C++ process owns the whole session. This probe records complete +request latency; it does not claim incremental speech streaming. +""" + +from __future__ import annotations + +import argparse +import asyncio +import hashlib +import json +import time +import wave +from pathlib import Path +from types import SimpleNamespace + + +async def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + for name in ("model-dir", "cli-bin", "reference-wav", "audio-wav", "image-jpeg", + "artifact-report", "work-root", "log-root", "output-report", "output-wav"): + parser.add_argument(f"--{name}", type=Path, required=True) + parser.add_argument("--cli-sha256", required=True) + parser.add_argument("--placement", choices=("cpu", "radeon-hybrid"), required=True) + parser.add_argument("--reserve-gib", type=int, default=24) + parser.add_argument("--capacity-gib", type=int, default=30) + parser.add_argument("--abort-check", action="store_true") + parser.add_argument("--expect-admission-refusal", action="store_true") + args = parser.parse_args() + + from vllm_omni.config.stage_config import DeployConfig, StageDeployConfig, merge_pipeline_deploy + from vllm_omni.engine.stage_runtime import StageRuntime + from vllm_omni.model_executor.models.minicpmo_4_5.pipeline import MINICPMO_4_5_GGUF_WHOLE_PIPELINE + + source = json.loads(args.artifact_report.read_text(encoding="utf-8")) + reference_hash = hashlib.sha256(args.reference_wav.read_bytes()).hexdigest() + inputs = {"audio_wav": args.audio_wav.read_bytes(), "image_jpeg": args.image_jpeg.read_bytes()} + backend = { + "name": "external.minicpmo.gguf.v1", + "placement": args.placement, + "ggml_vk_visible_devices": "1" if args.placement == "radeon-hybrid" else None, + "expected_gpu_name": "AMD Radeon(TM) 890M Graphics" if args.placement == "radeon-hybrid" else None, + "model_dir": str(args.model_dir), + "model_revision": source["model_revision"], + "artifact_sha256": {name: data["sha256"] for name, data in source["artifacts"].items()}, + "cli_bin": str(args.cli_bin), "cli_sha256": args.cli_sha256, + "reference_wav": str(args.reference_wav), "reference_sha256": reference_hash, + "work_root": str(args.work_root), "log_root": str(args.log_root), + "memory_overhead_bytes": 12 << 30, + "context_tokens": 2048, "max_new_tokens": 96, + "max_input_bytes": 2 << 20, "max_wav_bytes": 2 << 20, + "max_text_bytes": 16 << 10, "max_work_bytes": 64 << 20, + "max_input_audio_s": 10, "max_output_audio_s": 20, + "request_timeout_s": 240, "t2w_wait_seconds": 180, + } + budget = {"capacities": {"host_ram": args.capacity_gib << 30}, + "demands": {"host_ram": args.reserve_gib << 30}} + deploy = DeployConfig(async_chunk=False, stages=[StageDeployConfig( + stage_id=0, backend=backend, resource_budget=budget, + )]) + configs = [item.to_omegaconf() for item in merge_pipeline_deploy( + MINICPMO_4_5_GGUF_WHOLE_PIPELINE, deploy, + )] + runtime = StageRuntime(configs, "local-minicpmo-gguf", "", stage_init_timeout=180, + async_chunk=False) + report = {"scope": "MiniCPM-o GGUF complete audio+image→text+speech through Omni StageRuntime/StagePool", + "placement": args.placement, "model_revision": source["model_revision"], + "artifact_sha256": backend["artifact_sha256"], + "cli_sha256": args.cli_sha256, "reference_sha256": reference_hash, + "input_sha256": {key: hashlib.sha256(value).hexdigest() for key, value in inputs.items()}, + "memory_budget": budget, "profile_count": 1, "warmup_count": 0} + try: + started = time.perf_counter() + if args.expect_admission_refusal: + try: + runtime.initialize() + except Exception as exc: + if "exceed reservation" not in str(exc): + raise + report["admission_refusal"] = f"{type(exc).__name__}: {exc}" + report["status"] = "passed" + return + raise AssertionError("MiniCPM-o accepted an insufficient memory reservation") + runtime.initialize() + report["startup_s"] = time.perf_counter() - started + pool = runtime.stage_pools[0] + report["execution_plan_at_start"] = dict(pool.stage_client.execution_plan) + state = SimpleNamespace(sampling_params_list=[None]) + + async def request_one(request_id: str): + started = time.perf_counter() + await pool.submit_initial(request_id, state, inputs) + deadline = time.monotonic() + 250 + while True: + output = pool.poll_graph_output(0) + if output is not None: + break + if time.monotonic() >= deadline: + raise TimeoutError("MiniCPM-o Omni output timed out") + await asyncio.sleep(0.01) + try: + if output.error: + raise RuntimeError(output.error) + completion = output.outputs[0] + metadata = output.custom_output["audio_metadata"] + pcm = (completion.multimodal_output["audio"].numpy() * 32768).astype("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 Kk^ld{*Z%{#GhGt^ literal 0 HcmV?d00001 diff --git a/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/cpu_report.json b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/cpu_report.json new file mode 100644 index 000000000..2cd82301d --- /dev/null +++ b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/cpu_report.json @@ -0,0 +1,153 @@ +{ + "scope": "MiniCPM-o GGUF complete audio+image\u2192text+speech through Omni StageRuntime/StagePool", + "placement": "cpu", + "model_revision": "db25077c33951fe163b42986fba0132e279872a2", + "artifact_sha256": { + "MiniCPM-o-4_5-Q4_K_M.gguf": "1237a97ee081b8abebc47aa7dad565701e8f5f904cdc92f6723ac4281bbc0932", + "audio/MiniCPM-o-4_5-audio-F16.gguf": "d5b188ac7feaf98e17175c3f9bd14bf269301bfd187439fdaa3e3a494fc32ef7", + "vision/MiniCPM-o-4_5-vision-F16.gguf": "1453678cc4e4fe18de241952962e234f265cb8dda780773526103ab8ba82f421", + "tts/MiniCPM-o-4_5-tts-F16.gguf": "c7be3748a863dd6966ae7eed42600b7f41ca67affb03729ff245247f0e5ea088", + "tts/MiniCPM-o-4_5-projector-F16.gguf": "4b1b5b377358a5e594a304ff6ea5d52df606a9ba7d886c4299d232f0c67dd1fd", + "token2wav-gguf/encoder.gguf": "7f8d265da594eaf5e1de2db8f5f1867dbcb0bb75ef5878fadf2952347116f4d0", + "token2wav-gguf/flow_matching.gguf": "eda6069f3edeb5dd3a87fbf2aedb2ddd1b46f3273926c4fcf09b24476a39cab8", + "token2wav-gguf/flow_extra.gguf": "c67611aa7d02500fe395a7798bf0bfdfb55c74d37ba93934ca74d82b4e63f78d", + "token2wav-gguf/hifigan2.gguf": "1b8b3bf5d8d3066aeee4324fdcdd41aefce170d0ee907645858de408d82835c2", + "token2wav-gguf/prompt_cache.gguf": "81fe6f541ebe0b67db06a1e395df928da47991dc9637c2cf47d6c59d5b979f2c" + }, + "cli_sha256": "29247187ddf3b13591cd14cc070e5e25c6bb7547296acc5e8a74e2945811d725", + "reference_sha256": "cf4bb5cd9acbfbf67596d4a53310652b61ef4b7ede1d54eb03ef4882ca40223a", + "input_sha256": { + "audio_wav": "14ee147cbf2ce9afd9e32c8c8228d7cfe11985cd7e63456b2ad33871492aefcc", + "image_jpeg": "22c7ccea466a3f551c512045e6316c7597408d4e0a20205502f55784d977aa8d" + }, + "memory_budget": { + "capacities": { + "host_ram": 32212254720 + }, + "demands": { + "host_ram": 25769803776 + } + }, + "profile_count": 1, + "warmup_count": 0, + "startup_s": 6.932118400000036, + "execution_plan_at_start": { + "backend": "external.minicpmo.gguf.v1", + "stage_id": 0, + "worker_generation": "506f17f8d6044e468f18ff8a6bee5466", + "model_revision": "db25077c33951fe163b42986fba0132e279872a2", + "artifact_sha256": { + "MiniCPM-o-4_5-Q4_K_M.gguf": "1237a97ee081b8abebc47aa7dad565701e8f5f904cdc92f6723ac4281bbc0932", + "audio/MiniCPM-o-4_5-audio-F16.gguf": "d5b188ac7feaf98e17175c3f9bd14bf269301bfd187439fdaa3e3a494fc32ef7", + "vision/MiniCPM-o-4_5-vision-F16.gguf": "1453678cc4e4fe18de241952962e234f265cb8dda780773526103ab8ba82f421", + "tts/MiniCPM-o-4_5-tts-F16.gguf": "c7be3748a863dd6966ae7eed42600b7f41ca67affb03729ff245247f0e5ea088", + "tts/MiniCPM-o-4_5-projector-F16.gguf": "4b1b5b377358a5e594a304ff6ea5d52df606a9ba7d886c4299d232f0c67dd1fd", + "token2wav-gguf/encoder.gguf": "7f8d265da594eaf5e1de2db8f5f1867dbcb0bb75ef5878fadf2952347116f4d0", + "token2wav-gguf/flow_matching.gguf": "eda6069f3edeb5dd3a87fbf2aedb2ddd1b46f3273926c4fcf09b24476a39cab8", + "token2wav-gguf/flow_extra.gguf": "c67611aa7d02500fe395a7798bf0bfdfb55c74d37ba93934ca74d82b4e63f78d", + "token2wav-gguf/hifigan2.gguf": "1b8b3bf5d8d3066aeee4324fdcdd41aefce170d0ee907645858de408d82835c2", + "token2wav-gguf/prompt_cache.gguf": "81fe6f541ebe0b67db06a1e395df928da47991dc9637c2cf47d6c59d5b979f2c" + }, + "cli_sha256": "29247187ddf3b13591cd14cc070e5e25c6bb7547296acc5e8a74e2945811d725", + "requested_placement": "cpu", + "ggml_vk_visible_devices": null, + "shared_ram_reservation": { + "host_ram": 25769803776 + }, + "weights_bytes": 8872297088, + "memory_overhead_bytes": 12884901888, + "context_tokens": 2048, + "max_new_tokens": 96, + "request_capacity": 1, + "stateful_session": "C++-owned within one request; discarded after completion", + "placement_evidence": "pending first request" + }, + "complete_request": { + "text": "The square in the image is red.", + "wall_s": 24.338328399928287, + "audio_metadata": { + "sample_rate_hz": 24000, + "channels": 1, + "pcm_frames": 53760, + "duration_s": 2.24, + "pcm_sha256": "e4366dbc55177d11b2a8902c07685fcff2d3412abfaa3feb85b095672484f141" + }, + "stage_event": { + "request_id": "minicpmo-1", + "stage_id": 0, + "epoch": 1, + "seq": 1, + "kind": "audio", + "worker_generation": "506f17f8d6044e468f18ff8a6bee5466", + "buffers": [], + "terminal": true, + "error": null + }, + "metrics": { + "minicpmo_whole_request_wall_s": 24.305023799999617, + "peak_sampled_rss_bytes": 13107023872, + "worker_log": "C:\\Users\\zhout\\w2\\minicpmo_omni_logs_cpu\\minicpmo-1-478e965280734397918e5b3687e11006.log" + } + }, + "output_wav": "\\\\wsl.localhost\\Ubuntu\\home\\zhout\\project\\edge_infer\\vllm-omni-edge\\benchmarks\\edge_harness\\results\\e2e_expansion_20260923\\evidence\\minicpmo_omni_cpp\\cpu_output.wav", + "execution_plan_after_request": { + "backend": "external.minicpmo.gguf.v1", + "stage_id": 0, + "worker_generation": "506f17f8d6044e468f18ff8a6bee5466", + "model_revision": "db25077c33951fe163b42986fba0132e279872a2", + "artifact_sha256": { + "MiniCPM-o-4_5-Q4_K_M.gguf": "1237a97ee081b8abebc47aa7dad565701e8f5f904cdc92f6723ac4281bbc0932", + "audio/MiniCPM-o-4_5-audio-F16.gguf": "d5b188ac7feaf98e17175c3f9bd14bf269301bfd187439fdaa3e3a494fc32ef7", + "vision/MiniCPM-o-4_5-vision-F16.gguf": "1453678cc4e4fe18de241952962e234f265cb8dda780773526103ab8ba82f421", + "tts/MiniCPM-o-4_5-tts-F16.gguf": "c7be3748a863dd6966ae7eed42600b7f41ca67affb03729ff245247f0e5ea088", + "tts/MiniCPM-o-4_5-projector-F16.gguf": "4b1b5b377358a5e594a304ff6ea5d52df606a9ba7d886c4299d232f0c67dd1fd", + "token2wav-gguf/encoder.gguf": "7f8d265da594eaf5e1de2db8f5f1867dbcb0bb75ef5878fadf2952347116f4d0", + "token2wav-gguf/flow_matching.gguf": "eda6069f3edeb5dd3a87fbf2aedb2ddd1b46f3273926c4fcf09b24476a39cab8", + "token2wav-gguf/flow_extra.gguf": "c67611aa7d02500fe395a7798bf0bfdfb55c74d37ba93934ca74d82b4e63f78d", + "token2wav-gguf/hifigan2.gguf": "1b8b3bf5d8d3066aeee4324fdcdd41aefce170d0ee907645858de408d82835c2", + "token2wav-gguf/prompt_cache.gguf": "81fe6f541ebe0b67db06a1e395df928da47991dc9637c2cf47d6c59d5b979f2c" + }, + "cli_sha256": "29247187ddf3b13591cd14cc070e5e25c6bb7547296acc5e8a74e2945811d725", + "requested_placement": "cpu", + "ggml_vk_visible_devices": null, + "shared_ram_reservation": { + "host_ram": 25769803776 + }, + "weights_bytes": 8872297088, + "memory_overhead_bytes": 12884901888, + "context_tokens": 2048, + "max_new_tokens": 96, + "request_capacity": 1, + "stateful_session": "C++-owned within one request; discarded after completion", + "placement_evidence": { + "observed": "cpu", + "worker_pid": 66164, + "peak_sampled_rss_bytes": 13107023872, + "worker_log": "C:\\Users\\zhout\\w2\\minicpmo_omni_logs_cpu\\minicpmo-1-478e965280734397918e5b3687e11006.log" + } + }, + "abort_check": { + "stale_output": false, + "ledger": { + "capacities": { + "host_ram": 32212254720 + }, + "reserved": { + "host_ram": 0 + }, + "owners": [], + "quarantined": [] + } + }, + "status": "passed", + "ledger_after_shutdown": { + "capacities": { + "host_ram": 32212254720 + }, + "reserved": { + "host_ram": 0 + }, + "owners": [], + "quarantined": [] + } +} diff --git a/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/llama_cpp_omni_bounded.patch b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/llama_cpp_omni_bounded.patch new file mode 100644 index 000000000..a52ad2d80 --- /dev/null +++ b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/llama_cpp_omni_bounded.patch @@ -0,0 +1,156 @@ +diff --git a/tools/omni/omni-cli.cpp b/tools/omni/omni-cli.cpp +index 2e9623a..2b657a8 100644 +--- a/tools/omni/omni-cli.cpp ++++ b/tools/omni/omni-cli.cpp +@@ -11,6 +11,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -60,7 +61,10 @@ static void show_usage(const char * prog_name) { + " --projector Override projector model path\n" + " --ref-audio Reference audio for voice cloning (default: tools/omni/assets/default_ref_audio/default_ref_audio.wav)\n" + " -c, --ctx-size Context size (default: 4096)\n" ++ " --max-new-tokens Bound language generation to n tokens (default: context size)\n" + " -ngl Number of GPU layers (default: 99)\n" ++ " --t2w-device Token2Wav device: cpu or gpu: (default: gpu:0)\n" ++ " --t2w-wait-seconds Fail if async audio is incomplete after n seconds (default: 120)\n" + " --no-tts Disable TTS output\n" + " --omni Enable omni mode (audio + vision, media_type=2)\n" + " --vision-backend Vision compute backend: 'metal' (default) or 'coreml' (ANE)\n" +@@ -208,7 +212,10 @@ int main(int argc, char ** argv) { + std::string vision_coreml_model_path; // CoreML model path (required when vision_backend=coreml) + std::string ref_audio_path = "tools/omni/assets/default_ref_audio/default_ref_audio.wav"; + int n_ctx = 4096; ++ int max_new_tokens = -1; + int n_gpu_layers = 99; // GPU 层数,默认 99 ++ std::string token2wav_device = "gpu:0"; ++ int token2wav_wait_seconds = 120; + int media_type = 1; // 1=audio only, 2=omni (audio+vision) + bool use_tts = true; + bool run_test = false; +@@ -244,9 +251,30 @@ int main(int argc, char ** argv) { + else if ((arg == "-c" || arg == "--ctx-size") && i + 1 < argc) { + n_ctx = std::atoi(argv[++i]); + } ++ else if (arg == "--max-new-tokens" && i + 1 < argc) { ++ max_new_tokens = std::atoi(argv[++i]); ++ if (max_new_tokens < 1 || max_new_tokens >= n_ctx) { ++ fprintf(stderr, "Error: --max-new-tokens must be 1..ctx-size-1\n"); ++ return 1; ++ } ++ } + else if (arg == "-ngl" && i + 1 < argc) { + n_gpu_layers = std::atoi(argv[++i]); + } ++ else if (arg == "--t2w-device" && i + 1 < argc) { ++ token2wav_device = argv[++i]; ++ if (token2wav_device != "cpu" && token2wav_device.rfind("gpu:", 0) != 0) { ++ fprintf(stderr, "Error: --t2w-device must be cpu or gpu:\n"); ++ return 1; ++ } ++ } ++ else if (arg == "--t2w-wait-seconds" && i + 1 < argc) { ++ token2wav_wait_seconds = std::atoi(argv[++i]); ++ if (token2wav_wait_seconds < 1 || token2wav_wait_seconds > 3600) { ++ fprintf(stderr, "Error: --t2w-wait-seconds must be 1..3600\n"); ++ return 1; ++ } ++ } + else if (arg == "--no-tts") { + use_tts = false; + } +@@ -276,6 +304,10 @@ int main(int argc, char ** argv) { + } + + // 检查必需参数 ++ if (max_new_tokens >= n_ctx) { ++ fprintf(stderr, "Error: --max-new-tokens must be below ctx-size\n"); ++ return 1; ++ } + if (llm_path.empty()) { + fprintf(stderr, "Error: -m is required\n\n"); + show_usage(argv[0]); +@@ -322,6 +354,9 @@ int main(int argc, char ** argv) { + params.vision_coreml_model_path = vision_coreml_model_path; + } + params.n_ctx = n_ctx; ++ if (max_new_tokens > 0) { ++ params.n_predict = max_new_tokens; ++ } + params.n_gpu_layers = n_gpu_layers; + + // Projector 路径需要通过 tts_bin_dir 传递 +@@ -339,6 +374,7 @@ int main(int argc, char ** argv) { + printf(" TTS enabled: %s\n", use_tts ? "yes" : "no"); + printf(" Context size: %d\n", n_ctx); + printf(" GPU layers: %d\n", n_gpu_layers); ++ printf(" Token2Wav device: %s\n", token2wav_device.c_str()); + printf(" Vision backend: %s\n", vision_backend.c_str()); + if (vision_backend == "coreml") { + printf(" Vision CoreML: %s\n", vision_coreml_model_path.c_str()); +@@ -347,7 +383,8 @@ int main(int argc, char ** argv) { + printf(" Ref audio: %s\n", ref_audio_path.c_str()); + + // 🔧 Token2Wav 使用 GPU(Metal),已用 ggml_add+ggml_repeat 替代不支持的 ggml_add1 +- auto ctx_omni = omni_init(¶ms, media_type, use_tts, tts_bin_dir, -1, "gpu:0"); ++ auto ctx_omni = omni_init(¶ms, media_type, use_tts, tts_bin_dir, ++ token2wav_device == "cpu" ? 0 : -1, token2wav_device); + if (ctx_omni == nullptr) { + fprintf(stderr, "Error: Failed to initialize omni context\n"); + return 1; +@@ -366,13 +403,19 @@ int main(int argc, char ** argv) { + } + + // 等待 T2W 完成所有音频生成后再停止线程 ++ bool audio_complete = true; + if(ctx_omni->async && ctx_omni->use_tts) { + std::string done_flag = std::string(ctx_omni->base_output_dir) + "/round_000/tts_wav/generation_done.flag"; + fprintf(stderr, "Waiting for audio generation to complete...\n"); +- for (int i = 0; i < 1200; ++i) { // 最多等 120 秒 ++ audio_complete = false; ++ for (int i = 0; i < token2wav_wait_seconds * 10; ++i) { + FILE * f = fopen(done_flag.c_str(), "r"); +- if (f) { fclose(f); fprintf(stderr, "Audio generation completed.\n"); break; } +- usleep(100000); // 100ms ++ if (f) { fclose(f); audio_complete = true; fprintf(stderr, "Audio generation completed.\n"); break; } ++ std::this_thread::sleep_for(std::chrono::milliseconds(100)); ++ } ++ if (!audio_complete) { ++ fprintf(stderr, "Error: audio generation did not complete within %d seconds.\n", ++ token2wav_wait_seconds); + } + } + +@@ -386,5 +429,8 @@ int main(int argc, char ** argv) { + llama_perf_context_print(ctx_omni->ctx_llama); + + omni_free(ctx_omni); ++ if (!audio_complete) { ++ return 2; ++ } + return 0; + } +diff --git a/tools/omni/omni.h b/tools/omni/omni.h +index 145f515..b35c459 100644 +--- a/tools/omni/omni.h ++++ b/tools/omni/omni.h +@@ -13,7 +13,7 @@ + #include + + // Windows compatibility: pid_t is not defined on MSVC +-#ifdef _WIN32 ++#if defined(_WIN32) && !defined(__MINGW32__) + typedef int pid_t; + #endif + +@@ -485,4 +485,4 @@ void sliding_window_reset(struct omni_context * ctx_omni); + + // ==================== 高清模式函数声明 ==================== + // 设置 vision max_slice_nums 覆盖值,用于高清模式 +-void vision_set_max_slice_nums(struct vision_ctx * ctx_vision, int max_slice_nums); +\ No newline at end of file ++void vision_set_max_slice_nums(struct vision_ctx * ctx_vision, int max_slice_nums); diff --git a/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_cpu/minicpmo-1-478e965280734397918e5b3687e11006.log b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_cpu/minicpmo-1-478e965280734397918e5b3687e11006.log new file mode 100755 index 000000000..9b839c3fa --- /dev/null +++ b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_cpu/minicpmo-1-478e965280734397918e5b3687e11006.log @@ -0,0 +1,469 @@ +build: 64 (5202b7b) with x86_64-w64-mingw32-gcc-posix (GCC) 13-posix for x86_64-w64-mingw32 +llama_model_loader: loaded meta data with 27 key-value pairs and 399 tensors from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf\MiniCPM-o-4_5-Q4_K_M.gguf (version GGUF V3 (latest)) +llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output. +llama_model_loader: - kv 0: general.architecture str = qwen3 +llama_model_loader: - kv 1: general.type str = model +llama_model_loader: - kv 2: general.name str = Llm +llama_model_loader: - kv 3: general.size_label str = 8.2B +llama_model_loader: - kv 4: qwen3.block_count u32 = 36 +llama_model_loader: - kv 5: qwen3.context_length u32 = 40960 +llama_model_loader: - kv 6: qwen3.embedding_length u32 = 4096 +llama_model_loader: - kv 7: qwen3.feed_forward_length u32 = 12288 +llama_model_loader: - kv 8: qwen3.attention.head_count u32 = 32 +llama_model_loader: - kv 9: qwen3.attention.head_count_kv u32 = 8 +llama_model_loader: - kv 10: qwen3.rope.freq_base f32 = 1000000.000000 +llama_model_loader: - kv 11: qwen3.attention.layer_norm_rms_epsilon f32 = 0.000001 +llama_model_loader: - kv 12: qwen3.attention.key_length u32 = 128 +llama_model_loader: - kv 13: qwen3.attention.value_length u32 = 128 +llama_model_loader: - kv 14: tokenizer.ggml.model str = gpt2 +llama_model_loader: - kv 15: tokenizer.ggml.pre str = qwen2 +llama_model_loader: - kv 16: tokenizer.ggml.tokens arr[str,151748] = ["!", "\"", "#", "$", "%", "&", "'", ... +llama_model_loader: - kv 17: tokenizer.ggml.token_type arr[i32,151748] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... +llama_model_loader: - kv 18: tokenizer.ggml.merges arr[str,151387] = ["Ġ Ġ", "ĠĠ ĠĠ", "i n", "Ġ t",... +llama_model_loader: - kv 19: tokenizer.ggml.bos_token_id u32 = 151644 +llama_model_loader: - kv 20: tokenizer.ggml.eos_token_id u32 = 151645 +llama_model_loader: - kv 21: tokenizer.ggml.unknown_token_id u32 = 128244 +llama_model_loader: - kv 22: tokenizer.ggml.padding_token_id u32 = 151643 +llama_model_loader: - kv 23: tokenizer.ggml.add_bos_token bool = false +llama_model_loader: - kv 24: tokenizer.chat_template str = {%- if tools %}\n {{- '<|im_start|>... +llama_model_loader: - kv 25: general.quantization_version u32 = 2 +llama_model_loader: - kv 26: general.file_type u32 = 15 +llama_model_loader: - type f32: 145 tensors +llama_model_loader: - type q4_K: 217 tensors +llama_model_loader: - type q6_K: 37 tensors +print_info: file format = GGUF V3 (latest) +print_info: file type = Q4_K - Medium +print_info: file size = 4.68 GiB (4.90 BPW) +load: printing all EOG tokens: +load: - 151643 ('<|endoftext|>') +load: - 151645 ('<|im_end|>') +load: - 151662 ('<|fim_pad|>') +load: - 151663 ('<|repo_name|>') +load: - 151664 ('<|file_sep|>') +load: special tokens cache size = 106 +load: token to piece cache size = 0.9319 MB +print_info: arch = qwen3 +print_info: vocab_only = 0 +print_info: n_ctx_train = 40960 +print_info: n_embd = 4096 +print_info: n_layer = 36 +print_info: n_head = 32 +print_info: n_head_kv = 8 +print_info: n_rot = 128 +print_info: n_swa = 0 +print_info: is_swa_any = 0 +print_info: n_embd_head_k = 128 +print_info: n_embd_head_v = 128 +print_info: n_gqa = 4 +print_info: n_embd_k_gqa = 1024 +print_info: n_embd_v_gqa = 1024 +print_info: f_norm_eps = 0.0e+00 +print_info: f_norm_rms_eps = 1.0e-06 +print_info: f_clamp_kqv = 0.0e+00 +print_info: f_max_alibi_bias = 0.0e+00 +print_info: f_logit_scale = 0.0e+00 +print_info: f_attn_scale = 0.0e+00 +print_info: n_ff = 12288 +print_info: n_expert = 0 +print_info: n_expert_used = 0 +print_info: causal attn = 1 +print_info: pooling type = -1 +print_info: rope type = 2 +print_info: rope scaling = linear +print_info: freq_base_train = 1000000.0 +print_info: freq_scale_train = 1 +print_info: n_ctx_orig_yarn = 40960 +print_info: rope_finetuned = unknown +print_info: model type = 8B +print_info: model params = 8.19 B +print_info: general.name = Llm +print_info: vocab type = BPE +print_info: n_vocab = 151748 +print_info: n_merges = 151387 +print_info: BOS token = 151644 '<|im_start|>' +print_info: EOS token = 151645 '<|im_end|>' +print_info: EOT token = 151645 '<|im_end|>' +print_info: UNK token = 128244 '' +print_info: PAD token = 151643 '<|endoftext|>' +print_info: LF token = 198 'Ċ' +print_info: FIM PRE token = 151659 '<|fim_prefix|>' +print_info: FIM SUF token = 151661 '<|fim_suffix|>' +print_info: FIM MID token = 151660 '<|fim_middle|>' +print_info: FIM PAD token = 151662 '<|fim_pad|>' +print_info: FIM REP token = 151663 '<|repo_name|>' +print_info: FIM SEP token = 151664 '<|file_sep|>' +print_info: EOG token = 151643 '<|endoftext|>' +print_info: EOG token = 151645 '<|im_end|>' +print_info: EOG token = 151662 '<|fim_pad|>' +print_info: EOG token = 151663 '<|repo_name|>' +print_info: EOG token = 151664 '<|file_sep|>' +print_info: max token length = 256 +load_tensors: loading model tensors, this can take a while... (mmap = true) +load_tensors: CPU_REPACK model buffer size = 3199.50 MiB +load_tensors: CPU_Mapped model buffer size = 4761.17 MiB +..................................................................................... +llama_context: constructing llama_context +llama_context: n_seq_max = 1 +llama_context: n_ctx = 2048 +llama_context: n_ctx_per_seq = 2048 +llama_context: n_batch = 2048 +llama_context: n_ubatch = 512 +llama_context: causal_attn = 1 +llama_context: flash_attn = auto +llama_context: kv_unified = false +llama_context: freq_base = 1000000.0 +llama_context: freq_scale = 1 +llama_context: n_ctx_per_seq (2048) < n_ctx_train (40960) -- the full capacity of the model will not be utilized +llama_context: CPU output buffer size = 0.58 MiB +llama_kv_cache: CPU KV buffer size = 288.00 MiB +llama_kv_cache: size = 288.00 MiB ( 2048 cells, 36 layers, 1/1 seqs), K (f16): 144.00 MiB, V (f16): 144.00 MiB +llama_context: Flash Attention was auto, set to enabled +llama_context: CPU compute buffer size = 304.38 MiB +llama_context: graph nodes = 1267 +llama_context: graph splits = 1 +llama_model_loader: loaded meta data with 30 key-value pairs and 193 tensors from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts/MiniCPM-o-4_5-tts-F16.gguf (version GGUF V3 (latest)) +llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output. +llama_model_loader: - kv 0: general.architecture str = llama +llama_model_loader: - kv 1: general.type str = model +llama_model_loader: - kv 2: general.name str = Tts +llama_model_loader: - kv 3: general.size_label str = 445M +llama_model_loader: - kv 4: llama.block_count u32 = 20 +llama_model_loader: - kv 5: llama.context_length u32 = 4096 +llama_model_loader: - kv 6: llama.embedding_length u32 = 768 +llama_model_loader: - kv 7: llama.feed_forward_length u32 = 3072 +llama_model_loader: - kv 8: llama.attention.head_count u32 = 12 +llama_model_loader: - kv 9: llama.attention.head_count_kv u32 = 12 +llama_model_loader: - kv 10: llama.rope.freq_base f32 = 10000.000000 +llama_model_loader: - kv 11: llama.attention.layer_norm_rms_epsilon f32 = 0.000001 +llama_model_loader: - kv 12: llama.attention.key_length u32 = 64 +llama_model_loader: - kv 13: llama.attention.value_length u32 = 64 +llama_model_loader: - kv 14: general.file_type u32 = 1 +llama_model_loader: - kv 15: llama.vocab_size u32 = 158626 +llama_model_loader: - kv 16: llama.rope.dimension_count u32 = 64 +llama_model_loader: - kv 17: general.quantization_version u32 = 2 +llama_model_loader: - kv 18: tokenizer.ggml.model str = gpt2 +llama_model_loader: - kv 19: tokenizer.ggml.pre str = qwen2 +llama_model_loader: - kv 20: tokenizer.ggml.tokens arr[str,158626] = ["!", "\"", "#", "$", "%", "&", "'", ... +llama_model_loader: - kv 21: tokenizer.ggml.token_type arr[i32,158626] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... +llama_model_loader: - kv 22: tokenizer.ggml.merges arr[str,151387] = ["Ġ Ġ", "ĠĠ ĠĠ", "i n", "Ġ t",... +llama_model_loader: - kv 23: tokenizer.ggml.bos_token_id u32 = 151644 +llama_model_loader: - kv 24: tokenizer.ggml.eos_token_id u32 = 151645 +llama_model_loader: - kv 25: tokenizer.ggml.unknown_token_id u32 = 128244 +llama_model_loader: - kv 26: tokenizer.ggml.padding_token_id u32 = 151643 +llama_model_loader: - kv 27: tokenizer.ggml.add_bos_token bool = false +llama_model_loader: - kv 28: tokenizer.chat_template str = {%- if tools %}\n {{- '<|im_start|>... +llama_model_loader: - kv 29: tokenizer.ggml.add_space_prefix bool = false +llama_model_loader: - type f32: 50 tensors +llama_model_loader: - type f16: 143 tensors +print_info: file format = GGUF V3 (latest) +print_info: file type = F16 +print_info: file size = 1.07 GiB (20.70 BPW) +load: printing all EOG tokens: +load: - 151643 ('<|endoftext|>') +load: - 151645 ('<|im_end|>') +load: - 151662 ('<|fim_pad|>') +load: - 151663 ('<|repo_name|>') +load: - 151664 ('<|file_sep|>') +load: special tokens cache size = 106 +load: token to piece cache size = 0.9319 MB +print_info: arch = llama +print_info: vocab_only = 0 +print_info: n_ctx_train = 4096 +print_info: n_embd = 768 +print_info: n_layer = 20 +print_info: n_head = 12 +print_info: n_head_kv = 12 +print_info: n_rot = 64 +print_info: n_swa = 0 +print_info: is_swa_any = 0 +print_info: n_embd_head_k = 64 +print_info: n_embd_head_v = 64 +print_info: n_gqa = 1 +print_info: n_embd_k_gqa = 768 +print_info: n_embd_v_gqa = 768 +print_info: f_norm_eps = 0.0e+00 +print_info: f_norm_rms_eps = 1.0e-06 +print_info: f_clamp_kqv = 0.0e+00 +print_info: f_max_alibi_bias = 0.0e+00 +print_info: f_logit_scale = 0.0e+00 +print_info: f_attn_scale = 0.0e+00 +print_info: n_ff = 3072 +print_info: n_expert = 0 +print_info: n_expert_used = 0 +print_info: causal attn = 1 +print_info: pooling type = 0 +print_info: rope type = 0 +print_info: rope scaling = linear +print_info: freq_base_train = 10000.0 +print_info: freq_scale_train = 1 +print_info: n_ctx_orig_yarn = 4096 +print_info: rope_finetuned = unknown +print_info: model type = ?B +print_info: model params = 444.94 M +print_info: general.name = Tts +print_info: vocab type = BPE +print_info: n_vocab = 158626 +print_info: n_merges = 151387 +print_info: BOS token = 151644 '<|im_start|>' +print_info: EOS token = 151645 '<|im_end|>' +print_info: EOT token = 151645 '<|im_end|>' +print_info: UNK token = 128244 '' +print_info: PAD token = 151643 '<|endoftext|>' +print_info: LF token = 198 'Ċ' +print_info: FIM PRE token = 151659 '<|fim_prefix|>' +print_info: FIM SUF token = 151661 '<|fim_suffix|>' +print_info: FIM MID token = 151660 '<|fim_middle|>' +print_info: FIM PAD token = 151662 '<|fim_pad|>' +print_info: FIM REP token = 151663 '<|repo_name|>' +print_info: FIM SEP token = 151664 '<|file_sep|>' +print_info: EOG token = 151643 '<|endoftext|>' +print_info: EOG token = 151645 '<|im_end|>' +print_info: EOG token = 151662 '<|fim_pad|>' +print_info: EOG token = 151663 '<|repo_name|>' +print_info: EOG token = 151664 '<|file_sep|>' +print_info: max token length = 256 +load_tensors: loading model tensors, this can take a while... (mmap = true) +load_tensors: skipping TTS tensor emb_code.0.weight (size = 20158464 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor emb_text.weight (size = 467140608 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_semantic.linear1.weight (size = 12582912 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_semantic.linear1.bias (size = 3072 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_semantic.linear2.weight (size = 2359296 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_semantic.linear2.bias (size = 3072 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_spk.linear1.weight (size = 6291456 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_spk.linear1.bias (size = 3072 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_spk.linear2.weight (size = 1179648 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_spk.linear2.bias (size = 3072 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor head_code.0.weight (size = 20158464 bytes) -- will be loaded separately +load_tensors: CPU_Mapped model buffer size = 592.48 MiB +.............................................................. +llama_init_from_model: model default pooling_type is [0], but [-1] was specified +llama_context: constructing llama_context +llama_context: n_seq_max = 1 +llama_context: n_ctx = 2048 +llama_context: n_ctx_per_seq = 2048 +llama_context: n_batch = 2048 +llama_context: n_ubatch = 512 +llama_context: causal_attn = 1 +llama_context: flash_attn = auto +llama_context: kv_unified = false +llama_context: freq_base = 10000.0 +llama_context: freq_scale = 1 +llama_context: n_ctx_per_seq (2048) < n_ctx_train (4096) -- the full capacity of the model will not be utilized +llama_context: CPU output buffer size = 0.61 MiB +llama_kv_cache: CPU KV buffer size = 120.00 MiB +llama_kv_cache: size = 120.00 MiB ( 2048 cells, 20 layers, 1/1 seqs), K (f16): 60.00 MiB, V (f16): 60.00 MiB +llama_context: Flash Attention was auto, set to enabled +llama_context: CPU compute buffer size = 25.51 MiB +llama_context: graph nodes = 613 +llama_context: graph splits = 1 +vision_model_loader: model name: +vision_model_loader: description: image encoder for MiniCPM-V +vision_model_loader: GGUF version: 3 +vision_model_loader: alignment: 32 +vision_model_loader: n_tensors: 455 +vision_model_loader: n_kv: 20 + +vision_ctx: vision using CPU backend +load_hparams: model_type: 0 +load_hparams: n_embd: 1152 +load_hparams: n_head: 16 +load_hparams: n_ff: 4304 +load_hparams: n_layer: 27 +load_hparams: ffn_op: gelu +load_hparams: projection_dim: 0 + +--- vision hparams --- +load_hparams: image_size: 448 +load_hparams: patch_size: 14 +load_hparams: minicpmv_version: 100045 +load_hparams: proj_scale_factor: 0 +load_hparams: n_wa_pattern: 0 + +load_hparams: model size: 1044.36 MiB +load_hparams: metadata size: 0.16 MiB +load_tensors: ffn up/down are swapped +alloc_compute_meta: CPU compute buffer size = 100.30 MiB +init tts....init t2w....voc_hg2_model: CPU backend using 8 threads +audition_audio_preprocess: Decoded audio - sample_rate=16000, n_samples=32000 +audition_get_mel_filters: Retrieved mel filters from model: 80 mel bins x 201 fft bins +audition_audio_preprocess: Using mel filters - n_mel=80, n_fft=201 +audition_audio_preprocess: Generated 1 mel spectrogram chunk(s) +audition_audio_preprocess: Mel spectrogram ready - n_len=200, n_mel=80, total_size=16000 +build_whisper: Whisper encoder graph built (projector output, pre-pooling) +audition_audio_batch_encode: Audio input data - n_step=200, n_mel=80, total_elements=16000 +audition_audio_batch_encode: Before incrementing iter: input_frames=200, n_tokens=100, current_iter=0, current_total=0, new_total=100, max_tokens=1500 +audition_audio_batch_encode: KV cache iter incremented to 1 (total_tokens=100, max_tokens=1500) +audition_audio_batch_encode: Final output shape: [4096, 20] +audition_audio_batch_encode: Final output: 20 tokens x 4096 dims +=== Model Paths === + Base dir: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf + LLM: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf\MiniCPM-o-4_5-Q4_K_M.gguf [OK] + Vision: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/vision/MiniCPM-o-4_5-vision-F16.gguf [OK] + Audio: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/audio/MiniCPM-o-4_5-audio-F16.gguf [OK] + TTS: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts/MiniCPM-o-4_5-tts-F16.gguf [OK] + Projector: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts/MiniCPM-o-4_5-projector-F16.gguf [OK] +=================== +=== Initializing Omni Context === + Media type: 2 (omni: audio+vision) + TTS enabled: yes + Context size: 2048 + GPU layers: 0 + Token2Wav device: cpu + Vision backend: metal + TTS bin dir: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts + Ref audio: C:\Users\zhout\w2\minicpmo_cpp_cpu_v3\fixture_0000.wav +22:55:37.112 === omni_init start +22:55:37.112 media_type = 2, duplex_mode = 0, base_output_dir = ./tools/omni/output +22:55:37.112 === omni_init: loading new LLM model +22:55:39.207 === omni_init: loading TTS model +22:55:39.207 TTS model: loading with n_gpu_layers=0 +22:55:39.457 TTS sampler: temp=0.80, top_p=0.85, top_k=25, rep_penalty=1.05 +22:55:39.457 TTS: loading weights from GGUF (emb_code, emb_text, projector_semantic, head_code)... +22:55:39.781 TTS: head_code shape: dim0=6562, dim1=768, will transpose to [6562, 768] +22:55:39.784 TTS: head_code loaded, verifying first few values: +22:55:39.784 head_code_weight[0] = 0.01361084 (expect ~0.01385498) +22:55:39.784 head_code_weight[1] = -0.01660156 (expect ~-0.01647949) +22:55:39.784 head_code_weight[768] = 0.04101562 (this is weight[1, 0], expect ~0.04150391) +22:55:39.813 TTS: weights loaded successfully +22:55:39.813 Projector: loading from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts/MiniCPM-o-4_5-projector-F16.gguf +22:55:39.818 Projector: loaded successfully +22:55:39.818 === omni_init: loading APM model +22:55:39.992 APM: init from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/audio/MiniCPM-o-4_5-audio-F16.gguf +22:55:40.283 Token2Wav: found models in C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/token2wav-gguf +22:55:40.283 Token2Wav: all model files found, initializing session... +22:55:40.283 Token2Wav: non-CUDA backend, vocoder using CPU for better performance +22:55:40.284 Token2Wav: using prompt_cache from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/token2wav-gguf/prompt_cache.gguf +22:55:40.578 Token2Wav: initialized successfully +22:55:40.578 Python T2W: script_dir=./tools/omni/pyt2w, model_dir=./tools/omni/pyt2w/token2wav +22:55:40.578 Token2Wav: 使用 C++ 实现 +22:55:40.578 === omni_init success: ctx_llama = 000001f4ffbf1770 +=== Running test case === + Audio prefix: C:\Users\zhout\w2\minicpmo_omni_work_cpu\omni-minicpmo-1-gnkn2c28\fixture_ + Count: 2 +22:55:40.578 stream_prefill: n_past = 0 + voice_clone_prompt = <|im_start|>system +模仿音频样本的音色并生成新的内容。 +<|audio_start|> + assistant_prompt = <|audio_end|>你的任务是用这种声音模式来当一个助手。请认真、高质量地回复用户的问题。请用高自然度的方式和用户聊天。<|im_end|> +<|im_start|>user + +22:55:40.578 system prompt ref_audio: C:\Users\zhout\w2\minicpmo_omni_work_cpu\omni-minicpmo-1-gnkn2c28\fixture_0000.wav +22:55:41.684 system prompt ref_audio embedding: n_pos=20 +22:55:44.068 🔒 n_keep 设置为 72 (system prompt tokens),这部分永远不会被滑动窗口删除 +22:55:44.068 stream_prefill(index=0): system prompt 初始化完成,ref_audio 已在其中 prefill +22:55:44.068 [SW] system_prompt registered: preserve_length=72 (will be protected from sliding) +22:55:44.068 n_past = 72 +22:55:44.068 + +c++ finish stream_prefill(index=0). n_past=72, n_keep=72, n_ctx=2048 + +prefill 0 (audio) : 3.48983 s +encode_image_with_vision_chunks: step 1 of 1 encoded in 3122.89 ms +encode_image_with_vision_chunks: all 1 chunks encoded in 3141.27 ms (grid: 1x1) + +encode_image_with_vision_chunks: image encoded in 3141.27 ms by vision ( 3141.27 ms per chunk, 64 total tokens) +omni_image_embed_make_chunks_with_filename: created 1 vision chunks from C:\Users\zhout\w2\minicpmo_omni_work_cpu\omni-minicpmo-1-gnkn2c28\fixture_0001.jpg +stream_prefill: prefilled 1 vision chunks (64 tokens each) +audition_audio_preprocess: Decoded audio - sample_rate=16000, n_samples=49339 +audition_audio_preprocess: Audio not aligned to 100ms (49339 samples = 3083.7ms), padded with silence to 49600 samples (3100ms) +audition_get_mel_filters: Retrieved mel filters from model: 80 mel bins x 201 fft bins +audition_audio_preprocess: Using mel filters - n_mel=80, n_fft=201 +audition_audio_preprocess: Generated 1 mel spectrogram chunk(s) +audition_audio_preprocess: Mel spectrogram ready - n_len=310, n_mel=80, total_size=24800 +build_whisper: Whisper encoder graph built (projector output, pre-pooling) +audition_audio_batch_encode: Audio input data - n_step=310, n_mel=80, total_elements=24800 +audition_audio_batch_encode: Before incrementing iter: input_frames=310, n_tokens=155, current_iter=1, current_total=155, new_total=310, max_tokens=1500 +audition_audio_batch_encode: KV cache iter incremented to 2 (total_tokens=310, max_tokens=1500) +audition_audio_batch_encode: Final output shape: [4096, 31] +audition_audio_batch_encode: Final output: 31 tokens x 4096 dims +22:55:50.305 stream_prefill(index=1): processing user audio: C:\Users\zhout\w2\minicpmo_omni_work_cpu\omni-minicpmo-1-gnkn2c28\fixture_0001.wav +22:55:50.602 stream_prefill(index=1): user audio embedding: n_pos=31 +22:55:52.228 + +c++ finish stream_prefill(index=1). n_past=172, n_keep=72, n_ctx=2048 + +prefill 1 (audio+vision) : 8.15363 s +22:55:52.228 📍 stream_decode 开始: n_past=172, n_keep=72, n_ctx=2048, duplex_mode=0 +22:55:52.228 stream_decode: create tts thread (simplex mode) +22:55:52.228 stream_decode: create t2w thread +22:55:52.228 wait prefill done +22:55:52.229 📍 [单工TTS] 添加 assistant prompt: "<|im_end|> +<|im_start|>assistant + + + + +<|tts_bos|>", n_past=172 +22:55:52.229 T2W thread (C++) started + +22:55:52.231 TTS: 创建单工模式输出目录: ./tools/omni/output/round_000 +22:55:52.232 TTS thread started +22:55:52.741 📍 [单工TTS] assistant prompt 完成, n_past=182 +22:55:52.741 LLM decode: max_tgt_len = 96, n_predict = 96, n_ctx = 2048 +22:55:53.541 LLM: detected end token, set llm_generation_done=true +22:55:53.541 LLM->TTS: text='The square in the image is red.', n_tokens=8, hidden_size=32768, n_embd=4096, token_ids=[785 9334 304 279 2168 374 2518 13] +22:55:53.541 📍 Decode 结束: n_past=191, 剩余空间=1857, 无需滑窗 +22:55:53.541 📍 轮次 1 结束,记录边界于 n_past=191 +22:55:53.541 TTS<-LLM: chunk_idx=0, text='The square in the image is red.', n_tokens=8, hidden_size=32768, token_ids=[785 9334 304 279 2168 374 2518 13] +22:55:53.541 TTS: after queue pop - speek_done=0, llm_finish=1, llm_text.empty=0, token_ids.size=8 +22:55:53.541 TTS: before empty check - response.empty=0, response='The square in the image is red.', llm_finish=1 +Waiting for audio generation to complete... +TTS: chunk file ./tools/omni/output/round_000/tts_wav/tts_output_chunk_0.wav does not exist or is empty +TTS: chunk file ./tools/omni/output/round_000/tts_wav/tts_output_chunk_1.wav does not exist or is empty +TTS: no valid WAV files to merge +22:55:53.541 TTS: DEBUG before has_llm_data - token_ids.size=8, hidden_states.size=32768, n_embd=4096 +22:55:53.541 TTS: has_llm_data=1, token_ids=8, hidden_states=32768, n_embd=4096, llm_finish=1 +22:55:53.542 TTS: n_tokens_orig=8, n_tokens_filtered=8 (filtered 0 special tokens) +22:55:53.583 TTS: saved merged embeddings (text) to ./tools/omni/output/round_000/llm_debug/chunk_0/merged_embeddings.txt +22:55:53.583 TTS Simplex: generating audio tokens for chunk 0 (n_tokens=8, tts_n_embd=768) +22:55:53.583 TTS Simplex: 在 prefill 前添加 audio_bos (chunk_idx=0, new_size=9) +22:55:53.583 TTS Simplex: first chunk - cleared KV cache +22:55:53.583 TTS Simplex: first chunk - cleared tts_all_generated_tokens and tts_token_buffer +22:55:53.688 TTS Simplex: prefill completed, n_past_tts=9 +22:55:53.688 TTS Simplex: sampler created +22:55:53.688 TTS simplex: is_audio_bos=true (first audio token) +22:55:53.720 TTS Simplex Phase1: token 1/500: rel_id=761 +22:55:53.731 TTS Simplex Phase1: token 2/500: rel_id=4218 +22:55:53.745 TTS Simplex Phase1: token 3/500: rel_id=4218 +22:55:53.758 TTS Simplex Phase1: token 4/500: rel_id=4137 +22:55:53.769 TTS Simplex Phase1: token 5/500: rel_id=4137 +22:55:53.885 📍 为下一轮准备: eval <|im_end|>\n<|im_start|>user\n, n_past=196 +22:55:54.001 TTS Simplex Phase1: yield 25 tokens 到 T2W (step 25, buffer=25) +22:55:54.001 TTS Simplex Phase1: token 25/500: rel_id=3664 +22:55:54.001 T2W线程(C++): 轮次切换 (-1 -> 0),更新输出目录 +22:55:54.001 T2W线程(C++): 新输出目录 ./tools/omni/output/round_000/tts_wav +22:55:54.137 TTS Simplex Phase1: EOS token at step 38 +22:55:54.137 TTS Simplex: is_final_text_chunk=true, will enter Phase 2 for text_eos_embed +22:55:54.137 TTS Simplex Phase2: injecting text_eos_embed + audio_bos at n_past=46 +22:55:54.144 TTS Simplex Phase2: text_eos_embed injected, n_past=47 +22:55:54.153 TTS Simplex Phase2: audio_bos injected, n_past=48, starting final generation +22:55:54.298 TTS Simplex Phase2: yield 25 tokens 到 T2W +22:55:54.343 TTS Simplex Phase2: EOS at step 17 (final end) +22:55:54.343 TTS Simplex: chunk 结束,tts_token_buffer 剩余 3 tokens (保留等下一个 chunk) +22:55:54.343 TTS Simplex: is_final_text_chunk=true, flush 剩余 3 tokens 从 tts_token_buffer +22:55:54.343 TTS Simplex: generated 53 audio tokens for chunk 0 +22:55:54.343 TTS Simplex: chunk 0 first tokens: [761 4218 4218 4137 4137 ], last tokens: [737 136 75 764 735 ] +22:55:54.343 TTS Simplex: updated tts_n_past_accumulated=65, total_generated_tokens=53 +22:55:54.354 TTS: finished processing all chunks +22:55:54.354 TTS: 单工模式轮次结束,下一轮 round_idx=1 +22:55:54.354 TTS: sent is_final=true to T2W queue (turn end) +22:55:56.309 🎉 首响时间 (First Audio Response): 4080ms +22:55:56.309 T2W线程: wav_0.wav | 0.84s audio | 2306.7ms inference | RTF=2.75 | t=4080ms +22:55:58.525 T2W线程: wav_1.wav | 1.00s audio | 2216.0ms inference | RTF=2.22 | t=6296ms +22:56:00.521 T2W线程: wav_2.wav | 0.40s audio | 1995.5ms inference | RTF=4.99 | t=8293ms +22:56:00.522 T2W线程: 写入结束标记 ./tools/omni/output/round_000/tts_wav/generation_done.flag (last_wav=2) +22:56:00.522 T2W线程: 轮次结束后更新输出目录为 ./tools/omni/output/round_001/tts_wav +22:56:00.546 omni_stop_threads: stop signals sent +22:56:00.546 T2W(C++) 线程: 停止 +[timing] call=0 tokens=28 final=0 token2mel=1983.849ms vocoder=322.771ms total=2306.633ms audio=20160 +[timing] call=1 tokens=28 final=0 token2mel=1833.036ms vocoder=382.936ms total=2215.984ms audio=24000 +[timing] call=2 tokens=6 final=1 token2mel=1846.302ms vocoder=149.170ms total=1995.482ms audio=9600 +Audio generation completed. +llama_perf_context_print: load time = 13532.85 ms +llama_perf_context_print: prompt eval time = 12162.64 ms / 182 tokens ( 66.83 ms per token, 14.96 tokens per second) +llama_perf_context_print: eval time = 797.52 ms / 9 runs ( 88.61 ms per token, 11.28 tokens per second) +llama_perf_context_print: total time = 21337.55 ms / 191 tokens +llama_perf_context_print: graphs reused = 10 +Token2Wav (C++): session released +tts thread end +t2w thread end diff --git a/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_cpu/minicpmo-2-7fa1ace55f734e678e7e76f56d6bdf9d.log b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_cpu/minicpmo-2-7fa1ace55f734e678e7e76f56d6bdf9d.log new file mode 100755 index 000000000..34cdc565e --- /dev/null +++ b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_cpu/minicpmo-2-7fa1ace55f734e678e7e76f56d6bdf9d.log @@ -0,0 +1,19 @@ +build: 64 (5202b7b) with x86_64-w64-mingw32-gcc-posix (GCC) 13-posix for x86_64-w64-mingw32 +llama_model_loader: loaded meta data with 27 key-value pairs and 399 tensors from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf\MiniCPM-o-4_5-Q4_K_M.gguf (version GGUF V3 (latest)) +llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output. +llama_model_loader: - kv 0: general.architecture str = qwen3 +llama_model_loader: - kv 1: general.type str = model +llama_model_loader: - kv 2: general.name str = Llm +llama_model_loader: - kv 3: general.size_label str = 8.2B +llama_model_loader: - kv 4: qwen3.block_count u32 = 36 +llama_model_loader: - kv 5: qwen3.context_length u32 = 40960 +llama_model_loader: - kv 6: qwen3.embedding_length u32 = 4096 +llama_model_loader: - kv 7: qwen3.feed_forward_length u32 = 12288 +llama_model_loader: - kv 8: qwen3.attention.head_count u32 = 32 +llama_model_loader: - kv 9: qwen3.attention.head_count_kv u32 = 8 +llama_model_loader: - kv 10: qwen3.rope.freq_base f32 = 1000000.000000 +llama_model_loader: - kv 11: qwen3.attention.layer_norm_rms_epsilon f32 = 0.000001 +llama_model_loader: - kv 12: qwen3.attention.key_length u32 = 128 +llama_model_loader: - kv 13: qwen3.attention.value_length u32 = 128 +llama_model_loader: - kv 14: tokenizer.ggml.model str = gpt2 +llama_model_loader: - kv 15: tokenizer.ggml.pre str = qwen2 diff --git a/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_radeon/minicpmo-1-fec5accd5f8b463f8e62252d7a31c927.log b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_radeon/minicpmo-1-fec5accd5f8b463f8e62252d7a31c927.log new file mode 100755 index 000000000..e83cd85e5 --- /dev/null +++ b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_radeon/minicpmo-1-fec5accd5f8b463f8e62252d7a31c927.log @@ -0,0 +1,479 @@ +build: 64 (5202b7b) with x86_64-w64-mingw32-gcc-posix (GCC) 13-posix for x86_64-w64-mingw32 +llama_model_load_from_file_impl: using device Vulkan0 (AMD Radeon(TM) 890M Graphics) (unknown id) - 30720 MiB free +llama_model_loader: loaded meta data with 27 key-value pairs and 399 tensors from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf\MiniCPM-o-4_5-Q4_K_M.gguf (version GGUF V3 (latest)) +llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output. +llama_model_loader: - kv 0: general.architecture str = qwen3 +llama_model_loader: - kv 1: general.type str = model +llama_model_loader: - kv 2: general.name str = Llm +llama_model_loader: - kv 3: general.size_label str = 8.2B +llama_model_loader: - kv 4: qwen3.block_count u32 = 36 +llama_model_loader: - kv 5: qwen3.context_length u32 = 40960 +llama_model_loader: - kv 6: qwen3.embedding_length u32 = 4096 +llama_model_loader: - kv 7: qwen3.feed_forward_length u32 = 12288 +llama_model_loader: - kv 8: qwen3.attention.head_count u32 = 32 +llama_model_loader: - kv 9: qwen3.attention.head_count_kv u32 = 8 +llama_model_loader: - kv 10: qwen3.rope.freq_base f32 = 1000000.000000 +llama_model_loader: - kv 11: qwen3.attention.layer_norm_rms_epsilon f32 = 0.000001 +llama_model_loader: - kv 12: qwen3.attention.key_length u32 = 128 +llama_model_loader: - kv 13: qwen3.attention.value_length u32 = 128 +llama_model_loader: - kv 14: tokenizer.ggml.model str = gpt2 +llama_model_loader: - kv 15: tokenizer.ggml.pre str = qwen2 +llama_model_loader: - kv 16: tokenizer.ggml.tokens arr[str,151748] = ["!", "\"", "#", "$", "%", "&", "'", ... +llama_model_loader: - kv 17: tokenizer.ggml.token_type arr[i32,151748] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... +llama_model_loader: - kv 18: tokenizer.ggml.merges arr[str,151387] = ["Ġ Ġ", "ĠĠ ĠĠ", "i n", "Ġ t",... +llama_model_loader: - kv 19: tokenizer.ggml.bos_token_id u32 = 151644 +llama_model_loader: - kv 20: tokenizer.ggml.eos_token_id u32 = 151645 +llama_model_loader: - kv 21: tokenizer.ggml.unknown_token_id u32 = 128244 +llama_model_loader: - kv 22: tokenizer.ggml.padding_token_id u32 = 151643 +llama_model_loader: - kv 23: tokenizer.ggml.add_bos_token bool = false +llama_model_loader: - kv 24: tokenizer.chat_template str = {%- if tools %}\n {{- '<|im_start|>... +llama_model_loader: - kv 25: general.quantization_version u32 = 2 +llama_model_loader: - kv 26: general.file_type u32 = 15 +llama_model_loader: - type f32: 145 tensors +llama_model_loader: - type q4_K: 217 tensors +llama_model_loader: - type q6_K: 37 tensors +print_info: file format = GGUF V3 (latest) +print_info: file type = Q4_K - Medium +print_info: file size = 4.68 GiB (4.90 BPW) +load: printing all EOG tokens: +load: - 151643 ('<|endoftext|>') +load: - 151645 ('<|im_end|>') +load: - 151662 ('<|fim_pad|>') +load: - 151663 ('<|repo_name|>') +load: - 151664 ('<|file_sep|>') +load: special tokens cache size = 106 +load: token to piece cache size = 0.9319 MB +print_info: arch = qwen3 +print_info: vocab_only = 0 +print_info: n_ctx_train = 40960 +print_info: n_embd = 4096 +print_info: n_layer = 36 +print_info: n_head = 32 +print_info: n_head_kv = 8 +print_info: n_rot = 128 +print_info: n_swa = 0 +print_info: is_swa_any = 0 +print_info: n_embd_head_k = 128 +print_info: n_embd_head_v = 128 +print_info: n_gqa = 4 +print_info: n_embd_k_gqa = 1024 +print_info: n_embd_v_gqa = 1024 +print_info: f_norm_eps = 0.0e+00 +print_info: f_norm_rms_eps = 1.0e-06 +print_info: f_clamp_kqv = 0.0e+00 +print_info: f_max_alibi_bias = 0.0e+00 +print_info: f_logit_scale = 0.0e+00 +print_info: f_attn_scale = 0.0e+00 +print_info: n_ff = 12288 +print_info: n_expert = 0 +print_info: n_expert_used = 0 +print_info: causal attn = 1 +print_info: pooling type = -1 +print_info: rope type = 2 +print_info: rope scaling = linear +print_info: freq_base_train = 1000000.0 +print_info: freq_scale_train = 1 +print_info: n_ctx_orig_yarn = 40960 +print_info: rope_finetuned = unknown +print_info: model type = 8B +print_info: model params = 8.19 B +print_info: general.name = Llm +print_info: vocab type = BPE +print_info: n_vocab = 151748 +print_info: n_merges = 151387 +print_info: BOS token = 151644 '<|im_start|>' +print_info: EOS token = 151645 '<|im_end|>' +print_info: EOT token = 151645 '<|im_end|>' +print_info: UNK token = 128244 '' +print_info: PAD token = 151643 '<|endoftext|>' +print_info: LF token = 198 'Ċ' +print_info: FIM PRE token = 151659 '<|fim_prefix|>' +print_info: FIM SUF token = 151661 '<|fim_suffix|>' +print_info: FIM MID token = 151660 '<|fim_middle|>' +print_info: FIM PAD token = 151662 '<|fim_pad|>' +print_info: FIM REP token = 151663 '<|repo_name|>' +print_info: FIM SEP token = 151664 '<|file_sep|>' +print_info: EOG token = 151643 '<|endoftext|>' +print_info: EOG token = 151645 '<|im_end|>' +print_info: EOG token = 151662 '<|fim_pad|>' +print_info: EOG token = 151663 '<|repo_name|>' +print_info: EOG token = 151664 '<|file_sep|>' +print_info: max token length = 256 +load_tensors: loading model tensors, this can take a while... (mmap = true) +load_tensors: offloading 36 repeating layers to GPU +load_tensors: offloading output layer to GPU +load_tensors: offloaded 37/37 layers to GPU +load_tensors: Vulkan0 model buffer size = 4454.74 MiB +load_tensors: CPU_Mapped model buffer size = 333.43 MiB +..................................................................................... +llama_context: constructing llama_context +llama_context: n_seq_max = 1 +llama_context: n_ctx = 2048 +llama_context: n_ctx_per_seq = 2048 +llama_context: n_batch = 2048 +llama_context: n_ubatch = 512 +llama_context: causal_attn = 1 +llama_context: flash_attn = auto +llama_context: kv_unified = false +llama_context: freq_base = 1000000.0 +llama_context: freq_scale = 1 +llama_context: n_ctx_per_seq (2048) < n_ctx_train (40960) -- the full capacity of the model will not be utilized +llama_context: Vulkan_Host output buffer size = 0.58 MiB +llama_kv_cache: Vulkan0 KV buffer size = 288.00 MiB +llama_kv_cache: size = 288.00 MiB ( 2048 cells, 36 layers, 1/1 seqs), K (f16): 144.00 MiB, V (f16): 144.00 MiB +llama_context: Flash Attention was auto, set to enabled +llama_context: Vulkan0 compute buffer size = 304.38 MiB +llama_context: Vulkan_Host compute buffer size = 12.01 MiB +llama_context: graph nodes = 1267 +llama_context: graph splits = 2 +llama_model_load_from_file_impl: using device Vulkan0 (AMD Radeon(TM) 890M Graphics) (unknown id) - 25673 MiB free +llama_model_loader: loaded meta data with 30 key-value pairs and 193 tensors from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts/MiniCPM-o-4_5-tts-F16.gguf (version GGUF V3 (latest)) +llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output. +llama_model_loader: - kv 0: general.architecture str = llama +llama_model_loader: - kv 1: general.type str = model +llama_model_loader: - kv 2: general.name str = Tts +llama_model_loader: - kv 3: general.size_label str = 445M +llama_model_loader: - kv 4: llama.block_count u32 = 20 +llama_model_loader: - kv 5: llama.context_length u32 = 4096 +llama_model_loader: - kv 6: llama.embedding_length u32 = 768 +llama_model_loader: - kv 7: llama.feed_forward_length u32 = 3072 +llama_model_loader: - kv 8: llama.attention.head_count u32 = 12 +llama_model_loader: - kv 9: llama.attention.head_count_kv u32 = 12 +llama_model_loader: - kv 10: llama.rope.freq_base f32 = 10000.000000 +llama_model_loader: - kv 11: llama.attention.layer_norm_rms_epsilon f32 = 0.000001 +llama_model_loader: - kv 12: llama.attention.key_length u32 = 64 +llama_model_loader: - kv 13: llama.attention.value_length u32 = 64 +llama_model_loader: - kv 14: general.file_type u32 = 1 +llama_model_loader: - kv 15: llama.vocab_size u32 = 158626 +llama_model_loader: - kv 16: llama.rope.dimension_count u32 = 64 +llama_model_loader: - kv 17: general.quantization_version u32 = 2 +llama_model_loader: - kv 18: tokenizer.ggml.model str = gpt2 +llama_model_loader: - kv 19: tokenizer.ggml.pre str = qwen2 +llama_model_loader: - kv 20: tokenizer.ggml.tokens arr[str,158626] = ["!", "\"", "#", "$", "%", "&", "'", ... +llama_model_loader: - kv 21: tokenizer.ggml.token_type arr[i32,158626] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... +llama_model_loader: - kv 22: tokenizer.ggml.merges arr[str,151387] = ["Ġ Ġ", "ĠĠ ĠĠ", "i n", "Ġ t",... +llama_model_loader: - kv 23: tokenizer.ggml.bos_token_id u32 = 151644 +llama_model_loader: - kv 24: tokenizer.ggml.eos_token_id u32 = 151645 +llama_model_loader: - kv 25: tokenizer.ggml.unknown_token_id u32 = 128244 +llama_model_loader: - kv 26: tokenizer.ggml.padding_token_id u32 = 151643 +llama_model_loader: - kv 27: tokenizer.ggml.add_bos_token bool = false +llama_model_loader: - kv 28: tokenizer.chat_template str = {%- if tools %}\n {{- '<|im_start|>... +llama_model_loader: - kv 29: tokenizer.ggml.add_space_prefix bool = false +llama_model_loader: - type f32: 50 tensors +llama_model_loader: - type f16: 143 tensors +print_info: file format = GGUF V3 (latest) +print_info: file type = F16 +print_info: file size = 1.07 GiB (20.70 BPW) +load: printing all EOG tokens: +load: - 151643 ('<|endoftext|>') +load: - 151645 ('<|im_end|>') +load: - 151662 ('<|fim_pad|>') +load: - 151663 ('<|repo_name|>') +load: - 151664 ('<|file_sep|>') +load: special tokens cache size = 106 +load: token to piece cache size = 0.9319 MB +print_info: arch = llama +print_info: vocab_only = 0 +print_info: n_ctx_train = 4096 +print_info: n_embd = 768 +print_info: n_layer = 20 +print_info: n_head = 12 +print_info: n_head_kv = 12 +print_info: n_rot = 64 +print_info: n_swa = 0 +print_info: is_swa_any = 0 +print_info: n_embd_head_k = 64 +print_info: n_embd_head_v = 64 +print_info: n_gqa = 1 +print_info: n_embd_k_gqa = 768 +print_info: n_embd_v_gqa = 768 +print_info: f_norm_eps = 0.0e+00 +print_info: f_norm_rms_eps = 1.0e-06 +print_info: f_clamp_kqv = 0.0e+00 +print_info: f_max_alibi_bias = 0.0e+00 +print_info: f_logit_scale = 0.0e+00 +print_info: f_attn_scale = 0.0e+00 +print_info: n_ff = 3072 +print_info: n_expert = 0 +print_info: n_expert_used = 0 +print_info: causal attn = 1 +print_info: pooling type = 0 +print_info: rope type = 0 +print_info: rope scaling = linear +print_info: freq_base_train = 10000.0 +print_info: freq_scale_train = 1 +print_info: n_ctx_orig_yarn = 4096 +print_info: rope_finetuned = unknown +print_info: model type = ?B +print_info: model params = 444.94 M +print_info: general.name = Tts +print_info: vocab type = BPE +print_info: n_vocab = 158626 +print_info: n_merges = 151387 +print_info: BOS token = 151644 '<|im_start|>' +print_info: EOS token = 151645 '<|im_end|>' +print_info: EOT token = 151645 '<|im_end|>' +print_info: UNK token = 128244 '' +print_info: PAD token = 151643 '<|endoftext|>' +print_info: LF token = 198 'Ċ' +print_info: FIM PRE token = 151659 '<|fim_prefix|>' +print_info: FIM SUF token = 151661 '<|fim_suffix|>' +print_info: FIM MID token = 151660 '<|fim_middle|>' +print_info: FIM PAD token = 151662 '<|fim_pad|>' +print_info: FIM REP token = 151663 '<|repo_name|>' +print_info: FIM SEP token = 151664 '<|file_sep|>' +print_info: EOG token = 151643 '<|endoftext|>' +print_info: EOG token = 151645 '<|im_end|>' +print_info: EOG token = 151662 '<|fim_pad|>' +print_info: EOG token = 151663 '<|repo_name|>' +print_info: EOG token = 151664 '<|file_sep|>' +print_info: max token length = 256 +load_tensors: loading model tensors, this can take a while... (mmap = true) +load_tensors: skipping TTS tensor emb_code.0.weight (size = 20158464 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor emb_text.weight (size = 467140608 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_semantic.linear1.weight (size = 12582912 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_semantic.linear1.bias (size = 3072 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_semantic.linear2.weight (size = 2359296 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_semantic.linear2.bias (size = 3072 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_spk.linear1.weight (size = 6291456 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_spk.linear1.bias (size = 3072 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_spk.linear2.weight (size = 1179648 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor projector_spk.linear2.bias (size = 3072 bytes) -- will be loaded separately +load_tensors: skipping TTS tensor head_code.0.weight (size = 20158464 bytes) -- will be loaded separately +load_tensors: offloading 0 repeating layers to GPU +load_tensors: offloaded 0/21 layers to GPU +load_tensors: CPU_Mapped model buffer size = 592.48 MiB +.............................................................. +llama_init_from_model: model default pooling_type is [0], but [-1] was specified +llama_context: constructing llama_context +llama_context: n_seq_max = 1 +llama_context: n_ctx = 2048 +llama_context: n_ctx_per_seq = 2048 +llama_context: n_batch = 2048 +llama_context: n_ubatch = 512 +llama_context: causal_attn = 1 +llama_context: flash_attn = auto +llama_context: kv_unified = false +llama_context: freq_base = 10000.0 +llama_context: freq_scale = 1 +llama_context: n_ctx_per_seq (2048) < n_ctx_train (4096) -- the full capacity of the model will not be utilized +llama_context: CPU output buffer size = 0.61 MiB +llama_kv_cache: CPU KV buffer size = 120.00 MiB +llama_kv_cache: size = 120.00 MiB ( 2048 cells, 20 layers, 1/1 seqs), K (f16): 60.00 MiB, V (f16): 60.00 MiB +llama_context: Flash Attention was auto, set to enabled +llama_context: Vulkan0 compute buffer size = 30.75 MiB +llama_context: Vulkan_Host compute buffer size = 7.01 MiB +llama_context: graph nodes = 613 +llama_context: graph splits = 216 (with bs=512), 1 (with bs=1) +vision_model_loader: model name: +vision_model_loader: description: image encoder for MiniCPM-V +vision_model_loader: GGUF version: 3 +vision_model_loader: alignment: 32 +vision_model_loader: n_tensors: 455 +vision_model_loader: n_kv: 20 + +vision_ctx: vision using Vulkan0 backend +load_hparams: model_type: 0 +load_hparams: n_embd: 1152 +load_hparams: n_head: 16 +load_hparams: n_ff: 4304 +load_hparams: n_layer: 27 +load_hparams: ffn_op: gelu +load_hparams: projection_dim: 0 + +--- vision hparams --- +load_hparams: image_size: 448 +load_hparams: patch_size: 14 +load_hparams: minicpmv_version: 100045 +load_hparams: proj_scale_factor: 0 +load_hparams: n_wa_pattern: 0 + +load_hparams: model size: 1044.36 MiB +load_hparams: metadata size: 0.16 MiB +load_tensors: ffn up/down are swapped +alloc_compute_meta: Vulkan0 compute buffer size = 100.30 MiB +alloc_compute_meta: CPU compute buffer size = 18.30 MiB +init tts....init t2w....voc_hg2_model: CPU backend using 8 threads +audition_audio_preprocess: Decoded audio - sample_rate=16000, n_samples=32000 +audition_get_mel_filters: Retrieved mel filters from model: 80 mel bins x 201 fft bins +audition_audio_preprocess: Using mel filters - n_mel=80, n_fft=201 +audition_audio_preprocess: Generated 1 mel spectrogram chunk(s) +audition_audio_preprocess: Mel spectrogram ready - n_len=200, n_mel=80, total_size=16000 +build_whisper: Whisper encoder graph built (projector output, pre-pooling) +audition_audio_batch_encode: Audio input data - n_step=200, n_mel=80, total_elements=16000 +audition_audio_batch_encode: Before incrementing iter: input_frames=200, n_tokens=100, current_iter=0, current_total=0, new_total=100, max_tokens=1500 +audition_audio_batch_encode: KV cache iter incremented to 1 (total_tokens=100, max_tokens=1500) +audition_audio_batch_encode: Final output shape: [4096, 20] +audition_audio_batch_encode: Final output: 20 tokens x 4096 dims +=== Model Paths === + Base dir: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf + LLM: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf\MiniCPM-o-4_5-Q4_K_M.gguf [OK] + Vision: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/vision/MiniCPM-o-4_5-vision-F16.gguf [OK] + Audio: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/audio/MiniCPM-o-4_5-audio-F16.gguf [OK] + TTS: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts/MiniCPM-o-4_5-tts-F16.gguf [OK] + Projector: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts/MiniCPM-o-4_5-projector-F16.gguf [OK] +=================== +=== Initializing Omni Context === + Media type: 2 (omni: audio+vision) + TTS enabled: yes + Context size: 2048 + GPU layers: 99 + Token2Wav device: cpu + Vision backend: metal + TTS bin dir: C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts + Ref audio: C:\Users\zhout\w2\minicpmo_cpp_cpu_v3\fixture_0000.wav +22:56:40.659 === omni_init start +22:56:40.659 media_type = 2, duplex_mode = 0, base_output_dir = ./tools/omni/output +22:56:40.659 === omni_init: loading new LLM model +22:56:43.521 === omni_init: loading TTS model +22:56:43.521 TTS model: loading with n_gpu_layers=0 +22:56:43.847 TTS sampler: temp=0.80, top_p=0.85, top_k=25, rep_penalty=1.05 +22:56:43.847 TTS: loading weights from GGUF (emb_code, emb_text, projector_semantic, head_code)... +22:56:44.221 TTS: head_code shape: dim0=6562, dim1=768, will transpose to [6562, 768] +22:56:44.224 TTS: head_code loaded, verifying first few values: +22:56:44.224 head_code_weight[0] = 0.01361084 (expect ~0.01385498) +22:56:44.224 head_code_weight[1] = -0.01660156 (expect ~-0.01647949) +22:56:44.224 head_code_weight[768] = 0.04101562 (this is weight[1, 0], expect ~0.04150391) +22:56:44.257 TTS: weights loaded successfully +22:56:44.257 Projector: loading from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/tts/MiniCPM-o-4_5-projector-F16.gguf +22:56:44.263 Projector: loaded successfully +22:56:44.263 === omni_init: loading APM model +22:56:44.447 APM: init from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/audio/MiniCPM-o-4_5-audio-F16.gguf +22:56:45.272 Token2Wav: found models in C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/token2wav-gguf +22:56:45.272 Token2Wav: all model files found, initializing session... +22:56:45.272 Token2Wav: non-CUDA backend, vocoder using CPU for better performance +22:56:45.273 Token2Wav: using prompt_cache from C:\Users\zhout\w2\models\MiniCPM-o-4_5-gguf/token2wav-gguf/prompt_cache.gguf +22:56:45.545 Token2Wav: initialized successfully +22:56:45.545 Python T2W: script_dir=./tools/omni/pyt2w, model_dir=./tools/omni/pyt2w/token2wav +22:56:45.545 Token2Wav: 使用 C++ 实现 +22:56:45.545 === omni_init success: ctx_llama = 00000262404be2d0 +=== Running test case === + Audio prefix: C:\Users\zhout\w2\minicpmo_omni_work_radeon\omni-minicpmo-1-s53iymbq\fixture_ + Count: 2 +22:56:45.545 stream_prefill: n_past = 0 + voice_clone_prompt = <|im_start|>system +模仿音频样本的音色并生成新的内容。 +<|audio_start|> + assistant_prompt = <|audio_end|>你的任务是用这种声音模式来当一个助手。请认真、高质量地回复用户的问题。请用高自然度的方式和用户聊天。<|im_end|> +<|im_start|>user + +22:56:45.545 system prompt ref_audio: C:\Users\zhout\w2\minicpmo_omni_work_radeon\omni-minicpmo-1-s53iymbq\fixture_0000.wav +22:56:46.248 system prompt ref_audio embedding: n_pos=20 +22:56:46.947 🔒 n_keep 设置为 72 (system prompt tokens),这部分永远不会被滑动窗口删除 +22:56:46.947 stream_prefill(index=0): system prompt 初始化完成,ref_audio 已在其中 prefill +22:56:46.947 [SW] system_prompt registered: preserve_length=72 (will be protected from sliding) +22:56:46.947 n_past = 72 +22:56:46.947 + +c++ finish stream_prefill(index=0). n_past=72, n_keep=72, n_ctx=2048 + +prefill 0 (audio) : 1.40212 s +encode_image_with_vision_chunks: step 1 of 1 encoded in 1439.56 ms +encode_image_with_vision_chunks: all 1 chunks encoded in 1457.94 ms (grid: 1x1) + +encode_image_with_vision_chunks: image encoded in 1457.94 ms by vision ( 1457.94 ms per chunk, 64 total tokens) +omni_image_embed_make_chunks_with_filename: created 1 vision chunks from C:\Users\zhout\w2\minicpmo_omni_work_radeon\omni-minicpmo-1-s53iymbq\fixture_0001.jpg +stream_prefill: prefilled 1 vision chunks (64 tokens each) +audition_audio_preprocess: Decoded audio - sample_rate=16000, n_samples=49339 +audition_audio_preprocess: Audio not aligned to 100ms (49339 samples = 3083.7ms), padded with silence to 49600 samples (3100ms) +audition_get_mel_filters: Retrieved mel filters from model: 80 mel bins x 201 fft bins +audition_audio_preprocess: Using mel filters - n_mel=80, n_fft=201 +audition_audio_preprocess: Generated 1 mel spectrogram chunk(s) +audition_audio_preprocess: Mel spectrogram ready - n_len=310, n_mel=80, total_size=24800 +build_whisper: Whisper encoder graph built (projector output, pre-pooling) +audition_audio_batch_encode: Audio input data - n_step=310, n_mel=80, total_elements=24800 +audition_audio_batch_encode: Before incrementing iter: input_frames=310, n_tokens=155, current_iter=1, current_total=155, new_total=310, max_tokens=1500 +audition_audio_batch_encode: KV cache iter incremented to 2 (total_tokens=310, max_tokens=1500) +audition_audio_batch_encode: Final output shape: [4096, 31] +audition_audio_batch_encode: Final output: 31 tokens x 4096 dims +22:56:48.953 stream_prefill(index=1): processing user audio: C:\Users\zhout\w2\minicpmo_omni_work_radeon\omni-minicpmo-1-s53iymbq\fixture_0001.wav +22:56:49.244 stream_prefill(index=1): user audio embedding: n_pos=31 +22:56:49.565 + +c++ finish stream_prefill(index=1). n_past=172, n_keep=72, n_ctx=2048 + +prefill 1 (audio+vision) : 2.60773 s +22:56:49.565 📍 stream_decode 开始: n_past=172, n_keep=72, n_ctx=2048, duplex_mode=0 +22:56:49.565 stream_decode: create tts thread (simplex mode) +22:56:49.565 stream_decode: create t2w thread +22:56:49.565 wait prefill done +22:56:49.565 📍 [单工TTS] 添加 assistant prompt: "<|im_end|> +<|im_start|>assistant + + + + +<|tts_bos|>", n_past=172 +22:56:49.566 T2W thread (C++) started + +22:56:49.568 TTS: 创建单工模式输出目录: ./tools/omni/output/round_000 +22:56:49.569 TTS thread started +22:56:49.728 📍 [单工TTS] assistant prompt 完成, n_past=182 +22:56:49.728 LLM decode: max_tgt_len = 96, n_predict = 96, n_ctx = 2048 +22:56:50.241 LLM: detected end token, set llm_generation_done=true +22:56:50.241 LLM->TTS: text='The square in the image is red.', n_tokens=8, hidden_size=32768, n_embd=4096, token_ids=[785 9334 304 279 2168 374 2518 13] +22:56:50.241 📍 Decode 结束: n_past=191, 剩余空间=1857, 无需滑窗 +22:56:50.241 📍 轮次 1 结束,记录边界于 n_past=191 +22:56:50.242 TTS<-LLM: chunk_idx=0, text='The square in the image is red.', n_tokens=8, hidden_size=32768, token_ids=[785 9334 304 279 2168 374 2518 13] +22:56:50.242 TTS: after queue pop - speek_done=0, llm_finish=1, llm_text.empty=0, token_ids.size=8 +22:56:50.242 TTS: before empty check - response.empty=0, response='The square in the image is red.', llm_finish=1 +Waiting for audio generation to complete... +TTS: chunk file ./tools/omni/output/round_000/tts_wav/tts_output_chunk_0.wav does not exist or is empty +TTS: chunk file ./tools/omni/output/round_000/tts_wav/tts_output_chunk_1.wav does not exist or is empty +TTS: no valid WAV files to merge +22:56:50.242 TTS: DEBUG before has_llm_data - token_ids.size=8, hidden_states.size=32768, n_embd=4096 +22:56:50.242 TTS: has_llm_data=1, token_ids=8, hidden_states=32768, n_embd=4096, llm_finish=1 +22:56:50.243 TTS: n_tokens_orig=8, n_tokens_filtered=8 (filtered 0 special tokens) +22:56:50.278 TTS: saved merged embeddings (text) to ./tools/omni/output/round_000/llm_debug/chunk_0/merged_embeddings.txt +22:56:50.278 TTS Simplex: generating audio tokens for chunk 0 (n_tokens=8, tts_n_embd=768) +22:56:50.278 TTS Simplex: 在 prefill 前添加 audio_bos (chunk_idx=0, new_size=9) +22:56:50.278 TTS Simplex: first chunk - cleared KV cache +22:56:50.278 TTS Simplex: first chunk - cleared tts_all_generated_tokens and tts_token_buffer +22:56:50.339 TTS Simplex: prefill completed, n_past_tts=9 +22:56:50.339 TTS Simplex: sampler created +22:56:50.339 TTS simplex: is_audio_bos=true (first audio token) +22:56:50.364 TTS Simplex Phase1: token 1/500: rel_id=743 +22:56:50.375 TTS Simplex Phase1: token 2/500: rel_id=4218 +22:56:50.386 TTS Simplex Phase1: token 3/500: rel_id=4218 +22:56:50.398 TTS Simplex Phase1: token 4/500: rel_id=4137 +22:56:50.409 TTS Simplex Phase1: token 5/500: rel_id=4137 +22:56:50.551 📍 为下一轮准备: eval <|im_end|>\n<|im_start|>user\n, n_past=196 +22:22:56:56:50.667 TTS Simplex Phase1: yield 25 tokens 到 T2W (step 25, buffer=25) +22:56:50.667 TTS Simplex Phase1: token 25/500: rel_id=3670 +50.667 T2W线程(C++): 轮次切换 (-1 -> 0),更新输出目录 +22:56:50.667 T2W线程(C++): 新输出目录 ./tools/omni/output/round_000/tts_wav +22:56:50.803 TTS Simplex Phase1: EOS token at step 38 +22:56:50.803 TTS Simplex: is_final_text_chunk=true, will enter Phase 2 for text_eos_embed +22:56:50.803 TTS Simplex Phase2: injecting text_eos_embed + audio_bos at n_past=46 +22:56:50.812 TTS Simplex Phase2: text_eos_embed injected, n_past=47 +22:56:50.820 TTS Simplex Phase2: audio_bos injected, n_past=48, starting final generation +22:56:50.968 TTS Simplex Phase2: yield 25 tokens 到 T2W +22:56:51.119 TTS Simplex Phase2: EOS at step 26 (final end) +22:56:51.119 TTS Simplex: chunk 结束,tts_token_buffer 剩余 12 tokens (保留等下一个 chunk) +22:56:51.119 TTS Simplex: is_final_text_chunk=true, flush 剩余 12 tokens 从 tts_token_buffer +22:56:51.119 TTS Simplex: generated 62 audio tokens for chunk 0 +22:56:51.119 TTS Simplex: chunk 0 first tokens: [743 4218 4218 4137 4137 ], last tokens: [2919 1488 4218 4218 4137 ] +22:56:51.119 TTS Simplex: updated tts_n_past_accumulated=74, total_generated_tokens=62 +22:56:51.120 TTS: finished processing all chunks +22:56:51.120 TTS: 单工模式轮次结束,下一轮 round_idx=1 +22:56:51.120 TTS: sent is_final=true to T2W queue (turn end) +22:56:52.992 🎉 首响时间 (First Audio Response): 3426ms +22:56:52.992 T2W线程: wav_0.wav | 0.84s audio | 2323.9ms inference | RTF=2.77 | t=3426ms +22:56:55.205 T2W线程: wav_1.wav | 1.00s audio | 2213.0ms inference | RTF=2.21 | t=5639ms +22:56:57.330 T2W线程: wav_2.wav | 0.76s audio | 2124.0ms inference | RTF=2.79 | t=7764ms +22:56:57.330 T2W线程: 写入结束标记 ./tools/omni/output/round_000/tts_wav/generation_done.flag (last_wav=2) +22:56:57.330 T2W线程: 轮次结束后更新输出目录为 ./tools/omni/output/round_001/tts_wav +22:56:57.404 omni_stop_threads: stop signals sent +22:56:57.404 T2W(C++) 线程: 停止 +[timing] call=0 tokens=28 final=0 token2mel=1999.902ms vocoder=323.940ms total=2323.871ms audio=20160 +[timing] call=1 tokens=28 final=0 token2mel=1832.577ms vocoder=380.356ms total=2212.954ms audio=24000 +[timing] call=2 tokens=15 final=1 token2mel=1868.717ms vocoder=255.300ms total=2124.030ms audio=18240 +Audio generation completed. +llama_perf_context_print: load time = 6067.45 ms +llama_perf_context_print: prompt eval time = 4182.74 ms / 182 tokens ( 22.98 ms per token, 43.51 tokens per second) +llama_perf_context_print: eval time = 510.14 ms / 9 runs ( 56.68 ms per token, 17.64 tokens per second) +llama_perf_context_print: total time = 13742.63 ms / 191 tokens +llama_perf_context_print: graphs reused = 10 +Token2Wav (C++): session released +tts thread end +t2w thread end diff --git a/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_radeon/minicpmo-2-53637554493b4b38af27b722dc48ad51.log b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_radeon/minicpmo-2-53637554493b4b38af27b722dc48ad51.log new file mode 100755 index 000000000..7536419e6 --- /dev/null +++ b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/logs_radeon/minicpmo-2-53637554493b4b38af27b722dc48ad51.log @@ -0,0 +1 @@ +build: 64 (5202b7b) with x86_64-w64-mingw32-gcc-posix (GCC) 13-posix for x86_64-w64-mingw32 diff --git a/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/low_budget_report.json b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/low_budget_report.json new file mode 100644 index 000000000..a4678581c --- /dev/null +++ b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/low_budget_report.json @@ -0,0 +1,45 @@ +{ + "scope": "MiniCPM-o GGUF complete audio+image\u2192text+speech through Omni StageRuntime/StagePool", + "placement": "cpu", + "model_revision": "db25077c33951fe163b42986fba0132e279872a2", + "artifact_sha256": { + "MiniCPM-o-4_5-Q4_K_M.gguf": "1237a97ee081b8abebc47aa7dad565701e8f5f904cdc92f6723ac4281bbc0932", + "audio/MiniCPM-o-4_5-audio-F16.gguf": "d5b188ac7feaf98e17175c3f9bd14bf269301bfd187439fdaa3e3a494fc32ef7", + "vision/MiniCPM-o-4_5-vision-F16.gguf": "1453678cc4e4fe18de241952962e234f265cb8dda780773526103ab8ba82f421", + "tts/MiniCPM-o-4_5-tts-F16.gguf": "c7be3748a863dd6966ae7eed42600b7f41ca67affb03729ff245247f0e5ea088", + "tts/MiniCPM-o-4_5-projector-F16.gguf": "4b1b5b377358a5e594a304ff6ea5d52df606a9ba7d886c4299d232f0c67dd1fd", + "token2wav-gguf/encoder.gguf": "7f8d265da594eaf5e1de2db8f5f1867dbcb0bb75ef5878fadf2952347116f4d0", + "token2wav-gguf/flow_matching.gguf": "eda6069f3edeb5dd3a87fbf2aedb2ddd1b46f3273926c4fcf09b24476a39cab8", + "token2wav-gguf/flow_extra.gguf": "c67611aa7d02500fe395a7798bf0bfdfb55c74d37ba93934ca74d82b4e63f78d", + "token2wav-gguf/hifigan2.gguf": "1b8b3bf5d8d3066aeee4324fdcdd41aefce170d0ee907645858de408d82835c2", + "token2wav-gguf/prompt_cache.gguf": "81fe6f541ebe0b67db06a1e395df928da47991dc9637c2cf47d6c59d5b979f2c" + }, + "cli_sha256": "29247187ddf3b13591cd14cc070e5e25c6bb7547296acc5e8a74e2945811d725", + "reference_sha256": "cf4bb5cd9acbfbf67596d4a53310652b61ef4b7ede1d54eb03ef4882ca40223a", + "input_sha256": { + "audio_wav": "14ee147cbf2ce9afd9e32c8c8228d7cfe11985cd7e63456b2ad33871492aefcc", + "image_jpeg": "22c7ccea466a3f551c512045e6316c7597408d4e0a20205502f55784d977aa8d" + }, + "memory_budget": { + "capacities": { + "host_ram": 32212254720 + }, + "demands": { + "host_ram": 8589934592 + } + }, + "profile_count": 1, + "warmup_count": 0, + "admission_refusal": "ResourceUnavailable: MiniCPM-o weights, state/workspace, I/O and headroom exceed reservation", + "status": "passed", + "ledger_after_shutdown": { + "capacities": { + "host_ram": 32212254720 + }, + "reserved": { + "host_ram": 0 + }, + "owners": [], + "quarantined": [] + } +} diff --git a/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/radeon_output.wav b/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/minicpmo_omni_cpp/radeon_output.wav new file mode 100644 index 0000000000000000000000000000000000000000..f28a3ab3239e7ca18994d42ace34dca31ff51662 GIT binary patch literal 124844 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 str: + digest = hashlib.sha256() + with path.open("rb") as source: + for block in iter(lambda: source.read(8 << 20), b""): + digest.update(block) + return digest.hexdigest() + + +def _wav_format(data: bytes, *, sample_rate: int, max_frames: int) -> int: + with wave.open(io.BytesIO(data), "rb") as source: + fmt = (source.getnchannels(), source.getsampwidth(), source.getframerate()) + frames = source.getnframes() + if fmt != (1, 2, sample_rate) or not 0 < frames <= max_frames: + raise ValueError(f"expected bounded mono PCM16 {sample_rate} Hz WAV") + if len(source.readframes(frames)) != frames * 2: + raise ValueError("truncated input WAV") + return frames + + +def _jpeg_size(data: bytes) -> tuple[int, int]: + with Image.open(io.BytesIO(data)) as image: + if image.format != "JPEG": + raise ValueError("MiniCPM-o image input must be JPEG") + size = image.size + image.verify() + return size + + +def _tree_bytes(path: Path) -> int: + total = 0 + for item in path.rglob("*"): + try: + if item.is_file(): + total += item.stat().st_size + except FileNotFoundError: + pass # The worker may atomically replace an output while we sample. + return total + + +def _read_result(work_dir: Path, max_audio_s: float, max_wav_bytes: int, + max_text_bytes: int) -> tuple[str, bytes, int]: + round_dir = work_dir / "tools" / "omni" / "output" / "round_000" + wav_dir = round_dir / "tts_wav" + if not (wav_dir / "generation_done.flag").is_file(): + raise RuntimeError("MiniCPM-o audio generation is incomplete") + chunks = sorted( + wav_dir.glob("wav_*.wav"), + key=lambda path: int(_WAV_NAME.fullmatch(path.name).group(1)), + ) + if not chunks or len(chunks) > 256 or [item.name for item in chunks] != [ + f"wav_{index}.wav" for index in range(len(chunks)) + ]: + raise RuntimeError("MiniCPM-o WAV chunk sequence has gaps or is unbounded") + pcm_parts: list[bytes] = [] + frames = 0 + for path in chunks: + with wave.open(str(path), "rb") as source: + fmt = (source.getnchannels(), source.getsampwidth(), source.getframerate()) + count = source.getnframes() + if fmt != (1, 2, 24000) or not 0 < count <= 24000 * 10: + raise RuntimeError(f"MiniCPM-o invalid WAV chunk: {path.name}") + pcm = source.readframes(count) + if len(pcm) != count * 2: + raise RuntimeError(f"MiniCPM-o truncated WAV chunk: {path.name}") + frames += count + if frames > max_audio_s * 24000 or frames * 2 > max_wav_bytes: + raise ResourceUnavailable("MiniCPM-o speech exceeds admitted output bound") + pcm_parts.append(pcm) + pcm = b"".join(pcm_parts) + if not np.any(np.frombuffer(pcm, dtype=" max_text_bytes: + raise ResourceUnavailable("MiniCPM-o text is empty or exceeds admitted bound") + return text, pcm, frames + + +class MiniCPMOCppStageClient(StageClientBase): + def __init__(self, metadata, config: dict, ledger, reservation) -> None: + for name, value in vars(metadata).items(): + setattr(self, name, value) + self.stage_type = "graph" + self._ledger, self._reservation = ledger, reservation + self._generation = uuid.uuid4().hex + self._closed = False + self._active: str | None = None + self._task: asyncio.Task | None = None + self._output: OmniRequestOutput | None = None + self._proc: subprocess.Popen | None = None + self._lock = threading.Lock() + self._epoch = 0 + self._config = dict(config) + self._placement = str(config["placement"]) + self._memory_pool = str(config.get("memory_pool", "host_ram")) + self._context_tokens = int(config.get("context_tokens", 2048)) + self._max_new_tokens = int(config.get("max_new_tokens", 128)) + self._max_input_bytes = int(config.get("max_input_bytes", 2 << 20)) + self._max_wav_bytes = int(config.get("max_wav_bytes", 2 << 20)) + self._max_text_bytes = int(config.get("max_text_bytes", 16 << 10)) + self._max_work_bytes = int(config.get("max_work_bytes", 64 << 20)) + self._max_input_audio_s = float(config.get("max_input_audio_s", 10)) + self._max_output_audio_s = float(config.get("max_output_audio_s", 20)) + self._request_timeout_s = float(config.get("request_timeout_s", 300)) + self._t2w_wait_seconds = int(config.get("t2w_wait_seconds", 180)) + self._retain_workdir = bool(config.get("retain_workdir", False)) + try: + if self._placement not in ("cpu", "radeon-hybrid"): + raise ValueError("MiniCPM-o placement must be cpu or radeon-hybrid") + if self._placement == "radeon-hybrid" and ( + config.get("ggml_vk_visible_devices") != "1" + or config.get("expected_gpu_name") != "AMD Radeon(TM) 890M Graphics" + ): + raise ValueError("Radeon stage requires the pinned Vulkan device name and selector") + if not ( + 0 < self._max_new_tokens < self._context_tokens + and 0 < self._max_input_audio_s <= 30 + and 0 < self._max_output_audio_s <= 120 + and 0 < self._max_input_bytes <= 16 << 20 + and 0 < self._max_wav_bytes <= self._max_work_bytes + and 0 < self._max_text_bytes <= self._max_work_bytes + and 0 < self._t2w_wait_seconds < self._request_timeout_s <= 3600 + ): + raise ValueError("invalid MiniCPM-o context, media, time or output bound") + if self._memory_pool not in reservation.demands: + raise ResourceUnavailable("MiniCPM-o shared-RAM pool absent from reservation") + demand = int(reservation.demands[self._memory_pool]) + if psutil.virtual_memory().available < demand: + raise ResourceUnavailable("available host/shared RAM below MiniCPM-o reservation") + self._model_dir = Path(config["model_dir"]).resolve(strict=True) + self._binary = Path(config["cli_bin"]).resolve(strict=True) + self._reference_wav = Path(config["reference_wav"]).resolve(strict=True) + expected = dict(config["artifact_sha256"]) + if set(expected) != set(_ARTIFACTS): + raise ValueError("MiniCPM-o requires the exact ten-artifact manifest") + self._artifacts = {name: self._model_dir / name for name in _ARTIFACTS} + for name, path in self._artifacts.items(): + if not path.is_file() or _sha256(path) != str(expected[name]).lower(): + raise ValueError(f"MiniCPM-o GGUF differs from declared hash: {name}") + for path, digest in ( + (self._binary, str(config["cli_sha256"]).lower()), + (self._reference_wav, str(config["reference_sha256"]).lower()), + ): + if _sha256(path) != digest: + raise ValueError(f"MiniCPM-o executable/reference differs: {path.name}") + _wav_format(self._reference_wav.read_bytes(), sample_rate=16000, + max_frames=16000 * 10) + overhead = int(config["memory_overhead_bytes"]) + total_weights = sum(path.stat().st_size for path in self._artifacts.values()) + if overhead <= 0 or total_weights + overhead + self._max_work_bytes > demand: + raise ResourceUnavailable("MiniCPM-o weights, state/workspace, I/O and headroom exceed reservation") + help_result = subprocess.run( + [str(self._binary), "--help"], stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, timeout=10, check=True, + creationflags=subprocess.CREATE_NO_WINDOW if os.name == "nt" else 0, + ) + if not all(flag in help_result.stdout for flag in ( + b"--max-new-tokens", b"--t2w-device", b"--t2w-wait-seconds" + )): + raise ValueError("MiniCPM-o CLI lacks bounded-generation or completion support") + self._work_root = Path(config["work_root"]).resolve() + self._log_root = Path(config["log_root"]).resolve() + self._work_root.mkdir(parents=True, exist_ok=True) + self._log_root.mkdir(parents=True, exist_ok=True) + self.execution_plan = { + "backend": "external.minicpmo.gguf.v1", + "stage_id": self.stage_id, + "worker_generation": self._generation, + "model_revision": str(config["model_revision"]), + "artifact_sha256": {key: str(value).lower() for key, value in expected.items()}, + "cli_sha256": str(config["cli_sha256"]).lower(), + "requested_placement": self._placement, + "ggml_vk_visible_devices": config.get("ggml_vk_visible_devices"), + "shared_ram_reservation": dict(reservation.demands), + "weights_bytes": total_weights, + "memory_overhead_bytes": overhead, + "context_tokens": self._context_tokens, + "max_new_tokens": self._max_new_tokens, + "request_capacity": 1, + "stateful_session": "C++-owned within one request; discarded after completion", + "placement_evidence": "pending first request", + } + except BaseException: + self.shutdown() + raise + + async def add_request_async(self, request_id: str, prompt: Any, params: Any = None) -> None: + self.check_health() + if self._active is not None: + raise ResourceUnavailable("MiniCPM-o stage has an unacknowledged request; capacity is one") + if not isinstance(prompt, dict): + raise ValueError("MiniCPM-o request must contain audio_wav and image_jpeg bytes") + audio, image = prompt.get("audio_wav"), prompt.get("image_jpeg") + if not isinstance(audio, (bytes, bytearray)) or not isinstance(image, (bytes, bytearray)): + raise ValueError("MiniCPM-o media must use bounded byte buffers") + audio, image = bytes(audio), bytes(image) + if not 0 < len(audio) <= self._max_input_bytes or not 0 < len(image) <= self._max_input_bytes: + raise ResourceUnavailable("MiniCPM-o input exceeds admitted transfer bound") + _wav_format(audio, sample_rate=16000, + max_frames=int(self._max_input_audio_s * 16000)) + if _jpeg_size(image) != (448, 448): + raise ValueError("MiniCPM-o v1 stage accepts only a 448x448 JPEG") + self._epoch += 1 + request = StageRequest(request_id, self.stage_id, self._epoch, self._generation) + self._active = request_id + self._task = asyncio.create_task( + self._run(request, audio, image), name=f"minicpmo-{request_id}" + ) + + async def _run(self, request: StageRequest, audio: bytes, image: bytes) -> None: + try: + result = await asyncio.to_thread(self._execute, request, audio, image) + samples = np.frombuffer(result["pcm"], dtype=" dict: + work_dir = Path(tempfile.mkdtemp(prefix=f"omni-minicpmo-{request.epoch}-", dir=self._work_root)) + if not work_dir.resolve().is_relative_to(self._work_root): + raise RuntimeError("MiniCPM-o work directory escaped its declared root") + log_path = self._log_root / f"minicpmo-{request.epoch}-{uuid.uuid4().hex}.log" + started = time.perf_counter() + peak_rss = 0 + try: + shutil.copyfile(self._reference_wav, work_dir / "fixture_0000.wav") + (work_dir / "fixture_0001.wav").write_bytes(audio) + (work_dir / "fixture_0001.jpg").write_bytes(image) + command = [ + str(self._binary), "-m", str(self._artifacts[_ARTIFACTS[0]]), + "-ngl", "0" if self._placement == "cpu" else "99", + "-c", str(self._context_tokens), + "--max-new-tokens", str(self._max_new_tokens), + "--omni", "--t2w-device", "cpu", + "--t2w-wait-seconds", str(self._t2w_wait_seconds), + "--ref-audio", str(self._reference_wav), + "--test", str(work_dir / "fixture_"), "2", + ] + env = os.environ.copy() + env["GGML_VK_VISIBLE_DEVICES"] = ( + "" if self._placement == "cpu" else "1" + ) + with log_path.open("wb") as log: + with self._lock: + if self._closed or self._epoch != request.epoch: + raise RuntimeError("MiniCPM-o request was cancelled before launch") + self._proc = subprocess.Popen( + command, cwd=work_dir, stdout=log, stderr=subprocess.STDOUT, + env=env, + creationflags=subprocess.CREATE_NO_WINDOW if os.name == "nt" else 0, + ) + proc = self._proc + process = psutil.Process(proc.pid) + deadline = time.monotonic() + self._request_timeout_s + while proc.poll() is None: + if time.monotonic() >= deadline: + self._kill_process(proc) + raise TimeoutError("MiniCPM-o complete request timed out") + if log_path.stat().st_size + _tree_bytes(work_dir) > self._max_work_bytes: + self._kill_process(proc) + raise ResourceUnavailable("MiniCPM-o worker exceeded admitted file/I/O bound") + try: + peak_rss = max(peak_rss, process.memory_info().rss) + except psutil.NoSuchProcess: + pass + if peak_rss > self._reservation.demands[self._memory_pool]: + self._kill_process(proc) + raise ResourceUnavailable("MiniCPM-o worker RSS exceeded shared-RAM reservation") + try: + proc.wait(timeout=0.1) + except subprocess.TimeoutExpired: + pass + if proc.returncode != 0: + raise RuntimeError(f"MiniCPM-o CLI exited {proc.returncode}; see {log_path}") + log_text = log_path.read_text(encoding="utf-8", errors="replace") + if self._placement == "cpu": + required = ( + "GPU layers: 0", "vision_ctx: vision using CPU backend", + "Token2Wav device: cpu", + ) + else: + required = ( + "GPU layers: 99", + "using device Vulkan0 (AMD Radeon(TM) 890M Graphics)", + "offloaded 37/37 layers to GPU", + "vision_ctx: vision using Vulkan0 backend", + "TTS model: loading with n_gpu_layers=0", + "Token2Wav: non-CUDA backend, vocoder using CPU", + ) + if any(item not in log_text for item in required): + raise RuntimeError("REFUSE_DEVICE_PLACEMENT: MiniCPM-o did not use declared CPU/Radeon route") + if not all(item in log_text for item in ( + "stream_prefill(index=1): processing user audio:", + "stream_prefill: prefilled 1 vision chunks", + "Audio generation completed.", + )): + raise RuntimeError("MiniCPM-o complete input/output path not observed") + text, pcm, frames = _read_result( + work_dir, self._max_output_audio_s, + self._max_wav_bytes, self._max_text_bytes, + ) + self.execution_plan["placement_evidence"] = { + "observed": self._placement, + "worker_pid": proc.pid, + "peak_sampled_rss_bytes": peak_rss, + "worker_log": str(log_path), + } + return { + "text": text, "pcm": pcm, "frames": frames, + "peak_rss": peak_rss, "wall_s": time.perf_counter() - started, + "log_path": log_path, + } + finally: + with self._lock: + proc = self._proc + if proc is not None: + self._kill_process(proc) + with self._lock: + if self._proc is proc: + self._proc = None + if not self._retain_workdir: + if not work_dir.resolve().is_relative_to(self._work_root): + raise RuntimeError("refusing cleanup outside MiniCPM-o work root") + shutil.rmtree(work_dir) + + @staticmethod + def _kill_process(proc: subprocess.Popen) -> bool: + try: + if proc.poll() is None: + proc.terminate() + try: + proc.wait(timeout=5) + except subprocess.TimeoutExpired: + proc.kill() + proc.wait(timeout=5) + except OSError: + return False + return proc.poll() is not None + + def get_graph_output_nowait(self) -> OmniRequestOutput | None: + output, self._output = self._output, None + return output + + def acknowledge(self, request_id: str, epoch: int, generation: str) -> None: + if ( + self._active == request_id and epoch == self._epoch + and generation == self._generation + and (self._task is None or self._task.done()) + ): + self._active = None + self._task = None + + async def abort_requests_async(self, request_ids: list[str]) -> None: + if self._active not in request_ids: + return + self._epoch += 1 + self._output = None + with self._lock: + self._closed = True + proc = self._proc + drained = await asyncio.to_thread(self._kill_process, proc) if proc else True + if self._task is not None and not self._task.done(): + done, _ = await asyncio.wait({self._task}, timeout=5) + if done: + self._ledger.release(self._reservation, drained=drained) + else: + self._ledger.release(self._reservation, drained=False) + self._task.add_done_callback( + lambda task: self._ledger.release( + self._reservation, drained=drained and not task.cancelled() + ) + ) + self._active = None + + def check_health(self) -> None: + if self._closed: + from vllm.v1.engine.exceptions import EngineDeadError + + raise EngineDeadError() + + async def collective_rpc_async(self, method, timeout=None, args=(), kwargs=None): + raise NotImplementedError(f"MiniCPM-o backend does not implement collective RPC {method}") + + def shutdown(self) -> None: + with self._lock: + self._closed = True + proc = self._proc + drained = self._kill_process(proc) if proc else True + self._output = None + task = self._task + if task is not None and not task.done(): + self._ledger.release(self._reservation, drained=False) + task.add_done_callback( + lambda done: self._ledger.release( + self._reservation, drained=drained and not done.cancelled() + ) + ) + else: + self._ledger.release(self._reservation, drained=drained) diff --git a/vllm_omni/model_executor/models/minicpmo_4_5/pipeline.py b/vllm_omni/model_executor/models/minicpmo_4_5/pipeline.py index 0ca61a346..e05d1a870 100644 --- a/vllm_omni/model_executor/models/minicpmo_4_5/pipeline.py +++ b/vllm_omni/model_executor/models/minicpmo_4_5/pipeline.py @@ -87,3 +87,21 @@ MINICPMO_4_5_PIPELINE = PipelineConfig( ), ), ) + + +# The GGUF C++ worker owns the complete autoregressive/vision/audio/TTS session. +# This is a separate whole-session deployment of MiniCPM-o, not a replacement +# for the three-stage vLLM checkpoint above. Omni's graph path controls one +# bounded request, resource reservation and terminal audio acknowledgement. +MINICPMO_4_5_GGUF_WHOLE_PIPELINE = PipelineConfig( + model_type="minicpmo_4_5_gguf_whole", + stages=( + StagePipelineConfig( + stage_id=0, + model_stage="audio", + execution_type=StageExecutionType.GRAPH, + final_output=True, + final_output_type="audio", + ), + ), +)