FunASR OpenAI 互換 API サーバー完全ガイド:/v1/audio/transcriptionsで音声認識を OpenAI 互換に公開する実装と運用
【免费下载链接】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 の OpenAI 互換 API サーバーは、/v1/audio/transcriptionsという OpenAI 形式のエンドポイントを private な音声転写に提供するサンプル実装です。本記事ではリポジトリ内の サンプルサービス を軸に、API 契約の境界、クイックスタート、OpenAI SDK / curl / エージェントフレームワークからの利用法、Docker / Kubernetes デプロイ、設定パラメータ、トラブルシューティングまでを、ソースコードレベルの裏付けとともに解説します。読み終えると、ローカルで OpenAI 互換の音声認識 API を立ち上げ、任意の OpenAI 互換クライアントから安全に呼び出す実戦手順を身につけられます。
このサンプルの位置づけとスコープ
FunASR OpenAI 互換 API は、音声ファイルを multipart HTTP で送る/v1/audio/transcriptionsを提供します。これは音声転写用の OpenAI API の一部であり、API 全体、リアルタイム API、すべての SDK やフレームワーク機能への互換性を保証するものではありません。あくまで「OpenAI の音声転写サブセット」を private に再現するサンプルです。
本ページはリポジトリ内の サンプルサービス の手順です。パッケージ付属のfunasr-serverは 別の実装 であり、設定を流用する前に API 契約 を確認してください。日本語 Agent ガイド はパッケージ付属サービスや各種連携の入口です。プロセス内でAutoModel.generate()を呼び出す場合は、Python SDK ガイドの英語版または中国語版を参照してください。
ローカル開発から始めてください。このサービスには認証機能やアプリケーション側のアップロードサイズ上限が組み込まれておらず、SDK の仮の API キーも認証しません。以下ではホストの loopback に明示的にバインドします。共有・公開する前に、セキュリティとゲートウェイガイド に従い、TLS、認証、アップロードサイズ制限、レート制限、クライアントとゲートウェイのタイムアウトを設けてください。音声・転写文の保存期間とアクセス権を決め、/health、/v1/models、/openapi.jsonと Swagger UI/docsへのアクセスも制限します。CORS は認証の代わりにはなりません。
API 契約(API Contract)
サンプルサーバーとパッケージ付属サーバーでは、モデル既定値やレスポンススキーマが異なります。混同を避けるため、まず契約の境界を整理します。
- サンプル
server.py: 起動時のプリロードと、multipartmodel省略時の既定値はどちらもsensevoiceです。フォームはfile、model、language、response_formatを受け取ります。以下ではjsonまたはverbose_jsonを使います。 - パッケージ付属
funasr-server: CLI の既定値--model autoは、デバイス文字列がcudaで始まる場合にfun-asr-nano、それ以外ではsensevoiceを選びます(実装箇所 のプリロード選択ロジックで確認できます)。一方、multipartmodelを省略すると、プリロードとは独立してfun-asr-nanoになります。
リクエストには毎回modelを明示し、稼働中の/v1/modelsと/openapi.jsonを確認してください。paraformer-enはサンプルサービスに登録されていますが、パッケージ付属サービスの組み込み別名ではありません。パッケージ付属サービスでカスタムモデルを使う場合は--model-pathと適切な--hubを設定し、リクエストはmodel="custom"とします。これらの CLI オプションはサンプルserver.pyにはありません。任意の checkpoint ID を--modelに渡せるという意味でもありません。
response_format=verbose_jsonは応答形式の選択であり、話者分離やタイムスタンプ生成を有効にするスイッチではありません。サンプルサービスはモデルが返したsentence_infoのみをsegmentsに変換し、なければsegments=[]を返します。SDK のtimestampsやctc_timestampsが存在しても、それらを直接 HTTP のsegmentsとして返す処理ではありません。Nano の CTC 時刻は必要な学習済み重みが揃っていることに依存し、HTTP 経由で常に取得できるわけではありません。
サンプルにはspkフォームフィールドがありません。spk=trueを送っても外部話者処理は有効になりません。パッケージ付属サービスではspk=trueにより、ネイティブ話者分離モデル以外に対して別の話者処理を要求できます(既定値はFalse、対応する依存環境とモデルが必要です)。MOSS のネイティブ出力は録音内の匿名ラベルであり、実在する人物の識別や別録音間の同一人物判定ではありません。MOSS に外部 VAD や話者モデルを追加しないでください。
両サービスのstart/endは秒単位です。SDK のsentence_infoに含まれるミリ秒の座標は、HTTP アダプターで秒に変換されます(サンプルではseg.get("start", 0) / 1000.0という変換が行われます)。サンプルのdurationはgenerate()の処理時間で、初回モデルロードを含まず、音声の長さではありません。サンプルのlanguageは送信したヒント、未指定ならautoであり、言語検出結果とは限りません。パッケージ付属サービスのdurationは音声の長さで、fallback 経路ではメタデータを読めない場合に 0 になることがあります。languageはauto以外の明示したヒントを優先し、それがなければ取得できた検出結果を使います。パッケージ付属サービスの fallback はテキストと音声の長さから粗い区間を合成する場合があり、単語単位の強制アラインメントではありません。
パッケージ付属の verbose 応答はtaskと区間ごとのid/wordsを含み、サンプルはmodelを含みます。話者フィールドは欠落または null の場合があります。共通の完全な JSON スキーマとは考えず、応答例と話者リクエスト を確認してください。languageヒントの意味もモデル依存です。SDK のuse_itn、hotwords、キャッシュ、配列入力などはこの HTTP フォームのオプションではなく、AutoModel.generate()の全機能が公開されているわけではありません。
クイックスタート
POSIX シェルと Python 3.11 を使い、新しいチェックアウトと仮想環境を作成します。PyPI パッケージのインストールだけでは、このリポジトリのサンプルファイルは配置されません。
git clone https://github.com/modelscope/FunASR.git FunASR-api cd FunASR-api git checkout --detach d91d961e37a005837b1523bcc6b09f087877be54 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 cd examples/openai_api python server.py --host 127.0.0.1 --model sensevoice --device cpu --port 8000固定するのはソースの revision です。依存パッケージ、モデル重み、音声デコーダー、CUDA 環境まで固定する手順ではありません。インストールガイド に従って対象環境を準備してください。バージョン表示が1.4.14でも、公開済み PyPI パッケージと修正済みソースが同じ内容とは限りません。pip checkは依存宣言の整合性を調べるもので、新規インストールや音声推論の成功を証明しません。
CUDA を利用する場合は対応する PyTorch、ドライバーなどを準備し、CPU サーバーを停止してから、同じ仮想環境とexamples/openai_apiディレクトリで次の代替コマンドを実行します。同じポートで両方を同時起動しないでください。
python server.py --host 127.0.0.1 --model sensevoice --device cuda --port 8000モデルのロードを待ち、サーバー用ターミナルはそのままにします。初回ダウンロードや起動時間は checkpoint、キャッシュ、ネットワーク、ハードウェアに依存します。以下のクライアント操作は別のターミナルで行います。最初にgit cloneを実行した親ディレクトリから、同じ環境と作業ディレクトリに入ってください。
cd FunASR-api source .venv/bin/activate cd examples/openai_api curl -fsS http://localhost:8000/health curl -fsS http://localhost:8000/v1/models curl -fsS http://localhost:8000/openapi.jsonヘルスチェックやモデル一覧の成功だけでは、音声転写の成功は確認できません。別途記載がない限り、以降のクライアントコマンドはこのディレクトリで実行します。
コピーして使える連携例が必要な場合は、クライアントレシピ、JavaScript/TypeScript レシピ、Gradio ブラウザデモ、ワークフローレシピ、Postman コレクション、OpenAPI 仕様、セキュリティとゲートウェイガイド、Kubernetes デプロイテンプレート を参照してください。
エンドツーエンド smoke test
上記で準備したクライアント用ターミナルで、次のどちらかを実行できます。これは検証手順であり、対象環境での実行済み結果を示すものではありません。
bash smoke_test.sh # curl/bash を使わないクロスプラットフォーム版: python smoke_test.py手動で確認する場合は、次の公開サンプルを利用できます。これは中国語の音声であり、このサンプルの転写は日本語や韓国語の精度検証ではありません。
curl -fL https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/BAC009S0764W0121.wav -o sample.wav curl -fsS http://localhost:8000/health curl -fsS http://localhost:8000/v1/audio/transcriptions \ -F file=@sample.wav \ -F model=sensevoice \ -F response_format=verbose_jsonsmoke_test.pyはurllibのみで multipart ボディを組み立てるため、curl/bash が使えない環境でも/health→/v1/models→ 転写の順に検証できます。--base-url、--model、--response-format、--timeoutなどの引数と、BASE_URL/MODEL/RESPONSE_FORMAT/SAMPLE_URL/TIMEOUT環境変数に対応しています(実装)。
Gradio ブラウザデモ
ローカルファイルのアップロードやマイクで録音した音声の送信には、保守されている Gradio ブラウザデモ を参照してください。この API サーバーとは別の Python 3.12 環境.venv-gradioを使用します。ガイドではfunasr、vllm、sglang-omniの profiles、明示的なモデル選択、Docker/Kubernetes への接続、マイク権限、プライバシー上の制約を説明しています。UI は独立した HTTP クライアントであり、認証ゲートウェイでもリアルタイム文字起こしサービスでもありません。
OpenAI SDK で使う
OpenAI の HTTP クライアントを別途インストールします。これは FunASR のプロセス内 Python SDK ではありません。
python -m pip install openaimeeting.wavを実際のローカル音声ファイルに置き換えて実行します。デコード可能な形式は準備した音声依存環境にも依存します。仮のapi_keyは SDK の必須引数を満たすための値で、サンプルサービスによる認証ではありません。
from openai import OpenAI client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed") with open("meeting.wav", "rb") as audio: result = client.audio.transcriptions.create( model="sensevoice", file=audio, ) print(result.text) with open("meeting.wav", "rb") as audio: verbose = client.audio.transcriptions.create( model="sensevoice", file=audio, response_format="verbose_json", ) print(getattr(verbose, "segments", []))区間配列は空でも構いません。区間が返っても、そのことだけで正確な字幕時刻や話者分離が確認できるわけではありません。API 契約 を参照してください。
curl で使う
audio.wavは実際のローカル音声ファイルに置き換えてください。JSON に配列や URL を入れるのではなく、fileにバイナリファイルを multipart で送ります。
curl -fsS http://localhost:8000/v1/audio/transcriptions \ -F file=@audio.wav \ -F model=sensevoice curl -fsS http://localhost:8000/v1/audio/transcriptions \ -F file=@audio.wav \ -F model=sensevoice \ -F response_format=verbose_json利用できるモデル
以下はサンプルserver.pyのMODEL_CONFIGS(定義箇所)にある 5 つの別名です。SDK 全体やすべてのサーバーの共通モデル一覧ではなく、一定の処理速度や同時実行数を保証する表でもありません。
sensevoice: SenseVoiceSmall + FSMN-VAD。既定では文単位のタイムスタンプや外部話者クラスタリングを有効にしません(VAD にはmax_single_segment_time: 30000が設定されています)。paraformer:paraformer-zh+ FSMN-VAD + CT 句読点モデル(ct-punc)。句読点処理は設定されていますが、verbose_jsonだけでは文単位の記録を要求しません。paraformer-en:paraformer-en+ FSMN-VAD。このサンプルには句読点モデルの設定がなく、パッケージ付属サービスの組み込み別名でもありません。fun-asr-nano: HF の Fun-ASR-Nano(FunAudioLLM/Fun-ASR-Nano-2512)をAutoModel+ FSMN-VAD で使用します(hub: "hf"、trust_remote_code: True)。このサンプルは vLLM 経路ではなく、CTC 時刻が HTTP 区間として返る保証もありません。moss-transcribe-diarize: 第三者 OpenMOSS のネイティブ転写・話者分離アダプター(OpenMOSS-Team/MOSS-Transcribe-Diarize、固定 revisione8681d68e7042738ffca8ac8212bc8fcb1131ab8、backend: "hf")。専用の依存環境が必要で、モデルが返した時刻と匿名話者ラベルを保持します。
SenseVoice の HTTP テキストからは<|...|>のリッチタグが除去されます(サンプルの clean_text がre.sub(r'<\|[^|]*\|>', '', text)で除去します)。感情・イベントの専用フィールドを返す API ではありません。生のモデル出力が必要な場合はモデル別の Python SDK 契約を確認してください。
基本の Fun-ASR-Nano は中国語・英語・日本語と中国語方言・地域アクセントを対象とする経路であり、韓国語対応を含むという意味ではありません。31 言語のFun-ASR-MLT-Nano は別の checkpointで、この 2 つのサービスの組み込み別名ではありません。対象言語とモデル重みのライセンスはモデル選択ガイド と個別のモデルカードで確認してください。FunASR ソフトウェアの MIT ライセンスは、すべてのモデル重みのライセンスを意味しません。
MOSS は固定 revision の third-party HF model を使用し、外部 VAD / speaker model とは併用しません。ラベルは録音内の匿名話者を示すもので、人物の身元を検証するものではありません。MOSS deployment guide にfunasr-server、Docker、Kubernetes、vLLM、SGLang Omni、LocalAI、FunClip の個別経路をまとめています。別名が一覧に存在するだけでは、全モデルのロード済み状態や依存環境の互換性は確認できません。
API エンドポイント
| Endpoint | Method | 説明 |
|---|---|---|
/v1/audio/transcriptions | POST | OpenAI 互換の音声文字起こし |
/v1/models | GET | モデルエイリアスの一覧(readyフラグ付き) |
/health | GET | ヘルスチェック、ロード済みモデル、利用可能モデル |
/docs | GET | FastAPI Swagger ドキュメント |
/openapi.json | GET | 稼働中のサービスのスキーマ |
コードを書かずに確認したい場合は、Gradio ブラウザデモ でローカルアップロードやマイク入力を試すか、Postman コレクション をインポートしてください。OpenAPI 仕様 はサンプル用の資料であり、パッケージ付属サービスの全フィールドを表すものではありません。API ゲートウェイやクライアント生成には稼働中のスキーマも確認してください。
エージェントとローコードワークフロー
LangChain、LlamaIndex、AutoGen、CrewAI、Semantic Kernel、Dify、n8nなどには、multipart HTTP またはツール関数を介して接続できます。利用するバージョンと本サービスのフィールドで個別に確認してください。全フレームワーク機能やリアルタイム API の互換性を保証するものではありません。
両サービスは、n8n 向けの特別なリクエスト別名whisper-1を、起動時に選択したモデルへ対応付けます(サンプルでは resolve_openai_transcription_model がwhisper-1をDEFAULT_MODELに解決します)。これは OpenAI Whisper を実行する指定ではありません。パッケージ付属サービスで--model-pathを指定している場合はcustomに対応します。通常の HTTP ノードではmodelを明示し、この互換別名を任意のモデル切替機構として扱わないでください。
Dify/n8n のファイルは multipart のバイナリfileとして渡します。コンテナ内のlocalhostはそのコンテナ自身です。認可されたサービス名や到達可能なホストを設定し、接続問題の回避策として無認証の公開サービスにしないでください。URL を取得する worker を使う場合は、取得先の検証やサイズ制限も別途必要です。
- SDK、JavaScript/TypeScript、Agent tool の書き方は クライアントレシピ と JavaScript/TypeScript レシピ を参照してください。
- Dify、n8n、HTTP ノード、webhook worker は ワークフローレシピ を参照してください。
- GUI smoke test は Postman コレクション を参照してください。
- schema-driven import には OpenAPI 仕様 を使えます。
Docker デプロイ
リポジトリのルートから次のコマンドを実行します。すでにホスト側のサーバーを起動している場合は停止し、ポートを空けてください。既定のイメージはサンプルserver.pyを CPU モードで起動し、パッケージ付属のfunasr-serverは起動しません。
Dockerfile はバージョン未固定の PyPI FunASR と依存パッケージをインストールして、チェックアウトのserver.pyをコピーします。上のソース固定・editable install と同じ環境ではなく、再現可能なモデル検証済みイメージとも限りません。実際の Dockerfile はpython:3.10-slimベースでffmpeg、git、libsndfile1を入れ、HEALTHCHECKで/healthを確認する構成です。
cd examples/openai_api cp .env.example .env FUNASR_HOST_PORT=127.0.0.1:8000 docker compose up --buildこの POSIX シェルのプレフィックスは、既存 Compose ファイルのホスト側公開ポートを loopback に限定します。コンテナ内部のリスナーは0.0.0.0のままにしてください。コンテナのリスナーを127.0.0.1に変更することとは異なります。ホスト側 loopback はローカル開発用の設定であり、認証やネットワーク全体の安全性を保証するものではありません。
Compose と同時に起動しない場合のdocker run:
docker build -t funasr-api . docker run --rm -p 127.0.0.1:8000:8000 \ -e FUNASR_DEVICE=cpu \ -e FUNASR_MODEL=sensevoice \ funasr-apiGPU ホストでは NVIDIA Container Toolkit と CUDA 対応の PyTorch/FunASR イメージが必要です。CUDA 依存関係に合わせてイメージを調整した後、次のように起動できます。
docker run --rm --gpus all -p 127.0.0.1:8000:8000 \ -e FUNASR_DEVICE=cuda \ -e FUNASR_MODEL=sensevoice \ funasr-apiコンテナ起動後、同じ環境とサンプルディレクトリを用意した別のターミナルで、いずれかの方法で確認できます:
BASE_URL=http://localhost:8000 bash smoke_test.sh python smoke_test.py --base-url http://localhost:8000追加の build/run/smoke 手順は validate_docker.sh にありますが、既定ではホストの全インターフェースにポートを公開し、上記の loopback 設定を引き継ぎません。実行前にネットワーク設定を確認し、共有ネットワークでのローカル検証には上記の明示的な loopback 手順を使ってください。GPU モードには CUDA 対応イメージと NVIDIA Container Toolkit が必要です。このページの記述は Docker や音声推論の実行済み検証結果ではありません。
Kubernetes デプロイ
チーム内で共有したりゲートウェイ経由で公開したりする前に、セキュリティとゲートウェイガイド を確認し、TLS、認証、アップロード制限、レート制限、タイムアウト、ログと保存期間の方針を整えてください。
永続化されたモデルキャッシュ、ヘルスプローブ、プライベートClusterIPを持つ内部クラスタサービスが必要な場合は、Kubernetes デプロイテンプレート から始めてください。サンプルイメージをビルドして push し、manifests を適用した後、kubectl port-forwardとpython smoke_test.py --base-url http://localhost:8000で検証します。
CUDA 対応イメージと GPU スケジューリング設定が整うまでは、デフォルトの CPU モードを維持してください。
設定
以下はサンプルserver.pyの既定値(main の argparse)であり、funasr-serverの既定値ではありません。API 契約 と比較してください。ローカル手順では安全のため--host 127.0.0.1と--device cpuを明示しています。
| 引数 | デフォルト | 説明 |
|---|---|---|
--host | 0.0.0.0 | バインドアドレス |
--port | 8000 | ポート |
--device | cuda | cuda、cpu、mps |
--model | sensevoice | 起動時にプリロードするモデル |
Docker 環境変数:
| Env | デフォルト | 説明 |
|---|---|---|
FUNASR_PORT | 8000 | server.pyに渡すコンテナポート |
FUNASR_DEVICE | cpu | コンテナのデバイスモード。CUDA 対応依存関係を持つイメージでのみcudaに設定してください |
FUNASR_MODEL | sensevoice | コンテナ起動時にロードするモデルエイリアス |
FUNASR_HOST_PORT | 8000 | Compose のホスト側ポート指定。上のローカル手順では127.0.0.1:8000を指定します。 |
サーバー実装の仕組み
サンプルサーバーの処理フローを server.py で確認できます。
- モデルレジストリと遅延ロード:
MODEL_REGISTRYにロード済みモデルを保持し、load_model は未ロードの別名だけAutoModel(**cfg)で構築します。disable_update=Trueが設定され、起動時の--modelだけがプリロードされます。リクエストで別の別名が指定された場合、その時点で追加ロードされるため、/v1/modelsのreadyフラグが「全モデルロード済み」を意味しません。 - 転写エンドポイント: transcribe は multipart の
fileを一時ファイルに保存し、AutoModel.generate(input=tmp_path, batch_size=1)を呼びます。verbose_json時のみ、モデルが返したsentence_infoのstart/end(ミリ秒)を 1000 で割って秒に変換し、speakerはspkをそのまま保持、なければnullとします。durationはgenerate()の前後で測った経過秒です。 - ヘルスチェックとモデル一覧: health は device・ロード済み・利用可能モデルを返し、list_models は OpenAI 形式の
object: "model"リストにreadyフラグを付けて返します。
パッケージ付属サービス側の挙動は、テスト や サーバー実装 で裏付けられています。spk=trueによる CAM++ 話者分離の遅延ロード、fun-asr-nanoに対する vLLM 経路と AutoModel fallback、--model-path指定時のcustom別名解決などが、サンプルとは別の契約として実装されています。
トラブルシューティング
| 症状 | 対処 |
|---|---|
| CUDA が利用できない | まず--device cpuで smoke test を通します。 |
| 8000 ポートが使用中 | --port 9000に変更し、BASE_URL=http://localhost:9000 bash smoke_test.shまたはpython smoke_test.py --base-url http://localhost:9000を実行します。 |
| モデルのダウンロードが遅い | 安定したネットワークで再試行するか、ModelScope/Hugging Face から事前にモデルをダウンロードします。 |
Dify/n8n コンテナからlocalhostに接続できない | 認可された到達先のホスト名、Compose service name、または Kubernetes service name を使い、アクセス制御を維持します。 |
応答にsegmentsがない | response_format=verbose_jsonで区間フィールドのある形式を選べますが、配列は空の場合があります。タイムスタンプや話者分離を有効にする指定ではありません。API 契約 を確認してください。 |
本番公開前のセキュリティ要点
サンプルserver.pyにもパッケージ付属funasr-serverにも、ゲートウェイ認証やアプリケーション全体のアップロードサイズ上限は組み込まれていません。既定リスナーは0.0.0.0です。共有・公開する前に セキュリティとゲートウェイガイド を読み、以下の最小コントロールをゲートウェイ層(リバースプロキシ / API ゲートウェイ / ingress / service mesh)で実施してください。
- TLS: 音声は機密データを含み得るため、公開経路では必ず TLS。
- 認証: ローカルの
api_keyプレースホルダは FunASR 側では検査されません。Basic / Bearer / OAuth など、ゲートウェイとクライアントのペアで整合する方式を選ぶ。 - アップロードサイズ制限: 数 GB 級の誤アップロードとメモリ圧迫を防ぐ(例: NGINX の
client_max_body_size 200m、Caddy のrequest_body max_size 200MiB)。 - タイムアウト: 長い録音には長い HTTP タイムアウトが必要ですが、スタックしたクライアントが永遠に張り付かないようにもする。
- レート制限: GPU/CPU 容量をバーストから守る。
- 運用系ルートの保護:
/health、/v1/models、/openapi.json、/docsはサービスメタデータを露出するため、共有リスナーでは拒否し、監視用には別経路を設計する。 - ログと保存期間: リクエストメタデータは有用ですが、生音声は機密の可能性があります。保持ポリシーを定める。
NGINX と Caddy のリバースプロキシ設定例、Kubernetes のNetworkPolicy運用、curl --userによる Basic 検証、Bearer ゲートウェイ向け OpenAI SDK 設定、ローカル診断 → 認証付きアップロード → 未認証拒否 → 他ルート拒否 → サイズ/容量 → タイムアウト → バイパス確認のロールアウトチェックリストは、セキュリティとゲートウェイガイド に詳細があります。
このガイドの構成・モデル別名・応答スキーマは、サンプルサーバーとパッケージ付属サーバーの両方を対象に「契約の境界」を明確にした上で利用することが、誤った話者分離・タイムスタンプ解釈や無認証公開の事故を防ぐ近道です。
【免费下载链接】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),仅供参考