docs(diarization): разделен CPU-эксперимент по машинам
- Зачем: - один агент не может последовательно работать на двух ноутбуках. - Что: - этапы 0-4 закреплены за Intel, этапы 5-6 - за зависимой Ryzen-задачей. - добавлен проверяемый handoff через отчет, commit и приватную ZIP-капсулу. - устранен штатный возврат с Ryzen на Intel и ограничен финальный бюджет. - Проверка: - `.venv/bin/pytest -q tests/test_diarization_calibration.py tests/test_speaker_diarizer.py tests/test_diarization.py` (61 passed).
This commit is contained in:
1 parent
fde4c48859
commit
558c1baf89
1 file changed
+139
-63
@@ -40,8 +40,8 @@
|
||||
- расширить исследовательский стенд для новых ручек, повторов и счетчиков;
|
||||
- независимо проверить сокращение работы, модель с надежной оценкой числа
|
||||
говорящих и способы ускорить embedding-инференс;
|
||||
- собрать не больше трех комбинаций на Intel и перенести не больше двух на
|
||||
Ryzen;
|
||||
- собрать не больше трех комбинаций на Intel, передать их в Ryzen-этап и
|
||||
оставить там не больше двух финалистов после первичного A/B;
|
||||
- выбрать один итоговый вариант либо зафиксировать, почему ни один вариант не
|
||||
прошел;
|
||||
- выпустить публичный обезличенный отчет и сохранить полную переносимую капсулу
|
||||
@@ -105,6 +105,7 @@
|
||||
- размер batch, где он применим;
|
||||
- машину, число физических ядер, CPUID/ISA и версии библиотек;
|
||||
- номер повтора и позицию в расписании;
|
||||
- этап `intel` или `ryzen`; для Ryzen - исходный commit handoff;
|
||||
- хеш экспериментальной сборки или патча sherpa-onnx;
|
||||
- хеши моделей и приватных входов по прежнему контракту.
|
||||
|
||||
@@ -125,18 +126,78 @@
|
||||
идентификатору, а расписание оставшихся сохраняет заданный A/B-порядок. Режим
|
||||
`--validate-only` показывает полный план без приватных путей и текста.
|
||||
|
||||
### Приватная капсула
|
||||
|
||||
Капсула передается одним ZIP-архивом; `capsule_sha256` означает SHA-256 этого
|
||||
файла. В корне лежит `capsule.json` с идентификатором капсулы, исходным commit,
|
||||
хешем публичного Intel-отчета и SHA-256 каждого файла внутри. Все пути в manifest
|
||||
относительны корня распакованной капсулы.
|
||||
|
||||
Архив содержит:
|
||||
|
||||
- manifest и полный набор входов для трех пятиминутных и трех полных прогонов;
|
||||
- ASR-sidecar, опорные транскрипты и разметку, нужную для метрик и прослушивания;
|
||||
- калибровочный материал и готовый QDQ-граф, если QDQ передается в Ryzen;
|
||||
- сырые Intel-результаты, интервалы, worker requests и журналы, нужные для
|
||||
продолжения и разбора;
|
||||
- локально созданные или измененные модельные артефакты.
|
||||
|
||||
Публично загружаемые базовые модели можно не дублировать в архиве, если manifest
|
||||
фиксирует репозиторий, revision и SHA-256. После распаковки `--validate-only`
|
||||
сверяет внешний хеш архива, `capsule.json`, относительные пути и все внутренние
|
||||
хеши до запуска моделей.
|
||||
|
||||
### Приватность
|
||||
|
||||
За пределами Git остаются manifest, записи, WAV-кеш, ASR-sidecar, опорные
|
||||
транскрипты, сырые интервалы, результаты, worker requests, журналы и материалы
|
||||
слуховой проверки. Рабочий каталог стенда нельзя размещать в обычной
|
||||
`.scratch`: репозиторий игнорирует там только `.scratch/handoffs/`.
|
||||
`.scratch`: репозиторий игнорирует там только служебный каталог
|
||||
`.scratch/handoffs/`, не связанный с переносом эксперимента между ноутбуками.
|
||||
|
||||
Публичный отчет содержит хеши, агрегаты, конфигурацию и выводы. В него не входят
|
||||
локальные пути, распознанный текст, временные интервалы, имена участников и
|
||||
фрагменты приватных записей. Перед внешним ревью используется только публичный
|
||||
отчет и код стенда.
|
||||
|
||||
## Разделение работы между ноутбуками
|
||||
|
||||
Эксперимент выполняют две зависимые задачи. Один агент не меняет машину в ходе
|
||||
работы:
|
||||
|
||||
| Задача | Машина | Этапы | Результат |
|
||||
|---|---|---|---|
|
||||
| [Intel #41](https://git.dementev.space/ddmitry/local-transcriber/issues/41) | Core i7-6820HQ | 0-4 | стенд, Intel-отчет и handoff |
|
||||
| [Ryzen #42](https://git.dementev.space/ddmitry/local-transcriber/issues/42) | Ryzen 7 8845H | 5-6 | финальный отчет и решение |
|
||||
|
||||
Intel-агент коммитит в обычную ветку своей задачи код стенда и обезличенный
|
||||
отчет. Специальная общая ветка для handoff не создается. Manifest, сырые
|
||||
результаты и другие приватные материалы в Git не попадают. В финальном
|
||||
комментарии к Intel-задаче агент оставляет только индекс:
|
||||
|
||||
- `intel_outcome`: `handoff` или `stop-before-ryzen`;
|
||||
- ветку, точный commit и PR;
|
||||
- путь и SHA-256 публичного Intel-отчета;
|
||||
- число кандидатов и ссылку на их рецепты в отчете;
|
||||
- непрозрачный идентификатор приватной капсулы и ее SHA-256;
|
||||
- ссылку на ограничения в отчете.
|
||||
|
||||
При расхождении источником истины служит файл отчета в указанном commit,
|
||||
комментарий остается указателем. Он не содержит приватных путей, текста или
|
||||
интервалов. Пользователь передает капсулу на второй ноутбук отдельно и сливает
|
||||
Intel-PR обычным merge, без squash или rebase. После этого #41 закрывается и
|
||||
средствами Gitea разблокирует #42. Ryzen-агент сначала читает обе задачи и все
|
||||
комментарии к первой, обновляет `master` и проверяет присутствие handoff-commit
|
||||
в его истории. Затем он сверяет SHA-256 капсулы и запускает `--validate-only`.
|
||||
При наличии кандидатов агент создает обычную ветку #42 от `master`.
|
||||
Несовпадение commit, капсулы или плана переводит задачу в `needs-info`;
|
||||
недостающие данные агент не восстанавливает догадками.
|
||||
|
||||
Штатный путь идет только с Intel на Ryzen. Если на Ryzen обнаружена ошибка
|
||||
стенда, которая делает Intel-результаты недействительными, эксперимент
|
||||
останавливается и требует отдельного исправления. Обычный отсев или проигрыш
|
||||
кандидата не возвращает работу на Intel.
|
||||
|
||||
## Воронка вариантов
|
||||
|
||||
### Этап 0. Проверить механизмы без дорогих замеров
|
||||
@@ -199,21 +260,24 @@ embedding-заданий. Ускорение без соответствующе
|
||||
| M2 | CAMPPlus | счетчик, выбранный для CAMPPlus, + `FastClustering(N)` |
|
||||
| M3 | TitaNet small | счетчик, выбранный для TitaNet, + `FastClustering(N)` |
|
||||
|
||||
M1 намеренно отсутствует: отдельный контроль `Prepare/Finalize` перенесен в
|
||||
дешевую проверку этапа 0 и не получает CPU-ячейку.
|
||||
|
||||
M0, M2 и M3 получают по одному прогону трех фрагментов. Быстрая модель проходит
|
||||
дальше, если выдерживает обязательные условия и достигает порога продолжения
|
||||
относительно M0. Малая разница не уточняется дополнительными повторами.
|
||||
Регрессия диагностических метрик требует прослушать отмеченные пятиминутные
|
||||
случаи до сборки комбинации.
|
||||
|
||||
### Этап 3. Проверить исполнение эмбеддингов
|
||||
### Этап 3. Проверить исполнение эмбеддингов на Intel
|
||||
|
||||
#### QDQ WeSpeaker
|
||||
|
||||
S8S8 QDQ сравнивается с FP32 на обеих машинах при шаге `0.1`. На Intel
|
||||
достаточно одного A/B по трем фрагментам. Изолированный Ryzen A/B выполняется
|
||||
до сборки комбинаций этапа 4: по одному прогону baseline и кандидата на трех
|
||||
фрагментах. Проверка на Ryzen обязательна даже при проигрыше на Intel: выигрыш
|
||||
зависит от VNNI/AVX-512.
|
||||
S8S8 QDQ сравнивается с FP32 на Intel при шаге `0.1`; достаточно одного A/B по
|
||||
трем фрагментам. Если QDQ проходит обязательные условия и проверку памяти, он
|
||||
остается допустимым для C2 даже без порога продолжения на Intel: возможный
|
||||
выигрыш на Ryzen зависит от VNNI/AVX-512. Изолированный Ryzen A/B выполняется
|
||||
уже после handoff, в этапе 5.
|
||||
|
||||
U8U8 допускается как единственный запасной вариант, если S8S8 достигает порога
|
||||
продолжения по времени диаризации, но не проходит качество. Другие форматы
|
||||
@@ -221,12 +285,10 @@ U8U8 допускается как единственный запасной в
|
||||
|
||||
#### Shared-session streams
|
||||
|
||||
На Intel и Ryzen сравниваются четыре конфигурации при общем бюджете `P`. На
|
||||
Intel достаточно одного A/B по трем фрагментам. Изолированный Ryzen A/B также
|
||||
выполняется до этапа 4 и состоит из одного прогона baseline и одного прогона
|
||||
кандидата на трех фрагментах. Порядок baseline и кандидата меняется между
|
||||
парами. Эти прогоны в
|
||||
этапе 5 не повторяются.
|
||||
На Intel сравниваются четыре конфигурации при общем бюджете `P`; достаточно
|
||||
одного A/B по трем фрагментам. Лучшая shared-session конфигурация, прошедшая
|
||||
обязательные условия и проверку памяти, остается допустимой для C2 даже без
|
||||
порога продолжения. Изолированный Ryzen A/B выполняется в этапе 5.
|
||||
|
||||
| Ячейка | Outer workers | Intra-op | Session |
|
||||
|---|---:|---:|---|
|
||||
@@ -255,48 +317,51 @@ Batch TitaNet открывается только после прохожден
|
||||
| Ячейка | Состав |
|
||||
|---|---|
|
||||
| C0 | рабочий шаг + WeSpeaker FP32 + последовательный инференс |
|
||||
| C1 | рабочий шаг + одна сильнейшая прошедшая ветвь |
|
||||
| C2 | рабочий шаг + все совместимые прошедшие ветви |
|
||||
| C1 | рабочий шаг + сильнейшая ветвь по Intel |
|
||||
| C2 | рабочий шаг + заранее определенный ISA-стек |
|
||||
|
||||
Сильнейшая ветвь определяется по сокращению времени диаризации: для быстрой
|
||||
модели используется Intel, для QDQ и shared-session - обязательный изолированный
|
||||
Ryzen A/B из этапа 3. Это намеренно грубое межмашинное ранжирование: Intel
|
||||
дешево отсеивает быстрые модели, а ISA-чувствительные ветви оцениваются там, где
|
||||
их выигрыш проявляется. Оно не заменяет финальный Ryzen A/B. QDQ совместим
|
||||
только с WeSpeaker. Batch совместим только с TitaNet. Shared-session добавляется
|
||||
к выбранной модели после проверки сохранности всех входов и результатов на этой
|
||||
модели. Если C1 и C2 совпадают, дубликат не запускается. C0 совпадает с baseline
|
||||
и тоже не запускается, если рабочим остался шаг `0.1`.
|
||||
Для C1 рассматриваются ветви, достигшие порога продолжения на Intel; сильнейшая
|
||||
определяется по сокращению времени диаризации. C2 начинается с рабочего шага и
|
||||
WeSpeaker FP32. Если QDQ выдержал обязательные условия и память, он заменяет
|
||||
FP32 независимо от скорости на Intel. Затем добавляется лучшая допустимая
|
||||
shared-session конфигурация для WeSpeaker. Если ни QDQ, ни shared-session не
|
||||
допустимы, C2 собирается как совместимый стек прошедших Intel-ветвей. Так
|
||||
ISA-кандидаты доходят до Ryzen без предварительного Ryzen-замера. Batch совместим
|
||||
только с TitaNet. Если C1 и C2 совпадают, дубликат не запускается. C0 совпадает
|
||||
с baseline и тоже не запускается, если рабочим остался шаг `0.1`.
|
||||
|
||||
Каждая существующая комбинация получает один прогон трех фрагментов. Если C0
|
||||
отличается от baseline, он всегда переносится на Ryzen после обязательных
|
||||
условий, а из C1 и C2 туда идет максимум один вариант с лучшим временем
|
||||
диаризации. Если C0 совпадает с baseline, на Ryzen переносятся максимум два
|
||||
разных варианта C1/C2. При равенстве по скорости выбирается меньший RSS и
|
||||
меньшее изменение sherpa-onnx. Если прошел только новый шаг окна, воронка
|
||||
продолжается с одним C0. Если порога продолжения не достигла ни одна ветвь,
|
||||
эксперимент фиксирует `stop` до финального Ryzen A/B.
|
||||
Каждая существующая комбинация получает один прогон трех фрагментов на Intel.
|
||||
Все комбинации, выдержавшие обязательные условия и память, передаются в handoff;
|
||||
их остается не больше трех. Если прошел только новый шаг окна, передается один
|
||||
C0. Если новых комбинаций нет, Intel-агент фиксирует `stop-before-ryzen`:
|
||||
Ryzen-задача подтверждает итог по handoff и не запускает модели.
|
||||
|
||||
### Этап 5. Принять финалиста на Ryzen
|
||||
|
||||
На Ryzen выполняются:
|
||||
Ryzen-агент начинает с восстановления handoff. Если передано ноль кандидатов и
|
||||
Intel-итог равен `stop-before-ryzen`, после проверки commit, SHA-256 капсулы и
|
||||
`--validate-only` он фиксирует итог `stop` и закрывает задачу без запуска
|
||||
моделей. При наличии кандидатов агент воспроизводит совпадающий baseline и
|
||||
выполняет изолированные QDQ и shared-session A/B для используемых механизмов.
|
||||
Каждый такой A/B состоит из одного прогона baseline и одного прогона кандидата
|
||||
на трех фрагментах. Порядок baseline и кандидата меняется между парами. Эти A/B
|
||||
проверяют обязательные условия и объясняют вклад механизма. Проигрыш по скорости
|
||||
сам по себе не снимает переданную комбинацию; до первичного A/B она выбывает
|
||||
только при нарушении обязательных условий или правила памяти.
|
||||
|
||||
- совпадающий baseline;
|
||||
- не больше двух комбинаций из этапа 4.
|
||||
Затем первичный A/B получают все переданные комбинации, но не больше трех.
|
||||
Каждый A/B состоит из одного прогона baseline и одного прогона кандидата на трех
|
||||
фрагментах. Порядок меняется для следующей пары. Вариант, который нарушает
|
||||
обязательные условия или не достигает порога продолжения, выбывает без
|
||||
дополнительных прогонов.
|
||||
|
||||
Изолированные QDQ и shared-session A/B уже выполнены в этапе 3 и здесь не
|
||||
повторяются.
|
||||
|
||||
Первичный A/B состоит из одного прогона baseline и одного прогона кандидата на
|
||||
трех фрагментах. Порядок меняется для следующей пары. Вариант, который не
|
||||
достигает порога продолжения, выбывает без дополнительных прогонов.
|
||||
|
||||
Не больше двух вариантов, прошедших первичный A/B, получают по пять чередующихся
|
||||
A/B-циклов: C0, если он отличается от baseline, и лучший по времени диаризации
|
||||
из C1/C2; иначе два лучших варианта C1/C2. Один цикл содержит все три фрагмента;
|
||||
результат цикла - сумма времени диаризации. Итогом служат медиана пяти парных
|
||||
ускорений и MAD. Доверительные интервалы и новые повторы после пяти циклов не
|
||||
требуются.
|
||||
Не больше двух лучших вариантов, прошедших первичный A/B, получают по пять
|
||||
чередующихся A/B-циклов. Они выбираются по времени диаризации, при равенстве по
|
||||
скорости - по меньшему RSS, затем по меньшему числу отличий от baseline. При
|
||||
полном равенстве порядок C0, C1, C2 служит последним тай-брейком. Один цикл
|
||||
содержит все три фрагмента; результат цикла - сумма времени диаризации. Итогом
|
||||
служат медиана пяти парных ускорений и MAD. Доверительные интервалы и новые
|
||||
повторы после пяти циклов не требуются.
|
||||
|
||||
Итоговая комбинация проходит условие скорости, если достигает итогового порога
|
||||
на Ryzen. Примерно двукратное ускорение остается ориентиром. На Intel процент
|
||||
@@ -381,7 +446,7 @@ limits, температуры, throttling, swap и число потоков.
|
||||
|
||||
Peak RSS записывается для каждой ячейки и сравнивается с baseline той же машины.
|
||||
RSS выше 2 ГиБ на машине с 16 ГиБ RAM требует разбора, но сам по себе не
|
||||
отбрасывает вариант. Эксперимент останавливает ячейку при OOM, активной
|
||||
отбрасывает вариант. Правило памяти останавливает ячейку при OOM, активной
|
||||
подкачке, росте RSS между повторами без плато или линейном росте памяти с числом
|
||||
workers или session.
|
||||
|
||||
@@ -398,14 +463,18 @@ workers или session.
|
||||
равенстве по скорости выбирается более простой и экономный по памяти вариант.
|
||||
Ни один экспериментальный результат автоматически не меняет production-профиль.
|
||||
|
||||
Возможны четыре исхода:
|
||||
`stop-before-ryzen` - промежуточный итог Intel-этапа; после проверки handoff он
|
||||
становится итогом `stop`. `needs-info` - состояние заблокированной задачи, а не
|
||||
результат эксперимента.
|
||||
|
||||
Возможны четыре итоговых исхода:
|
||||
|
||||
- `go`: один вариант достигает итогового порога на Ryzen и проходит все
|
||||
проверки;
|
||||
- `needs-decision`: Ryzen проходит итоговый порог, но Intel показывает
|
||||
практически значимую регрессию;
|
||||
- `stop`: ни один вариант не проходит скорость, качество или память; причины
|
||||
сохраняются по каждой ветви;
|
||||
- `stop`: baseline 1.13.6 не принят либо ни один вариант не проходит скорость,
|
||||
качество или память; причины сохраняются по каждой ветви;
|
||||
- `new map`: сокращение окон и цены эмбеддинга упирается в качество раньше
|
||||
порога скорости, поэтому отдельно рассматривается end-to-end архитектура.
|
||||
|
||||
@@ -424,8 +493,9 @@ uv run pytest -q \
|
||||
повторы, смешанные результаты счетчиков, ветвь только с шагом окна, совместимый
|
||||
стек, наследование происхождения QDQ-материала и запрет общего исходника с
|
||||
контрольными записями, обязательные условия, два показателя остаточных кластеров,
|
||||
контроль общего бюджета потоков, продолжение незавершенного запуска и отсутствие
|
||||
приватного текста в ошибках.
|
||||
контроль общего бюджета потоков, продолжение незавершенного запуска, границу
|
||||
этапов Intel/Ryzen, не больше трех handoff-кандидатов и отсутствие приватного
|
||||
текста в ошибках.
|
||||
|
||||
До моделей выполняются:
|
||||
|
||||
@@ -437,9 +507,10 @@ uv run python scripts/benchmarks/diarization_calibration.py \
|
||||
--validate-only
|
||||
```
|
||||
|
||||
После эксперимента публичный отчет должен позволять восстановить все решения по
|
||||
агрегатам и хешам. Полное воспроизведение использует приватную капсулу из
|
||||
закрытой папки Яндекс Диска.
|
||||
Intel-отчет должен позволять восстановить отсев и точные рецепты переданных
|
||||
комбинаций по агрегатам и хешам. Финальный Ryzen-отчет ссылается на него и
|
||||
добавляет первичный A/B, финальные циклы и решение. Полное воспроизведение
|
||||
использует приватную капсулу из закрытой папки Яндекс Диска.
|
||||
|
||||
## Отклоненные варианты
|
||||
|
||||
@@ -451,16 +522,21 @@ uv run python scripts/benchmarks/diarization_calibration.py \
|
||||
которые могут складываться с сокращением работы.
|
||||
- Только современный CPU отклонен: он скрывает регрессии на AVX2 и не дает
|
||||
понять, зависит ли выигрыш от ISA.
|
||||
- Полная матрица на Ryzen отклонена: старый Intel дешевле для первичного отсева,
|
||||
а Ryzen нужен для ISA-чувствительных A/B и финальной комбинации.
|
||||
- Полная матрица на Ryzen отклонена: старый Intel дешевле для первичного отсева.
|
||||
Ryzen получает максимум три комбинации для одного первичного A/B и оставляет
|
||||
максимум две для дорогих циклов.
|
||||
- Сохранение текущего профиля остается допустимым итогом, если практического
|
||||
победителя нет.
|
||||
|
||||
## Критерии завершения задачи эксперимента
|
||||
## Критерии завершения задач эксперимента
|
||||
|
||||
- [ ] Стенд и тесты реализуют описанную воронку и не меняют пользовательский
|
||||
контракт диаризации.
|
||||
- [ ] Совпадающий baseline воспроизведен на Intel и Ryzen.
|
||||
- [ ] Intel-задача принимает baseline и завершает этапы 0-4 либо фиксирует
|
||||
подтвержденную регрессию как `stop-before-ryzen`; в обоих случаях коммитит
|
||||
обезличенный отчет и публикует полный handoff-комментарий.
|
||||
- [ ] Ryzen-задача начинает с указанного commit и проверенной капсулы, затем
|
||||
воспроизводит свой baseline без возврата к обычным Intel-замерам.
|
||||
- [ ] Все пройденные и остановленные ветви имеют явную причину и ссылку на
|
||||
ячейки результата.
|
||||
- [ ] Финальный A/B завершен либо зафиксировано, почему до него не дошел ни один
|
||||
|
||||
Reference in new issue
Block a user