Sakhanda Wire
NVDA $221.97 +2.54% MSFT $532.95 +0.20% GOOGL $334.76 -1.62% META $697.52 +0.47% AMZN $262.37 -0.10%
← До новин

Посібник із програмування для Cactus Whistle: Чи витримує мовна модель розміром 16,9 МБ порівняння з Whisper Base? Частота помилок у словах, швидкість, потокова передача, часові мітки, ключові слова та виклики інструментів із мовлення на CPU

У цьому посібнику ми використовуємо Whistle — модель перетворення мовлення на текст від Cactus Compute, файл розміром 16,9 МБ, який працює на CPU, транскрибує сім мов і повертає часові мітки та ймовірності для окремих слів. У картці моделі стверджується, що вона перевершує Whisper base на LibriSpeech; ми тестуємо її на фіксованих вибірках test-clean і test-other, порівнюючи Whistle з Whisper tiny та base на ідентичних фрагментах і оцінюючи результати за парними інтервалами кластерів мовців із поправкою Голма. Ми виявили перевагу над Whisper base із жадібним декодуванням на test-other, відсутність статистично значущого розриву порівняно з пошуковим декодуванням і перевагу в швидкості, яка зменшується зі збільшенням тривалості фрагментів. Окрім заголовкових результатів, ми досліджуємо 30-секундне вікно, у межах якого закріплений рушій непомітно пропускає середину довшого аудіо, а також затримку потокової обробки, часові мітки, керування ключовими словами, інші мови, шум, ембеддинги та виклики мовлення до інструментів. Наші показники — це результати одного запуску на Apple M4, а опубліковані числа для повних вибірок наведено як цитати, а не виміряно нами.

Копіювати кодСкопійованоВикористати інший браузер
import os
import io
import re
import sys
import json
import math
import time
import random
import hashlib
import shutil
import zipfile
import platform
import traceback
import subprocess
import collections
import urllib.error
import urllib.request
 
RESULTS = {}
VERDICTS = []
 
 
def banner(title):
    print("\n" + "=" * 78)
    print(title)
    print("=" * 78)
 
 
def section(name):
    def wrap(fn):
        def run(*a, **kw):
            banner(name)
            t0 = time.time()
            try:
                out = fn(*a, **kw)
                RESULTS[name] = out if isinstance(out, str) else "ok"
                return out
            except Exception as e:
                RESULTS[name] = f"SKIPPED / FAILED -> {type(e).__name__}: {e}"
                print(f"\n[!] {name} did not complete: {type(e).__name__}: {e}")
                traceback.print_exc(limit=3)
                return None
            finally:
                print(f"\n[{time.time() - t0:.0f} s]")
                json.dump({"results": RESULTS, "verdicts": VERDICTS}, open("results.json", "w"), indent=1)
        return run
    return wrap

Ми встановлюємо cactus-needle 3.2.0 із зафіксованими залежностями та вимикаємо анонімну телеметрію. Пакет завантажує ваги Whistle, її рушій і ваги Needle 3 із репозиторіїв Hugging Face, файли в яких замінюються безпосередньо, тому ми фіксуємо обидві репозиторії на певних ревізіях і виводимо хеші SHA-256. Допоміжна функція page() читає API рядків datasets-server із повторними спробами після обмеження частоти запитів, а load_audio() змінює частоту дискретизації фрагментів до 16 кГц. Перший фрагмент test-clean, що містить 3,5 с мовлення, транскрибується за 33 мс реального часу; кожне слово має час початку, час завершення та ймовірність.

Результат мало важить, якщо його правило встановлюють уже після отримання фінальних чисел, тому ми записали власні правила в ноутбуці до фінального запуску, після попередніх досліджень, які охоплювали частину тих самих фрагментів. Ми вибираємо фіксовану за початковим значенням вибірку з 300 рядків для кожної частини та вилучаємо фрагменти, довші за однопрохідне вікно Whistle, залишаючи по 299 фрагментів у кожній. Парні підвибірки — перші 100 фрагментів test-other і 60 фрагментів test-clean — обробляються Whisper, а невелика кількість мовців робить їхні інтервали наближеними. Різниця враховується лише тоді, коли її 95% парний бутстреп-інтервал кластерів мовців не охоплює нуль, а скориговане за Голмом значення p нижче 0,05.

Декодер Whisper за замовчуванням використовує жадібний пошук із переходом на іншу температуру. Водночас у статті числа для LibriSpeech отримано пошуковим декодуванням, а Whistle декодує за допомогою пошуку з п’ятьма променями, тому в кожному порівнянні потрібно чітко називати базову систему. За єдиним нормалізатором WER Whistle на вибірці test-other становить 10,47% — близько до опублікованих 10,49% для всієї вибірки, які ми наводимо як цитату, а не вимірюємо. На парній підвибірці показник становить 10,27% проти 12,46% для Whisper base із жадібним декодуванням і 10,83% для пошукового декодування. Перевага у 2,19 відсоткового пункта над жадібним декодуванням зберігається після поправки Голма, але розрив із пошуковим декодуванням — ні, тож ця базова система перемагає.

Порівнювати швидкість складно, коли рушії працюють в одному процесі, оскільки потоки torch можуть сповільнювати один одного. Тому кожен рушій запускається в окремому процесі на ідентичних масивах float32; час вимірюється як медіана після прогрівання. Розрив зменшується зі збільшенням тривалості фрагментів: від 7,7 раза швидше за Whistle на 5-секундному фрагменті до 2,8 раза на 30-секундному, частково через фіксоване вікно доповнення Whisper. Пікова пам’ять становить 124 МБ для Whistle і 823 МБ для Whisper base. Час Whistle на окремий фрагмент відрізнявся майже утричі між двома частинами, чого не пояснює довжина фрагментів, тому наведені співвідношення слід вважати приблизними.

Об’єднання висловлювань одного мовця дає довгий фрагмент із точною еталонною транскрипцією, а README обіцяє обробку вікнами для аудіо, довшого за обмеження 30 секунд. Коротший фрагмент повертається майже слово в слово, але закріплений рушій версії 3.3.0 непомітно пропускає середину повного фрагмента, повертаючи менш як половину його слів без жодної помилки. Рушій версії 3.2.0 натомість відмовляється обробляти таке аудіо й повертає RuntimeError, тож дві збірки поводяться по-різному, а розділення маємо виконувати ми. Розділення в тихих місцях дає WER 3,75% проти 6,74% для фіксованих вікон, хоча один фрагмент не може бути остаточним доказом.

Потокова обробка через stream() повторно транскрибує недавнє аудіо й фіксує слово, коли два послідовні проходи збігаються, тому зі збільшенням розміру фрагмента очікування зростає. Вісім сесій одного мовця, створених об’єднанням висловлювань, оброблені потоково з односекундними фрагментами, дають WER 10,05% проти 10,41%, коли ті самі висловлювання транскрибуються окремо; ця різниця статистично незначуща. Слово фіксується в медіані через 1,68 с після його завершення, а на двох сесіях медіана зростає з 0,78 с для фрагментів по пів секунди до 3,44 с для фрагментів по дві секунди. Об’єднання є штучним, тож цей тест перевіряє механізм, а не розмовне мовлення.

Без еталонного вирівнювання ми перевіряємо часові мітки за властивостями, яких вони мають дотримуватися. Часові мітки слів монотонні на кожному перевіреному фрагменті, а додавання двох секунд тиші на початку двадцяти фрагментів зміщує перше слово на медіанні 2,000 с. Обрізання в кінці слова має відтворювати його префікс, але це відбувається лише в одній п’ятій із двадцяти випадків; такий тест перевіряє стабільність, а не точність часу завершення. Ймовірність є сильнішим сигналом: слова з оцінкою нижче 0,5 були неправильними у 69,2% випадків, тоді як для оцінки 0,9 або вище — у 2,5%; AUROC для неправильних слів становить 0,916 проти 0,509 для тривалості.

Керування ключовими словами потребує контрольних умов, оскільки оракул, який читає відповідь, створює ілюзію переваги. Оракул перелічує слова, у яких Whistle припустилася помилки; контрольна умова використовує слова з іншого фрагмента, вилучаючи ті, що трапляються в поточному. У 185 фрагментах із помилками оракул зменшує WER із 14,74% до 7,62%, тоді як неправильні слова з контрольної умови залишають його на рівні 14,82% — статистично незначуща зміна. Вісім частотних слів, відсутніх у фрагменті, підвищують WER на 2,05 відсоткового пункта. Порівняно з оракулом неправильні слова дають результат на 7,20 пункта гірший; після поправки Голма ця різниця значуща, отже важливі саме правильні слова.

Примусове задання справжньої мови приховало б помилки її визначення, тому кожна система також має визначати мову. Ми вибираємо по 12 фрагментів для кожної мови з трьох випадкових сторінок, зафіксованих наперед, і оцінюємо обидві сторони за допомогою BasicTextNormalizer. Ревізію MLS не фіксуємо, тому хешуємо кожен фрагмент окремо. На 72 фрагментах від 22 мовців примусово задана Whistle показує 26,40% проти 24,06% для Whisper base із жадібним декодуванням; перевага Whisper статистично незначуща. Обидві системи правильно визначають мову на всіх 72 фрагментах. Результати для окремих мов мають лише описовий характер.

Для тиші, тихого мовлення та білого шуму на трьох рівнях SNR Whistle порівнюється з Whisper base.

Перекладено автоматично з англійської. Оригінал статті — за посиланням нижче.

Вперше опубліковано виданням MarkTechPost

Читати оригінал на MarkTechPost ↗

Текст і зображення належать MarkTechPost і наводяться тут із зазначенням авторства та посиланням на оригінальну публікацію.

← До новин

Ще новини

Усі останні новини