Qualify scoped WSL CPU Qwen3-TTS Omni complete requests

This commit is contained in:
tzhouam committed 2026-09-24 00:41:14 +08:00
1 parent 10ae2818c7
commit e6ea35ca12
28 files changed
+15097 -9

No files matched your search

@@ -8,6 +8,7 @@ import asyncio
import hashlib
import json
import math
import platform
import time
import wave
from pathlib import Path
@@ -41,6 +42,9 @@ async def main() -> None:
parser.add_argument("--repeats", type=int, default=20)
parser.add_argument("--reserve-gib", type=int, default=10)
parser.add_argument("--abort-check", action="store_true")
parser.add_argument("--allow-platform-variation", action="store_true")
parser.add_argument("--overlay-marker-sha256")
parser.add_argument("--expect-admission-refusal", action="store_true")
args = parser.parse_args()
if args.warmups < 0 or args.repeats <= 0 or not 0 < args.reserve_gib <= 16:
parser.error("invalid profile or budget")
@@ -55,6 +59,7 @@ async def main() -> None:
"python_sha256": args.python_sha256,
"model_dir": args.model_dir,
"overlay_dir": args.overlay_dir,
"overlay_marker_sha256": args.overlay_marker_sha256,
"talker_sha256": args.talker_sha256,
"tokenizer_sha256": args.tokenizer_sha256,
"log_file": args.server_log,
@@ -81,7 +86,9 @@ async def main() -> None:
configs = [stage.to_omegaconf() for stage in merge_pipeline_deploy(pipeline, deploy)]
runtime = StageRuntime(configs, "local-qwen-tts-cpu", "", stage_init_timeout=180, async_chunk=False)
report = {
"scope": "complete resident native Windows CPU Qwen3-TTS text-to-WAV through Omni",
"scope": "complete resident local CPU Qwen3-TTS text-to-WAV through Omni",
"host_os": platform.platform(),
"allow_platform_variation": args.allow_platform_variation,
"warmup_count": args.warmups,
"measured_count": args.repeats,
"memory_budget": deploy.stages[0].resource_budget,
@@ -90,6 +97,16 @@ async def main() -> None:
stop_sampling = asyncio.Event()
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("Qwen CPU TTS accepted an insufficient reservation")
runtime.initialize()
report["startup_s"] = time.perf_counter() - started
pool = runtime.stage_pools[0]
@@ -168,7 +185,7 @@ async def main() -> None:
report["standalone_pcm_parity"] = [
row["pcm_sha256"] == digest for row, digest in zip(report["checks"], expected)
]
if report["standalone_pcm_parity"] != [True, True]:
if report["standalone_pcm_parity"] != [True, True] and not args.allow_platform_variation:
raise RuntimeError("CPU Omni PCM differs from the same checkpoint's standalone output")
report["warmups"] = [await request_one(first) for _ in range(args.warmups)]
report["measured"] = [await request_one(first, save=i == 0) for i in range(args.repeats)]
@@ -22,6 +22,12 @@ async def main() -> None:
"tokenizer_sha256", "server_log", "output_report",
):
parser.add_argument("--" + name.replace("_", "-"), required=True)
parser.add_argument("--overlay-marker-sha256")
parser.add_argument("--expected-frames", type=int, default=109440)
parser.add_argument(
"--expected-pcm-sha256",
default="c8a49b5c73efd642a1eb04be973d6aefdc8ed9cfd18b34ff67690b8464906bed",
)
args = parser.parse_args()
from vllm_omni.entrypoints.async_omni import AsyncOmni
@@ -33,6 +39,7 @@ async def main() -> None:
"python_sha256": args.python_sha256,
"model_dir": args.model_dir,
"overlay_dir": args.overlay_dir,
"overlay_marker_sha256": args.overlay_marker_sha256,
"talker_sha256": args.talker_sha256,
"tokenizer_sha256": args.tokenizer_sha256,
"log_file": args.server_log,
@@ -87,8 +94,8 @@ async def main() -> None:
report["request_wall_s"] = time.perf_counter() - started
report["outputs"] = outputs
assert len(outputs) == 1 and outputs[0]["request_id"] == "public-cpu-tts-1"
assert outputs[0]["sample_rate"] == 24000 and outputs[0]["frames"] == 109440
assert outputs[0]["pcm_sha256"] == "c8a49b5c73efd642a1eb04be973d6aefdc8ed9cfd18b34ff67690b8464906bed"
assert outputs[0]["sample_rate"] == 24000 and outputs[0]["frames"] == args.expected_frames
assert outputs[0]["pcm_sha256"] == args.expected_pcm_sha256
report["status"] = "passed"
except BaseException as exc:
report["status"] = "failed"
@@ -4,6 +4,7 @@ This extends the [60-cell device × model matrix](../e2e_profiling_20260922/evid
| Device / model | Verified depth | Observed output and time | Remaining gate |
|---|---|---|---|
| WSL HX370 CPU / Qwen3-TTS 0.6B CustomVoice BF16 | Scoped complete-request Omni resident CPU whole-session stage (P for two named texts; not playable streaming) | One warmup + 20 serial requests returned identical 3.44 s WAVs; nearest-rank complete-request wall p50/p95 8.27/8.47 s (RTF 2.40/2.46), excluding 19.82 s startup. One pinned Whisper tiny.en transcription matched the reference (WER 0); public `AsyncOmni` audio, 10 GiB admission, 4 GiB refusal and cancellation drain passed. The WSL PCM differs from the native Windows output for the same checkpoint/settings. | Cross-OS numerical/quality investigation, playable streaming, post-cancel restart, loading peak, concurrency and sustained power; [raw evidence](evidence/qwen_tts_omni_wsl_cpu/README.md). |
| WSL HX370 CPU / MiniCPM-o 4.5 Q4_K_M/F16 GGUF | Scoped complete-request Omni C++ whole-session graph stage (P for one synthetic combined spoken-question+image input; CPU-only model execution) | All 20 measured requests after one warmup answered the red-square question correctly with complete nonzero 24 kHz speech. Nearest-rank complete-request wall p50/p95 22.67/24.83 s; audio duration 1.60–2.92 s, maximum sampled worker RSS 13.70 GB. One WAV independently transcribed exactly (Whisper tiny.en WER 0). 24 GiB admission, 8 GiB refusal and cancellation with zero remaining ledger passed. | Real multimodal suites, playable streaming, speech alignment, post-cancel restart, loading peak, concurrency and sustained power; [raw evidence](evidence/minicpmo_omni_wsl_cpu/README.md). |
| Native Windows HX370 CPU / MiniCPM-o 4.5 Q4_K_M/F16 GGUF | Scoped complete-request Omni C++ whole-session graph stage (P for one synthetic combined audio+image input) | Correct red-square answer, 2.24 s 24 kHz WAV; one cold request 24.34 s, sampled RSS 13.11 GB. 24 GiB admission, 8 GiB refusal and in-flight cancellation with zero remaining reservation passed. | Real multimodal suites, playable streaming, repeated latency, loading peak, post-cancel restart and sustained power; [raw evidence](evidence/minicpmo_omni_cpp/README.md). |
| Native Windows HX370 CPU+Radeon 890M / same MiniCPM-o GGUF | Scoped complete-request Omni hybrid graph stage (P for one synthetic combined audio+image input) | Correct red-square answer, 2.60 s 24 kHz WAV; one cold request 18.27 s, sampled RSS 15.57 GB. Log verifies Radeon language+vision and CPU TTS/Token2Wav; cancellation drained without stale output or reservation. | Real multimodal suites, playable streaming, repeated/concurrent latency, loading peak and sustained power; [raw evidence](evidence/minicpmo_omni_cpp/README.md). |
@@ -0,0 +1,76 @@
# WSL CPU Qwen3-TTS complete requests through Omni
This is a scoped text-to-complete-WAV pass on Ryzen AI 9 HX 370 under Ubuntu
26.04/WSL2 kernel `6.18.33.2-microsoft-standard-WSL2`. The public
`AsyncOmni` API and `StageRuntime` used the existing
`external.qwen_tts.cpu.v1` whole-session stage, with a resident isolated
PyTorch worker. The worker's model parameters and output are CPU-only BF16/SDPA,
eight threads, `Ryan`/English, seed 42 and `max_new_tokens=64`. CUDA is masked;
no Radeon, RTX or NPU execution is claimed. The Omni controller uses installed
vLLM 0.29.0; the worker uses PyTorch 2.13.0+cu130 on CPU, `qwen-tts` 0.1.1 and
Transformers 4.57.3. Its exact [overlay manifest](overlay_manifest.json) and
[optional-kernels CPU shim](kernels/__init__.py) are retained. The local SoX
Python package emitted a missing SoX CLI warning; the named text-to-WAV path
completed, while SoX-dependent audio-input paths were not tested.
The checkpoint is Qwen3-TTS-12Hz-0.6B-CustomVoice revision
`85e237c12c027371202489a0ec509ded67b5e4b5`, with talker SHA256
`bc3c7e785eb961179c25450d1acff03f839e0002f2f3a5aeb67b5735c0fa2adb`
and speech-tokenizer SHA256
`836b7b357f5ea43e889936a3709af68dfe3751881acefe4ecf0dbd30ba571258`.
The stage checked both, the declared interpreter hash and the optional shim
hash before accepting requests. The [profile report](profile20.json) records
the worker's package versions, actual CPU placement and loaded memory.
| Check | WSL CPU observation | Evidence |
|---|---|---|
| Two named complete requests | “Hello from the local computer.” returned 82,560 frames (3.44 s); “The blue car is parked beside the library.” returned 80,640 frames (3.36 s), both 24 kHz mono WAVs. | [report](profile20.json), [worker log](profile20_worker.log) |
| Serial profile | One warmup excluded; **20/20** measured first-sentence requests returned the same PCM SHA256. Nearest-rank complete-request wall p50/p95 **8.27/8.47 s** for 3.44 s audio (RTF 2.40/2.46). These are resident-worker times after 19.82 s stage startup, not first-audio latency. | [all timings and memory samples](profile20.json), [first measured WAV](profile20.wav) |
| Independent speech proxy | Pinned Whisper tiny.en transcribed the first measured WAV as “Hello from the local computer!”, WER 0 against the stated sentence. This covers one output, not perceptual or speaker quality. | [ASR report](profile20_asr.json) |
| Public API | `AsyncOmni.generate` returned one terminal audio event with the same 82,560-frame PCM hash as the measured stage run. Startup was 20.29 s; the one public request took 12.10 s. | [public report](public_report.json), [worker log](public_worker.log) |
| Admission and cancellation | A 10 GiB host-RAM reservation from a declared 16 GiB pool passed; 4 GiB was refused before worker launch. In-flight cancellation left no stale output, exited the worker and returned the ledger to zero. | [refusal report](low_budget_report.json), [profile report](profile20.json) |
The two WSL WAV hashes and durations **differ from the same-checkpoint native
Windows CPU outputs** recorded [here](../qwen_tts_omni_cpu/README.md), despite
matching declared BF16 settings and seed. The WSL profile's own 20 repeated
outputs are identical. The cause of the cross-OS difference is not established,
so Windows PCM parity is not claimed. The first WSL output passed the named ASR
proxy, but broader speech quality and numerical agreement remain open.
A [post-portability-change native Windows regression](windows_regression_report.json)
repeated the two named requests and one measured request with the original
Windows pins: both standalone PCM parity checks still passed, in-flight
cancellation drained the worker, and the ledger returned to zero. Its
[worker log](windows_regression_worker.log) and [WAV](windows_regression.wav)
are retained. This verifies the launch-path change did not alter the already
qualified Windows fixture; it does not explain the WSL waveform difference.
The 0.25 s profile samples observed at most 3.39 GB summed process-tree RSS;
Linux's `psutil` private-memory fallback used RSS, so that column is not a
separate private-memory measurement. The samples do not prove loading peak,
unique physical RAM, pagefile peak or concurrent admission. No power mode or
thermal history was captured. The worker returns complete WAVs only: playable
streaming, post-cancel restart, larger prompts and sustained real-time use are
unqualified; measured RTF remains above one.
The [first failed attempt](attempt1_report.json) resolved the Linux virtualenv
`python` symlink to a bare interpreter, which lost the venv packages. The
adapter now preserves the declared launch path while hashing its target. The
[second failed attempt](attempt2_report.json) produced both complete WAVs but
hit the probe's Windows-only PCM assertion; `--allow-platform-variation` now
records that difference explicitly. The [original logs](attempt1_driver.log),
[worker error](attempt1_worker.log), [second driver](attempt2_driver.log) and
[second worker](attempt2_worker.log) remain available.
Reproduce with
[`probe_omni_qwen_tts_cpu.py`](../../../../experiments/probe_omni_qwen_tts_cpu.py)
and [`probe_omni_qwen_tts_cpu_entrypoint.py`](../../../../experiments/probe_omni_qwen_tts_cpu_entrypoint.py)
using the checkpoint and hashes above, the recorded Python interpreter hash
`021044895e95be79dc2f110367607e684119afbc8ce75f6f0eec94844e0acec7`,
the pinned overlay packages in the manifest, and a copy of the shim at
`<overlay>/kernels/__init__.py`. Pass its SHA256
`e155388b1045b573082534132778828a71203522f95a22680f8245362f1e06ee`
as `--overlay-marker-sha256`. The serial profile used
`--warmups 1 --repeats 20 --abort-check --allow-platform-variation`; the
public check used `--expected-frames 82560` and PCM SHA256
`66ca76a468807381c208b21ba458e5005510c752efa89323ee909749047ab1db`.
@@ -0,0 +1,82 @@
INFO 09-24 00:25:57 [patch.py:259] NVFP4 W4A4 weight_scale NaN-clamp: installed.
INFO 09-24 00:25:57 [patch.py:510] inductor factorable-divisibility patch: installed.
INFO 09-24 00:25:57 [patch.py:589] [cumem-cuda] CuMemAllocator._python_free_callback patched: asleep guard extended to all platforms.
INFO 09-24 00:25:58 [stage_init_utils.py:768] [stage_init] Set VLLM_WORKER_MULTIPROC_METHOD=spawn
WARNING 09-24 00:25:58 [stage_init_utils.py:1887] [stage_init] Failed to load transfer config: [Errno 21] Is a directory: '/home/zhout/project/edge_infer/vllm-omni-edge'
ERROR 09-24 00:26:11 [stage_runtime.py:265] [StageRuntime] Stage initialization failed; shutting down 0 initialized client(s)
ERROR 09-24 00:26:11 [stage_runtime.py:265] Traceback (most recent call last):
ERROR 09-24 00:26:11 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 252, in initialize
ERROR 09-24 00:26:11 [stage_runtime.py:265] initialized_clients = self._initialize_stage_replicas(stage_plans, self._stage_init_timeout)
ERROR 09-24 00:26:11 [stage_runtime.py:265] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERROR 09-24 00:26:11 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 589, in _initialize_stage_replicas
ERROR 09-24 00:26:11 [stage_runtime.py:265] raise primary_exc
ERROR 09-24 00:26:11 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 550, in _init_group
ERROR 09-24 00:26:11 [stage_runtime.py:265] client = self._initialize_replica(
ERROR 09-24 00:26:11 [stage_runtime.py:265] ^^^^^^^^^^^^^^^^^^^^^^^^^
ERROR 09-24 00:26:11 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 817, in _initialize_replica
ERROR 09-24 00:26:11 [stage_runtime.py:265] return create_graph_client(
ERROR 09-24 00:26:11 [stage_runtime.py:265] ^^^^^^^^^^^^^^^^^^^^
ERROR 09-24 00:26:11 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/backends/__init__.py", line 23, in create_graph_client
ERROR 09-24 00:26:11 [stage_runtime.py:265] return QwenTTSCPUStageClient(metadata, backend, ledger, reservation)
ERROR 09-24 00:26:11 [stage_runtime.py:265] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERROR 09-24 00:26:11 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/backends/qwen_tts_cpu.py", line 107, in __init__
ERROR 09-24 00:26:11 [stage_runtime.py:265] raise RuntimeError(f"CPU TTS worker exited during load; see {self._log_path}")
ERROR 09-24 00:26:11 [stage_runtime.py:265] RuntimeError: CPU TTS worker exited during load; see /home/zhout/project/edge_infer/vllm-omni-edge/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/qwen_tts_omni_wsl_cpu/worker.log
{
"scope": "complete resident native Windows CPU Qwen3-TTS text-to-WAV through Omni",
"warmup_count": 0,
"measured_count": 1,
"memory_budget": {
"capacities": {
"host_ram": 17179869184
},
"demands": {
"host_ram": 10737418240
}
},
"status": "failed",
"error": "RuntimeError: CPU TTS worker exited during load; see /home/zhout/project/edge_infer/vllm-omni-edge/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/qwen_tts_omni_wsl_cpu/worker.log",
"ledger_after_shutdown": {
"capacities": {
"host_ram": 17179869184
},
"reserved": {
"host_ram": 0
},
"owners": [],
"quarantined": []
}
}
Traceback (most recent call last):
File "/home/zhout/project/edge_infer/vllm-omni-edge/benchmarks/edge_harness/experiments/probe_omni_qwen_tts_cpu.py", line 216, in <module>
asyncio.run(main())
File "/home/zhout/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/asyncio/runners.py", line 195, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/home/zhout/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zhout/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/asyncio/base_events.py", line 691, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/home/zhout/project/edge_infer/vllm-omni-edge/benchmarks/edge_harness/experiments/probe_omni_qwen_tts_cpu.py", line 93, in main
runtime.initialize()
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 278, in initialize
raise exc
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 252, in initialize
initialized_clients = self._initialize_stage_replicas(stage_plans, self._stage_init_timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 589, in _initialize_stage_replicas
raise primary_exc
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 550, in _init_group
client = self._initialize_replica(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 817, in _initialize_replica
return create_graph_client(
^^^^^^^^^^^^^^^^^^^^
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/backends/__init__.py", line 23, in create_graph_client
return QwenTTSCPUStageClient(metadata, backend, ledger, reservation)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/backends/qwen_tts_cpu.py", line 107, in __init__
raise RuntimeError(f"CPU TTS worker exited during load; see {self._log_path}")
RuntimeError: CPU TTS worker exited during load; see /home/zhout/project/edge_infer/vllm-omni-edge/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/qwen_tts_omni_wsl_cpu/worker.log
@@ -0,0 +1,25 @@
{
"scope": "complete resident native Windows CPU Qwen3-TTS text-to-WAV through Omni",
"warmup_count": 0,
"measured_count": 1,
"memory_budget": {
"capacities": {
"host_ram": 17179869184
},
"demands": {
"host_ram": 10737418240
}
},
"status": "failed",
"error": "RuntimeError: CPU TTS worker exited during load; see /home/zhout/project/edge_infer/vllm-omni-edge/benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/qwen_tts_omni_wsl_cpu/worker.log",
"ledger_after_shutdown": {
"capacities": {
"host_ram": 17179869184
},
"reserved": {
"host_ram": 0
},
"owners": [],
"quarantined": []
}
}
@@ -0,0 +1,6 @@
Traceback (most recent call last):
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/backends/qwen_tts_cpu_worker.py", line 138, in <module>
main()
File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/backends/qwen_tts_cpu_worker.py", line 36, in main
import numpy as np
ModuleNotFoundError: No module named 'numpy'
@@ -0,0 +1,137 @@
INFO 09-24 00:27:04 [patch.py:259] NVFP4 W4A4 weight_scale NaN-clamp: installed.
INFO 09-24 00:27:04 [patch.py:510] inductor factorable-divisibility patch: installed.
INFO 09-24 00:27:04 [patch.py:589] [cumem-cuda] CuMemAllocator._python_free_callback patched: asleep guard extended to all platforms.
INFO 09-24 00:27:05 [stage_init_utils.py:768] [stage_init] Set VLLM_WORKER_MULTIPROC_METHOD=spawn
WARNING 09-24 00:27:05 [stage_init_utils.py:1887] [stage_init] Failed to load transfer config: [Errno 21] Is a directory: '/home/zhout/project/edge_infer/vllm-omni-edge'
{
"scope": "complete resident native Windows CPU Qwen3-TTS text-to-WAV through Omni",
"warmup_count": 0,
"measured_count": 1,
"memory_budget": {
"capacities": {
"host_ram": 17179869184
},
"demands": {
"host_ram": 10737418240
}
},
"startup_s": 20.292010181990918,
"execution_plan": {
"backend": "external.qwen_tts.cpu.v1",
"stage_id": 0,
"worker_generation": "11b36820eb34430f80bebc322a38ab74",
"worker_pid": 3642346,
"worker_script_sha256": "862177bec7221114ec93f496602434dbefd36ca903d009ea35ffdca37b529205",
"artifact_sha256": {
"python_sha256": "021044895e95be79dc2f110367607e684119afbc8ce75f6f0eec94844e0acec7",
"talker_sha256": "bc3c7e785eb961179c25450d1acff03f839e0002f2f3a5aeb67b5735c0fa2adb",
"tokenizer_sha256": "836b7b357f5ea43e889936a3709af68dfe3751881acefe4ecf0dbd30ba571258"
},
"model_dir": "/mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c",
"placement": "CPU BF16 SDPA, 8 threads; isolated Transformers 4.57.3",
"worker_props": {
"model_dir": "/mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c",
"placement": "cpu",
"torch": "2.13.0+cu130",
"transformers": "4.57.3",
"qwen_tts": "0.1.1",
"dtype": "bfloat16",
"attention": "sdpa",
"threads": 8,
"sample_rate": 24000,
"speaker": "Ryan",
"max_new_tokens": 64,
"load_s": 3.402708667970728
},
"loaded_rss_bytes": 2125488128,
"loaded_private_bytes": 2125488128,
"loaded_process_tree": [
{
"pid": 3642346,
"rss_bytes": 2125488128,
"private_bytes": 2125488128
}
],
"reserved_bytes": {
"host_ram": 10737418240
},
"memory_overhead_bytes": 6442450944,
"max_text_bytes": 4096,
"max_wav_bytes": 4194304,
"max_audio_s": 10.0,
"voice": "Ryan",
"seed": 42,
"request_capacity": 1,
"stateful_session": "Qwen PyTorch worker-owned; complete WAV per request",
"evidence": "B"
},
"checks": [
{
"text": "Hello from the local computer.",
"wall_s": 12.656105556990951,
"frames": 82560,
"duration_s": 3.44,
"pcm_sha256": "66ca76a468807381c208b21ba458e5005510c752efa89323ee909749047ab1db",
"stage_event": {
"request_id": "cpu-tts-434866642434220",
"stage_id": 0,
"epoch": 1,
"seq": 1,
"kind": "audio",
"worker_generation": "11b36820eb34430f80bebc322a38ab74",
"buffers": [],
"terminal": true,
"error": null
}
},
{
"text": "The blue car is parked beside the library.",
"wall_s": 8.73547542700544,
"frames": 80640,
"duration_s": 3.36,
"pcm_sha256": "c661953310ee1b6b39806156f4180a0793d4372425d13f58bc1440b1d027eeb0",
"stage_event": {
"request_id": "cpu-tts-434879299154073",
"stage_id": 0,
"epoch": 2,
"seq": 1,
"kind": "audio",
"worker_generation": "11b36820eb34430f80bebc322a38ab74",
"buffers": [],
"terminal": true,
"error": null
}
}
],
"standalone_pcm_parity": [
false,
false
],
"status": "failed",
"error": "RuntimeError: CPU Omni PCM differs from the same checkpoint's standalone output",
"ledger_after_shutdown": {
"capacities": {
"host_ram": 17179869184
},
"reserved": {
"host_ram": 0
},
"owners": [],
"quarantined": []
}
}
Traceback (most recent call last):
File "/home/zhout/project/edge_infer/vllm-omni-edge/benchmarks/edge_harness/experiments/probe_omni_qwen_tts_cpu.py", line 216, in <module>
asyncio.run(main())
File "/home/zhout/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/asyncio/runners.py", line 195, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/home/zhout/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/zhout/.local/share/uv/python/cpython-3.12.13-linux-x86_64-gnu/lib/python3.12/asyncio/base_events.py", line 691, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/home/zhout/project/edge_infer/vllm-omni-edge/benchmarks/edge_harness/experiments/probe_omni_qwen_tts_cpu.py", line 172, in main
raise RuntimeError("CPU Omni PCM differs from the same checkpoint's standalone output")
RuntimeError: CPU Omni PCM differs from the same checkpoint's standalone output
@@ -0,0 +1,117 @@
{
"scope": "complete resident native Windows CPU Qwen3-TTS text-to-WAV through Omni",
"warmup_count": 0,
"measured_count": 1,
"memory_budget": {
"capacities": {
"host_ram": 17179869184
},
"demands": {
"host_ram": 10737418240
}
},
"startup_s": 20.292010181990918,
"execution_plan": {
"backend": "external.qwen_tts.cpu.v1",
"stage_id": 0,
"worker_generation": "11b36820eb34430f80bebc322a38ab74",
"worker_pid": 3642346,
"worker_script_sha256": "862177bec7221114ec93f496602434dbefd36ca903d009ea35ffdca37b529205",
"artifact_sha256": {
"python_sha256": "021044895e95be79dc2f110367607e684119afbc8ce75f6f0eec94844e0acec7",
"talker_sha256": "bc3c7e785eb961179c25450d1acff03f839e0002f2f3a5aeb67b5735c0fa2adb",
"tokenizer_sha256": "836b7b357f5ea43e889936a3709af68dfe3751881acefe4ecf0dbd30ba571258"
},
"model_dir": "/mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c",
"placement": "CPU BF16 SDPA, 8 threads; isolated Transformers 4.57.3",
"worker_props": {
"model_dir": "/mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c",
"placement": "cpu",
"torch": "2.13.0+cu130",
"transformers": "4.57.3",
"qwen_tts": "0.1.1",
"dtype": "bfloat16",
"attention": "sdpa",
"threads": 8,
"sample_rate": 24000,
"speaker": "Ryan",
"max_new_tokens": 64,
"load_s": 3.402708667970728
},
"loaded_rss_bytes": 2125488128,
"loaded_private_bytes": 2125488128,
"loaded_process_tree": [
{
"pid": 3642346,
"rss_bytes": 2125488128,
"private_bytes": 2125488128
}
],
"reserved_bytes": {
"host_ram": 10737418240
},
"memory_overhead_bytes": 6442450944,
"max_text_bytes": 4096,
"max_wav_bytes": 4194304,
"max_audio_s": 10.0,
"voice": "Ryan",
"seed": 42,
"request_capacity": 1,
"stateful_session": "Qwen PyTorch worker-owned; complete WAV per request",
"evidence": "B"
},
"checks": [
{
"text": "Hello from the local computer.",
"wall_s": 12.656105556990951,
"frames": 82560,
"duration_s": 3.44,
"pcm_sha256": "66ca76a468807381c208b21ba458e5005510c752efa89323ee909749047ab1db",
"stage_event": {
"request_id": "cpu-tts-434866642434220",
"stage_id": 0,
"epoch": 1,
"seq": 1,
"kind": "audio",
"worker_generation": "11b36820eb34430f80bebc322a38ab74",
"buffers": [],
"terminal": true,
"error": null
}
},
{
"text": "The blue car is parked beside the library.",
"wall_s": 8.73547542700544,
"frames": 80640,
"duration_s": 3.36,
"pcm_sha256": "c661953310ee1b6b39806156f4180a0793d4372425d13f58bc1440b1d027eeb0",
"stage_event": {
"request_id": "cpu-tts-434879299154073",
"stage_id": 0,
"epoch": 2,
"seq": 1,
"kind": "audio",
"worker_generation": "11b36820eb34430f80bebc322a38ab74",
"buffers": [],
"terminal": true,
"error": null
}
}
],
"standalone_pcm_parity": [
false,
false
],
"status": "failed",
"error": "RuntimeError: CPU Omni PCM differs from the same checkpoint's standalone output",
"ledger_after_shutdown": {
"capacities": {
"host_ram": 17179869184
},
"reserved": {
"host_ram": 0
},
"owners": [],
"quarantined": []
}
}
@@ -0,0 +1,23 @@
********
Warning: flash-attn is not installed. Will only run the manual PyTorch version. Please install flash-attn for faster inference.
********
/bin/sh: 1: sox: not found
SoX could not be found!
If you do not have SoX, proceed here:
- - - http://sox.sourceforge.net/ - - -
If you do (or think that you should) have SoX, double-check your
path variables.
qwen-tts-cpu-worker ready port=36531 props={"model_dir": "/mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c", "placement": "cpu", "torch": "2.13.0+cu130", "transformers": "4.57.3", "qwen_tts": "0.1.1", "dtype": "bfloat16", "attention": "sdpa", "threads": 8, "sample_rate": 24000, "speaker": "Ryan", "max_new_tokens": 64, "load_s": 3.402708667970728}
127.0.0.1 - - [24/Sep/2026 00:27:25] "GET /health HTTP/1.1" 200 -
127.0.0.1 - - [24/Sep/2026 00:27:25] "GET /props HTTP/1.1" 200 -
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:27:38] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=12.619
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:27:47] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.360 wall_s=8.729
@@ -0,0 +1 @@
raise ImportError("optional kernels disabled for CPU-only Qwen3-TTS worker")
@@ -0,0 +1,51 @@
INFO 09-24 00:33:52 [patch.py:259] NVFP4 W4A4 weight_scale NaN-clamp: installed.
INFO 09-24 00:33:52 [patch.py:510] inductor factorable-divisibility patch: installed.
INFO 09-24 00:33:52 [patch.py:589] [cumem-cuda] CuMemAllocator._python_free_callback patched: asleep guard extended to all platforms.
INFO 09-24 00:33:53 [stage_init_utils.py:768] [stage_init] Set VLLM_WORKER_MULTIPROC_METHOD=spawn
WARNING 09-24 00:33:53 [stage_init_utils.py:1887] [stage_init] Failed to load transfer config: [Errno 21] Is a directory: '/home/zhout/project/edge_infer/vllm-omni-edge'
ERROR 09-24 00:34:06 [stage_runtime.py:265] [StageRuntime] Stage initialization failed; shutting down 0 initialized client(s)
ERROR 09-24 00:34:06 [stage_runtime.py:265] Traceback (most recent call last):
ERROR 09-24 00:34:06 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 252, in initialize
ERROR 09-24 00:34:06 [stage_runtime.py:265] initialized_clients = self._initialize_stage_replicas(stage_plans, self._stage_init_timeout)
ERROR 09-24 00:34:06 [stage_runtime.py:265] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERROR 09-24 00:34:06 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 589, in _initialize_stage_replicas
ERROR 09-24 00:34:06 [stage_runtime.py:265] raise primary_exc
ERROR 09-24 00:34:06 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 550, in _init_group
ERROR 09-24 00:34:06 [stage_runtime.py:265] client = self._initialize_replica(
ERROR 09-24 00:34:06 [stage_runtime.py:265] ^^^^^^^^^^^^^^^^^^^^^^^^^
ERROR 09-24 00:34:06 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/stage_runtime.py", line 817, in _initialize_replica
ERROR 09-24 00:34:06 [stage_runtime.py:265] return create_graph_client(
ERROR 09-24 00:34:06 [stage_runtime.py:265] ^^^^^^^^^^^^^^^^^^^^
ERROR 09-24 00:34:06 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/backends/__init__.py", line 23, in create_graph_client
ERROR 09-24 00:34:06 [stage_runtime.py:265] return QwenTTSCPUStageClient(metadata, backend, ledger, reservation)
ERROR 09-24 00:34:06 [stage_runtime.py:265] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ERROR 09-24 00:34:06 [stage_runtime.py:265] File "/home/zhout/project/edge_infer/vllm-omni-edge/vllm_omni/engine/backends/qwen_tts_cpu.py", line 89, in __init__
ERROR 09-24 00:34:06 [stage_runtime.py:265] raise ResourceUnavailable("CPU TTS weights plus state/workspace/headroom exceed reservation")
ERROR 09-24 00:34:06 [stage_runtime.py:265] vllm_omni.engine.resource_ledger.ResourceUnavailable: CPU TTS weights plus state/workspace/headroom exceed reservation
{
"scope": "complete resident local CPU Qwen3-TTS text-to-WAV through Omni",
"host_os": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.43",
"allow_platform_variation": true,
"warmup_count": 1,
"measured_count": 20,
"memory_budget": {
"capacities": {
"host_ram": 17179869184
},
"demands": {
"host_ram": 4294967296
}
},
"admission_refusal": "ResourceUnavailable: CPU TTS weights plus state/workspace/headroom exceed reservation",
"status": "passed",
"ledger_after_shutdown": {
"capacities": {
"host_ram": 17179869184
},
"reserved": {
"host_ram": 0
},
"owners": [],
"quarantined": []
}
}
@@ -0,0 +1,27 @@
{
"scope": "complete resident local CPU Qwen3-TTS text-to-WAV through Omni",
"host_os": "Linux-6.18.33.2-microsoft-standard-WSL2-x86_64-with-glibc2.43",
"allow_platform_variation": true,
"warmup_count": 1,
"measured_count": 20,
"memory_budget": {
"capacities": {
"host_ram": 17179869184
},
"demands": {
"host_ram": 4294967296
}
},
"admission_refusal": "ResourceUnavailable: CPU TTS weights plus state/workspace/headroom exceed reservation",
"status": "passed",
"ledger_after_shutdown": {
"capacities": {
"host_ram": 17179869184
},
"reserved": {
"host_ram": 0
},
"owners": [],
"quarantined": []
}
}
@@ -0,0 +1,40 @@
{
"scope": "WSL CPU Qwen worker-only Python overlay; base Omni interpreter is separate",
"packages": {
"qwen-tts": {
"version": "0.1.1",
"path": "qwen_tts/__init__.py",
"sha256": "ea52de59d070fde366467a6902d0edcfc1b0575b8c570a0c71020c41d6a593ed"
},
"transformers": {
"version": "4.57.3",
"path": "transformers/__init__.py",
"sha256": "7eb0743ed843f24c1d4e8b8daf4b18249cb81403b4571a70c00be0a4c0a67bd4"
},
"huggingface-hub": {
"version": "0.36.2",
"path": "huggingface_hub/__init__.py",
"sha256": "e586b64612482128fd24119364bc4dc6dca938407134e454a5e876341b364e35"
},
"sox": {
"version": "1.5.0",
"path": "sox/__init__.py",
"sha256": "0c3e15258ce1f95ca050e045af634d1b16956af2b47ff7670f78b08567d19d47"
},
"optional-kernels-stub": {
"version": "local",
"path": "kernels/__init__.py",
"sha256": "e155388b1045b573082534132778828a71203522f95a22680f8245362f1e06ee"
}
},
"base_interpreter_packages": {
"torch": "2.13.0",
"torchaudio": "2.11.0",
"numpy": "2.3.5",
"tokenizers": "0.22.2",
"accelerate": "1.12.0",
"safetensors": "0.8.0",
"librosa": "1.0.0",
"soundfile": "0.14.0"
}
}
@@ -0,0 +1,16 @@
{
"scope": "local Whisper tiny.en ASR proxy for generated speech; no perceptual quality claim",
"asr_model": "openai/whisper-tiny.en",
"asr_revision": "87c7102498dcde7456f24cfd30239ca606ed9063",
"asr_weights_sha256": "db59695928ded6043adaef491a53ef4e12da9611184d77c53baa691a60b958ad",
"transformers": "4.57.3",
"torch": "2.4.1+cpu",
"wav_sha256": "f1b5348ed3fe95e3ce1518656383e631cb88a4ec59fe80eacf8b8fc6b4023566",
"input_sample_rate": 24000,
"input_duration_s": 3.44,
"reference_text": "Hello from the local computer.",
"transcript": "Hello from the local computer!",
"word_error_rate": 0.0,
"asr_load_s": 0.8476594999665394,
"asr_inference_s": 0.8502050000242889
}
@@ -0,0 +1,87 @@
********
Warning: flash-attn is not installed. Will only run the manual PyTorch version. Please install flash-attn for faster inference.
********
/bin/sh: 1: sox: not found
SoX could not be found!
If you do not have SoX, proceed here:
- - - http://sox.sourceforge.net/ - - -
If you do (or think that you should) have SoX, double-check your
path variables.
qwen-tts-cpu-worker ready port=42833 props={"model_dir": "/mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c", "placement": "cpu", "torch": "2.13.0+cu130", "transformers": "4.57.3", "qwen_tts": "0.1.1", "dtype": "bfloat16", "attention": "sdpa", "threads": 8, "sample_rate": 24000, "speaker": "Ryan", "max_new_tokens": 64, "load_s": 3.237298524007201}
127.0.0.1 - - [24/Sep/2026 00:29:33] "GET /health HTTP/1.1" 200 -
127.0.0.1 - - [24/Sep/2026 00:29:33] "GET /props HTTP/1.1" 200 -
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:29:45] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=12.176
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:29:54] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.360 wall_s=8.703
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:30:02] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.348
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:30:11] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.261
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:30:19] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.223
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:30:27] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.163
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:30:35] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.229
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:30:44] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.398
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:30:52] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.129
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:31:00] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.251
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:31:08] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.431
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:31:17] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.461
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:31:25] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.501
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:31:34] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.250
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:31:42] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.414
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:31:51] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.367
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:31:59] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.346
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:32:07] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.326
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:32:16] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.388
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:32:24] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.201
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:32:32] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.207
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:32:40] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.165
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:32:48] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=8.282
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
@@ -0,0 +1,49 @@
INFO 09-24 00:34:52 [patch.py:259] NVFP4 W4A4 weight_scale NaN-clamp: installed.
INFO 09-24 00:34:52 [patch.py:510] inductor factorable-divisibility patch: installed.
INFO 09-24 00:34:52 [patch.py:589] [cumem-cuda] CuMemAllocator._python_free_callback patched: asleep guard extended to all platforms.
INFO 09-24 00:34:53 [omni_base.py:216] [AsyncOmni] Initializing with model /mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c
INFO 09-24 00:34:53 [async_omni_engine.py:172] [AsyncOmniEngine] Initializing with model /mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c
ERROR 09-24 00:34:53 [repo_utils.py:119] Error parsing config for /mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c: The checkpoint you are trying to load has model type `qwen3_tts` but Transformers does not recognize this architecture. This could be because of an issue with the checkpoint, or because your version of Transformers is out of date.
ERROR 09-24 00:34:53 [repo_utils.py:119]
ERROR 09-24 00:34:53 [repo_utils.py:119] You can update Transformers with the command `pip install --upgrade transformers`. If this does not work, and the checkpoint is very new, then there may not be a release version that supports this model yet. In this case, you can get the most up-to-date code by installing Transformers from source with the command `pip install git+https://github.com/huggingface/transformers.git`, retrying 1 of 2
ERROR 09-24 00:34:55 [repo_utils.py:117] Error parsing config for /mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c: The checkpoint you are trying to load has model type `qwen3_tts` but Transformers does not recognize this architecture. This could be because of an issue with the checkpoint, or because your version of Transformers is out of date.
ERROR 09-24 00:34:55 [repo_utils.py:117]
ERROR 09-24 00:34:55 [repo_utils.py:117] You can update Transformers with the command `pip install --upgrade transformers`. If this does not work, and the checkpoint is very new, then there may not be a release version that supports this model yet. In this case, you can get the most up-to-date code by installing Transformers from source with the command `pip install git+https://github.com/huggingface/transformers.git`
INFO 09-24 00:34:55 [async_omni_engine.py:290] [AsyncOmniEngine] Launching Orchestrator thread with 1 stages
INFO 09-24 00:34:55 [stage_init_utils.py:768] [stage_init] Set VLLM_WORKER_MULTIPROC_METHOD=spawn
INFO 09-24 00:34:55 [initialization.py:356] Loaded OmniTransferConfig with 0 connector configurations
INFO 09-24 00:35:13 [orchestrator.py:604] [Orchestrator] Starting event loop
INFO 09-24 00:35:13 [async_omni_engine.py:323] [AsyncOmniEngine] Orchestrator ready with 1 stages
INFO 09-24 00:35:13 [omni_base.py:235] [AsyncOmni] AsyncOmniEngine initialized in 20.28 seconds
INFO 09-24 00:35:13 [omni_base.py:255] [AsyncOmni] Initialized with 1 stages for model /mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c
INFO 09-24 00:35:25 [omni_base.py:781] [AsyncOmni] Shutting down
INFO 09-24 00:35:25 [async_omni_engine.py:1807] [AsyncOmniEngine] Shutting down Orchestrator
INFO 09-24 00:35:25 [orchestrator.py:705] [Orchestrator] Received shutdown signal
INFO 09-24 00:35:25 [orchestrator.py:3092] [Orchestrator] Shutting down all 1 client(s)
INFO 09-24 00:35:25 [stage_pool.py:1354] [StagePool] Stage 0 replica 0 shut down
{
"entrypoint": "AsyncOmni.generate",
"pipeline": "qwen3_tts_cpu_whole",
"startup_s": 20.290129358007107,
"request_wall_s": 12.097587361990009,
"outputs": [
{
"request_id": "public-cpu-tts-1",
"sample_rate": 24000,
"frames": 82560,
"pcm_sha256": "66ca76a468807381c208b21ba458e5005510c752efa89323ee909749047ab1db",
"stage_event": {
"request_id": "public-cpu-tts-1-843808ee",
"stage_id": 0,
"epoch": 1,
"seq": 1,
"kind": "audio",
"worker_generation": "bc022f43fee646f18572e4d6cef602a6",
"buffers": [],
"terminal": true,
"error": null
}
}
],
"status": "passed"
}
@@ -0,0 +1,26 @@
{
"entrypoint": "AsyncOmni.generate",
"pipeline": "qwen3_tts_cpu_whole",
"startup_s": 20.290129358007107,
"request_wall_s": 12.097587361990009,
"outputs": [
{
"request_id": "public-cpu-tts-1",
"sample_rate": 24000,
"frames": 82560,
"pcm_sha256": "66ca76a468807381c208b21ba458e5005510c752efa89323ee909749047ab1db",
"stage_event": {
"request_id": "public-cpu-tts-1-843808ee",
"stage_id": 0,
"epoch": 1,
"seq": 1,
"kind": "audio",
"worker_generation": "bc022f43fee646f18572e4d6cef602a6",
"buffers": [],
"terminal": true,
"error": null
}
}
],
"status": "passed"
}
@@ -0,0 +1,20 @@
********
Warning: flash-attn is not installed. Will only run the manual PyTorch version. Please install flash-attn for faster inference.
********
/bin/sh: 1: sox: not found
SoX could not be found!
If you do not have SoX, proceed here:
- - - http://sox.sourceforge.net/ - - -
If you do (or think that you should) have SoX, double-check your
path variables.
qwen-tts-cpu-worker ready port=48689 props={"model_dir": "/mnt/c/Users/zhout/w2/models/Qwen3-TTS-0.6B-85e237c", "placement": "cpu", "torch": "2.13.0+cu130", "transformers": "4.57.3", "qwen_tts": "0.1.1", "dtype": "bfloat16", "attention": "sdpa", "threads": 8, "sample_rate": 24000, "speaker": "Ryan", "max_new_tokens": 64, "load_s": 3.1872041929746047}
127.0.0.1 - - [24/Sep/2026 00:35:13] "GET /health HTTP/1.1" 200 -
127.0.0.1 - - [24/Sep/2026 00:35:13] "GET /props HTTP/1.1" 200 -
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:35:25] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=12.089
@@ -0,0 +1,31 @@
********
Warning: flash-attn is not installed. Will only run the manual PyTorch version. Please install flash-attn for faster inference.
********
'\\wsl.localhost\Ubuntu\home\zhout\project\edge_infer'
用作为当前目录的以上路径启动了 CMD.EXE。
UNC 路径不受支持。默认值设为 Windows 目录。
'sox' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
SoX could not be found!
If you do not have SoX, proceed here:
- - - http://sox.sourceforge.net/ - - -
If you do (or think that you should) have SoX, double-check your
path variables.
qwen-tts-cpu-worker ready port=61654 props={"model_dir": "C:\\Users\\zhout\\w2\\models\\Qwen3-TTS-0.6B-85e237c", "placement": "cpu", "torch": "2.13.0+cu130", "transformers": "4.57.3", "qwen_tts": "0.1.1", "dtype": "bfloat16", "attention": "sdpa", "threads": 8, "sample_rate": 24000, "speaker": "Ryan", "max_new_tokens": 64, "load_s": 1.6466022999957204}
127.0.0.1 - - [24/Sep/2026 00:38:46] "GET /health HTTP/1.1" 200 -
127.0.0.1 - - [24/Sep/2026 00:38:46] "GET /props HTTP/1.1" 200 -
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:39:02] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=4.560 wall_s=15.215
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:39:13] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=3.440 wall_s=11.343
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
127.0.0.1 - - [24/Sep/2026 00:39:28] "POST /v1/audio/speech HTTP/1.1" 200 -
tts request duration_s=4.560 wall_s=15.133
Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation.
@@ -2,13 +2,19 @@
All 60 pairings have a disposition. The timing tables below remain the 2026-09-22 measurements. The configuration matrix and affected per-cell reasons incorporate the [2026-09-23 scoped recovery runs](../../../e2e_recovery_20260923/README.md) and [WSL CPU/native Windows expansion](../../../e2e_expansion_20260923/README.md). The expansion adds separate 20-request serial MiniCPM-o text-to-speech profiles on WSL CPU and native Windows GPU, a Spark output-head component profile on the HX370 AMD NPU, complete Spark text-request profiles through standalone llama.cpp and a bounded Omni whole-session stage on native Windows CPU and Radeon 890M, native Windows CPU Qwen3-TTS text-to-WAV profiles through both standalone PyTorch and a bounded Omni whole-session stage, and a hybrid CPU+Radeon 890M Qwen3-TTS profile likewise repeated through a bounded Omni whole-session stage. A pinned GGUF MiniCPM-o route adds combined image+audio to text+speech runs on WSL CPU, native Windows CPU and native Windows Radeon 890M+CPU. All three now pass a bounded complete request through an Omni graph stage; the WSL CPU path additionally passed one warmup plus 20 serial measured requests. These are scoped synthetic cases, not full release qualification.
## Configuration × model
## Configuration × model
The WSL CPU Qwen3-TTS cell also has a separate bounded Omni whole-session
text-to-complete-WAV profile with one warmup, 20 measured requests, a public
audio request, pinned ASR proxy, memory refusal and cancellation evidence.
It does not replace the earlier short-stream finding or establish playable
streaming.
NOT E2E means no complete device/model workload was verified. “Scoped E2E” identifies only the named input/output path; “standalone” means the whole model ran outside Omni. The Spark GGUF Omni stage uses a complete-request control path; it has no incremental token stream or restart-after-cancel contract yet. “Synthetic policy pass” does not establish a real robot-task result. See the per-cell reasons below.
| Device | Spark-X2.5 | Qwen3-TTS 0.6B CustomVoice | Qwen3.8-27B | MiniCPM-o 4.5 | InternVLA-A1 |
|---|---|---|---|---|---|
| PC HX370: CPU / WSL | profile completed | scoped E2E: short stream | NOT E2E | scoped E2E: Omni GGUF combined image+audio → text+speech | synthetic policy pass |
| PC HX370: CPU / WSL | profile completed | scoped E2E: Omni CPU text → complete WAV | NOT E2E | scoped E2E: Omni GGUF combined image+audio → text+speech | synthetic policy pass |
| PC HX370: CPU / native Windows | scoped E2E: Omni Spark text | scoped E2E: Omni CPU text → complete WAV | NOT E2E | scoped E2E: Omni GGUF image+audio → text+speech | synthetic policy pass |
| PC HX370 + RTX 5090 Laptop / WSL | profile completed | profile completed | scoped E2E: text + image | scoped E2E: text/image/audio → speech | synthetic policy pass |
| PC HX370 + RTX 5090 Laptop / Windows | profile completed | profile completed | NOT E2E | scoped E2E: text/image/audio → speech | synthetic policy pass |
@@ -26,7 +32,7 @@ NOT E2E means no complete device/model workload was verified. “Scoped E2E” i
| Device | Model | Current profiling disposition | Reason / remaining work | Next step |
|---|---|---|---|---|
| PC HX370: CPU / WSL | Spark-X2.5 | PROFILE_COMPLETED | not fully qualified: reference-quality and remaining reliability/performance gates must be reviewed | Qualify a matching vLLM 0.29 CPU build and token parity separately. |
| PC HX370: CPU / WSL | Qwen3-TTS 0.6B CustomVoice | SCOPED_E2E | The 2026-09-23 compatibility fix enabled real-weight two-frame PCM and four short-stream requests, including cancellation recovery. One measured request generated 3.04 s of audio in 17.02 s (RTF 5.60) with four simulated playback underruns. The CPU wheel remains vLLM 0.28 versus Omni 0.29. | Qualify a matching CPU runtime, speech quality, uninterrupted playback and sustained load; [recovery evidence](../../../e2e_recovery_20260923/README.md). |
| PC HX370: CPU / WSL | Qwen3-TTS 0.6B CustomVoice | SCOPED_E2E_OMNI_COMPLETE_REQUEST | The earlier vLLM 0.28 CPU path passed four short streams but had four simulated playback underruns in one measured request; its wheel remains mismatched with Omni 0.29. Separately, the pinned BF16 0.6B CustomVoice checkpoint ran two named text-to-complete-WAV requests through an Omni 0.29 whole-session stage with an isolated CPU worker on WSL. One warmup plus 20 serial measured requests returned identical 3.44 s audio; nearest-rank complete-request wall p50/p95 was 8.27/8.47 s (RTF 2.40/2.46), excluding 19.82 s startup. Pinned Whisper tiny.en transcribed the first measured WAV exactly (WER 0, one-output intelligibility proxy). Public `AsyncOmni` audio output passed; the stage verified weights, interpreter and CPU placement, reserved 10 GiB host RAM, refused 4 GiB before launch, and drained in-flight cancellation with zero remaining reservation. WSL PCM differs from the same-checkpoint native Windows outputs despite the declared settings; its cause is unqualified. Sampled process-tree RSS reached 3.39 GB, not a loading peak. This worker delivers only a complete WAV, not a playable stream. | Qualify cross-OS numerical/quality difference, playable streaming without underruns, post-cancel restart, loading peak, concurrency and sustained power/thermal behavior; [WSL Omni raw evidence](../../../e2e_expansion_20260923/evidence/qwen_tts_omni_wsl_cpu/README.md), [earlier stream evidence](../../../e2e_recovery_20260923/README.md). |
| PC HX370: CPU / WSL | Qwen3.8-27B | NOT_E2E_PROFILEABLE | No compatible CPU artifact/deployment for this model was found in the checked model roots. Available Qwen 27B FP8/NVFP4 CUDA artifacts do not establish a CPU route. | Supply and validate the missing matching artifact/backend, then run the complete specified workload. |
| PC HX370: CPU / WSL | MiniCPM-o 4.5 | SCOPED_E2E_OMNI_COMPLETE_REQUEST | The BF16/vLLM 0.28 three-stage path previously passed separate text, synthetic red-square image and synthetic 440 Hz audio inputs to text+speech; its 20-request serial **text-only** profile was p50/p95 21.86/22.97 s with swap and shutdown warnings. A separate pinned Q4_K_M/F16 GGUF worker now runs a **combined spoken question+image → text+speech** request through a bounded Omni StageRuntime/StagePool graph stage on WSL CPU, with installed vLLM 0.29 for the controller and CPU-only C++ model execution. All 20 measured requests after one warmup answered “The square in the image is red.”, emitted complete nonzero speech and a terminal audio event; nearest-rank complete-request wall p50/p95 was 22.67/24.83 s, speech duration 1.60–2.92 s, and maximum sampled worker RSS 13.70 GB. The first measured WAV independently transcribed exactly with pinned Whisper tiny.en (WER 0, one-output intelligibility proxy). Ten weight hashes and CPU placement were verified; 24 GiB shared RAM was reserved, 8 GiB was refused before launch, and in-flight cancellation left no stale output or reservation. Host RAM/swap samples covered only part of the profile. One synthetic fixture and variable speech PCM do not establish general quality, playable streaming, loading peak or sustained performance. | Validate real image/audio suites, speech alignment and quality, video input, concurrent admission, post-cancel restart, loading peak and sustained thermal behavior; [GGUF Omni raw evidence](../../../e2e_expansion_20260923/evidence/minicpmo_omni_wsl_cpu/README.md), [BF16/vLLM CPU evidence](../../../e2e_expansion_20260923/README.md), [earlier standalone GGUF run](../../../e2e_expansion_20260923/evidence/minicpmo_cpp_cpu/README.md). |
| PC HX370: CPU / WSL | InternVLA-A1 | SYNTHETIC_POLICY_PASS | The Place_Markpen checkpoint strict-loaded in CPU-only PyTorch and produced finite `[1, 50, 32]` actions from zero observations/noise in one 3.25 s forward. Compared with the same CUDA checkpoint/input, relative L2 error was 1.30% and cosine similarity 0.999917; no task-quality tolerance is established. | Validate real observations against reference actions, units/timestamps, repeated latency and memory before robot-task qualification; [CPU evidence](../../../e2e_expansion_20260923/README.md). |
+11
View File
@@ -193,6 +193,17 @@ The 2026-09-23 [Spark GGUF Omni follow-up](../../benchmarks/edge_harness/results
The [Qwen3-TTS Omni hybrid follow-up](../../benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/qwen_tts_omni_hybrid/README.md) adds one complete-request stage for the native Windows HX370 CPU+Radeon 890M route. A pinned Q8_0 talker and F16 codec produced two named PCM outputs exactly matching the prior standalone backend; one warmup plus 20 serial requests measured 3.298/3.336 s p50/p95 for 2.56 s of audio. Public `AsyncOmni` audio, cancellation drain and explicit 8 GiB host admission passed. This is progress toward M2 integration, not M2 acceptance: RTF remains above 1, and playable chunk streaming, post-cancel restart, loading/iGPU peaks, broader voice quality and 30-minute thermal behavior remain open. No NPU participated.
The [WSL CPU Qwen3-TTS Omni follow-up](../../benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/qwen_tts_omni_wsl_cpu/README.md)
adds the same bounded whole-session CPU stage on Ubuntu/WSL with a pinned
worker-only dependency overlay. One warmup plus 20 serial complete requests
produced identical 3.44 s WAVs at nearest-rank wall p50/p95 8.27/8.47 s,
excluding worker startup. The public audio path, one-output Whisper proxy
(WER 0), 10 GiB admission, 4 GiB refusal and cancellation drain passed. WSL
PCM differs from the same-checkpoint native Windows result; its numerical
cause remains open. The existing vLLM 0.28 short-stream path still has playback
underruns. These complete-WAV findings advance M2 desktop coverage but do not
establish playable streaming, RTF below one, broad quality or sustained use.
VLA qualification here ends at action data. Physical robot control, collision
avoidance and actuator safety belong to the external controller.
+13 -2
View File
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
"""Native Windows CPU Qwen3-TTS whole-session stage with isolated dependencies.
"""Local CPU Qwen3-TTS whole-session stage with isolated dependencies.
The worker alone imports Qwen's PyTorch wrapper and Transformers 4.57.3.
This adapter reuses the bounded complete-WAV request, fencing and ownership
@@ -57,7 +57,12 @@ class QwenTTSCPUStageClient(CrispTTSStageClient):
demand = reservation.demands[self._memory_pool]
if self._max_wav_bytes > demand:
raise ResourceUnavailable("CPU TTS output bound exceeds stage reservation")
self._python = Path(config["python_bin"]).resolve(strict=True)
# On POSIX, a virtualenv's python is often a symlink to the base
# interpreter. Launch via the declared path so Python discovers
# the virtualenv; _sha256 still follows the link for verification.
self._python = Path(config["python_bin"]).absolute()
if not self._python.is_file():
raise FileNotFoundError(f"CPU TTS interpreter absent: {self._python}")
self._model_dir = Path(config["model_dir"]).resolve(strict=True)
self._overlay = Path(config["overlay_dir"]).resolve(strict=True)
self._talker = self._model_dir / "model.safetensors"
@@ -70,6 +75,11 @@ class QwenTTSCPUStageClient(CrispTTSStageClient):
}
if not (self._overlay / "transformers" / "__init__.py").is_file():
raise FileNotFoundError("pinned Transformers overlay is absent")
overlay_marker_hash = config.get("overlay_marker_sha256")
if overlay_marker_hash is not None:
marker = self._overlay / "kernels" / "__init__.py"
if not marker.is_file() or _sha256(marker) != str(overlay_marker_hash).lower():
raise ValueError("CPU TTS optional-kernels overlay differs from declared hash")
for label, (path, digest) in expected.items():
if _sha256(path) != digest:
raise ValueError(f"CPU TTS {label} differs from the declared artifact hash")
@@ -152,6 +162,7 @@ class QwenTTSCPUStageClient(CrispTTSStageClient):
"worker_pid": self._proc.pid,
"worker_script_sha256": _sha256(self._worker),
"artifact_sha256": {label: digest for label, (_, digest) in expected.items()},
"overlay_marker_sha256": overlay_marker_hash,
"model_dir": str(self._model_dir),
"placement": "CPU BF16 SDPA, 8 threads; isolated Transformers 4.57.3",
"worker_props": props,