Language

Windows ML を使用して独自の Whisper モデルで音声を認識する

Important

Windows ML Runtime と音声認識 API は現在、実験的な機能であり、運用環境での使用はサポートされていません。 これらの API を試しているアプリは、Microsoft Store に公開しないでください。

Important

Windows ML ランタイムと音声認識 API は、現在 C++ および Python で利用可能です。C# については、現時点ではサポートされていません。C# からこれらの API を利用することにご興味がある場合は、Windows ML の GitHub リポジトリにイシューを投稿して、ぜひお知らせください!

Windows ML 音声認識 API を使用すると、独自の Whisper モデルで自動音声認識 (ASR) を簡単に実行できます。 これは、Whisper エンコーダー パイプライン、デコーダー パイプライン、トークナイザーで構成されており、Windows ML Runtime API を基盤として、自己回帰型転写ループ、ストリーミング出力、キャンセル処理を自動的に処理します。 Windows にはこの API 用のモデルは同梱されていません。Whisper モデル (エンコーダーとデコーダーのファイル、トークナイザー) は、ユーザー自身が選択し、パッケージ化して、アプリと一緒に配布する必要があります。

Tip

特定のWhisper モデルやカスタム デプロイが不要で、Microsoft が管理するモデルを使用してデバイス上で音声テキスト変換を行うだけの場合は、代わりにすぐに使用できる音声認識 APIを使用します。

基になるランタイム オブジェクト (エンコーダーとデコーダー モデル、実行ターゲット、パイプライン) を作成し、セッションに渡します。 この API は、ハードウェアの配置を隠すものではなく、独自のデコード ループを記述する必要をなくすだけです。

サポートされているモデル

音声認識 API は、Whisper エンコーダー/デコーダー アーキテクチャ向けに特化して構築されています。これは汎用 ASR API ではありません。 入力する項目:

  • ONNX エンコーダーとデコーダー モデル (encoder_model.onnx および decoder_model.onnx)、ONNX Runtime上で実行

エンコーダ/デコーダのペアには、トークナイザー ファイルが付属しています。 入力テンソルには、モノラル浮動小数点 PCM サンプルに加えて、サンプル レートと有効な長さのメタデータが保持されます。

オーディオの文字起こし

波形サンプルを保持するランタイム テンソルを提供します。 Whisperエンコーダー モデルとデコーダー モデルを読み込み、それぞれのパイプラインを構築し、トークナイザーと組み合わせてセッションを構成します。

// Create the runtime and an execution target (CPU here; GPU/NPU also available).
ComPtr<IWinMLRuntime> runtime;
THROW_IF_FAILED(WinMLCreateRuntime(IID_PPV_ARGS(runtime.GetAddressOf())));
ComPtr<IWinMLExecutionTarget> target;
THROW_IF_FAILED(runtime->CreateCpuExecutionTarget(target.GetAddressOf()));

// Load the Whisper encoder as its own single-stage pipeline.
ComPtr<IWinMLModel> encoderModel;
THROW_IF_FAILED(runtime->LoadModelFromFile(
    L"C:\\models\\whisper\\encoder_model.onnx", nullptr, encoderModel.GetAddressOf()));
ComPtr<IWinMLPipelineBuilder> encoderBuilder;
THROW_IF_FAILED(runtime->CreatePipelineBuilder(encoderBuilder.GetAddressOf()));
ComPtr<IWinMLStage> encoderStage;
THROW_IF_FAILED(encoderBuilder->AddModelStage(
    encoderModel.Get(), target.Get(), L"whisper-encoder", encoderStage.GetAddressOf()));
ComPtr<IWinMLPipeline> encoderPipeline;
THROW_IF_FAILED(encoderBuilder->Build(encoderPipeline.GetAddressOf()));

// Load the Whisper decoder the same way.
ComPtr<IWinMLModel> decoderModel;
THROW_IF_FAILED(runtime->LoadModelFromFile(
    L"C:\\models\\whisper\\decoder_model.onnx", nullptr, decoderModel.GetAddressOf()));
ComPtr<IWinMLPipelineBuilder> decoderBuilder;
THROW_IF_FAILED(runtime->CreatePipelineBuilder(decoderBuilder.GetAddressOf()));
ComPtr<IWinMLStage> decoderStage;
THROW_IF_FAILED(decoderBuilder->AddModelStage(
    decoderModel.Get(), target.Get(), L"whisper-decoder", decoderStage.GetAddressOf()));
ComPtr<IWinMLPipeline> decoderPipeline;
THROW_IF_FAILED(decoderBuilder->Build(decoderPipeline.GetAddressOf()));

ComPtr<IWinMLTokenizer> tokenizer;
THROW_IF_FAILED(WinMLCreateTokenizerFromFile(
    L"C:\\models\\whisper\\tokenizer.json", tokenizer.GetAddressOf()));

// Compose the encoder/decoder pipelines and tokenizer into a session.
const winml::tasks::speech::asr::AutomaticSpeechRecognitionArguments arguments{
    runtime.Get(),
    tokenizer.Get(),
    {
        encoderPipeline.Get(),
        encoderStage.Get(),
        decoderPipeline.Get(),
        decoderStage.Get(),
        target.Get(),
    },
};
winml::tasks::speech::asr::AutomaticSpeechRecognition speechRecognition;
THROW_IF_FAILED(winml::tasks::speech::asr::BuildAutomaticSpeechRecognition(
    arguments, speechRecognition));

TranscribeWaveformを呼び出してストリーミング操作を開始し、返されたストリームから完了を報告するまでフラグメントをプルします。

ComPtr<IWinMLCancellationSource> cancellation;
THROW_IF_FAILED(speechRecognition.tasks->CreateCancellationSource(
    cancellation.GetAddressOf()));

ComPtr<IWinMLAutomaticSpeechRecognitionPullStream> stream;
THROW_IF_FAILED(speechRecognition.session->TranscribeWaveform(
    waveform.Get(),
    &waveformMetadata,
    cancellation.Get(),
    stream.GetAddressOf()));

// Pull transcript text one fragment at a time until the stream completes.
WINML_AUTOMATIC_SPEECH_RECOGNITION_READ_STATUS status{};
LPCWSTR fragment = nullptr;
while (SUCCEEDED(stream->ReadNext(&status, &fragment)) &&
    status == WINML_AUTOMATIC_SPEECH_RECOGNITION_READ_STATUS_UPDATE)
{
    std::wprintf(L"%ls", fragment);
}

// The terminal result is the authoritative transcript and finish reason.
ComPtr<IWinMLAutomaticSpeechRecognitionResult> result;
THROW_IF_FAILED(stream->GetResult(result.GetAddressOf()));

waveform と waveformMetadata は、音声を読み込むための独自のコードから取得されます。これらは、モノラル浮動小数点 PCM サンプルを格納するランタイムテ ンソルと、それを記述するサンプリングレートおよび有効長に関するメタデータです。

完了した結果は、完全なトランスクリプトと終了理由 (トランスクリプト終了トークン、キャンセル、エラーなど) を報告します。

C++とPython

ネイティブ API は、WinMLTasks.h と winml/tasks/speech/asr/WhisperAutomaticSpeechRecognition.hpp にある型付き C++ ヘルパーを通じて公開されています。 Python アプリケーションでは、windowsml.runtimeプロジェクションをwindowsml.tasksと共に使用します。

Windows ML サンプルには、C++ と Python の Whisper 文字起こしサンプルが含まれます。 このサンプルでは、音声認識構成の横にランタイムの完全なセットアップが示されているため、抽象化が開始される場所と、基になるワークフローをカスタマイズする方法を確認できます。

参照