FunASR Agent 連携ガイド:OpenAI 互換 HTTP API、MCP サーバー、デスクトップ音声入力、字幕生成の4経路を実装コードで解読
【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR
FunASR の音声認識能力を外部の音声アプリケーション(ワークフロー、エージェント、デスクトップツール)に接続する方法を、4 通りのインターフェース——OpenAI 互換 HTTP サーバー、ローカル MCP ツール、デスクトップ録音、ローカル字幕生成——に沿って体系的に解説する。各経路が利用可能なモデル・オプション・出力フィールドが異なるため、本記事では エージェント連携ドキュメント の内容を軸に、リポジトリ内のサーバー実装(funasr/bin/server.py、funasr/bin/_server_app.py)とサンプルスクリプトの実コードを照らし合わせ、設定・コマンド・レスポンス契約の正誤を判定できる実務的な知識を提供する。プロセス内で直接推論を行う場合は Python SDK ガイド を参照する。
1. 4 経路の使い分け:モデル・オプション・出力フィールドは共有されない
FunASR では「用途に合ったインターフェースを選ぶ」ことが基本原則である。同じ音声認識でも、HTTP によるファイル文字起こし、ローカル MCP ツール、デスクトップ録音、ローカル字幕生成では、利用可能なモデル、オプション、出力フィールドがすべて異なる。
| 経路 | 起動方法 | 主なモデル | 特徴 |
|---|---|---|---|
| HTTP サーバー | funasr-server(パッケージ付属)またはexamples/openai_api/server.py(サンプル) | SenseVoice / Paraformer / Fun-ASR-Nano / MOSS-Transcribe-Diarize / カスタム | OpenAI 互換/v1/audio/transcriptions。リモート・コンテナ・ワークフロー向け |
| MCP サーバー | python examples/mcp_server/funasr_mcp.py | 既定iic/SenseVoiceSmall | AI アシスタント(Claude、Cursor 等)向け。stdio 経由で起動 |
| デスクトップ音声入力 | python examples/voice_input/funasr_input.py | HTTP サーバーのモデル | ホットキーで録音→転写→貼り付け |
| 字幕生成 | python examples/subtitle/generate_subtitle.py | 既定 SenseVoiceSmall(VAD + 句読点併用) | ローカルAutoModelパイプライン。SRT/VTT 出力 |
ここでの重要な原則は、どの経路の挙動を他の経路に転用してはならないことである。HTTP インターフェースの存在だけを根拠にタイムスタンプを保証したり、ある経路で有効なオプションを別経路に適用したりしないこと。
2. HTTP サーバーの準備:ソースベースのエディブルインストール
2.1 環境構築コマンド
パッケージの PyPI 版をインストールするだけでは、リポジトリ内のサンプルスクリプト(後述のserver.py、funasr_input.pyなど)は配置されない。POSIX シェルで、新しいチェックアウトと仮想環境を使う:
git clone https://github.com/modelscope/FunASR.git FunASR-agent cd FunASR-agent git checkout --detach e19029adca384a06a2f60bd8c18cb98f1a0499aa python3.11 -m venv .venv source .venv/bin/activate python -m pip install -e . python -m pip install fastapi uvicorn python-multipart python -m pip checkここで固定されるのはソースのリビジョンであり、依存パッケージやモデルの重みのすべてではない。インストールガイド に従って CPU/GPU 環境を準備し、解決したパッケージ・モデルのバージョンを記録して、対象モデルでの実際のリクエストで動作を確認すること。pip checkだけでは CUDA、音声デコーダー、クリーンインストールの成功を検証できない。
2.2funasr-serverの起動とコマンドライン引数
準備した環境で、次のコマンドのどちらか一方を実行する。CPU の例では SenseVoice を明示的に指定している。CUDA の例には動作する GPU 環境が必要である。サーバーのターミナルを開いたままにし、クライアントは別の準備済みターミナルから実行する。
funasr-server --host 127.0.0.1 --device cpu --model sensevoice --port 8000 # Alternative: stop the CPU server before using the same port. funasr-server --host 127.0.0.1 --device cuda --model sensevoice --port 8000ヘルスチェックとモデル一覧の確認:
curl -fsS http://localhost:8000/health curl -fsS http://localhost:8000/v1/models起動引数のデフォルト値と意味は、コンソールコマンドの定義箇所 サーバー入口 で確認できる。setup.pyのconsole_scriptsによりfunasr-server = funasr.bin.server:mainが登録されており、引数は以下の通りである:
| 引数 | デフォルト | 説明 |
|---|---|---|
--host | 0.0.0.0 | バインドアドレス。ローカル検証では127.0.0.1を推奨 |
--port | 8000 | ポート番号 |
--device | cuda | cuda/cpu/mps |
--model | auto | auto(GPU ならfun-asr-nano、それ以外はsensevoice)、sensevoice、paraformer、fun-asr-nano、moss-transcribe-diarize |
--model-path | なし | ローカルパスまたはモデル ID。指定するとリクエスト側はmodel="custom"を使う |
--hub | ms | ms(ModelScope)/hf(HuggingFace) |
--spk-model | cam++ | 話者モデル。最初のspk=trueリクエスト時に遅延ロードされる |
--cors-origin | 無効 | 信頼ブラウザオリジン。複数指定可。CORS は認証ではない |
2.3 エンドポイントの役割
- ファイルアップロード先は
/v1/audio/transcriptions(multipartPOST)。 - 稼働中サービスのスキーマは
/openapi.jsonにある。 - Swagger UI は
/docsである。この/docsは FunASR ウェブサイトの文書ディレクトリではない。 /healthは起動済みのモデルとデバイスを返す(実装:health エンドポイント)。
ヘルスチェックやモデル一覧の応答だけでは、対象モデルによる文字起こしの成功は確認できない。必ず実際の転写リクエストで検証すること。
2.4 パッケージ付属サーバーとサンプルサーバーの差(API 契約)
パッケージ付属のfunasr-serverと サンプル HTTP サーバー は、デフォルト値・モデル別名・応答スキーマが異なる。これは実装コードで裏付けられる:
- 起動時のモデル自動選択:create_app 内で
preload_model == "auto"のとき、deviceがcudaで始まればfun-asr-nano、それ以外はsensevoiceが読み込まれる。 - リクエストの
modelフォームデフォルト:パッケージ付属サーバーの transcribe エンドポイント では、multipart にmodelを省略するとfun-asr-nanoになる。起動時プリロードとは独立したデフォルトである。 - 組み込み別名:
FALLBACK_CONFIGS(参照)に登録されているのはsensevoice(iic/SenseVoiceSmall+fsmn-vad)、paraformer(paraformer-zh+fsmn-vad+ct-punc)、moss-transcribe-diarizeの 3 つ+fun-asr-nano+カスタム時のcustomである。paraformer-enはサンプルサーバー側の別名であり、パッケージ付属サーバーの組み込み別名ではない。 - n8n 向けエイリアス:リクエストの
model="whisper-1"は n8n が固定する OpenAI 互換モデル名として、サーバー既定モデルにマッピングされる(resolve_openai_transcription_model)。
したがって、起動時だけでなくリクエストにもmodelを指定することを徹底し、稼働中サービスの別名一覧は/v1/modelsで、フィールドは/openapi.jsonで確認する。カスタムモデルは適切な--hubと--model-pathで指定し、リクエストにはmodel="custom"を使う。任意のモデル ID がそのまま--modelの組み込み別名になるわけではない。
2.5 モデル特性に関する注意
- SenseVoice:HTTP 表示テキストからはリッチタグ(
<|...|>形式)が除去される(実装:_process_fallback の正規表現)。これは感情・イベントを専用フィールドで返す API ではない。 - Fun-ASR-Nano:基本版は中国語・英語・日本語と中国語方言・地域アクセントの評価経路であり、31 言語の Fun-ASR-MLT-Nano は別の checkpointである。基本 Nano の範囲から韓国語対応を推測したり、HTTP インターフェースだけを根拠にタイムスタンプを保証したりしないこと。実際の経路は モデル選択ガイド と デプロイ方式マトリクス で確認する。
- MOSS-Transcribe-Diarize:英語ドキュメント にある通り、OpenMOSS が提供する第三者モデルで、独自のデプロイ要件を持つ。ネイティブの話者ラベルは録音内の匿名ラベルであり、実在人物の識別ではない。外部 VAD や外部話者モデルは不要なので、これらの段階を追加しないこと(コードでも
NATIVE_DIARIZATION_MODELS = {"moss-transcribe-diarize"}が外部話者処理の対象外として定義されている:参照)。 - ローカルサーバーは認証しない:後の SDK 例の仮の API キーは認証されない。ネットワークに公開する前に、セキュリティガイド に従い、TLS、認証、アップロードサイズ制限、レート制限を設けること。
3. クライアント実装:OpenAI SDK と curl
3.1 OpenAI Python SDK
クライアント環境に OpenAI HTTP クライアントを別途インストールする(これは FunASR の Python SDK ではない):
python -m pip install openaifrom openai import OpenAI client = OpenAI(base_url="http://localhost:8000/v1", api_key="local-development") with open("meeting.wav", "rb") as audio: result = client.audio.transcriptions.create( model="sensevoice", file=audio, response_format="verbose_json", ) print(result.text) for segment in getattr(result, "segments", []): print(segment)api_keyはプレースホルダーであり、ローカルサーバーはこれを認証しない。
3.2 curl での直接呼び出し
curl -fsS http://localhost:8000/v1/audio/transcriptions \ -F file=@audio.wav \ -F model=sensevoice \ -F response_format=verbose_jsonパッケージ付属サーバーの multipart フォームフィールドは transcribe 関数のシグネチャ で確認できる:file(必須)、model、language、response_format、spk(response_formatはjson/text/verbose_jsonのいずれかで、textとjsonはより単純な応答形式である)。
3.3verbose_jsonが保証しないこと
verbose_jsonは応答形式を選ぶだけで、話者分離を有効にしたり、リッチタグを復元したり、単語単位の時刻やアラインメントを保証したりするものではない。この点は 2 つのサーバー実装の挙動差と照らして理解する:
- サンプルサーバー(
examples/openai_api/server.py):既存のsentence_infoからsegmentsを作り、情報がなければ空リストを返す。spkフォームフィールドは存在しない。 - パッケージ付属サーバー:
sentence_infoが無い場合、テキストと音源の長さを基準に粗い代替区間(フォールバック segments)を合成する。実装は build_openai_fallback_segments で、文字数比に応じて時刻を内挿する単純な手法であり、単語単位の強制的アラインメントではない。verbose_json応答の構造(task/language/duration/text/segments)は build_openai_verbose_json で構築される。 durationの意味差:両サービスとも segment の時刻は秒単位だが、サンプルサーバーのdurationはgenerate()前後の経過時間(秒)であり音源長さではない。一方パッケージ付属サーバーのdurationは音源の長さ(秒、メタデータ取得不能なら 0 の可能性がある)である。時刻を利用する前に クライアント応答の契約 を確認すること。- 話者処理:
spk=trueによる話者分離はパッケージ付属 API の機能であり、サンプルサーバーのリクエストスキーマにはない。パッケージ付属サーバーではspk=trueが付くと CAM++ 話者モデルが初めてのリクエスト時に遅延ロードされ、attach_speaker_labels により区間にSPK{n}形式の匿名話者ラベルが付与される。話者ラベルと人物識別の違いは 話者・感情ガイド を参照。
3.4 ワークフロー連携(Dify / n8n / webhook)
Dify / n8n などの HTTP ノードでは、文字起こしエンドポイントにPOSTで multipart を送る。バイナリファイルのフィールド名はfile、テキストフィールドはmodelとresponse_formatである。
fileに音声 URL を入れることは、音声のバイト列をアップロードすることと等価ではない。- コンテナ内の
localhostはそのコンテナ自身を指すため、FunASR ホストではない。意図したゲートウェイを経由してアクセスできるサービスアドレスを設定する。
リポジトリ内の対応レシピ:
- Dify / n8n / webhook worker:リクエストの接続例。
- JavaScript / TypeScript:SDK と multipart クライアント。
- Postman コレクション と スモークテスト:デプロイ済みエンドポイントの確認。
- Gradio:ブラウザのアップロードとマイク入力。
- OpenAPI:リポジトリにチェックインされたサンプルのスキーマと、稼働中のパッケージ付属サービスのスキーマの区別。
ホストフレームワークには、これらのリクエスト・応答の境界に従って文字起こしツールを登録する。ただし URL worker の例は完全な安全対策を備えたダウンローダーではない。信頼できない URL を受け付ける前に、宛先の許可リスト、プライベートネットワークへのアクセス遮断、リダイレクトの検証、サイズ制限、タイムアウトを追加すること。ワークフローのフィールド表が両サーバーにそのまま当てはまるとは限らないため、前述の応答契約を使うこと。これらの例は、すべてのフレームワークのバージョンで連携を検証した証拠でも、任意の URL の安全性を保証するものでもない。
4. MCP サーバー:AI アシスタントに文字起こしツールを登録する
4.1 起動とクライアント設定
準備済みのリポジトリのルートと環境から実行する:
python examples/mcp_server/funasr_mcp.py文字起こしの前に、インストールガイドに従って PyTorch と互換性のある音声特徴抽出バックエンドを準備する。ツールキットのインストールや MCP のハンドシェイク成功だけでは、モデルの実行は検証できない。このスクリプトは追加の MCP SDK パッケージを必要としない——funasr_mcp.py を読むと、JSON-RPC over stdio のハンドリング(initialize/tools/list/tools/callの分岐:handle_request)が標準ライブラリjson+sys.stdinループだけで実装されているのが確認できる。
MCP クライアントは HTTP ではなくstdioでスクリプトを起動する。準備済み Python 環境とチェックアウトの絶対パスを設定する:
{ "mcpServers": { "funasr": { "command": "/path/to/FunASR-agent/.venv/bin/python", "args": ["/path/to/FunASR-agent/examples/mcp_server/funasr_mcp.py"], "env": { "FUNASR_DEVICE": "cpu", "FUNASR_MODEL": "iic/SenseVoiceSmall" } } } }4.2transcribe_audioツールのスキーマと実装事実
ツール定義(tools/list 部分)とソースから確認できる重要な事実:
transcribe_audioはサーバーから見える既存のローカルaudio_pathを受け取る。コンテナに読み取り専用でマウントしたパスも使えるが、URL やライブストリームは受け取らない(呼び出し時にos.path.isfileでチェック:参照)。- 初回呼び出しでは重みのダウンロードとロードが発生する可能性がある(get_model が
AutoModelを遅初期化するため)。モデル構築時にfsmn-vadを併用し、max_single_segment_timeは 30000ms(30 秒)に固定されている。 - 言語ヒントは
auto、zh、yue、en、ja、koの 6 種類のみ(SUPPORTED_LANGUAGES:参照)。それ以外を渡すと明確なエラーで拒否される。 FUNASR_MODELを変更してもツールのスキーマは変わらず、別のモデルとその VAD 経路の互換性も保証されない。環境変数のデフォルトはFUNASR_DEVICE=cpu、FUNASR_MODEL=iic/SenseVoiceSmall(DEFAULT_MODEL)。- 結果は MCP の
content内のtype=textとして整形され、必要に応じて区間情報を含む。これはHTTP の応答オブジェクトではない。トップレベルの転写テキストからはリッチタグ(<\|...\|>形式)が正規表現で除去される(transcribe 関数)が、任意の区間テキストはモデル出力からそのままコピーされる。
MCP のソースとコンテナ設定 でクライアント設定とファイルシステムマウント方法を確認すること。アシスタントとサーバーがアクセスできるファイルを制限すること。ローカルツール自体はファイルシステムの権限境界ではない。
5. デスクトップ音声入力:録音 → 転写 → 貼り付け
HTTP サーバーを起動したまま、準備済みチェックアウトで別のターミナルを開く:
python -m pip install sounddevice numpy pyperclip openai pynput python examples/voice_input/funasr_input.py --server http://localhost:8000/v1 --model sensevoicefunasr_input.py の引数(argparse 定義):
| 引数 | デフォルト | 説明 |
|---|---|---|
--server | http://localhost:8000/v1 | FunASR サーバーの OpenAI 互換ベース URL |
--model | sensevoice | リクエストに渡すモデル名 |
--lang | auto | 言語ヒント(※後述の限界あり) |
--rate | 16000 | 録音のサンプリング周波数 |
--hotkey | ctrl+shift+space | 録音開始/停止のホットキー |
スクリプトの動作は:ホットキーで録音を開始・停止し、フレームを WAV にエンコードして HTTP サービスにアップロードし、転写テキストをコピーする(stop_and_transcribe)。貼り付けは macOS でosascript、Linux でxdotool key ctrl+vを使う。マイクの権限と音声デバイスの対応が必要で、macOS ではアクセシビリティ権限が必要な場合もある。クリップボードや貼り付けの挙動はデスクトップ環境に依存する。
実装上の重要な注意点:現在の--langは解析されるが文字起こしリクエストには渡されない。リクエスト部分 を見ると、create()に渡されるのはmodelとfileだけでlanguage引数が見えないため、この経路では--langは有効な言語指定ではない。
リモートの--serverを指定すると、録音がそのエンドポイントに送信される。したがって「常に完全オフラインである」「音声が端末外に出ない」「一定の遅延を達成する」などの保証はない。デプロイ前に 設定項目 と 実装本体 を確認すること。
6. 字幕生成:ローカルAutoModelパイプライン
これはローカルのAutoModelパイプラインであり、HTTP や MCP のクライアントではない。generate_subtitle.py は、準備済みチェックアウトで、ローカルの入力ファイルと適切な推論環境を使って実行する:
python examples/subtitle/generate_subtitle.py video.mp4 python examples/subtitle/generate_subtitle.py meeting.wav --spk python examples/subtitle/generate_subtitle.py podcast.mp3 --format vtt python examples/subtitle/generate_subtitle.py audio.wav --device cpu6.1 オプションの意味(実装で確認できる事実)
| オプション | デフォルト | 実装上の挙動 |
|---|---|---|
--device | cuda | 既定は CUDA。最後の例は CPU を明示選択 |
--model | iic/SenseVoiceSmall | AutoModel 構築 にfsmn-vadとct-puncを併用 |
--spk | 無効 | 有効時にspk_model="cam++"を追加。CAM++ による匿名話者ラベル(人物の身元は検証しない)。出力行は[Speaker N] テキスト形式 |
--format | srt | SRT / VTT 選択。時刻書式は SRT がコンマ、VTT がピリオド |
--output | 入力名 + 拡張子 | 既存の出力ファイルは上書きされる(open(output_path, "w"))。以前の字幕を残す場合は別のパスを指定 |
--lang | auto | auto以外の場合のみ推論のlanguage引数に渡される |
--max-single-segment-time | 60000 | VAD の単一区間上限。ミリ秒単位 |
この固定パイプラインは任意のモデルに適用できる汎用手順ではない。モデル名にFun-ASR-NanoまたはQwenを含む場合のみtrust_remote_code=Trueとhub="hf"が自動付与される(参照)。
6.2 区間モードとタイムスタンプの限界
generate()にはsentence_timestamp=True、output_timestamp=True、return_time_stamps=Trueが常に渡される(参照)。
--segment-mode readable(既定):認識テキストや句読点を書き換えず、funasr/cli.pyのmerge_subtitle_segmentsで表示用の字幕をまとめる。--segment-mode sentence:モデルの元の文単位の区切りを保つ。- どちらのモードも句読点の誤りを修正せず、音素の境界も保証しない。
タイムスタンプ欠如時のフォールバックは セグメント構築部 に現れる:sentence_infoが空でトップレベルにテキストのみがある場合、timestamp/timestampsから区間境界を推定できなければ(0, 0)の長さゼロ区間にフォールバックする。これは妥当性が確認された字幕ではない。実際のタイムスタンプの有無を確認し、元の音声と再生を照合すること。入力デコード、モデル・依存パッケージのロード、GPU 容量は環境ごとに検証が必要である。
出力の解釈には 字幕オプション と 話者ガイド を参照すること。
7. 検証チェックリスト
各経路で「動いた」ことを確認するための最低限の検証手順:
- HTTP サーバー:
/healthと/v1/modelsだけで十分ではない。実際の WAV をPOST /v1/audio/transcriptionsに投げ、期待言語のテキストが返ることを確認する。verbose_jsonを使う場合は segment 時刻(秒)とdurationの意味を、該当サーバーの応答契約で確認する。 - MCP:
initializeハンドシェイクの成功はモデル実行の検証ではない。初回tools/callの遅延(重み DL/ロード込み)を許容し、返却テキストが空でないことを確認する。 - デスクトップ入力:ローカルサーバーでの往復を確認のうえ、リモート
--serverへの切替はネットワーク設定とプライバシー要件のレビュー後に実施する。 - 字幕:生成 SRT/VTT をプレーヤーで再生し、時刻とテキストを照合する。
(0, 0)区間や極端に長い単一区間を検出したら、入力デコードとモデル経路を疑う。
共通の鉄則は 2 つである:インターフェースごとにモデル・オプション・フィールド契約が異なるので、他の経路の知識を横流ししないこと、そしてヘルスチェック・ハンドシェイク・pip checkはすべて「起動できた」の証拠であり「認識が成功した」の証拠ではないこと。
【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考