24 Commits
Author SHA1 Message Date
iamdoubz 8cdd0f61df Merge pull request 'Parakeet v Whisper h2h' (#26) from test_parakeet into main
Reviewed-on: #26
2026-07-16 10:23:17 -05:00
iamdoubz 2d1c9fa478 Bench test npu 2026-07-16 10:10:30 -05:00
iamdoubz a71299803f docs(release): v0.7.4 release notes with SHA-256 checksums 2026-07-16 10:03:23 -05:00
iamdoubz fcf72da9db chore: bump version 0.7.4 2026-07-16 09:56:22 -05:00
iamdoubz 616d2f4f97 chore(bench): rustfmt asr_bench + allow large_enum_variant (one Engine per process) 2026-07-16 08:47:11 -05:00
iamdoubz be49c53940 docs(bench): W1 anomaly resolved — LP-E-core spin-barrier root cause, fixed numbers, criteria updated 2026-07-16 08:44:17 -05:00
iamdoubz 6cd736bec1 test(bench): W1 re-run after thread-cap fix — RTF 0.218, 0.827 cpu-sec/audio-sec, WER unchanged 2026-07-16 08:43:26 -05:00
iamdoubz 0d2eee7416 fix(transcription): cap whisper n_threads at 4 — hybrid-CPU spin-barrier pathology
available_parallelism() put ggml workers on Meteor Lake LP E-cores; every
per-node spin barrier then waits on the slowest worker while the rest burn
CPU: RTF ~22 at 14 threads vs 0.28 at 4 threads (~80x), same build. This
was the real W1 CPU-pathology root cause; /Od-vs-/O2 made no difference.
4 matches whisper.cpp upstream default and is the CPU-frugal choice
(NFR-RES-1). WA_WHISPER_THREADS env overrides for support/bench.
2026-07-16 08:39:45 -05:00
iamdoubz c7899e72a2 fix(build): use Ninja generator so cmake-rs stops clobbering MSVC /O2
The cmake crate strips -O*/O* from CFLAGS and, with no explicit generator
on MSVC, overwrites CMAKE_C_FLAGS_RELEASE — so the previous CFLAGS=/O2
attempt could never work (verified: /DNDEBUG survived, /O2 stripped).
With CMAKE_GENERATOR=Ninja the override branch is skipped and CMake's
default Release flags (/O2 /Ob2 /DNDEBUG) reach ggml.
2026-07-16 08:20:07 -05:00
iamdoubz 4e6c5a357e docs(bench): qualitative real-recording pass — P1 cleanest + best punctuation, W4 worst 2026-07-16 08:18:00 -05:00
iamdoubz 181af150e5 test(bench): qualitative meeting-audio pass — W2/W4/P1 on bank_deposits.wav
62 s real recording (48 kHz stereo, downmixed/resampled by the production
reader). Reference .txt is a placeholder; WER column is meaningless here,
only the hypothesis text counts.
2026-07-16 08:16:53 -05:00
iamdoubz d89b99db6c fix(build): restore /O2 /DNDEBUG for native deps clobbered by cmake-rs on MSVC
cmake-rs hardcodes opt_level(0) and replaces CMake's Release C flags, so
ggml/whisper.cpp compiled at /Od — root cause of the W1 CPU-pathology
(RTF ~20) in docs/benchmarks/2026-07-parakeet-vs-whisper.md. cc-rs appends
env CFLAGS/CXXFLAGS last, restoring optimization for all native deps.
2026-07-16 08:14:08 -05:00
iamdoubz 32e0d3c8d9 test(bench): raw benchmark CSVs (30-utterance LibriSpeech matrix + W1 non-vulkan rerun) 2026-07-16 00:42:26 -05:00
iamdoubz 21691d3756 docs(bench): parakeet-vs-whisper results — pre-registered criteria evaluated, per-rung recommendation 2026-07-16 00:42:25 -05:00
iamdoubz ca0563039d test(bench): p2-parakeet-dml contender (Parakeet on the iGPU via DirectML EP) 2026-07-15 23:14:47 -05:00
iamdoubz a682ffccdd test(bench): bench-directml feature for DirectML sherpa binaries (P2, never default) 2026-07-15 23:14:42 -05:00
iamdoubz 68632db6ef fix(bench): named Set-Content params — positional+NoNewline silently wrote nothing on PS 5.1 2026-07-15 21:45:46 -05:00
iamdoubz 297c412488 test(bench): sequential matrix runner (6 corpus + 3 live runs) 2026-07-15 21:42:28 -05:00
iamdoubz ad4495f220 test(bench): asr_bench harness — W1-W4 + Parakeet contenders, WER/RTF/CPU-seconds, live-window mode 2026-07-15 21:40:44 -05:00
iamdoubz 4dddcdfe1a test(bench): typeperf CPU/GPU/NPU counter capture script 2026-07-15 21:35:43 -05:00
iamdoubz 965f1adc86 test(bench): parakeet-tdt-0.6b-v2 int8 staging script 2026-07-15 21:35:42 -05:00
iamdoubz 96072a2f75 test(bench): corpus staging script + gitignore for bench-corpus (parakeet bake-off) 2026-07-15 21:35:41 -05:00
iamdoubz 8c8e476cb7 Ignore memory file 2026-07-15 21:16:46 -05:00
iamdoubz 22810df4c1 Delete MEMORY.md 2026-07-15 21:15:06 -05:00
20 changed files with 1052 additions and 548 deletions
+14
View File
@@ -0,0 +1,14 @@
# Fix: whisper.cpp (whisper-rs-sys) is configured by the cmake crate, which on
# MSVC *without an explicit generator* overwrites CMAKE_C_FLAGS_RELEASE with
# unoptimized flags (it also strips any -O*/O* flag from CFLAGS, so env
# optimization flags can't survive). Result: ggml's CPU kernels compiled at
# /Od — CPU-only transcription ran ~40x slower than real time (bench finding
# W1, docs/benchmarks/2026-07-parakeet-vs-whisper.md). With a generator set,
# cmake-rs skips that override (`if generator.is_none() && msvc` in
# cmake-0.1.58) and CMake's default Release flags (/O2 /Ob2 /DNDEBUG) apply.
# Ninja ships with VS Build Tools; builds already require vcvars64 (which puts
# it on PATH). NDEBUG kept explicitly so C deps never build with asserts on.
[env]
CMAKE_GENERATOR = "Ninja"
CFLAGS = "/DNDEBUG"
CXXFLAGS = "/DNDEBUG"
+4
View File
@@ -46,3 +46,7 @@ packaging/npu-runtime/*.zip
# --features vulkan build (bundled into the installer); a redistributable blob,
# not committed.
src-tauri/vulkan-1.dll
MEMORY.md
# ASR bench corpus (test_parakeet branch): LibriSpeech-derived WAVs + refs,
# staged by scripts/bench/fetch-corpus.ps1 — audio never enters the repo.
bench-corpus/
-543
View File
@@ -1,543 +0,0 @@
# Memory — whispassist
> Generated: 2026-07-07 21:30:45
> Total memories: **75**
> Breakdown: fact: 3, decision: 10, goal: 1, preference: 1, context: 3, event: 1, learning: 24, observation: 2, artifact: 25, error: 5
---
## Instructions
*Standing rules, constraints, and guidelines to always follow.*
*No memories of this type.*
---
## Facts
*Verified information, project status, and established truths.*
### parakeet-rs (altunenes) DOES have a genuine increm...
parakeet-rs (altunenes) DOES have a genuine incremental streaming decode API for Parakeet-family models: ParakeetEOU and Nemotron structs thread real recurrent state between calls internally (EncoderCache: cache_last_channel/cache_last_time/cache_last_channel_len; decoder LSTM state_h/state_c; last_token) plus a 4s rolling audio ring buffer, so callers just feed sequential small chunks (160ms for EOU, 560ms for Nemotron) and get incremental partial text -- it is not naive re-chunking of a batch decoder. Source: github.com/altunenes/parakeet-rs src/parakeet_eou.rs and model_eou.rs, examples/streaming.rs (checked 2026-07-02).
*Confidence: 0.95 | Status: active | Created: 2026-07-02T20:09:27*
### WhispAssist app icon/branding: real logo provided ...
WhispAssist app icon/branding: real logo provided by user (paperclip mascot + purple speech-bubble-with-sparkles mark, WhispAssist wordmark). The app icon (title bar/taskbar/tray/installer) is cropped from just the small speech-bubble-with-sparkles mark, not the full marketing graphic or the paperclip mascot (too much fine detail to read at 16-32px). Updated twice: first a transparent-background crop, then a refined version on its own gradient purple background from a cleaner logo revision the user provided. Regenerated via ; that command generates iOS/Android/Appx/macOS outputs by default which must be deleted since WhispAssist is Windows-only (not referenced by tauri.conf.json). tray.png is a manual 32x32 export, not one of tauri icon's own output names.
*Confidence: 1.0 | Status: active | Created: 2026-07-02T20:13:49*
### The EOU streaming variant used by parakeet-rs is a...
The EOU streaming variant used by parakeet-rs is a genuinely separate ONNX export, not a mode of the batch Parakeet TDT model: it's NVIDIA's own nvidia/parakeet_realtime_eou_120m-v1 (120M params, cache-aware FastConformer encoder + LSTM decoder, 80-160ms chunks, English-only, no punctuation/casing, emits <EOU> token). This is distinct from istupakov/parakeet-tdt-0.6b-v3-onnx (600M, the community ONNX conversion used for WhispAssist's originally-considered batch/full-file transcription path, which has the ~4-5min length limit). Both are downloaded separately; author's own code comment on reset_on_eou says 'I must admit that this is not work very well on my real world tests'.
*Confidence: 0.9 | Status: active | Created: 2026-07-02T20:09:30*
---
## Decisions
*Architectural choices, approach selections, and their rationale.*
### M4.4 (MS Graph calendar source, T8.9, FR-CAL-6) SH...
M4.4 (MS Graph calendar source, T8.9, FR-CAL-6) SHIPPED 2026-07-07 on branch feature_chore_bug_005 (commits 83cb30e..7df76df + 1cf0be1). This LIFTS the 2026-07-02 'T8.9 on hold' decision — user explicitly asked to build it in this session, overriding the earlier hold. Implementation: calendar::GraphSource implementing CalendarSource, reusing sync::oauth's provider-agnostic PKCE/loopback machinery (added a 'graph-calendar' OAuth provider entry, made sync::resolve_access_token pub(crate) for cross-module reuse) rather than building new OAuth plumbing. This completes all of milestone M4 (M4.1 chunked upload, M4.2 multi-language, M4.3 Dropbox/Box, M4.4 Graph calendar).
*Confidence: 0.95 | Status: active | Created: 2026-07-08T02:22:48*
### WhispAssist roadmap: T8.8 (at-rest encryption / va...
WhispAssist roadmap: T8.8 (at-rest encryption / vault) and T8.9 (Microsoft Graph calendar) are ON HOLD per user decision (2026-07-02). Consequence: Phase 9c (T9.12 client-side encryption before upload) is blocked since it depends on the T8.8 vault - skip 9c for now. Building Phase 9 (remote sync) starting with 9a (WebDAV).
*Confidence: 1.0 | Status: active | Created: 2026-07-03T01:01:49*
### WhispAssist GPU acceleration decision (2026-07): w...
WhispAssist GPU acceleration decision (2026-07): whisper.cpp GPU transcription via VULKAN as primary cross-vendor path — ONE binary covers NVIDIA+AMD+Intel (whisper-rs 'vulkan' feature). whisper-rs GPU features: cuda (NVIDIA-only, CUDA toolkit at build), vulkan (cross-vendor, Vulkan SDK at build + vulkan-1.dll loader shipping with every GPU driver), hipblas (AMD/ROCm LINUX-ONLY, unusable on Windows), metal (Apple). KEY: whisper.cpp GPU backends are COMPILE-TIME/static (cannot download runtime on-demand like the ort load-dynamic NPU path); binary must be built with the feature. Vulkan is default GPU build; CUDA is optional NVIDIA-only turbo variant LATER (user: 'we will do cuda later'). Vulkan degrades to CPU if no GPU present.
*Confidence: 1.0 | Status: active | Created: 2026-07-05T22:03:34*
### WhispAssist roadmap: T8.8 (at-rest encryption/vaul...
WhispAssist roadmap: T8.8 (at-rest encryption/vault) and T8.9 (MS Graph calendar) ON HOLD per user (2026-07-02). Consequence: Phase 9c (T9.12 client-side encryption) blocked (needs T8.8 vault) - skip for now. Building Phase 9 remote sync starting with 9a WebDAV.
*Confidence: 1.0 | Status: active | Created: 2026-07-03T01:02:11*
### In WhispAssist's calendar module, CalendarSource::...
In WhispAssist's calendar module, CalendarSource::import() is a synchronous trait method (matches PstSource's blocking subprocess call). GraphSource (MS Graph, async reqwest HTTP) bridges into that sync signature via tauri::async_runtime::block_on inside fetch_events, and callers run the whole import() call inside tauri::async_runtime::spawn_blocking (same pattern commands.rs already used for PstSource's readpst subprocess) — avoids making CalendarSource async just for one source. Kept a separate WA_GRAPH_CALENDAR_BASE_URL env var (distinct from sync's WA_GRAPH_BASE_URL used by OneDriveTarget) so calendar and sync tests never race on the same process-global env var in cargo test.
*Confidence: 0.9 | Status: active | Created: 2026-07-08T02:22:55*
### WhispAssist PST usability fixes (2026-07-06, commi...
WhispAssist PST usability fixes (2026-07-06, commits 00de9d3/9d757be/75ec24d): (1) calendar path is now remembered in Settings (pst_last_path field) so the user doesn't re-browse every launch; (2) added an opt-in 'auto-sync on launch' checkbox (pst_auto_sync) that re-imports the remembered path once at startup - deliberately a ONE-SHOT pass mirroring the existing sync-job-resume pattern in lib.rs, NOT a periodic timer, because NFR-RES-1 ('no polling timers when idle') is enforced consistently everywhere else in this codebase (every startup task has a comment noting this). User asked about a periodic 'read frequency' option too; I declined to build that specific piece and explained the NFR-RES-1 conflict rather than silently building or silently dropping it.
*Confidence: 0.95 | Status: active | Created: 2026-07-06T20:40:52*
### Completed a full UI/UX redesign of WhispAssist: se...
Completed a full UI/UX redesign of WhispAssist: semantic CSS design-token system (light/dark, WCAG AA verified), all emoji/Unicode icons replaced with @lucide/svelte SVG icons, segmented Monitor/Sun/Moon theme toggle defaulting to system preference, custom theme-aware scrollbars. Informed by researching Granola and Meetily's UIs; kept WhispAssist's 3-pane layout since diarization/speaker-naming already beats both competitors.
*Confidence: 0.95 | Status: active | Created: 2026-07-02T20:13:34*
### WhispAssist M1 feature-briefs decomposition (2026-...
WhispAssist M1 feature-briefs decomposition (2026-07-06, docs-only, branch feature_chore_bug_004). KEY INSIGHT: M1 is heavily scaffolded already, do NOT re-create — IPC types FeatureBrief/FeatureBriefInfo/ContextExcerpt (models.rs), api.ts bindings createFeatureBrief/listFeatureBriefs/getFeatureBrief/setBriefExposed, the 4 commands registered in lib.rs, DB tables feature_briefs + mcp_access_log (migrations/0003_ai_mcp.sql), the briefs/<id>.json schema (docs/03-data-model.md), and the FeatureBriefBuilder trait (docs/04-api-contracts.md) ALL EXIST; only the 4 command bodies return not_implemented(). REMAINING to build: (1) Store methods insert_feature_brief/list_feature_briefs/get_feature_brief_row/set_brief_exposed; (2) a new non-streaming LlmProvider::complete(system,user)->String primitive (mirrors suggest_tags; impl Ollama+OpenAiCompat, Anthropic later); (3) FeatureBriefBuilder in a new briefs module (strict '## Title/## Problem/## Desired Outcome/## Acceptance Criteria' prompt like RESPONSE_FORMAT_INSTRUCTIONS + parse_brief mirroring parse_summary); (4) the 4 command bodies (add state: State<AppState>, Tauri injects it, api.ts unchanged); (5) UI in SummaryPanel; (6) golden-transcript tests. KEY DESIGN DECISIONS: context_excerpts are VERBATIM transcript substrings (grounding invariant enforced by the golden test), selected by keyword overlap, NOT model paraphrase; the on-disk file is a sealed BriefFile envelope {schema,generated_at,provider,model,...fields,source} indexed by the feature_briefs table (file=truth, row=index); write file+row only AFTER a successful distill (no partial artifacts on LLM failure). Full implementation-ready checklist in docs/05-roadmap.md M1; JSON schema in docs/03-data-model.md; tests in docs/06-test-strategy.md P10.
*Confidence: 1.0 | Status: active | Created: 2026-07-07T04:28:36*
### Decision: NOT pursuing NVIDIA Parakeet or DirectML...
Decision: NOT pursuing NVIDIA Parakeet or DirectML/NPU acceleration for WhispAssist transcription near-term, as of 2026-07-02. Researched achetronic/parakeet (Go, Linux-only, dead end) and altunenes/parakeet-rs (Rust, built on ort, has genuine streaming via a separate EOU 120M model with real internally-threaded encoder cache and LSTM decoder state). Reasons not to pursue now: (1) DirectML support for this model family is unproven - zero reports of anyone running it, and there is a live unresolved ONNX Runtime bug (microsoft/onnxruntime issue 19837) producing wrong output on DirectML for the exact LSTM+Einsum op combination these models use; (2) DirectML itself is now in Microsoft maintenance mode, with new NPU/GPU work moving to Windows ML instead, which calls WhispAssist's existing ADR-0004 (ort + DirectML for NPU) into question independent of Parakeet; (3) Parakeet streaming needs a continuous per-meeting state machine fed small sequential chunks, fundamentally incompatible with WhispAssist's current stateless independent 4-second-window architecture - a real rearchitecture, not a swap, and it would lose whisper.cpp's crash-recoverable-per-window property; (4) competitor Meetily does not actually do live Parakeet+hardware-acceleration either - they only use it for offline batch re-transcription. Recommended future path if revisited: CPU-only Parakeet-EOU streaming spike first to validate the rearchitecture and quality tradeoffs (EOU is English-only, no punctuation/capitalization), treat NPU acceleration as a separate track that should probably target Windows ML rather than raw DirectML.
*Confidence: 0.9 | Status: active | Created: 2026-07-02T20:14:37*
### WhispAssist CUDA + AMD-non-Vulkan acceleration PLA...
WhispAssist CUDA + AMD-non-Vulkan acceleration PLAN (2026-07-05): whisper.cpp bakes in exactly ONE GPU backend at compile time. Universal build=Vulkan (all vendors). NEW: NVIDIA-turbo installer variant = whisper.cpp CUDA (feature already declared Cargo.toml:94) — but a CUDA build has NO Vulkan, so AMD/Intel GPUs in that variant need a non-Vulkan accel path. DECISION (recommended, user was away/didn't confirm): AMD-non-Vulkan = DirectML via the EXISTING ort/ONNX NPU path (OnnxNpuTranscriber generalized to accept EP: OpenVINO-NPU vs DirectML-GPU+device_id). DirectML works on any DX12 GPU, load-dynamic (no new build toolchain), one binary, degrades to CPU. hipBLAS/ROCm DEFERRED (narrow gfx coverage, fragile on Windows, needs 3rd installer). CORE CODE CHANGE: add AccelPath enum {WhisperCuda,WhisperVulkan,WhisperCpu,OnnxOpenVino,OnnxDirectML} + resolver in hardware/mod.rs from (BackendId+cfg!(feature)+runtime readiness); transcriber factory switches on it. This also CLOSES the known detection-honesty gap (GPU marked available from DXGI regardless of compiled feature -> no-op GPU routing). PHASES: P0 detection-honesty+AccelPath (small, no hw, do first), P2 AMD/Intel DirectML (validate on Intel Arc iGPU locally), P1 CUDA (needs NVIDIA hw/CI). ort needs 'directml' feature + an onnxruntime.dll built with DML EP in the runtime bundle; DirectML.dll ships with Win10 1903+.
*Confidence: 0.85 | Status: active | Created: 2026-07-05T23:28:58*
---
## Goals
*Objectives, targets, and milestones to track progress.*
### WhispAssist NEXT STEPS — CPU transcription slownes...
WhispAssist NEXT STEPS — CPU transcription slowness testing round (open bug): the full transcribe_file path takes ~90s for a 6.3s clip on a 14-thread CPU with base.en (should be ~2-3s). This is PRE-EXISTING (predates Vulkan) and independent of the GPU work. To root-cause next: (a) verify whisper set_n_threads actually applies available_threads()=14 (log n_threads in run_full); (b) check whether the encoder pays full 1500 audio_ctx per 30s window even for a 6s clip in the non-streaming path (the streaming path fix in commit 8530a22 scaled audio_ctx by window length, but transcribe_file/run_full may not); (c) run stock whisper-cli directly on the same model+wav to isolate whether it's OUR run_full config vs whisper.cpp itself; (d) test greedy vs beam params and q5_1 vs f16 model; (e) confirm it's not thermal/throttle. The non-vulkan CPU baseline re-run (task, ~90s expected) was in progress to formally confirm parity with the vulkan build's CPU number.
*Confidence: 1.0 | Status: active | Created: 2026-07-05T22:04:11*
---
## Commitments
*Promises, obligations, and TODOs that need follow-through.*
*No memories of this type.*
---
## Preferences
*User and entity preferences for personalization.*
### WhispAssist user working style (observed 2026-07-0...
WhispAssist user working style (observed 2026-07-06): (1) Demands EMPIRICAL PROOF over theory. When I attributed silent new recordings to the mic-not-in-WAV design, they pushed back ('the old file is also vault-sealed and plays fine, so it must be the 32->16bit change'). Resolving it required an actual real-hardware loopback capture test (play a known sound, read peak i16 from the WAV) to prove the 16-bit path records real audio — only then accept the diagnosis. HOW TO APPLY: when diagnosing a bug, verify the cause with a runnable test/measurement and show the evidence; don't just assert a root cause. (2) Highly protective of encryption-at-rest. They independently spotted that the decrypted audio.play.wav on disk and the browser 'download' button undermined the vault, and asked to switch playback to in-memory on-the-fly decryption. HOW TO APPLY: proactively avoid writing plaintext of vault-sealed data to disk and close off easy exfiltration paths (downloads, temp files).
*Confidence: 0.9 | Status: active | Created: 2026-07-07T01:05:30*
---
## Relationships
*Entity connections, team context, and collaboration patterns.*
*No memories of this type.*
---
## Context
*Session summaries, status updates, and conversation state.*
### WhispAssist release/versioning process (as of v0.2...
WhispAssist release/versioning process (as of v0.2.0, 2026-07-06): the version string lives in THREE files that must be bumped together — package.json, src-tauri/tauri.conf.json, src-tauri/Cargo.toml (Cargo.lock updates on build). The shipped UNIVERSAL installer is built with: npm run tauri build -- --features vulkan --config src-tauri/tauri.vulkan.conf.json, with env VULKAN_SDK=C:\VulkanSDK\1.4.350.0, CMAKE_GENERATOR=Ninja, CARGO_TARGET_DIR=C:\wt, and vcvars64.bat loaded from 'C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat'. Outputs land at C:\wt\release\bundle\msi\WhispAssist_<ver>_x64_en-US.msi and \nsis\WhispAssist_<ver>_x64-setup.exe (MSI ~44MB, NSIS ~9MB). The build does NOT create/push git tags — after merging to main, tag manually: git tag v<ver>; git push origin v<ver>. Last release before 0.2.0 was v0.1.6 (PR #15).
*Confidence: 1.0 | Status: active | Created: 2026-07-07T01:05:16*
### Project status as of 2026-07-02: Phase 8 tasks T8....
Project status as of 2026-07-02: Phase 8 tasks T8.7 (multi-language transcription + i18n scaffold) and T8.8 (at-rest encryption/vault, needs an ADR decision on SQLCipher vs file-level encryption first) remain deferred/pending. User paused them to do a full UI/UX redesign, then a transcription-latency investigation and fix, then Parakeet/NPU research. Both T8.7 and T8.8 are still the next planned work whenever the user returns to the Phase 8 roadmap.
*Confidence: 0.9 | Status: active | Created: 2026-07-02T20:14:43*
### WhispAssist remaining-work assessment + plan (2026...
WhispAssist remaining-work assessment + plan (2026-07-06, docs-only planning on branch feature_chore_bug_004, NOT built). As of v0.2.0, Phases 1-9 ship. The only real gap is Phase 10 (external AI + agent handoff, ADR-0011) plus a few polish items. STUBBED (commands return Err(not_implemented)): create/list/get_feature_brief, set_brief_exposed, mcp_status, set_mcp_enabled, set_mcp_scope, mcp_access_log, run_agent, create_issue_from_brief. SKELETON/ABSENT: mcp/mod.rs (trait + todo!() only), AnthropicProvider (returns 'not built yet'), MS Graph CalendarSource, multi-language transcription, DropboxTarget/BoxTarget (OAuth wired in sync/oauth.rs but no upload impl), chunked/resumable upload. BUILT already: OpenAiCompatProvider. The phased plan lives in docs/05-roadmap.md section 'Remaining work — post-v0.2.0 execution plan': M1 feature briefs (first; LLM-only, no egress) -> M2 MCP server (the differentiator; inbound loopback, zero added egress, FR-MCP-7 egress-unchanged is the merge gate) ; M3 hosted AI (parallel; finish Anthropic + hosted-key/banner/allowlist) ; M4 reliability/breadth (chunked upload is TOP item because recordings are now ~50-100MB and put() buffers whole file, OneDrive/Graph caps PUT at 250MB; then multi-language, Dropbox/Box) ; M5 push handoff (agent runner + issue tracker, Could-priority, last/optional). MS Graph calendar deferred (Could).
*Confidence: 1.0 | Status: active | Created: 2026-07-07T04:28:28*
---
## Events
*Important conversations, milestones, and temporal occurrences.*
### WhispAssist reached v0.2.0 (2026-07-06), supersedi...
WhispAssist reached v0.2.0 (2026-07-06), superseding v0.1.6. Additions since 0.1.6: microphone capture (records+transcribes the user's voice, mixed into transcript AND the saved recording at native quality via MicBridge), in-app recording playback with in-memory on-the-fly decryption (waaudio:// custom protocol, no plaintext on disk, download disabled), AI-generated tags + chip tag editor + tag filtering, meeting rename (editable title), notes single-pane Editor/Preview toggle, cancel-a-recording, 16-bit half-size recordings, live per-item sync upload progress, audio output + microphone device pickers, Outlook .pst recurring-event import/filtering + auto-sync-on-launch, and a SINGLE universal Vulkan installer (bundled vulkan-1.dll) replacing the separate CPU/NPU vs Vulkan builds. Built on branch feature_chore_bug_003 — still needs merge to main + tag v0.2.0. Installers already produced at C:\wt\release\bundle.
*Confidence: 1.0 | Status: active | Created: 2026-07-07T01:05:36*
---
## Learnings
*Knowledge acquired from experience, corrections, and insights.*
### Real libpst quirk found via a real 7.2GB mailbox t...
Real libpst quirk found via a real 7.2GB mailbox test (2026-07-06): this readpst/libpst build joins a multi-value RRULE BYDAY with semicolons instead of RFC 5545's commas, e.g. 'RRULE:FREQ=WEEKLY;COUNT=10;BYDAY=MO;TU;WE;TH;FR' - so TU/WE/TH/FR appear as bare semicolon-separated tokens with no '='. A naive RRULE parser using '?' on split_once('=') silently bails out (returns None) for any event with more than one weekday, which is why the first version of expand_rrule worked for single-BYDAY series but silently dropped recurrence for multi-weekday ones. Fix: track the last-seen key and attribute a bare (no '=') token to it as a continuation value. This joins other already-documented libpst 0.6.63 quirks in ADR-0008 (no ORGANIZER/ATTENDEE emitted, no -8 flag support, wrong -t usage string).
*Confidence: 1.0 | Status: active | Created: 2026-07-06T20:40:50*
### WhispAssist WASAPI microphone finding (2026-07-06)...
WhispAssist WASAPI microphone finding (2026-07-06): unlike get_default_device(Render) which FAILS in cargo test on this dev machine, capturing the DEFAULT MIC (Direction::Capture) DOES work under cargo test AND delivers real frames (~3840 16kHz frames in 0.6s). Caveat: the FIRST COM activation of the mic can deliver 0 frames within the first ~600ms (cold start); a second run delivers normally. So a hardware mic smoke test should assert open+stop succeed (summary.sample_rate>0), not frames>0. Test: audio::tests::microphone_capture_opens_and_stops_cleanly (#[ignore], run with --ignored).
*Confidence: 0.9 | Status: active | Created: 2026-07-06T21:34:39*
### CONFIRMED FIX for WhispAssist release build crashe...
CONFIRMED FIX for WhispAssist release build crashes: Windows Defender real-time scanning of src-tauri/target was corrupting rustc.exe's compilation (random STATUS_STACK_BUFFER_OVERRUN crashes on different crates each run). Adding Defender exclusions (Add-MpPreference -ExclusionPath for target/, ~/.cargo, ~/.rustup, and -ExclusionProcess for rustc.exe/cargo.exe) fixed it completely -- full release build (whisper-rs, sherpa-rs native deps, MSI+NSIS bundling) now succeeds cleanly with the project's normal aggressive release profile (opt-level=z, codegen-units=1, lto=true). No toolchain reinstall or profile change was needed after all; those were red herrings from earlier in the debugging session. Also: a leftover running whispassist.exe instance can block cargo from overwriting the binary with 'Access is denied' -- close it before rebuilding.
*Confidence: 0.95 | Status: active | Created: 2026-07-01T21:09:24*
### Dark-mode bug pattern learned: CSS custom properti...
Dark-mode bug pattern learned: CSS custom properties don't cascade upward to ancestor elements. If data-theme (or similar theme attribute) is only set on an inner .app div, html/body keep the browser's default white background + 8px UA-stylesheet margin, invisible in light mode but a bright white border around the whole window in dark mode. Fix: mirror the theme attribute onto document.documentElement via an effect, and add a global html/body margin:0 + background:var(--bg) rule.
*Confidence: 0.9 | Status: active | Created: 2026-07-02T20:13:41*
### WhispAssist NPU spike (T3.4): Intel AI Boost NPU (...
WhispAssist NPU spike (T3.4): Intel AI Boost NPU (Core Ultra 5 135U, Meteor Lake, PCI VEN_8086&DEV_7D1D) runs the Whisper base.en ONNX encoder via ONNX Runtime OpenVINO EP (device_type=NPU) at ~66 ms/window vs ~236 ms/window on CPU = 3.58x faster, correct output shape (1,1500,512), full op coverage. Validates the plan: offload the fixed-shape Whisper encoder to the NPU, keep the dynamic decoder on CPU.
*Confidence: 0.95 | Status: active | Created: 2026-07-02T20:31:08*
### WhispAssist: an OAuth-linked calendar source (MS G...
WhispAssist: an OAuth-linked calendar source (MS Graph) is stored in Settings (settings.json: graph_calendar_enabled + graph_calendar_credential_ref) rather than as a sync_targets DB row, because it is not a SyncTarget/upload destination — reusing add_sync_target's OAuth flow would have wrongly surfaced it in the Sync UI and risked the upload pump trying to build a SyncTarget for it. begin_graph_calendar_link is a separate command from begin_oauth_link for this reason, duplicating ~60 lines of PKCE handshake rather than sharing it, since the two flows diverge in storage/eventing.
*Confidence: 0.85 | Status: active | Created: 2026-07-08T02:23:03*
### cargo fmt -- <specific files> does not scope forma...
cargo fmt -- <specific files> does not scope formatting to those files in the WhispAssist repo (src-tauri) — it reformats the entire crate regardless of file args passed after --, pulling in unrelated pre-existing drift in untouched files (observed: src/audio/mod.rs). After running cargo fmt scoped to touched files, always git status/diff to catch and git checkout -- any unrelated files it touched before committing. Also: memanto's on-prem backend (localhost:8080) needs Ollama (localhost:11434, embedding model nomic-embed-text) running for recall/export/sync to work, and the active agent session (memanto agent activate whispassist) can expire/drop mid-session — 'remember' can report success even when the write doesn't actually persist/index, so verify with 'memanto recall --recent' after a batch of remember calls rather than trusting the success message alone.
*Confidence: 0.9 | Status: active | Created: 2026-07-08T02:23:10*
### WhispAssist runtime bundle URLs CORRECTED to gitea...
WhispAssist runtime bundle URLs CORRECTED to gitea /media/ path (2026-07-06, commit 224aaf9): the .7z runtime bundles are hosted via Git LFS, and gitea's /raw/ endpoint returns the LFS POINTER (text) not the file, so the download URLs were changed from /raw/branch/main/ to /media/branch/main/ (gitea's media endpoint resolves LFS objects). Final URLs: NPU=https://git.dou.bet/iamdoubz/WhispAssist/media/branch/main/runtime/openvino.7z, DirectML=https://git.dou.bet/iamdoubz/WhispAssist/media/branch/main/runtime/directml.7z. SHAs unchanged (openvino ca0be9fc..., directml 34369222...). Files tracked via Git LFS (.gitattributes: runtime/*.7z filter=lfs). Still on branch chore_debug (no PR yet); URLs point at main so they resolve after merge. GOTCHA for future: GitHub raw.githubusercontent AND gitea /raw/ both serve LFS pointers not content — always use gitea /media/ (or GitHub media/LFS URL) for LFS-backed download targets.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T14:45:20*
### cargo test in WhispAssist src-tauri reliably crash...
cargo test in WhispAssist src-tauri reliably crashes at LINK time (rustc.exe exit 0xc0000409 STATUS_STACK_BUFFER_OVERRUN) when linking the full debug test binary against whisper.cpp+sherpa-onnx native libs with full debug info (debuginfo=2 default for test profile). This reproduces even from a clean target/debug, with reduced --jobs, regardless of Defender exclusions (which fixed the earlier release-build crashes but not this). FIX: set env var CARGO_PROFILE_TEST_DEBUG=0 (drop debug info) before cargo test -- this shrinks the PDB/link footprint enough to avoid the crash. Confirmed working: 'cargo test privacy_self_check' passed cleanly with CARGO_PROFILE_TEST_DEBUG=0 --jobs 4. Also noted: commands.rs is NOT feature-gated for cpu-transcription/diarization (unconditionally imports SherpaDiarizer/WhisperTranscriber/run_streaming_worker), so cargo test --no-default-features fails to compile -- can't lighten the native-link footprint that way, must use the debug-info trick instead.
*Confidence: 0.95 | Status: active | Created: 2026-07-01T22:01:31*
### WhispAssist dark-theme native-control gotcha (2026...
WhispAssist dark-theme native-control gotcha (2026-07-06, commits 4442f80/8038918): the app theme is a MANUAL toggle (data-theme on html + .app), independent of the OS prefers-color-scheme. Native form controls default to LIGHT and render bright-white in dark mode. Fixes applied: (1) added CSS 'color-scheme: light' on :global(:root) and 'color-scheme: dark' on :global([data-theme="dark"]) in App.svelte — this alone fixed unstyled controls. (2) A <textarea> was white because Settings.svelte's 'input, select { background:var(--bg); color:var(--fg) }' rule EXCLUDED textarea; fix = add textarea to that selector. (3) The header template <select> (.theme-select) options popup stayed WHITE even with color-scheme:dark because it had 'background: transparent' — an AUTHOR-styled select makes Chromium/WebView2 render its options popup in light unless the options carry their own colors. Fix = give .theme-select an explicit 'background: var(--bg-elevated)' AND style '.theme-select option { background: var(--bg-elevated); color: var(--fg) }'. LESSON: for dark-mode selects, set color-scheme on the root AND author the <option> background/color with theme tokens; don't rely on transparent backgrounds.
*Confidence: 0.95 | Status: active | Created: 2026-07-06T13:02:41*
### WhispAssist test-environment quirk found 2026-07-0...
WhispAssist test-environment quirk found 2026-07-06: wasapi::get_default_device(&Direction::Render) (and thus find_render_device(None)) FAILS when called from within 'cargo test' on this dev machine, even though the real desktop app (running as a normal foreground GUI process) resolves it fine. Enumeration itself (DeviceCollection) works fine in both contexts -- it's specifically the 'default device' role query that needs a real interactive audio session. Tests for this were written to assert consistency (find_render_device(None) vs a raw wasapi::get_default_device call, or unknown-id fallback vs None) rather than assuming a default device is resolvable, so they pass in both environments. Implication: don't trust 'cargo test' alone to validate anything touching wasapi's default-device APIs -- verify audio-device-selection behavior via the actual running app instead.
*Confidence: 0.9 | Status: active | Created: 2026-07-06T21:02:54*
### WhispAssist NPU Rust recipe (T3.4, validated): ort...
WhispAssist NPU Rust recipe (T3.4, validated): ort crate v2.0.0-rc.10 with features [load-dynamic, openvino] links against Intel's pip onnxruntime-openvino DLLs and runs the Whisper base.en encoder on the Intel NPU at 65 ms/window (matches Python; CPU is 236ms). Recipe: (1) ORT_DYLIB_PATH -> site-packages/onnxruntime/capi/onnxruntime.dll (the OpenVINO-enabled ORT build); (2) prepend BOTH openvino/libs AND onnxruntime/capi to PATH so dependent DLLs (openvino.dll, onnxruntime_providers_openvino.dll, onnxruntime_providers_shared.dll) resolve; (3) OpenVINOExecutionProvider::default().with_device_type("NPU").build().error_on_failure() to make a failed NPU registration LOUD instead of silently falling back to CPU; (4) Session::run needs &mut session. For shipping, bundle these DLLs with the Tauri app (resource/sidecar) instead of relying on pip. load-dynamic means no C++/OpenVINO build step in cargo.
*Confidence: 1.0 | Status: active | Created: 2026-07-02T20:42:31*
### DirectML support in parakeet-rs for NVIDIA Parakee...
DirectML support in parakeet-rs for NVIDIA Parakeet/EOU/Nemotron models is purely theoretical/unvalidated, not a proven working combination. Evidence: (1) parakeet-rs's own Cargo.toml/execution.rs just forwards to ort's generic directml feature with zero model-specific notes -- contrast with its explicit CoreML warning ('CoreML EP currently runs slower than CPU for Sortformer/Parakeet models because the ONNX graphs have dynamic input shapes'); no equivalent DirectML note exists. (2) Searched all 113 issues in altunenes/parakeet-rs GitHub repo: zero mention DirectML. (3) microsoft/onnxruntime issue #19837 (opened 2024, still unresolved as of check) reports DirectML EP producing wrong numeric results on a model containing LSTM+Einsum ops -- root cause never found. (4) Microsoft's own microsoft/DirectML GitHub repo now carries a banner: DirectML is in maintenance/sustained-engineering mode, with new feature development moved to Windows ML (WinML); relevant since WhispAssist ADR-0004 specifies ort+DirectML for NPU accel. Recommend flagging ADR-0004 for review given this shift.
*Confidence: 0.85 | Status: active | Created: 2026-07-02T20:09:34*
### Rebuilding WhispAssist release binary after Phase ...
Rebuilding WhispAssist release binary after Phase 6: initial 'tauri build' failed with 'only metadata stub found for rlib dependency core' / cannot find crate for std,num_traits (whisper-rs-sys build script, atoi). Root cause: stale/corrupted 19GB target/ dir from a prior interrupted build. Fix: cargo clean in src-tauri, then rebuild clean. Always load vcvars64.bat (VS2022 BuildTools) before cargo/tauri build.
*Confidence: 0.9 | Status: active | Created: 2026-07-01T20:27:51*
### Root cause of WhispAssist release build crashes fo...
Root cause of WhispAssist release build crashes found: NOT toolchain corruption. rustc.exe crashes with STATUS_STACK_BUFFER_OVERRUN (0xc0000409) specifically compiling the windows-rs crate (v0.61.3) and pxfm crate, reproducible under both rustc 1.94.1 and 1.96.1. Root cause is the project's aggressive release profile in src-tauri/Cargo.toml: opt-level='z' + codegen-units=1 + lto=true triggers an LLVM/rustc codegen crash on these large generated crates. Confirmed fix: overriding just opt-level=2, codegen-units=16 via CARGO_PROFILE_RELEASE_OPT_LEVEL/CARGO_PROFILE_RELEASE_CODEGEN_UNITS env vars lets the windows crate compile cleanly in isolation. Earlier 'toolchain corruption' and 'cargo clean' theories were red herrings -- the missing-std/core-prelude errors seen on other crates were a cascade effect of cargo continuing after the crashed crate's .rlib was never written.
*Confidence: 0.9 | Status: active | Created: 2026-07-01T20:40:50*
### WhispAssist recording fix + diagnosis (2026-07-06,...
WhispAssist recording fix + diagnosis (2026-07-06, branch feature_chore_bug_003): User reported new recordings had 'no sound' while old ones played. DIAGNOSED: NOT the 32->16bit change. Proved via ignored hardware test loopback_16bit_wav_captures_played_audio (played Windows Alarm01.wav through default device, captured peak i16=11670) that 16-bit loopback capture records real audio fine. Root cause: the recorded WAV was loopback-only, so a mic-only moment (user talking, nothing playing through speakers) recorded as silence while their voice still reached the transcript. FIX (user chose native-quality): added audio::MicBridge (AtomicU32 rate + Mutex<VecDeque<f32>>, cap ~0.5s for clock-drift): loopback thread publishes its rate + pulls mic samples per-frame and mixes into every channel in write_wav_bytes(mic:&[f32]); mic thread resamples its audio to loopback rate (Resampler::new_to) and pushes to the bridge. New WasapiCapture::start_loopback_recording / start_microphone_recording; commands.rs uses them with a shared bridge when mic enabled. Recording is now native rate/stereo 16-bit WITH the user's voice. Verified by ignored test loopback_recording_with_mic_bridge_captures_played_audio (peak i16=22358). This SUPERSEDES the earlier 'mic transcript-only, not in WAV' limitation.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T23:27:12*
### WhispAssist T3.4 steps 1-3 DONE & validated end-to...
WhispAssist T3.4 steps 1-3 DONE & validated end-to-end: OnnxNpuTranscriber transcribes speech correctly on the Intel NPU. Pipeline: hand-rolled Whisper log-mel (transcription/mel.rs, matches HF WhisperFeatureExtractor) -> NPU encoder (OpenVINO EP) -> CPU greedy decoder (no KV cache, re-feeds prefix) -> hand-rolled byte-BPE detok from tokenizer.json (no tokenizers crate). Behind cargo feature 'npu' = [dep:ort, dep:rustfft]; renamed from the old empty 'directml' feature. Decode config from generation_config.json: decoder_start=50257, eos=50256, forced_decoder_ids=[[1,50362]] (notimestamps); mask token ids >=50257 (except eot) in argmax. TTS test: spoke 'testing one two three four, the quick brown fox...' got 'testing 1234 the quick brown fox jumps over the lazy dog.' All gates green first try (clippy -D, fmt, 69 default tests, 77 npu tests). NOT YET wired into commands.rs dispatch (that is step 6) — nothing routes to it in-app yet.
*Confidence: 1.0 | Status: active | Created: 2026-07-02T21:14:31*
### WhispAssist NPU build gotcha: ort's default downlo...
WhispAssist NPU build gotcha: ort's default download-binaries do NOT include the OpenVINO execution provider. Must supply an ONNX Runtime built with OpenVINO (Intel's prebuilt onnxruntime-openvino) PLUS the OpenVINO runtime DLLs on the DLL path. HARD VERSION PIN: onnxruntime-openvino 1.24.1 requires openvino runtime 2025.4.1 EXACTLY. Version mismatch (e.g. openvino 2026.2) does NOT error loudly — it silently falls back to CPUExecutionProvider (Win Error 127 'procedure could not be found'). Pin the ort<->onnxruntime<->openvino version triple and assert the active provider is OpenVINOExecutionProvider at load, else the NPU is silently unused.
*Confidence: 1.0 | Status: active | Created: 2026-07-02T20:31:10*
### CONFIRMED ROOT CAUSE (2026-07-02) of the WhispAssi...
CONFIRMED ROOT CAUSE (2026-07-02) of the WhispAssist whisper.cpp model-load crash: it is Trend Micro Security Agent (Worry-Free Business Security, corporate-managed -- services ntrtscan/TMBMServer/TmCCSF/tmlisten all running) injecting into whispassist.exe and hooking file I/O / MessageBox APIs. Live cdb attach to the process while the 'Debug Assertion Failed: _osfile(fh) & FOPEN' dialog was showing revealed 'tmmon64' (Trend Micro's monitoring module) sitting directly in the call stack between USER32!MessageBoxW and ucrtbased!__acrt_MessageBoxW, and the read path (whisper.cpp's std::ifstream -> xsgetn -> fread) resolves into ucrtbased.dll (debug CRT) even though whisper-rs-sys's CMakeCache.txt confirms /MD (release CRT) was used to build it -- i.e. Trend Micro's hook is corrupting the CRT call path, not a real build misconfiguration. Ruled out first: NOT a stack-size issue (tried 16MiB worker thread stack, crash identical), NOT stale/corrupted build artifacts (crash reproduces identically from a fully clean cargo clean --profile dev rebuild), NOT Windows Defender (already excluded target/ and C:\Users\dadous\AppData\Local\WhispAssist, crash persisted). Fix requires excluding whispassist.exe / the WhispAssist install and model directories from Trend Micro's real-time scan and behavior monitoring -- likely needs corporate IT/policy admin involvement since TMBMServer implies tamper-protected central management, not a self-service local exclusion like Defender. Tooling note: installed WinDbg Preview via 'winget install --id Microsoft.WinDbg' -- ships cdbX64.exe (classic command-line debugger) alongside the modern WinDbgX.exe GUI, usable for live process attach analysis without needing the full Visual Studio IDE debugger.
*Confidence: 0.95 | Status: active | Created: 2026-07-02T13:30:42*
### Fixed a real bug behind reported 30-65 second live...
Fixed a real bug behind reported 30-65 second live-transcription lag: whisper.cpp's encoder always runs over a full padded 30-second mel window (1500 encoder positions) unless audio_ctx is explicitly reduced via set_audio_ctx. WhispAssist's live-transcription streaming windows are only about 4 seconds each but were never setting audio_ctx, so every window paid the full 30-second-equivalent encode cost, serially, on one worker thread. Fixed in src-tauri/src/transcription/mod.rs (function audio_ctx_for_window) by scaling audio_ctx proportionally to the real window length (1500 positions = 30s, so a 4s window gets about 201). Committed as 8530a22. Verified about 30 percent faster in a controlled A/B benchmark, though that specific test ran under heavy CPU contention from Docker Desktop and other concurrent Claude Code sessions on this machine, which likely masks a larger real-world improvement since the fix targets the encoder O(n^2)-ish attention cost specifically.
*Confidence: 0.9 | Status: active | Created: 2026-07-02T20:14:23*
### WhispAssist dev/test workflow gotchas (2026-07-06)...
WhispAssist dev/test workflow gotchas (2026-07-06): (1) A running 'npm run tauri dev' / whispassist.exe holds the cargo build lock on its target dir — STOP it (Stop-Process -Name whispassist, plus kill the node/cargo/vite procs whose CommandLine matches tauri|whispassist|vite) BEFORE running cargo build/clippy/test or the build blocks on the lock. (2) 'npm run tauri dev' writes output to the Windows console handle, NOT the redirected background-task log file (which stays empty) — confirm the app actually launched via Get-Process whispassist, not by reading the log; it typically appears ~30s after launch. (3) The audio-device tests find_render_device_none_matches_get_default_device and find_render_device_unknown_id_falls_back_exactly_like_none are FLAKY under cargo test (the wasapi get_default_device(Render) COM quirk) — a rerun passes; do NOT chase them as regressions. Loopback/mic hardware smoke tests (loopback_16bit_wav_captures_played_audio, etc.) are #[ignore]'d and run with --ignored.
*Confidence: 0.95 | Status: active | Created: 2026-07-07T01:05:20*
### WhispAssist tooling FOOTGUN (2026-07-06): 'npm run...
WhispAssist tooling FOOTGUN (2026-07-06): 'npm run format' = 'prettier --write .' — it reformats the ENTIRE repo, not just changed files. Running it during a small change reformatted 120+ files (all docs/ADRs/.claude skills/CLAUDE.md/stores/etc) because the repo isn't uniformly prettier-clean, burying the real diff. RECOVERY that worked: git diff --name-only | grep out the intended KEEP files | xargs git checkout -- , then verify only intended files remain; the reformats were content+EOL noise (git diff -w showed EOL-only for many). LESSON: to format/verify only your touched files use 'npx prettier --write <files>' or just 'npm run check' (svelte-check) + 'npx eslint <files>' which don't write. ALSO: 'npm run lint' currently reports ~143 PRE-EXISTING errors (mostly 'console'/'process' is not defined no-undef in node-context files) unrelated to app code — don't be alarmed, they predate any given change. Repo has mixed LF/CRLF (git warns 'LF will be replaced by CRLF'); harmless line-ending churn.
*Confidence: 0.95 | Status: active | Created: 2026-07-06T12:48:15*
### WhispAssist dev-run finding (2026-07-06): 'npm run...
WhispAssist dev-run finding (2026-07-06): 'npm run tauri dev' builds the Rust with features audio,cpu-transcription,diarization,pst,sync,npu = the DEFAULT set MINUS vulkan and cuda. Consequence: the everyday dev/default build has NEITHER a whisper.cpp GPU backend NOR CUDA, so on the Intel Core Ultra + Arc iGPU dev machine the ONLY GPU accel path is DirectML (via the ort/npu feature) — and directml_would_help() returns TRUE there, so the DirectML Settings card is visible. To exercise the Vulkan path you must build with --features vulkan explicitly (see whispassist-vulkan-build-recipe). Incremental dev rebuild ~42s once whisper.cpp/deps are cached; debug binary at src-tauri/target/debug/whispassist.exe. Launch recipe: load vcvars64.bat (VS2022 BuildTools) then 'npm run tauri dev'; the WebView2 window opens on the user's desktop. Opening Settings does NOT trigger the debug-CRT Abort/Retry/Ignore assertion dialog (that only fires on the transcription file-read path), so a UI-only visual check on the debug build is safe.
*Confidence: 0.9 | Status: active | Created: 2026-07-06T12:27:54*
### Windows dev-loop gotchas confirmed again this sess...
Windows dev-loop gotchas confirmed again this session (2026-07-06): (1) Git Bash's quoting of 'cmd.exe /c "...vcvars64.bat" && cargo ...' silently no-ops (just opens/closes an interactive cmd shell) - must run that exact vcvars64.bat wrapper via the PowerShell tool instead, never Bash; (2) both 'cargo fmt' (no path args) and 'npm run format' (prettier --write .) reformat the ENTIRE repo/workspace, not just touched files - this touched unrelated pre-existing files (commands.rs WebDavTarget chain, all of docs/, .claude/skills/, package.json, CLAUDE.md, package-lock.json) and had to be reverted via targeted git checkout, keeping only the intended diff. Going forward: use 'rustfmt --edition 2021 <specific files>' and 'npx prettier --write <specific files>' instead of the whole-repo commands.
*Confidence: 0.95 | Status: active | Created: 2026-07-06T20:40:55*
---
## Observations
*Patterns noticed, behavioral notes, and recurring themes.*
### WhispAssist transcription benchmark (2026-07, rele...
WhispAssist transcription benchmark (2026-07, release 0.1.4, SAME 6.3s TTS clip 'Testing 1234 the quick brown fox...', base.en q5_1 model, full transcribe_file path, machine=Intel Core Ultra 14-thread + Arc iGPU): VULKAN on Intel Arc iGPU = load 274ms, infer ~4.5s (fastest, edges out NPU). NPU OpenVINO = load 1355ms, infer ~5.7s. CPU whisper.cpp = load ~190ms, infer 92-99s (PATHOLOGICAL, ~15x SLOWER than real-time). All three produce the correct transcript. CRITICAL FINDING (user-confirmed): CPU was ALREADY ~90s BEFORE Vulkan was added — so the Vulkan build did NOT regress the CPU path; the 0.1.4 Vulkan build is SAFE to ship (CPU fallback unchanged). The ~90s CPU is a PRE-EXISTING bug in the full transcribe_file path, NOT caused by Vulkan. Vulkan and NPU are ~16-20x faster than the broken CPU path. Note the STREAMING path was already fixed earlier (audio_ctx scaling, commit 8530a22); transcribe_file (single_segment=false, 30s-padded seek loop) is the still-slow one.
*Confidence: 1.0 | Status: active | Created: 2026-07-05T22:04:09*
### Meetily (Zackriya-Solutions/meetily), the competit...
Meetily (Zackriya-Solutions/meetily), the competitor app cited as prior art for Parakeet integration, uses Parakeet only for BATCH/offline transcription via the transcribe-rs crate (built on istupakov's ONNX conversion, per meetily's own README credits) -- not live streaming. Its 'Import & Enhance' feature (post-hoc re-transcription) is the actual use case; no DirectML-specific hardware acceleration for Parakeet is documented in its backend README. A true streaming fork (Nemotron streaming ASR engine) exists only as a community fork (Amitsurya2000/transcribe-rs), not upstream. sherpa-onnx (k2-fsa) also lacks true streaming Parakeet TDT support as of its open issues #2918 and #3573. Checked 2026-07-02, informs WhispAssist NPU/Parakeet research.
*Confidence: 0.85 | Status: active | Created: 2026-07-02T20:09:37*
---
## Artifacts
*Tool outputs, files, reports, and external references.*
### M4.1 (chunked/resumable upload, T9.2 refinement, F...
M4.1 (chunked/resumable upload, T9.2 refinement, FR-SYNC-2/5) SHIPPED 2026-07-07 on branch feature_chore_bug_005 (commits be025bb, 2cc48c9), same day as M4.2/M4.3/M4.4 but a separate prior session. Recordings are now native-quality (~50-100 MB) and the old put() buffered the whole file into memory in one PUT; OneDrive/Graph also caps a single PUT at 250 MB. Fixed by streaming disk-to-network in fixed-size chunks on both sync backends: WebDavTarget::put and OneDriveTarget::put now use tokio::fs::File + BufReader (O(chunk) memory, not O(file size)) for every upload. Files at/below LARGE_FILE_THRESHOLD (8 MiB) still take a single streamed PUT — only large artifacts (.wav recordings) take the chunked path. WebDAV (Nextcloud/ownCloud) implements the chunking-v2 protocol; OneDrive uses Graph's upload-session API. Needed enabling tokio's io-util/net features for AsyncReadExt/AsyncSeekExt/BufReader (separate chore commit be025bb).
*Confidence: 1.0 | Status: active | Created: 2026-07-08T02:27:25*
### WhispAssist calendar/PST recurrence expansion (202...
WhispAssist calendar/PST recurrence expansion (2026-07-06, commits fa8a7f2/6f07f28): expand_rrule in calendar/mod.rs now parses RRULE (DAILY/WEEKLY/MONTHLY/YEARLY, INTERVAL/COUNT/UNTIL/BYDAY/BYMONTHDAY/BYMONTH) and expands each recurring PST event into its own stored row keyed by '{uid}@{ymd}' for dedup, instead of only storing the first occurrence. Rewritten on chrono::Local (promoted from transitive to direct dependency) instead of hand-rolled epoch-day math, because the first version had a real DST bug: it kept a fixed UTC time-of-day per occurrence, so a meeting created in winter (CST) drifted an hour once its weekly recurrence crossed into summer (CDT) - e.g. 16:30 UTC showed correctly as 10:30 in January but wrongly as 11:30 in July. Fix: convert dtstart to local wall-clock once, keep hour/min/sec fixed, re-resolve the UTC offset per occurrence date. Tests assert local wall-clock time is identical across all occurrences (would fail under the old code).
*Confidence: 1.0 | Status: active | Created: 2026-07-06T20:40:48*
### WhispAssist audio-device-selection feature (2026-0...
WhispAssist audio-device-selection feature (2026-07-06, commits bb1d173/8e3e22c/2759a0e/5b28153/1376059/38b9cb2/b8dc5fc): added Settings > Hardware > 'Audio Devices' picker overriding the default 'Default system audio' WASAPI loopback render device. Backend: AudioCapture::start now takes device_id: Option<&str> (Device::get_id() string) instead of always resolving wasapi::get_default_device(&Direction::Render); new find_render_device() enumerates via wasapi::DeviceCollection and falls back to system default if the configured device is gone (same degrade-gracefully spirit as the existing mid-recording reconnect, which now retries the SAME selection first instead of switching to whatever's currently default). New list_render_devices()/list_audio_devices command (wasapi crate already supported enumeration, just was unused until now). Settings.audio_output_device: Option<String>, #[serde(default)] for backward compat. This is playback/render-device-only (loopback capture) -- WhispAssist has no microphone capture path at all (FR-CAP-1), so there is no separate 'input device' setting.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T21:02:52*
### WhispAssist M3 (hosted AI providers) SHIPPED (2026...
WhispAssist M3 (hosted AI providers) SHIPPED (2026-07-07, branch feature_chore_bug_005, merge commit e966181, on top of M1+M2 merge 2582d89). Built by an agent in an isolated git worktree, but that worktree's base snapshot was stale (pre-dated M1/M2 - based on 3038b9d, not the then-current feature_chore_bug_005 HEAD) - a real limitation of this session's worktree isolation mechanism worth remembering: it can silently reuse an earlier repo snapshot rather than the live current branch when a new worktree agent is launched later in the same session. Concretely this meant the M3 agent never saw M1's LlmProvider::complete() trait method addition, so AnthropicProvider::complete() was left as M1's not-yet-implemented stub even though M3 finished summarize/suggest_tags/status for real. Caught this by grepping the worktree for 'fn complete' before merging (found nothing) rather than trusting the agent's done report, then implemented AnthropicProvider::complete_with_key (non-streaming POST to /v1/messages, mirrors suggest_tags_with_key) myself as part of merge reconciliation. Also resolved three merge conflicts: llm/mod.rs (the complete() gap above), and two lucide-icon-import-list conflicts in Settings.svelte/SummaryPanel.svelte (M2 and M3 each added their own icon imports at the same insertion point) - unioned both, verified every icon is actually used before committing. What M3 built: AnthropicProvider real implementation (x-api-key + anthropic-version headers, SSE streaming for summarize, non-streaming for tags/complete), set_llm_provider storing the Anthropic key only in the OS credential store (never settings.json/DB, tested) and adding api.anthropic.com to the egress allowlist only when actually configured, HostedAiBanner.svelte one-time third-party-egress acknowledgment component, active-provider indicator + per-use quick-switch in SummaryPanel. Verified independently end to end on the fully merged M1+M2+M3 tree: cargo test --features mcp = 165 passed/0 failed, clippy clean (default + --features mcp), cargo fmt clean (only the same pre-existing unrelated audio/mod.rs drift as before), svelte-check 0 errors. Lesson for future milestone builds in this repo: after any worktree-isolated agent finishes, grep for the specific trait methods/functions the previous milestone added before trusting 'this builds on M<n-1>' claims - isolation snapshots can silently drift stale mid-session.
*Confidence: 1.0 | Status: active | Created: 2026-07-07T13:16:21*
### WhispAssist meeting title + tags features (2026-07...
WhispAssist meeting title + tags features (2026-07-06, commits 2efe295/e68e888 and 68c32ff/16fcb15): (1) meetings previously had NO way to rename from 'Untitled meeting' anywhere in the UI - added an inline-editable title header above the transcript/notes pane (TranscriptNotes.svelte) backed by a new rename_meeting command; (2) attach_meeting_to_event now also mirrors the linked calendar event's subject onto the meeting's title when it has one, so linking 'Jerry / Daniel - Weekly 1:1' auto-renames the meeting; (3) added a 'Generate tags' feature mirroring 'Generate summary' - new LlmProvider::suggest_tags trait method (implemented for Ollama/OpenAI-compatible/Anthropic-stub), reads the transcript via the same build_prompt assembly, non-streamed, returns 1-8 tags merged into (not replacing) the existing tag list; (4) replaced the old comma-separated text-input tags UI with GitHub-topics-style removable/clickable chips (new shared TagChip.svelte component using existing --accent/--accent-soft tokens) - clicking a chip's label calls meetings.filterByTag() which filters the sidebar meeting list, an 'x' removes it.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T20:40:53*
### WhispAssist Phase 9a increment 1 DONE (branch feat...
WhispAssist Phase 9a increment 1 DONE (branch feature_another_one): WebDAV target management + connection test, validated end-to-end against a live wsgidav server (file physically uploaded via PROPFIND->MKCOL->PUT->HEAD). Added: storage SyncTargetRow CRUD (sqlx FromRow); sync::WebDavTarget real impl; sync::credentials keyring wrapper (service 'WhispAssist-sync', secret keyed by credential_ref, never in DB); TLS enforcement (enforce_transport: https always, http only for LAN+opt-in); commands list/add/update/remove/test_sync_target + set_sync_enabled (take State now); privacy_self_check wired to real targets. Enabled 'sync' in default cargo features. Anonymous targets supported (basic_auth only sent when a secret exists). All gates green: clippy -D, fmt, 74 tests. Local test server: python -m wsgidav.server.server_cli --host 127.0.0.1 --port 8899 --root <dir> --auth anonymous; test env WA_WEBDAV_URL/USER/PASS, run 'cargo test webdav_round_trip -- --ignored'. STILL TODO increment 2: durable queue + pump/backoff + sync_meeting + finalize-hook enqueue + sync://job events + sync_status/retry_sync_job (currently still not_implemented) + Settings sync UI. Increment 3: 9b OAuth (OneDrive/Dropbox/Box). 9c encryption on hold (needs T8.8 vault).
*Confidence: 1.0 | Status: active | Created: 2026-07-03T01:17:19*
### M4.2 (multi-language transcription, T8.7, FR-TRX-4...
M4.2 (multi-language transcription, T8.7, FR-TRX-4) SHIPPED 2026-07-07 on branch feature_chore_bug_005 (large commit chain: 6bc0949 add multilingual/language fields to ModelInfo+Settings, 37a6dd1 multilingual model catalog entries, 7f88101 whisper language catalog for Settings dropdown, 496a8aa wire whisper language param through Transcriber trait, 66d9eff persist requested language at meeting creation, 75ca3df track resolved per-meeting language on RecordingSession, 7490ff5 wire language selection through recording/reprocess/recovery, 34fff3f register list_whisper_languages command, plus a full UI chain (4c00496/4892719/dc969df/e6e995e/7bff392/353d582) for a Settings language picker + per-meeting badge + reprocess override, and a same-day bugfix 40709b2 making resolve_language normalize case-insensitive 'en' matches so the English-only-model guard fires correctly). Delivers: multilingual model option, whisper language param (select/auto-detect), per-meeting language persisted, Settings dropdown + reprocess picker in the UI.
*Confidence: 1.0 | Status: active | Created: 2026-07-08T02:27:34*
### WhispAssist Phase 9a increment 2 DONE: durable upl...
WhispAssist Phase 9a increment 2 DONE: durable upload queue (sync_jobs CRUD, pump w/ backoff, finalize hook, startup pump, sync://job events). 78 tests green. TODO: Upload-now UI. Increment 3: 9b OAuth; 9c on hold.
*Confidence: 1.0 | Status: active | Created: 2026-07-03T02:57:46*
### WhispAssist in-memory recording playback (2026-07-...
WhispAssist in-memory recording playback (2026-07-06, branch feature_chore_bug_003): Replaced the file-based player (which decrypted vault-sealed audio.wav to a plaintext audio.play.wav on disk, weakening encryption-at-rest) with an in-memory custom Tauri protocol. commands::serve_recording backs a registered 'waaudio' uri scheme (URL http://waaudio.localhost/<meeting_id> on Windows): reads audio.wav, vault::open decrypts in RAM, streams audio/wav with Range support (parse_byte_range) for seeking; 404 no file, 403 sealed+locked, path-traversal guarded (id must be alnum/hyphen). recording_playback_path now returns that URL after a cheap sealed-prefix + is_unlocked precheck and deletes stale audio.play.wav. commands::cleanup_playback_temp() sweeps all meetings/*/audio.play.wav at startup (called in lib.rs setup). Removed assetProtocol config + tauri protocol-asset feature + convertFileSrc; CSP media-src now 'self' http://waaudio.localhost. UI <audio> has controlsList=nodownload noplaybackrate + oncontextmenu preventDefault so the decrypted audio can't be saved to disk. Verified: clippy clean, svelte-check clean, full build, startup sweep removed leftover play-temp files.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T23:41:52*
### WhispAssist runtime bundles switched to 7z from re...
WhispAssist runtime bundles switched to 7z from repo raw URLs (2026-07-06, branch chore_debug, commits 27ba4f9/e6f1916). The NPU (OpenVINO) and DirectML runtimes are now downloaded as .7z (LZMA2+BCJ) from gitea RAW paths: NPU=https://git.dou.bet/iamdoubz/WhispAssist/raw/branch/main/runtime/openvino.7z (SHA ca0be9fc52c78ee623b152f790450b3d4020c5a7ebe99d27736455b308782191), DirectML=https://git.dou.bet/iamdoubz/WhispAssist/raw/branch/main/runtime/directml.7z (SHA 34369222fcc1be2e72a957b868b1976a90150ba704a06c9e8992c34ee368926b). REPLACED the zip crate with sevenz-rust2 (pinned 0.7.0 — newer needs rustc>1.77 MSRV; optional + npu-gated). extract_zip_flat -> extract_7z_flat (uses decompress_file_with_extract_fn, flattens basenames — archives nest DLLs under directml/ and openvino/ folders). stage_directml_runtime now defaults to DIRECTML_RUNTIME_URL const (no longer requires WA_DIRECTML_RUNTIME_URL env). Env overrides WA_NPU_RUNTIME_URL / WA_DIRECTML_RUNTIME_URL still honored. sevenz-rust2 0.7.0 confirmed to decode LZMA2+BCJ (has src/bcj/x86.rs); validated by test extract_7z_flat_unpacks_the_directml_bundle (extracts ../runtime/directml.7z, asserts onnxruntime.dll == 17253408 bytes, flattened) — PASSES. clippy -D warnings clean on default/shipped build; 104+ tests green. NOTE: raw URLs point to branch/main, so they only resolve once runtime/openvino.7z + runtime/directml.7z are committed to MAIN. As of now those .7z files are UNTRACKED (left for the user to commit — plain git add vs Git LFS decision; ~27MB total). The old .zip package-registry URL (git.dou.bet/api/packages/.../npu-runtime/...) is retired. archives were created with 7z LZMA2:24m BCJ.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T13:26:14*
### WhispAssist M1 (feature briefs) + M2 (MCP server) ...
WhispAssist M1 (feature briefs) + M2 (MCP server) SHIPPED (2026-07-07, branch feature_chore_bug_005, merge commit 2582d89). Built in parallel by two agents in isolated git worktrees, then merged sequentially (M1 first, ff-merge; M2 second, conflict-merged). M1: Store methods for feature_briefs (insert/list/get_row/set_exposed), LlmProvider::complete() primitive (Ollama+OpenAI-compat), FeatureBriefBuilder distiller (briefs/mod.rs, keyword-overlap grounding), the 4 create/list/get_feature_brief+set_brief_exposed commands, SummaryPanel.svelte UI, golden-transcript tests. M2: mcp module on rmcp (loopback bind + token gate, Streamable HTTP + stdio adapter), 4 tools (list_recent_meetings/get_transcript/get_action_items/get_feature_brief), scope control (none|selected|all), mcp_status/set_mcp_enabled lifecycle (token in OS credential store), disclosure UI + mcp_access_log audit, privacy panel integration. Gated behind an optional mcp Cargo feature. Merge required resolving one real conflict (storage/mod.rs trait+impl interleaving) plus one real cross-branch integration bug: M2's handler.rs called commands::get_feature_brief(id) with the pre-M1 stub arity; fixed by extracting get_feature_brief_core(store, id) shared between the Tauri command and the MCP handler, and wired the previously-stubbed selected-scope exposed-flag check (scope::brief_visible) that M2 had left as a documented KNOWN GAP. Verified independently (not just trusting agent reports): cargo test --features mcp = 154 passed/0 failed, clippy clean (default + --features mcp), cargo fmt clean (only pre-existing unrelated audio/mod.rs drift), svelte-check 0 errors. Known environment gotcha hit repeatedly during verification: whisper-rs-sys native build intermittently fails with MSVC error C1056 'cannot update time date stamp' - Trend Micro AV interference, same class as the previously-recorded model-loading hang; resolved by retrying the build, not a code defect. Also: building in a deeply-nested git worktree path (.claude/worktrees/agent-id/...) can overflow Windows MAX_PATH during whisper.cpp's CMake TryCompile scratch dirs - work around with a short CARGO_TARGET_DIR (e.g. C:/wa-build-x) when testing worktrees directly. M2's one incomplete acceptance item: no compiled end-to-end MCP wire-protocol client test (blocked on an rmcp reqwest-0.13-vs-0.12 version conflict pulling in aws-lc-rs; agent reverted the attempt cleanly rather than leave it unverified) - unit-level loopback-bind-refusal and scope-enforcement tests substitute for now. Next: M3 (hosted AI providers, Anthropic) per user pre-authorization to skip the usage checkpoint and go straight to a scheduled resume.
*Confidence: 1.0 | Status: active | Created: 2026-07-07T06:17:52*
### M4.3 (Dropbox/Box upload targets, T9.10, FR-SYNC-9...
M4.3 (Dropbox/Box upload targets, T9.10, FR-SYNC-9) SHIPPED 2026-07-07 on branch feature_chore_bug_005 (commit 6991c1d), same day as M4.1/M4.2/M4.4 but a separate prior session. Implements DropboxTarget and BoxTarget SyncTarget impls (OAuth PKCE was already wired for both providers). DropboxTarget: path-addressed like OneDrive/WebDAV; create_folder_v2 creates the whole intermediate path in one call; upload-session chunking above LARGE_FILE_THRESHOLD (start/append_v2/finish). BoxTarget: Box addresses items by numeric ID not path, so ensure_dir/exists/put all walk (and lazily create) the folder chain from root ('0') by listing each level's children; always uploads via Box's session API regardless of file size (its session API takes plain PUT bodies, consistent with every other target, needs no new reqwest feature, and Box computes/returns each part's digest so no local hashing needed). Both follow the same documented ceiling as OneDriveTarget's put_chunked (M4.1): the upload-session id lives only for one put() call, not persisted across process restarts — a crash mid-chunked-upload restarts that file's upload from scratch rather than resuming (unlike WebDAV's chunking-v2 which is genuinely resumable).
*Confidence: 1.0 | Status: active | Created: 2026-07-08T02:27:46*
### WhispAssist T3.4 NPU acceleration COMPLETE (steps ...
WhispAssist T3.4 NPU acceleration COMPLETE (steps 1-6, feature_npu branch). Dispatch: commands.rs load_transcriber() routes BackendId::Npu -> OnnxNpuTranscriber (onnx model dir), else whisper.cpp, with graceful CPU fall-through; used by streaming worker and batch reprocess. run_streaming_worker now takes &dyn Transcriber (T: ?Sized). hardware_status returns npu:{present,runtimeReady,modelInstalled}. download_npu_package command + npu://download progress events; startup auto-fetches ONNX model in background if NPU present && model missing. Settings>Hardware shows NPU detected + download indicator. All gates green first try: fmt, clippy default+npu -D warnings, 69 default tests, 77 npu tests, svelte-check 0 errors, eslint. Real NPU inference re-verified post-refactor. KNOWN GAP: OpenVINO runtime staging (stage_npu_runtime) copies DLLs from local dirs in env WA_NPU_RUNTIME_SRC (';'-separated) not a hosted download - no hosted runtime bundle URL yet. Upgrade path: host versioned ORT+OpenVINO bundle, download+unzip into paths::npu_runtime_dir(). Repo frontend NOT prettier-clean (117 files pre-existing); only touched files formatted.
*Confidence: 1.0 | Status: active | Created: 2026-07-02T22:17:13*
### WhispAssist merged single installer (2026-07-06, b...
WhispAssist merged single installer (2026-07-06, branch feature_chore_bug_003): Combined the two installers (13MB default/NPU-DirectML at src-tauri/target vs 67MB Vulkan at C:\wt) into ONE universal Vulkan installer. Verified facts: default exe 13MB imports no vulkan-1.dll (runs anywhere, GPU via runtime DirectML); Vulkan exe 67MB imports vulkan-1.dll at LOAD time (dumpbin) so it won't launch without the loader. Fix (option A = bundle the loader): build.rs stage_vulkan_loader() runs when CARGO_FEATURE_VULKAN set — copies vulkan-1.dll from %VULKAN_SDK%\Bin (fallback C:\Windows\System32) next to the exe (OUT_DIR ancestors nth(3) = target/<profile>, correct under CARGO_TARGET_DIR=C:\wt) AND into src-tauri/ (gitignored) for bundling. New src-tauri/tauri.vulkan.conf.json overlay adds bundle.resources ['vulkan-1.dll']. Release build cmd: npm run tauri build -- --features vulkan --config src-tauri/tauri.vulkan.conf.json (needs VULKAN_SDK, CMAKE_GENERATOR=Ninja, CARGO_TARGET_DIR=C:\wt). VERIFIED end-to-end: built MSI+NSIS 0.1.6; WiX main.wxs shows vulkan-1.dll as a Component in the same install dir as whispassist.exe + sibling DLLs (onnxruntime/sherpa/whispassist_lib), so the loader finds it. DirectML stays hidden when vulkan compiled (directml_would_help returns false). STILL TO TEST BY USER: launch the merged installer on a clean VM with NO vulkan-1.dll / no GPU driver to confirm graceful CPU fallback before retiring the 13MB build.
*Confidence: 1.0 | Status: active | Created: 2026-07-07T00:06:25*
### WhispAssist 5-feature batch (2026-07-06, branch fe...
WhispAssist 5-feature batch (2026-07-06, branch feature_chore_bug_003): (1) Notes single-pane Editor/Preview toggle in TranscriptNotes.svelte (one button flips label Preview<->Editor). (2) Recording playback FR-REC-5: command recording_playback_path decrypts vault-sealed wav to audio.play.wav; enabled tauri protocol-asset feature + assetProtocol scope [$LOCALDATA/WhispAssist/meetings/**] + media-src CSP; SummaryPanel <audio controls> via convertFileSrc. (3) Smaller wav FR-CAP-8: wav_spec_for now forces 16-bit Int at native rate; write_wav_bytes quantizes f32->i16 via f32_to_i16 (clamp*i16::MAX) — halves 205MB->~103MB. Kept native rate (48k), did NOT resample to 44.1k (marginal, needs multichannel resampler in hot path). (4) Cancel recording FR-CAP-9: cancel_recording command stops loopback+mic, joins worker, store.delete_meeting (row+folder), emits recording://state state:cancelled; App.svelte Cancel button with confirm. (5) Live sync progress FR-SYNC-11: sync put() streams body via futures_util::stream::unfold + reqwest wrap_stream + Content-Length, sends incremental (sent,total); upload_job drains on a std thread (throttled 250ms) calling on_progress; pump_sync emits live sync://job; SummaryPanel <progress> bar. All clippy-clean, svelte-check clean, vite+full cargo build pass.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T22:57:29*
### WhispAssist 0.1.6 release build (2026-07-06): Vulk...
WhispAssist 0.1.6 release build (2026-07-06): Vulkan build (npm run tauri build -- --features vulkan; VULKAN_SDK=C:\VulkanSDK\1.4.350.0, CMAKE_GENERATOR=Ninja, CARGO_TARGET_DIR=C:\wt, use QUOTED 'set "VAR=val"' to avoid trailing-space bug). Headline fix vs 0.1.5: keyring windows-native (OS credential store was a no-op mock; sync/AI creds never persisted). Artifacts in C:\wt\release\bundle\: msi\WhispAssist_0.1.6_x64_en-US.msi (27MB, SHA256 ffbe32d9b53f2feaaa4b8a6a858b2f283cc5520b7e77814bc5cf7a41e04b5301), nsis\WhispAssist_0.1.6_x64-setup.exe (8.8MB, SHA256 669147d9578b2644b0838de346dda9ce7edd2b614a18f63ca5f61ffd64c6b526). SHA256SUMS.txt written to C:\wt\release\bundle\. Upload the .msi + -setup.exe + SHA256SUMS.txt; NOT the .7z runtime bundles (hosted in-repo via Git LFS, pulled from /media/branch/main/runtime/). 27MB MSI confirms Vulkan (CPU-only=11MB). Commits since 0.1.5: keyring fix 33c0397, version bump 6a4b832, plus sync-target-edit, Nextcloud server-URL auto-build, dark-theme fixes, About page, 7z runtime download.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T18:14:30*
### WhispAssist 0.1.5 shipped (2026-07-06, branch chor...
WhispAssist 0.1.5 shipped (2026-07-06, branch chore_debug): two UI fixes + version bump, 6 commits (035abb9..0d62416). (1) Settings panel horizontal-scroll/close-button-cutoff FIXED: the tab <nav> in Settings.svelte didn't wrap inside the fixed-width panel (width:min(720px,92vw)), overflowing and pushing the .close (X) button off-edge + adding a horizontal scrollbar. Fix: nav { flex:1 1 auto; min-width:0; flex-wrap:wrap }, header align-items:flex-start, .close flex:0 0 auto. (2) New ABOUT page (Settings ▸ About, Info icon tab): shows version (env!(CARGO_PKG_VERSION)) + build commit hash + a source link to https://git.dou.bet/iamdoubz/WhispAssist. Commit hash baked at build time via build.rs (git rev-parse --short HEAD -> cargo:rustc-env=WA_GIT_HASH, rerun-if-changed=../.git/logs/HEAD). Two new Tauri commands: app_info()->{version,commit}, open_url(url) (validates http(s), Windows-only via 'explorer <url>' — no shell injection, reuses installed toolchain instead of adding tauri-plugin-opener). api.ts got AppInfo type + appInfo()/openUrl() bindings. NOTE the section {#if}/{:else if} chain in Settings.svelte: privacy was the catch-all {:else} — adding an About branch required converting privacy to {:else if section==="privacy"} because {:else if} can't follow {:else}. Version bumped 0.1.4->0.1.5 in package.json, src-tauri/Cargo.toml, src-tauri/tauri.conf.json, Cargo.lock (package-lock.json tracks app version as 0.0.0, untouched). clippy -D warnings + svelte-check + eslint(my files) all clean.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T12:48:09*
### WhispAssist P2 DirectML GREEN end-to-end (2026-07-...
WhispAssist P2 DirectML GREEN end-to-end (2026-07-05): staged Microsoft.ML.OnnxRuntime.DirectML v1.24.1 (EXACT match to the OpenVINO bundle's ORT 1.24.1, from nuget flat-container api.nuget.org/v3-flatcontainer/microsoft.ml.onnxruntime.directml/1.24.1/...nupkg) into %LOCALAPPDATA%/WhispAssist/runtime/directml/ = onnxruntime.dll (17MB, DML EP baked in) + onnxruntime_providers_shared.dll. DirectML.dll NOT in the nuget — the Win11 System32 DirectML.dll (v1.15.5) satisfied it. Ran directml_transcribes_speech spike (no ORT_DYLIB_PATH; ensure_runtime_env pointed ort at runtime/directml/onnxruntime.dll + prepended its dir to PATH): backend=Intel (Arc iGPU via DirectMLExecutionProvider device_id 0), load=1222ms, infer=453ms, transcript='(gentle music)' (test wav was music; non-empty => PASS). So the full P0+P2 DirectML path is proven working on real GPU hardware, infer time on par with Vulkan/NPU. Repro: nuget version MUST be >= the ORT the OpenVINO bundle ships (1.24.x) for ABI/symbol match with ort rc.10. Older DirectML nugets (1.20-1.23) would risk GetProcAddress misses.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T02:30:59*
### WhispAssist sync-target EDIT feature added (2026-0...
WhispAssist sync-target EDIT feature added (2026-07-06, commits 149f2c9/45b2acb/496a337/fb79009). Root cause of the user's Nextcloud auth failure: the saved target's base_url was missing the /remote.php/dav/files/<user>/ path (they entered just the host) -> PROPFIND hit a non-DAV path -> 401. Credentials + app password were CORRECT (verified via curl PROPFIND returning 207 + X-User-Id). The app had NO way to edit a saved target — only add/delete/toggle-enabled — so they couldn't fix the URL. FIX: the backend update_sync_target command + store + api.updateSyncTarget ALREADY existed (was only used by the enable toggle); added the missing UI. Changes: (1) SyncTargetInfo (models.rs + api.ts) gained upload_transcript/notes/summary/recording, trigger_on_finalize, allow_plaintext_lan, encrypt_before_upload + row_to_info populates them (secret still never exposed, FR-SYNC-6); (2) settings.svelte.ts store.updateTarget(); (3) Settings.svelte: per-webdav-target Edit button -> startEdit() loads it into the add-form (secret blank), heading/submit become 'Edit target'/'Save changes', kind tabs hidden during edit, Cancel button. Password left blank on save = keep stored (update only rotates the credential when a non-empty secret is provided). Test-connection in edit mode tests the TYPED values (form has no id) so it needs the password re-entered; the simpler fix-and-save path preserves the secret. Correct Nextcloud WebDAV base_url = https://HOST/remote.php/dav/files/USERNAME/ . clippy + svelte-check + eslint all clean.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T15:41:28*
### WhispAssist 0.1.5 release build (2026-07-06, first...
WhispAssist 0.1.5 release build (2026-07-06, first public release): Vulkan build via 'npm run tauri build -- --features vulkan' with env VULKAN_SDK=C:\VulkanSDK\1.4.350.0, CMAKE_GENERATOR=Ninja (ninja 1.10.2 at C:\Tools\Standalone), CARGO_TARGET_DIR=C:\wt, vcvars64 loaded. GOTCHA that failed the first attempt: cmd 'set CARGO_TARGET_DIR=C:\wt && ...' captured a TRAILING SPACE (C:\wt ) -> 'failed to create directory C:\wt \release'; fix = quoted set: set "CARGO_TARGET_DIR=C:\wt". Artifacts in C:\wt\release\bundle\: msi\WhispAssist_0.1.5_x64_en-US.msi (27MB, SHA256 ed83ad0001c654221f3e5787088d922a1211d2722acbd5c2b4523f4f98c745e6), nsis\WhispAssist_0.1.5_x64-setup.exe (8.8MB, SHA256 dfa3a3acf7e9fdfe6d104527d55f660f0b9c0c1364da0cf665113aad60c61422). SHA256SUMS.txt written to C:\wt\release\bundle\. 27MB MSI size confirms Vulkan (CPU-only was 11MB). Release page should upload: the .msi, the -setup.exe, and SHA256SUMS.txt — NOT the .7z runtime bundles (those are hosted in-repo via Git LFS, pulled on-demand from /media/branch/main/runtime/).
*Confidence: 1.0 | Status: active | Created: 2026-07-06T15:03:01*
### WhispAssist microphone-capture feature FR-CAP-7 (2...
WhispAssist microphone-capture feature FR-CAP-7 (2026-07-06, branch feature_chore_bug_002): WA now optionally captures the user's mic alongside loopback and mixes both 16kHz-mono streams into the single transcription worker via audio::spawn_mixer (Mixer struct sums+clamps aligned samples, forwards survivor when one source stalls/ends). New: WasapiCapture::start_microphone (Direction::Capture, no WAV), audio::list_capture_devices, list_input_devices command, Settings.microphone_enabled(default true)+audio_input_device. capture_loop generalized: wav_path Option, direction param, emit_level only for loopback. RecordingSession.mic_capture Option; stop/pause/resume handle both. Settings>Hardware>Audio Devices got a Microphone picker (Off/Default/devices). Loopback WAV stays byte-accurate native; mic is transcript-only (not in WAV/diarization) - tracked ponytail limitation.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T21:34:29*
### WhispAssist P0+P2 GPU acceleration SHIPPED (2026-0...
WhispAssist P0+P2 GPU acceleration SHIPPED (2026-07-05, branch chore_debug). P0 (2 commits e9567b8,7fe0d87): AccelPath enum {WhisperCpu,WhisperVulkan,WhisperCuda,OnnxOpenVino,OnnxDirectML} + resolve_accel(_with) in hardware/mod.rs = single source of truth; BackendInfo.available now derived from it (DXGI + NPU), closing the no-op-GPU detection gap; load_transcriber drives engine choice from it. 3 new pure resolver unit tests, all green. P2 (DirectML for AMD/Intel non-Vulkan): ort gains 'directml' feature; OnnxNpuTranscriber RENAMED to OnnxTranscriber (file still npu.rs) — load() now picks OpenVINO(NPU) vs DirectML(Amd/Intel, device_id 0) EP by BackendId over the SAME onnx artifacts; ensure_runtime_env takes the runtime dll path; paths::directml_runtime_dir/dll/ready added (C:\Users\dadous\AppData\Local/WhispAssist/runtime/directml/onnxruntime.dll); download_and_extract_runtime parameterized (sha+ready) and reused by new stage_directml_runtime + download_directml_package command (registered in lib.rs); hardware_status reports a directml field. 104 lib tests + clippy -D warnings all green across feature sets. TESTED end-to-end: directml_transcribes_speech spike (ignored test in npu.rs, env WA_DML_MODEL_DIR/WA_DML_TEST_WAV/WA_DML_BACKEND) run with ORT_DYLIB_PATH=the existing OpenVINO onnxruntime.dll -> FAILED as expected with 'GetProcAddress OrtSessionOptionsAppendExecutionProvider_DML failed' = the OpenVINO ORT build has NO DirectML EP. This PROVES the DML dispatch path selects the EP and fails LOUDLY (error_on_failure) instead of silently. REMAINING for a GREEN GPU run: stage a real DirectML-EP onnxruntime.dll (Microsoft.ML.OnnxRuntime.DirectML) into runtime/directml/, VERSION-MATCHED to ort rc.10 / ORT ~1.24.x (OpenVINO bundle is ORT 1.24.1). No hosted DirectML bundle published yet; WA_DIRECTML_RUNTIME_URL env drives download, empty SHA. CUDA (P1) NOT done yet (needs NVIDIA hw/CI).
*Confidence: 0.95 | Status: active | Created: 2026-07-06T00:45:47*
### WhispAssist DirectML Settings toggle WIRED (2026-0...
WhispAssist DirectML Settings toggle WIRED (2026-07-06, branch chore_debug, 4 commits 281ccf0/ceb7e59/1b743da/1b74e0b). Backend: hardware::directml_would_help() (pub, in hardware/mod.rs) = cfg!(feature=npu) && !cfg!(feature=vulkan) && a present AMD/Intel GPU (or NVIDIA when !cfg!(cuda)) via dxgi::enumerate_gpus() presence — gates the card so it stays HIDDEN on the shipping Vulkan build (Vulkan already covers all GPUs) and only shows on CUDA/non-Vulkan builds where a GPU lacks coverage. hardware_status now returns directml:{applicable,runtimeReady,modelInstalled} (mirrors the npu:{} field). Frontend: api.ts HardwareStatus gained directml?:{applicable,runtimeReady,modelInstalled} + api.downloadDirectmlPackage(); Settings.svelte has a 'GPU acceleration (DirectML)' card mirroring the NPU package card (reuses .npu-package CSS), shown when directml.applicable, Ready badge when runtimeReady&&modelInstalled else a Download button -> downloadDirectmlPackage() -> loadHardware(). Progress is await-driven (busy flag), NO % listener — DirectML runtime/model progress still emits on the cosmetic npu://download channel (only 'done' on directml://download). It's a package-DOWNLOAD action, not a persistent on/off toggle; the real 'use this GPU' switch is the existing Preferred-backend dropdown (which now enables AMD/Intel once staged, via the P0 availability fix). clippy -D warnings + svelte-check both clean (fixed a needless_return in directml_would_help by using the cfg-block tail-expression pattern like npu_hardware_present).
*Confidence: 1.0 | Status: active | Created: 2026-07-06T12:27:50*
### WhispAssist release 0.1.4 = first Vulkan-enabled b...
WhispAssist release 0.1.4 = first Vulkan-enabled build. Artifacts: C:\wt\release\bundle\msi\WhispAssist_0.1.4_x64_en-US.msi (27MB), C:\wt\release\bundle\nsis\WhispAssist_0.1.4_x64-setup.exe (8.7MB), C:\wt\release\whispassist.exe (64MB) — sizes jumped from 11MB/4.1MB/13MB (0.1.3 CPU-only) because the Vulkan backend + embedded SPIR-V shaders are statically compiled in. Built via 'npm run tauri build -- --features vulkan' with the [[whispassist-vulkan-build-recipe]] env. REMAINING WIRING GAPS (not yet done): (1) detection-honesty gating — mark GPU backends 'available' only when a vulkan/cuda feature is compiled (cfg!(feature=...)), else best() routes to a no-op GPU; (2) make Vulkan the standing release build flag instead of manual --features vulkan; (3) preferred_backend UI so the user can force Intel GPU (currently best() picks NPU rank-0 over Intel rank-3 on this machine, so the app uses NPU not Vulkan unless overridden).
*Confidence: 1.0 | Status: active | Created: 2026-07-05T22:04:13*
### WhispAssist Nextcloud sync UX overhaul (2026-07-06...
WhispAssist Nextcloud sync UX overhaul (2026-07-06, commits 8f6e804/9c670f9). ROOT CAUSE of user's confusion (dwdoubet@box.dou.bet): they were editing with the password field BLANK. WebDavTarget.test() does PROPFIND on base_url+remote_base_path. Bare host https://box.dou.bet + blank pw -> PROPFIND https://box.dou.bet/WhispAssist = NON-DAV path -> 404 (no auth needed) -> test treats 404 as success -> FALSE 'Connected'. Full DAV URL + blank pw -> real DAV endpoint -> 401 -> 'auth failed'. So bare-host 'Connected' was a false positive. FIX 1: WebDavTarget gained provider_hint field; for nextcloud/owncloud, dav_root() derives origin (scheme+host+port) from base_url and builds {origin}/remote.php/dav/files/{username}/ — so users enter ONLY the server URL (https://box.dou.bet) and the app builds the canonical DAV path; a pasted full path is normalized via origin(). Other providers (seafile /seafdav, synology /dav, cloudreve, generic) still use base_url verbatim. url_for uses dav_root(). FIX 2: test_sync_target — for an EXISTING webdav target (id present), it now builds WebDavTarget from the stored row's credential_ref (STORED password) + applies form overrides (base_url/username/remote_base_path/provider_hint/allow_plaintext_lan), unless the user typed a NEW password (temp cred). So Test works after a URL fix WITHOUT re-entering the password. Frontend: davAutoPath derived (provider is nextcloud/owncloud) drives the Server URL placeholder/hint; testConnection passes id in edit mode. Test nextcloud_builds_dav_path_from_server_url added. Correct Nextcloud username here = dwdoubet, host box.dou.bet. NOTE: their existing saved target may just start working after this (url_for rebuilds path from origin+username) if provider_hint=nextcloud. clippy --all-targets + svelte-check + eslint clean; 13 sync tests pass.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T16:11:14*
---
## Errors
*Failure records, bugs, and lessons learned from mistakes.*
### WhispAssist crash to INVESTIGATE LATER (2026-07-06...
WhispAssist crash to INVESTIGATE LATER (2026-07-06, dev build, branch feature_chore_bug_002): app crashed with exit code 0x80000003 (STATUS_BREAKPOINT) around DirectML use on an Intel GPU. Repro sequence: NPU recording worked fine (mic capture confirmed working); user then switched to test DirectML, downloaded the DirectML components, then hit Record and it crashed — crash may have occurred DURING the component download or immediately after starting recording. Log evidence at crash: WARN 'ONNX engine load failed (model load failed: Error attempting to load symbol OrtSessionOptionsAppendExecutionProvider_DML from dynamic library: GetProcAddress failed); falling back to CPU', then whisper_model_load loading ggml-small.en-q5_1.bin, then process exited 0x80000003. CONFIRMED unrelated to the microphone/mixer feature (FR-CAP-7) — it's in the DirectML/ONNX + whisper model-load path. Suspect: DirectML runtime download/activation or DML EP symbol-load failure interacting with recording start. Next: reproduce by enabling DirectML on Intel GPU + start recording; check GetProcAddress DML symbol load and whether crash is during download vs whisper load.
*Confidence: 0.9 | Status: active | Created: 2026-07-06T21:59:37*
### WhispAssist build gotcha (cost ~1hr this session, ...
WhispAssist build gotcha (cost ~1hr this session, masqueraded as a Node 26 incompatibility): NEVER use PowerShell 'Set-Content -Encoding utf8' on package.json / tauri.conf.json / any JSON or TOML — Windows PowerShell 5.1 writes UTF-8 WITH a BOM. The BOM in package.json breaks vite (fails 'type:module' detection -> 'This package is ESM only but was loaded by require' for @sveltejs/vite-plugin-svelte) AND vitefu (JSON.parse chokes: 'Unexpected token, not valid JSON' -> 'Unable to read package.json'), which fails 'npm run build' / the whole tauri build. Fix: use the Edit tool, or sed, or [System.IO.File]::WriteAllText. Strip an existing BOM with: sed -i '1s/^\xef\xbb\xbf//' file. Node was v26.3.0 at C:\Tools\node but Node was NOT the cause.
*Confidence: 1.0 | Status: active | Created: 2026-07-05T22:04:14*
### Critical recurring issue: WhispAssist debug (dev) ...
Critical recurring issue: WhispAssist debug (dev) builds hang/stall during whisper.cpp model loading on this machine, apparently due to Trend Micro AV behavior-monitoring interfering with ZwWriteVirtualMemory calls made during model load. Confirmed reproducible even in a bare standalone Rust example binary with zero Tauri/webview involvement, so it is specific to whisper.cpp model loading in a debug-profile binary, not the app shell. Release (optimized+stripped) builds do NOT hit this - confirmed by the user and by direct testing. Escalated to IT, unresolved as of 2026-07-02. Workaround: use release builds for real testing/spot-checking; expect dev-mode launches to sometimes hang at model load and need force-killing.
*Confidence: 0.9 | Status: active | Created: 2026-07-02T20:14:14*
### WhispAssist CRITICAL BUG FOUND + FIXED (2026-07-06...
WhispAssist CRITICAL BUG FOUND + FIXED (2026-07-06): the OS credential store was a NO-OP the entire time. keyring 3.x feature-gates its platform backends and they are OFF by default; 'keyring = { version = "3", optional = true }' had NO backend feature, so on Windows keyring silently used its MOCK keystore. The mock does NOT persist across keyring::Entry instances, so credentials::set (Entry A) appeared to succeed while credentials::get (a fresh Entry B, same service+name) always returned NoEntry -> has_secret=false -> no HTTP Basic auth sent -> 401. This broke ALL sync WebDAV auth, and would break MCP/hosted-AI keys + OAuth tokens too (anything via sync::credentials, SERVICE='WhispAssist-sync'). FIX: keyring = { version = "3", optional = true, features = ["windows-native"] } (pulls dep:windows-sys = real Windows Credential Manager). Confirmed: WA_SYNC_TEST_DIAG went from status=401 has_secret=false to status=207 has_secret=true. DIAGNOSIS JOURNEY (Nextcloud box.dou.bet user dwdoubet): symptom 'auth failed'; the user's credentials + full DAV URL were valid (curl PROPFIND 207). Red herrings: (a) earlier the Nextcloud base_url was missing /remote.php/dav/files/<user>/; (b) a bare-host test gave a FALSE 'Connected' because a non-DAV path 404 is treated as success; (c) blank password in edit test. Real root cause was keyring. TOOLING NOTE: diagnosed via temporary tracing::info! logs (WA_SYNC_CMD_DIAG in test_sync_target = has_id+secret_len; WA_SYNC_SET_DIAG in add branch; WA_SYNC_TEST_DIAG in WebDavTarget::test() = url+status+has_secret) read live from the 'npm run tauri dev' output (tracing filter is 'info' in lib.rs). Also learned keyring feature name = windows-native, and the app's tracing default level is info. These temp diagnostics MUST be removed before release.
*Confidence: 1.0 | Status: active | Created: 2026-07-06T18:06:13*
### WhispAssist debug-CRT assertion (found 2026-07 whi...
WhispAssist debug-CRT assertion (found 2026-07 while running the non-vulkan CPU baseline in DEBUG): the whispassist_lib debug test binary throws MSVC Debug Assertion 'Expression: _osfile(fh) & FOPEN' at ucrt read.cpp:381 = a read() on a CLOSED/invalid file handle. It pops a MODAL Abort/Retry/Ignore dialog that HANGS the test (this is what stalled the overnight non-vulkan baseline run for 8 hours). Only fires under the debug CRT (-MDd); the RELEASE 0.1.4 build does NOT assert (release CRT skips the check), so shipping is unaffected — but the underlying 'read on a closed handle' is latent UB worth root-causing. Likely in the transcription file-read path (whisper.cpp model load or our audio read_wav_mono_16k / vault::open passthrough). ADD to the CPU testing round: investigate this handle bug alongside the ~90s transcribe_file slowness (may or may not be related). Workaround to get a clean non-vulkan CPU number: run 'cargo test --release' (no debug CRT dialog), not plain 'cargo test'.
*Confidence: 0.95 | Status: active | Created: 2026-07-05T22:07:51*
---
*End of memory export.*
+78
View File
@@ -0,0 +1,78 @@
# WhispAssist v0.7.4
**Privacy-first, Windows-native meeting assistant — everything on-device, nothing leaves unless you say so.**
A small, focused performance release for **CPU transcription**. If WhispAssist runs the Whisper
engine on your CPU — either because your machine has no usable GPU/NPU, or because you selected
the CPU backend — this update takes it from far-slower-than-real-time to comfortably real-time.
Machines on the NPU or GPU backends are unaffected in behavior and simply pick up a
better-optimized build. Nothing here changes the privacy posture; there are no new downloads.
One universal installer (**MSI** and **NSIS**) covers every machine: **Vulkan** for all GPUs
(NVIDIA/AMD/Intel), the Intel **NPU** (OpenVINO), a **DirectML** fallback, and **CPU**.
---
## ⚡ CPU transcription fixed (up to ~90× faster on hybrid Intel CPUs)
Whisper-on-CPU previously spawned one worker thread per logical CPU. On modern hybrid Intel
processors (P-cores + E-cores + low-power E-cores) the workers synchronize in lock-step, so the
two slow low-power cores stalled *every* step while the remaining threads burned CPU waiting —
transcription ran ~20× slower than real time while looking like it was using the whole machine.
WhispAssist now caps Whisper's CPU decode at **4 threads** (the whisper.cpp upstream default).
Measured on a Core Ultra 5 135U over a 4-minute test corpus, same accuracy:
| | before | after |
|---|---|---|
| Speed vs real time | 20× **slower** | **4.6× faster** (RTF 0.218) |
| CPU cost per second of audio | 232.6 cpu-sec | 0.83 cpu-sec |
Live (streaming) transcription shares this code path and benefits equally. If you want to
experiment, the `WA_WHISPER_THREADS` environment variable overrides the cap.
## 🔧 Native code now built fully optimized
A build-toolchain issue caused the bundled native libraries (including whisper.cpp's CPU
kernels) to be compiled **without compiler optimization**. That's fixed; this release ships
optimized native code across the board. (For CPU transcription the thread fix above is the
dominant win; this one is belt-and-suspenders for everything else.)
---
## 📦 Install
**Requirements:** Windows 10 or 11 (x64). WhispAssist needs **WebView2** (preinstalled on Windows 11;
the installer fetches it on Windows 10). Importing from a file/URL additionally needs **`ffmpeg`**
(and **`yt-dlp`** for URLs) on your PATH — the Import dialog links to both.
1. Download **`WhispAssist_0.7.4_x64_en-US.msi`** (or the NSIS **`WhispAssist_0.7.4_x64-setup.exe`**).
2. Run it and accept the UAC prompt. If SmartScreen appears, choose **More info → Run anyway**.
3. Launch **WhispAssist** from the Start menu.
On first run WA picks the best transcription backend (**NPU → NVIDIA → AMD → Intel → CPU**). It runs
without admin rights, does **not** add itself to startup unless you opt in, and keeps all data under
`%LOCALAPPDATA%\WhispAssist`.
Deploying to many machines? See [`docs/enterprise-deployment.md`](docs/enterprise-deployment.md).
## 🔐 Checksums (SHA-256)
```
5c4e6d6b23a4b404c6fa200b6491e74f143c3a886042dc3bef3c2861168ef17c WhispAssist_0.7.4_x64_en-US.msi
eb2ececff06373e9cbb43ee6455c433c1b88785e9060b68ef7bed193191d9761 WhispAssist_0.7.4_x64-setup.exe
```
Verify after download:
```powershell
Get-FileHash .\WhispAssist_0.7.4_x64_en-US.msi -Algorithm SHA256
```
---
## Privacy, unchanged
Everything optional is **off by default**. With nothing configured, WhispAssist makes **no content
egress at all**. Recording is opt-in; sync/AI credentials live only in the OS credential store; the
MCP server is loopback-only and adds no egress; the deployment file never carries secrets. The
reachable-host allowlist is derived from your settings and enforced in the core.
+4
View File
@@ -0,0 +1,4 @@
contender,file,audio_secs,load_ms,wall_ms,cpu_ms,wer_errors,ref_words,hypothesis
w2-vulkan-base,bank_deposits,61.85,324,1398,765,135,4,"Bank deposits are not securities and are not covered by the securities investor protection corporation. Funds used to purchase or sweep to a bank deposit are SIPC protected until deposited to a program bank at which time funds may be eligible for FDIC insurance. Customers are responsible for monitoring their total deposits at each program bank to determine the extent of available FDIC insurance. Refer to the bank deposit details section which appears later in this statement for information on the banks holding your deposits. If your account was established on the last business day of the month, your statement will not include a bank deposit detailed section. The interest rate below is the interest rate effective for cash balances and your FDIC insured bank deposit suite on the last day of the statement period."
w4-npu-onnx,bank_deposits,61.85,5709,3396,2938,137,4,"Bank deposits are not securities and are not covered by the Securities Investor Protection Corporation. Funds used to purchase or sweep to a bank deposit or SIPC protected until deposited to a program bank at which time funds may be eligible for FDIC insurance. Customers are responsible for monitoring their total deposits at each program bank to determine the extent of available FDIC insurance. Refer to the Bank Deposit D-Tales section, which appears later in this statement for information on the banks holding your deposits. If your account was established on the last business day of the month, your statement will not include a Bank Deposit D-Tales section. The interest rate below is the interest rate effective for cash balances in your FDIC insured bank deposit suite on the last day of the state. period."
p1-parakeet-t4,bank_deposits,61.85,5244,3570,14047,135,4," Bank deposits are not securities and are not covered by the Securities Investor Protection Corporation. Funds used to purchase or sweep to a bank deposit are SIPC protected until deposited to a program bank at which time funds may be eligible for FDIC insurance. Customers are responsible for monitoring their total deposits at each program bank to determine the extent of available FDIC insurance. Refer to the bank deposit details section, which appears later in this statement, for information on the banks holding your deposits. If your account was established on the last business day of the month, your statement will not include a bank deposit detail section. The interest rate below is the interest rate effective for cash balances in your FDIC insured bank deposit suite on the last day of the statement period."
1 contender file audio_secs load_ms wall_ms cpu_ms wer_errors ref_words hypothesis
2 w2-vulkan-base bank_deposits 61.85 324 1398 765 135 4 Bank deposits are not securities and are not covered by the securities investor protection corporation. Funds used to purchase or sweep to a bank deposit are SIPC protected until deposited to a program bank at which time funds may be eligible for FDIC insurance. Customers are responsible for monitoring their total deposits at each program bank to determine the extent of available FDIC insurance. Refer to the bank deposit details section which appears later in this statement for information on the banks holding your deposits. If your account was established on the last business day of the month, your statement will not include a bank deposit detailed section. The interest rate below is the interest rate effective for cash balances and your FDIC insured bank deposit suite on the last day of the statement period.
3 w4-npu-onnx bank_deposits 61.85 5709 3396 2938 137 4 Bank deposits are not securities and are not covered by the Securities Investor Protection Corporation. Funds used to purchase or sweep to a bank deposit or SIPC protected until deposited to a program bank at which time funds may be eligible for FDIC insurance. Customers are responsible for monitoring their total deposits at each program bank to determine the extent of available FDIC insurance. Refer to the Bank Deposit D-Tales section, which appears later in this statement for information on the banks holding your deposits. If your account was established on the last business day of the month, your statement will not include a Bank Deposit D-Tales section. The interest rate below is the interest rate effective for cash balances in your FDIC insured bank deposit suite on the last day of the state. period.
4 p1-parakeet-t4 bank_deposits 61.85 5244 3570 14047 135 4 Bank deposits are not securities and are not covered by the Securities Investor Protection Corporation. Funds used to purchase or sweep to a bank deposit are SIPC protected until deposited to a program bank at which time funds may be eligible for FDIC insurance. Customers are responsible for monitoring their total deposits at each program bank to determine the extent of available FDIC insurance. Refer to the bank deposit details section, which appears later in this statement, for information on the banks holding your deposits. If your account was established on the last business day of the month, your statement will not include a bank deposit detail section. The interest rate below is the interest rate effective for cash balances in your FDIC insured bank deposit suite on the last day of the statement period.
+31
View File
@@ -0,0 +1,31 @@
contender,file,audio_secs,load_ms,wall_ms,cpu_ms,wer_errors,ref_words,hypothesis
w1-cpu-base,1089-134686-0000,10.44,163,2606,8219,1,28,"He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour-fatten sauce."
w1-cpu-base,1089-134686-0001,3.27,163,2111,7469,1,8,"Stuff it into you, his belly counseled him."
w1-cpu-base,1089-134686-0002,6.62,163,2067,7360,0,18,"After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels."
w1-cpu-base,1089-134686-0003,2.68,163,1844,6999,0,7,"Hello Bertie, any good in your mind?"
w1-cpu-base,1089-134686-0004,5.22,163,1941,7250,1,11,"Number 10. Fresh Nelly is waiting on you. Good night husband."
w1-cpu-base,1089-134686-0005,9.63,163,1778,6719,0,22,"The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless pale for weariness."
w1-cpu-base,1089-134686-0006,10.55,163,1860,7000,2,24,"The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail."
w1-cpu-base,1089-134686-0007,4.28,163,1659,6500,0,8,"A cold, lucid indifference reigned in his soul."
w1-cpu-base,1089-134686-0008,6.73,163,1727,6594,1,15,"The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself."
w1-cpu-base,1089-134686-0009,10.57,163,1779,6890,0,27,"At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace."
w1-cpu-base,1089-134686-0010,4.41,163,1673,6547,0,14,"""Well now, Ennis, I declare you have a head and so has my stick."""
w1-cpu-base,1089-134686-0011,12.45,163,1835,7000,2,39,"On Saturday mornings when the so dallity met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses."
w1-cpu-base,1089-134686-0012,11.64,163,1713,6312,0,28,"Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her."
w1-cpu-base,1089-134686-0013,7.92,163,1684,6423,1,25,"If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night."
w1-cpu-base,1089-134686-0014,2.23,163,1573,6155,0,8,"He tried to think how it could be."
w1-cpu-base,1089-134686-0015,5.82,163,1615,6298,0,14,"but the dusk deepening in the schoolroom covered over his thoughts. The bell rang."
w1-cpu-base,1089-134686-0016,3.54,163,1568,6125,1,10,"Then you can ask him questions on the Catechism Daedalus."
w1-cpu-base,1089-134686-0017,8.87,163,1640,6359,0,24,"Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,"
w1-cpu-base,1089-134686-0018,15.72,163,1697,6641,0,41,"It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation."
w1-cpu-base,1089-134686-0019,13.89,163,1713,6593,1,39,"The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state."
w1-cpu-base,1089-134686-0020,16.79,163,1806,6922,0,50,"If a man had stolen a pound in his youth and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune."
w1-cpu-base,1089-134686-0021,6.55,163,1689,6656,1,17,"If a layman in giving baptism poor the water before saying the words is the child baptized."
w1-cpu-base,1089-134686-0022,11.18,163,1651,6470,2,32,"How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?"
w1-cpu-base,1089-134686-0023,13.28,163,1706,6734,0,36,"Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?"
w1-cpu-base,1089-134686-0024,11.65,163,1757,6829,0,30,"If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?"
w1-cpu-base,1089-134686-0025,6.61,163,1618,6280,0,18,"A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question."
w1-cpu-base,1089-134686-0026,4.01,163,1591,6110,0,13,"The rector did not ask for a catechism to hear the lesson from."
w1-cpu-base,1089-134686-0027,2.71,163,1549,5937,0,9,"He clasped his hands on the desk and said,"
w1-cpu-base,1089-134686-0028,7.83,163,1602,6204,2,18,"The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier, whose feast day is Saturday."
w1-cpu-base,1089-134686-0029,4.67,163,1601,6280,0,11,"On Friday, confession will be heard all the afternoon after beads."
1 contender file audio_secs load_ms wall_ms cpu_ms wer_errors ref_words hypothesis
2 w1-cpu-base 1089-134686-0000 10.44 163 2606 8219 1 28 He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour-fatten sauce.
3 w1-cpu-base 1089-134686-0001 3.27 163 2111 7469 1 8 Stuff it into you, his belly counseled him.
4 w1-cpu-base 1089-134686-0002 6.62 163 2067 7360 0 18 After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels.
5 w1-cpu-base 1089-134686-0003 2.68 163 1844 6999 0 7 Hello Bertie, any good in your mind?
6 w1-cpu-base 1089-134686-0004 5.22 163 1941 7250 1 11 Number 10. Fresh Nelly is waiting on you. Good night husband.
7 w1-cpu-base 1089-134686-0005 9.63 163 1778 6719 0 22 The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless pale for weariness.
8 w1-cpu-base 1089-134686-0006 10.55 163 1860 7000 2 24 The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail.
9 w1-cpu-base 1089-134686-0007 4.28 163 1659 6500 0 8 A cold, lucid indifference reigned in his soul.
10 w1-cpu-base 1089-134686-0008 6.73 163 1727 6594 1 15 The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself.
11 w1-cpu-base 1089-134686-0009 10.57 163 1779 6890 0 27 At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace.
12 w1-cpu-base 1089-134686-0010 4.41 163 1673 6547 0 14 "Well now, Ennis, I declare you have a head and so has my stick."
13 w1-cpu-base 1089-134686-0011 12.45 163 1835 7000 2 39 On Saturday mornings when the so dallity met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses.
14 w1-cpu-base 1089-134686-0012 11.64 163 1713 6312 0 28 Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her.
15 w1-cpu-base 1089-134686-0013 7.92 163 1684 6423 1 25 If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night.
16 w1-cpu-base 1089-134686-0014 2.23 163 1573 6155 0 8 He tried to think how it could be.
17 w1-cpu-base 1089-134686-0015 5.82 163 1615 6298 0 14 but the dusk deepening in the schoolroom covered over his thoughts. The bell rang.
18 w1-cpu-base 1089-134686-0016 3.54 163 1568 6125 1 10 Then you can ask him questions on the Catechism Daedalus.
19 w1-cpu-base 1089-134686-0017 8.87 163 1640 6359 0 24 Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,
20 w1-cpu-base 1089-134686-0018 15.72 163 1697 6641 0 41 It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation.
21 w1-cpu-base 1089-134686-0019 13.89 163 1713 6593 1 39 The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state.
22 w1-cpu-base 1089-134686-0020 16.79 163 1806 6922 0 50 If a man had stolen a pound in his youth and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune.
23 w1-cpu-base 1089-134686-0021 6.55 163 1689 6656 1 17 If a layman in giving baptism poor the water before saying the words is the child baptized.
24 w1-cpu-base 1089-134686-0022 11.18 163 1651 6470 2 32 How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?
25 w1-cpu-base 1089-134686-0023 13.28 163 1706 6734 0 36 Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?
26 w1-cpu-base 1089-134686-0024 11.65 163 1757 6829 0 30 If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?
27 w1-cpu-base 1089-134686-0025 6.61 163 1618 6280 0 18 A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question.
28 w1-cpu-base 1089-134686-0026 4.01 163 1591 6110 0 13 The rector did not ask for a catechism to hear the lesson from.
29 w1-cpu-base 1089-134686-0027 2.71 163 1549 5937 0 9 He clasped his hands on the desk and said,
30 w1-cpu-base 1089-134686-0028 7.83 163 1602 6204 2 18 The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier, whose feast day is Saturday.
31 w1-cpu-base 1089-134686-0029 4.67 163 1601 6280 0 11 On Friday, confession will be heard all the afternoon after beads.
+31
View File
@@ -0,0 +1,31 @@
contender,file,audio_secs,load_ms,wall_ms,cpu_ms,wer_errors,ref_words,hypothesis
w1-cpu-base,1089-134686-0000,10.44,112,216077,2510125,1,28,"He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour-fatten sauce."
w1-cpu-base,1089-134686-0001,3.27,112,82717,961829,1,8,"Stuff it into you, his belly counseled him."
w1-cpu-base,1089-134686-0002,6.62,112,148497,1736531,0,18,"After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels."
w1-cpu-base,1089-134686-0003,2.68,112,77434,887500,0,7,"Hello Bertie, any good in your mind?"
w1-cpu-base,1089-134686-0004,5.22,112,99168,1158844,1,11,"Number 10. Fresh Nelly is waiting on you. Good night husband."
w1-cpu-base,1089-134686-0005,9.63,112,167320,1939858,0,22,"The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless pale for weariness."
w1-cpu-base,1089-134686-0006,10.55,112,175803,2025703,2,24,"The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail."
w1-cpu-base,1089-134686-0007,4.28,112,81833,956001,0,8,"A cold, lucid indifference reigned in his soul."
w1-cpu-base,1089-134686-0008,6.73,112,116962,1353344,1,15,"The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself."
w1-cpu-base,1089-134686-0009,10.57,112,194254,2274906,0,27,"At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace."
w1-cpu-base,1089-134686-0010,4.41,112,116123,1357843,0,14,"""Well now, Ennis, I declare you have a head and so has my stick."""
w1-cpu-base,1089-134686-0011,12.45,112,266344,3091765,2,39,"On Saturday mornings when the so dallity met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses."
w1-cpu-base,1089-134686-0012,11.64,112,216072,2501111,0,28,"Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her."
w1-cpu-base,1089-134686-0013,7.92,112,169507,1978264,1,25,"If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night."
w1-cpu-base,1089-134686-0014,2.23,112,70139,820125,0,8,"He tried to think how it could be."
w1-cpu-base,1089-134686-0015,5.82,112,120268,1383735,0,14,"but the dusk deepening in the schoolroom covered over his thoughts. The bell rang."
w1-cpu-base,1089-134686-0016,3.54,112,108330,1241142,1,10,"Then you can ask him questions on the Catechism Daedalus."
w1-cpu-base,1089-134686-0017,8.87,112,194063,2182906,0,24,"Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,"
w1-cpu-base,1089-134686-0018,15.72,112,305117,3388062,0,41,"It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation."
w1-cpu-base,1089-134686-0019,13.89,112,280828,3258859,1,39,"The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state."
w1-cpu-base,1089-134686-0020,16.79,112,341186,3965438,0,50,"If a man had stolen a pound in his youth and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune."
w1-cpu-base,1089-134686-0021,6.55,112,121607,1409156,1,17,"If a layman in giving baptism poor the water before saying the words is the child baptized."
w1-cpu-base,1089-134686-0022,11.18,112,227716,2617797,2,32,"How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?"
w1-cpu-base,1089-134686-0023,13.28,112,242491,2812172,0,36,"Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?"
w1-cpu-base,1089-134686-0024,11.65,112,195153,2262469,0,30,"If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?"
w1-cpu-base,1089-134686-0025,6.61,112,124006,1425344,0,18,"A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question."
w1-cpu-base,1089-134686-0026,4.01,112,111022,1272891,0,13,"The rector did not ask for a catechism to hear the lesson from."
w1-cpu-base,1089-134686-0027,2.71,112,70567,820750,0,9,"He clasped his hands on the desk and said,"
w1-cpu-base,1089-134686-0028,7.83,112,139096,1612905,2,18,"The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier, whose feast day is Saturday."
w1-cpu-base,1089-134686-0029,4.67,112,87495,1024704,0,11,"On Friday, confession will be heard all the afternoon after beads."
1 contender file audio_secs load_ms wall_ms cpu_ms wer_errors ref_words hypothesis
2 w1-cpu-base 1089-134686-0000 10.44 112 216077 2510125 1 28 He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour-fatten sauce.
3 w1-cpu-base 1089-134686-0001 3.27 112 82717 961829 1 8 Stuff it into you, his belly counseled him.
4 w1-cpu-base 1089-134686-0002 6.62 112 148497 1736531 0 18 After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels.
5 w1-cpu-base 1089-134686-0003 2.68 112 77434 887500 0 7 Hello Bertie, any good in your mind?
6 w1-cpu-base 1089-134686-0004 5.22 112 99168 1158844 1 11 Number 10. Fresh Nelly is waiting on you. Good night husband.
7 w1-cpu-base 1089-134686-0005 9.63 112 167320 1939858 0 22 The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless pale for weariness.
8 w1-cpu-base 1089-134686-0006 10.55 112 175803 2025703 2 24 The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail.
9 w1-cpu-base 1089-134686-0007 4.28 112 81833 956001 0 8 A cold, lucid indifference reigned in his soul.
10 w1-cpu-base 1089-134686-0008 6.73 112 116962 1353344 1 15 The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself.
11 w1-cpu-base 1089-134686-0009 10.57 112 194254 2274906 0 27 At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace.
12 w1-cpu-base 1089-134686-0010 4.41 112 116123 1357843 0 14 "Well now, Ennis, I declare you have a head and so has my stick."
13 w1-cpu-base 1089-134686-0011 12.45 112 266344 3091765 2 39 On Saturday mornings when the so dallity met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses.
14 w1-cpu-base 1089-134686-0012 11.64 112 216072 2501111 0 28 Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her.
15 w1-cpu-base 1089-134686-0013 7.92 112 169507 1978264 1 25 If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night.
16 w1-cpu-base 1089-134686-0014 2.23 112 70139 820125 0 8 He tried to think how it could be.
17 w1-cpu-base 1089-134686-0015 5.82 112 120268 1383735 0 14 but the dusk deepening in the schoolroom covered over his thoughts. The bell rang.
18 w1-cpu-base 1089-134686-0016 3.54 112 108330 1241142 1 10 Then you can ask him questions on the Catechism Daedalus.
19 w1-cpu-base 1089-134686-0017 8.87 112 194063 2182906 0 24 Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,
20 w1-cpu-base 1089-134686-0018 15.72 112 305117 3388062 0 41 It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation.
21 w1-cpu-base 1089-134686-0019 13.89 112 280828 3258859 1 39 The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state.
22 w1-cpu-base 1089-134686-0020 16.79 112 341186 3965438 0 50 If a man had stolen a pound in his youth and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune.
23 w1-cpu-base 1089-134686-0021 6.55 112 121607 1409156 1 17 If a layman in giving baptism poor the water before saying the words is the child baptized.
24 w1-cpu-base 1089-134686-0022 11.18 112 227716 2617797 2 32 How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?
25 w1-cpu-base 1089-134686-0023 13.28 112 242491 2812172 0 36 Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?
26 w1-cpu-base 1089-134686-0024 11.65 112 195153 2262469 0 30 If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?
27 w1-cpu-base 1089-134686-0025 6.61 112 124006 1425344 0 18 A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question.
28 w1-cpu-base 1089-134686-0026 4.01 112 111022 1272891 0 13 The rector did not ask for a catechism to hear the lesson from.
29 w1-cpu-base 1089-134686-0027 2.71 112 70567 820750 0 9 He clasped his hands on the desk and said,
30 w1-cpu-base 1089-134686-0028 7.83 112 139096 1612905 2 18 The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier, whose feast day is Saturday.
31 w1-cpu-base 1089-134686-0029 4.67 112 87495 1024704 0 11 On Friday, confession will be heard all the afternoon after beads.
+181
View File
@@ -0,0 +1,181 @@
contender,file,audio_secs,load_ms,wall_ms,cpu_ms,wer_errors,ref_words,hypothesis
w1-cpu-base,1089-134686-0000,10.44,188,235064,2608516,1,28,"He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour-fatten sauce."
w1-cpu-base,1089-134686-0001,3.27,188,82564,917655,1,8,"Stuff it into you, his belly counseled him."
w1-cpu-base,1089-134686-0002,6.62,188,141113,1583500,0,18,"After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels."
w1-cpu-base,1089-134686-0003,2.68,188,73065,818720,0,7,"Hello Bertie, any good in your mind?"
w1-cpu-base,1089-134686-0004,5.22,188,109834,1145937,1,11,"Number 10. Fresh Nelly is waiting on you. Good night husband."
w1-cpu-base,1089-134686-0005,9.63,188,191016,2067515,0,22,"The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless pale for weariness."
w1-cpu-base,1089-134686-0006,10.55,188,229757,2240907,2,24,"The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail."
w1-cpu-base,1089-134686-0007,4.28,188,90484,890719,0,8,"A cold, lucid indifference reigned in his soul."
w1-cpu-base,1089-134686-0008,6.73,188,149468,1484047,1,15,"The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself."
w1-cpu-base,1089-134686-0009,10.57,188,245502,2490203,0,27,"At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace."
w1-cpu-base,1089-134686-0010,4.41,188,138481,1458718,0,14,"""Well now, Ennis, I declare you have a head and so has my stick."""
w1-cpu-base,1089-134686-0011,12.45,188,297210,3179094,2,39,"On Saturday mornings when the so dallity met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses."
w1-cpu-base,1089-134686-0012,11.64,188,213355,2401078,0,28,"Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her."
w1-cpu-base,1089-134686-0013,7.92,188,178175,2032875,1,25,"If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night."
w1-cpu-base,1089-134686-0014,2.23,188,66047,748750,0,8,"He tried to think how it could be."
w1-cpu-base,1089-134686-0015,5.82,188,110044,1269406,0,14,"but the dusk deepening in the schoolroom covered over his thoughts. The bell rang."
w1-cpu-base,1089-134686-0016,3.54,188,88080,1015922,1,10,"Then you can ask him questions on the Catechism Daedalus."
w1-cpu-base,1089-134686-0017,8.87,188,195530,2211422,0,24,"Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,"
w1-cpu-base,1089-134686-0018,15.72,188,264086,3047875,0,41,"It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation."
w1-cpu-base,1089-134686-0019,13.89,188,253612,2945906,1,39,"The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state."
w1-cpu-base,1089-134686-0020,16.79,188,329473,3803813,0,50,"If a man had stolen a pound in his youth and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune."
w1-cpu-base,1089-134686-0021,6.55,188,103520,1196969,1,17,"If a layman in giving baptism poor the water before saying the words is the child baptized."
w1-cpu-base,1089-134686-0022,11.18,188,225421,2617859,2,32,"How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?"
w1-cpu-base,1089-134686-0023,13.28,188,239276,2776860,0,36,"Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?"
w1-cpu-base,1089-134686-0024,11.65,188,185962,2162656,0,30,"If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?"
w1-cpu-base,1089-134686-0025,6.61,188,113562,1311750,0,18,"A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question."
w1-cpu-base,1089-134686-0026,4.01,188,102779,1173296,0,13,"The rector did not ask for a catechism to hear the lesson from."
w1-cpu-base,1089-134686-0027,2.71,188,69835,812876,0,9,"He clasped his hands on the desk and said,"
w1-cpu-base,1089-134686-0028,7.83,188,129944,1503437,2,18,"The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier, whose feast day is Saturday."
w1-cpu-base,1089-134686-0029,4.67,188,86115,1006610,0,11,"On Friday, confession will be heard all the afternoon after beads."
w2-vulkan-base,1089-134686-0000,10.44,248,1388,1375,2,28,"He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered flower-faton sauce."
w2-vulkan-base,1089-134686-0001,3.27,248,491,172,1,8,"Stuff it into you, his belly counseled him."
w2-vulkan-base,1089-134686-0002,6.62,248,771,297,0,18,"After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels."
w2-vulkan-base,1089-134686-0003,2.68,248,546,140,0,7,"Hello Bertie, any good in your mind?"
w2-vulkan-base,1089-134686-0004,5.22,248,371,219,1,11,"Number 10. Fresh Nelly is waiting on you. Good night husband."
w2-vulkan-base,1089-134686-0005,9.63,248,535,375,0,22,"The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless pale for weariness."
w2-vulkan-base,1089-134686-0006,10.55,248,316,141,2,24,"The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail."
w2-vulkan-base,1089-134686-0007,4.28,248,261,125,0,8,"A cold, lucid indifference reigned in his soul."
w2-vulkan-base,1089-134686-0008,6.73,248,423,202,1,15,"The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself."
w2-vulkan-base,1089-134686-0009,10.57,248,525,219,0,27,"At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace."
w2-vulkan-base,1089-134686-0010,4.41,248,268,78,0,14,"""Well now, Ennis, I declare you have a head and so has my stick."""
w2-vulkan-base,1089-134686-0011,12.45,248,390,234,2,39,"On Saturday mornings when the so-dality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses."
w2-vulkan-base,1089-134686-0012,11.64,248,761,375,0,28,"Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her."
w2-vulkan-base,1089-134686-0013,7.92,248,771,344,1,25,"If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night."
w2-vulkan-base,1089-134686-0014,2.23,248,377,126,0,8,"He tried to think how it could be."
w2-vulkan-base,1089-134686-0015,5.82,248,419,108,0,14,"but the dusk deepening in the schoolroom covered over his thoughts. The bell rang."
w2-vulkan-base,1089-134686-0016,3.54,248,252,78,1,10,"Then you can ask him questions on the Catechism Daedalus."
w2-vulkan-base,1089-134686-0017,8.87,248,320,157,0,24,"Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,"
w2-vulkan-base,1089-134686-0018,15.72,248,454,157,0,41,"It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation."
w2-vulkan-base,1089-134686-0019,13.89,248,756,468,1,39,"The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state."
w2-vulkan-base,1089-134686-0020,16.79,248,540,172,0,50,"If a man had stolen a pound in his youth and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune."
w2-vulkan-base,1089-134686-0021,6.55,248,664,234,1,17,"If a layman in giving baptism poor the water before saying the words is the child baptized."
w2-vulkan-base,1089-134686-0022,11.18,248,926,391,2,32,"How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?"
w2-vulkan-base,1089-134686-0023,13.28,248,849,344,0,36,"Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?"
w2-vulkan-base,1089-134686-0024,11.65,248,883,327,0,30,"If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?"
w2-vulkan-base,1089-134686-0025,6.61,248,629,234,0,18,"A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question."
w2-vulkan-base,1089-134686-0026,4.01,248,649,236,0,13,"The rector did not ask for a catechism to hear the lesson from."
w2-vulkan-base,1089-134686-0027,2.71,248,603,186,0,9,"He clasped his hands on the desk and said,"
w2-vulkan-base,1089-134686-0028,7.83,248,590,204,2,18,"The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier, whose feast day is Saturday."
w2-vulkan-base,1089-134686-0029,4.67,248,553,172,0,11,"On Friday, confession will be heard all the afternoon after beads."
w3-vulkan-medium,1089-134686-0000,10.44,724,5211,2187,0,28,"He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick peppered flour-fattened sauce."
w3-vulkan-medium,1089-134686-0001,3.27,724,2691,625,1,8,"""Stuff it into you,"" his belly counseled him."
w3-vulkan-medium,1089-134686-0002,6.62,724,3736,813,0,18,"After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels."
w3-vulkan-medium,1089-134686-0003,2.68,724,1895,484,0,7,"Hello Bertie, any good in your mind?"
w3-vulkan-medium,1089-134686-0004,5.22,724,2074,578,1,11,"Number ten! Fresh Nellie is waiting on you. Good night, husband."
w3-vulkan-medium,1089-134686-0005,9.63,724,2304,656,0,22,"The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless, pale for weariness."
w3-vulkan-medium,1089-134686-0006,10.55,724,2267,641,0,24,"The dull light fell more faintly upon the page whereon another equation began to unfold itself slowly and to spread abroad its widening tail."
w3-vulkan-medium,1089-134686-0007,4.28,724,1917,500,0,8,"A cold lucid indifference reigned in his soul."
w3-vulkan-medium,1089-134686-0008,6.73,724,2074,516,1,15,"The chaos in which his ardor extinguished itself was a cold indifferent knowledge of himself."
w3-vulkan-medium,1089-134686-0009,10.57,724,2433,640,0,27,"At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace."
w3-vulkan-medium,1089-134686-0010,4.41,724,2078,594,0,14,"""Well now, Ennis, I declare you have a head and so has my stick."""
w3-vulkan-medium,1089-134686-0011,12.45,724,2687,735,0,39,"On Saturday mornings when the Sodality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses."
w3-vulkan-medium,1089-134686-0012,11.64,724,2495,718,0,28,"Her eyes seemed to regard him with mild pity; her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her."
w3-vulkan-medium,1089-134686-0013,7.92,724,2318,673,0,25,"If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her knight."
w3-vulkan-medium,1089-134686-0014,2.23,724,1847,453,0,8,"He tried to think how it could be."
w3-vulkan-medium,1089-134686-0015,5.82,724,2144,468,0,14,"but the dusk, deepening in the schoolroom, covered over his thoughts. The bell rang."
w3-vulkan-medium,1089-134686-0016,3.54,724,2009,657,1,10,"Then you can ask him questions on the catechism, Daedalus."
w3-vulkan-medium,1089-134686-0017,8.87,724,2558,874,7,24,"Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Harren checked from time to time by saying, ""I'm not going to do it."""
w3-vulkan-medium,1089-134686-0018,15.72,724,2722,876,0,41,"It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the Church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation."
w3-vulkan-medium,1089-134686-0019,13.89,724,2754,735,1,39,"The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state."
w3-vulkan-medium,1089-134686-0020,16.79,724,3047,1265,0,50,"If a man had stolen a pound in his youth, and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune?"
w3-vulkan-medium,1089-134686-0021,6.55,724,2168,547,0,17,"If a layman, in giving baptism, pour the water before saying the words, ""Is the child baptized?"""
w3-vulkan-medium,1089-134686-0022,11.18,724,2522,687,0,32,"How comes it that while the first beatitude promises the kingdom of heaven to the poor of heart, the second beatitude promises also to the meek that they shall possess the land?"
w3-vulkan-medium,1089-134686-0023,13.28,724,2674,812,0,36,"""Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present body and blood, soul and divinity, in the bread alone and in the wine alone?"""
w3-vulkan-medium,1089-134686-0024,11.65,724,2397,735,0,30,"If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?"
w3-vulkan-medium,1089-134686-0025,6.61,724,2080,578,0,18,"A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question."
w3-vulkan-medium,1089-134686-0026,4.01,724,2033,578,0,13,"The rector did not ask for a catechism to hear the lesson from."
w3-vulkan-medium,1089-134686-0027,2.71,724,2145,515,7,9,"He clasped his hands on the desk and said, ""I'm not going to go to bed."""
w3-vulkan-medium,1089-134686-0028,7.83,724,2140,516,2,18,"The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier whose feast day is Saturday."
w3-vulkan-medium,1089-134686-0029,4.67,724,1954,672,0,11,"On Friday, confession will be heard all the afternoon after beads."
w4-npu-onnx,1089-134686-0000,10.44,4723,975,1062,2,28,"He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered flower-faten sauce."
w4-npu-onnx,1089-134686-0001,3.27,4723,286,189,3,8,"Stuffered into you, his belly counseled him."
w4-npu-onnx,1089-134686-0002,6.62,4723,409,328,0,18,"After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels."
w4-npu-onnx,1089-134686-0003,2.68,4723,262,172,0,7,"Hello Bertie, any good in your mind?"
w4-npu-onnx,1089-134686-0004,5.22,4723,356,265,1,11,"Number 10. Fresh Nelly is waiting on you. Good night, husband."
w4-npu-onnx,1089-134686-0005,9.63,4723,475,422,0,22,"The music came nearer, and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless, pale for weariness."
w4-npu-onnx,1089-134686-0006,10.55,4723,471,390,2,24,"The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail."
w4-npu-onnx,1089-134686-0007,4.28,4723,261,188,0,8,"A cold, lucid indifference reigned in his soul."
w4-npu-onnx,1089-134686-0008,6.73,4723,354,297,1,15,"The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself."
w4-npu-onnx,1089-134686-0009,10.57,4723,524,469,0,27,"At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace."
w4-npu-onnx,1089-134686-0010,4.41,4723,372,296,0,14,"""Well now, Ennis, I declare you have a head, and so has my stick."""
w4-npu-onnx,1089-134686-0011,12.45,4723,682,626,2,39,"On Saturday mornings, when the so-dality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses."
w4-npu-onnx,1089-134686-0012,11.64,4723,558,468,0,28,"Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her."
w4-npu-onnx,1089-134686-0013,7.92,4723,461,376,1,25,"If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night."
w4-npu-onnx,1089-134686-0014,2.23,4723,242,156,0,8,"He tried to think how it could be."
w4-npu-onnx,1089-134686-0015,5.82,4723,339,282,0,14,"but the dusk deepening in the schoolroom covered over his thoughts. The bell rang."
w4-npu-onnx,1089-134686-0016,3.54,4723,338,249,1,10,"Then you can ask him questions on the Catechism Daedalus."
w4-npu-onnx,1089-134686-0017,8.87,4723,491,438,0,24,"Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,"
w4-npu-onnx,1089-134686-0018,15.72,4723,717,624,0,41,"It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation."
w4-npu-onnx,1089-134686-0019,13.89,4723,711,626,1,39,"The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state."
w4-npu-onnx,1089-134686-0020,16.79,4723,869,796,1,50,"If a man had stolen a pound in his youth, and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, were the pound together with the compound interest accruing upon it, or all his huge fortune."
w4-npu-onnx,1089-134686-0021,6.55,4723,368,281,1,17,"If a layman in giving baptism poor the water before saying the words is the child baptized,"
w4-npu-onnx,1089-134686-0022,11.18,4723,593,531,2,32,"How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?"
w4-npu-onnx,1089-134686-0023,13.28,4723,636,547,0,36,"Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?"
w4-npu-onnx,1089-134686-0024,11.65,4723,567,469,0,30,"If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?"
w4-npu-onnx,1089-134686-0025,6.61,4723,371,312,0,18,"A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question."
w4-npu-onnx,1089-134686-0026,4.01,4723,338,266,0,13,"The rector did not ask for a catechism to hear the lesson from."
w4-npu-onnx,1089-134686-0027,2.71,4723,269,203,0,9,"He clasped his hands on the desk and said,"
w4-npu-onnx,1089-134686-0028,7.83,4723,371,298,2,18,"The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier whose feast day is Saturday."
w4-npu-onnx,1089-134686-0029,4.67,4723,296,233,0,11,"On Friday, confession will be heard all the afternoon after beads."
p1-parakeet-t8,1089-134686-0000,10.44,4576,494,4234,0,28," He hoped there would be stew for dinner turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour fattened sauce."
p1-parakeet-t8,1089-134686-0001,3.27,4576,185,1719,0,8," Stuff it into you, his belly counselled him."
p1-parakeet-t8,1089-134686-0002,6.62,4576,332,2797,0,18," After early nightfall the yellow lamps would light up, here and there, the squalid quarter of the brothels."
p1-parakeet-t8,1089-134686-0003,2.68,4576,164,1344,0,7," Hello, Bertie. Any good in your mind?"
p1-parakeet-t8,1089-134686-0004,5.22,4576,229,1844,0,11," Number ten Fresh Nelly is waiting on you. Good night, husband."
p1-parakeet-t8,1089-134686-0005,9.63,4576,379,3172,0,22," The music came nearer and he recalled the words the words of Shelley's fragment upon the moon wandering companionless, pale for weariness."
p1-parakeet-t8,1089-134686-0006,10.55,4576,401,3499,0,24," The dull light fell more faintly upon the page, whereon another equation began to unfold itself slowly and to spread abroad its widening tail."
p1-parakeet-t8,1089-134686-0007,4.28,4576,265,2454,0,8," A cold, lucid indifference reigned in his soul."
p1-parakeet-t8,1089-134686-0008,6.73,4576,336,2875,0,15," The chaos in which his ardour extinguished itself was a cold, indifferent knowledge of himself,"
p1-parakeet-t8,1089-134686-0009,10.57,4576,431,3578,0,27," At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace."
p1-parakeet-t8,1089-134686-0010,4.41,4576,309,2891,0,14," Well now, Ennis, I declare you have a head, and so has my stick"
p1-parakeet-t8,1089-134686-0011,12.45,4576,599,5406,0,39," On Saturday mornings when the sodality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses."
p1-parakeet-t8,1089-134686-0012,11.64,4576,512,4172,0,28," Her eyes seemed to regard him with mild pity her holiness, a strange light glowing faintly upon her frail flesh did not humiliate the sinner who approached her."
p1-parakeet-t8,1089-134686-0013,7.92,4576,318,2671,0,25," If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her knight."
p1-parakeet-t8,1089-134686-0014,2.23,4576,112,860,0,8," He tried to think how it could be"
p1-parakeet-t8,1089-134686-0015,5.82,4576,268,2250,0,14," but the dusk, deepening in the schoolroom, covered over his thoughts. The bell rang"
p1-parakeet-t8,1089-134686-0016,3.54,4576,223,2015,1,10," Then you can ask him questions on the Catechism, Daedalus."
p1-parakeet-t8,1089-134686-0017,8.87,4576,317,2562,0,24," Stephen leaning back and drawing idly on his scribbler, listened to the talk about him, which Heron checked from time to time by saying"
p1-parakeet-t8,1089-134686-0018,15.72,4576,738,6234,0,41," It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the Church, and penetrating into obscure silences only to hear and feel the more deeply his own condemnation."
p1-parakeet-t8,1089-134686-0019,13.89,4576,705,5515,0,39," The sentence of Saint James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state."
p1-parakeet-t8,1089-134686-0020,16.79,4576,764,6156,0,50," If a man had stolen a pound in his youth, and had used that pound to amass a huge fortune, how much was he obliged to give back the pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune?"
p1-parakeet-t8,1089-134686-0021,6.55,4576,308,2437,0,17," If a layman, in giving baptism, pour the water before saying the words, is the child baptized?"
p1-parakeet-t8,1089-134686-0022,11.18,4576,566,4797,0,32," How comes it that while the first Beatitude promises the kingdom of heaven to the poor of heart, the second Beatitude promises also to the meek that they shall possess the land?"
p1-parakeet-t8,1089-134686-0023,13.28,4576,567,4922,0,36," Why was the sacrament of the Eucharist instituted under the two species of bread and wine, if Jesus Christ be present body and blood, soul and divinity, in the bread alone, and in the wine alone?"
p1-parakeet-t8,1089-134686-0024,11.65,4576,458,3719,0,30," If the wine change into vinegar, and the host crumble into corruption, after they have been consecrated, is Jesus Christ still present under their species as God and as man?"
p1-parakeet-t8,1089-134686-0025,6.61,4576,308,2640,0,18," A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question."
p1-parakeet-t8,1089-134686-0026,4.01,4576,238,2406,0,13," The rector did not ask for a catechism to hear the lesson from"
p1-parakeet-t8,1089-134686-0027,2.71,4576,162,1391,0,9," He clasped his hands on the desk and said"
p1-parakeet-t8,1089-134686-0028,7.83,4576,407,3437,1,18," The retreat will begin on Wednesday afternoon in honour of Saint Xavier, whose feast day is Saturday."
p1-parakeet-t8,1089-134686-0029,4.67,4576,209,1798,1,11," On Friday confession will be heard all the afternoon after Bedes."
p1-parakeet-t4,1089-134686-0000,10.44,4552,509,2203,0,28," He hoped there would be stew for dinner turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour fattened sauce."
p1-parakeet-t4,1089-134686-0001,3.27,4552,175,968,0,8," Stuff it into you, his belly counselled him."
p1-parakeet-t4,1089-134686-0002,6.62,4552,347,1640,0,18," After early nightfall the yellow lamps would light up, here and there, the squalid quarter of the brothels."
p1-parakeet-t4,1089-134686-0003,2.68,4552,159,829,0,7," Hello, Bertie. Any good in your mind?"
p1-parakeet-t4,1089-134686-0004,5.22,4552,247,1187,0,11," Number ten Fresh Nelly is waiting on you. Good night, husband."
p1-parakeet-t4,1089-134686-0005,9.63,4552,446,2140,0,22," The music came nearer and he recalled the words the words of Shelley's fragment upon the moon wandering companionless, pale for weariness."
p1-parakeet-t4,1089-134686-0006,10.55,4552,465,2172,0,24," The dull light fell more faintly upon the page, whereon another equation began to unfold itself slowly and to spread abroad its widening tail."
p1-parakeet-t4,1089-134686-0007,4.28,4552,232,1157,0,8," A cold, lucid indifference reigned in his soul."
p1-parakeet-t4,1089-134686-0008,6.73,4552,325,1515,0,15," The chaos in which his ardour extinguished itself was a cold, indifferent knowledge of himself,"
p1-parakeet-t4,1089-134686-0009,10.57,4552,466,2062,0,27," At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace."
p1-parakeet-t4,1089-134686-0010,4.41,4552,210,1140,0,14," Well now, Ennis, I declare you have a head, and so has my stick"
p1-parakeet-t4,1089-134686-0011,12.45,4552,603,2734,0,39," On Saturday mornings when the sodality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses."
p1-parakeet-t4,1089-134686-0012,11.64,4552,532,2422,0,28," Her eyes seemed to regard him with mild pity her holiness, a strange light glowing faintly upon her frail flesh did not humiliate the sinner who approached her."
p1-parakeet-t4,1089-134686-0013,7.92,4552,373,1704,0,25," If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her knight."
p1-parakeet-t4,1089-134686-0014,2.23,4552,133,781,0,8," He tried to think how it could be"
p1-parakeet-t4,1089-134686-0015,5.82,4552,278,1328,0,14," but the dusk, deepening in the schoolroom, covered over his thoughts. The bell rang"
p1-parakeet-t4,1089-134686-0016,3.54,4552,206,1031,1,10," Then you can ask him questions on the Catechism, Daedalus."
p1-parakeet-t4,1089-134686-0017,8.87,4552,448,1984,0,24," Stephen leaning back and drawing idly on his scribbler, listened to the talk about him, which Heron checked from time to time by saying"
p1-parakeet-t4,1089-134686-0018,15.72,4552,764,3359,0,41," It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the Church, and penetrating into obscure silences only to hear and feel the more deeply his own condemnation."
p1-parakeet-t4,1089-134686-0019,13.89,4552,638,2578,0,39," The sentence of Saint James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state."
p1-parakeet-t4,1089-134686-0020,16.79,4552,865,3688,0,50," If a man had stolen a pound in his youth, and had used that pound to amass a huge fortune, how much was he obliged to give back the pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune?"
p1-parakeet-t4,1089-134686-0021,6.55,4552,337,1485,0,17," If a layman, in giving baptism, pour the water before saying the words, is the child baptized?"
p1-parakeet-t4,1089-134686-0022,11.18,4552,514,2296,0,32," How comes it that while the first Beatitude promises the kingdom of heaven to the poor of heart, the second Beatitude promises also to the meek that they shall possess the land?"
p1-parakeet-t4,1089-134686-0023,13.28,4552,609,2688,0,36," Why was the sacrament of the Eucharist instituted under the two species of bread and wine, if Jesus Christ be present body and blood, soul and divinity, in the bread alone, and in the wine alone?"
p1-parakeet-t4,1089-134686-0024,11.65,4552,532,2406,0,30," If the wine change into vinegar, and the host crumble into corruption, after they have been consecrated, is Jesus Christ still present under their species as God and as man?"
p1-parakeet-t4,1089-134686-0025,6.61,4552,360,1734,0,18," A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question."
p1-parakeet-t4,1089-134686-0026,4.01,4552,214,1078,0,13," The rector did not ask for a catechism to hear the lesson from"
p1-parakeet-t4,1089-134686-0027,2.71,4552,153,812,0,9," He clasped his hands on the desk and said"
p1-parakeet-t4,1089-134686-0028,7.83,4552,395,1751,1,18," The retreat will begin on Wednesday afternoon in honour of Saint Xavier, whose feast day is Saturday."
p1-parakeet-t4,1089-134686-0029,4.67,4552,270,1375,1,11," On Friday confession will be heard all the afternoon after Bedes."
1 contender file audio_secs load_ms wall_ms cpu_ms wer_errors ref_words hypothesis
2 w1-cpu-base 1089-134686-0000 10.44 188 235064 2608516 1 28 He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour-fatten sauce.
3 w1-cpu-base 1089-134686-0001 3.27 188 82564 917655 1 8 Stuff it into you, his belly counseled him.
4 w1-cpu-base 1089-134686-0002 6.62 188 141113 1583500 0 18 After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels.
5 w1-cpu-base 1089-134686-0003 2.68 188 73065 818720 0 7 Hello Bertie, any good in your mind?
6 w1-cpu-base 1089-134686-0004 5.22 188 109834 1145937 1 11 Number 10. Fresh Nelly is waiting on you. Good night husband.
7 w1-cpu-base 1089-134686-0005 9.63 188 191016 2067515 0 22 The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless pale for weariness.
8 w1-cpu-base 1089-134686-0006 10.55 188 229757 2240907 2 24 The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail.
9 w1-cpu-base 1089-134686-0007 4.28 188 90484 890719 0 8 A cold, lucid indifference reigned in his soul.
10 w1-cpu-base 1089-134686-0008 6.73 188 149468 1484047 1 15 The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself.
11 w1-cpu-base 1089-134686-0009 10.57 188 245502 2490203 0 27 At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace.
12 w1-cpu-base 1089-134686-0010 4.41 188 138481 1458718 0 14 "Well now, Ennis, I declare you have a head and so has my stick."
13 w1-cpu-base 1089-134686-0011 12.45 188 297210 3179094 2 39 On Saturday mornings when the so dallity met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses.
14 w1-cpu-base 1089-134686-0012 11.64 188 213355 2401078 0 28 Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her.
15 w1-cpu-base 1089-134686-0013 7.92 188 178175 2032875 1 25 If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night.
16 w1-cpu-base 1089-134686-0014 2.23 188 66047 748750 0 8 He tried to think how it could be.
17 w1-cpu-base 1089-134686-0015 5.82 188 110044 1269406 0 14 but the dusk deepening in the schoolroom covered over his thoughts. The bell rang.
18 w1-cpu-base 1089-134686-0016 3.54 188 88080 1015922 1 10 Then you can ask him questions on the Catechism Daedalus.
19 w1-cpu-base 1089-134686-0017 8.87 188 195530 2211422 0 24 Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,
20 w1-cpu-base 1089-134686-0018 15.72 188 264086 3047875 0 41 It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation.
21 w1-cpu-base 1089-134686-0019 13.89 188 253612 2945906 1 39 The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state.
22 w1-cpu-base 1089-134686-0020 16.79 188 329473 3803813 0 50 If a man had stolen a pound in his youth and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune.
23 w1-cpu-base 1089-134686-0021 6.55 188 103520 1196969 1 17 If a layman in giving baptism poor the water before saying the words is the child baptized.
24 w1-cpu-base 1089-134686-0022 11.18 188 225421 2617859 2 32 How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?
25 w1-cpu-base 1089-134686-0023 13.28 188 239276 2776860 0 36 Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?
26 w1-cpu-base 1089-134686-0024 11.65 188 185962 2162656 0 30 If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?
27 w1-cpu-base 1089-134686-0025 6.61 188 113562 1311750 0 18 A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question.
28 w1-cpu-base 1089-134686-0026 4.01 188 102779 1173296 0 13 The rector did not ask for a catechism to hear the lesson from.
29 w1-cpu-base 1089-134686-0027 2.71 188 69835 812876 0 9 He clasped his hands on the desk and said,
30 w1-cpu-base 1089-134686-0028 7.83 188 129944 1503437 2 18 The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier, whose feast day is Saturday.
31 w1-cpu-base 1089-134686-0029 4.67 188 86115 1006610 0 11 On Friday, confession will be heard all the afternoon after beads.
32 w2-vulkan-base 1089-134686-0000 10.44 248 1388 1375 2 28 He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered flower-faton sauce.
33 w2-vulkan-base 1089-134686-0001 3.27 248 491 172 1 8 Stuff it into you, his belly counseled him.
34 w2-vulkan-base 1089-134686-0002 6.62 248 771 297 0 18 After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels.
35 w2-vulkan-base 1089-134686-0003 2.68 248 546 140 0 7 Hello Bertie, any good in your mind?
36 w2-vulkan-base 1089-134686-0004 5.22 248 371 219 1 11 Number 10. Fresh Nelly is waiting on you. Good night husband.
37 w2-vulkan-base 1089-134686-0005 9.63 248 535 375 0 22 The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless pale for weariness.
38 w2-vulkan-base 1089-134686-0006 10.55 248 316 141 2 24 The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail.
39 w2-vulkan-base 1089-134686-0007 4.28 248 261 125 0 8 A cold, lucid indifference reigned in his soul.
40 w2-vulkan-base 1089-134686-0008 6.73 248 423 202 1 15 The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself.
41 w2-vulkan-base 1089-134686-0009 10.57 248 525 219 0 27 At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace.
42 w2-vulkan-base 1089-134686-0010 4.41 248 268 78 0 14 "Well now, Ennis, I declare you have a head and so has my stick."
43 w2-vulkan-base 1089-134686-0011 12.45 248 390 234 2 39 On Saturday mornings when the so-dality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses.
44 w2-vulkan-base 1089-134686-0012 11.64 248 761 375 0 28 Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her.
45 w2-vulkan-base 1089-134686-0013 7.92 248 771 344 1 25 If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night.
46 w2-vulkan-base 1089-134686-0014 2.23 248 377 126 0 8 He tried to think how it could be.
47 w2-vulkan-base 1089-134686-0015 5.82 248 419 108 0 14 but the dusk deepening in the schoolroom covered over his thoughts. The bell rang.
48 w2-vulkan-base 1089-134686-0016 3.54 248 252 78 1 10 Then you can ask him questions on the Catechism Daedalus.
49 w2-vulkan-base 1089-134686-0017 8.87 248 320 157 0 24 Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,
50 w2-vulkan-base 1089-134686-0018 15.72 248 454 157 0 41 It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation.
51 w2-vulkan-base 1089-134686-0019 13.89 248 756 468 1 39 The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state.
52 w2-vulkan-base 1089-134686-0020 16.79 248 540 172 0 50 If a man had stolen a pound in his youth and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune.
53 w2-vulkan-base 1089-134686-0021 6.55 248 664 234 1 17 If a layman in giving baptism poor the water before saying the words is the child baptized.
54 w2-vulkan-base 1089-134686-0022 11.18 248 926 391 2 32 How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?
55 w2-vulkan-base 1089-134686-0023 13.28 248 849 344 0 36 Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?
56 w2-vulkan-base 1089-134686-0024 11.65 248 883 327 0 30 If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?
57 w2-vulkan-base 1089-134686-0025 6.61 248 629 234 0 18 A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question.
58 w2-vulkan-base 1089-134686-0026 4.01 248 649 236 0 13 The rector did not ask for a catechism to hear the lesson from.
59 w2-vulkan-base 1089-134686-0027 2.71 248 603 186 0 9 He clasped his hands on the desk and said,
60 w2-vulkan-base 1089-134686-0028 7.83 248 590 204 2 18 The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier, whose feast day is Saturday.
61 w2-vulkan-base 1089-134686-0029 4.67 248 553 172 0 11 On Friday, confession will be heard all the afternoon after beads.
62 w3-vulkan-medium 1089-134686-0000 10.44 724 5211 2187 0 28 He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick peppered flour-fattened sauce.
63 w3-vulkan-medium 1089-134686-0001 3.27 724 2691 625 1 8 "Stuff it into you," his belly counseled him.
64 w3-vulkan-medium 1089-134686-0002 6.62 724 3736 813 0 18 After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels.
65 w3-vulkan-medium 1089-134686-0003 2.68 724 1895 484 0 7 Hello Bertie, any good in your mind?
66 w3-vulkan-medium 1089-134686-0004 5.22 724 2074 578 1 11 Number ten! Fresh Nellie is waiting on you. Good night, husband.
67 w3-vulkan-medium 1089-134686-0005 9.63 724 2304 656 0 22 The music came nearer and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless, pale for weariness.
68 w3-vulkan-medium 1089-134686-0006 10.55 724 2267 641 0 24 The dull light fell more faintly upon the page whereon another equation began to unfold itself slowly and to spread abroad its widening tail.
69 w3-vulkan-medium 1089-134686-0007 4.28 724 1917 500 0 8 A cold lucid indifference reigned in his soul.
70 w3-vulkan-medium 1089-134686-0008 6.73 724 2074 516 1 15 The chaos in which his ardor extinguished itself was a cold indifferent knowledge of himself.
71 w3-vulkan-medium 1089-134686-0009 10.57 724 2433 640 0 27 At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace.
72 w3-vulkan-medium 1089-134686-0010 4.41 724 2078 594 0 14 "Well now, Ennis, I declare you have a head and so has my stick."
73 w3-vulkan-medium 1089-134686-0011 12.45 724 2687 735 0 39 On Saturday mornings when the Sodality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses.
74 w3-vulkan-medium 1089-134686-0012 11.64 724 2495 718 0 28 Her eyes seemed to regard him with mild pity; her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her.
75 w3-vulkan-medium 1089-134686-0013 7.92 724 2318 673 0 25 If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her knight.
76 w3-vulkan-medium 1089-134686-0014 2.23 724 1847 453 0 8 He tried to think how it could be.
77 w3-vulkan-medium 1089-134686-0015 5.82 724 2144 468 0 14 but the dusk, deepening in the schoolroom, covered over his thoughts. The bell rang.
78 w3-vulkan-medium 1089-134686-0016 3.54 724 2009 657 1 10 Then you can ask him questions on the catechism, Daedalus.
79 w3-vulkan-medium 1089-134686-0017 8.87 724 2558 874 7 24 Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Harren checked from time to time by saying, "I'm not going to do it."
80 w3-vulkan-medium 1089-134686-0018 15.72 724 2722 876 0 41 It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the Church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation.
81 w3-vulkan-medium 1089-134686-0019 13.89 724 2754 735 1 39 The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state.
82 w3-vulkan-medium 1089-134686-0020 16.79 724 3047 1265 0 50 If a man had stolen a pound in his youth, and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune?
83 w3-vulkan-medium 1089-134686-0021 6.55 724 2168 547 0 17 If a layman, in giving baptism, pour the water before saying the words, "Is the child baptized?"
84 w3-vulkan-medium 1089-134686-0022 11.18 724 2522 687 0 32 How comes it that while the first beatitude promises the kingdom of heaven to the poor of heart, the second beatitude promises also to the meek that they shall possess the land?
85 w3-vulkan-medium 1089-134686-0023 13.28 724 2674 812 0 36 "Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present body and blood, soul and divinity, in the bread alone and in the wine alone?"
86 w3-vulkan-medium 1089-134686-0024 11.65 724 2397 735 0 30 If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?
87 w3-vulkan-medium 1089-134686-0025 6.61 724 2080 578 0 18 A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question.
88 w3-vulkan-medium 1089-134686-0026 4.01 724 2033 578 0 13 The rector did not ask for a catechism to hear the lesson from.
89 w3-vulkan-medium 1089-134686-0027 2.71 724 2145 515 7 9 He clasped his hands on the desk and said, "I'm not going to go to bed."
90 w3-vulkan-medium 1089-134686-0028 7.83 724 2140 516 2 18 The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier whose feast day is Saturday.
91 w3-vulkan-medium 1089-134686-0029 4.67 724 1954 672 0 11 On Friday, confession will be heard all the afternoon after beads.
92 w4-npu-onnx 1089-134686-0000 10.44 4723 975 1062 2 28 He hoped there would be stew for dinner, turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered flower-faten sauce.
93 w4-npu-onnx 1089-134686-0001 3.27 4723 286 189 3 8 Stuffered into you, his belly counseled him.
94 w4-npu-onnx 1089-134686-0002 6.62 4723 409 328 0 18 After early nightfall the yellow lamps would light up here and there the squalid quarter of the brothels.
95 w4-npu-onnx 1089-134686-0003 2.68 4723 262 172 0 7 Hello Bertie, any good in your mind?
96 w4-npu-onnx 1089-134686-0004 5.22 4723 356 265 1 11 Number 10. Fresh Nelly is waiting on you. Good night, husband.
97 w4-npu-onnx 1089-134686-0005 9.63 4723 475 422 0 22 The music came nearer, and he recalled the words, the words of Shelley's fragment upon the moon wandering companionless, pale for weariness.
98 w4-npu-onnx 1089-134686-0006 10.55 4723 471 390 2 24 The dull light fell more faintly upon the page, where on another equation began to unfold itself slowly, and to spread abroad its widening tail.
99 w4-npu-onnx 1089-134686-0007 4.28 4723 261 188 0 8 A cold, lucid indifference reigned in his soul.
100 w4-npu-onnx 1089-134686-0008 6.73 4723 354 297 1 15 The chaos in which his order extinguished itself was a cold, indifferent knowledge of himself.
101 w4-npu-onnx 1089-134686-0009 10.57 4723 524 469 0 27 At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace.
102 w4-npu-onnx 1089-134686-0010 4.41 4723 372 296 0 14 "Well now, Ennis, I declare you have a head, and so has my stick."
103 w4-npu-onnx 1089-134686-0011 12.45 4723 682 626 2 39 On Saturday mornings, when the so-dality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses.
104 w4-npu-onnx 1089-134686-0012 11.64 4723 558 468 0 28 Her eyes seemed to regard him with mild pity. Her holiness, a strange light glowing faintly upon her frail flesh, did not humiliate the sinner who approached her.
105 w4-npu-onnx 1089-134686-0013 7.92 4723 461 376 1 25 If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her night.
106 w4-npu-onnx 1089-134686-0014 2.23 4723 242 156 0 8 He tried to think how it could be.
107 w4-npu-onnx 1089-134686-0015 5.82 4723 339 282 0 14 but the dusk deepening in the schoolroom covered over his thoughts. The bell rang.
108 w4-npu-onnx 1089-134686-0016 3.54 4723 338 249 1 10 Then you can ask him questions on the Catechism Daedalus.
109 w4-npu-onnx 1089-134686-0017 8.87 4723 491 438 0 24 Stephen, leaning back and drawing idly on his scribbler, listened to the talk about him which Heron checked from time to time by saying,
110 w4-npu-onnx 1089-134686-0018 15.72 4723 717 624 0 41 It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the church and penetrating into obscure silences only to hear and feel the more deeply his own condemnation.
111 w4-npu-onnx 1089-134686-0019 13.89 4723 711 626 1 39 The sentence of St. James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state.
112 w4-npu-onnx 1089-134686-0020 16.79 4723 869 796 1 50 If a man had stolen a pound in his youth, and had used that pound to amass a huge fortune, how much was he obliged to give back? The pound he had stolen only, were the pound together with the compound interest accruing upon it, or all his huge fortune.
113 w4-npu-onnx 1089-134686-0021 6.55 4723 368 281 1 17 If a layman in giving baptism poor the water before saying the words is the child baptized,
114 w4-npu-onnx 1089-134686-0022 11.18 4723 593 531 2 32 How comes it that while the first beattitude promises the kingdom of heaven to the poor of heart, the second beattitude promises also to the meek that they shall possess the land?
115 w4-npu-onnx 1089-134686-0023 13.28 4723 636 547 0 36 Why was the sacrament of the Eucharist instituted under the two species of bread and wine if Jesus Christ be present, body and blood, soul and divinity in the bread alone and in the wine alone?
116 w4-npu-onnx 1089-134686-0024 11.65 4723 567 469 0 30 If the wine change into vinegar and the host crumble into corruption after they have been consecrated, is Jesus Christ still present under their species as God and as man?
117 w4-npu-onnx 1089-134686-0025 6.61 4723 371 312 0 18 A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question.
118 w4-npu-onnx 1089-134686-0026 4.01 4723 338 266 0 13 The rector did not ask for a catechism to hear the lesson from.
119 w4-npu-onnx 1089-134686-0027 2.71 4723 269 203 0 9 He clasped his hands on the desk and said,
120 w4-npu-onnx 1089-134686-0028 7.83 4723 371 298 2 18 The retreat will begin on Wednesday afternoon in honor of St. Francis Xavier whose feast day is Saturday.
121 w4-npu-onnx 1089-134686-0029 4.67 4723 296 233 0 11 On Friday, confession will be heard all the afternoon after beads.
122 p1-parakeet-t8 1089-134686-0000 10.44 4576 494 4234 0 28 He hoped there would be stew for dinner turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour fattened sauce.
123 p1-parakeet-t8 1089-134686-0001 3.27 4576 185 1719 0 8 Stuff it into you, his belly counselled him.
124 p1-parakeet-t8 1089-134686-0002 6.62 4576 332 2797 0 18 After early nightfall the yellow lamps would light up, here and there, the squalid quarter of the brothels.
125 p1-parakeet-t8 1089-134686-0003 2.68 4576 164 1344 0 7 Hello, Bertie. Any good in your mind?
126 p1-parakeet-t8 1089-134686-0004 5.22 4576 229 1844 0 11 Number ten Fresh Nelly is waiting on you. Good night, husband.
127 p1-parakeet-t8 1089-134686-0005 9.63 4576 379 3172 0 22 The music came nearer and he recalled the words the words of Shelley's fragment upon the moon wandering companionless, pale for weariness.
128 p1-parakeet-t8 1089-134686-0006 10.55 4576 401 3499 0 24 The dull light fell more faintly upon the page, whereon another equation began to unfold itself slowly and to spread abroad its widening tail.
129 p1-parakeet-t8 1089-134686-0007 4.28 4576 265 2454 0 8 A cold, lucid indifference reigned in his soul.
130 p1-parakeet-t8 1089-134686-0008 6.73 4576 336 2875 0 15 The chaos in which his ardour extinguished itself was a cold, indifferent knowledge of himself,
131 p1-parakeet-t8 1089-134686-0009 10.57 4576 431 3578 0 27 At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace.
132 p1-parakeet-t8 1089-134686-0010 4.41 4576 309 2891 0 14 Well now, Ennis, I declare you have a head, and so has my stick
133 p1-parakeet-t8 1089-134686-0011 12.45 4576 599 5406 0 39 On Saturday mornings when the sodality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses.
134 p1-parakeet-t8 1089-134686-0012 11.64 4576 512 4172 0 28 Her eyes seemed to regard him with mild pity her holiness, a strange light glowing faintly upon her frail flesh did not humiliate the sinner who approached her.
135 p1-parakeet-t8 1089-134686-0013 7.92 4576 318 2671 0 25 If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her knight.
136 p1-parakeet-t8 1089-134686-0014 2.23 4576 112 860 0 8 He tried to think how it could be
137 p1-parakeet-t8 1089-134686-0015 5.82 4576 268 2250 0 14 but the dusk, deepening in the schoolroom, covered over his thoughts. The bell rang
138 p1-parakeet-t8 1089-134686-0016 3.54 4576 223 2015 1 10 Then you can ask him questions on the Catechism, Daedalus.
139 p1-parakeet-t8 1089-134686-0017 8.87 4576 317 2562 0 24 Stephen leaning back and drawing idly on his scribbler, listened to the talk about him, which Heron checked from time to time by saying
140 p1-parakeet-t8 1089-134686-0018 15.72 4576 738 6234 0 41 It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the Church, and penetrating into obscure silences only to hear and feel the more deeply his own condemnation.
141 p1-parakeet-t8 1089-134686-0019 13.89 4576 705 5515 0 39 The sentence of Saint James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state.
142 p1-parakeet-t8 1089-134686-0020 16.79 4576 764 6156 0 50 If a man had stolen a pound in his youth, and had used that pound to amass a huge fortune, how much was he obliged to give back the pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune?
143 p1-parakeet-t8 1089-134686-0021 6.55 4576 308 2437 0 17 If a layman, in giving baptism, pour the water before saying the words, is the child baptized?
144 p1-parakeet-t8 1089-134686-0022 11.18 4576 566 4797 0 32 How comes it that while the first Beatitude promises the kingdom of heaven to the poor of heart, the second Beatitude promises also to the meek that they shall possess the land?
145 p1-parakeet-t8 1089-134686-0023 13.28 4576 567 4922 0 36 Why was the sacrament of the Eucharist instituted under the two species of bread and wine, if Jesus Christ be present body and blood, soul and divinity, in the bread alone, and in the wine alone?
146 p1-parakeet-t8 1089-134686-0024 11.65 4576 458 3719 0 30 If the wine change into vinegar, and the host crumble into corruption, after they have been consecrated, is Jesus Christ still present under their species as God and as man?
147 p1-parakeet-t8 1089-134686-0025 6.61 4576 308 2640 0 18 A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question.
148 p1-parakeet-t8 1089-134686-0026 4.01 4576 238 2406 0 13 The rector did not ask for a catechism to hear the lesson from
149 p1-parakeet-t8 1089-134686-0027 2.71 4576 162 1391 0 9 He clasped his hands on the desk and said
150 p1-parakeet-t8 1089-134686-0028 7.83 4576 407 3437 1 18 The retreat will begin on Wednesday afternoon in honour of Saint Xavier, whose feast day is Saturday.
151 p1-parakeet-t8 1089-134686-0029 4.67 4576 209 1798 1 11 On Friday confession will be heard all the afternoon after Bedes.
152 p1-parakeet-t4 1089-134686-0000 10.44 4552 509 2203 0 28 He hoped there would be stew for dinner turnips and carrots and bruised potatoes and fat mutton pieces to be ladled out in thick, peppered, flour fattened sauce.
153 p1-parakeet-t4 1089-134686-0001 3.27 4552 175 968 0 8 Stuff it into you, his belly counselled him.
154 p1-parakeet-t4 1089-134686-0002 6.62 4552 347 1640 0 18 After early nightfall the yellow lamps would light up, here and there, the squalid quarter of the brothels.
155 p1-parakeet-t4 1089-134686-0003 2.68 4552 159 829 0 7 Hello, Bertie. Any good in your mind?
156 p1-parakeet-t4 1089-134686-0004 5.22 4552 247 1187 0 11 Number ten Fresh Nelly is waiting on you. Good night, husband.
157 p1-parakeet-t4 1089-134686-0005 9.63 4552 446 2140 0 22 The music came nearer and he recalled the words the words of Shelley's fragment upon the moon wandering companionless, pale for weariness.
158 p1-parakeet-t4 1089-134686-0006 10.55 4552 465 2172 0 24 The dull light fell more faintly upon the page, whereon another equation began to unfold itself slowly and to spread abroad its widening tail.
159 p1-parakeet-t4 1089-134686-0007 4.28 4552 232 1157 0 8 A cold, lucid indifference reigned in his soul.
160 p1-parakeet-t4 1089-134686-0008 6.73 4552 325 1515 0 15 The chaos in which his ardour extinguished itself was a cold, indifferent knowledge of himself,
161 p1-parakeet-t4 1089-134686-0009 10.57 4552 466 2062 0 27 At most, by an alms given to a beggar whose blessing he fled from, he might hope wearily to win for himself some measure of actual grace.
162 p1-parakeet-t4 1089-134686-0010 4.41 4552 210 1140 0 14 Well now, Ennis, I declare you have a head, and so has my stick
163 p1-parakeet-t4 1089-134686-0011 12.45 4552 603 2734 0 39 On Saturday mornings when the sodality met in the chapel to recite the little office, his place was a cushioned kneeling desk at the right of the altar from which he led his wing of boys through the responses.
164 p1-parakeet-t4 1089-134686-0012 11.64 4552 532 2422 0 28 Her eyes seemed to regard him with mild pity her holiness, a strange light glowing faintly upon her frail flesh did not humiliate the sinner who approached her.
165 p1-parakeet-t4 1089-134686-0013 7.92 4552 373 1704 0 25 If ever he was impelled to cast sin from him and to repent, the impulse that moved him was the wish to be her knight.
166 p1-parakeet-t4 1089-134686-0014 2.23 4552 133 781 0 8 He tried to think how it could be
167 p1-parakeet-t4 1089-134686-0015 5.82 4552 278 1328 0 14 but the dusk, deepening in the schoolroom, covered over his thoughts. The bell rang
168 p1-parakeet-t4 1089-134686-0016 3.54 4552 206 1031 1 10 Then you can ask him questions on the Catechism, Daedalus.
169 p1-parakeet-t4 1089-134686-0017 8.87 4552 448 1984 0 24 Stephen leaning back and drawing idly on his scribbler, listened to the talk about him, which Heron checked from time to time by saying
170 p1-parakeet-t4 1089-134686-0018 15.72 4552 764 3359 0 41 It was strange, too, that he found an arid pleasure in following up to the end the rigid lines of the doctrines of the Church, and penetrating into obscure silences only to hear and feel the more deeply his own condemnation.
171 p1-parakeet-t4 1089-134686-0019 13.89 4552 638 2578 0 39 The sentence of Saint James, which says that he who offends against one commandment becomes guilty of all, had seemed to him first a swollen phrase, until he had begun to grope in the darkness of his own state.
172 p1-parakeet-t4 1089-134686-0020 16.79 4552 865 3688 0 50 If a man had stolen a pound in his youth, and had used that pound to amass a huge fortune, how much was he obliged to give back the pound he had stolen only, or the pound together with the compound interest accruing upon it, or all his huge fortune?
173 p1-parakeet-t4 1089-134686-0021 6.55 4552 337 1485 0 17 If a layman, in giving baptism, pour the water before saying the words, is the child baptized?
174 p1-parakeet-t4 1089-134686-0022 11.18 4552 514 2296 0 32 How comes it that while the first Beatitude promises the kingdom of heaven to the poor of heart, the second Beatitude promises also to the meek that they shall possess the land?
175 p1-parakeet-t4 1089-134686-0023 13.28 4552 609 2688 0 36 Why was the sacrament of the Eucharist instituted under the two species of bread and wine, if Jesus Christ be present body and blood, soul and divinity, in the bread alone, and in the wine alone?
176 p1-parakeet-t4 1089-134686-0024 11.65 4552 532 2406 0 30 If the wine change into vinegar, and the host crumble into corruption, after they have been consecrated, is Jesus Christ still present under their species as God and as man?
177 p1-parakeet-t4 1089-134686-0025 6.61 4552 360 1734 0 18 A gentle kick from the tall boy in the bench behind urged Stephen to ask a difficult question.
178 p1-parakeet-t4 1089-134686-0026 4.01 4552 214 1078 0 13 The rector did not ask for a catechism to hear the lesson from
179 p1-parakeet-t4 1089-134686-0027 2.71 4552 153 812 0 9 He clasped his hands on the desk and said
180 p1-parakeet-t4 1089-134686-0028 7.83 4552 395 1751 1 18 The retreat will begin on Wednesday afternoon in honour of Saint Xavier, whose feast day is Saturday.
181 p1-parakeet-t4 1089-134686-0029 4.67 4552 270 1375 1 11 On Friday confession will be heard all the afternoon after Bedes.
+2
View File
@@ -0,0 +1,2 @@
contender,file,audio_secs,load_ms,wall_ms,cpu_ms,wer_errors,ref_words,hypothesis
p1-parakeet-t8,npu-test,6.92,6863,339,2734,2,16," The quick brown fox jumps over the lazy dog. Wisp assist is testing the neural processing unit."
1 contender file audio_secs load_ms wall_ms cpu_ms wer_errors ref_words hypothesis
2 p1-parakeet-t8 npu-test 6.92 6863 339 2734 2 16 The quick brown fox jumps over the lazy dog. Wisp assist is testing the neural processing unit.
@@ -0,0 +1,148 @@
# Parakeet vs Whisper — default-model bake-off (2026-07-16)
Pre-registered comparison (criteria fixed before any numbers existed — see the plan on branch
`test_parakeet`) between WhispAssist's shipping Whisper `base.en` paths and NVIDIA Parakeet
TDT 0.6B v2, to decide whether the default transcription model should change.
## Provenance
- **Machine:** Intel Core Ultra 5 135U (Meteor Lake: 12C/14T CPU, Intel Arc iGPU, Intel AI Boost
NPU, driver 32.0.100.4724), Windows 11 Pro 26200. App version under test: 0.7.3.
- **Harness:** `src-tauri/examples/asr_bench.rs` — drives the *production* transcribers
(`WhisperTranscriber`, `OnnxTranscriber`) and a sherpa-onnx `TransducerRecognizer`; one
contender per process (clean CPU accounting). WER = word-level Levenshtein after
lowercase/punctuation-strip normalization (self-tested).
- **Corpus:** first 30 LibriSpeech test-clean utterances (241.7 s, 644 reference words), 16 kHz
mono, staged by `scripts/bench/fetch-corpus.ps1`. Live latency: sequential 10 s windows over a
3-minute concatenation (16 windows).
- **Models:** ggml `base.en-q5_1`, `medium.en-q5_0`; WA ONNX `base.en` (merged decoder, encoder
on OpenVINO/NPU + decoder on OpenVINO/GPU — EP confirmed in-run);
`sherpa-onnx-nemo-parakeet-tdt-0.6b-v2-int8` (encoder 652 MB + decoder 7 MB + joiner 2 MB).
- **Raw data:** `bench-results/raw.csv`, `bench-results/raw-w1-novulkan.csv` (committed).
## Results — corpus (accuracy + cost)
| Contender | Engine / device | WER | RTF (wall) | CPU-sec per audio-sec | Load |
|---|---|---|---|---|---|
| W1 base.en (as shipped, 14 thr) | whisper.cpp, CPU | 2.48 % | ⚠ 20.1 | ⚠ 232.6 | 112 ms |
| W1 base.en (thread-cap fix) | whisper.cpp, CPU | 2.48 % | 0.218 | 0.827 | 163 ms |
| W2 base.en | whisper.cpp Vulkan, iGPU | 2.64 % | 0.071 | **0.033** | 248 ms |
| W3 medium.en | whisper.cpp Vulkan, iGPU | 3.26 % | 0.304 | 0.088 | 724 ms |
| W4 base.en (default) | ort ONNX, NPU + iGPU | 3.11 % | 0.058 | 0.049 | ~4.7 s |
| **P1 parakeet int8, t8** | sherpa-onnx, CPU | **0.47 %** | **0.047** | 0.396 | ~4.6 s |
| **P1 parakeet int8, t4** | sherpa-onnx, CPU | **0.47 %** | 0.049 | 0.224 | ~4.6 s |
- **Parakeet: 3 errors in 644 words**, vs 20 for the current default — an **85 % relative WER
improvement** — while also posting the best RTF in the field, on the CPU alone.
- Parakeet at 4 threads costs ≈0.22 CPU-cores sustained (~1.6 % of this machine's 14 threads);
the NPU+iGPU Whisper path costs ≈0.05.
- ✅ **W1 anomaly RESOLVED (2026-07-16 follow-up):** root cause was `n_threads =
available_parallelism()` (14) putting ggml spin-barrier workers on the two slow LP E-cores —
every graph-node barrier waits on the slowest worker while the rest burn CPU. 12 threads is
healthy (RTF 0.200), 14 collapses (RTF ~22). The original suspect (`opt-level = "z"` /
unoptimized ggml) was **disproven**: a verified `/O2` build was equally slow. Fix: default
capped at 4 threads, whisper.cpp's own upstream default (`WA_WHISPER_THREADS` env overrides);
re-run row above — RTF 20.1 → 0.218 (92×), CPU 232.6 → 0.827 (281×), WER identical.
(The build *was* also silently unoptimized — the cmake crate clobbers MSVC `/O2` when no
generator is set; fixed via `CMAKE_GENERATOR=Ninja` in `.cargo/config.toml` as build hygiene,
though it wasn't the bottleneck.) Raw data: `bench-results/raw-w1-fixed.csv`.
- W3 (medium) scoring *worse* than base on this corpus (21 vs 17 errors) is small-sample noise
on clean read speech; treat W3's WER as "≈base" here, not as medium being worse in general.
## Results — live windows (10 s, n=16)
| Contender | p50 | p95 | max |
|---|---|---|---|
| W2 Vulkan base.en | 1055 ms | 3722 ms | 4148 ms |
| W4 NPU+iGPU (default) | 519 ms | 630 ms | 928 ms |
| **P1 parakeet t8 (CPU)** | **450 ms** | **497 ms** | **514 ms** |
All hold real-time; Parakeet is fastest **and** near-flat (64 ms p50→max spread), which would
make the live transcript feel noticeably steadier.
## Evidence sample (file 1089-134686-0000, 10.4 s)
> **Reference:** HE HOPED THERE WOULD BE STEW FOR DINNER TURNIPS AND CARROTS AND BRUISED
> POTATOES AND FAT MUTTON PIECES TO BE LADLED OUT IN THICK PEPPERED FLOUR FATTENED SAUCE
- **W4 (default):** "He hoped there would be stew for dinner, turnips and carrots and bruised
potatoes and fat mutton pieces to be ladled out in thick peppered **flour-fatted** sauce." (2 err)
- **P1 (parakeet):** " He hoped there would be stew for dinner turnips and carrots and bruised
potatoes and fat mutton pieces to be ladled out in thick peppered flour fattened sauce" (0 err)
Note the trade visible even here: Whisper punctuates richly; Parakeet's int8 output carries
casing but **sparse punctuation** — a real consideration for notes.md readability (see
integration costs).
## Qualitative pass — real recording (2026-07-16 follow-up)
`bench-corpus/test_wavs/bank_deposits.wav` (62 s real recording, 48 kHz stereo — financial
disclosure read aloud; downmixed/resampled by the production reader). No reference transcript,
so transcripts were compared by eye; raw hypotheses in `bench-results/raw-qual-bank-deposits.csv`
(its WER column is against a placeholder — ignore it).
- **P1 (parakeet t4):** cleanest of the three — zero audible-word errors, and the **best
punctuation**, including commas around a parenthetical clause ("…the bank deposit details
section, which appears later in this statement, for information…"). The "sparse punctuation"
concern from the LibriSpeech sample did **not** reproduce on this longer real clip.
- **W2 (Vulkan base.en):** near-perfect; one function-word slip ("effective for cash balances
*and* your FDIC insured…" — W4 and P1 both hear "*in* your").
- **W4 (NPU ONNX, shipping default):** worst of the three — "details" → "**D-Tales**" twice,
"are SIPC protected" → "**or** SIPC protected", and a segmentation break at the end
("statement period" → "**state. period.**").
One clip, one speaker, clean audio — directionally consistent with the corpus WERs
(P1 ≥ W2 > W4), and it removes punctuation as an argument against Parakeet. Multi-speaker
crosstalk remains untested.
## Pre-registered criteria, evaluated
| Criterion | Result |
|---|---|
| (a) WER ≥30 % relatively better than W4 | **PASS** — 85 % better (0.47 % vs 3.11 %) |
| (b) CPU rung: beat W1 on WER **and** CPU-seconds | **PASS** — vs the *fixed* W1 (follow-up): 5.3× better WER (0.47 % vs 2.48 %), 3.7× less CPU (0.224 vs 0.827 cpu-sec/audio-sec) |
| (b) NPU rung: accelerator execution or CPU ≤ W4 | **FAIL (strictly)** — 0.224 vs 0.049 CPU-sec/audio-sec; accelerated Parakeet not achieved (below) |
| (c) Live windows hold real-time | **PASS** — best in field, p95 497 ms |
**Phase-4 finding (accelerated Parakeet, timeboxed):** the sherpa route is packaging-blocked —
`sherpa-rs`'s `directml` feature is mutually exclusive with `download-binaries`
(`compile_error!` in `sherpa-rs-sys` 0.6.8), and escaping via `SHERPA_LIB_PATH` + a
version-matched prebuilt DirectML archive would require replacing the base dependency
configuration for the whole branch, with transducer-on-DirectML performance unproven (and a
prior DirectML-on-Intel-GPU crash on record). The genuine route is a TDT decode loop on our own
ort/OpenVINO stack (istupakov-style ONNX exports) — estimated **days, not hours**, and only
worth it if the NPU rung must flip. The `bench-directml` cargo feature + `p2-parakeet-dml`
contender remain in the harness as the documented attempt.
## Recommendation (per hardware rung)
1. **CPU-only machines: change the default to Parakeet TDT 0.6B v2 int8.** Even against the
*fixed* W1 (thread cap, follow-up above) it is ~5× more accurate and 3.7× cheaper in
CPU-seconds at comparable wall RTF. This is the unambiguous win — just no longer by three
orders of magnitude, since the W1 pathology itself is fixed.
2. **NPU+iGPU machines (this machine): the pre-registered rule says keep Whisper-ONNX** —
Parakeet-on-CPU costs 4.6× the CPU of the current near-idle path. The override argument the
numbers support: 0.22 cores is still objectively tiny, and it buys 85 % fewer errors plus the
steadiest live latency. That trade is the user's call, not the benchmark's; if low-CPU stays
the hard constraint, the NPU rung flips only after the ort/OpenVINO TDT work lands.
3. **GPU (Vulkan) machines without NPU:** W2 is the cheapest-CPU option (0.033), but Parakeet's
accuracy gap applies here too — same judgment call as the NPU rung, cheaper to revisit after
the integration items below.
**Integration costs before any default flip** (not solved by this bench): timestamped segments
(sherpa-rs's `transducer` API returns text only; the C API exposes timestamps — small upstream
PR or direct `-sys` call), punctuation restoration (sparse on short LibriSpeech clips, though
the real-recording qualitative pass showed *good* punctuation on longer audio — may be a
non-issue), English-only v2 (v3 is multilingual — the whisper multilingual path must remain for
non-English), a ~660 MB model download, and the model catalog/dispatch work (same shape as the
0.7.3 merged-decoder swap).
## Caveats
- LibriSpeech is clean read speech; WERs are comparative, not absolute product claims. The
qualitative pass over a real recording was run as a follow-up (section above) — still
single-speaker; multi-speaker meeting audio with crosstalk remains untested.
- int8 quantization slightly penalizes Parakeet vs published fp32 figures — it *still* won by
85 %; the fp32 bundle exists if a tighter number is ever needed.
- Single machine, single run per cell (30 files each). Differences here are far larger than
run-to-run noise, but treat third-decimal RTF differences as noise.
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "whispassist",
"private": true,
"version": "0.7.3",
"version": "0.7.4",
"type": "module",
"description": "Privacy-first, fully local Windows meeting assistant.",
"license": "MIT OR Apache-2.0",
+24
View File
@@ -0,0 +1,24 @@
# Best-effort system-counter capture alongside a bench run: total CPU utility
# + GPU compute-engine utilization (and NPU engines where the OS exposes them;
# absent counters are skipped by typeperf). Primary CPU metric remains the
# harness's in-process CPU-seconds — this is corroborating evidence.
param(
[string]$Out = "bench-results\counters.csv",
[int]$Seconds = 120
)
$ErrorActionPreference = "Stop"
New-Item -ItemType Directory -Force (Split-Path -Parent $Out) | Out-Null
$counters = @(
"\Processor Information(_Total)\% Processor Utility",
"\GPU Engine(*engtype_Compute)\Utilization Percentage",
"\NPU Engine(*)\Utilization Percentage"
)
# typeperf exits nonzero if ANY counter is invalid; probe each and keep the valid ones.
$valid = @()
foreach ($c in $counters) {
typeperf $c -sc 1 | Out-Null
if ($LASTEXITCODE -eq 0) { $valid += $c }
}
if ($valid.Count -eq 0) { throw "no usable counters on this machine" }
typeperf $valid -si 1 -sc $Seconds -f CSV -o $Out -y | Out-Null
Write-Output "captured $($valid.Count) counter set(s) for ${Seconds}s -> $Out"
+47
View File
@@ -0,0 +1,47 @@
# Stages the WER corpus for asr_bench: the first N LibriSpeech test-clean
# utterances as 16 kHz mono WAV + one reference .txt each, under bench-corpus\
# at the repo root (git-ignored — audio never enters the repo).
param([int]$Utterances = 30)
$ErrorActionPreference = "Stop"
if (-not (Get-Command ffmpeg -ErrorAction SilentlyContinue)) {
throw "ffmpeg is required on PATH (same requirement as the app's Import feature)"
}
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$corpus = Join-Path $repo "bench-corpus"
$cache = "$env:LOCALAPPDATA\WhispAssist\models\bench-cache"
New-Item -ItemType Directory -Force $corpus, $cache | Out-Null
$tarball = Join-Path $cache "test-clean.tar.gz"
if (-not (Test-Path $tarball)) {
Write-Output "downloading LibriSpeech test-clean (~346 MB)"
curl.exe -sL -o "$tarball.part" "https://www.openslr.org/resources/12/test-clean.tar.gz"
if ($LASTEXITCODE -ne 0) { throw "download failed ($LASTEXITCODE)" }
Move-Item -Force "$tarball.part" $tarball
}
$extracted = Join-Path $cache "LibriSpeech\test-clean"
if (-not (Test-Path $extracted)) {
Write-Output "extracting"
tar -xzf $tarball -C $cache
if ($LASTEXITCODE -ne 0) { throw "extract failed ($LASTEXITCODE)" }
}
$flacs = Get-ChildItem -Recurse -Filter *.flac $extracted | Sort-Object FullName |
Select-Object -First $Utterances
foreach ($f in $flacs) {
$name = $f.BaseName
$wav = Join-Path $corpus "$name.wav"
if (-not (Test-Path $wav)) {
ffmpeg -v error -y -i $f.FullName -ar 16000 -ac 1 $wav
if ($LASTEXITCODE -ne 0) { throw "ffmpeg failed on $name" }
}
$trans = Get-ChildItem -Path $f.DirectoryName -Filter *.trans.txt | Select-Object -First 1
$line = Get-Content $trans.FullName | Where-Object { $_.StartsWith("$name ") } | Select-Object -First 1
if (-not $line) { throw "no reference line for $name" }
# Named parameters on purpose: positional binding alongside -NoNewline
# silently wrote nothing under Windows PowerShell 5.1 (found the hard way);
# the WER normalizer doesn't care about a trailing newline.
Set-Content -Path (Join-Path $corpus "$name.txt") -Value $line.Substring($name.Length + 1) -Encoding utf8
}
Write-Output "staged $($flacs.Count) utterances in $corpus"
+25
View File
@@ -0,0 +1,25 @@
# Stages the Parakeet TDT 0.6B v2 int8 bundle (sherpa-onnx export) for the
# asr_bench harness (test_parakeet branch). Bench-only artifact: lives next to
# the app's models but under bench-parakeet\, never read by the app itself.
$ErrorActionPreference = "Stop"
$dest = "$env:LOCALAPPDATA\WhispAssist\models\bench-parakeet"
$url = "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-nemo-parakeet-tdt-0.6b-v2-int8.tar.bz2"
$cache = "$env:LOCALAPPDATA\WhispAssist\models\bench-cache"
New-Item -ItemType Directory -Force $cache | Out-Null
$archive = Join-Path $cache "parakeet-tdt-0.6b-v2-int8.tar.bz2"
if (Test-Path (Join-Path $dest "tokens.txt")) {
Write-Output "already staged: $dest"
exit 0
}
if (-not (Test-Path $archive)) {
Write-Output "downloading $url"
curl.exe -sL -o "$archive.part" $url
if ($LASTEXITCODE -ne 0) { throw "download failed ($LASTEXITCODE)" }
Move-Item -Force "$archive.part" $archive
}
New-Item -ItemType Directory -Force $dest | Out-Null
tar -xjf $archive -C $dest --strip-components=1
if ($LASTEXITCODE -ne 0) { throw "extract failed ($LASTEXITCODE)" }
Get-ChildItem $dest | Select-Object Name, Length
Write-Output "staged: $dest"
+22
View File
@@ -0,0 +1,22 @@
# Runs the full pre-registered contender matrix sequentially (one process per
# contender — clean CPU accounting, no runtime co-tenancy), then the live-window
# latency runs on the realistic live rungs.
$ErrorActionPreference = "Continue"
$repo = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
Set-Location $repo
$exe = "C:\wt\release\examples\asr_bench.exe"
$live = "bench-corpus\test_wavs\live-concat.wav"
$contenders = @(
"w1-cpu-base", "w2-vulkan-base", "w3-vulkan-medium",
"w4-npu-onnx", "p1-parakeet-t8", "p1-parakeet-t4"
)
foreach ($c in $contenders) {
Write-Output "===== corpus: $c ====="
& $exe $c --corpus bench-corpus --out bench-results\raw.csv 2>&1
}
foreach ($c in @("w2-vulkan-base", "w4-npu-onnx", "p1-parakeet-t8")) {
Write-Output "===== live: $c ====="
& $exe $c --live $live 2>&1
}
Write-Output "===== matrix done ====="
+1 -1
View File
@@ -6088,7 +6088,7 @@ dependencies = [
[[package]]
name = "whispassist"
version = "0.7.3"
version = "0.7.4"
dependencies = [
"argon2",
"async-trait",
+5 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "whispassist"
version = "0.7.3"
version = "0.7.4"
description = "Privacy-first, fully local Windows meeting assistant"
authors = ["WhispAssist contributors"]
license = "MIT OR Apache-2.0"
@@ -126,6 +126,10 @@ diarization = ["dep:sherpa-rs"] # sherpa-onnx
pst = [] # shells out to readpst (libpst) — no crate dep, see ADR-0008 update
# Phase 9
sync = ["dep:keyring"] # remote upload (WebDAV + OAuth providers)
# Bench-only (test_parakeet branch): DirectML-enabled sherpa-onnx binaries so
# asr_bench's P2 contender can try Parakeet on the iGPU. NEVER a default
# feature — it swaps the sherpa runtime the whole binary links against.
bench-directml = ["sherpa-rs?/directml"]
# Phase 10
mcp = [
"dep:rmcp", "dep:keyring", "dep:hyper", "dep:hyper-util",
+418
View File
@@ -0,0 +1,418 @@
//! ASR bench harness — the Parakeet-vs-Whisper bake-off (test_parakeet branch).
//!
//! Drives the *production* transcribers (`WhisperTranscriber`, `OnnxTranscriber`)
//! plus a sherpa-onnx `TransducerRecognizer` (Parakeet TDT) over a shared corpus,
//! and reports WER / RTF / process-CPU-seconds per contender. One contender per
//! process invocation, deliberately: (1) process CPU time then measures exactly
//! one engine, and (2) the ort crate (OpenVINO runtime) and sherpa's bundled
//! onnxruntime never coexist in one address space.
//!
//! Usage:
//! asr_bench <contender> [--corpus DIR] [--out CSV]
//! asr_bench <contender> --live WAV # sequential 10 s window latency
//! asr_bench --self-test # WER scorer assertions
//!
//! Contenders: w1-cpu-base | w2-vulkan-base | w3-vulkan-medium | w4-npu-onnx |
//! p1-parakeet-t<N> (N = sherpa num_threads)
//!
//! Corpus layout: {name}.wav (16 kHz mono) + {name}.txt reference per utterance
//! (staged by scripts/bench/fetch-corpus.ps1).
use std::io::Write as _;
use std::path::{Path, PathBuf};
use std::time::Instant;
use whispassist_lib::audio::read_wav_mono_16k;
use whispassist_lib::models::BackendId;
use whispassist_lib::paths;
use whispassist_lib::transcription::{
onnx_models, AudioWindow, OnnxTranscriber, Transcriber, WhisperTranscriber,
};
const WINDOW_SECS: usize = 10;
const SAMPLE_RATE: usize = 16_000;
// ---- process CPU time (kernel + user) via GetProcessTimes — no crate
// features needed, kernel32 is always linked on Windows. ----
#[cfg(windows)]
mod cputime {
#[repr(C)]
#[derive(Default, Clone, Copy)]
struct Filetime {
lo: u32,
hi: u32,
}
extern "system" {
fn GetCurrentProcess() -> isize;
fn GetProcessTimes(
h: isize,
creation: *mut Filetime,
exit: *mut Filetime,
kernel: *mut Filetime,
user: *mut Filetime,
) -> i32;
}
/// Cumulative process CPU time in milliseconds.
pub fn process_cpu_ms() -> u64 {
let (mut c, mut e, mut k, mut u) = (
Filetime::default(),
Filetime::default(),
Filetime::default(),
Filetime::default(),
);
// SAFETY: pseudo-handle + four valid out-pointers, per the API contract.
let ok = unsafe { GetProcessTimes(GetCurrentProcess(), &mut c, &mut e, &mut k, &mut u) };
if ok == 0 {
return 0;
}
let ms = |f: Filetime| (((f.hi as u64) << 32) | f.lo as u64) / 10_000; // 100 ns units
ms(k) + ms(u)
}
}
#[cfg(not(windows))]
mod cputime {
pub fn process_cpu_ms() -> u64 {
0
}
}
// ---- WER ----
/// Lowercase, strip everything but alphanumerics/apostrophes, split to words —
/// LibriSpeech references are uppercase without punctuation; hypotheses carry
/// casing + punctuation, so both sides normalize through here.
fn normalize(s: &str) -> Vec<String> {
s.to_lowercase()
.chars()
.map(|c| {
if c.is_alphanumeric() || c == '\'' {
c
} else {
' '
}
})
.collect::<String>()
.split_whitespace()
.map(str::to_string)
.collect()
}
/// Word-level Levenshtein distance (two-row DP).
fn edit_distance(a: &[String], b: &[String]) -> usize {
let mut prev: Vec<usize> = (0..=b.len()).collect();
let mut cur = vec![0usize; b.len() + 1];
for (i, wa) in a.iter().enumerate() {
cur[0] = i + 1;
for (j, wb) in b.iter().enumerate() {
let sub = prev[j] + usize::from(wa != wb);
cur[j + 1] = sub.min(prev[j + 1] + 1).min(cur[j] + 1);
}
std::mem::swap(&mut prev, &mut cur);
}
prev[b.len()]
}
fn self_test() {
assert_eq!(edit_distance(&normalize("a b c"), &normalize("a b c")), 0);
assert_eq!(edit_distance(&normalize("a b c"), &normalize("a x c")), 1); // sub
assert_eq!(edit_distance(&normalize("a b c"), &normalize("a c")), 1); // del
assert_eq!(edit_distance(&normalize("a c"), &normalize("a b c")), 1); // ins
assert_eq!(
normalize("The QUICK, brown-fox's."),
vec!["the", "quick", "brown", "fox's"]
);
assert!(edit_distance(&normalize("hello world"), &normalize("")) == 2);
println!("self-test OK");
}
// ---- engines ----
// ponytail: one Engine per process for its whole lifetime — variant size skew is irrelevant.
#[allow(clippy::large_enum_variant)]
enum Engine {
Whisper(WhisperTranscriber),
Onnx(OnnxTranscriber),
Parakeet(std::sync::Mutex<sherpa_rs::transducer::TransducerRecognizer>),
}
impl Engine {
fn transcribe_wav(&self, wav: &Path) -> Result<String, String> {
match self {
Engine::Whisper(t) => Ok(join_segments(
t.transcribe_file(wav).map_err(|e| e.to_string())?,
)),
Engine::Onnx(t) => Ok(join_segments(
t.transcribe_file(wav).map_err(|e| e.to_string())?,
)),
Engine::Parakeet(r) => {
let samples = read_wav_mono_16k(wav).map_err(|e| e.to_string())?;
Ok(r.lock()
.map_err(|_| "poisoned".to_string())?
.transcribe(SAMPLE_RATE as u32, &samples))
}
}
}
/// One live window; returns the wall time only (text is discarded — this
/// mode measures latency, corpus mode measures accuracy).
fn time_window(&self, samples: Vec<f32>, offset_ms: u64) -> Result<u128, String> {
let t0 = Instant::now();
match self {
Engine::Whisper(t) => {
let (tx, rx) = std::sync::mpsc::channel();
t.transcribe_stream(AudioWindow { samples, offset_ms }, tx)
.map_err(|e| e.to_string())?;
drop(rx);
}
Engine::Onnx(t) => {
let (tx, rx) = std::sync::mpsc::channel();
t.transcribe_stream(AudioWindow { samples, offset_ms }, tx)
.map_err(|e| e.to_string())?;
drop(rx);
}
Engine::Parakeet(r) => {
let _ = r
.lock()
.map_err(|_| "poisoned".to_string())?
.transcribe(SAMPLE_RATE as u32, &samples);
}
}
Ok(t0.elapsed().as_millis())
}
}
fn join_segments(segs: Vec<whispassist_lib::models::TranscriptSegment>) -> String {
segs.iter()
.map(|s| s.text.trim())
.collect::<Vec<_>>()
.join(" ")
}
/// First file in `dir` whose name starts with `prefix` and ends with `.onnx`.
fn find_onnx(dir: &Path, prefix: &str) -> Result<PathBuf, String> {
std::fs::read_dir(dir)
.map_err(|e| format!("{}: {e}", dir.display()))?
.filter_map(|e| e.ok())
.map(|e| e.path())
.find(|p| {
p.file_name()
.and_then(|n| n.to_str())
.is_some_and(|n| n.starts_with(prefix) && n.ends_with(".onnx"))
})
.ok_or_else(|| format!("no {prefix}*.onnx under {}", dir.display()))
}
fn load_engine(contender: &str) -> Result<Engine, String> {
let whisper = |model: &str, backend: BackendId| -> Result<Engine, String> {
let path = paths::whisper_model_file(model);
WhisperTranscriber::load(&path, backend, Some("en"))
.map(Engine::Whisper)
.map_err(|e| e.to_string())
};
match contender {
"w1-cpu-base" => whisper("base.en-q5_1", BackendId::Cpu),
"w2-vulkan-base" => whisper("base.en-q5_1", BackendId::Intel),
"w3-vulkan-medium" => whisper("medium.en-q5_0", BackendId::Intel),
"w4-npu-onnx" => {
let dir = onnx_models::model_dir(onnx_models::DEFAULT_ONNX_MODEL);
OnnxTranscriber::load(&dir, BackendId::Npu, None)
.map(Engine::Onnx)
.map_err(|e| e.to_string())
}
p if p.starts_with("p1-parakeet-t") || p.starts_with("p2-parakeet-dml-t") => {
let dml = p.starts_with("p2-");
let threads: i32 = p
.rsplit_once('t')
.and_then(|(_, n)| n.parse().ok())
.ok_or_else(|| format!("bad thread count in '{p}'"))?;
let dir = paths::models_dir().join("bench-parakeet");
let config = sherpa_rs::transducer::TransducerConfig {
encoder: find_onnx(&dir, "encoder")?.to_string_lossy().into_owned(),
decoder: find_onnx(&dir, "decoder")?.to_string_lossy().into_owned(),
joiner: find_onnx(&dir, "joiner")?.to_string_lossy().into_owned(),
tokens: dir.join("tokens.txt").to_string_lossy().into_owned(),
model_type: "nemo_transducer".to_string(),
decoding_method: "greedy_search".to_string(),
sample_rate: SAMPLE_RATE as i32,
feature_dim: 80,
num_threads: threads,
// "directml" needs the bench-directml cargo feature (DirectML
// sherpa-onnx binaries); with plain binaries sherpa falls back
// noisily and the run is invalid — P2 rows only count from a
// bench-directml build.
provider: Some(if dml { "directml" } else { "cpu" }.to_string()),
..Default::default()
};
sherpa_rs::transducer::TransducerRecognizer::new(config)
.map(|r| Engine::Parakeet(std::sync::Mutex::new(r)))
.map_err(|e| e.to_string())
}
other => Err(format!(
"unknown contender '{other}' (w1-cpu-base | w2-vulkan-base | w3-vulkan-medium | w4-npu-onnx | p1-parakeet-t<N> | p2-parakeet-dml-t<N>)"
)),
}
}
// ---- modes ----
fn csv_escape(s: &str) -> String {
format!("\"{}\"", s.replace('"', "\"\""))
}
fn run_corpus(contender: &str, engine: &Engine, load_ms: u128, corpus: &Path, out: &Path) {
let mut wavs: Vec<PathBuf> = std::fs::read_dir(corpus)
.unwrap_or_else(|e| panic!("corpus dir {}: {e}", corpus.display()))
.filter_map(|e| e.ok())
.map(|e| e.path())
.filter(|p| p.extension().is_some_and(|x| x == "wav"))
.collect();
wavs.sort();
assert!(!wavs.is_empty(), "no wavs in {}", corpus.display());
if let Some(parent) = out.parent() {
std::fs::create_dir_all(parent).expect("create out dir");
}
let new_file = !out.exists();
let mut csv = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(out)
.expect("open csv");
if new_file {
writeln!(
csv,
"contender,file,audio_secs,load_ms,wall_ms,cpu_ms,wer_errors,ref_words,hypothesis"
)
.unwrap();
}
let (mut errors, mut words, mut wall_total, mut cpu_total, mut audio_total) =
(0usize, 0usize, 0u128, 0u64, 0f64);
for wav in &wavs {
let stem = wav.file_stem().unwrap().to_string_lossy().into_owned();
let reference = std::fs::read_to_string(wav.with_extension("txt")).unwrap_or_else(|e| {
panic!(
"missing reference {}: {e}",
wav.with_extension("txt").display()
)
});
let audio_secs = read_wav_mono_16k(wav)
.map(|s| s.len() as f64 / SAMPLE_RATE as f64)
.unwrap_or(0.0);
let cpu0 = cputime::process_cpu_ms();
let t0 = Instant::now();
let hypothesis = match engine.transcribe_wav(wav) {
Ok(t) => t,
Err(e) => {
eprintln!("FAILED {stem}: {e}");
continue;
}
};
let wall = t0.elapsed().as_millis();
let cpu = cputime::process_cpu_ms() - cpu0;
let r = normalize(&reference);
let h = normalize(&hypothesis);
let err = edit_distance(&r, &h);
errors += err;
words += r.len();
wall_total += wall;
cpu_total += cpu;
audio_total += audio_secs;
writeln!(
csv,
"{contender},{stem},{audio_secs:.2},{load_ms},{wall},{cpu},{err},{},{}",
r.len(),
csv_escape(&hypothesis)
)
.unwrap();
println!(
"{stem}: {audio_secs:.1}s wall={wall}ms cpu={cpu}ms wer={err}/{}",
r.len()
);
}
println!("---- {contender} summary ----");
println!(
"files: {} audio: {audio_total:.1}s load: {load_ms}ms",
wavs.len()
);
println!(
"WER: {:.2}% ({errors}/{words})",
100.0 * errors as f64 / words.max(1) as f64
);
println!(
"RTF (wall): {:.3}",
wall_total as f64 / 1000.0 / audio_total.max(0.001)
);
println!(
"CPU-sec per audio-sec: {:.3}",
cpu_total as f64 / 1000.0 / audio_total.max(0.001)
);
}
fn run_live(contender: &str, engine: &Engine, wav: &Path) {
let samples = read_wav_mono_16k(wav).expect("read live wav");
let chunk = WINDOW_SECS * SAMPLE_RATE;
let mut latencies: Vec<u128> = Vec::new();
for (i, part) in samples.chunks(chunk).enumerate() {
if part.len() < SAMPLE_RATE {
continue; // sub-second tail: skip, same spirit as MIN_DIARIZE_SAMPLES
}
let ms = engine
.time_window(part.to_vec(), (i * WINDOW_SECS * 1000) as u64)
.expect("window decode");
println!("window {i}: {ms}ms");
latencies.push(ms);
}
latencies.sort_unstable();
let pct = |p: f64| latencies[(((latencies.len() - 1) as f64) * p) as usize];
println!(
"---- {contender} live ({WINDOW_SECS}s windows, n={}) ----",
latencies.len()
);
println!(
"p50={}ms p95={}ms max={}ms (budget: {}ms)",
pct(0.50),
pct(0.95),
latencies.last().unwrap(),
WINDOW_SECS * 1000
);
}
fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
if args.iter().any(|a| a == "--self-test") {
self_test();
return;
}
let contender = args
.first()
.expect("usage: asr_bench <contender> [--corpus DIR|--live WAV]");
let flag = |name: &str| {
args.iter()
.position(|a| a == name)
.and_then(|i| args.get(i + 1))
.map(PathBuf::from)
};
let corpus = flag("--corpus").unwrap_or_else(|| PathBuf::from("bench-corpus"));
let out = flag("--out").unwrap_or_else(|| PathBuf::from("bench-results/raw.csv"));
let t0 = Instant::now();
let engine = match load_engine(contender) {
Ok(e) => e,
Err(e) => {
eprintln!("load failed: {e}");
std::process::exit(1);
}
};
let load_ms = t0.elapsed().as_millis();
println!("{contender}: loaded in {load_ms}ms");
match flag("--live") {
Some(wav) => run_live(contender, &engine, &wav),
None => run_corpus(contender, &engine, load_ms, &corpus, &out),
}
}
+15 -1
View File
@@ -287,8 +287,22 @@ impl Transcriber for WhisperTranscriber {
#[cfg(feature = "cpu-transcription")]
fn available_threads() -> std::ffi::c_int {
// WA_WHISPER_THREADS: support/bench override — see cap rationale below.
if let Some(n) = std::env::var("WA_WHISPER_THREADS")
.ok()
.and_then(|s| s.parse().ok())
{
return n;
}
// Capped at 4 (whisper.cpp's own CLI default): ggml workers spin-wait at
// a per-graph-node barrier, so one worker scheduled on a slow core stalls
// every node while the rest burn CPU. With all 14 logical CPUs of a
// hybrid Meteor Lake (incl. 2 LP E-cores) this measured RTF ~22 — ~80x
// slower than the same build at 4 threads (RTF 0.28), regardless of
// compiler flags. 4 threads is also the CPU-frugal choice (NFR-RES-1):
// 1.07 vs 2.16 cpu-sec/audio-sec at 12 threads for near-equal wall time.
std::thread::available_parallelism()
.map(|n| n.get() as std::ffi::c_int)
.map(|n| (n.get() as std::ffi::c_int).min(4))
.unwrap_or(4)
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "WhispAssist",
"version": "0.7.3",
"version": "0.7.4",
"identifier": "bet.dou.whispassist",
"build": {
"frontendDist": "../dist",