whisper.cpp - OpenAIのC/C++でのウィスパーモデルの移植

(Port of OpenAI's Whisper model in C/C++)

Created at: 2022-09-26 02:26:37
Language: C
License: MIT

ささやく.cpp

アクションのステータス ライセンス: MIT ティッカー

安定版: v1.2.0 / ロードマップ |F.A.Q.

OpenAIのウィスパー自動音声認識(ASR)モデルの高性能推論:

  • 依存関係のないプレーンなC / C ++実装
  • アップルシリコンファーストクラスの市民 - Arm NeonとAccelerateフレームワークを介して最適化
  • x86 アーキテクチャに対する AVX 組み込みのサポート
  • POWERアーキテクチャのVSX組み込みサポート
  • 混合F16/F32精度
  • メモリ使用量が少ない(フラッシュアテンション)
  • 実行時のメモリ割り当てがゼロ
  • CPU上で実行
  • C スタイル API

サポートされているプラットフォーム:

モデルの実装全体は、次の 2 つのソース ファイルに含まれています。

モデルをこのように軽量に実装することで、さまざまなプラットフォームやアプリケーションに簡単に統合できます。 例として、iPhone 13デバイスでモデルを実行するビデオを次に示します-完全にオフライン、デバイス上:whisper.objc

https://user-images.githubusercontent.com/1991296/197385372-962a6dea-bca1-4d50-bf96-1d8c27b98c81.mp4

独自のオフライン音声アシスタントアプリケーションを簡単に作成することもできます:コマンド

https://user-images.githubusercontent.com/1991296/204038393-2f846eae-c255-4099-a76d-5735c25c49da.mp4

または、ブラウザで直接実行することもできます:talk.wasm

実装の詳細

  • コアテンソル演算はC(ggml.h / ggml.c)で実装されています)
  • トランスフォーマーモデルと高レベルのCスタイルのAPIはC ++で実装されています(whisper.h / whisper.cpp)
  • 使用例は main で示されています.cpp
  • マイクからのリアルタイムの音声文字起こしのサンプルは、ストリームで示されます.cpp
  • 他にもさまざまな例が examples フォルダーにあります。

テンソル演算子は、AppleシリコンCPU用に大幅に最適化されています。計算サイズに応じて、アームネオンSIMD 組み込みまたは CBLAS アクセラレート フレームワーク ルーチンが使用されます。後者は、より大きなサイズに特に効果的です。 アクセラレートフレームワークは、最新のアップル製品で利用可能な専用AMXコプロセッサを利用しています。

クイックスタート

まず、ggml形式に変換されたウィスパーモデルの1つをダウンロードします。例えば:

bash ./models/download-ggml-model.sh base.en

次に、メインの例を作成し、次のようにオーディオファイルを転記します。

# build the main example
make

# transcribe an audio file
./main -f samples/jfk.wav

簡単なデモについては、次のコマンドを実行するだけです。

make base.en

$ make base.en

cc  -I.              -O3 -std=c11   -pthread -DGGML_USE_ACCELERATE   -c ggml.c -o ggml.o
c++ -I. -I./examples -O3 -std=c++11 -pthread -c whisper.cpp -o whisper.o
c++ -I. -I./examples -O3 -std=c++11 -pthread examples/main/main.cpp whisper.o ggml.o -o main  -framework Accelerate
./main -h

usage: ./main [options] file0.wav file1.wav ...

options:
  -h,        --help              [default] show this help message and exit
  -t N,      --threads N         [4      ] number of threads to use during computation
  -p N,      --processors N      [1      ] number of processors to use during computation
  -ot N,     --offset-t N        [0      ] time offset in milliseconds
  -on N,     --offset-n N        [0      ] segment index offset
  -d  N,     --duration N        [0      ] duration of audio to process in milliseconds
  -mc N,     --max-context N     [-1     ] maximum number of text context tokens to store
  -ml N,     --max-len N         [0      ] maximum segment length in characters
  -bo N,     --best-of N         [5      ] number of best candidates to keep
  -bs N,     --beam-size N       [-1     ] beam size for beam search
  -wt N,     --word-thold N      [0.01   ] word timestamp probability threshold
  -et N,     --entropy-thold N   [2.40   ] entropy threshold for decoder fail
  -lpt N,    --logprob-thold N   [-1.00  ] log probability threshold for decoder fail
  -su,       --speed-up          [false  ] speed up audio by x2 (reduced accuracy)
  -tr,       --translate         [false  ] translate from source language to english
  -di,       --diarize           [false  ] stereo audio diarization
  -nf,       --no-fallback       [false  ] do not use temperature fallback while decoding
  -otxt,     --output-txt        [false  ] output result in a text file
  -ovtt,     --output-vtt        [false  ] output result in a vtt file
  -osrt,     --output-srt        [false  ] output result in a srt file
  -owts,     --output-words      [false  ] output script for generating karaoke video
  -ocsv,     --output-csv        [false  ] output result in a CSV file
  -of FNAME, --output-file FNAME [       ] output file path (without file extension)
  -ps,       --print-special     [false  ] print special tokens
  -pc,       --print-colors      [false  ] print colors
  -pp,       --print-progress    [false  ] print progress
  -nt,       --no-timestamps     [true   ] do not print timestamps
  -l LANG,   --language LANG     [en     ] spoken language ('auto' for auto-detect)
             --prompt PROMPT     [       ] initial prompt
  -m FNAME,  --model FNAME       [models/ggml-base.en.bin] model path
  -f FNAME,  --file FNAME        [       ] input WAV file path


bash ./models/download-ggml-model.sh base.en
Downloading ggml model base.en ...
ggml-base.en.bin               100%[========================>] 141.11M  6.34MB/s    in 24s
Done! Model 'base.en' saved in 'models/ggml-base.en.bin'
You can now use it like this:

  $ ./main -m models/ggml-base.en.bin -f samples/jfk.wav


===============================================
Running base.en on all samples in ./samples ...
===============================================

----------------------------------------------
[+] Running base.en on samples/jfk.wav ... (run 'ffplay samples/jfk.wav' to listen)
----------------------------------------------

whisper_init_from_file: loading model from 'models/ggml-base.en.bin'
whisper_model_load: loading model
whisper_model_load: n_vocab       = 51864
whisper_model_load: n_audio_ctx   = 1500
whisper_model_load: n_audio_state = 512
whisper_model_load: n_audio_head  = 8
whisper_model_load: n_audio_layer = 6
whisper_model_load: n_text_ctx    = 448
whisper_model_load: n_text_state  = 512
whisper_model_load: n_text_head   = 8
whisper_model_load: n_text_layer  = 6
whisper_model_load: n_mels        = 80
whisper_model_load: f16           = 1
whisper_model_load: type          = 2
whisper_model_load: mem required  =  215.00 MB (+    6.00 MB per decoder)
whisper_model_load: kv self size  =    5.25 MB
whisper_model_load: kv cross size =   17.58 MB
whisper_model_load: adding 1607 extra tokens
whisper_model_load: model ctx     =  140.60 MB
whisper_model_load: model size    =  140.54 MB

system_info: n_threads = 4 / 10 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 0 | VSX = 0 |

main: processing 'samples/jfk.wav' (176000 samples, 11.0 sec), 4 threads, 1 processors, lang = en, task = transcribe, timestamps = 1 ...


[00:00:00.000 --> 00:00:11.000]   And so my fellow Americans, ask not what your country can do for you, ask what you can do for your country.


whisper_print_timings:     fallbacks =   0 p /   0 h
whisper_print_timings:     load time =   113.81 ms
whisper_print_timings:      mel time =    15.40 ms
whisper_print_timings:   sample time =    11.58 ms /    27 runs (    0.43 ms per run)
whisper_print_timings:   encode time =   266.60 ms /     1 runs (  266.60 ms per run)
whisper_print_timings:   decode time =    66.11 ms /    27 runs (    2.45 ms per run)
whisper_print_timings:    total time =   476.31 ms

このコマンドは、カスタム形式に変換されたモデルをダウンロードし、フォルダー内のすべてのサンプルに対して推論を実行します。

base.en
ggml
.wav
samples

詳細な使用手順については、以下を実行してください。

./main -h

メインの例は現在 16 ビットの WAV ファイルでのみ実行されるため、ツールを実行する前に必ず入力を変換してください。 たとえば、次のように使用できます。

ffmpeg

ffmpeg -i input.mp3 -ar 16000 -ac 1 -c:a pcm_s16le output.wav

その他のオーディオサンプル

追加のオーディオサンプルを再生したい場合は、次のコマンドを実行するだけです。

make samples

これにより、ウィキペディアからさらにいくつかのオーディオファイルがダウンロードされ、を介して16ビットWAV形式に変換されます。

ffmpeg

他のモデルは、次のようにダウンロードして実行できます。

make tiny.en
make tiny
make base.en
make base
make small.en
make small
make medium.en
make medium
make large-v1
make large

メモリ使用量

モデル ディスク メム シャ
ちっぽけ 75 メガバイト ~125 MB
bd577a113a864445d4c299885e0cb97d4ba92b5f
142 メガバイト ~210 MB
465707469ff3a37a2b9b8d8f89f2f99de7299dac
小さい 466 メガバイト ~600 MB
55356645c2b361a969dfd0ef2c5a50d530afd8d5
中程度 1.5ギガバイト ~1.7 ギガバイト
fd9727b6e1217c2f614f9b698455c4ffd82463b4
大きい 2.9ギガバイト ~3.3 ギガバイト
0f4c8e34f21cf1a914c59d8b3ce882345ad349d6

制限

  • 推論のみ
  • GPU はサポートされていません (まだ)

別の例

これは、モデルを使用して、MacBook M3 Proで約24分で1:<>分のスピーチを書き写す別の例です。

medium.en

展開して結果を表示する
$ ./main -m models/ggml-medium.en.bin -f samples/gb1.wav -t 8

whisper_init_from_file: loading model from 'models/ggml-medium.en.bin'
whisper_model_load: loading model
whisper_model_load: n_vocab       = 51864
whisper_model_load: n_audio_ctx   = 1500
whisper_model_load: n_audio_state = 1024
whisper_model_load: n_audio_head  = 16
whisper_model_load: n_audio_layer = 24
whisper_model_load: n_text_ctx    = 448
whisper_model_load: n_text_state  = 1024
whisper_model_load: n_text_head   = 16
whisper_model_load: n_text_layer  = 24
whisper_model_load: n_mels        = 80
whisper_model_load: f16           = 1
whisper_model_load: type          = 4
whisper_model_load: mem required  = 1720.00 MB (+   43.00 MB per decoder)
whisper_model_load: kv self size  =   42.00 MB
whisper_model_load: kv cross size =  140.62 MB
whisper_model_load: adding 1607 extra tokens
whisper_model_load: model ctx     = 1462.35 MB
whisper_model_load: model size    = 1462.12 MB

system_info: n_threads = 8 / 10 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 0 | VSX = 0 |

main: processing 'samples/gb1.wav' (3179750 samples, 198.7 sec), 8 threads, 1 processors, lang = en, task = transcribe, timestamps = 1 ...


[00:00:00.000 --> 00:00:08.000]   My fellow Americans, this day has brought terrible news and great sadness to our country.
[00:00:08.000 --> 00:00:17.000]   At nine o'clock this morning, Mission Control in Houston lost contact with our Space Shuttle Columbia.
[00:00:17.000 --> 00:00:23.000]   A short time later, debris was seen falling from the skies above Texas.
[00:00:23.000 --> 00:00:29.000]   The Columbia's lost. There are no survivors.
[00:00:29.000 --> 00:00:32.000]   On board was a crew of seven.
[00:00:32.000 --> 00:00:39.000]   Colonel Rick Husband, Lieutenant Colonel Michael Anderson, Commander Laurel Clark,
[00:00:39.000 --> 00:00:48.000]   Captain David Brown, Commander William McCool, Dr. Kultna Shavla, and Ilan Ramon,
[00:00:48.000 --> 00:00:52.000]   a colonel in the Israeli Air Force.
[00:00:52.000 --> 00:00:58.000]   These men and women assumed great risk in the service to all humanity.
[00:00:58.000 --> 00:01:03.000]   In an age when space flight has come to seem almost routine,
[00:01:03.000 --> 00:01:07.000]   it is easy to overlook the dangers of travel by rocket
[00:01:07.000 --> 00:01:12.000]   and the difficulties of navigating the fierce outer atmosphere of the Earth.
[00:01:12.000 --> 00:01:18.000]   These astronauts knew the dangers, and they faced them willingly,
[00:01:18.000 --> 00:01:23.000]   knowing they had a high and noble purpose in life.
[00:01:23.000 --> 00:01:31.000]   Because of their courage and daring and idealism, we will miss them all the more.
[00:01:31.000 --> 00:01:36.000]   All Americans today are thinking as well of the families of these men and women
[00:01:36.000 --> 00:01:40.000]   who have been given this sudden shock and grief.
[00:01:40.000 --> 00:01:45.000]   You're not alone. Our entire nation grieves with you,
[00:01:45.000 --> 00:01:52.000]   and those you love will always have the respect and gratitude of this country.
[00:01:52.000 --> 00:01:56.000]   The cause in which they died will continue.
[00:01:56.000 --> 00:02:04.000]   Mankind is led into the darkness beyond our world by the inspiration of discovery
[00:02:04.000 --> 00:02:11.000]   and the longing to understand. Our journey into space will go on.
[00:02:11.000 --> 00:02:16.000]   In the skies today, we saw destruction and tragedy.
[00:02:16.000 --> 00:02:22.000]   Yet farther than we can see, there is comfort and hope.
[00:02:22.000 --> 00:02:29.000]   In the words of the prophet Isaiah, "Lift your eyes and look to the heavens
[00:02:29.000 --> 00:02:35.000]   who created all these. He who brings out the starry hosts one by one
[00:02:35.000 --> 00:02:39.000]   and calls them each by name."
[00:02:39.000 --> 00:02:46.000]   Because of His great power and mighty strength, not one of them is missing.
[00:02:46.000 --> 00:02:55.000]   The same Creator who names the stars also knows the names of the seven souls we mourn today.
[00:02:55.000 --> 00:03:01.000]   The crew of the shuttle Columbia did not return safely to earth,
[00:03:01.000 --> 00:03:05.000]   yet we can pray that all are safely home.
[00:03:05.000 --> 00:03:13.000]   May God bless the grieving families, and may God continue to bless America.
[00:03:13.000 --> 00:03:19.000]   [Silence]


whisper_print_timings:     fallbacks =   1 p /   0 h
whisper_print_timings:     load time =   569.03 ms
whisper_print_timings:      mel time =   146.85 ms
whisper_print_timings:   sample time =   238.66 ms /   553 runs (    0.43 ms per run)
whisper_print_timings:   encode time = 18665.10 ms /     9 runs ( 2073.90 ms per run)
whisper_print_timings:   decode time = 13090.93 ms /   549 runs (   23.85 ms per run)
whisper_print_timings:    total time = 32733.52 ms

リアルタイムオーディオ入力の例

これは、マイクからのオーディオに対してリアルタイムの推論を実行する単純な例です。 ストリームツールは、10秒ごとにオーディオをサンプリングし、文字起こしを継続的に実行します。 詳細については、問題#<>を参照してください。

make stream
./stream -m ./models/ggml-base.en.bin -t 8 --step 500 --length 5000

https://user-images.githubusercontent.com/1991296/194935793-76afede7-cfa8-48d8-a80f-28ba83be7d09.mp4

信頼度の色分け

引数を追加すると、実験的な色分け戦略を使用して文字起こしされたテキストが印刷されます 信頼度が高いまたは低い単語を強調表示するには:

--print-colors

画像

生成されるテキストセグメントの長さの制御(試験的)

たとえば、行の長さを最大 16 文字に制限するには、次のように追加します。

-ml 16

./main -m ./models/ggml-base.en.bin -f ./samples/jfk.wav -ml 16

whisper_model_load: loading model from './models/ggml-base.en.bin'
...
system_info: n_threads = 4 / 10 | AVX2 = 0 | AVX512 = 0 | NEON = 1 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 |

main: processing './samples/jfk.wav' (176000 samples, 11.0 sec), 4 threads, 1 processors, lang = en, task = transcribe, timestamps = 1 ...

[00:00:00.000 --> 00:00:00.850]   And so my
[00:00:00.850 --> 00:00:01.590]   fellow
[00:00:01.590 --> 00:00:04.140]   Americans, ask
[00:00:04.140 --> 00:00:05.660]   not what your
[00:00:05.660 --> 00:00:06.840]   country can do
[00:00:06.840 --> 00:00:08.430]   for you, ask
[00:00:08.430 --> 00:00:09.440]   what you can do
[00:00:09.440 --> 00:00:10.020]   for your
[00:00:10.020 --> 00:00:11.000]   country.

単語レベルのタイムスタンプ

引数は、単語レベルのタイムスタンプを取得するために使用できます。単に使用する:

--max-len
-ml 1

./main -m ./models/ggml-base.en.bin -f ./samples/jfk.wav -ml 1

whisper_model_load: loading model from './models/ggml-base.en.bin'
...
system_info: n_threads = 4 / 10 | AVX2 = 0 | AVX512 = 0 | NEON = 1 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 |

main: processing './samples/jfk.wav' (176000 samples, 11.0 sec), 4 threads, 1 processors, lang = en, task = transcribe, timestamps = 1 ...

[00:00:00.000 --> 00:00:00.320]  
[00:00:00.320 --> 00:00:00.370]   And
[00:00:00.370 --> 00:00:00.690]   so
[00:00:00.690 --> 00:00:00.850]   my
[00:00:00.850 --> 00:00:01.590]   fellow
[00:00:01.590 --> 00:00:02.850]   Americans
[00:00:02.850 --> 00:00:03.300]  ,
[00:00:03.300 --> 00:00:04.140]   ask
[00:00:04.140 --> 00:00:04.990]   not
[00:00:04.990 --> 00:00:05.410]   what
[00:00:05.410 --> 00:00:05.660]   your
[00:00:05.660 --> 00:00:06.260]   country
[00:00:06.260 --> 00:00:06.600]   can
[00:00:06.600 --> 00:00:06.840]   do
[00:00:06.840 --> 00:00:07.010]   for
[00:00:07.010 --> 00:00:08.170]   you
[00:00:08.170 --> 00:00:08.190]  ,
[00:00:08.190 --> 00:00:08.430]   ask
[00:00:08.430 --> 00:00:08.910]   what
[00:00:08.910 --> 00:00:09.040]   you
[00:00:09.040 --> 00:00:09.320]   can
[00:00:09.320 --> 00:00:09.440]   do
[00:00:09.440 --> 00:00:09.760]   for
[00:00:09.760 --> 00:00:10.020]   your
[00:00:10.020 --> 00:00:10.510]   country
[00:00:10.510 --> 00:00:11.000]  .

カラオケスタイルの映画生成(実験的)

主な例では、カラオケスタイルのムービーの出力をサポートしています。 現在発音されている単語が強調表示されます。引数を使用して、生成されたbashスクリプトを実行します。 これには、インストール済みである必要があります。

-wts
ffmpeg

ここにいくつかの「典型的な」例があります:

./main -m ./models/ggml-base.en.bin -f ./samples/jfk.wav -owts
source ./samples/jfk.wav.wts
ffplay ./samples/jfk.wav.mp4

https://user-images.githubusercontent.com/1991296/199337465-dbee4b5e-9aeb-48a3-b1c6-323ac4db5b2c.mp4


./main -m ./models/ggml-base.en.bin -f ./samples/mm0.wav -owts
source ./samples/mm0.wav.wts
ffplay ./samples/mm0.wav.mp4

https://user-images.githubusercontent.com/1991296/199337504-cc8fd233-0cb7-4920-95f9-4227de3570aa.mp4


./main -m ./models/ggml-base.en.bin -f ./samples/gb0.wav -owts
source ./samples/gb0.wav.wts
ffplay ./samples/gb0.wav.mp4

https://user-images.githubusercontent.com/1991296/199337538-b7b0c7a3-2753-4a88-a0cd-f28a317987ba.mp4


Benchmarks

In order to have an objective comparison of the performance of the inference across different system configurations, use the bench tool. The tool simply runs the Encoder part of the model and prints how much time it took to execute it. The results are summarized in the following Github issue:

Benchmark results

ggml format

The original models are converted to a custom binary format. This allows to pack everything needed into a single file:

  • model parameters
  • mel filters
  • vocabulary
  • weights

You can download the converted models using the models/download-ggml-model.sh script or manually from here:

For more details, see the conversion script models/convert-pt-to-ggml.py or the README in models.

Bindings

examples フォルダーには、さまざまなプロジェクトでライブラリを使用するさまざまな例があります。 一部の例は、WebAssemblyを使用してブラウザで実行するように移植されています。それらをチェックしてください!

ウェブ 形容
メイン ささやき.ワズム ウィスパーを使用してオーディオを翻訳および転記するためのツール
ベンチ ベンチ.ワズム マシンでのウィスパーのパフォーマンスをベンチマークする
ストリーム.wasm 生のマイクキャプチャのリアルタイム文字起こし
命令 コマンド.wasm マイクから音声コマンドを受信するための基本的な音声アシスタントの例
話す トーク・ワズム GPT-2ボットと話す
ささやき.objc ささやき声を使用したiOSモバイルアプリケーション.cpp
ささやき.スウィフトイ ウィスパーを使用したSwiftUI iOS / macOSアプリケーション.cpp
ささやきアンドロイド ささやきを使用したAndroidモバイルアプリケーション.cpp
ささやき.nvim ネオビム用の音声テキスト変換プラグイン
generate-karaoke.sh 生のオーディオキャプチャのカラオケビデオを簡単に生成するためのヘルパースクリプト
livestream.sh ライブストリームの音声文字起こし
yt-wsp.sh ダウンロード+VODの文字起こしおよび/または翻訳(オリジナル)

議論

このプロジェクトについて何らかのフィードバックがある場合は、ディスカッションセクションを使用して、新しいトピックを開いてください。 [表示して伝える] カテゴリを使用できます。 を使用して、 を使用する独自のプロジェクトを共有します。質問がある場合は、よくある質問(#126)ディスカッションを必ず確認してください。

whisper.cpp