Verify Qwen3-TTS hybrid recovery after in-flight cancellation
This commit is contained in:
1 parent
6d0b758dbe
commit
b4179a9c1c
13 files changed
+633
-6
No files matched your search
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Audit the pinned native-Windows Qwen3-TTS in-flight cancel/restart probe."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import wave
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ARTIFACT_HASHES = {
|
||||
"server_sha256": "999c6af252077195adb723b96da9ee5d3cd291dc7c7a4b32dc493ae148035529",
|
||||
"talker_sha256": "5227dcbc4df7c5533341d111cc469fa491a48e722b23dd10f553181b52dff2d9",
|
||||
"codec_sha256": "70dc95dbfdd9aa5d9d406236ff771d061bf17b0cda02a72513953355606e719b",
|
||||
"punc_sha256": "faf4a43e3135bc307a66194685af00f756e6f4c28c7d9e2dd8f3517cddca5c45",
|
||||
}
|
||||
PREFILL = "qwen3_tts[customvoice]: prefill role="
|
||||
PCM_SHA256 = "57f60228e2b456f6dfefc7e49df862c7bff6ba7cf39231ef1824f615948a1539"
|
||||
|
||||
|
||||
def sha256(path: Path) -> str:
|
||||
with path.open("rb") as stream:
|
||||
return hashlib.file_digest(stream, "sha256").hexdigest()
|
||||
|
||||
|
||||
def clean_ledger(value: dict) -> bool:
|
||||
return (value["reserved"] == {"host_ram": 0}
|
||||
and value["owners"] == [] and value["quarantined"] == [])
|
||||
|
||||
|
||||
def audit(root: Path) -> dict:
|
||||
report_path = root / "tts_restart_report.json"
|
||||
first_log = root / "tts_restart_server.log"
|
||||
second_log = root / "tts_restart_server_restart.log"
|
||||
wav_path = root / "tts_restart.wav"
|
||||
hardware_path = root / "hardware.json"
|
||||
run = json.loads(report_path.read_text(encoding="utf-8"))
|
||||
before = run["execution_plan"]
|
||||
after = run["restart_check"]["fresh_execution_plan"]
|
||||
abort = run["abort_check"]
|
||||
restart = run["restart_check"]
|
||||
if run["status"] != "passed" or run["measured_count"] != 1:
|
||||
raise ValueError("TTS probe did not pass the declared single-request recovery scope")
|
||||
if any(plan["artifact_sha256"] != ARTIFACT_HASHES for plan in (before, after)):
|
||||
raise ValueError("TTS artifact hashes changed between sessions")
|
||||
if any(plan["placement"] != "Radeon Vulkan0 talker/codec + CPU FP32 code predictor"
|
||||
or plan["expected_gpu_name"] != "AMD Radeon(TM) 890M Graphics"
|
||||
or plan["ggml_vk_visible_devices"] != "1" for plan in (before, after)):
|
||||
raise ValueError("TTS execution placement changed")
|
||||
if any(row["pcm_sha256"] != PCM_SHA256 or row["frames"] != 61440
|
||||
for row in (run["checks"][0], run["measured"][0], restart["fresh_request"])):
|
||||
raise ValueError("TTS fresh request differs from the pinned complete-WAV output")
|
||||
if (not restart["same_pcm_as_before_abort"] or restart["late_output"]
|
||||
or abort["stale_output"] or not abort["worker_exited"]
|
||||
or abort["prefills_after_abort_request_start"] <= abort["prefills_before_abort_request"]):
|
||||
raise ValueError("TTS cancellation or fresh-stage recovery failed")
|
||||
if not all(clean_ledger(value) for value in (
|
||||
abort["ledger_after_abort"], restart["first_runtime_ledger_after_shutdown"],
|
||||
run["ledger_after_shutdown"],
|
||||
)):
|
||||
raise ValueError("TTS RAM reservation or quarantine remained")
|
||||
if (before["worker_generation"] == after["worker_generation"]
|
||||
or restart["fresh_request"]["stage_event"]["worker_generation"]
|
||||
!= after["worker_generation"]):
|
||||
raise ValueError("TTS fresh request reused the cancelled worker")
|
||||
logs = [path.read_text(encoding="utf-8", errors="replace") for path in (first_log, second_log)]
|
||||
if (logs[0].count(PREFILL) < abort["prefills_after_abort_request_start"]
|
||||
or logs[1].count(PREFILL) < 1
|
||||
or any("desc=AMD Radeon(TM) 890M Graphics" not in log
|
||||
or "code_pred CPU-pinned" not in log
|
||||
or "codec: GPU default - loading weights onto Vulkan0" not in log
|
||||
for log in logs)):
|
||||
raise ValueError("TTS raw server logs do not verify prefill and hybrid placement")
|
||||
with wave.open(str(wav_path), "rb") as wav:
|
||||
if wav.getnchannels() != 1 or wav.getsampwidth() != 2 or wav.getframerate() != 24000:
|
||||
raise ValueError("saved WAV format differs from the declared output")
|
||||
if wav.getnframes() != 61440 or hashlib.sha256(wav.readframes(61440)).hexdigest() != PCM_SHA256:
|
||||
raise ValueError("saved WAV payload differs from the stage-reported PCM")
|
||||
files = [report_path, first_log, second_log, wav_path, hardware_path]
|
||||
return {
|
||||
"status": "passed",
|
||||
"scope": "one native Windows hybrid TTS cancellation after backend prefill and fresh StageRuntime request",
|
||||
"old_generation": before["worker_generation"],
|
||||
"new_generation": after["worker_generation"],
|
||||
"first_server_prefills": logs[0].count(PREFILL),
|
||||
"fresh_server_prefills": logs[1].count(PREFILL),
|
||||
"fresh_pcm_sha256": PCM_SHA256,
|
||||
"ledger_cleared": True,
|
||||
"files": {path.name: {"bytes": path.stat().st_size, "sha256": sha256(path)} for path in files},
|
||||
"limits": [
|
||||
"The stage returns a complete WAV, not incremental playable audio.",
|
||||
"A fresh StageRuntime starts after cancellation; no same-session state migration is claimed.",
|
||||
"One recovery case is not concurrency or sustained reliability qualification.",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--evidence-dir", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
result = audit(args.evidence_dir)
|
||||
(args.evidence_dir / "audit_report.json").write_text(
|
||||
json.dumps(result, indent=2) + "\n", encoding="utf-8"
|
||||
)
|
||||
print(json.dumps({"status": result["status"], "fresh_pcm_sha256": result["fresh_pcm_sha256"]}))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -42,11 +42,15 @@ async def main() -> None:
|
||||
parser.add_argument("--warmups", type=int, default=1)
|
||||
parser.add_argument("--repeats", type=int, default=20)
|
||||
parser.add_argument("--abort-check", action="store_true")
|
||||
parser.add_argument("--restart-check", action="store_true",
|
||||
help="After in-flight cancellation, start a fresh stage and verify audio")
|
||||
parser.add_argument("--capacity-gib", type=int, default=16)
|
||||
parser.add_argument("--reserve-gib", type=int, default=8)
|
||||
args = parser.parse_args()
|
||||
if args.warmups < 0 or args.repeats <= 0 or args.reserve_gib <= 0 or args.capacity_gib < args.reserve_gib:
|
||||
parser.error("invalid warmup/repeat count or memory budget")
|
||||
if args.restart_check and not args.abort_check:
|
||||
parser.error("--restart-check requires --abort-check")
|
||||
|
||||
from vllm_omni.config.stage_config import DeployConfig, StageDeployConfig, merge_pipeline_deploy
|
||||
from vllm_omni.engine.stage_runtime import StageRuntime
|
||||
@@ -149,18 +153,85 @@ async def main() -> None:
|
||||
report["nearest_rank_p95_wall_s"] = _rank(walls, 0.95)
|
||||
report["all_same_pcm_sha256"] = len({row["pcm_sha256"] for row in report["measured"]}) == 1
|
||||
if args.abort_check:
|
||||
def started_tts_prefills() -> int:
|
||||
log = Path(args.server_log).read_text(encoding="utf-8", errors="replace")
|
||||
return log.count("qwen3_tts[customvoice]: prefill role=")
|
||||
|
||||
prefills_before_abort = started_tts_prefills()
|
||||
request_id = f"tts-abort-{time.monotonic_ns()}"
|
||||
await pool.submit_initial(request_id, state, {"text": second, "voice": "ryan", "seed": 42})
|
||||
await asyncio.sleep(0.01)
|
||||
deadline = time.monotonic() + 10
|
||||
while started_tts_prefills() <= prefills_before_abort:
|
||||
if time.monotonic() >= deadline:
|
||||
raise TimeoutError("abort request did not reach the owned TTS server")
|
||||
await asyncio.sleep(0.02)
|
||||
premature = pool.poll_graph_output(0)
|
||||
if premature is not None:
|
||||
premature.release_stage_buffers()
|
||||
raise RuntimeError("TTS request completed before in-flight cancellation")
|
||||
await pool.abort_requests([request_id])
|
||||
await asyncio.sleep(0.1)
|
||||
stale = pool.poll_graph_output(0)
|
||||
report["abort_check"] = {
|
||||
"stale_output": pool.poll_graph_output(0) is not None,
|
||||
"prefills_before_abort_request": prefills_before_abort,
|
||||
"prefills_after_abort_request_start": started_tts_prefills(),
|
||||
"stale_output": stale is not None,
|
||||
"worker_exited": pool.stage_client._proc.poll() is not None,
|
||||
"ledger_after_abort": runtime.resource_ledger.snapshot(),
|
||||
}
|
||||
if stale is not None:
|
||||
stale.release_stage_buffers()
|
||||
if report["abort_check"]["stale_output"] or not report["abort_check"]["worker_exited"]:
|
||||
raise RuntimeError("CrispASR cancellation left stale output or live worker")
|
||||
if args.restart_check:
|
||||
old_generation = report["execution_plan"]["worker_generation"]
|
||||
runtime.shutdown()
|
||||
released = runtime.resource_ledger.snapshot()
|
||||
if released["reserved"]["host_ram"] or released["quarantined"]:
|
||||
raise RuntimeError("cancelled TTS stage retained a host-RAM reservation")
|
||||
server_log = Path(args.server_log)
|
||||
restart_log = server_log.with_name(
|
||||
server_log.stem + "_restart" + server_log.suffix
|
||||
)
|
||||
restart_deploy = DeployConfig(
|
||||
async_chunk=False,
|
||||
stages=[StageDeployConfig(
|
||||
stage_id=0,
|
||||
backend={**backend, "log_file": str(restart_log)},
|
||||
resource_budget=deploy.stages[0].resource_budget,
|
||||
)],
|
||||
)
|
||||
restart_configs = [
|
||||
stage.to_omegaconf()
|
||||
for stage in merge_pipeline_deploy(pipeline, restart_deploy)
|
||||
]
|
||||
runtime = StageRuntime(
|
||||
restart_configs, "local-qwen-tts-crisp-restart", "",
|
||||
stage_init_timeout=180, async_chunk=False,
|
||||
)
|
||||
restarted_at = time.perf_counter()
|
||||
runtime.initialize()
|
||||
fresh_startup_s = time.perf_counter() - restarted_at
|
||||
pool = runtime.stage_pools[0]
|
||||
state = SimpleNamespace(sampling_params_list=[None])
|
||||
fresh_plan = pool.stage_client.execution_plan
|
||||
if fresh_plan["worker_generation"] == old_generation:
|
||||
raise RuntimeError("restart reused the cancelled TTS worker generation")
|
||||
restarted = await request_one(first)
|
||||
late = pool.poll_graph_output(0)
|
||||
report["restart_check"] = {
|
||||
"first_runtime_ledger_after_shutdown": released,
|
||||
"fresh_startup_s": fresh_startup_s,
|
||||
"fresh_server_log": str(restart_log),
|
||||
"fresh_execution_plan": fresh_plan,
|
||||
"fresh_request": restarted,
|
||||
"same_pcm_as_before_abort": restarted["pcm_sha256"] == report["checks"][0]["pcm_sha256"],
|
||||
"late_output": late is not None,
|
||||
}
|
||||
if late is not None:
|
||||
late.release_stage_buffers()
|
||||
if late is not None or not report["restart_check"]["same_pcm_as_before_abort"]:
|
||||
raise RuntimeError("fresh TTS stage emitted extra or changed audio")
|
||||
report["status"] = "passed"
|
||||
except BaseException as exc:
|
||||
report["status"] = "failed"
|
||||
|
||||
+2
@@ -26,3 +26,5 @@ Both named PCM hashes match the [earlier standalone output](../qwen_tts_radeon89
|
||||
The profile cancelled a live request after the measured series, observed no stale audio, terminated its owned process and released the ledger with no quarantine. It does not prove the stage can continue serving after that active cancellation. A [4 GiB reservation was refused](omni_crisp_tts_pinned_reject_memory_20260923.json) before load, and a [different declared GPU was refused](omni_crisp_tts_pinned_reject_device_20260923.json); both left the ledger empty. The admitted 8 GiB includes 1.38 GB of pinned GGUF files plus a declared 5 GiB allowance for KV, activations, workspace, transfers, loading and headroom; loaded process RSS was 2,723,655,680 bytes. Neither number is a measured loading peak or complete iGPU-memory attribution. The route remained slower than real-time generation and was not checked for continuous playback, concurrent requests, longer speech, thermal throttling or 30-minute sustained behavior, so M2 release qualification remains open. The CPU+iGPU+NPU joint row is unchanged because no NPU participated.
|
||||
|
||||
Reproduce with the [stage profile script](../../../../experiments/probe_omni_crisp_tts.py) and [public API script](../../../../experiments/probe_omni_crisp_tts_entrypoint.py) on native Windows Python/vLLM 0.29 with `PYTHONPATH` pointing to this checkout, `PYTHONUTF8=1`, and `VLLM_ENABLE_V1_MULTIPROCESSING=0`. Supply local paths and the four hashes above, plus `--server-log`, `--output-report`, and for the stage profile `--output-wav --warmups 1 --repeats 20 --abort-check`. The public probe also accepts `--model-config-dir`. No mobile or embedded device is implied by this Windows run.
|
||||
|
||||
The later [2026-09-24 in-flight cancellation and fresh-stage restart probe](../../../e2e_expansion_20260924/evidence/qwen_tts_omni_windows_restart/README.md) closes the one-request restart gap for this exact hybrid route. The earlier 20-request timing and its other qualification limits remain unchanged.
|
||||
@@ -1,4 +1,4 @@
|
||||
# 2026-09-24 Qualcomm component expansion
|
||||
# 2026-09-24 E2E and component expansion
|
||||
|
||||
A separate [complete Spark 1.7B BF16 WSL CPU run](evidence/spark_bf16_wsl_cpu/README.md)
|
||||
now uses both verified upstream weight shards in the fork-branch Omni local text
|
||||
@@ -27,6 +27,13 @@ confirmed server task start before cancellation on both HX370 CPU and Radeon
|
||||
Paris and cleared the ledger without stale output. This is fresh-stage
|
||||
recovery, not same-session token continuation.
|
||||
|
||||
A [native Windows Qwen3-TTS hybrid restart probe](evidence/qwen_tts_omni_windows_restart/README.md)
|
||||
also confirmed backend prefill before cancellation. The worker and host-RAM
|
||||
reservation drained; a fresh Omni stage with the same pinned Radeon Vulkan0
|
||||
talker/codec and CPU predictor returned the identical 24 kHz PCM under a new
|
||||
generation. This adds one recovery case to the earlier 20-request profile,
|
||||
without establishing playable streaming or a new latency distribution.
|
||||
|
||||
For S25, the historical [25-frame TFLite GPU-requested vocoder](evidence/qwen_tts_vocoder_qualcomm/s25/full_tflite_gpu_profile/README.md)
|
||||
has a newly measured 100-sample p50/p95 **0.839/1.157 s** for 2 s of audio,
|
||||
with mixed CPU/GPU placement and component median RTF **0.420**. Its 4.24%
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
# Qwen3-TTS native Windows hybrid stage after in-flight cancellation
|
||||
|
||||
The pinned Qwen3-TTS 0.6B CustomVoice route completed one more scoped recovery check on the native Windows HX370 machine. The first Omni `StageRuntime` served two named complete-WAV requests and one additional measured request. Its owned CrispASR server log then showed a fourth request entering `qwen3_tts[customvoice]: prefill` before the Omni stage cancelled it. Cancellation emitted no terminal audio, exited the worker and released the full 8 GiB host-RAM reservation without quarantine. A newly initialized `StageRuntime` used a different worker generation, retained the same four artifact hashes and Radeon Vulkan0 talker/codec plus CPU FP32 predictor placement, and returned the first sentence with the same 61,440-frame PCM SHA-256, `57f60228e2b456f6dfefc7e49df862c7bff6ba7cf39231ef1824f615948a1539`. No late output followed. The [independent audit](audit_report.json) checks the report, both raw server logs and the [saved WAV](tts_restart.wav).
|
||||
|
||||
This follows the [20-request hybrid profile](../../../e2e_expansion_20260923/evidence/qwen_tts_omni_hybrid/README.md), whose p50/p95 complete-request wall time remains **3.298/3.336 s** for 2.56 s of speech. The one measured request in this recovery run took 3.591 s and is not a new p50/p95 performance profile. The fresh request took 3.567 s after 4.607 s of fresh-stage startup. The run establishes fresh-stage restart after one genuinely started cancellation, not resumed same-session generation, playable chunk streaming, concurrency or sustained real-time operation. The previous RTF-above-1 and quality/thermal gaps remain.
|
||||
|
||||
The host was Windows 11 build 26200 on Ryzen AI 9 HX 370, Radeon 890M driver `32.0.22018.6001`, power scheme `Performance`; an RTX 5090 Laptop GPU was installed but not selected. [Hardware data](hardware.json) was captured immediately after the run. The local CPU/Vulkan CrispASR v0.8.35 build, Q8_0 talker, F16 codec and cached punctuation GGUF are pinned in both execution plans of the [raw report](tts_restart_report.json); their SHA-256 values and source revisions are documented in the [earlier hybrid record](../../../e2e_expansion_20260923/evidence/qwen_tts_omni_hybrid/README.md). All weights remain in local storage outside Git. The source-checkpoint/converter provenance and full same-checkpoint numerical parity are still unestablished.
|
||||
|
||||
Reproduce with [the stage probe](../../../../experiments/probe_omni_crisp_tts.py) on native Windows Python/vLLM 0.29 using this checkout on `PYTHONPATH`, `PYTHONUTF8=1` and `VLLM_ENABLE_V1_MULTIPROCESSING=0`. Supply the four pinned local artifacts and hashes, `--server-log`, `--output-report`, `--output-wav`, `--warmups 0 --repeats 1 --abort-check --restart-check`. Run [the auditor](../../../../experiments/audit_qwen_tts_windows_restart.py) against this directory. The auditor verifies the saved PCM payload, backend-start marker, device route, generation change and cleared ledgers. Neither this Windows test nor the hosted Qualcomm component tests is a mobile E2E result.
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"status": "passed",
|
||||
"scope": "one native Windows hybrid TTS cancellation after backend prefill and fresh StageRuntime request",
|
||||
"old_generation": "a8d34f360d81401d81ee9b2da7b2a647",
|
||||
"new_generation": "b620c98d9023499b958178d3c626fd51",
|
||||
"first_server_prefills": 4,
|
||||
"fresh_server_prefills": 1,
|
||||
"fresh_pcm_sha256": "57f60228e2b456f6dfefc7e49df862c7bff6ba7cf39231ef1824f615948a1539",
|
||||
"ledger_cleared": true,
|
||||
"files": {
|
||||
"tts_restart_report.json": {
|
||||
"bytes": 6122,
|
||||
"sha256": "6affe36b168ddcea713ebe1a98a327bd5f0b5eb833626a39235945d509e9af6e"
|
||||
},
|
||||
"tts_restart_server.log": {
|
||||
"bytes": 7387,
|
||||
"sha256": "67253d6dfa6a0a0c368869deb1412c15e00630ce2c05be64e29c82353edaccea"
|
||||
},
|
||||
"tts_restart_server_restart.log": {
|
||||
"bytes": 6562,
|
||||
"sha256": "be940c180220aebc6b25bc4a176167a72624f968c322b305da3cf4124674dc9e"
|
||||
},
|
||||
"tts_restart.wav": {
|
||||
"bytes": 122924,
|
||||
"sha256": "1bb9590f367ab531c66fc20d9b8aed9f0477fde67f2bdbe16e60de5a40b17e27"
|
||||
},
|
||||
"hardware.json": {
|
||||
"bytes": 712,
|
||||
"sha256": "6d211d37d1743fd2de0a43f3ec298ec43510a8bf5f5b4fda09d5df4610092ad6"
|
||||
}
|
||||
},
|
||||
"limits": [
|
||||
"The stage returns a complete WAV, not incremental playable audio.",
|
||||
"A fresh StageRuntime starts after cancellation; no same-session state migration is claimed.",
|
||||
"One recovery case is not concurrency or sustained reliability qualification."
|
||||
]
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"os": {
|
||||
"Caption": "Microsoft Windows 11 家庭版 中文版",
|
||||
"BuildNumber": "26200",
|
||||
"TotalVisibleMemorySize": 66185068
|
||||
},
|
||||
"power_scheme": "电源方案 GUID: 27fa6203-3987-4dcc-918d-748559d549ec (Performance)",
|
||||
"gpus": [
|
||||
{
|
||||
"Name": "NVIDIA GeForce RTX 5090 Laptop GPU",
|
||||
"DriverVersion": "32.0.16.1071",
|
||||
"AdapterRAM": 4293918720
|
||||
},
|
||||
{
|
||||
"Name": "AMD Radeon(TM) 890M Graphics",
|
||||
"DriverVersion": "32.0.22018.6001",
|
||||
"AdapterRAM": 536870912
|
||||
}
|
||||
],
|
||||
"cpu": {
|
||||
"Name": "AMD Ryzen AI 9 HX 370 w/ Radeon 890M ",
|
||||
"NumberOfCores": 12,
|
||||
"NumberOfLogicalProcessors": 24
|
||||
},
|
||||
"captured_at": "2026-09-24T15:25:59.9813208+08:00"
|
||||
}
|
||||
BIN
Binary file not shown.
+194
@@ -0,0 +1,194 @@
|
||||
{
|
||||
"scope": "complete resident Qwen3-TTS CustomVoice text-to-WAV through Omni StageRuntime/StagePool",
|
||||
"placement": "Radeon Vulkan talker/codec + CPU FP32 code predictor",
|
||||
"warmup_count": 0,
|
||||
"measured_count": 1,
|
||||
"memory_budget": {
|
||||
"capacities": {
|
||||
"host_ram": 17179869184
|
||||
},
|
||||
"demands": {
|
||||
"host_ram": 8589934592
|
||||
}
|
||||
},
|
||||
"startup_s": 5.106592299998738,
|
||||
"execution_plan": {
|
||||
"backend": "external.crisp.tts.v1",
|
||||
"stage_id": 0,
|
||||
"worker_generation": "a8d34f360d81401d81ee9b2da7b2a647",
|
||||
"worker_pid": 29064,
|
||||
"artifact_sha256": {
|
||||
"server_sha256": "999c6af252077195adb723b96da9ee5d3cd291dc7c7a4b32dc493ae148035529",
|
||||
"talker_sha256": "5227dcbc4df7c5533341d111cc469fa491a48e722b23dd10f553181b52dff2d9",
|
||||
"codec_sha256": "70dc95dbfdd9aa5d9d406236ff771d061bf17b0cda02a72513953355606e719b",
|
||||
"punc_sha256": "faf4a43e3135bc307a66194685af00f756e6f4c28c7d9e2dd8f3517cddca5c45"
|
||||
},
|
||||
"placement": "Radeon Vulkan0 talker/codec + CPU FP32 code predictor",
|
||||
"expected_gpu_name": "AMD Radeon(TM) 890M Graphics",
|
||||
"ggml_vk_visible_devices": "1",
|
||||
"loaded_rss_bytes": 2729025536,
|
||||
"reserved_bytes": {
|
||||
"host_ram": 8589934592
|
||||
},
|
||||
"memory_overhead_bytes": 5368709120,
|
||||
"max_text_bytes": 4096,
|
||||
"max_wav_bytes": 4194304,
|
||||
"max_audio_s": 10.0,
|
||||
"voice": "ryan",
|
||||
"seed": 42,
|
||||
"request_capacity": 1,
|
||||
"stateful_session": "CrispASR-owned; complete WAV per request",
|
||||
"evidence": "B"
|
||||
},
|
||||
"checks": [
|
||||
{
|
||||
"text": "Hello from the local computer.",
|
||||
"wall_s": 3.680498000001535,
|
||||
"frames": 61440,
|
||||
"duration_s": 2.56,
|
||||
"pcm_sha256": "57f60228e2b456f6dfefc7e49df862c7bff6ba7cf39231ef1824f615948a1539",
|
||||
"stage_event": {
|
||||
"request_id": "tts-689434125000000",
|
||||
"stage_id": 0,
|
||||
"epoch": 1,
|
||||
"seq": 1,
|
||||
"kind": "audio",
|
||||
"worker_generation": "a8d34f360d81401d81ee9b2da7b2a647",
|
||||
"buffers": [],
|
||||
"terminal": true,
|
||||
"error": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "The blue car is parked beside the library.",
|
||||
"wall_s": 4.554462900036015,
|
||||
"frames": 76800,
|
||||
"duration_s": 3.2,
|
||||
"pcm_sha256": "4832877787577d2e47b51f325a09e17df37b7f2a95ed5297b37259977286476d",
|
||||
"stage_event": {
|
||||
"request_id": "tts-689437812000000",
|
||||
"stage_id": 0,
|
||||
"epoch": 2,
|
||||
"seq": 1,
|
||||
"kind": "audio",
|
||||
"worker_generation": "a8d34f360d81401d81ee9b2da7b2a647",
|
||||
"buffers": [],
|
||||
"terminal": true,
|
||||
"error": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"warmups": [],
|
||||
"measured": [
|
||||
{
|
||||
"text": "Hello from the local computer.",
|
||||
"wall_s": 3.5914841999765486,
|
||||
"frames": 61440,
|
||||
"duration_s": 2.56,
|
||||
"pcm_sha256": "57f60228e2b456f6dfefc7e49df862c7bff6ba7cf39231ef1824f615948a1539",
|
||||
"stage_event": {
|
||||
"request_id": "tts-689442359000000",
|
||||
"stage_id": 0,
|
||||
"epoch": 3,
|
||||
"seq": 1,
|
||||
"kind": "audio",
|
||||
"worker_generation": "a8d34f360d81401d81ee9b2da7b2a647",
|
||||
"buffers": [],
|
||||
"terminal": true,
|
||||
"error": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"nearest_rank_p50_wall_s": 3.5914841999765486,
|
||||
"nearest_rank_p95_wall_s": 3.5914841999765486,
|
||||
"all_same_pcm_sha256": true,
|
||||
"abort_check": {
|
||||
"prefills_before_abort_request": 3,
|
||||
"prefills_after_abort_request_start": 4,
|
||||
"stale_output": false,
|
||||
"worker_exited": true,
|
||||
"ledger_after_abort": {
|
||||
"capacities": {
|
||||
"host_ram": 17179869184
|
||||
},
|
||||
"reserved": {
|
||||
"host_ram": 0
|
||||
},
|
||||
"owners": [],
|
||||
"quarantined": []
|
||||
}
|
||||
},
|
||||
"restart_check": {
|
||||
"first_runtime_ledger_after_shutdown": {
|
||||
"capacities": {
|
||||
"host_ram": 17179869184
|
||||
},
|
||||
"reserved": {
|
||||
"host_ram": 0
|
||||
},
|
||||
"owners": [],
|
||||
"quarantined": []
|
||||
},
|
||||
"fresh_startup_s": 4.606651999987662,
|
||||
"fresh_server_log": "\\\\wsl.localhost\\Ubuntu\\home\\zhout\\project\\edge_infer\\vllm-omni-edge\\benchmarks\\edge_harness\\results\\e2e_expansion_20260924\\evidence\\qwen_tts_omni_windows_restart\\tts_restart_server_restart.log",
|
||||
"fresh_execution_plan": {
|
||||
"backend": "external.crisp.tts.v1",
|
||||
"stage_id": 0,
|
||||
"worker_generation": "b620c98d9023499b958178d3c626fd51",
|
||||
"worker_pid": 8584,
|
||||
"artifact_sha256": {
|
||||
"server_sha256": "999c6af252077195adb723b96da9ee5d3cd291dc7c7a4b32dc493ae148035529",
|
||||
"talker_sha256": "5227dcbc4df7c5533341d111cc469fa491a48e722b23dd10f553181b52dff2d9",
|
||||
"codec_sha256": "70dc95dbfdd9aa5d9d406236ff771d061bf17b0cda02a72513953355606e719b",
|
||||
"punc_sha256": "faf4a43e3135bc307a66194685af00f756e6f4c28c7d9e2dd8f3517cddca5c45"
|
||||
},
|
||||
"placement": "Radeon Vulkan0 talker/codec + CPU FP32 code predictor",
|
||||
"expected_gpu_name": "AMD Radeon(TM) 890M Graphics",
|
||||
"ggml_vk_visible_devices": "1",
|
||||
"loaded_rss_bytes": 2729070592,
|
||||
"reserved_bytes": {
|
||||
"host_ram": 8589934592
|
||||
},
|
||||
"memory_overhead_bytes": 5368709120,
|
||||
"max_text_bytes": 4096,
|
||||
"max_wav_bytes": 4194304,
|
||||
"max_audio_s": 10.0,
|
||||
"voice": "ryan",
|
||||
"seed": 42,
|
||||
"request_capacity": 1,
|
||||
"stateful_session": "CrispASR-owned; complete WAV per request",
|
||||
"evidence": "B"
|
||||
},
|
||||
"fresh_request": {
|
||||
"text": "Hello from the local computer.",
|
||||
"wall_s": 3.566567700006999,
|
||||
"frames": 61440,
|
||||
"duration_s": 2.56,
|
||||
"pcm_sha256": "57f60228e2b456f6dfefc7e49df862c7bff6ba7cf39231ef1824f615948a1539",
|
||||
"stage_event": {
|
||||
"request_id": "tts-689451015000000",
|
||||
"stage_id": 0,
|
||||
"epoch": 1,
|
||||
"seq": 1,
|
||||
"kind": "audio",
|
||||
"worker_generation": "b620c98d9023499b958178d3c626fd51",
|
||||
"buffers": [],
|
||||
"terminal": true,
|
||||
"error": null
|
||||
}
|
||||
},
|
||||
"same_pcm_as_before_abort": true,
|
||||
"late_output": false
|
||||
},
|
||||
"status": "passed",
|
||||
"ledger_after_shutdown": {
|
||||
"capacities": {
|
||||
"host_ram": 17179869184
|
||||
},
|
||||
"reserved": {
|
||||
"host_ram": 0
|
||||
},
|
||||
"owners": [],
|
||||
"quarantined": []
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
crispasr 0.8.35 (git 00c9e752, Release) [backends: cpu,vulkan]
|
||||
=== build info ===
|
||||
version : 0.8.35
|
||||
git sha : 00c9e752
|
||||
git date : 2026-09-21T20:44:31Z
|
||||
git subject : release-_bump_VERSION_to_0.8.35
|
||||
build date : 2026-09-21T21:04:24Z
|
||||
build type : Release
|
||||
compiler : msvc 1951
|
||||
os : windows
|
||||
arch : x86_64
|
||||
ggml backends : cpu,vulkan
|
||||
|
||||
=== runtime env ===
|
||||
PATH = C:\Users\zhout\w2\omni029venv\Lib\site-packages\cv2\../../x64/vc17/bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\powershell;C:\Users\zhout\.codex\tmp\arg0\codex-arg0hEiqWp;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\libheif\libheif\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\jxrlib\jxrlib\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\poppler\Library\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\override;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.4\bin\x64;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.4\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA App\NvDLISR;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\Git\cmd;C:\Program Files\NVIDIA Corporation\Nsight Compute 2026.3.0\;C:\Users\zhout\.cargo\bin;C:\Users\zhout\AppData\Local\Programs\Python\Python312\Scripts\;C:\Users\zhout\AppData\Local\Programs\Python\Python312\;C:\Users\zhout\AppData\Local\Programs\Python\Launcher\;c:\Users\zhout\AppData\Local\Programs\cursor\resources\app\codeBin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\powershell;C:\Users\zhout\AppData\Local\Microsoft\WindowsApps;C:\Users\zhout\AppData\Local\Programs\cursor\resources\app\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\fallback;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\git\cmd;C:\Users\zhout\AppData\Local\OpenAI\Codex\bin\d5b459afd5dcd195;C:\Users\zhout\AppData\Local\OpenAI\Codex\bin\80f78947ad880e6e
|
||||
LD_LIBRARY_PATH = (unset)
|
||||
LIBRARY_PATH = (unset)
|
||||
CUDA_HOME = (unset)
|
||||
CUDA_PATH = C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.4
|
||||
CUDA_VISIBLE_DEVICES = 1
|
||||
NVIDIA_VISIBLE_DEVICES = (unset)
|
||||
NVIDIA_DRIVER_CAPABILITIES = (unset)
|
||||
GGML_CUDA_DEBUG = 1
|
||||
GGML_VK_VISIBLE_DEVICES = 1
|
||||
GGML_VK_PIPELINE_CACHE_DEBUG = 1
|
||||
CRISPASR_USE_CUDA_COMPAT = (unset)
|
||||
CRISPASR_BACKEND = (unset)
|
||||
CRISPASR_CACHE_DIR = (unset)
|
||||
|
||||
=== ggml backends + devices ===
|
||||
ggml_vulkan: Found 1 Vulkan devices:
|
||||
ggml_vulkan: 0 = AMD Radeon(TM) 890M Graphics (AMD proprietary driver) | uma: 1 | fp16: 1 | bf16: 1 | fp4: 0 | warp size: 64 | shared memory: 32768 | int dot: 1 | matrix cores: KHR_coopmat
|
||||
registered backends: 2
|
||||
[0] Vulkan (devices: 1)
|
||||
[1] CPU (devices: 1)
|
||||
registered devices : 2
|
||||
[0] igpu name=Vulkan0 desc=AMD Radeon(TM) 890M Graphics mem=46080/48505 MiB id=?
|
||||
[1] cpu name=CPU desc=AMD Ryzen AI 9 HX 370 w/ Radeon 890M mem=26845/64633 MiB id=?
|
||||
|
||||
cpu-isa: OK — built for AVX2/FMA/F16C/BMI2/AVX; host CPU supports the build's ISA baseline
|
||||
crispasr_init_gpu_backend: using preferred GPU backend: Vulkan0
|
||||
qwen3_tts: code_pred CPU-pinned (72 tensors, 432 MB, copy=f32)
|
||||
qwen3_tts: kv cache 448 MiB (head_dim=128 max_ctx=4096 n_kv=8 n_layers=28)
|
||||
qwen3_tts: loaded C:\Users\zhout\w2\models\crisp_qwen3tts_0.6b\qwen3-tts-12hz-0.6b-customvoice-q8_0.gguf (talker 28L/1024 code_pred 5L vocab 3072)
|
||||
qwen3_tts: codec: GPU default - loading weights onto Vulkan0
|
||||
qwen3_tts: codec loaded from 'C:\Users\zhout\w2\models\crisp_qwen3tts_0.6b\qwen3-tts-tokenizer-12hz.gguf' (8L d=512/1024 rvq=16)
|
||||
qwen3_tts: codec encoder loaded (SEANet+xfmr+RVQ)
|
||||
crispasr[qwen3-tts]: codec loaded from 'C:\Users\zhout\w2\models\crisp_qwen3tts_0.6b\qwen3-tts-tokenizer-12hz.gguf'
|
||||
crispasr-server: warmup completed in 0 ms
|
||||
crispasr-server: backend 'qwen3-tts-customvoice' loaded, model 'C:\Users\zhout\w2\models\crisp_qwen3tts_0.6b\qwen3-tts-12hz-0.6b-customvoice-q8_0.gguf'
|
||||
fireredpunc: 12L, d=768, ffn=3072, heads=12, vocab=21128, labels=5
|
||||
crispasr_init_gpu_backend: using preferred GPU backend: Vulkan0
|
||||
crispasr-server: loaded punctuation model 'C:\Users\zhout\.cache\crispasr\fireredpunc-q4_k.gguf'
|
||||
|
||||
crispasr-server: listening on 127.0.0.1:61307
|
||||
POST /inference — upload audio (native JSON)
|
||||
POST /v1/audio/transcriptions — OpenAI-compatible API
|
||||
POST /v1/audio/speech — TTS (OpenAI-compatible)
|
||||
POST /load — hot-swap model
|
||||
GET /health — server status
|
||||
GET /backends — list backends
|
||||
GET /v1/models — model info
|
||||
GET /v1/voices — list voices in --voice-dir
|
||||
/voices, /v1/audio/voices — aliases (llama-swap compat)
|
||||
POST /v1/voices — upload voice file (multipart)
|
||||
DELETE /v1/voices/:name — delete voice file
|
||||
crispasr-server: warning: --voice-dir not set; /v1/voices will return empty and /v1/audio/speech will reject requests with a 'voice' field
|
||||
|
||||
crispasr: warning: 'qwen3-tts-customvoice' does not record whether its preset voice belongs to a real person, so no spoken AI
|
||||
disclosure was added. If the voice is that of an identifiable individual, the output is a
|
||||
deep fake under EU AI Act Art. 3(60) and you carry the Art. 50(4) duty to disclose it.
|
||||
Pass --speaker-identity real_person to have CrispASR prepend the disclosure, or
|
||||
--speaker-identity synthetic to silence this.
|
||||
qwen3_tts: selected CustomVoice speaker 'ryan' (spk_id=3061)
|
||||
crispasr[qwen3-tts]: CustomVoice speaker = 'ryan' (available: aiden, dylan, eric, ono_anna, ryan, serena, sohee, uncle_fu, vivian)
|
||||
qwen3_tts[customvoice]: prefill role=3 + bridge=5 + text=7 + final=1 = T=16 trailing=1
|
||||
qwen3_tts: produced 32 frames × 16 codebooks = 512 codes
|
||||
qwen3_tts: perf — codes=3293 ms codec=293 ms total=3587 ms audio=2.6 s rtf=1.401
|
||||
crispasr-server: synthesized 2.6s audio in 3.61s (RTF=1.41) voice='<startup>' speed=1.00 format=wav model='<unset>' chunks=1 sr=24000Hz
|
||||
qwen3_tts[customvoice]: prefill role=3 + bridge=5 + text=10 + final=1 = T=19 trailing=1
|
||||
qwen3_tts: produced 40 frames × 16 codebooks = 640 codes
|
||||
qwen3_tts: perf — codes=4180 ms codec=323 ms total=4504 ms audio=3.2 s rtf=1.407
|
||||
crispasr-server: synthesized 3.2s audio in 4.54s (RTF=1.42) voice='<startup>' speed=1.00 format=wav model='<unset>' chunks=1 sr=24000Hz
|
||||
qwen3_tts[customvoice]: prefill role=3 + bridge=5 + text=7 + final=1 = T=16 trailing=1
|
||||
qwen3_tts: produced 32 frames × 16 codebooks = 512 codes
|
||||
qwen3_tts: perf — codes=3318 ms codec=261 ms total=3579 ms audio=2.6 s rtf=1.398
|
||||
crispasr-server: synthesized 2.6s audio in 3.58s (RTF=1.40) voice='<startup>' speed=1.00 format=wav model='<unset>' chunks=1 sr=24000Hz
|
||||
qwen3_tts[customvoice]: prefill role=3 + bridge=5 + text=10 + final=1 = T=19 trailing=1
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
crispasr 0.8.35 (git 00c9e752, Release) [backends: cpu,vulkan]
|
||||
=== build info ===
|
||||
version : 0.8.35
|
||||
git sha : 00c9e752
|
||||
git date : 2026-09-21T20:44:31Z
|
||||
git subject : release-_bump_VERSION_to_0.8.35
|
||||
build date : 2026-09-21T21:04:24Z
|
||||
build type : Release
|
||||
compiler : msvc 1951
|
||||
os : windows
|
||||
arch : x86_64
|
||||
ggml backends : cpu,vulkan
|
||||
|
||||
=== runtime env ===
|
||||
PATH = C:\Users\zhout\w2\omni029venv\Lib\site-packages\cv2\../../x64/vc17/bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\powershell;C:\Users\zhout\.codex\tmp\arg0\codex-arg0hEiqWp;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\libheif\libheif\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\jxrlib\jxrlib\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\poppler\Library\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\override;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.4\bin\x64;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.4\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA App\NvDLISR;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files\Git\cmd;C:\Program Files\NVIDIA Corporation\Nsight Compute 2026.3.0\;C:\Users\zhout\.cargo\bin;C:\Users\zhout\AppData\Local\Programs\Python\Python312\Scripts\;C:\Users\zhout\AppData\Local\Programs\Python\Python312\;C:\Users\zhout\AppData\Local\Programs\Python\Launcher\;c:\Users\zhout\AppData\Local\Programs\cursor\resources\app\codeBin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\powershell;C:\Users\zhout\AppData\Local\Microsoft\WindowsApps;C:\Users\zhout\AppData\Local\Programs\cursor\resources\app\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\fallback;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\bin;C:\Users\zhout\.cache\codex-runtimes\codex-primary-runtime\dependencies\native\git\cmd;C:\Users\zhout\AppData\Local\OpenAI\Codex\bin\d5b459afd5dcd195;C:\Users\zhout\AppData\Local\OpenAI\Codex\bin\80f78947ad880e6e
|
||||
LD_LIBRARY_PATH = (unset)
|
||||
LIBRARY_PATH = (unset)
|
||||
CUDA_HOME = (unset)
|
||||
CUDA_PATH = C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.4
|
||||
CUDA_VISIBLE_DEVICES = 1
|
||||
NVIDIA_VISIBLE_DEVICES = (unset)
|
||||
NVIDIA_DRIVER_CAPABILITIES = (unset)
|
||||
GGML_CUDA_DEBUG = 1
|
||||
GGML_VK_VISIBLE_DEVICES = 1
|
||||
GGML_VK_PIPELINE_CACHE_DEBUG = 1
|
||||
CRISPASR_USE_CUDA_COMPAT = (unset)
|
||||
CRISPASR_BACKEND = (unset)
|
||||
CRISPASR_CACHE_DIR = (unset)
|
||||
|
||||
=== ggml backends + devices ===
|
||||
ggml_vulkan: Found 1 Vulkan devices:
|
||||
ggml_vulkan: 0 = AMD Radeon(TM) 890M Graphics (AMD proprietary driver) | uma: 1 | fp16: 1 | bf16: 1 | fp4: 0 | warp size: 64 | shared memory: 32768 | int dot: 1 | matrix cores: KHR_coopmat
|
||||
registered backends: 2
|
||||
[0] Vulkan (devices: 1)
|
||||
[1] CPU (devices: 1)
|
||||
registered devices : 2
|
||||
[0] igpu name=Vulkan0 desc=AMD Radeon(TM) 890M Graphics mem=46080/48505 MiB id=?
|
||||
[1] cpu name=CPU desc=AMD Ryzen AI 9 HX 370 w/ Radeon 890M mem=27395/64633 MiB id=?
|
||||
|
||||
cpu-isa: OK — built for AVX2/FMA/F16C/BMI2/AVX; host CPU supports the build's ISA baseline
|
||||
crispasr_init_gpu_backend: using preferred GPU backend: Vulkan0
|
||||
qwen3_tts: code_pred CPU-pinned (72 tensors, 432 MB, copy=f32)
|
||||
qwen3_tts: kv cache 448 MiB (head_dim=128 max_ctx=4096 n_kv=8 n_layers=28)
|
||||
qwen3_tts: loaded C:\Users\zhout\w2\models\crisp_qwen3tts_0.6b\qwen3-tts-12hz-0.6b-customvoice-q8_0.gguf (talker 28L/1024 code_pred 5L vocab 3072)
|
||||
qwen3_tts: codec: GPU default - loading weights onto Vulkan0
|
||||
qwen3_tts: codec loaded from 'C:\Users\zhout\w2\models\crisp_qwen3tts_0.6b\qwen3-tts-tokenizer-12hz.gguf' (8L d=512/1024 rvq=16)
|
||||
qwen3_tts: codec encoder loaded (SEANet+xfmr+RVQ)
|
||||
crispasr[qwen3-tts]: codec loaded from 'C:\Users\zhout\w2\models\crisp_qwen3tts_0.6b\qwen3-tts-tokenizer-12hz.gguf'
|
||||
crispasr-server: warmup completed in 0 ms
|
||||
crispasr-server: backend 'qwen3-tts-customvoice' loaded, model 'C:\Users\zhout\w2\models\crisp_qwen3tts_0.6b\qwen3-tts-12hz-0.6b-customvoice-q8_0.gguf'
|
||||
fireredpunc: 12L, d=768, ffn=3072, heads=12, vocab=21128, labels=5
|
||||
crispasr_init_gpu_backend: using preferred GPU backend: Vulkan0
|
||||
crispasr-server: loaded punctuation model 'C:\Users\zhout\.cache\crispasr\fireredpunc-q4_k.gguf'
|
||||
|
||||
crispasr-server: listening on 127.0.0.1:61338
|
||||
POST /inference — upload audio (native JSON)
|
||||
POST /v1/audio/transcriptions — OpenAI-compatible API
|
||||
POST /v1/audio/speech — TTS (OpenAI-compatible)
|
||||
POST /load — hot-swap model
|
||||
GET /health — server status
|
||||
GET /backends — list backends
|
||||
GET /v1/models — model info
|
||||
GET /v1/voices — list voices in --voice-dir
|
||||
/voices, /v1/audio/voices — aliases (llama-swap compat)
|
||||
POST /v1/voices — upload voice file (multipart)
|
||||
DELETE /v1/voices/:name — delete voice file
|
||||
crispasr-server: warning: --voice-dir not set; /v1/voices will return empty and /v1/audio/speech will reject requests with a 'voice' field
|
||||
|
||||
crispasr: warning: 'qwen3-tts-customvoice' does not record whether its preset voice belongs to a real person, so no spoken AI
|
||||
disclosure was added. If the voice is that of an identifiable individual, the output is a
|
||||
deep fake under EU AI Act Art. 3(60) and you carry the Art. 50(4) duty to disclose it.
|
||||
Pass --speaker-identity real_person to have CrispASR prepend the disclosure, or
|
||||
--speaker-identity synthetic to silence this.
|
||||
qwen3_tts: selected CustomVoice speaker 'ryan' (spk_id=3061)
|
||||
crispasr[qwen3-tts]: CustomVoice speaker = 'ryan' (available: aiden, dylan, eric, ono_anna, ryan, serena, sohee, uncle_fu, vivian)
|
||||
qwen3_tts[customvoice]: prefill role=3 + bridge=5 + text=7 + final=1 = T=16 trailing=1
|
||||
qwen3_tts: produced 32 frames × 16 codebooks = 512 codes
|
||||
qwen3_tts: perf — codes=3257 ms codec=240 ms total=3497 ms audio=2.6 s rtf=1.366
|
||||
crispasr-server: synthesized 2.6s audio in 3.51s (RTF=1.37) voice='<startup>' speed=1.00 format=wav model='<unset>' chunks=1 sr=24000Hz
|
||||
@@ -8,6 +8,8 @@ A [follow-up MiniCPM-o storage experiment](../../../e2e_expansion_20260923/evide
|
||||
|
||||
The [WSL CPU Spark GGUF Omni profile](../../../e2e_expansion_20260923/evidence/spark_omni_wsl_cpu/README.md) adds a separate current-Omni complete-request path to the earlier vLLM INT8 CPU result. It passed two named prompts, 20/20 serial measured inventory requests at p50/p95 7.82/7.97 s, a public text request, context refusal and cancellation cleanup. The CPU-only llama.cpp build required explicit CPU-buffer placement evidence because it omits the Windows offload-count log line. This does not establish token streaming or broad quality.
|
||||
|
||||
A [native Windows Radeon+CPU Qwen3-TTS recovery probe](../../../e2e_expansion_20260924/evidence/qwen_tts_omni_windows_restart/README.md) now verifies that the owned server entered prefill before cancellation, then a fresh Omni stage with the same pinned weights and hybrid placement returned identical PCM under a new worker generation. The single recovery run supplements the earlier 20-request complete-WAV profile; it does not establish playable streaming, same-session continuation or sustained real-time speech.
|
||||
|
||||
A complete pinned [Spark 1.7B BF16 WSL CPU checkpoint and acceptance run](../../../e2e_expansion_20260924/evidence/spark_bf16_wsl_cpu/README.md) adds a second current-Omni text artifact to the GGUF route. Twelve prompts produced 128 tokens each with clean cancellation; all 12 token-ID sequences exactly matched standalone vLLM on the same checkpoint. One warmup plus 20 serial 28-prompt-token/64-output-token requests measured p50/p95 complete-request wall time 5.411/5.751 s and TTFT 0.129/0.146 s on the fork branch. A fresh-session restart after an eight-token cancellation reproduced the same 128 greedy token IDs, while the retired handle was explicitly rejected. This is WSL CPU full-text scope, not mobile generation or broad quality qualification.
|
||||
|
||||
On a hosted [Galaxy S24 Spark attention-layer experiment](../../../e2e_expansion_20260923/evidence/spark_s24_full_attention/README.md), a real one-layer W8A16 QDQ artifact executed on NPU and matched prior S25 component outputs exactly on one dataset. The 100-sample layer p50/p95 was 1.109/1.205 ms; the service's 1.098 ms estimated-time field was the sample minimum. FP32-source versus S24 output hidden-state relative L2 was 1.351% without a downstream token-quality gate. This adds component C evidence only; device-local generation remains absent.
|
||||
@@ -46,7 +48,7 @@ NOT E2E means no complete device/model workload was verified. “Scoped E2E” i
|
||||
| PC HX370: CPU / native Windows | scoped E2E: Omni Spark text; fresh restart after in-flight cancel | scoped E2E: Omni CPU text → complete WAV | NOT E2E | scoped E2E: Omni GGUF image+audio → text+speech (native-storage 20-run profile) | synthetic policy pass: Omni CPU |
|
||||
| PC HX370 + RTX 5090 Laptop / WSL | profile completed | profile completed | scoped E2E: text + image | scoped E2E: text/image/audio → speech | synthetic policy pass: admitted Omni CUDA |
|
||||
| PC HX370 + RTX 5090 Laptop / Windows | profile completed | profile completed; 30-min repeat no collapse, brief playback jitter | NOT E2E | scoped E2E: text/image/audio → speech | synthetic policy pass: admitted Omni CUDA |
|
||||
| PC HX370 + Radeon 890M / Windows worker | scoped E2E: Omni Spark text; fresh restart after in-flight cancel | scoped E2E: Omni Radeon talker/codec + CPU predictor | NOT E2E | scoped E2E: Omni Radeon+CPU image+audio → text+speech (native-storage 20-run profile) | synthetic policy pass: Omni CPU+Radeon Cosmos (WSL/native Windows) |
|
||||
| PC HX370 + Radeon 890M / Windows worker | scoped E2E: Omni Spark text; fresh restart after in-flight cancel | scoped E2E: Omni Radeon talker/codec + CPU predictor; fresh restart after in-flight cancel | NOT E2E | scoped E2E: Omni Radeon+CPU image+audio → text+speech (native-storage 20-run profile) | synthetic policy pass: Omni CPU+Radeon Cosmos (WSL/native Windows) |
|
||||
| PC HX370 + AMD NPU / Windows worker | NOT E2E (output-head component passed) | NOT E2E | NOT E2E | NOT E2E | NOT E2E |
|
||||
| PC CPU+iGPU+NPU +/- discrete GPU, joint model execution | NOT E2E | NOT E2E | NOT E2E | NOT E2E | NOT E2E |
|
||||
| PC Snapdragon X Elite CRD / AI Hub | NOT E2E (one Spark attention layer on NPU) | NOT E2E (CPU talker/vocoder steps; two-frame QNN vocoder on NPU, component RTF 22.89) | NOT E2E | NOT E2E (NPU speech-head step profiled) | NOT E2E (Cosmos NPU encoder profiled) |
|
||||
@@ -80,7 +82,7 @@ NOT E2E means no complete device/model workload was verified. “Scoped E2E” i
|
||||
| PC HX370 + RTX 5090 Laptop / Windows | MiniCPM-o 4.5 | SCOPED_E2E | The verified checkpoint completed native Windows three-stage BF16 text, one synthetic image, and one synthetic audio input to text+speech in separate constrained plans with 5 GiB thinker host offload and explicit 2,048/512-token limits. Text and all 32 thinker token IDs matched WSL CUDA; a 5.2 s WAV was nonzero. The red-square image produced the same description and 27 thinker token IDs as WSL plus a nonzero 5.2 s WAV in 17.15 s. The 2 s/440 Hz tone produced the same whistling description and nine IDs as WSL plus a nonzero 2.16 s WAV in 8.26 s. The initial text run needed 900/600 s startup limits after a 300 s timeout; a separate 1-warmup/20-measured serial text run had request wall p50 18.38 s/p95 18.73 s, with sampled host available RAM as low as 0.78 GB and pagefile use up to 11.17 GB. These synthetic inputs do not establish general image/audio or speech quality. | Check real image/audio suites, video input, speech intelligibility/alignment, concurrency, interruption, loading-peak admission and sustained thermal/power behavior before broader qualification; [native evidence](../../../e2e_expansion_20260923/README.md). |
|
||||
| PC HX370 + RTX 5090 Laptop / Windows | InternVLA-A1 | SYNTHETIC_POLICY_PASS_OMNI_CUDA; NOT_TASK_E2E | The real Place_Markpen checkpoint ran through an admitted native Windows Omni whole-policy graph stage with BF16 policy and Cosmos encoder on the RTX 5090 Laptop GPU. After one warmup, 20/20 serial patterned synthetic requests returned identical finite float32 [1,50,32] actions with terminal events; nearest-rank complete-request wall p50/p95 was 0.746/0.806 s, excluding 147.77 s startup. The 16 GiB host-RAM and 16 GiB CUDA demands were within explicit 18/21 GiB ceilings checked against available memory. Actual CUDA placement was verified, PyTorch peak reserved VRAM reached 7.86 GB, and an 8 GiB VRAM plan was refused before worker launch. In-flight cancellation and shutdown released both ledgers with no stale output; a separate public AsyncOmni.generate request returned the same action hash. Relative to the separate native CPU patterned output, action relative L2 difference was 2.340% with no task tolerance; native-vs-WSL CUDA relative L2 was 1.555%. The earlier one-forward zero-input direct CUDA run was a different experiment. This is synthetic action-policy integration, not robot-task E2E; units/order/step time remain unverified and control_ready=false. | Validate real observations/reference actions and physical action semantics, post-cancel restart, concurrent admission, loading peak, deadlines and sustained latency/power/thermal behavior; [Omni Windows CUDA evidence](../../../e2e_expansion_20260923/evidence/internvla_omni_windows_cuda/README.md), [earlier direct result](../../../e2e_expansion_20260923/README.md). |
|
||||
| PC HX370 + Radeon 890M / Windows worker | Spark-X2.5 | SCOPED_E2E_OMNI_COMPLETE_REQUEST; RESTART_AFTER_INFLIGHT_CANCEL_PASS | The same pinned Spark-X2.5-1.7B Q4_K_M GGUF completed text prefill/decode through a bounded Omni whole-session stage with llama.cpp Vulkan1. The log identifies Radeon 890M and 29/29 layers offloaded there, rather than RTX 5090; an intentionally wrong device name was refused. `Paris` and `1511` passed; one warmup plus 20 serial complete requests were 20/20 correct, nearest-rank wall p50/p95 2.10/2.14 s. A public AsyncOmni request passed; an oversized context was rejected with a later correct request; in-flight cancellation produced no stale output and released the ledger. The prior standalone run was 2.18/2.20 s. A separate confirmed server-start cancellation of the 120-item request terminated the Vulkan1 worker, left no stale output or reservation, and a fresh StageRuntime returned Paris under a new worker generation with Radeon 890M placement again verified. This is fresh-stage recovery, not same-session continuation. No streaming, GPU-memory peak or sustained power/thermal check is claimed. | Qualify public configuration, broader text/token quality, streaming, concurrent recovery, shared-RAM/GPU peak and sustained use; [restart evidence](../../../e2e_expansion_20260924/evidence/spark_omni_windows_restart/README.md), [Omni raw evidence](../../../e2e_expansion_20260923/evidence/spark_omni_llamacpp/README.md), [standalone evidence](../../../e2e_expansion_20260923/evidence/spark_radeon890m_llamacpp/README.md). |
|
||||
| PC HX370 + Radeon 890M / Windows worker | Qwen3-TTS 0.6B CustomVoice | SCOPED_E2E_OMNI_COMPLETE_REQUEST_HYBRID | The pinned Q8_0 CustomVoice talker, F16 codec and punctuation GGUFs completed two named text-to-WAV requests through an Omni whole-session CrispASR stage on native Windows. The runtime log identifies Radeon 890M Vulkan0 for talker/codec and the 432 MB code predictor pinned to CPU FP32; this is not all-Radeon or NPU execution. Both PCM hashes exactly match the earlier standalone outputs. Whisper tiny.en transcribed the first Omni WAV and both standalone WAVs exactly (WER 0 as an intelligibility proxy). One warmup plus 20 serial complete Omni requests for 2.56 s of audio had identical PCM and nearest-rank wall p50/p95 3.298/3.336 s (RTF 1.29/1.30). A public AsyncOmni audio request passed; cancellation drained the worker without stale output or remaining reservation. The earlier standalone profile was 3.310/3.345 s. The default Vulkan configuration previously fell back to CPU, all-Vulkan ran away to a 360-frame cap, and DirectML failed waveform quality. No playable stream, post-cancel restart, loading peak, broad speech quality or sustained power/thermal run is claimed. | Validate playable streaming, restart/recovery, broader voice quality, shared-RAM/GPU peak, concurrency and sustained real-time behavior before wider qualification; [Omni raw evidence](../../../e2e_expansion_20260923/evidence/qwen_tts_omni_hybrid/README.md), [standalone evidence](../../../e2e_expansion_20260923/evidence/qwen_tts_radeon890m_joint/README.md), [failed DirectML route](../../../e2e_expansion_20260923/evidence/qwen_tts_radeon890m_directml/README.md). |
|
||||
| PC HX370 + Radeon 890M / Windows worker | Qwen3-TTS 0.6B CustomVoice | SCOPED_E2E_OMNI_COMPLETE_REQUEST_HYBRID; RESTART_AFTER_INFLIGHT_CANCEL_PASS | The pinned Q8_0 CustomVoice talker, F16 codec and punctuation GGUFs completed two named text-to-WAV requests through an Omni whole-session CrispASR stage on native Windows. The runtime log identifies Radeon 890M Vulkan0 for talker/codec and the 432 MB code predictor pinned to CPU FP32; this is not all-Radeon or NPU execution. Both PCM hashes exactly match the earlier standalone outputs. Whisper tiny.en transcribed the first Omni WAV and both standalone WAVs exactly (WER 0 as an intelligibility proxy). One warmup plus 20 serial complete Omni requests for 2.56 s of audio had identical PCM and nearest-rank wall p50/p95 3.298/3.336 s (RTF 1.29/1.30). A public AsyncOmni audio request passed. In a separate recovery run, the owned server log confirmed a new request entered TTS prefill before cancellation; the worker exited, the 8 GiB reservation cleared, and a fresh StageRuntime with a new worker generation returned the same 61,440-frame PCM SHA-256 without stale or late output. This is fresh-stage restart, not same-session continuation; its one measured request is not a replacement latency profile. The earlier standalone profile was 3.310/3.345 s. The default Vulkan configuration previously fell back to CPU, all-Vulkan ran away to a 360-frame cap, and DirectML failed waveform quality. No playable stream, loading peak, broad speech quality or sustained power/thermal run is claimed. | Validate playable streaming, broader voice quality, shared-RAM/GPU peak, concurrency and sustained real-time behavior before wider qualification; [restart raw evidence](../../../e2e_expansion_20260924/evidence/qwen_tts_omni_windows_restart/README.md), [Omni 20-request evidence](../../../e2e_expansion_20260923/evidence/qwen_tts_omni_hybrid/README.md), [standalone evidence](../../../e2e_expansion_20260923/evidence/qwen_tts_radeon890m_joint/README.md), [failed DirectML route](../../../e2e_expansion_20260923/evidence/qwen_tts_radeon890m_directml/README.md). |
|
||||
| PC HX370 + Radeon 890M / Windows worker | Qwen3.8-27B | NOT_E2E_PROFILEABLE | FP32 448x448 vision tower: DirectML 85/113 nodes; normalized max error 9.095e-06 versus torch CPU. Historical component path, not full 27B or current graph-stage image-to-text integration. | Recover the hashed tower bundle and qualify its current Omni graph handoff with the language stage. |
|
||||
| PC HX370 + Radeon 890M / Windows worker | MiniCPM-o 4.5 | SCOPED_E2E_OMNI_COMPLETE_REQUEST_HYBRID; NATIVE_STORAGE_PROFILED | The pinned Q4_K_M/F16 GGUF combined synthetic spoken-question+JPEG → text+speech route passed one warmup and 20/20 serial complete requests through a bounded Omni whole-session stage with weights on native NTFS. Nearest-rank wall p50/p95 was **16.35/17.20 s**, range 14.08–17.30 s, excluding 8.75 s startup; all requests returned the red-square sentence and nonzero 2.08–2.88 s 24 kHz speech with terminal audio events. The first WAV exactly matched pinned Whisper tiny.en ASR (WER 0, one-output intelligibility proxy). All 21 successful worker logs identified Radeon 890M Vulkan0 language (37/37 layers) and vision plus CPU Token2Wav, with zero prefetch warnings; sampled RSS peaked at 15.30 GB. The 21 GiB shared-RAM reservation admitted after file-cache reclaim; an initial identical attempt was explicitly refused before model load when available RAM had fallen below reservation. Cancellation left no stale output or reservation. A sequential same-artifact one-request UNC control took 90.63 s versus 16.89 s native and logged two prefetch warnings; the previous UNC 20-request profile remains p50/p95 87.27/91.45 s for that path. Storage is strongly associated with the slowdown, but OS cache/run order are uncontrolled and the separate CPU/Radeon profiles are not a qualified iGPU speedup comparison. This is CPU+iGPU joint execution, not all-Radeon, NPU, general quality, playable streaming or sustained thermal/power qualification. | Validate real multimodal quality, playable streaming, post-cancel restart, concurrency, loading peak and sustained power/thermal behavior; capture matched OS/shared-iGPU memory traces. [Native/UNC raw evidence](../../../e2e_expansion_20260923/evidence/minicpmo_omni_native_weights_io/README.md), [earlier UNC 20-request evidence](../../../e2e_expansion_20260923/evidence/minicpmo_omni_radeon_profile20/README.md). |
|
||||
| PC HX370 + Radeon 890M / Windows worker | InternVLA-A1 | SYNTHETIC_POLICY_PASS_HYBRID_OMNI; NOT_TASK_E2E | The real Place_Markpen checkpoint ran in admitted Omni whole-policy stages on both WSL CPU+Radeon and native Windows CPU+Radeon. In each, the BF16 Qwen3-VL/flow action policy stayed on CPU and a pinned six-frame FP32 Cosmos encoder used Omni's external DirectML worker; the selected Radeon 890M and graph output device were verified, without internal per-op attribution. Each placement returned 20/20 identical finite `[1,50,32]` actions after one warmup. WSL hybrid complete-request p50/p95 was 3.120/3.197 s versus its separate CPU baseline 3.175/3.219 s, with action relative L2 difference 2.305%. Native Windows hybrid was 4.575/4.725 s versus its separate CPU baseline 4.878/4.902 s, with action relative L2 difference 2.4391%. Native hybrid startup was 140.31 s versus CPU 135.60 s. These are separate one-fixture serial runs, not paired speedup or task-quality proof. FP32 encoder is an explicit precision change after DirectML BF16 aborted. Both stages verified hashes, reserved 16 GiB shared host RAM, rejected insufficient demand before launch, emitted terminal actions through public `AsyncOmni.generate`, and released reservations after in-flight cancellation/shutdown. An initial WSL hybrid shutdown quarantined 16 GiB; the lifecycle fix and reruns cleared it. The older direct hybrid zero-input profile is a different experiment. | Validate real observations/reference actions, physical units/order/step time, post-cancel restart, loading peak, concurrency and sustained tail/power before deployment; [WSL Omni evidence](../../../e2e_expansion_20260923/evidence/internvla_omni_policy/README.md), [native Windows Omni evidence](../../../e2e_expansion_20260923/evidence/internvla_omni_windows_hybrid/README.md), [earlier direct component evidence](../../../e2e_expansion_20260923/evidence/internvla_cosmos_radeon890m/README.md). |
|
||||
|
||||
@@ -327,7 +327,7 @@ outputs need reference analysis; timing alone cannot identify their cause.
|
||||
|
||||
The 2026-09-23 [Spark GGUF Omni follow-up](../../benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/spark_omni_llamacpp/README.md) adds a separate native Windows CPU/Radeon 890M whole-session option. Its pinned 1.7B Q4_K_M artifact passed two named complete text requests and 20 serial inventory requests per device through `StageRuntime`/`StagePool`; public `AsyncOmni` short requests passed on both devices. It verifies CPU or Vulkan1 placement, explicit 4 GiB host reservation, terminal event/acknowledgement and cancellation drain. A [2026-09-24 restart audit](../../benchmarks/edge_harness/results/e2e_expansion_20260924/evidence/spark_omni_windows_restart/README.md) confirmed the server had begun the long request before cancellation on each placement, then a fresh StageRuntime with the same artifact returned Paris under a new worker generation with no stale output or reservation. This does not change the vLLM M0 acceptance or establish M1 mobile generation. Its next gates are incremental output, broader token/quality parity, loading/device-memory peaks, concurrency and sustained power/thermal behavior.
|
||||
|
||||
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 [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. A separate [in-flight cancellation audit](../../benchmarks/edge_harness/results/e2e_expansion_20260924/evidence/qwen_tts_omni_windows_restart/README.md) confirmed that the request reached server prefill before cancellation; a fresh stage with the same artifacts and hybrid placement emitted the identical PCM under a new worker generation, without stale output or a retained reservation. This is progress toward M2 integration, not M2 acceptance: RTF remains above 1, and playable chunk streaming, same-session continuation, 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
|
||||
|
||||
Reference in new issue
Block a user