Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install optional OpenBLAS backend
if: runner.os == 'Linux' && contains(matrix.flags, '--all-features')
run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
# Pin a complete, present Xcode on macOS: the floating `macos-latest`
# image intermittently leaves a default selection whose clang runtime
# (`libclang_rt.osx.a`) is missing, breaking the link with
Expand Down Expand Up @@ -93,6 +96,9 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install optional OpenBLAS backend
if: runner.os == 'Linux' && contains(matrix.flags, '--all-features')
run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
# See the `check` job: deterministic Xcode so macOS linking is stable.
- if: runner.os == 'macOS'
id: xcode
Expand Down Expand Up @@ -133,6 +139,9 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install optional OpenBLAS backend
if: runner.os == 'Linux' && contains(matrix.flags, '--all-features')
run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
# See the `check` job: deterministic Xcode so macOS linking is stable.
- if: runner.os == 'macOS'
id: xcode
Expand Down Expand Up @@ -212,6 +221,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install optional OpenBLAS backend
run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo doc --no-deps --all-features
Expand All @@ -230,6 +241,8 @@ jobs:
contents: read
steps:
- uses: actions/checkout@v4
- name: Install optional OpenBLAS backend
run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
- uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
Expand Down Expand Up @@ -325,6 +338,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# cargo-semver-checks enables public features, including system-openblas.
- run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@v2
Expand Down Expand Up @@ -365,6 +380,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install optional OpenBLAS backend
run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@v2
Expand Down Expand Up @@ -524,3 +541,13 @@ jobs:
- run: |
sudo apt-get update && sudo apt-get install -y minisign
- run: ./scripts/sign-models.sh --dry-run

linux-blas:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
- name: Verify Rust default and explicit OpenBLAS artifacts
run: bash scripts/check-linux-blas.sh
5 changes: 2 additions & 3 deletions .github/workflows/linux-cpu-der.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,14 @@ jobs:
env:
OUT: benchmarks/results/linux-cpu-native-der-ci
EP: cpu
FEATURES: cli
# Match release assets: Rust kernels, no system-openblas.
FEATURES: cli-native
POLYVOICE_POWERSET_BATCH_SIZE: "8"
POLYVOICE_VBX_PLDA_DIR: ${{ github.workspace }}/fixtures/vbx-plda
ASSERT_BASELINE: "1"
BASELINE_JSON: ${{ github.workspace }}/tests/der_baseline.json
run: |
set -euo pipefail
sudo apt-get update -qq
sudo apt-get install -y -qq libopenblas-dev pkg-config
if [ "$MODE" = "full" ]; then
export MAX_VOX=0 MAX_AMI=0
else
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/mutants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
- uses: taiki-e/install-action@v2
with:
tool: cargo-mutants
- run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
- run: cargo mutants --all-features --timeout 300
- if: always()
uses: actions/upload-artifact@v4
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ jobs:
- run: bash scripts/download-ami-test-single.sh
- run: bash scripts/download-voxconverse-test.sh
- run: cargo run --features cli --bin polyvoice -- download-models --profile balanced
- name: Install OpenBLAS for all-features validation
run: sudo apt-get update -qq && sudo apt-get install -y libopenblas-dev pkg-config
- run: bash scripts/release-check.sh

cli-binaries:
Expand Down Expand Up @@ -105,6 +107,7 @@ jobs:
~/Library/Caches/ort.pyke.io
~/AppData/Local/ort.pyke.io
key: ort-dfbin-${{ runner.os }}-${{ hashFiles('Cargo.lock') }}
# Release assets use Rust Linux kernels; system-openblas is not enabled.
- run: cargo build --release --features cli --target ${{ matrix.target }}
- name: Rename binary (unix)
if: runner.os != 'Windows'
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Linux native builds now use Rust kernels regardless of installed BLAS.
Enable `system-openblas` for the optional LP64 OpenBLAS backend; missing
development files fail clearly instead of silently selecting a fallback.
`--all-features` includes this opt-in. Darwin remains unchanged.

- `PipelineBuilder::validate` rejects out-of-range public settings (NaN,
infinity, `max_speakers == 0`, `min_cluster_size == 0`, non-positive
embed windows, AHC thresholds outside [-1, 1], AS-norm `top_n < 2`,
Expand Down
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,8 @@ Library docs: [docs/API.md](docs/API.md).
## License

By contributing, you agree that your contributions will be licensed under MIT.

On Linux, `--all-features` and the release checks require LP64 OpenBLAS
development files and `pkg-config` because they enable `system-openblas`.
Ordinary `--features cli` builds use Rust kernels without BLAS. See the
[backend contract](docs/strategy/zero-deps.md#linux-backend-selection).
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ crate-type = ["cdylib", "rlib"]

[features]
default = []
# Opt-in Linux LP64 OpenBLAS for enabled native kernels; no effect on Darwin.
system-openblas = ["polyvoice-kernels?/system-openblas"]
# InferenceRuntime surface (tensors, factory, session trait). No native dylib.
# Enabled by `backend-tract`. Stages that load ONNX *files* via tract depend
# on this, not on a concrete engine. The product CLI does not enable `infer`.
Expand Down
4 changes: 2 additions & 2 deletions PRODUCTION-READINESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ mean no C/C++ code, no system libraries, or zero Rust crates.

- Empty default features provide the BYO core with normal Rust dependencies.
- Native Darwin inference compiles C shims and links Accelerate/BNNS.
- Native Linux uses Rust kernels and currently auto-detects installed BLAS.
Making that choice explicit and reproducible remains a release requirement.
- Native Linux uses Rust kernels by default; `system-openblas` explicitly
enables the optional LP64 OpenBLAS backend.
- Download-enabled builds pull TLS dependencies, including `ring` native
code. `pipeline-local` omits the downloader and its TLS graph.
- Python also depends on the Python runtime/ABI.
Expand Down
97 changes: 97 additions & 0 deletions benchmarks/results/linux-blas-selection-2026-09-24/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Explicit Linux OpenBLAS selection: before/after evidence

Host: AMD Ryzen AI 9 HX 370, Linux x86_64, 24 logical CPUs, performance
CPU governor. Date: 2026-09-24. Release profile, balanced INT8, v2 + VBx,
CPU, powerset batch 8, collar 0, overlap included, checked-in PLDA fixtures.

## Revisions and artifacts

- `baseline`: master `a8461d42f7793f2f21409b41f7619e881b4c5a43`, `--features cli`.
Its auto-detection found no BLAS; the saved binary has no BLAS imports.
- `rust`: `64f13c8433c684b6ff73f8cc5e5f5597baa278ec`, `--features cli`.
Default Rust backend even with OpenBLAS available to pkg-config.
- `openblas`: same implementation revision, `--features cli,system-openblas`.
Ubuntu LP64 pthread OpenBLAS 0.3.32, extracted locally with its Fortran
runtime dependencies; no system installation changes. pkg-config points
to that prefix and the runtime loader path points to its shared libraries.

[Measurements](measurements.json) include binary SHA-256, source revision,
DER, wall RTFx and process peak RSS for every completed run. Source revision
is recorded explicitly: the bench program itself queries the current checkout
at runtime, which cannot identify a saved baseline executable.

Model pair unchanged, **8,414,314 bytes**:

- powerset_int8: `175896d26f639933cd86906d2dd3e6796eddb23c1f719925a3949052da76183b`
- resnet34_int8: `24b58559fefb2af624a5d371c43ebae891a9a8ca363b2f9e7c31fd8e440a36b3`

## Scope and results

Vox-3 is euqef/fuzfh/msbyq. Vox-10 is the first ten filenames in sorted
VoxConverse-test order; AMI-1 is the first sorted AMI-test recording.
The exact filenames and all per-file quality fields are in
[quality.json](quality.json). These are fixed diagnostic subsets, not the
published full-split Vox/AMI reference scores.

Vox-3 runs alternate baseline/rust/openblas five times for each jobs setting.
Vox-10 has one run per backend; AMI-1 repeats baseline/rust three times and
OpenBLAS once. Table timing/RSS values are medians, **not release floors**.

| Dataset | Jobs | Backend | Runs | DER₀ micro % | Wall RTFx | Peak RSS MiB |
|---------|------|---------|------|--------------|-----------|--------------|
| vox3 | 1 | baseline | 5 | 7.0295 | 91.7 | 316.5 |
| vox3 | 1 | rust | 5 | 7.0295 | 89.4 | 314.8 |
| vox3 | 1 | openblas | 5 | 7.0295 | 93.0 | 321.2 |
| vox3 | 3 | baseline | 5 | 7.0295 | 117.0 | 469.5 |
| vox3 | 3 | rust | 5 | 7.0295 | 127.7 | 480.4 |
| vox3 | 3 | openblas | 5 | 7.0295 | 132.3 | 480.5 |
| vox10 | 3 | baseline | 1 | 16.4243 | 134.8 | 2283.0 |
| vox10 | 3 | rust | 1 | 16.4243 | 95.6 | 2224.9 |
| vox10 | 3 | openblas | 1 | 15.6938 | 165.1 | 2242.2 |
| ami1 | 3 | baseline | 3 | 32.5584 | 144.7 | 1263.9 |
| ami1 | 3 | rust | 3 | 32.5584 | 150.0 | 1292.6 |
| ami1 | 3 | openblas | 1 | 31.7272 | 163.5 | 1299.3 |

Default Rust matches the baseline on every recorded per-file quality field,
including speaker counts and turn counts. OpenBLAS matches Vox-3 quality but
changes clustering on Vox-10/AMI-1; its lower DER here is subset evidence,
not a universal improvement or numerical-equivalence claim.

**Performance limitation:** unrelated builds and CPU-heavy tests were active
on the host. Throughput fluctuated substantially, including between repeated
runs of the same binary. Full-corpus comparisons were stopped after detecting
that contention; no incomplete full-corpus result is included. These runs
measure before/after behavior but do not certify isolated performance parity
or establish new speed/RSS baselines. Default median AMI RSS is slightly
higher than baseline, with overlapping observed ranges; no memory improvement
is claimed. Re-run on an idle reference host for performance qualification.

Darwin implementation and all five locked scoreboard limits are unchanged.
Darwin scoreboard CI passed; its shared-runner result does not substitute for
an isolated Darwin RTF/RSS measurement. Linux subset RSS is not the Darwin
Vox-3 memory protocol.

## Reproduction and verification

Save a release `polyvoice-bench` from each revision/feature selection. Prepare
subset directories with `audio/` and `rttm/` symlinks for the recorded filenames.
For each binary and dataset:

```bash
POLYVOICE_VBX_PLDA_DIR="$PWD/fixtures/vbx-plda" POLYVOICE_POWERSET_BATCH_SIZE=8 \
/usr/bin/time -v ./saved-polyvoice-bench DATASET \
--profile balanced --pipeline v2 --clusterer vbx --execution-provider cpu \
--collar 0 --jobs 3 --output result.json
```

For the OpenBLAS binary, install the runtime or set `LD_LIBRARY_PATH` to its
local prefix. Read process RSS from `/usr/bin/time -v`, not summed workers.

Validation:

- `scripts/check-linux-blas.sh`: passes for both artifacts with OpenBLAS
available, including missing-prerequisite failure and `readelf`/`ldd` checks.
- Kernel tests: 58 Rust / 59 OpenBLAS passed; three manual tests ignored each.
- Product CLI/FFI/OpenBLAS library tests: 943 passed; local-only library: 875.
- Clippy: product CLI/FFI and all-features with `-D warnings` passed.
- Dependency invariants, standalone lockfiles, formatting and doc links passed.
Loading
Loading