From 4df59cc15386ff3bb10916256d807ebc5c85f81d Mon Sep 17 00:00:00 2001 From: zhifu gao Date: Fri, 28 Aug 2026 00:59:31 +0800 Subject: [PATCH] chore(release): prepare 1.4.5 (#3534) Publish the optional-torchaudio inference path, pin the verified nine-platform llama.cpp runtime matrix, and document the protected exact-main publication gate. Signed-off-by: LauraGPT <170200537+LauraGPT@users.noreply.github.com> --- .github/workflows/release-on-tag.yml | 4 +- README.md | 1 + README_ja.md | 1 + README_ko.md | 1 + README_zh.md | 1 + funasr/version.txt | 2 +- runtime/llama.cpp/current-release.txt | 1 + scripts/update_release_runtime_downloads.py | 21 ++++++++- tests/test_release_runtime_downloads.py | 50 ++++++++++++++++----- tests/test_release_version_contract.py | 2 +- 10 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 runtime/llama.cpp/current-release.txt diff --git a/.github/workflows/release-on-tag.yml b/.github/workflows/release-on-tag.yml index 47865bd0c..67fbc3c5f 100644 --- a/.github/workflows/release-on-tag.yml +++ b/.github/workflows/release-on-tag.yml @@ -25,4 +25,6 @@ jobs: - name: Add Runtime assets and downloads to GitHub Release env: GH_TOKEN: ${{ github.token }} - run: python scripts/update_release_runtime_downloads.py "${{ github.ref_name }}" + run: | + RUNTIME_TAG="$(cat runtime/llama.cpp/current-release.txt)" + python scripts/update_release_runtime_downloads.py "${{ github.ref_name }}" --runtime-tag "$RUNTIME_TAG" diff --git a/README.md b/README.md index ec1ae2a51..9cb087bf1 100644 --- a/README.md +++ b/README.md @@ -330,6 +330,7 @@ asset is published. ## What's new +- 2026/08/28: **v1.4.5 on PyPI** — `torchaudio` is no longer a hard inference dependency. Feature extraction uses `torchaudio.compliance.kaldi` when available or the optional `kaldi-native-fbank` backend, while operations that still require `torchaudio` now fail with an actionable message. The fallback was verified end to end on Ascend 910B: 70.47 s of audio processed in 1.15 s (RTF 0.016). Upgrade with `python -m pip install -U "funasr==1.4.5"`; on systems without `torchaudio`, install `python -m pip install -U "funasr[knf]==1.4.5"`. The GitHub Release also carries the verified nine-platform llama.cpp v0.2.1 runtime archives. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.5) - 2026/08/27: **llama.cpp runtime v0.2.1** — Vulkan device selection now accepts matching integrated GPUs, prefers a matching discrete GPU when both are available, and otherwise falls back to the iGPU. Nine Linux, macOS, and Windows archives were rebuilt and verified with published SHA-256 values. Radeon 780M still needs reporter hardware confirmation; the separate RX 9070 XT `0xC0000005` initialization crash is not claimed fixed. [Download matrix & quickstart ->](https://www.funasr.com/en/deploy/llama-cpp.html) · [Release ->](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.2.1) - 2026/08/26: **v1.4.4 on PyPI** — realtime WebSocket decoding now batches compatible sessions instead of serializing every connection behind one process-wide lock. On the H100 regression workload, 12-client STOP p95 fell from 19.8 s to 0.4 s and 16-client aggregate throughput rose from 8.6x to 13.2x, with no client errors. This hotfix also restores compatibility with PyTorch releases that do not expose `torch.amp` and raises real runtime-binding exceptions. Upgrade with `python -m pip install -U "funasr==1.4.4"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.4) - 2026/08/21: **v1.4.3 on PyPI** — `AutoModel(vad_model="silero-vad")` now offers an optional Silero VAD adapter with millisecond segments, configurable thresholds, 8/16 kHz input, ONNX mode, and bounded segment lengths. Upgrade with `python -m pip install -U "funasr==1.4.3"`; enable the adapter with `python -m pip install -U "funasr[silero]==1.4.3"`. Speaker diarization with a known speaker count now routes large embedding sets through fixed-K clustering instead of memory-heavy dense spectral clustering. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.4.3) diff --git a/README_ja.md b/README_ja.md index c9fc7ace0..adc3cd428 100644 --- a/README_ja.md +++ b/README_ja.md @@ -99,6 +99,7 @@ Whisper は単一モデルですが、**FunASR はツールキット**です— ## 最新情報 +- 2026/08/28:**v1.4.5 を PyPI に公開** — `torchaudio` は推論の必須依存関係ではなくなりました。特徴抽出は利用可能な場合に `torchaudio.compliance.kaldi` を使い、そうでなければ任意の `kaldi-native-fbank` backend を利用できます。引き続き `torchaudio` が必要な処理は、実行可能な依存関係メッセージを返します。この fallback は Ascend 910B で end-to-end 検証済みで、70.47 秒の音声を 1.15 秒(RTF 0.016)で処理しました。更新:`python -m pip install -U "funasr==1.4.5"`。`torchaudio` がない環境:`python -m pip install -U "funasr[knf]==1.4.5"`。GitHub Release には検証済みの llama.cpp v0.2.1 9 platform runtime archive も含まれます。[Release →](https://github.com/modelscope/FunASR/releases/tag/v1.4.5) - 2026/08/27:**llama.cpp runtime v0.2.1** — Vulkan のデバイス選択が一致する統合 GPU を受け入れ、一致する discrete GPU があればそちらを優先し、なければ iGPU にフォールバックするようになりました。SHA-256 を公開した Linux、macOS、Windows 向け 9 archive を再構築・検証済みです。Radeon 780M は報告者の実機確認待ちで、別件の RX 9070 XT `0xC0000005` 初期化 crash は修正済みとはしていません。[ダウンロード一覧と quickstart →](https://www.funasr.com/en/deploy/llama-cpp.html) · [Release →](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.2.1) - 2026/08/26:**v1.4.4 を PyPI に公開** — realtime WebSocket decode は、全 connection を 1 つの process-wide lock で直列化せず、互換性のある session を batch 処理するようになりました。H100 regression workload では、12 client の STOP p95 が 19.8 秒から 0.4 秒に短縮され、16 client の aggregate throughput は 8.6x から 13.2x に向上し、client error は 0 件でした。この hotfix は `torch.amp` を持たない PyTorch release との互換性も復元し、runtime binding から実際の例外を送出します。更新:`python -m pip install -U "funasr==1.4.4"`。[Release →](https://github.com/modelscope/FunASR/releases/tag/v1.4.4) - 2026/08/21:**v1.4.3 を PyPI に公開** — `AutoModel(vad_model="silero-vad")` で任意の Silero VAD アダプターを利用でき、ミリ秒単位の区間、しきい値、8/16 kHz 入力、ONNX mode、最大区間長を設定できます。更新:`python -m pip install -U "funasr==1.4.3"`。アダプターの有効化:`python -m pip install -U "funasr[silero]==1.4.3"`。話者数が既知の話者ダイアライゼーションは、大規模 embedding をメモリ負荷の高い密なスペクトラルクラスタリングではなく fixed-K クラスタリングで処理します。[Release →](https://github.com/modelscope/FunASR/releases/tag/v1.4.3) diff --git a/README_ko.md b/README_ko.md index 34fed02b1..6399e514a 100644 --- a/README_ko.md +++ b/README_ko.md @@ -99,6 +99,7 @@ Whisper는 단일 모델이지만, **FunASR는 툴킷**입니다. 용도에 맞 ## 최신 소식 +- 2026/08/28: **v1.4.5 PyPI 공개** — `torchaudio`는 더 이상 inference의 필수 dependency가 아닙니다. Feature extraction은 사용할 수 있으면 `torchaudio.compliance.kaldi`를 사용하고, 그렇지 않으면 선택형 `kaldi-native-fbank` backend를 사용할 수 있습니다. 여전히 `torchaudio`가 필요한 작업은 해결 방법이 포함된 dependency 메시지를 반환합니다. 이 fallback은 Ascend 910B에서 end-to-end로 검증됐으며 70.47초 오디오를 1.15초(RTF 0.016)에 처리했습니다. 업데이트: `python -m pip install -U "funasr==1.4.5"`. `torchaudio`가 없는 환경: `python -m pip install -U "funasr[knf]==1.4.5"`. GitHub Release에는 검증된 llama.cpp v0.2.1 9개 platform runtime archive도 함께 제공됩니다. [Release →](https://github.com/modelscope/FunASR/releases/tag/v1.4.5) - 2026/08/27: **llama.cpp runtime v0.2.1** — Vulkan device 선택이 일치하는 integrated GPU를 허용하며, 일치하는 discrete GPU가 함께 있으면 이를 우선하고 없으면 iGPU로 fallback합니다. SHA-256을 공개한 Linux, macOS, Windows용 archive 9개를 다시 빌드하고 검증했습니다. Radeon 780M은 제보자의 실제 하드웨어 확인이 필요하며, 별도 RX 9070 XT `0xC0000005` 초기화 crash는 수정됐다고 주장하지 않습니다. [다운로드 목록 및 quickstart →](https://www.funasr.com/en/deploy/llama-cpp.html) · [Release →](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.2.1) - 2026/08/26: **v1.4.4 PyPI 공개** — realtime WebSocket decode가 모든 connection을 하나의 process-wide lock으로 직렬화하지 않고 호환되는 session을 batch 처리합니다. H100 regression workload에서 12-client STOP p95는 19.8초에서 0.4초로 줄었고, 16-client aggregate throughput은 8.6x에서 13.2x로 향상됐으며 client error는 0건이었습니다. 이 hotfix는 `torch.amp`가 없는 PyTorch release와의 호환성도 복원하고 runtime binding에서 실제 예외를 발생시킵니다. 업데이트: `python -m pip install -U "funasr==1.4.4"`. [Release →](https://github.com/modelscope/FunASR/releases/tag/v1.4.4) - 2026/08/21: **v1.4.3 PyPI 공개** — `AutoModel(vad_model="silero-vad")`에서 선택형 Silero VAD adapter를 사용할 수 있으며, 밀리초 단위 구간, threshold, 8/16 kHz 입력, ONNX mode, 최대 구간 길이를 지원합니다. 업데이트: `python -m pip install -U "funasr==1.4.3"`. Adapter 활성화: `python -m pip install -U "funasr[silero]==1.4.3"`. 화자 수를 알고 있는 speaker diarization은 대규모 embedding을 메모리 사용량이 큰 dense spectral clustering 대신 fixed-K clustering으로 처리합니다. [Release →](https://github.com/modelscope/FunASR/releases/tag/v1.4.3) diff --git a/README_zh.md b/README_zh.md index 8f8c223b2..625960fa3 100644 --- a/README_zh.md +++ b/README_zh.md @@ -149,6 +149,7 @@ Whisper 是单个模型,**FunASR 是一个工具箱**——按场景挑模型 ## 最新动态 +- 2026/08/28:**v1.4.5 已发布到 PyPI** — `torchaudio` 不再是推理的硬依赖。特征提取会优先使用 `torchaudio.compliance.kaldi`,不可用时可切换到可选的 `kaldi-native-fbank` 后端;仍然必须使用 `torchaudio` 的操作会给出可执行的依赖提示。该 fallback 已在 Ascend 910B 上端到端验证:70.47 秒音频用时 1.15 秒(RTF 0.016)。常规升级:`python -m pip install -U "funasr==1.4.5"`;没有 `torchaudio` 的环境请安装:`python -m pip install -U "funasr[knf]==1.4.5"`。GitHub 发布页同时提供已验证的 llama.cpp v0.2.1 九平台运行包。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.4.5) - 2026/08/27:**llama.cpp runtime v0.2.1** — Vulkan 设备选择现在接受匹配的集成 GPU;同时存在匹配独显时优先独显,否则回退到核显。九个 Linux、macOS 与 Windows 压缩包已重新构建并通过公开 SHA-256 复核。Radeon 780M 仍需报告者实机确认;单独的 RX 9070 XT `0xC0000005` 初始化崩溃不在本次修复声明内。[下载矩阵与快速开始 →](https://www.funasr.com/deploy/llama-cpp.html) · [发布页 →](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.2.1) - 2026/08/26:**v1.4.4 已发布到 PyPI** — 实时 WebSocket 解码会对兼容会话进行批处理,不再让所有连接排队经过同一个进程级锁。在 H100 回归负载下,12 路 STOP p95 从 19.8 秒降至 0.4 秒,16 路聚合吞吐从 8.6x 提升到 13.2x,且客户端零错误。本热修复同时兼容不提供 `torch.amp` 的 PyTorch 版本,并让运行时绑定抛出真实异常。升级命令:`python -m pip install -U "funasr==1.4.4"`。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.4.4) - 2026/08/21:**v1.4.3 已发布到 PyPI** — `AutoModel(vad_model="silero-vad")` 现可选用 Silero VAD 适配器,返回毫秒级片段,并支持阈值、8/16 kHz 输入、ONNX 模式和最长片段限制。基础升级命令:`python -m pip install -U "funasr==1.4.3"`;启用该适配器:`python -m pip install -U "funasr[silero]==1.4.3"`。已知说话人数的说话人分离在大规模 embedding 输入下改用固定 K 聚类,避免内存开销较高的稠密谱聚类。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.4.3) diff --git a/funasr/version.txt b/funasr/version.txt index 1c99cf0e8..e516bb9d9 100644 --- a/funasr/version.txt +++ b/funasr/version.txt @@ -1 +1 @@ -1.4.4 +1.4.5 diff --git a/runtime/llama.cpp/current-release.txt b/runtime/llama.cpp/current-release.txt new file mode 100644 index 000000000..29359b9f2 --- /dev/null +++ b/runtime/llama.cpp/current-release.txt @@ -0,0 +1 @@ +runtime-llamacpp-v0.2.1 diff --git a/scripts/update_release_runtime_downloads.py b/scripts/update_release_runtime_downloads.py index 3b63526b2..4c75379fb 100644 --- a/scripts/update_release_runtime_downloads.py +++ b/scripts/update_release_runtime_downloads.py @@ -18,6 +18,17 @@ from typing import Any RUNTIME_SECTION_HEADING = "## Runtime downloads" RUNTIME_SECTION_START = "" RUNTIME_SECTION_END = "" +EXPECTED_RUNTIME_ASSET_NAMES = { + "funasr-llamacpp-linux-arm64.tar.gz", + "funasr-llamacpp-linux-x64-avx2.tar.gz", + "funasr-llamacpp-linux-x64-vulkan.tar.gz", + "funasr-llamacpp-linux-x64.tar.gz", + "funasr-llamacpp-macos-arm64.tar.gz", + "funasr-llamacpp-windows-x64-avx2.zip", + "funasr-llamacpp-windows-x64-cuda.zip", + "funasr-llamacpp-windows-x64-vulkan.zip", + "funasr-llamacpp-windows-x64.zip", +} def run_gh_json(args: list[str]) -> Any: @@ -119,8 +130,14 @@ def runtime_assets(release: dict[str, Any]) -> list[dict[str, Any]]: selected = [ asset for asset in assets if asset["name"].startswith("funasr-llamacpp-") ] - if not selected: - raise RuntimeError(f"{release['tagName']} has no llama.cpp assets") + actual_names = {asset["name"] for asset in selected} + if actual_names != EXPECTED_RUNTIME_ASSET_NAMES: + missing = sorted(EXPECTED_RUNTIME_ASSET_NAMES - actual_names) + unexpected = sorted(actual_names - EXPECTED_RUNTIME_ASSET_NAMES) + raise RuntimeError( + f"{release['tagName']} does not contain the exact runtime asset matrix; " + f"missing={missing}, unexpected={unexpected}" + ) return selected diff --git a/tests/test_release_runtime_downloads.py b/tests/test_release_runtime_downloads.py index b62d9327b..c38f365c1 100644 --- a/tests/test_release_runtime_downloads.py +++ b/tests/test_release_runtime_downloads.py @@ -98,6 +98,37 @@ def test_release_on_tag_workflow_adds_runtime_assets_and_downloads(): assert "if !" in workflow +def test_release_on_tag_workflow_uses_versioned_runtime_pointer(): + workflow = (ROOT / ".github" / "workflows" / "release-on-tag.yml").read_text( + encoding="utf-8" + ) + runtime_pointer = ROOT / "runtime" / "llama.cpp" / "current-release.txt" + + assert "runtime/llama.cpp/current-release.txt" in workflow + assert '--runtime-tag "$RUNTIME_TAG"' in workflow + assert runtime_pointer.read_text(encoding="utf-8").strip() == ( + "runtime-llamacpp-v0.2.1" + ) + + +@pytest.mark.parametrize("mutation", ("missing", "unexpected")) +def test_runtime_assets_rejects_non_exact_platform_matrix(mutation): + module = load_release_script() + release = runtime_release_payload() + if mutation == "missing": + release["assets"].pop() + else: + release["assets"].append( + { + "name": "funasr-llamacpp-linux-riscv64.tar.gz", + "digest": sha256_digest("linuxriscv64"), + } + ) + + with pytest.raises(RuntimeError, match="exact runtime asset matrix"): + module.runtime_assets(release) + + def test_latest_runtime_tag_is_stable_for_python_release_time(): module = load_release_script() calls = [] @@ -249,15 +280,14 @@ def test_sync_runtime_assets_downloads_verifies_and_uploads_missing_asset(): payload = b"runtime archive" digest = hashlib.sha256(payload).hexdigest() asset_name = "funasr-llamacpp-linux-x64.tar.gz" - runtime_release = { - "tagName": "runtime-llamacpp-v0.1.9", - "assets": [ - { - "name": asset_name, - "digest": f"sha256:{digest}", - } - ], - } + runtime_release = runtime_release_payload() + target_asset = next( + asset for asset in runtime_release["assets"] if asset["name"] == asset_name + ) + target_asset["digest"] = f"sha256:{digest}" + existing_assets = [ + asset for asset in runtime_release["assets"] if asset["name"] != asset_name + ] calls = [] def fake_run_gh(args): @@ -272,7 +302,7 @@ def test_sync_runtime_assets_downloads_verifies_and_uploads_missing_asset(): repository="modelscope/FunASR", python_tag="v1.3.27", runtime_release=runtime_release, - python_release=python_release_payload(), + python_release=python_release_payload(existing_assets), ) assert calls[0][:3] == [ diff --git a/tests/test_release_version_contract.py b/tests/test_release_version_contract.py index 23be8cd76..8e956ad9e 100644 --- a/tests/test_release_version_contract.py +++ b/tests/test_release_version_contract.py @@ -2,7 +2,7 @@ from pathlib import Path ROOT = Path(__file__).resolve().parents[1] -RELEASE_VERSION = "1.4.4" +RELEASE_VERSION = "1.4.5" README_FILES = ("README.md", "README_zh.md", "README_ja.md", "README_ko.md")