Profile pinned S25 and X Elite vocoders on Qualcomm hardware

This commit is contained in:
tzhouam committed 2026-09-24 14:55:50 +08:00
1 parent 4386562f9b
commit 02b6af44ec
24 files changed
+11308 -32

No files matched your search

@@ -0,0 +1,114 @@
#!/usr/bin/env python3
"""Bind a generated-code S25 waveform to its pinned TFLite target and CPU references."""
from __future__ import annotations
import argparse
import hashlib
import json
import math
from pathlib import Path
import numpy as np
def sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def waveform(path: Path, key: str) -> np.ndarray:
with np.load(path, allow_pickle=False) as data:
if data.files != [key]:
raise ValueError(f"{path}: expected only {key}")
value = np.asarray(data[key])
if value.shape != (1, 48000) or value.dtype != np.float32 or not np.isfinite(value).all():
raise ValueError(f"{path}: invalid 25-frame waveform {value.shape}/{value.dtype}")
return value
def compare(reference: np.ndarray, observed: np.ndarray) -> dict:
a = reference.astype(np.float64).ravel()
b = observed.astype(np.float64).ravel()
error = float(np.linalg.norm(a - b))
norm = float(np.linalg.norm(a))
return {
"relative_l2": error / norm,
"snr_db": 20 * math.log10(norm / error) if error else None,
"max_abs": float(np.max(np.abs(a - b))),
"reference_rms": float(np.sqrt(np.mean(a * a))),
"device_rms": float(np.sqrt(np.mean(b * b))),
"device_saturated_fraction_abs_ge_0_999": float(np.mean(np.abs(b) >= 0.999)),
}
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--evidence-dir", type=Path, required=True)
parser.add_argument("--pinned-compile", type=Path, required=True)
parser.add_argument("--pinned-export", type=Path, required=True)
args = parser.parse_args()
p = args.evidence_dir
local = json.loads((p / "report.json").read_text())
dataset = json.loads((p / "dataset_submission.json").read_text())
submitted = json.loads((p / "inference_submission.json").read_text())
inference = json.loads((p / "inference_report.json").read_text())
compiled = json.loads(args.pinned_compile.read_text())
exported = json.loads(args.pinned_export.read_text())
if (local["model_revision"] != exported["model_snapshot_revision"]
or local["decoder_weight_sha256"] != exported["model_weight_sha256"]
or local["onnx_sha256"] != exported["onnx_sha256"]):
raise ValueError("generated codes and compiled source are not from the pinned export")
if (local["files"]["fixture"]["sha256"] != dataset["fixture_sha256"]
or dataset["input_shape"] != [1, 512, 97]
or sha256(p / "fixture.npz") != dataset["fixture_sha256"]):
raise ValueError("device input differs from real generated-code fixture")
if (submitted["job_id"] != inference["job_id"]
or inference["status"] != "SUCCESS"
or inference["model_id"] != compiled["target_model_id"]
or inference["input_dataset_id"] != dataset["dataset_id"]
or inference["options"] != "--compute_unit gpu"
or inference["device"] != compiled["device"]
or inference["device"]["name"] != "Samsung Galaxy S25"):
raise ValueError("device result does not bind to pinned S25 GPU target")
for name in ("eager", "ort", "full_reference"):
entry = local["files"][name]
if sha256(p / entry["filename"]) != entry["sha256"]:
raise ValueError(f"local {name} reference changed")
cpu = waveform(p / "ort_output.npz", "wav")
eager = waveform(p / "eager_output.npz", "wav")
full = waveform(p / "full_reference_segment.npz", "wav")
hosted = waveform(p / "device_output.npz", "output_0__0")
comparison = compare(cpu, hosted)
gross_failure = (comparison["relative_l2"] >= 1.0
or comparison["device_saturated_fraction_abs_ge_0_999"] >= 0.1)
report = {
"scope": "one generated-code 25-frame vocoder window on hosted S25; no device-local talker or complete stream",
"status": "component_gross_numeric_failure" if gross_failure else "component_numeric_measured_no_speech_quality_gate",
"device": inference["device"],
"source_model_id": compiled["source_model_id"],
"target_model_id": compiled["target_model_id"],
"input_dataset_id": dataset["dataset_id"],
"jobs": {"compile": compiled["job_id"], "inference": inference["job_id"]},
"files": {name: {"sha256": sha256(p / filename), "bytes": (p / filename).stat().st_size}
for name, filename in {"fixture": "fixture.npz", "device": "device_output.npz",
"ort": "ort_output.npz", "eager": "eager_output.npz",
"full": "full_reference_segment.npz"}.items()},
"ort_cpu_vs_device": comparison,
"eager_cpu_vs_device": compare(eager, hosted),
"full_fp32_decoder_segment_vs_device": compare(full, hosted),
"gross_numeric_failure_screen": {
"failed": gross_failure,
"criteria": "relative L2 >= 1.0 or >=10% saturated samples; not a speech-quality tolerance",
},
"limits": [
"One generated-code window is not a speech listening or intelligibility test.",
"Talker, predictor, co-resident handoff, state, cancellation and memory admission did not run on S25.",
"The separate placement profile used Workbench-generated same-shape input, not this fixture.",
],
}
(p / "audit_report.json").write_text(json.dumps(report, indent=2) + "\n")
print(json.dumps({"status": report["status"], "ort_cpu_vs_device": comparison}, indent=2))
if __name__ == "__main__":
main()
@@ -0,0 +1,196 @@
#!/usr/bin/env python3
"""Capture one generated CustomVoice code stream and audit a 25-frame export.
Set PYTHONPATH to include the pinned qwen_tts source checkout when invoking.
The hosted device is not used here; this checks a real-code local window and
its truncation against the full FP32 decoder before a device quality attempt.
"""
from __future__ import annotations
import argparse
import hashlib
import inspect
import json
import math
import os
from pathlib import Path
import numpy as np
import onnxruntime as ort
import torch
from qwen_tts import Qwen3TTSModel
from qwen_tts.core.tokenizer_12hz.configuration_qwen3_tts_tokenizer_v2 import (
Qwen3TTSTokenizerV2Config,
)
from qwen_tts.core.tokenizer_12hz.modeling_qwen3_tts_tokenizer_v2 import (
Qwen3TTSTokenizerV2Decoder,
)
from safetensors.torch import load_file
def load_decoder(model: Path) -> Qwen3TTSTokenizerV2Decoder:
config = Qwen3TTSTokenizerV2Config.from_pretrained(str(model), subfolder="speech_tokenizer")
decoder = Qwen3TTSTokenizerV2Decoder._from_config(config.decoder_config)
state = load_file(str(model / "speech_tokenizer" / "model.safetensors"))
decoder_state = {key[len("decoder."):]: value for key, value in state.items()
if key.startswith("decoder.")}
missing, unexpected = decoder.load_state_dict(decoder_state, strict=False)
if missing or unexpected:
raise RuntimeError(f"decoder state mismatch: {len(missing)} missing, {len(unexpected)} unexpected")
decoder.eval().float()
if hasattr(decoder, "precompute_snake_caches"):
decoder.precompute_snake_caches()
return decoder
def decode_quantized(decoder: Qwen3TTSTokenizerV2Decoder, quantized: torch.Tensor) -> torch.Tensor:
hidden = decoder.pre_conv(quantized).transpose(1, 2)
hidden = decoder.pre_transformer(inputs_embeds=hidden).last_hidden_state
hidden = hidden.permute(0, 2, 1)
for blocks in decoder.upsample:
for block in blocks:
hidden = block(hidden)
for block in decoder.decoder:
hidden = block(hidden)
return hidden.clamp(-1, 1).reshape(1, -1)
def sha256(path: Path) -> str:
with path.open("rb") as stream:
return hashlib.file_digest(stream, "sha256").hexdigest()
def compare(reference: np.ndarray, observed: np.ndarray) -> dict:
a = reference.astype(np.float64).ravel()
b = observed.astype(np.float64).ravel()
error = float(np.linalg.norm(a - b))
norm = float(np.linalg.norm(a))
return {
"relative_l2": error / norm,
"snr_db": 20 * math.log10(norm / error) if error else None,
"max_abs": float(np.max(np.abs(a - b))),
"reference_rms": float(np.sqrt(np.mean(a * a))),
"observed_rms": float(np.sqrt(np.mean(b * b))),
}
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--model", required=True, type=Path)
parser.add_argument("--onnx", required=True, type=Path)
parser.add_argument("--output-dir", required=True, type=Path)
parser.add_argument("--text", default=(
"The small red square is centered on the white card. I can see its "
"straight edges clearly, and the surrounding background is bright "
"and uncluttered."
))
parser.add_argument("--max-new-tokens", type=int, default=144)
parser.add_argument("--threads", type=int, default=8)
args = parser.parse_args()
if args.max_new_tokens < 97 or args.threads <= 0:
parser.error("at least 97 max new tokens and positive threads required")
os.environ["HF_HUB_OFFLINE"] = "1"
os.environ["TRANSFORMERS_OFFLINE"] = "1"
torch.set_num_threads(args.threads)
wrapper = Qwen3TTSModel.from_pretrained(
str(args.model.resolve()), device_map="cpu", dtype=torch.bfloat16,
attn_implementation="sdpa", local_files_only=True,
)
captured: list[torch.Tensor] = []
original_decode = wrapper.model.speech_tokenizer.decode
def capture(items: list[dict], *extra: object, **kwargs: object):
captured.extend(item["audio_codes"].detach().cpu().clone() for item in items)
return original_decode(items, *extra, **kwargs)
wrapper.model.speech_tokenizer.decode = capture
torch.manual_seed(42)
wavs, sample_rate = wrapper.generate_custom_voice(
text=args.text, language="English", speaker="Ryan",
max_new_tokens=args.max_new_tokens, do_sample=True,
non_streaming_mode=True,
)
if len(captured) != 1 or len(wavs) != 1 or sample_rate != 24000:
raise RuntimeError("expected one generated code stream and 24 kHz waveform")
codes = captured[0]
if codes.ndim != 2 or codes.shape[0] < 97 or codes.shape[1] != 16:
raise RuntimeError(f"expected >=97 frames of 16-code speech, got {tuple(codes.shape)}")
generated = np.asarray(wavs[0], dtype=np.float32).ravel()
if len(generated) != codes.shape[0] * 1920 or not np.isfinite(generated).all():
raise RuntimeError("complete request has invalid audio length or samples")
del wrapper
decoder = load_decoder(args.model)
window_codes = codes[:97].T.unsqueeze(0).contiguous().long()
full_codes = codes.T.unsqueeze(0).contiguous().long()
with torch.inference_mode():
quantized = decoder.quantizer.decode(window_codes).detach().float().numpy()
eager = decode_quantized(decoder, torch.from_numpy(quantized))[:, -25 * 1920:].detach().numpy()
full = decoder(full_codes).reshape(1, -1).detach().numpy()
if quantized.shape != (1, 512, 97) or eager.shape != (1, 48000):
raise RuntimeError("real-code window violates fixed export shape")
full_segment = full[:, 72 * 1920 : 97 * 1920]
if full_segment.shape != eager.shape:
raise RuntimeError("full decoder output does not align with window")
options = ort.SessionOptions()
options.intra_op_num_threads = args.threads
session = ort.InferenceSession(str(args.onnx), sess_options=options,
providers=["CPUExecutionProvider"])
observed = np.asarray(session.run(["wav"], {"quantized": quantized})[0])
if observed.shape != eager.shape or not np.isfinite(observed).all():
raise RuntimeError("ONNX output violates waveform contract")
args.output_dir.mkdir(parents=True, exist_ok=True)
files = {
"codes": ("codes.npz", {"codes": codes.numpy()}),
"fixture": ("fixture.npz", {"quantized": quantized}),
"eager": ("eager_output.npz", {"wav": eager}),
"ort": ("ort_output.npz", {"wav": observed}),
"full_reference": ("full_reference_segment.npz", {"wav": full_segment}),
}
for name, (filename, arrays) in files.items():
np.savez_compressed(args.output_dir / filename, **arrays)
report = {
"scope": "one real generated-code 25-frame Code2Wav window on local CPU; no device execution",
"model_revision": args.model.resolve().name,
"model_weight_sha256": sha256(args.model / "model.safetensors"),
"decoder_weight_sha256": sha256(args.model / "speech_tokenizer" / "model.safetensors"),
"onnx_sha256": sha256(args.onnx),
"torch": torch.__version__,
"onnxruntime": ort.__version__,
"qwen_tts_sources": {
"wrapper": {"path": inspect.getfile(Qwen3TTSModel),
"sha256": sha256(Path(inspect.getfile(Qwen3TTSModel)))},
"decoder": {"path": inspect.getfile(Qwen3TTSTokenizerV2Decoder),
"sha256": sha256(Path(inspect.getfile(Qwen3TTSTokenizerV2Decoder)))},
},
"text": args.text,
"speaker": "Ryan",
"language": "English",
"seed": 42,
"generator_dtype": "bfloat16",
"decoder_dtype": "float32",
"threads": args.threads,
"generated_frames": int(codes.shape[0]),
"generated_audio_samples": len(generated),
"window": {"start_frame": 0, "history_frames": 72, "new_frames": 25},
"files": {name: {"filename": filename, "sha256": sha256(args.output_dir / filename)}
for name, (filename, _) in files.items()},
"ort_vs_window_eager": compare(eager, observed),
"window_eager_vs_full_fp32_decoder_segment": compare(full_segment, eager),
"limits": [
"One generated stream and one window do not establish speech quality.",
"The model generates codes on local CPU; this does not test a mobile talker or handoff.",
"The FP32 full decoder reference is separate from the BF16 generator's waveform.",
],
}
(args.output_dir / "report.json").write_text(json.dumps(report, indent=2) + "\n")
print(json.dumps({"frames": report["generated_frames"],
"ort_vs_eager": report["ort_vs_window_eager"],
"window_vs_full": report["window_eager_vs_full_fp32_decoder_segment"]}, indent=2))
if __name__ == "__main__":
main()
@@ -34,7 +34,14 @@ from that pinned snapshot matches local eager CPU at 1.99e-6 relative L2 and
has compiled to S25 TFLite. Its GPU-requested inference returned an
unsaturated waveform at 4.239% relative L2 versus local ONNX CPU, bitwise
identical to the historical GPU output on this fixture. Its own placement
profile remains pending; the historical timing is separate evidence.
profile measured 100 component samples at p50/p95 **0.671/1.454 s** for
2 s audio (median RTF **0.335**), with 403 CPU and 335 GPU rows. The
historical profile is a separate run, and neither establishes full streaming.
A [generated-code window](evidence/qwen_tts_vocoder_qualcomm/s25/real_code_window/README.md)
from one pinned CustomVoice utterance passed local FP32 window/full-decoder
continuity; the pinned S25 GPU-requested target returned an unsaturated
waveform at **1.153% relative L2 / 38.76 dB SNR** versus local ONNX CPU.
No listening-quality tolerance or complete device-local stream passed.
The same pinned [two-frame graph on Galaxy S24](evidence/qwen_tts_vocoder_qualcomm/s24/tflite_short_chunk/README.md)
matched local ONNX CPU at 5.75e-6 relative L2 when requested on CPU, while
@@ -45,8 +52,10 @@ A FP32-preserving GPU control returned the same saturated waveform bitwise.
A
[Snapdragon X Elite FP16 QNN short graph](evidence/qwen_tts_vocoder_qualcomm/xelite/qnn_short_chunk/README.md)
compiled and returned an unsaturated NPU-requested waveform at 0.930%
relative L2 versus local ONNX CPU on one fixture. Its placement profile
remains pending. These are component-only results.
relative L2 versus local ONNX CPU on one fixture. Its 100-sample profile
attributed all 728 rows to NPU, but p50/p95 was **3.662/3.676 s** for
0.16 s audio (median component RTF **22.89**). These are component-only
results and the short NPU vocoder is too slow for playable streaming.
The [Qwen3-TTS vocoder study](evidence/qwen_tts_vocoder_qualcomm/README.md) reuses a retained fixed-shape Code2Wav export and historical Workbench input to test numerical behavior on SA8775P and other Qualcomm settings. The fresh SA8775P GPU-requested inference produces a saturated waveform, while the same binary's CPU-requested output on the exact SA device matches ONNX CPU within 4.13e-6 relative L2. Its 100-sample CPU-requested component profile had p50/p95 5.384/5.534 s with all 738 execution-detail rows on CPU. A FP32-preserving GPU-option control still saturated 84.89% of samples, so that option did not repair the tested path. RB3 GPU-requested execution produces an unsaturated but 15.73%-divergent waveform; its fresh 100-sample mixed CPU/GPU component p50/p95 was 3.099/3.133 s, not a usable TTS timing claim. On the exact RB3 device, the same binary requested on CPU matched original ONNX CPU within 4.13e-6 relative L2 on the retained fixture; its 47-sample component profile measured p50/p95 12.727/13.424 s with all 738 execution-detail rows on CPU. This is a major streaming-latency blocker. A single-fixture-calibrated RB3 INT8 QNN vocoder returned a finite but 66.93%-relative-L2 divergent waveform (3.49 dB SNR) versus ONNX CPU; its 100-sample component profile was p50/p95 1.971/1.992 s with all 728 execution-detail rows on NPU; these timings describe numerically unqualified audio. X Elite ONNX CPU output matches the local ONNX Runtime reference on the retained fixture; its 94-sample component p50/p95 was 6.384/6.644 s with all execution-detail rows on CPU. Corrected X Elite DirectML inference and profile both failed during provider initialization; separate FP16 QNN DLC inference returned an unsaturated waveform at 1.138% relative L2 / 38.88 dB SNR against original ONNX CPU; its placement profile timed out during QNN graph preparation without samples. A separate SA8775P FP16 QNN vocoder compile passed, but same-fixture NPU-requested inference failed after compilation without a waveform or placement samples. Fresh S24 and S25 CPU-requested TFLite vocoder inferences matched ONNX CPU within 4.04e-6 relative L2 on the retained fixture. S25 measured 100 component samples at p50/p95 4.418/4.641 s with all 738 execution-detail rows on CPU; S24 measured 100 at 4.826/4.958 s with all 738 rows on CPU. Separate explicit INT8 and W8A16 QDQ ONNX exports checked on local ORT CPU failed the same-fixture numerical gate at 246.97% and 331.83% waveform relative L2, respectively. S25 CPU talker inference preserved token 80 and its 100-sample component profile measured p50/p95 30.161/31.301 ms with all 1,800 rows on CPU. No complete on-device TTS stream or model-quality qualification is claimed.
@@ -16,14 +16,23 @@ matched its eager decoder at 1.99e-6 relative L2 on the retained synthetic
fixture and compiled for S25 TFLite. Its GPU-requested inference returned a
finite unsaturated waveform at 4.239% relative L2 versus local ONNX CPU,
bitwise identical to the historical target's device output on the same fixture.
Its own placement profile is still running; the historical target's latency
is separate evidence.
Its own 100-sample placement profile measured p50/p95 **0.671/1.454 s** for
2 s audio (median component RTF **0.335**), with 403 CPU and 335 GPU rows.
This is a separate run from the historical target's 0.839/1.157 s profile;
neither is a complete-stream or listening-quality result.
A [generated-code window](s25/real_code_window/README.md) from one pinned
CustomVoice utterance matched local FP32 ONNX/eager and full-decoder segment
within 1.02e-6 and 7.26e-8 relative L2. The same S25 GPU-requested target
returned an unsaturated waveform at **1.153% relative L2 / 38.76 dB SNR**
versus ONNX CPU on that real-code window. This has no listening-quality or
full-pipeline gate.
The same pinned two-frame source [compiled for X Elite QNN](xelite/qnn_short_chunk/README.md)
and its NPU-requested inference returned an unsaturated waveform at 0.930%
relative L2 / 40.63 dB SNR versus local ONNX CPU. Its placement profile is
still running; this is component numerical evidence, not verified NPU node
placement or complete TTS.
relative L2 / 40.63 dB SNR versus local ONNX CPU. Its 100-sample placement
profile attributed all 728 rows to NPU, but p50/p95 was **3.662/3.676 s**
for only 0.16 s audio (median component RTF **22.89**). This is a measured
playable-stream blocker for that artifact, not complete TTS.
On [Galaxy S24](s24/tflite_short_chunk/README.md), the same pinned two-frame TFLite source matched local ONNX CPU at 5.75e-6 relative L2 when requested on CPU, but its GPU-requested output saturated every sample and differed by 24.218 relative L2. The 100-sample CPU component p50/p95 was 3.433/3.873 s for only 0.16 s audio (median RTF 21.46), with all 738 rows on CPU. The mixed CPU/GPU component measured 0.601/0.895 s with 403 CPU and 335 GPU rows, but that timing describes numerically failed audio. An [FP32-preserving delegate control](s24/tflite_short_chunk_gpu_fp32/audit_report.json) returned the same saturated waveform bitwise, so that option did not fix this artifact. Neither route is a complete S24 TTS stream.
@@ -20,6 +20,18 @@ The new device waveform is [bitwise identical](historical_device_parity_report.j
to the [historical 25-frame target's](../full_tflite_gpu_profile/README.md)
GPU output on this retained fixture. This supports numerical continuity on
one input, not identical historical export provenance or listening quality.
A separate [placement profile](profile_submission.json) is in progress; GPU
node placement and latency for this revision-pinned target remain unverified.
Complete-stream handoff and sustained behavior are also unverified.
A separate [placement profile](profile_report.json) returned 100 component
samples at nearest-rank p50/p95 **0.671/1.454 s** for 2 s audio, with 403 CPU
and 335 GPU execution-detail rows and 380,100,608 bytes reported peak memory.
The median component RTF is **0.335**. Workbench generated profile input of
the same shape, while the numerical inference used the retained fixture; the
[audit](audit_report.json) binds both jobs to the exact target. Complete-stream
handoff, listening quality and sustained behavior remain unverified.
A separate [real generated-code window](../real_code_window/README.md) passed
local ONNX/eager parity at 1.02e-6 relative L2 and matched the corresponding
full FP32 decode segment at 7.26e-8 relative L2. The same fixture has a
successful inference on this pinned S25 target: the unsaturated device
waveform differed from local ONNX CPU by 1.153% relative L2 / 38.76 dB SNR.
This one real-code window is encouraging component evidence, not a speech
quality tolerance or complete mobile stream.
@@ -1,6 +1,6 @@
{
"scope": "one 25-frame Qwen3-TTS vocoder component on hosted Samsung Galaxy S25; no complete stream",
"status": "component_inference_numeric_measured",
"status": "component_inference_numeric_and_placement_measured",
"device": {
"name": "Samsung Galaxy S25",
"os": "15",
@@ -25,7 +25,8 @@
"input_dataset_id": "d2nmpxd57",
"jobs": {
"compile": "jgddd1zzg",
"inference": "jglyymx25"
"inference": "jglyymx25",
"profile": "j568847ng"
},
"route": {
"compile_options": "--target_runtime tflite",
@@ -72,7 +73,18 @@
"limits": [
"One fixed-window waveform has no listening-quality tolerance.",
"The 72-frame input history, talker, predictor and stage handoff did not run on the device.",
"No persistent state, admission, cancellation or complete TTS stream was tested.",
"Requested accelerator execution is not verified node placement without a profile."
]
"No persistent state, admission, cancellation or complete TTS stream was tested."
],
"profile": {
"sample_count": 100,
"min_us": 560210,
"nearest_rank_p50_us": 670776,
"nearest_rank_p95_us": 1453828,
"reported_peak_memory_bytes": 380100608,
"compute_unit_row_counts": {
"CPU": 403,
"GPU": 335
},
"profile_input": "Workbench generated input with audited tensor shape; the waveform inference used the retained fixture"
}
}
@@ -0,0 +1,27 @@
# S25 pinned vocoder on generated speech codes
The [reproducer](../../../../../../experiments/probe_qwen_tts_real_code_window.py)
ran the pinned Qwen3-TTS 0.6B CustomVoice checkpoint at revision
`85e237c12c027371202489a0ec509ded67b5e4b5` on HX370 WSL CPU. One
seed-42 Ryan utterance yielded 117 frames of 16 codebook indices and a
224,640-sample waveform. It decoded frames 0–96 as 72 history plus 25 new
frames through the FP32 decoder and the revision-pinned ONNX export.
The [local report](report.json) shows ONNX Runtime CPU versus the exact
25-frame eager window at **1.02e-6 relative L2**. The eager window versus
the same segment from an FP32 full 117-frame decode differed by **7.26e-8
relative L2**. The [code tensor](codes.npz), [quantized fixture](fixture.npz),
[eager](eager_output.npz), [ONNX CPU](ort_output.npz) and
[full-decoder segment](full_reference_segment.npz) are retained. This checks
the window boundary on one real generated-code stream; it is not a speech
quality or mobile pipeline pass.
The quantized fixture was uploaded as [Workbench dataset](dataset_submission.json)
and [GPU-requested inference](inference_report.json) succeeded against the
exact pinned S25 TFLite target. The [device waveform](device_output.npz) was
finite and unsaturated; the [audit](audit_report.json) measures **1.153%
relative L2 / 38.76 dB SNR** versus local ONNX CPU on this generated-code
window. The separate 100-sample component profile used Workbench-generated
input of the same shape and does not measure this specific fixture. One
generated window does not establish speech intelligibility, all utterances,
or device-local talker/predictor/vocoder integration.
@@ -0,0 +1,85 @@
{
"scope": "one generated-code 25-frame vocoder window on hosted S25; no device-local talker or complete stream",
"status": "component_numeric_measured_no_speech_quality_gate",
"device": {
"name": "Samsung Galaxy S25",
"os": "15",
"attributes": [
"os:android",
"framework:tflite",
"framework:onnx",
"abi:aarch64-android",
"vendor:samsung",
"format:phone",
"chipset:qualcomm-snapdragon-8-elite-for-galaxy",
"chipset:sm8750-ac",
"hexagon:v79",
"soc-model:69",
"htp-supports-fp16:true",
"htp-supports-weight-sharing:true",
"framework:qnn"
]
},
"source_model_id": "mng2vkdrm",
"target_model_id": "mn4o5j17q",
"input_dataset_id": "d2q4y5jl7",
"jobs": {
"compile": "jgddd1zzg",
"inference": "j5688yryg"
},
"files": {
"fixture": {
"sha256": "4220eec4ee00e5fbb0df6f195d883c6d4549accf399853c3a8e2f83821724452",
"bytes": 185626
},
"device": {
"sha256": "7ecafcc289f098aa497f9c9eaa1da0e19879386157e8d2af7c1842e5ea1bfe46",
"bytes": 112200
},
"ort": {
"sha256": "df4ad896c62a0d621c9bc48120f929d3561666359a570068b01a3228354411a0",
"bytes": 179186
},
"eager": {
"sha256": "8c0c55197daa99433e8a7594525748b4e50e0570ef983dc5b76eedb56936d6d4",
"bytes": 179198
},
"full": {
"sha256": "3571033b52c4715761b469e17915d7b1456f5c251322c8a718fad8f905d428e9",
"bytes": 179207
}
},
"ort_cpu_vs_device": {
"relative_l2": 0.011533186351546298,
"snr_db": 38.76101381296397,
"max_abs": 0.011052757501602173,
"reference_rms": 0.074840782807901,
"device_rms": 0.07483006310024524,
"device_saturated_fraction_abs_ge_0_999": 0.0
},
"eager_cpu_vs_device": {
"relative_l2": 0.011533295679175895,
"snr_db": 38.760931476374985,
"max_abs": 0.011053577065467834,
"reference_rms": 0.0748407755479042,
"device_rms": 0.07483006310024524,
"device_saturated_fraction_abs_ge_0_999": 0.0
},
"full_fp32_decoder_segment_vs_device": {
"relative_l2": 0.011533293686009369,
"snr_db": 38.76093297745728,
"max_abs": 0.011053577065467834,
"reference_rms": 0.07484077531515666,
"device_rms": 0.07483006310024524,
"device_saturated_fraction_abs_ge_0_999": 0.0
},
"gross_numeric_failure_screen": {
"failed": false,
"criteria": "relative L2 >= 1.0 or >=10% saturated samples; not a speech-quality tolerance"
},
"limits": [
"One generated-code window is not a speech listening or intelligibility test.",
"Talker, predictor, co-resident handoff, state, cancellation and memory admission did not run on S25.",
"The separate placement profile used Workbench-generated same-shape input, not this fixture."
]
}
@@ -0,0 +1,14 @@
{
"timestamp_utc": "2026-09-24T06:46:09.898281+00:00",
"facility": "Qualcomm AI Hub Workbench",
"qai_hub_version": "0.55.0",
"fixture_sha256": "4220eec4ee00e5fbb0df6f195d883c6d4549accf399853c3a8e2f83821724452",
"dataset_id": "d2q4y5jl7",
"input_shape": [
1,
512,
97
],
"sample_count": 1,
"status": "UPLOADED"
}
@@ -0,0 +1,33 @@
{
"timestamp_utc": "2026-09-24T06:53:00.381461+00:00",
"qai_hub_version": "0.55.0",
"facility": "Qualcomm AI Hub Workbench",
"job_id": "j5688yryg",
"url": "https://workbench.aihub.qualcomm.com/jobs/j5688yryg/",
"status": "SUCCESS",
"status_message": "",
"options": "--compute_unit gpu",
"hub_version": "aihub-2026.09.11.0",
"device": {
"name": "Samsung Galaxy S25",
"os": "15",
"attributes": [
"os:android",
"framework:tflite",
"framework:onnx",
"abi:aarch64-android",
"vendor:samsung",
"format:phone",
"chipset:qualcomm-snapdragon-8-elite-for-galaxy",
"chipset:sm8750-ac",
"hexagon:v79",
"soc-model:69",
"htp-supports-fp16:true",
"htp-supports-weight-sharing:true",
"framework:qnn"
]
},
"model_id": "mn4o5j17q",
"input_dataset_id": "d2q4y5jl7",
"outputs": "device_output.npz"
}
@@ -0,0 +1,12 @@
{
"timestamp_utc": "2026-09-24T06:46:12.071383+00:00",
"facility": "Qualcomm AI Hub Workbench",
"qai_hub_version": "0.55.0",
"job_id": "j5688yryg",
"url": "https://workbench.aihub.qualcomm.com/jobs/j5688yryg/",
"model_id": "mn4o5j17q",
"input_dataset_id": "d2q4y5jl7",
"options": "--compute_unit gpu",
"device": "Samsung Galaxy S25",
"status": "SUBMITTED"
}
@@ -0,0 +1,74 @@
{
"scope": "one real generated-code 25-frame Code2Wav window on local CPU; no device execution",
"model_revision": "85e237c12c027371202489a0ec509ded67b5e4b5",
"model_weight_sha256": "bc3c7e785eb961179c25450d1acff03f839e0002f2f3a5aeb67b5735c0fa2adb",
"decoder_weight_sha256": "836b7b357f5ea43e889936a3709af68dfe3751881acefe4ecf0dbd30ba571258",
"onnx_sha256": "01ee1cd02e5cd264200e5c50767a1805a6180378b051ff9b7ec0d8b6c75d7989",
"torch": "2.13.0+cpu",
"onnxruntime": "1.29.0",
"text": "The small red square is centered on the white card. I can see its straight edges clearly, and the surrounding background is bright and uncluttered.",
"speaker": "Ryan",
"language": "English",
"seed": 42,
"generator_dtype": "bfloat16",
"decoder_dtype": "float32",
"threads": 8,
"generated_frames": 117,
"generated_audio_samples": 224640,
"window": {
"start_frame": 0,
"history_frames": 72,
"new_frames": 25
},
"files": {
"codes": {
"filename": "codes.npz",
"sha256": "2768b9274748d767deca67ebd4c0201b914f4839902b89d5693d39e9b8e8c946"
},
"fixture": {
"filename": "fixture.npz",
"sha256": "4220eec4ee00e5fbb0df6f195d883c6d4549accf399853c3a8e2f83821724452"
},
"eager": {
"filename": "eager_output.npz",
"sha256": "8c0c55197daa99433e8a7594525748b4e50e0570ef983dc5b76eedb56936d6d4"
},
"ort": {
"filename": "ort_output.npz",
"sha256": "df4ad896c62a0d621c9bc48120f929d3561666359a570068b01a3228354411a0"
},
"full_reference": {
"filename": "full_reference_segment.npz",
"sha256": "3571033b52c4715761b469e17915d7b1456f5c251322c8a718fad8f905d428e9"
}
},
"ort_vs_window_eager": {
"relative_l2": 1.01682301490854e-06,
"snr_db": 119.85509264926462,
"max_abs": 1.1324882507324219e-06,
"reference_rms": 0.0748407755479042,
"observed_rms": 0.074840782807901
},
"window_eager_vs_full_fp32_decoder_segment": {
"relative_l2": 7.264658178733583e-08,
"snr_db": 142.7756963116475,
"max_abs": 1.695007085800171e-07,
"reference_rms": 0.07484077531515666,
"observed_rms": 0.0748407755479042
},
"limits": [
"One generated stream and one window do not establish speech quality.",
"The model generates codes on local CPU; this does not test a mobile talker or handoff.",
"The FP32 full decoder reference is separate from the BF16 generator's waveform."
],
"qwen_tts_sources": {
"wrapper": {
"path": "/home/zhout/project/edge_infer/scratch/qwentts_wsl_pins/qwen_tts/inference/qwen3_tts_model.py",
"sha256": "e1da450732857c1f5fe3e36ebab85db2f6dc6a48caaff6973f463384e30275e4"
},
"decoder": {
"path": "/home/zhout/project/edge_infer/scratch/qwentts_wsl_pins/qwen_tts/core/tokenizer_12hz/modeling_qwen3_tts_tokenizer_v2.py",
"sha256": "844e8dd8c0182ef9c6463c874631c22ef3c5a4fd1899dd657016164cc5379628"
}
}
}
@@ -6,9 +6,14 @@ compiled to [FP16 QNN DLC](compile_report.json) for Snapdragon X Elite CRD.
fixture. The [audit](audit_report.json) measures **0.930% relative L2** and
**40.63 dB SNR** against local ONNX Runtime CPU, with no saturated samples.
This is one synthetic, two-frame waveform without a listening-quality gate.
A separate [placement profile](profile_submission.json) remains in progress
for the same target and tensor shape; the request alone does not verify NPU
node placement or latency. The earlier
A separate [placement profile](profile_report.json) returned 100 component
samples at nearest-rank p50/p95 **3.662/3.676 s** for **0.16 s** audio,
with all 728 execution-detail rows on NPU and 15,855,616 bytes reported
inference peak. Its median component RTF is **22.89**. The profile used
Workbench-generated same-shape input, while the waveform inference used the
retained fixture; the [audit](audit_report.json) binds both jobs to the exact
target. This measured latency is a playable-stream blocker for this artifact.
The earlier
[25-frame X Elite NPU attempt](../qnn_npu/inference_report.json) returned a
waveform but its placement profile timed out during graph preparation; this
shorter artifact tests a separate memory/graph-preparation boundary. Neither
@@ -1,6 +1,6 @@
{
"scope": "one 2-frame Qwen3-TTS vocoder component on hosted Snapdragon X Elite CRD; no complete stream",
"status": "component_inference_numeric_measured",
"status": "component_inference_numeric_and_placement_measured",
"device": {
"name": "Snapdragon X Elite CRD",
"os": "11",
@@ -24,7 +24,8 @@
"input_dataset_id": "d7ovqp0w2",
"jobs": {
"compile": "j5m0m22qg",
"inference": "jgdd3lxeg"
"inference": "jgdd3lxeg",
"profile": "jp4yyrrvp"
},
"route": {
"compile_options": "--target_runtime qnn_dlc --qnn_options default_graph_htp_precision=FLOAT16",
@@ -71,7 +72,17 @@
"limits": [
"One fixed-window waveform has no listening-quality tolerance.",
"The 72-frame input history, talker, predictor and stage handoff did not run on the device.",
"No persistent state, admission, cancellation or complete TTS stream was tested.",
"Requested accelerator execution is not verified node placement without a profile."
]
"No persistent state, admission, cancellation or complete TTS stream was tested."
],
"profile": {
"sample_count": 100,
"min_us": 3646540,
"nearest_rank_p50_us": 3661691,
"nearest_rank_p95_us": 3676170,
"reported_peak_memory_bytes": 15855616,
"compute_unit_row_counts": {
"NPU": 728
},
"profile_input": "Workbench generated input with audited tensor shape; the waveform inference used the retained fixture"
}
}
@@ -49,8 +49,8 @@ NOT E2E means no complete device/model workload was verified. “Scoped E2E” i
| PC HX370 + Radeon 890M / Windows worker | scoped E2E: Omni Spark text | 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 + 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 waveform measured, placement pending) | NOT E2E | NOT E2E (NPU speech-head step profiled) | NOT E2E (Cosmos NPU encoder profiled) |
| Mobile Galaxy S25 / Snapdragon 8 Elite for Galaxy | NOT E2E (one Spark attention layer on NPU) | NOT E2E (FP16 talker token mismatch; CPU talker + vocoder profiled; 25-frame and two-frame QNN vocoder memory failures; historical 25-frame TFLite mixed vocoder component RTF 0.420; pinned 25-frame GPU waveform measured, placement pending; short chunk RTF 3.49) | NOT E2E | NOT E2E (NPU speech head step profiled) | NOT E2E (Cosmos NPU encoder profiled) |
| 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) |
| Mobile Galaxy S25 / Snapdragon 8 Elite for Galaxy | NOT E2E (one Spark attention layer on NPU) | NOT E2E (FP16 talker token mismatch; CPU talker + vocoder profiled; 25-frame and two-frame QNN vocoder memory failures; historical 25-frame TFLite mixed vocoder component RTF 0.420; pinned 25-frame mixed CPU/GPU vocoder profiled at RTF 0.335; generated-code waveform measured; short chunk RTF 3.49) | NOT E2E | NOT E2E (NPU speech head step profiled) | NOT E2E (Cosmos NPU encoder profiled) |
| Mobile Galaxy S24 / Snapdragon 8 Gen 3 | NOT E2E (one Spark attention layer on NPU) | NOT E2E (FP16 talker mismatch; short CPU vocoder RTF 21.46; mixed CPU/GPU waveform saturated) | NOT E2E | NOT E2E (NPU speech head step profiled) | NOT E2E (Cosmos encoder numeric and NPU profiled) |
| Embedded SA8775P ADP / AI Hub | NOT E2E (one Spark attention layer on NPU) | NOT E2E (CPU talker/vocoder steps; NPU vocoder failed) | NOT E2E | NOT E2E (NPU speech-head step profiled) | NOT E2E (Cosmos NPU encoder profiled) |
| Embedded RB3 Gen 2 / QCS6490 / AI Hub | NOT E2E (Spark CPU layer passed; W8A8 NPU quality open) | NOT E2E (CPU talker + vocoder profiled; INT8 NPU vocoder fails numeric gate) | NOT E2E | NOT E2E (CPU speech-head step profiled) | NOT E2E (Cosmos CPU numeric and profiled) |
@@ -95,12 +95,12 @@ NOT E2E means no complete device/model workload was verified. “Scoped E2E” i
| PC CPU+iGPU+NPU +/- discrete GPU, joint model execution | MiniCPM-o 4.5 | NOT_E2E_PROFILEABLE | No qualifying same-model multi-accelerator deployment/artifact plan or overlap/recovery evidence. Individual routes are not a joint pipeline. | Supply and validate the missing matching artifact/backend, then run the complete specified workload. |
| PC CPU+iGPU+NPU +/- discrete GPU, joint model execution | InternVLA-A1 | NOT_E2E_PROFILEABLE | No qualifying same-model multi-accelerator deployment/artifact plan or overlap/recovery evidence. Individual routes are not a joint pipeline. | Supply and validate the missing matching artifact/backend, then run the complete specified workload. |
| PC Snapdragon X Elite CRD / AI Hub | Spark-X2.5 | COMPONENT_NPU_INFERENCE_PROFILED; NOT_E2E_PROFILEABLE | A real Spark-X2.5-1.7B one-layer W8A16 QDQ attention artifact, compiled as QNN DLC, ran on the exact hosted Snapdragon X Elite CRD (Windows 11 ARM64). Inference returned finite hidden/new-K/new-V tensors bitwise identical to the prior S24/S25 NPU outputs on the same fixture; the profile attributed all 73 execution-detail rows to NPU. Across 100 component samples, nearest-rank p50/p95 was 1.433/1.606 ms; the 1.346 ms estimated-time field is the minimum. Hidden/K/V relative L2 versus original FP32 ONNX CPU was 1.351%/0.377%/0.650%, without a next-token quality tolerance. There is no complete 28-layer prefill/decode/KV-ring/sampling loop, resident Omni controller or complete-request timing. | Qualify a complete X Elite resident artifact/controller with state, token quality, memory admission/cancel and sustained power; [X Elite NPU raw evidence](../../../e2e_expansion_20260923/evidence/spark_xelite_full_attention/README.md). |
| PC Snapdragon X Elite CRD / AI Hub | Qwen3-TTS 0.6B CustomVoice | COMPONENT_ONNX_CPU_VOCODER_PARITY_PROFILED; DIRECTML_RUNTIME_FAILED; TALKER_FP16_NUMERIC_FAIL; QNN_NPU_VOCODER_NUMERIC_MEASURED_PROFILE_TIMEOUT; SHORT_QNN_VOCODER_NUMERIC_MEASURED_PLACEMENT_PENDING; TALKER_ONNX_CPU_NUMERIC_PROFILED; NOT_E2E_PROFILEABLE | The fresh ONNX vocoder inference on the exact Windows 11 ARM64 X Elite CRD requested CPU and returned an unsaturated waveform on the pinned fixture, matching local ONNX Runtime CPU with 8.09e-7 relative L2 and 121.84 dB SNR. Its 94-sample component profile had nearest-rank p50/p95 6.384/6.644 s and all 634 execution-detail rows on CPU; 5.917 s estimated time is the sample minimum. This is one component, without a listening-quality gate. Corrected DirectML inference and profile both failed at provider initialization with Windows error 80070057. A separate FP16 QNN DLC vocoder inference returned an unsaturated waveform at 1.138% relative L2 / 38.88 dB SNR versus local ONNX CPU on the same fixture; the NPU node-placement profile timed out during graph preparation with no timing or per-node samples, and no listening-quality tolerance is set. A new [two-frame QNN vocoder candidate](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/xelite/qnn_short_chunk/README.md) compiled for X Elite and returned an unsaturated waveform at 0.930% relative L2 / 40.63 dB SNR versus pinned local ONNX CPU on one synthetic fixture. Its NPU-requested placement profile remains in progress; inference request alone does not verify NPU nodes or latency. The 28-layer FP16 QNN talker step executed, yet changed CPU top-1 token 80 to 1720 with 8.57% logits relative L2 on a synthetic cache fixture; a separate ONNX CPU-requested talker step preserved CPU token 80 with logits relative L2 2.07e-5 and maximum K/V relative L2 2.18e-5. Its 100-sample component profile had p50/p95 191.414/309.428 ms and all 1,744 execution-detail rows on CPU. The older TFLite vocoder target was rejected on Windows ARM; no complete stream exists. | Complete the short QNN vocoder placement profile and audit CPU talker placement; investigate DirectML failure, then qualify complete local streaming, memory and sustained behavior; [vocoder](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/README.md) and [talker](../../../e2e_expansion_20260924/evidence/qwen_tts_talker_qualcomm/README.md) evidence. |
| PC Snapdragon X Elite CRD / AI Hub | Qwen3-TTS 0.6B CustomVoice | COMPONENT_ONNX_CPU_VOCODER_PARITY_PROFILED; DIRECTML_RUNTIME_FAILED; TALKER_FP16_NUMERIC_FAIL; QNN_NPU_VOCODER_NUMERIC_MEASURED_PROFILE_TIMEOUT; SHORT_QNN_NPU_VOCODER_NUMERIC_PROFILED_SLOW; TALKER_ONNX_CPU_NUMERIC_PROFILED; NOT_E2E_PROFILEABLE | The fresh ONNX vocoder inference on the exact Windows 11 ARM64 X Elite CRD requested CPU and returned an unsaturated waveform on the pinned fixture, matching local ONNX Runtime CPU with 8.09e-7 relative L2 and 121.84 dB SNR. Its 94-sample component profile had nearest-rank p50/p95 6.384/6.644 s and all 634 execution-detail rows on CPU; 5.917 s estimated time is the sample minimum. This is one component, without a listening-quality gate. Corrected DirectML inference and profile both failed at provider initialization with Windows error 80070057. A separate FP16 QNN DLC vocoder inference returned an unsaturated waveform at 1.138% relative L2 / 38.88 dB SNR versus local ONNX CPU on the same fixture; the NPU node-placement profile timed out during graph preparation with no timing or per-node samples, and no listening-quality tolerance is set. A new [two-frame QNN vocoder candidate](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/xelite/qnn_short_chunk/README.md) compiled for X Elite and returned an unsaturated waveform at 0.930% relative L2 / 40.63 dB SNR versus pinned local ONNX CPU on one synthetic fixture. Its 100-sample placement profile measured nearest-rank p50/p95 3.662/3.676 s for 0.16 s audio, all 728 execution rows on NPU, 15,855,616 bytes reported peak and median component RTF 22.89. The profile used Workbench-generated same-shape input; the waveform used the retained fixture. This is too slow for playable streaming on the tested artifact. The 28-layer FP16 QNN talker step executed, yet changed CPU top-1 token 80 to 1720 with 8.57% logits relative L2 on a synthetic cache fixture; a separate ONNX CPU-requested talker step preserved CPU token 80 with logits relative L2 2.07e-5 and maximum K/V relative L2 2.18e-5. Its 100-sample component profile had p50/p95 191.414/309.428 ms and all 1,744 execution-detail rows on CPU. The older TFLite vocoder target was rejected on Windows ARM; no complete stream exists. | Find a quality-passing, much faster vocoder path and audit CPU talker placement; investigate DirectML failure, then qualify complete local streaming, memory and sustained behavior; [vocoder](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/README.md) and [talker](../../../e2e_expansion_20260924/evidence/qwen_tts_talker_qualcomm/README.md) evidence. |
| PC Snapdragon X Elite CRD / AI Hub | Qwen3.8-27B | NOT_E2E_PROFILEABLE | No complete qualified target artifact and device-local stateful Omni backend. Hub jobs provide component execution, not an on-device generation/streaming controller; ADB has no attached device. | Supply and validate the missing matching artifact/backend, then run the complete specified workload. |
| PC Snapdragon X Elite CRD / AI Hub | MiniCPM-o 4.5 | COMPONENT_SPEECH_HEAD_NPU_NUMERIC_PROFILED; NOT_E2E_PROFILEABLE | The real 20-layer MiniCPM-o speech-head FP16 QNN DLC ran on the exact X Elite CRD. Same-fixture inference returned 41 finite tensors, preserved ONNX CPU top-1 speech token 1867, and had 0.3170% logits relative L2 and 1.221% maximum K/V relative L2. Its 100-sample component profile had nearest-rank p50/p95 9.905/11.037 ms, with all 944 execution-detail rows on NPU. Reported inference peak memory was 79,208,448 bytes and first-load peak 1,081,573,376 bytes. Thinker/encoders/vocoder and a device-local stateful Omni backend remain unqualified. | Validate the complete multimodal pipeline, state, quality, co-resident memory and sustained behavior; [X Elite raw evidence](../../../e2e_expansion_20260924/evidence/minicpmo_tts_qualcomm/README.md). |
| PC Snapdragon X Elite CRD / AI Hub | InternVLA-A1 | COMPONENT_COSMOS_NPU_NUMERIC_PROFILED; NOT_E2E_PROFILEABLE | The real Place_Markpen Cosmos FP16 QNN image encoder returned a finite FP32 latent for the six-frame synthetic pattern on exact X Elite CRD. Against the pinned source, relative L2 was 0.0608%, SNR 64.32 dB and cosine 0.999999815. The 100-sample six-frame encoder profile had p50/p95 82.939/83.837 ms, with all 121 execution-detail rows on NPU. Reported component inference peak memory was 24,059,904 bytes and first-load peak 692,891,648 bytes. No real-observation action tolerance, complete policy or local stateful Omni backend exists. | Validate real observations, action units/timing, state, admission, cancellation and sustained behavior; [X Elite Cosmos raw evidence](../../../e2e_expansion_20260924/evidence/internvla_cosmos_qualcomm/README.md). |
| Mobile Galaxy S25 / Snapdragon 8 Elite for Galaxy | Spark-X2.5 | COMPONENT_NPU_INFERENCE_PROFILED; NOT_E2E_PROFILEABLE | The real 1.7B checkpoint one-layer W8A16 full-attention decoder artifact executed for a fixed 1,024-token cache bucket. Same-fixture outputs matched S24; the hosted S25 profile had 100 component samples at nearest-rank p50/p95 0.957/1.028 ms with all 73 execution-detail rows on NPU. FP32-source hidden-state relative L2 was 1.351% without a downstream token-quality gate. No full 28-layer prefill/decode, KV/ring, sampling or resident controller ran on S25. | Implement and validate local 128-token generation, 512/1024 transitions, cancellation, resident memory and sustained power; [S25/S24 component evidence](../../../e2e_expansion_20260923/evidence/spark_s24_full_attention/README.md). |
| Mobile Galaxy S25 / Snapdragon 8 Elite for Galaxy | Qwen3-TTS 0.6B CustomVoice | TALKER_FP16_NUMERIC_FAIL; CPU_TALKER_AND_VOCODER_NUMERIC_PROFILED; QNN_VOCODER_MEMORY_FAIL; FULL_TFLITE_MIXED_COMPONENT_PROFILED; PINNED_FULL_TFLITE_GPU_NUMERIC_MEASURED_PLACEMENT_PENDING; SHORT_TFLITE_MIXED_COMPONENT_PROFILED; NOT_E2E_PROFILEABLE | Fresh FP16 predictor inference passed; its one output exactly matches the same compiled artifact/dataset reference. The same historical S25 TFLite vocoder target requested on CPU returned a finite unsaturated waveform at 4.04e-6 relative L2 / 107.86 dB SNR versus original ONNX CPU on the retained fixture. Its 100-sample component profile measured nearest-rank p50/p95 4.418/4.641 s, with all 738 execution-detail rows on CPU and reported inference peak memory 867,893,248 bytes. A separate 28-layer TFLite CPU-requested talker step returned 57 finite outputs, preserved ONNX CPU top-1 speech token 80, and had logits relative L2 3.33e-5 and maximum new-cache relative L2 3.41e-5. Its 100-sample component profile measured p50/p95 30.161/31.301 ms, with all 1,800 execution-detail rows on CPU and reported inference peak memory 1,929,318,400 bytes. The FP16 QNN talker step executed on the synthetic cache fixture but changed CPU top-1 speech token 80 to 412 with 8.99% logits relative L2 and maximum new-K/V relative L2 11.71%. A separately compiled FP16 QNN DLC talker also changed top-1 to 1720 with 8.77% logits relative L2 and 11.27% maximum new-cache relative L2. Both tested NPU talker artifacts are numerically unqualified. A fresh 25-frame FP16 QNN DLC vocoder compiled for S25, but its NPU-requested inference failed when Workbench reported device memory limits; it returned no waveform or profile samples. A [two-frame short-window export](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/qnn_short_chunk/README.md) matched local ONNX CPU at 2.96e-6 relative L2, then its separately compiled S25 FP16 QNN DLC also failed NPU-requested inference with the same reported device-memory limit. Its local HX370 WSL CPU component p50/p95 was 1.365/1.453 s to produce 0.16 s audio, not an S25 estimate. A separate [two-frame TFLite GPU-requested inference](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/tflite_short_chunk/README.md) returned finite unsaturated audio at 2.325% relative L2 / 32.67 dB SNR versus local ONNX CPU on one fixture; its 100-sample placement profile measured p50/p95 0.559/1.052 s for 0.16 s audio, with 403 CPU and 335 GPU execution-detail rows and 379,121,664 bytes reported peak. The mixed CPU/GPU short component median RTF is 3.49. A separate [25-frame TFLite GPU-requested profile](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/full_tflite_gpu_profile/README.md) of the historical target measured 100 component samples at p50/p95 0.839/1.157 s for 2 s audio, with 403 CPU and 335 GPU rows, reported 374,591,488-byte peak and median component RTF 0.420. Its retained GPU waveform differed from ONNX CPU by 4.24% relative L2 on one fixture. A pinned CustomVoice eager 25-frame decoder matched the historical ONNX CPU waveform at 1.89e-6 relative L2 on that fixture, but the historical export revision and listening quality remain unverified. A fresh [revision-pinned 25-frame TFLite export](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/full_pinned_tflite/README.md) matched local eager CPU at 1.99e-6 relative L2 and compiled for S25. Its GPU-requested inference returned an unsaturated waveform at 4.239% relative L2 / 27.46 dB SNR versus pinned local ONNX CPU, bitwise identical to the historical GPU output on this one fixture. Its own placement profile remains pending; the historical target's timing does not transfer automatically. No complete co-resident NPU/GPU stream exists. | Improve and revalidate the [talker artifact](../../../e2e_expansion_20260924/evidence/qwen_tts_talker_qualcomm/README.md), then qualify the [device-local predictor/vocoder pipeline](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/README.md), output quality, recovery and 30-minute thermal behavior. |
| Mobile Galaxy S25 / Snapdragon 8 Elite for Galaxy | Qwen3-TTS 0.6B CustomVoice | TALKER_FP16_NUMERIC_FAIL; CPU_TALKER_AND_VOCODER_NUMERIC_PROFILED; QNN_VOCODER_MEMORY_FAIL; FULL_TFLITE_MIXED_COMPONENT_PROFILED; PINNED_FULL_TFLITE_MIXED_COMPONENT_PROFILED; SHORT_TFLITE_MIXED_COMPONENT_PROFILED; NOT_E2E_PROFILEABLE | Fresh FP16 predictor inference passed; its one output exactly matches the same compiled artifact/dataset reference. The same historical S25 TFLite vocoder target requested on CPU returned a finite unsaturated waveform at 4.04e-6 relative L2 / 107.86 dB SNR versus original ONNX CPU on the retained fixture. Its 100-sample component profile measured nearest-rank p50/p95 4.418/4.641 s, with all 738 execution-detail rows on CPU and reported inference peak memory 867,893,248 bytes. A separate 28-layer TFLite CPU-requested talker step returned 57 finite outputs, preserved ONNX CPU top-1 speech token 80, and had logits relative L2 3.33e-5 and maximum new-cache relative L2 3.41e-5. Its 100-sample component profile measured p50/p95 30.161/31.301 ms, with all 1,800 execution-detail rows on CPU and reported inference peak memory 1,929,318,400 bytes. The FP16 QNN talker step executed on the synthetic cache fixture but changed CPU top-1 speech token 80 to 412 with 8.99% logits relative L2 and maximum new-K/V relative L2 11.71%. A separately compiled FP16 QNN DLC talker also changed top-1 to 1720 with 8.77% logits relative L2 and 11.27% maximum new-cache relative L2. Both tested NPU talker artifacts are numerically unqualified. A fresh 25-frame FP16 QNN DLC vocoder compiled for S25, but its NPU-requested inference failed when Workbench reported device memory limits; it returned no waveform or profile samples. A [two-frame short-window export](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/qnn_short_chunk/README.md) matched local ONNX CPU at 2.96e-6 relative L2, then its separately compiled S25 FP16 QNN DLC also failed NPU-requested inference with the same reported device-memory limit. Its local HX370 WSL CPU component p50/p95 was 1.365/1.453 s to produce 0.16 s audio, not an S25 estimate. A separate [two-frame TFLite GPU-requested inference](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/tflite_short_chunk/README.md) returned finite unsaturated audio at 2.325% relative L2 / 32.67 dB SNR versus local ONNX CPU on one fixture; its 100-sample placement profile measured p50/p95 0.559/1.052 s for 0.16 s audio, with 403 CPU and 335 GPU execution-detail rows and 379,121,664 bytes reported peak. The mixed CPU/GPU short component median RTF is 3.49. A separate [25-frame TFLite GPU-requested profile](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/full_tflite_gpu_profile/README.md) of the historical target measured 100 component samples at p50/p95 0.839/1.157 s for 2 s audio, with 403 CPU and 335 GPU rows, reported 374,591,488-byte peak and median component RTF 0.420. Its retained GPU waveform differed from ONNX CPU by 4.24% relative L2 on one fixture. A pinned CustomVoice eager 25-frame decoder matched the historical ONNX CPU waveform at 1.89e-6 relative L2 on that fixture, but the historical export revision and listening quality remain unverified. A fresh [revision-pinned 25-frame TFLite export](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/full_pinned_tflite/README.md) matched local eager CPU at 1.99e-6 relative L2 and compiled for S25. Its GPU-requested inference returned an unsaturated waveform at 4.239% relative L2 / 27.46 dB SNR versus pinned local ONNX CPU, bitwise identical to the historical GPU output on this one fixture. Its own 100-sample placement profile measured nearest-rank p50/p95 0.671/1.454 s for 2 s audio, median component RTF 0.335, with 403 CPU and 335 GPU execution rows and 380,100,608 bytes reported peak memory. The profile used Workbench-generated same-shape input; the numerical inference used the retained fixture. The historical 0.839/1.157 s profile is a separate run. A [real generated-code 25-frame window](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/real_code_window/README.md) passed local ONNX/eager parity at 1.02e-6 relative L2 and matched the corresponding full FP32 decoder segment at 7.26e-8 relative L2; the same pinned S25 GPU-requested target returned an unsaturated waveform at 1.153% relative L2 / 38.76 dB SNR versus local ONNX CPU on this generated-code window, without a listening-quality gate. No complete co-resident NPU/GPU stream exists. | Improve and revalidate the [talker artifact](../../../e2e_expansion_20260924/evidence/qwen_tts_talker_qualcomm/README.md), then qualify the [device-local predictor/vocoder pipeline](../../../e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/README.md), output quality, recovery and 30-minute thermal behavior. |
| Mobile Galaxy S25 / Snapdragon 8 Elite for Galaxy | Qwen3.8-27B | NOT_E2E_PROFILEABLE | No complete qualified target artifact and device-local stateful Omni backend. Hub jobs provide component execution, not an on-device generation/streaming controller; ADB has no attached device. | Supply and validate the missing matching artifact/backend, then run the complete specified workload. |
| Mobile Galaxy S25 / Snapdragon 8 Elite for Galaxy | MiniCPM-o 4.5 | COMPONENT_FP16_SPEECH_HEAD_NPU_NUMERIC_PROFILED; NOT_E2E_PROFILEABLE | Fresh FP16 speech-head inference passed; all 41 outputs exactly matched the same artifact/dataset reference. Against the recovered original ONNX CPU source on the same fixture, logits relative L2 was 0.3605%, maximum new-K/V relative L2 1.311%, and top-1 speech token 1867 matched. Historical FP16 parity passed; tested W8A16 top-1 parity failed. The 100-sample component profile had p50/p95 7.197/7.615 ms, with all 1,029 execution-detail rows on NPU and reported inference peak memory 185,991,168 bytes. Generated-audio quality and qualified thinker/encoders/vocoder remain unverified. | Qualify a complete mobile checkpoint/export and the full multimodal/stateful pipeline; [speech-head evidence](../../../e2e_expansion_20260924/evidence/minicpmo_tts_qualcomm/README.md). |
| Mobile Galaxy S25 / Snapdragon 8 Elite for Galaxy | InternVLA-A1 | COMPONENT_COSMOS_NPU_NUMERIC_PROFILED; SYNTHETIC_ACTION_SENSITIVITY_MEASURED; NOT_E2E_PROFILEABLE | The real Place_Markpen Cosmos image encoder FP32 ONNX export matched its source on two six-frame fixtures. Galaxy S25 FP16 QNN DLC inference returned a finite latent within 0.0524% relative L2 / 65.61 dB SNR of the pinned pattern source. Injecting this device latent into the same real policy on local CPU changed synthetic `[1,50,32]` actions by 0.742% relative L2; the CPU source repeated bitwise identically. The 100-sample six-frame encoder profile had nearest-rank p50/p95 49.665/51.382 ms, all 121 execution-detail rows on NPU, and a reported inference peak of 158,232,576 bytes. No real-observation task tolerance exists, and the action policy was not resident on S25. ADB has no attached device. | Extend the [S25 encoder component](../../../e2e_expansion_20260924/evidence/internvla_cosmos_qualcomm/README.md), then validate real action quality, device-local state, admission, cancellation and sustained behavior. |
+14 -4
View File
@@ -48,8 +48,16 @@ now matches local eager CPU at 1.99e-6 relative L2 and has compiled for S25
TFLite. Its GPU-requested inference returned an unsaturated waveform at
4.239% relative L2 versus pinned local ONNX CPU, bitwise identical to the
historical target's output on the same fixture. The new target's own
node-placement profile is pending, so the historical timing does not yet
qualify this revision-pinned artifact.
100-sample node-placement profile measured p50/p95 0.671/1.454 s for 2 s
audio, with 403 CPU and 335 GPU rows (median component RTF 0.335). This
qualifies only the tested vocoder component; full co-resident streaming,
speech quality and sustained behavior remain open.
A [real generated-code 25-frame window](../../benchmarks/edge_harness/results/e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s25/real_code_window/README.md)
also passed local ONNX/eager parity at 1.02e-6 relative L2 and matched its
full FP32 decoder segment at 7.26e-8 relative L2. The corresponding S25
GPU-requested inference returned an unsaturated waveform at 1.153% relative
L2 / 38.76 dB SNR versus ONNX CPU. This tests one generated-code window,
not mobile talker/vocoder co-residency or speech quality.
On [Galaxy S24](../../benchmarks/edge_harness/results/e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/s24/tflite_short_chunk/README.md),
the same pinned two-frame TFLite source passed CPU-requested waveform parity
at 5.75e-6 relative L2, but the GPU-requested waveform saturated completely
@@ -59,8 +67,10 @@ measured 0.601/0.895 s but failed the waveform gate. A FP32-preserving GPU
option returned the same saturated waveform bitwise, so it did not repair
the tested delegate artifact. A [Snapdragon X Elite short QNN graph](../../benchmarks/edge_harness/results/e2e_expansion_20260924/evidence/qwen_tts_vocoder_qualcomm/xelite/qnn_short_chunk/README.md)
compiled and returned an unsaturated NPU-requested waveform at 0.930%
relative L2 versus local ONNX CPU on one synthetic fixture. Its node-placement
profile is pending. Neither changes M2 support
relative L2 versus local ONNX CPU on one synthetic fixture. Its 100-sample
profile attributed all 728 rows to NPU, but p50/p95 was 3.662/3.676 s for
0.16 s audio (median component RTF 22.89). This artifact therefore fails
the playable-stream latency gate. Neither changes M2 support
depth before full stream and quality gates.
The [Spark hosted Qualcomm component expansion](../../benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/spark_s24_full_attention/README.md) advances M1 only to one real fixed-shape decoder attention layer. The same W8A16 QNN DLC ran on S24, Snapdragon X Elite CRD and SA8775P ADP NPUs with identical outputs on one pinned fixture; S25 had prior separate component evidence. On [RB3 Gen 2](../../benchmarks/edge_harness/results/e2e_expansion_20260923/evidence/spark_rb3_full_attention/README.md), the tested W8A16 graph failed QNN loading even after an exact-device compile. FP32 ONNX ran on CPU with near-source parity, while calibrated W8A8 ran on NPU but had 20.9% hidden-state relative L2 and remains numerically unqualified. These are component C results, not full M1: device-local 28-layer prefill/continuous decode, KV/ring, sampling, token quality, admission/cancellation, complete-request timing and sustained power/thermal gates remain open. AI Hub is the test facility, not a deployment dependency.