チュートリアル

ゼロからプロダクションまで——10 分で FunASR を完全にマスター。

30 秒デモ

以下をコピペして実行するだけ。設定不要——FunASR がすべて自動ダウンロードします:

pip install funasr

python -c "
from funasr import AutoModel
model = AutoModel(model='paraformer-zh', vad_model='fsmn-vad', punc_model='ct-punc')
res = model.generate(input='https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav')
print(res[0]['text'])
"

出力:

欢迎大家来体验达摩院推出的语音识别模型。

これだけです。1 つのモデルオブジェクトが音声読み込み、VAD セグメンテーション、ASR、句読点のすべてを処理します。

インストール

# 安定版
pip install funasr

# 最新版(推奨——最新モデルとバグ修正を含む)
pip install git+https://github.com/modelscope/FunASR.git
中国のユーザー:モデルはデフォルトで ModelScope からダウンロード(中国国内では高速)。海外ユーザー:hub="hf" を追加して HuggingFace からダウンロード。

どのモデルを使うべきか?

モデル最適な用途対応言語速度句読点
Paraformer中国語本番 ASR中国語・英語高速punc_model 必要
Fun-ASR-Nano多言語・方言・歌詞31 言語中程度内蔵 ✓
SenseVoice感情 + イベント + ASR5 言語超高速(10s → 70ms)内蔵 ✓
Qwen3-ASR最高精度・文脈理解52 言語低速(LLM)内蔵 ✓
Paraformer-Streamingリアルタイム文字起こし中国語リアルタイムpunc_model 必要
おすすめ:
• 中国語会議/通話 → paraformer-zh + fsmn-vad + ct-punc + cam++
• 多言語 → Fun-ASR-Nano
• 感情/音声イベント検出 → SenseVoice
• リアルタイム字幕 → paraformer-zh-streaming
• 最高品質・レイテンシ不問 → Qwen3-ASR

使用シナリオ

🎤 「会議の録音をテキスト化して、誰が話したか区別したい」

→ Paraformer + VAD + 句読点 + 話者分離 → 話者分離へ

📺 「ライブ配信にリアルタイム字幕をつけたい」

→ Paraformer-Streaming、600ms ごとに音声チャンクを入力 → ストリーミング ASR へ

😊 「音声からユーザーの感情を検出したい」

→ SenseVoice(感情タグを出力:happy、sad、angry、neutral)→ 感情検出へ

🌍 「日本語/韓国語/アラビア語などの音声がある」

→ Fun-ASR-Nano(31 言語)または Qwen3-ASR(52 言語)→ オフライン ASR へ

✂️ 「話した内容に基づいて動画をクリップしたい」

FunClip を使用(FunASR を統合したスマート動画編集ツール)

オフライン ASR

Paraformer(中国語)

from funasr import AutoModel

model = AutoModel(
    model="paraformer-zh",          # 中国語 ASR
    vad_model="fsmn-vad",           # 任意の長さの音声に対応
    vad_kwargs={"max_single_segment_time": 60000},
    punc_model="ct-punc",           # 句読点を追加
)
res = model.generate(input="meeting.wav", batch_size_s=300, hotword='达摩院 语音识别')
print(res[0]["text"])       # "欢迎大家来体验达摩院推出的语音识别模型。"
print(res[0]["timestamp"])  # [[880,1120],[1120,1360],...] (文字ごとのms タイムスタンプ)

Fun-ASR-Nano(31 言語)

from funasr import AutoModel

model = AutoModel(
    model="FunAudioLLM/Fun-ASR-Nano-2512",
    trust_remote_code=True,
    remote_code="./model.py",
    vad_model="fsmn-vad",
    vad_kwargs={"max_single_segment_time": 30000},
    device="cuda:0",
    hub="hf",
)
res = model.generate(input=["audio.wav"], cache={}, batch_size=1,
                     hotwords=["keyword"], language="中文")
print(res[0]["text"])        # 句読点付き認識テキスト
print(res[0]["timestamps"])  # [{"token":"開","start_time":0.42,"end_time":0.48}, ...]
Fun-ASR-Nano は句読点を内蔵出力——punc_model は不要です。

SenseVoice(ASR + 感情 + イベント)

from funasr import AutoModel
from funasr.utils.postprocess_utils import rich_transcription_postprocess

model = AutoModel(
    model="iic/SenseVoiceSmall",
    vad_model="fsmn-vad",
    vad_kwargs={"max_single_segment_time": 30000},
    device="cuda:0",
)
res = model.generate(input="audio.wav", cache={}, language="auto",
                     use_itn=True, batch_size_s=60, merge_vad=True, merge_length_s=15)

# 生の出力には感情/イベントタグが含まれる:<|zh|><|HAPPY|><|Speech|>你好
text = rich_transcription_postprocess(res[0]["text"])
print(text)  # "你好"(クリーンテキスト)

Qwen3-ASR(52 言語・最高精度)

# pip install qwen-asr
from funasr import AutoModel

model = AutoModel(model="Qwen/Qwen3-ASR-1.7B", hub="hf", device="cuda:0")
res = model.generate(input="audio.wav")
print(res[0]["text"])             # 認識テキスト
print(res[0].get("language"))    # 自動検出された言語

ストリーミング ASR(リアルタイム)

音声をチャンクごとに処理してリアルタイム文字起こしを実現。各チャンクが即座に部分テキストを返します。

from funasr import AutoModel
import soundfile

model = AutoModel(model="paraformer-zh-streaming")

speech, sr = soundfile.read("audio.wav")
chunk_size = [0, 10, 5]          # 600ms 表示、300ms 先読み
chunk_stride = chunk_size[1] * 960  # チャンクあたり 9600 サンプル

cache = {}
total_chunks = int((len(speech) - 1) / chunk_stride + 1)
for i in range(total_chunks):
    chunk = speech[i * chunk_stride:(i + 1) * chunk_stride]
    is_final = (i == total_chunks - 1)

    res = model.generate(input=chunk, cache=cache, is_final=is_final,
                         chunk_size=chunk_size,
                         encoder_chunk_look_back=4,
                         decoder_chunk_look_back=1)
    if res[0]["text"]:
        print(res[0]["text"], end="", flush=True)  # インクリメンタル出力

出力(段階的に表示):

欢迎大 | 家来 | 体验达 | 摩院推 | 出的语 | 音识 | 别模型
重要ポイント:
cache={} はすべてのチャンク間で保持する必要がある(再作成しないこと)
• 最後のチャンクで is_final=True を設定し、バッファ内の残りテキストを出力
chunk_size=[0,10,5]:最初の数値は未使用、2番目=表示粒度(×60ms)、3番目=先読み(×60ms)

話者分離(「誰が何を言ったか」)

3 つの主要モデルすべてに対応:Paraformer、Fun-ASR-Nano、SenseVoice。spk_model="cam++" を追加するだけで文ごとに話者ラベルが付きます。

Paraformer + 話者分離

from funasr import AutoModel

model = AutoModel(
    model="paraformer-zh",
    vad_model="fsmn-vad",
    punc_model="ct-punc",      # Paraformer は文分割に句読点モデルが必要
    spk_model="cam++",
)
res = model.generate(input="meeting.wav", batch_size_s=300)

for sent in res[0]["sentence_info"]:
    print(f"[話者 {sent['spk']}] [{sent['start']}-{sent['end']}ms] {sent['text']}")

出力:

[話者 0] [880-5195ms] 欢迎大家来体验达摩院推出的语音识别模型。

Fun-ASR-Nano + 話者分離(punc 不要)

model = AutoModel(
    model="FunAudioLLM/Fun-ASR-Nano-2512",
    trust_remote_code=True, remote_code="./model.py",
    vad_model="fsmn-vad", vad_kwargs={"max_single_segment_time": 30000},
    spk_model="cam++",     # punc_model 不要!
    device="cuda:0", hub="hf",
)
res = model.generate(input=["meeting.wav"], cache={}, batch_size=1, language="中文")
for sent in res[0]["sentence_info"]:
    print(f"話者 {sent['spk']}: {sent.get('text', sent.get('sentence', ''))}")

SenseVoice + 話者分離(punc 不要)

model = AutoModel(
    model="iic/SenseVoiceSmall",
    vad_model="fsmn-vad", vad_kwargs={"max_single_segment_time": 30000},
    spk_model="cam++",    # punc_model 不要!
    device="cuda:0",
)
res = model.generate(input="meeting.wav", cache={}, language="auto",
                     use_itn=True, batch_size_s=60, merge_vad=True, merge_length_s=15)
for sent in res[0]["sentence_info"]:
    print(f"話者 {sent['spk']}: {rich_transcription_postprocess(sent['text'])}")

感情検出

専用感情モデル(emotion2vec)

from funasr import AutoModel

model = AutoModel(model="iic/emotion2vec_plus_large", device="cuda:0")
res = model.generate(input="audio.wav", granularity="utterance")

print(res[0]["labels"])  # ['angry', 'happy', 'neutral', 'sad', ...]
print(res[0]["scores"])  # [0.01,   0.03,   0.89,      0.05, ...]
# → この音声は「neutral」で信頼度 89%

SenseVoice(1 回の推論で ASR と感情検出を同時実行)

SenseVoice は認識結果に感情タグを直接埋め込みます:

# 生の出力:"<|zh|><|HAPPY|><|Speech|><|withitn|>今天真是太开心了。"
# <|HAPPY|> タグがその音声区間の感情を示す
# rich_transcription_postprocess() でクリーンテキストを取得

音声活動検出(VAD)

オフライン(完全音声)

from funasr import AutoModel

model = AutoModel(model="fsmn-vad")
res = model.generate(input="audio.wav")
print(res[0]["value"])  # [[610, 5530], [7200, 12400], ...]
                         # 各ペア:[開始ms, 終了ms] 音声区間

ストリーミング(チャンクごと)

import soundfile
from funasr import AutoModel

model = AutoModel(model="fsmn-vad")
speech, sr = soundfile.read("audio.wav")
chunk_stride = int(200 * sr / 1000)  # 200ms チャンク

cache = {}
for i in range(int((len(speech)-1)/chunk_stride+1)):
    chunk = speech[i*chunk_stride:(i+1)*chunk_stride]
    is_final = i == int((len(speech)-1)/chunk_stride)
    res = model.generate(input=chunk, cache=cache, is_final=is_final, chunk_size=200)
    if res[0]["value"]:
        print(res[0]["value"])
        # [[610, -1]]   → 610ms で音声開始
        # [[-1, 5530]]  → 5530ms で音声終了
        # [[610, 5530]] → 完全なセグメント

句読点復元

from funasr import AutoModel

model = AutoModel(model="ct-punc")
res = model.generate(input="那今天的会就到这里吧 happy new year 明年见")
print(res[0]["text"])  # "那今天的会就到这里吧,happy new year,明年见。"
いつ必要か?Paraformer のみ(句読点なしのテキストを出力するため)。Fun-ASR-Nano、SenseVoice、Qwen3-ASR は句読点を内蔵出力します。

ONNX エクスポート

# モデルを ONNX フォーマットにエクスポート
from funasr import AutoModel
model = AutoModel(model="paraformer", device="cpu")
model.export(quantize=False)   # モデルキャッシュディレクトリに保存

# ONNX モデルを使用(高速、PyTorch 不要)
# pip install funasr-onnx
from funasr_onnx import Paraformer
model = Paraformer("damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch",
                   batch_size=1, quantize=True)
result = model(["audio.wav"])
print(result)

FAQ・トラブルシューティング

モデルのダウンロードが遅い

hub="hf" で HuggingFace に切り替え(中国国外では高速)、または一度ダウンロードしてローカルパスを使用:

model = AutoModel(model="/path/to/local/model", disable_update=True)

メモリ不足(OOM)

メモリを削減する 3 つの方法:

  1. batch_size_s を減らす(例:300 → 60)
  2. vad_kwargs の max_single_segment_time を減らす(例:30000 → 15000)
  3. batch_size_threshold_s=30 を追加して長いセグメントに batch=1 を強制

起動のたびに "Downloading Model..." と表示される

実際にはダウンロードしていません——キャッシュの検証をしているだけです。完全にスキップするには:

model = AutoModel(model="/local/path/to/model", disable_update=True)

"ModelName is not registered" エラー

通常は pip 版が古いことが原因。ソースからインストール:

pip install git+https://github.com/modelscope/FunASR.git

プログレスバーとログをすべて非表示にしたい

model = AutoModel(model="...", disable_update=True, disable_pbar=True, log_level="ERROR")

読み込み済みの numpy 音声を渡すには?

import soundfile as sf
audio, sr = sf.read("audio.wav")  # numpy 配列、16kHz
res = model.generate(input=audio)  # 直接渡す——ファイル不要

GPU が使われていない?

# 確認:
import torch
print(torch.cuda.is_available())  # True であること

# GPU を明示的に指定:
model = AutoModel(model="...", device="cuda:0")