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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ asset is published.

## What's new

- 2026/07/24: **v1.3.27 on PyPI** — the OpenAI-compatible server now reports detected SenseVoice language metadata in `verbose_json` and reuses the cached Fun-ASR-Nano `AutoModel` after vLLM fallback. When vLLM/VAD setup and its fallback both fail, half-initialized engine state is cleared so a later request can retry. Install with `python -m pip install -U "funasr==1.3.27"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.3.27)
- 2026/07/23: **llama.cpp runtime v0.1.9** — adds `funasr-llamacpp-windows-x64-vulkan.zip` for standalone SenseVoiceSmall Vulkan inference on Windows with AMD, Intel, or NVIDIA drivers. Linux Vulkan, Windows CUDA, CPU/AVX2, Linux arm64, and macOS arm64 assets remain available. [Release ->](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.1.9)
- 2026/07/23: **v1.3.26 on PyPI** — `funasr-server --model fun-asr-nano --hub ms` now honors the requested ModelScope hub for the default Fun-ASR-Nano model in both the vLLM path and the AutoModel fallback, avoiding unintended Hugging Face downloads when users choose ModelScope. Install with `python -m pip install -U "funasr==1.3.26"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.3.26)
- 2026/07/23: **v1.3.25 on PyPI** — realtime WebSocket users can now use deterministic final-text hotword corrections with `POSTPROCESS_HOTWORDS:wrong=>right` or `--postprocess-hotword-file`, keeping fixed-name cleanup separate from model-level `HOTWORDS:` decoding bias. The source-tree realtime entrypoint also works without preinstalling the package. Install with `python -m pip install -U "funasr==1.3.25"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.3.25)
Expand Down
1 change: 1 addition & 0 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Whisper は単一モデルですが、**FunASR はツールキット**です—

## 最新情報

- 2026/07/24:**v1.3.27 が PyPI に公開** — OpenAI 互換サーバーが `verbose_json` で SenseVoice の検出言語を返し、vLLM fallback 後はキャッシュ済み Fun-ASR-Nano `AutoModel` を再利用します。vLLM/VAD 初期化と fallback の両方が失敗した場合は、半初期化状態を残さず、後続リクエストで再試行できます。インストール:`python -m pip install -U "funasr==1.3.27"`。[Release →](https://github.com/modelscope/FunASR/releases/tag/v1.3.27)
- 2026/07/23:**v1.3.26 が PyPI に公開** — `funasr-server --model fun-asr-nano --hub ms` は ModelScope hub 指定を vLLM 経路と AutoModel fallback の両方で尊重します。インストール:`python -m pip install -U "funasr==1.3.26"`。[Release →](https://github.com/modelscope/FunASR/releases/tag/v1.3.26)
- 2026/07/23:**llama.cpp runtime v0.1.9** — Windows Vulkan 向け `funasr-llamacpp-windows-x64-vulkan.zip` を追加。現在の AMD、Intel、NVIDIA Vulkan ドライバーで SenseVoiceSmall を単独実行できます。Linux Vulkan、Windows CUDA、CPU/AVX2、Linux arm64、macOS arm64 も引き続き提供します。[Release →](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.1.9)
- 2026/07/22:**llama.cpp runtime v0.1.8** — Linux Vulkan tarball と Windows CUDA zip を含む CPU/エッジ向け GGUF ランタイム。ダウンロードと手順:[funasr.com/llama-cpp](https://www.funasr.com/llama-cpp.html) · [Release →](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.1.8)
Expand Down
1 change: 1 addition & 0 deletions README_ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Whisper는 단일 모델이지만, **FunASR는 툴킷**입니다. 용도에 맞

## 최신 소식

- 2026/07/24: **v1.3.27 PyPI 공개** — OpenAI 호환 서버가 `verbose_json`에 SenseVoice 감지 언어를 반환하고, vLLM fallback 후에는 캐시된 Fun-ASR-Nano `AutoModel`을 재사용합니다. vLLM/VAD 초기화와 fallback이 모두 실패하면 반쯤 초기화된 상태를 남기지 않아 이후 요청에서 다시 시도할 수 있습니다. 설치: `python -m pip install -U "funasr==1.3.27"`. [Release →](https://github.com/modelscope/FunASR/releases/tag/v1.3.27)
- 2026/07/23: **v1.3.26 PyPI 공개** — `funasr-server --model fun-asr-nano --hub ms`가 vLLM 경로와 AutoModel fallback 모두에서 ModelScope hub 선택을 존중합니다. 설치: `python -m pip install -U "funasr==1.3.26"`. [Release →](https://github.com/modelscope/FunASR/releases/tag/v1.3.26)
- 2026/07/23: **llama.cpp runtime v0.1.9** — Windows Vulkan용 `funasr-llamacpp-windows-x64-vulkan.zip`을 추가했습니다. 최신 AMD, Intel 또는 NVIDIA Vulkan 드라이버에서 SenseVoiceSmall을 독립 실행할 수 있습니다. Linux Vulkan, Windows CUDA, CPU/AVX2, Linux arm64, macOS arm64 패키지도 계속 제공합니다. [Release →](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.1.9)
- 2026/07/22: **llama.cpp runtime v0.1.8** — Linux Vulkan tarball과 Windows CUDA zip을 포함한 CPU/엣지용 GGUF 런타임입니다. 다운로드와 빠른 시작: [funasr.com/llama-cpp](https://www.funasr.com/llama-cpp.html) · [Release →](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.1.8)
Expand Down
1 change: 1 addition & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ Whisper 是单个模型,**FunASR 是一个工具箱**——按场景挑模型

## 最新动态

- 2026/07/24:**v1.3.27 已发布到 PyPI** — OpenAI 兼容服务现在会在 `verbose_json` 中返回 SenseVoice 检测到的语言,并在 vLLM 降级后复用已缓存的 Fun-ASR-Nano `AutoModel`。当 vLLM/VAD 初始化及其 fallback 均失败时,不会残留半初始化的 engine 状态,后续请求可以重试。安装命令:`python -m pip install -U "funasr==1.3.27"`。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.3.27)
- 2026/07/23:**llama.cpp runtime v0.1.9** — 新增独立的 Windows Vulkan 包 `funasr-llamacpp-windows-x64-vulkan.zip`,支持在安装当前 AMD、Intel 或 NVIDIA Vulkan 驱动的 Windows 机器上运行 SenseVoiceSmall;Linux Vulkan、Windows CUDA、CPU/AVX2、Linux arm64 和 macOS arm64 包继续提供。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/runtime-llamacpp-v0.1.9)
- 2026/07/23:**v1.3.26 已发布到 PyPI** — `funasr-server --model fun-asr-nano --hub ms` 现在会在默认 Fun-ASR-Nano 的 vLLM 路径和 AutoModel fallback 路径中都尊重 ModelScope hub 选择,避免用户指定 ModelScope 时仍误走 Hugging Face 下载。安装命令:`python -m pip install -U "funasr==1.3.26"`。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.3.26)
- 2026/07/23:**v1.3.25 已发布到 PyPI** — 实时 WebSocket 服务新增 `POSTPROCESS_HOTWORDS:错词=>正确词` 与 `--postprocess-hotword-file`,可在 final 文本阶段做确定性热词纠正,避免把固定错词修正误用成模型层 `HOTWORDS:` 解码偏置;源码目录下的实时服务入口也可直接运行。安装命令:`python -m pip install -U "funasr==1.3.25"`。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.3.25)
Expand Down
6 changes: 5 additions & 1 deletion funasr/bin/_server_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import time
import logging
import tempfile
from pathlib import Path
from typing import Optional

import numpy as np
Expand All @@ -26,6 +27,9 @@
logger = logging.getLogger("funasr.server")


PACKAGE_VERSION = (Path(__file__).resolve().parents[1] / "version.txt").read_text().strip()


_LANGUAGE_TAG_RE = re.compile(r"<\|(zh|en|yue|ja|ko)\|>")


Expand Down Expand Up @@ -126,7 +130,7 @@ def create_app(device: str = "cuda", preload_model: str = "auto", model_path: st
if preload_model == "auto":
preload_model = "fun-asr-nano" if device.startswith("cuda") else "sensevoice"

app = FastAPI(title="FunASR Server", version="1.3.6")
app = FastAPI(title="FunASR Server", version=PACKAGE_VERSION)
app.state.device = device
app.state.engine = None
app.state.vad_model = None
Expand Down
10 changes: 9 additions & 1 deletion funasr/bin/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@

import argparse
import sys
from pathlib import Path


PACKAGE_VERSION = (Path(__file__).resolve().parents[1] / "version.txt").read_text().strip()


def server_version_label():
return f"FunASR Server v{PACKAGE_VERSION}"


def main():
Expand Down Expand Up @@ -58,7 +66,7 @@ def main():
app = create_app(device=args.device, preload_model=args.model, model_path=args.model_path, hub=args.hub)

print(f"╔══════════════════════════════════════════════╗")
print(f"║ FunASR Server v1.3.6 ║")
print(f"║ {server_version_label():<44}║")
print(f"║ Device: {args.device:<8} ║")
print(f"║ Model: {args.model:<12} ║")
if args.model_path:
Expand Down
2 changes: 1 addition & 1 deletion funasr/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.3.26
1.3.27
56 changes: 54 additions & 2 deletions tests/test_server_app_openai_segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@

REPO_ROOT = Path(__file__).resolve().parents[1]
SERVICE_PATH = REPO_ROOT / "funasr" / "bin" / "_server_app.py"
SERVER_CLI_PATH = REPO_ROOT / "funasr" / "bin" / "server.py"


def load_server_app(monkeypatch):
class DummyFastAPI:
def __init__(self, *args, **kwargs):
self.state = types.SimpleNamespace()
self.routes = {}
self.metadata = kwargs

def post(self, path, *args, **kwargs):
def decorator(func):
Expand Down Expand Up @@ -53,7 +55,17 @@ def decorator(func):
return module


def install_dummy_funasr(monkeypatch, fail_once_for_models=()):
def load_server_cli():
module_name = "funasr_server_cli_under_test"
sys.modules.pop(module_name, None)
spec = importlib.util.spec_from_file_location(module_name, SERVER_CLI_PATH)
module = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(module)
return module


def install_dummy_funasr(monkeypatch, fail_once_for_models=(), generated_text="transcript"):
remaining_failures = {model: 1 for model in fail_once_for_models}

class DummyAutoModel:
Expand All @@ -72,7 +84,7 @@ def __init__(self, **kwargs):
def generate(self, **kwargs):
if self.kwargs.get("model") == "fsmn-vad":
return [{"value": [[0, 1000]]}]
return [{"text": "transcript"}]
return [{"text": generated_text}]

funasr_stub = types.ModuleType("funasr")
funasr_stub.AutoModel = DummyAutoModel
Expand Down Expand Up @@ -174,6 +186,46 @@ def test_resolve_transcription_language_does_not_default_to_chinese(monkeypatch)
assert module.resolve_transcription_language(None, {}) != "zh"


def test_verbose_json_reports_sensevoice_detected_language(monkeypatch):
module = load_server_app(monkeypatch)
install_dummy_funasr(
monkeypatch,
generated_text="<|en|><|NEUTRAL|><|Speech|>hello",
)
monkeypatch.setattr(module.sf, "info", lambda path: types.SimpleNamespace(duration=1.25))
app = module.create_app(device="cpu", preload_model="sensevoice")
transcribe = app.routes[("POST", "/v1/audio/transcriptions")]

response = asyncio.run(
transcribe(
file=DummyUpload(),
model="sensevoice",
language=None,
response_format="verbose_json",
spk=False,
)
)

assert response["language"] == "en"
assert response["text"] == "hello"
assert response["segments"] == [
{"id": 0, "start": 0.0, "end": 1.25, "text": "hello", "words": []}
]


def test_server_versions_follow_package_version(monkeypatch):
expected = (REPO_ROOT / "funasr" / "version.txt").read_text().strip()
module = load_server_app(monkeypatch)
server_module = load_server_cli()
install_dummy_funasr(monkeypatch)

app = module.create_app(device="cpu", preload_model="sensevoice")

assert app.metadata["version"] == expected
assert hasattr(server_module, "server_version_label")
assert server_module.server_version_label() == f"FunASR Server v{expected}"


def test_default_fun_asr_nano_uses_requested_modelscope_hub(monkeypatch):
module = load_server_app(monkeypatch)
DummyAutoModel = install_dummy_funasr(monkeypatch)
Expand Down
Loading