このトピックでは、Fun-ASR-Realtime リアルタイム音声認識モデル用の Python SDK のパラメータとインターフェイスについて説明します。
前提条件
サービスが有効化されており、「API キーの取得」が完了していること。コード漏洩によるセキュリティリスクを防ぐため、コードにハードコーディングするのではなく、「API キーを環境変数として設定」してください。
クイックスタート
コアリソース(client.audio.asr)は、非ストリーミング呼び出しと双方向ストリーミング呼び出しなどのインターフェイスを提供します。実際の要件に応じて、適切な呼び出し方法を選択してください:
- 非ストリーミング呼び出し(
recognize_file):ローカルファイルを認識します。SDK が自動的に音声を分割送信し、タスクの終了までドライブします。事前に録音された音声の処理に適しています。 - 双方向ストリーミング呼び出し(
recognizeセッション):音声ストリームを直接認識し、結果をリアルタイムで出力します。音声ストリームは、マイクなどの外部デバイスから取得することも、ローカルファイルから読み取ることもできます。即時のフィードバックを必要とするシナリオに適しています。
非ストリーミング呼び出し
単一のリアルタイム音声認識タスクを送信し、ローカルファイルを渡す方式で同期的にブロックして認識結果を取得します。
コアリソース(client.audio.asr)の recognize_file メソッドを呼び出してリクエストパラメーターをバインドし、ローカルファイルのパスを渡します。サーバーイベントを反復処理して認識結果を取得します。
import os
import dashscope
# API キーは、シンガポールリージョンと北京リージョンで異なります。 API キーの取得: https://www.alibabacloud.com/help/model-studio/get-api-key
# 環境変数を設定していない場合は、次の行を Model Studio API キーに置き換えてください:api_key="sk-xxx"
client = dashscope.Client(
api_key=os.environ.get('DASHSCOPE_API_KEY'),
# 以下はシンガポールリージョンの設定です。 呼び出す際に、"{WorkspaceId}" を実際のワークスペース ID に置き換えてください。 設定はリージョンによって異なります。
workspace="{WorkspaceId}",
region="ap-southeast-1",
)
# ローカル音声ファイルを認識します:recognize_file が自動的に音声を分割送信し、タスクの終了までドライブします
for event in client.audio.asr.recognize_file(
'{YOUR_AUDIO_FILE}',
model='fun-asr-realtime',
format='wav',
sample_rate=16000):
payload = event.get('payload') or {}
sentence = (payload.get('output') or {}).get('sentence') or {}
if sentence.get('text') and not sentence.get('heartbeat'):
print('Recognition result: ', sentence['text'])
双方向ストリーミング呼び出し
単一のリアルタイム音声認識タスクを送信し、イベントを反復処理する方式でリアルタイム認識結果をストリーミング出力します。
-
ストリーミング音声認識を開始します。
コアリソース(
client.audio.asr)のrecognizeメソッドを呼び出して認識セッションを作成し、リクエストパラメーターをバインドします。withコンテキストに入ると(startメソッドが自動的に呼び出され、接続の確立とタスクの送信が行われます)、ストリーミング音声認識が開始されます。 -
音声をストリーミングします。
セッションの
send_audio_frameメソッドをループで呼び出し、ローカルファイルまたはマイクなどのデバイスから読み取ったバイナリ音声ストリームをセグメントに分けてサーバーに送信します。送信と受信は並行して行う必要があります:受信スレッドはセッションのevents()メソッドでサーバーイベントを反復処理し、認識結果をリアルタイムでクライアントに返します。送信する各音声の長さは約 100 ミリ秒、データサイズは 1 KB から 16 KB の間に保ってください。
-
タスクを終了します。
セッションの
stopメソッドを呼び出して、音声認識を終了します。このメソッドはサーバーに入力の終了のみを通知します。受信スレッドは
events()をtask-finishedイベントまで消費し続け、最後の認識結果と統計情報を取得する必要があります。ws 層のエラーはDashScopeError例外としてスローされるため、送信/受信処理で try/except で捕捉できます。
import os
import signal # キーボードイベント処理用 (「Ctrl+C」を押して録音を終了)
import sys
import dashscope
import pyaudio
from concurrent.futures import ThreadPoolExecutor
mic = None
stream = None
# 録音パラメーターの設定
sample_rate = 16000 # サンプリングレート (Hz)
channels = 1 # モノラルチャネル
dtype = 'int16' # データ型
format_pcm = 'pcm' # 音声データのフォーマット
block_size = 3200 # バッファあたりのフレーム数
# リアルタイム音声認識イベントレシーバー
def receive_events(rec):
for event in rec.events():
payload = event.get('payload') or {}
sentence = (payload.get('output') or {}).get('sentence') or {}
if sentence.get('text') and not sentence.get('heartbeat'):
print('Recognition text: ', sentence['text'])
if sentence.get('sentence_end'):
print(
'Recognition sentence end, request_id:%s, usage:%s'
% (rec.request_id, rec.usage))
def signal_handler(sig, frame):
print('Ctrl+C pressed, stop recognition ...')
# 認識を停止
recognition.stop()
print('Recognition stopped.')
print(
'[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
.format(
recognition.request_id,
recognition.first_package_delay,
recognition.last_package_delay,
))
# プログラムを強制終了します
sys.exit(0)
# メイン関数
if __name__ == '__main__':
# API キーは、シンガポールリージョンと北京リージョンで異なります。 API キーの取得: https://www.alibabacloud.com/help/model-studio/get-api-key
# 環境変数を設定していない場合は、次の行を Model Studio API キーに置き換えてください:api_key="sk-xxx"
client = dashscope.Client(
api_key=os.environ.get('DASHSCOPE_API_KEY'),
# 以下はシンガポールリージョンの設定です。 呼び出す際に、"{WorkspaceId}" を実際のワークスペース ID に置き換えてください。 設定はリージョンによって異なります。
workspace="{WorkspaceId}",
region="ap-southeast-1",
)
# 認識サービスを呼び出します。モデル、フォーマット、
# サンプリングレートなどの認識パラメーターをカスタマイズできます
with client.audio.asr.recognize(
model='fun-asr-realtime',
format=format_pcm,
# 'pcm'、'wav'、'opus'、'speex'、'aac'、'amr'。サポートされているフォーマットはドキュメントで確認できます
sample_rate=sample_rate,
# 8000、16000 をサポート
) as recognition:
# マイクを開きます
mic = pyaudio.PyAudio()
stream = mic.open(format=pyaudio.paInt16,
channels=1,
rate=16000,
input=True)
with ThreadPoolExecutor(max_workers=1) as pool:
receiver = pool.submit(receive_events, recognition)
try:
# 「Ctrl+C」が押されるまでマイクから音声を送信します
while stream:
data = stream.read(3200, exception_on_overflow=False)
recognition.send_audio_frame(data)
recognition.stop()
receiver.result()
finally:
# close はプールのコンテキスト内で実行する必要があります(レシーバーのブロックを解除するため)
recognition.close()
stream.stop_stream()
stream.close()
mic.terminate()
stream = None
mic = None
import os
import time
import dashscope
from concurrent.futures import ThreadPoolExecutor
# API キーは、シンガポールリージョンと北京リージョンで異なります。 API キーの取得: https://www.alibabacloud.com/help/model-studio/get-api-key
# 環境変数を設定していない場合は、次の行を Model Studio API キーに置き換えてください:api_key="sk-xxx"
client = dashscope.Client(
api_key=os.environ.get('DASHSCOPE_API_KEY'),
# 以下はシンガポールリージョンの設定です。 呼び出す際に、"{WorkspaceId}" を実際のワークスペース ID に置き換えてください。 設定はリージョンによって異なります。
workspace="{WorkspaceId}",
region="ap-southeast-1",
)
from datetime import datetime
def get_timestamp():
now = datetime.now()
formatted_timestamp = now.strftime("[%Y-%m-%d %H:%M:%S.%f]")
return formatted_timestamp
# リアルタイム音声認識イベントレシーバー
def receive_events(rec):
for event in rec.events():
payload = event.get('payload') or {}
sentence = (payload.get('output') or {}).get('sentence') or {}
if sentence.get('text') and not sentence.get('heartbeat'):
print(get_timestamp() + ' Recognition text: ', sentence['text'])
if sentence.get('sentence_end'):
print(get_timestamp() +
'Recognition sentence end, request_id:%s, usage:%s'
% (rec.request_id, rec.usage))
with client.audio.asr.recognize(
model='fun-asr-realtime',
format='wav',
sample_rate=16000,
) as recognition:
with ThreadPoolExecutor(max_workers=1) as pool:
receiver = pool.submit(receive_events, recognition)
try:
audio_data: bytes = None
f = open("{YOUR_AUDIO_FILE}", 'rb')
if os.path.getsize("{YOUR_AUDIO_FILE}"):
# ファイルデータを一度にすべてバッファに読み込みます
file_buffer = f.read()
f.close()
print("Start Recognition")
# バッファから 3200 バイトずつ送信します
buffer_size = len(file_buffer)
offset = 0
chunk_size = 3200
while offset < buffer_size:
# 今回送信するデータチャンクのサイズを計算します
remaining_bytes = buffer_size - offset
current_chunk_size = min(chunk_size, remaining_bytes)
# バッファから現在のデータチャンクを抽出します
audio_data = file_buffer[offset:offset + current_chunk_size]
# 音声データフレームを送信します
recognition.send_audio_frame(audio_data)
# オフセットを更新します
offset += current_chunk_size
# リアルタイム伝送をシミュレートするために遅延を追加します
time.sleep(0.1)
recognition.stop()
receiver.result()
else:
raise Exception(
'The supplied file was empty (zero bytes long)')
finally:
# close はプールのコンテキスト内で実行する必要があります(レシーバーのブロックを解除するため)
recognition.close()
print(
'[Metric] requestId: {}, first package delay ms: {}, last package delay ms: {}'
.format(
recognition.request_id,
recognition.first_package_delay,
recognition.last_package_delay,
))
リクエストパラメーター
リクエストパラメーターは、コアリソース(client.audio.asr)の recognize/recognize_file メソッドで設定します:model、format、sample_rate、vocabulary_id は具名パラメーターで、その他のパラメーター(max_sentence_silence、language_hints など)は parameters ディクショナリで渡します。
| パラメーター | タイプ | 必須 | 説明 |
|---|---|---|---|
model | str | はい | モデル名。 |
sample_rate | int | はい | サンプリングレート (Hz)。 有効な値: 8 kHz モデルは 8000 Hz のみをサポートします。その他のモデルは任意のサンプリングレートをサポートします。 |
format | str | はい | オーディオフォーマット。 有効な値:
重要opus/speex: Ogg カプセル化を使用する必要があります。 wav: PCM エンコーディングを使用する必要があります。 amr: AMR-NB タイプのみをサポートしています。 |
vocabulary_id | str | いいえ | 事前コンパイル済みのホットワードリストのID。 ホットワードリスト作成 API を呼び出して、この ID を事前に生成します。認識時に ID を渡して、リスト内のホットワードを使用します。 語彙が既知で比較的安定しており、リクエスト間で同じ単語リストを再利用する必要があるシナリオに適しています。 使用法の詳細については、「事前コンパイル済みホットワード」をご参照ください。 |
max_sentence_silence | int | いいえ | セグメンテーションのための VAD の無音しきい値 (ミリ秒)。音声セグメントの後の無音時間がこのしきい値を超えると、システムは文が終了したと判断します。 デフォルト値: 1300。 有効な値: [200, 6000]。 |
multi_threshold_mode_enabled | bool | いいえ | マルチしきい値モードを有効にするかどうか。有効にすると、VAD セグメンテーションが長すぎるセグメントを生成するのを防ぎます。 デフォルト:False。 |
punctuation_prediction_enabled | bool | いいえ | 認識結果に句読点を自動的に追加するかどうか:
|
heartbeat | bool | いいえ | ハートビートパケットを有効にするかどうか。 デフォルト:False。
無音オーディオとは、オーディオファイルまたはデータストリーム内で音声信号を含まないコンテンツを指します。 Audacity や Adobe Audition のような音声編集ソフトウェアを使用したり、FFmpeg のようなコマンドラインツールを使用したりするなど、いくつかの方法で無音のオーディオを生成できます。 このフィールドには SDK バージョン 1.23.1 以降が必要です。 |
language_hints | list[str] | いいえ | 認識する音声の言語。デフォルト値はありません。設定しない場合、モデルは自動的に言語を検出します。 1 つの値を設定できます。複数設定した場合は、最初の値のみが有効です。 クリックしてサポートされている言語コードを表示
|
speech_noise_threshold | float | いいえ | 音声とノイズを区別するためのしきい値であり、VAD (音声アクティビティ検出) の感度調整に使用します。 有効な値: [-1.0, 1.0]。 値の説明:
これは高度な設定パラメーターです。調整すると認識結果に大きな影響を与える可能性があります。推奨事項:
|
special_word_filter | str | いいえ | 音声認識中に処理するセンシティブな単語を指定し、単語ごとに異なる処理方法を設定できます。詳細については、「センシティブな単語のフィルタリング」をご参照ください。 |
callback | RecognitionCallback | いいえ | コールバックインターフェイス (RecognitionCallback)。 |
以下のパラメーターを、Recognition インスタンスの call または start メソッドにキーワード引数として渡します。
| パラメーター | タイプ | 必須 | 説明 |
|---|---|---|---|
raw_input | dict | いいえ | 会話コンテキストを渡すために使用される入力オブジェクト。コンテキスト強化により、ドメイン固有の用語の認識精度が向上します。使用方法については、「クイックスタート」をご参照ください。 重要コンテキストパラメーターは、 dict には、値がメッセージのリスト (list[dict]) である
重要制限: 重要コンテキストを渡す際、 注記このフィールドには SDK バージョン 2.0.1 以降が必要です。 |
主要なインターフェイス
コアリソース(client.audio.asr)
リアルタイム音声認識能力は client.audio.asr リソースにマウントされています:recognize は双方向ストリーミング認識セッション(Recognition)を作成し、recognize_file はローカルファイルを一度に認識します。
| メンバーメソッド | メソッドシグネチャ | 説明 |
|---|---|---|
recognize | | 双方向ストリーミング認識セッションを作成します。 音声の送信とイベントの消費は並行して行う必要があります( |
recognize_file | | ローカルファイルをベースとした非ストリーミング呼び出しです:SDK が自動的に音声を分割送信し、タスクの終了までドライブして、サーバーイベントを 1 つずつ産出します。このメソッドは、認識対象のファイルに読み取り権限があることを要求します。 |
start | | 音声認識を開始します:接続を確立し、タスクを送信して |
send_audio_frame | | 音声をプッシュします。毎回プッシュされる音声ストリームは、大きすぎたり小さすぎたりしないようにしてください。各音声パケットの長さは約 100 ms、サイズは 1 KB~16 KB の間にすることを推奨します。 認識結果は |
stop | | 音声認識を停止します:サーバーに入力の終了のみを通知します。受信スレッドは |
events / results | | サーバーイベントを反復処理します: |
close | | 認識セッションを閉じます。 |
request_id / first_package_delay / last_package_delay / last_response | | request_id、初回パケット遅延(最初の音声パケットの送信から最初の認識結果パケットの受信までのレイテンシー)、最終パケット遅延( |
イベント反復(events()/results())
双方向ストリーミング呼び出しでは、サーバーはイベントの方式で主要なプロセス情報とデータをクライアントに返します。受信スレッドでセッションの events()(原始イベント dict)または results()(型付き認識結果フレーム)を反復処理し、サーバーから返された情報やデータを処理する必要があります。
# 原始イベントを反復処理します:認識テキストは payload.output.sentence にあります
def receive_events(rec):
for event in rec.events():
payload = event.get('payload') or {}
sentence = (payload.get('output') or {}).get('sentence') or {}
if sentence.get('text') and not sentence.get('heartbeat'):
print('Recognition text: ', sentence['text'])
# または認識結果フレームのみを反復処理します(RecognitionResult を返し、ハートビートフレームはフィルタリング済み)
def receive_results(rec):
for result in rec.results():
sentence = result.get_sentence()
if sentence and 'text' in sentence:
print('Recognition text: ', sentence['text'])
| イベント/反復メソッド | 産出内容 | 戻り値 | 説明 |
|---|---|---|---|
|
| なし |
|
|
| イテレーター | サーバーからの返信があるときにイベントを産出します。認識結果は |
|
| イテレーター | 認識結果フレームのみを産出します(ハートビートフレームはフィルタリング済み)。すべての認識結果が返された後に反復処理が終了します。 |
|
| なし | 異常発生時に送信/受信スレッドでスローされます。try/except で捕捉できます。 |
|
| なし | サーバーがすべての認識を完了した後に |
応答
認識結果 (RecognitionResult)
RecognitionResult は、セッションの results() の反復処理で産出される 1 回の認識結果フレームを表します(双方向ストリーミング呼び出しと非ストリーミング呼び出しのどちらでも使用できます。events() が産出するのは原始イベント dict であるため、この型付きビューが必要な場合は results() を使用してください)。
| メンバーメソッド | メソッドシグネチャ | 説明 |
|---|---|---|
get_sentence | | 現在認識されている文と、そのタイムスタンプ情報を取得します。このメソッドは、Dict[str, Any](単文情報)を返します。 詳細については、「単文情報 (Sentence)」をご参照ください。 |
request_id | | 現在のイベントに対応するリクエストの request_id。 |
is_sentence_end | | 現在の文が終了したかどうかを判定します。このメソッドは、 |
文情報 (Sentence)
Sentence クラスのメンバーは次のとおりです:
| パラメーター | 型 | 説明 |
|---|---|---|
begin_time | int | 文の開始時刻 (ms) です。 |
end_time | int | 文の終了時刻 (ms) です。 |
text | str | 認識されたテキストです。 |
words | 単語レベルのタイムスタンプ情報 (Word) のリスト | 単語レベルのタイムスタンプ情報です。 |
単語レベルのタイムスタンプ情報 (Word)
Word クラスのメンバーは次のとおりです:
| パラメーター | 型 | 説明 |
|---|---|---|
begin_time | int | 単語の開始時刻 (ms) です。 |
end_time | int | 単語の終了時刻 (ms) です。 |
text | str | 単語です。 |
punctuation | str | 句読点です。 |
エラーコード
エラーが発生した場合は、「エラーコード」を参照してトラブルシューティングを行ってください。
問題が解決しない場合は、開発者コミュニティ に参加し、問題を報告して Request ID を提供してください。
よくある質問
機能
Q:長時間の無音状態でも接続を維持するにはどうすればよいですか?
heartbeat リクエストパラメーターを true に設定し、サーバーに無音オーディオを送信し続けます。
無音オーディオは、オーディオファイルまたはストリームに含まれる音響信号のないコンテンツです。無音オーディオは、Audacity や Adobe Audition などのオーディオ編集ソフトウェア、または FFmpeg などのコマンドラインツールを使用して、いくつかの方法で生成できます。
Q:オーディオをサポートされているフォーマットに変換するにはどうすればよいですか?
FFmpeg を使用します。詳しい使い方については、FFmpeg の公式サイトをご参照ください。
# 基本的な変換コマンド (汎用テンプレート)
# -i: 入力ファイルパス。例: audio.wav
# -c:a: オーディオコーデック。例: aac、libmp3lame、pcm_s16le
# -b:a: ビットレート (音質制御)。例: 192k、320k
# -ar: サンプルレート。例: 44100 (CD)、48000、16000
# -ac: チャンネル数。例: 1 (モノラル)、2 (ステレオ)
# -y: 既存のファイルを上書き (値は不要)
ffmpeg -i input_audio.ext -c:a codec_name -b:a bitrate -ar sample_rate -ac channels output.ext
# 例:WAV から MP3 へ (元の品質を維持)
ffmpeg -i input.wav -c:a libmp3lame -q:a 0 output.mp3
# 例:MP3 から WAV へ (16 ビット PCM 標準フォーマット)
ffmpeg -i input.mp3 -c:a pcm_s16le -ar 44100 -ac 2 output.wav
# 例:M4A から AAC へ (Apple オーディオの抽出または変換)
ffmpeg -i input.m4a -c:a copy output.aac # 再エンコードせずに直接抽出
ffmpeg -i input.m4a -c:a aac -b:a 256k output.aac # 品質を向上させるために再エンコード
# 例:FLAC ロスレスから Opus へ (高圧縮)
ffmpeg -i input.flac -c:a libopus -b:a 128k -vbr on output.opus
Q:ローカルファイル (録音) を認識するにはどうすればよいですか?
ローカルファイルを認識するには 2 つの方法があります:
-
ローカルファイルパスを直接渡す:この方法では、認識が完了した後にのみ完全な結果が返されるため、即時のフィードバックが必要なシナリオには適していません。
「非ストリーミング呼び出し」を参照し、Recognition クラス の
callメソッドにファイルパスを渡して録音を直接認識します。 -
ローカルファイルをバイナリストリームに変換して認識する:この方法では、結果をストリーミングしながらファイルを認識するため、即時のフィードバックが必要なシナリオに適しています。
「双方向ストリーミングコール」を参照し、Recognition クラスの
send_audio_frameメソッドを使用して、バイナリ ストリームをサーバーに送信して認識を行います。
トラブルシューティング
Q:音声が認識されない (認識結果がない) のはなぜですか?
-
リクエストパラメーターの音声フォーマット (
format) とサンプルレート (sampleRate/sample_rate) が正しいこと、およびパラメーターの制約を満たしていることを確認してください。 よくあるエラーとして、以下が挙げられます。- 音声ファイルの拡張子は .wav ですが、実際は MP3 形式であり、
formatリクエストパラメーターは mp3 に設定されています(パラメーター設定が正しくありません)。 - 音声サンプルレートは 3600 Hz ですが、
sampleRate/sample_rateリクエストパラメーターは 48000 に設定されています (不正なパラメーター設定)。
ffprobe ツールを使用して、オーディオのコンテナ、コーデック、サンプルレート、チャンネル数、その他の情報を取得します:
- 音声ファイルの拡張子は .wav ですが、実際は MP3 形式であり、
ffprobe -v error -show_entries format=format_name -show_entries stream=codec_name,sample_rate,channels -of default=noprint_wrappers=1 input.xxx
- 上記のいずれのチェックでも問題が解決しない場合は、カスタムホットワードを追加して特定の用語の認識を向上させてください。