Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# FunASR ASR Python Extension

A local (self-hosted) speech-to-text extension for TEN Framework, powered by
[FunASR](https://github.com/modelscope/FunASR) — an open-source speech toolkit
from Tongyi Lab with strong multilingual ASR (Chinese, Cantonese, English,
Japanese, Korean and more). The model runs locally on CPU or CUDA; **no API key
is required** and audio never leaves your machine.

It mirrors the existing `whisper_stt_python` extension, swapping faster-whisper
for a local FunASR model — a natural fit for Chinese / Asian-language agents.

## Features

- Local, self-hosted ASR — no cloud, no API key, no per-minute billing.
- Strong Chinese / multilingual recognition; default model **SenseVoice-Small**
auto-detects the spoken language and emits inverse-text-normalized text.
- Swappable models via config (e.g. the flagship `FunAudioLLM/Fun-ASR-Nano-2512`
on GPU, or `paraformer-zh` for Chinese with timestamps).
- CPU or CUDA via the `device` parameter.

## Configuration (`property.json` → `params`)

| Param | Default | Description |
|---|---|---|
| `model` | `iic/SenseVoiceSmall` | FunASR model id. Use `FunAudioLLM/Fun-ASR-Nano-2512` (flagship LLM-ASR) on GPU, or `paraformer-zh` for Chinese. |
| `device` | `cpu` | `cpu` or `cuda`. |
| `language` | `auto` | Language hint, or `auto` to detect. |
| `use_itn` | `true` | Apply inverse text normalization. |
| `sample_rate` | `16000` | Input PCM sample rate (16-bit mono). |

## Requirements

```
pip install funasr
```

The model is downloaded automatically on first run.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#
# This file is part of TEN Framework, an open source project.
# Licensed under the Apache License, Version 2.0.
#

from . import addon

__all__ = ["addon"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# This file is part of TEN Framework, an open source project.
# Licensed under the Apache License, Version 2.0.
#

from ten_runtime import Addon, register_addon_as_extension, TenEnv


@register_addon_as_extension("funasr_asr_python")
class FunASRExtensionAddon(Addon):
def on_create_instance(self, ten_env: TenEnv, name: str, context) -> None:
from .extension import FunASRExtension

ten_env.log_info("FunASRExtensionAddon on_create_instance")
ten_env.on_create_instance_done(FunASRExtension(name), context)
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#
# This file is part of TEN Framework, an open source project.
# Licensed under the Apache License, Version 2.0.
#

from typing import Dict, Any
from pydantic import BaseModel, Field
from ten_ai_base.utils import encrypt


class FunASRConfig(BaseModel):
"""FunASR ASR Configuration"""

# Debugging and dumping
dump: bool = False
dump_path: str = "/tmp"

# Finalize mode: "disconnect" or "silence"
finalize_mode: str = "disconnect"
silence_duration_ms: int = 1000

# Vendor parameters (pass-through design)
params: Dict[str, Any] = Field(default_factory=dict)

def update(self, params: Dict[str, Any]) -> None:
"""Update configuration with additional parameters."""
for key, value in params.items():
if hasattr(self, key):
setattr(self, key, value)

def to_json(self, sensitive_handling: bool = False) -> str:
"""Convert config to JSON string with optional sensitive data handling."""
config_dict = self.model_dump()
if sensitive_handling and config_dict.get("params"):
# Mask sensitive keys
for key in ["api_key", "key", "token", "secret"]:
if key in config_dict["params"] and config_dict["params"][key]:
config_dict["params"][key] = encrypt(
config_dict["params"][key]
)
return str(config_dict)

@property
def normalized_language(self) -> str:
"""Convert language code to normalized format"""
language_map = {
"zh": "zh-CN",
"en": "en-US",
"ja": "ja-JP",
"ko": "ko-KR",
"yue": "yue-CN",
"de": "de-DE",
"fr": "fr-FR",
"ru": "ru-RU",
"es": "es-ES",
"pt": "pt-PT",
"it": "it-IT",
"hi": "hi-IN",
"ar": "ar-AE",
}
params_dict = self.params or {}
language_code = params_dict.get("language", "") or ""
return language_map.get(language_code, language_code)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#
# This file is part of TEN Framework, an open source project.
# Licensed under the Apache License, Version 2.0.
#

MODULE_NAME_ASR = "asr"
DUMP_FILE_NAME = "funasr_asr_in.pcm"
LOG_CATEGORY_VENDOR = "vendor"
LOG_CATEGORY_KEY_POINT = "key_point"
Loading
Loading