GitHub — Frikallo/parakeet.cpp: сверхбыстрая и портативная реализация Parakeet для вывода на устройстве на C++ с использованием Axiom с унифицированной памятью MPS и поддержкой Cuda.

GitHub — Frikallo/parakeet.cpp: сверхбыстрая и портативная реализация Parakeet для вывода на устройстве на C++ с использованием Axiom с унифицированной памятью MPS и поддержкой Cuda.


Быстрое распознавание речи с помощью модели NVIDIA Parakeet на чистом C++.

Построен на Axiom — легкой тензорной библиотеке с автоматическим ускорением Metal GPU. Никакой среды выполнения ONNX, среды выполнения Python и тяжелых зависимостей. Только C++ и тензорная библиотека, которая переопределяет PyTorch MPS.

Оценка кодировщика ~27 мс на графическом процессоре Apple Silicon Для звука 10 с (модель 110M) — в 96 раз быстрее, чем процессор.

Образец Сорт размер Тип Описание
tdt-ctc-110m ParakeetTDTCTC 110 м оффлайн Английский, двойная декодерная головка CTC/TDT
tdt-600m ParakeetTDT 600 метров оффлайн Многоязычный декодер TDT
eou-120m ParakeetEOU 120 м потоковая передача Английский, с отслеживанием произношения окончания rnnt
nemotron-600m ParakeetNemotron 600 метров потоковая передача Многоязычная, настраиваемая задержка (80–1120 мс)
sortformer Sortformer 117 м потоковая передача Диаризизация спикеров (до 4 спикеров)

Все модели ASR используют один и тот же аудиоконвейер: моно WAV 16 кГц → 80-битная Mel-спектрограмма → кодер FastConformer.

#include <parakeet/parakeet.hpp>

parakeet::Transcriber t("model.safetensors", "vocab.txt");
t.to_gpu();  // optional — Metal acceleration

auto result = t.transcribe("audio.wav");
std::cout << result.text << std::endl;

Выберите декодер на месте вызова:

auto result = t.transcribe("audio.wav", parakeet::Decoder::CTC);  // fast greedy
auto result = t.transcribe("audio.wav", parakeet::Decoder::TDT);  // better accuracy (default)

Временная метка на уровне слова:

auto result = t.transcribe("audio.wav", parakeet::Decoder::TDT, /*timestamps=*/true);
for (const auto &w : result.word_timestamps) {
    std::cout << "[" << w.start << "s - " << w.end << "s] " << w.word << std::endl;
}

Автономная транскрипция (TDT-CTC 110M)

parakeet::Transcriber t("model.safetensors", "vocab.txt");
t.to_gpu();
auto result = t.transcribe("audio.wav");

Автономная транскрипция (TDT 600M многоязычный)

parakeet::TDTTranscriber t("model.safetensors", "vocab.txt",
                            parakeet::make_tdt_600m_config());
auto result = t.transcribe("audio.wav");

Потоковая транскрипция (120 млн евро)

parakeet::StreamingTranscriber t("model.safetensors", "vocab.txt",
                                  parakeet::make_eou_120m_config());

// Feed audio chunks (e.g., from microphone)
while (auto chunk = get_audio_chunk()) {
    auto text = t.transcribe_chunk(chunk);
    if (!text.empty()) std::cout << text << std::flush;
}
std::cout << t.get_text() << std::endl;

Потоковая транскрипция (Немотрон 600М)

// Latency modes: 0=80ms, 1=160ms, 6=560ms, 13=1120ms
auto cfg = parakeet::make_nemotron_600m_config(/*latency_frames=*/1);
parakeet::NemotronTranscriber t("model.safetensors", "vocab.txt", cfg);

while (auto chunk = get_audio_chunk()) {
    auto text = t.transcribe_chunk(chunk);
    if (!text.empty()) std::cout << text << std::flush;
}

Диаризация спикера (Сортформер 117М)

Определите, кто и когда говорил. Обнаруживает до 4 говорящих с возможностью покадровой активности:

parakeet::Sortformer model(parakeet::make_sortformer_117m_config());
model.load_state_dict(axiom::io::safetensors::load("sortformer.safetensors"));

auto wav = parakeet::read_wav("meeting.wav");
auto features = parakeet::preprocess_audio(wav.samples, {.normalize = false});
auto segments = model.diarize(features);

for (const auto &seg : segments) {
    std::cout << "Speaker " << seg.speaker_id
              << ": [" << seg.start << "s - " << seg.end << "s]" << std::endl;
}
// Speaker 0: [0.56s - 2.96s]
// Speaker 0: [3.36s - 4.40s]
// Speaker 1: [4.80s - 6.24s]

Потоковая диаризация с отслеживанием ордера по порядку прибытия:

parakeet::Sortformer model(parakeet::make_sortformer_117m_config());
model.load_state_dict(axiom::io::safetensors::load("sortformer.safetensors"));

parakeet::EncoderCache enc_cache;
parakeet::AOSCCache aosc_cache(4);  // max 4 speakers

while (auto chunk = get_audio_chunk()) {
    auto features = parakeet::preprocess_audio(chunk, {.normalize = false});
    auto segments = model.diarize_chunk(features, enc_cache, aosc_cache);
    for (const auto &seg : segments) {
        std::cout << "Speaker " << seg.speaker_id
                  << ": [" << seg.start << "s - " << seg.end << "s]" << std::endl;
    }
}

Для полного контроля над трубопроводом:

КТК (английский, пунктуация и заглавные буквы):

auto cfg = parakeet::make_110m_config();
parakeet::ParakeetTDTCTC model(cfg);
model.load_state_dict(axiom::io::safetensors::load("model.safetensors"));

auto wav = parakeet::read_wav("audio.wav");
auto features = parakeet::preprocess_audio(wav.samples);
auto encoder_out = model.encoder()(features);

auto log_probs = model.ctc_decoder()(encoder_out);
auto tokens = parakeet::ctc_greedy_decode(log_probs);

parakeet::Tokenizer tokenizer;
tokenizer.load("vocab.txt");
std::cout << tokenizer.decode(tokens[0]) << std::endl;

ТДТ (преобразователь токена и продолжительности):

auto encoder_out = model.encoder()(features);
auto tokens = parakeet::tdt_greedy_decode(model, encoder_out, cfg.durations);
std::cout << tokenizer.decode(tokens[0]) << std::endl;

тюлень (CTC или TDT):

// CTC timestamps
auto ts = parakeet::ctc_greedy_decode_with_timestamps(log_probs);

// TDT timestamps
auto ts = parakeet::tdt_greedy_decode_with_timestamps(model, encoder_out, cfg.durations);

// Group into word-level timestamps
auto words = parakeet::group_timestamps(ts[0], tokenizer.pieces());

ускорение графического процессора (Металл):

model.to(axiom::Device::GPU);
auto features_gpu = features.gpu();
auto encoder_out = model.encoder()(features_gpu);

// Decode on CPU
auto tokens = parakeet::ctc_greedy_decode(
    model.ctc_decoder()(encoder_out).cpu()
);
Usage: parakeet   [options]

Model types:
  --model TYPE     Model type (default: tdt-ctc-110m)
                   Types: tdt-ctc-110m, tdt-600m, eou-120m,
                          nemotron-600m, sortformer

Decoder options:
  --ctc            Use CTC decoder (default: TDT)
  --tdt            Use TDT decoder

Other options:
  --vocab PATH     SentencePiece vocab file
  --gpu            Run on Metal GPU
  --timestamps     Show word-level timestamps
  --streaming      Use streaming mode (eou/nemotron models)
  --latency N      Right context frames for nemotron (0/1/6/13)
  --features PATH  Load pre-computed features from .npy file

Пример:

# Basic transcription (TDT decoder, default)
./build/parakeet model.safetensors audio.wav --vocab vocab.txt

# CTC decoder
./build/parakeet model.safetensors audio.wav --vocab vocab.txt --ctc

# GPU acceleration
./build/parakeet model.safetensors audio.wav --vocab vocab.txt --gpu

# Word-level timestamps
./build/parakeet model.safetensors audio.wav --vocab vocab.txt --timestamps

# 600M multilingual TDT model
./build/parakeet model.safetensors audio.wav --vocab vocab.txt --model tdt-600m

# Streaming with EOU
./build/parakeet model.safetensors audio.wav --vocab vocab.txt --model eou-120m

# Nemotron streaming with configurable latency
./build/parakeet model.safetensors audio.wav --vocab vocab.txt --model nemotron-600m --latency 6

# Speaker diarization
./build/parakeet sortformer.safetensors meeting.wav --model sortformer
# Speaker 0: [0.56s - 2.96s]
# Speaker 0: [3.36s - 4.40s]
# Speaker 1: [4.80s - 6.24s]

Требуется С++20. Axiom — единственная зависимость (включенная как подмодуль).

git clone --recursive https://github.com/noahkay13/parakeet.cpp
cd parakeet.cpp
make build

Загрузите NeMo Checkpoint с сайта NVIDIA и конвертируйте в Softensor:

# Download from HuggingFace (requires pip install huggingface_hub)
huggingface-cli download nvidia/parakeet-tdt_ctc-110m --include "*.nemo" --local-dir .

# Convert to safetensors
pip install safetensors torch
python scripts/convert_nemo.py parakeet-tdt_ctc-110m.nemo -o model.safetensors

Поддерживает все типы моделей через конвертер --model флаг:

# 110M TDT-CTC (default)
python scripts/convert_nemo.py checkpoint.nemo -o model.safetensors --model 110m-tdt-ctc

# 600M multilingual TDT
python scripts/convert_nemo.py checkpoint.nemo -o model.safetensors --model 600m-tdt

# 120M EOU streaming
python scripts/convert_nemo.py checkpoint.nemo -o model.safetensors --model eou-120m

# 600M Nemotron streaming
python scripts/convert_nemo.py checkpoint.nemo -o model.safetensors --model nemotron-600m

# 117M Sortformer diarization
python scripts/convert_nemo.py checkpoint.nemo -o model.safetensors --model sortformer

Также поддерживает сырой .ckpt Файлы и проверка:

python scripts/convert_nemo.py model_weights.ckpt -o model.safetensors
python scripts/convert_nemo.py --dump model.nemo  # inspect checkpoint keys

Получите словарь SentencePiece из того же репозитория HuggingFace. файл находится в .nemo Архивируйте или скачайте напрямую:

# Extract from .nemo
tar xf parakeet-tdt_ctc-110m.nemo ./tokenizer.model
# or use the vocab.txt from the HF files page

Построен на общем кодировщике FastConformer (Conv2d с 8-кратной субдискретизацией → N конформных блоков с относительным позиционным вниманием):

Образец Сорт декодер Пример
КТК ParakeetCTC жадный аргамакс быстро, только английский
рннт ParakeetRNNT Авторегрессионный LSTM потоковая передача включена
ТДТ ParakeetTDT LSTM+прогноз периода Лучшая точность, чем RNNT
ТДТ-СТЦ ParakeetTDTCTC TDT и CTC — оба основные переключить декодер по предположению

Потоковая передача с поддержкой кэша, построенная на кодере FastConverter со случайной сверткой и вниманием к ограниченному контексту:

Образец Сорт декодер Пример
ЕОУ ParakeetEOU Потоковое RNNT Находим конец произношения
немотрон ParakeetNemotron Потоковое ТДТ Настраиваемая задержка потоковой передачи

Образец Сорт архитектура Пример
сортировщик Sortformer Nest Encoder → Трансформатор → Сигмовидная Диаризизация спикеров (до 4 спикеров)

Измерено на Apple M3 16 ГБ с имитацией аудиовхода (Tensor::randn). Время указано для каждого прямого прохода кодировщика (сортировщик: полный прямой проход).

Пропускная способность кодировщика — аудио 10 с:

Образец параметры ЦП (мс) графический процессор (МС) ускорение графического процессора
110 метров (TDT-CTC) 110 м 2581 27 96x
ТДТ-600М 600 метров 10,779 520 21x
РНТ-600М 600 метров 10 648 1468 7x
сортировочная машина 117 м 3195 479 7x

Масштабирование длины звука на 110 м с помощью графического процессора:

аудио ЦП (мс) графический процессор (МС) rtf Поток
1 с 262 24 0,024 41x
5 с 1222 26 0,005 190x
10 с 2581 27 0,003 370x
30 лет 10 061 32 0,001 935x
60 26 559 72 0,001 833x

Ускорение графического процессора на основе компилятора Metal Graph от Axiom, который объединяет полный кодировщик в оптимизированные операции MPSGraph.

# Full suite
make bench ARGS="--110m=models/model.safetensors --tdt-600m=models/tdt.safetensors"

# Single model
make bench-single ARGS="--110m=models/model.safetensors --benchmark_filter=110m"

# Markdown table output
./build/parakeet_bench --110m=models/model.safetensors --markdown

# Skip GPU benchmarks
./build/parakeet_bench --110m=models/model.safetensors --no-gpu

Доступные флаги модели: --110m, --tdt-600m, --rnnt-600m, --sortformer. Все флаги тестов Google (--benchmark_filter, --benchmark_format=json, --benchmark_repetitions=N) прошли.

  • Аудио: моно WAV 16 кГц (16-битный PCM или 32-битный с плавающей запятой)
  • Автономные модели имеют ограничение продолжительности звука ~ 4–5 минут; Разделяйте длинные файлы или используйте потоковую модель
  • Пустой идентификатор токена: 1024 (110M) или 8192 (600M).
  • Для ускорения графического процессора требуется процессор Apple с поддержкой Metal.
  • Временные метки используют выравнивание на уровне кадра: frame * 0.08s (8x субдискретизация × 160 скачков/16 кГц)
  • Диаризизация сортформера использует необычные функции (normalize = false) — отличается от модели ASR.

Массачусетский технологический институт

Leave a Reply

Your email address will not be published. Required fields are marked *