◂ База знанийRYA.AETranscription Pipeline — транскрибация съёмочного дняобновлено 6 сен 2026
Транскрибация — фундамент этапов 2–4: каждый клип камеры и каждый TX-лав получает пословный транскрипт с таймкодами, и уже на нём стоят 2.3 Word Precision, 3.2 Word-Sync, 3.3 Fine Sync, 3.6 Transcript Document и 4.5 Assembly Brief. Мультикам синхронится по речи — по creation_time запрещено (кварц врёт на ±5–22 мин).
Быстрый старт. Штатная стадия — Phase 2 в run_pipeline.py (только с --all или --only transcribe). На Apple Silicon быстрый путь — mlx_whisper (Metal): 42-мин 4K → ~6 мин; офлайн-раннер держит ×11.5 реального времени. Один mlx-джоб за раз, длинное — фоном (nohup+caffeinate, лог в 00_Setup/logs/).
видео / WAVаудио 16k monoWhisper пословноpyannote диаризацияроли / спикерыJSON · SRT · Claude4_assembly
1Место в пайплайне2Движки3Команды4Язык5Диаризация6Роли слов7Zoom8Артефакты9Файлы

🧭2.6 · 1Место в пайплайне

  • Assembly brief читает {CODE}_Claude4_assembly.json с массивом words[] {w,s,e} на сегмент — из него берутся точные суб-сегменты: tc_in = first_word.s, tc_out = last_word.e + smart padding ≤0.3с.
  • Word-Sync — пословные транскрипты являются якорем синхронизации камер; часы устройств врут.
  • UXP-панель — Stage 6 стадии генерирует {CODE}_ingest.json в 00_Setup/01_Ingest/ для сборки проекта в Premiere.
  • Per-source EN-библиотека — каждый клип и TX-лав получает свой {stem}_en.json (mlx task=translate по аудио, НЕ LLM-перевод русского ASR) — строительные блоки для сборки.
  • Транскрипт таймлайна делается не проекцией слов из источников, а сборкой единого аудио таймлайна (лучшая дорожка на каждый момент) и его транскрибацией целиком — 100% покрытие, таймкоды сразу в timeline-времени.
Speaker ID (имена спикеров) — отдельный шаг вне пайплайна: python 03_speaker_id/00_process_all.py --project или Claude-проект.

⚙️2.6 · 2Движки: штатный и быстрый

штатная стадияmlx-инструменты
чтоscripts/02_transcribe/020101_transcribe/transcribe_project.py (v3.0): openai-whisper large-v3 + pyannote 3.1, 6 стадий (audio → diar → whisper → map → generate → ingest)scripts/999_extra/: mlx_transcribe_review.py (одно видео), mlx_transcribe_folder.py (пачка per-source), wordrole_transcribe.py (слова+роли), ytch_ru_transcribe/ (офлайн-раннер с ctl.sh)
скоростьчасами — openai-whisper на Mac идёт на CPU FP32 (mps игнорируется); телл-тейл в логе: «FP16 is not supported on CPU»минуты — Metal/MLX, модель mlx-community/whisper-large-v3-mlx: 42-мин 4K → ~6 мин; wordrole 6 ч аудио → 41 мин
форматper-clip JSON/SRT + {CODE}_Claude4_assembly.jsonтот же JSON-schema {duration, segments:[{id,start,end,text,words[]}]} + SRT; words.json wordsync-совместим ({w,s,e} float-секунды)
⚠️ Один mlx-джоб за раз — два параллельных не помещаются в RAM → jetsam-kill. ⚠️ Шебанг .venv_transcribe/bin/pip сломан (venv переезжал) — работает .../bin/python. У mlx_transcribe_folder: condition_on_previous_text=False + no_speech_threshold=0.5 (меньше каскадных галлюцинаций); тихие клипы помечаются likely_silent, готовые {stem}.words.json скипаются (идемпотентно).

▶️2.6 · 3Команды

штатная стадия (run_pipeline форвардит -n / --language / -m и добавляет -y)
# окружение
source ~/YTAI/environment/.venv_transcribe/bin/activate
# только транскрибация (язык известен → флаг; смешанный EN+RU → БЕЗ флага)
python ~/YTAI/scripts/run_pipeline.py "$PROJECT" --only transcribe --language en --no-pause
# всё (prepare + transcribe) · статус фаз
python ~/YTAI/scripts/run_pipeline.py "$PROJECT" --all --language en --no-pause
python ~/YTAI/scripts/run_pipeline.py "$PROJECT" --list
mlx: одно видео · папка per-source
HF_HUB_OFFLINE=1 ~/YTAI/environment/.venv_transcribe/bin/python \
  ~/YTAI/scripts/999_extra/mlx_transcribe_review.py --video V.mp4 --output 05_Review/ --language ru
PY=~/YTAI/environment/.venv_transcribe/bin/python
$PY ~/YTAI/scripts/999_extra/mlx_transcribe_folder.py --folder ".../01_Source/Video/07_Scene" --language en
Полезные ключи стадии: -n/--speakers (число спикеров, авто если опущен) · --skip-done · --force · --resume · --stages 3,4,5 · --multicam. Офлайн-раннер YTCH: ctl.sh {start|pause|status|watch}, переживает ребут.

🌐2.6 · 4Язык: правило флага --language

  • Автоопределение = флаг ОПУСКАЕТСЯ. Значение форвардится прямо в Whisper, который валидирует ISO-код.
  • Один известный язык → --language en / --language ru; смешанный проект (EN+RU, как YTCR03) → без флага.
  • У mlx_transcribe_folder.py дефолт — en, не auto.
⚠️ НИКОГДА --language auto: строка «auto» — невалидный код → «Unsupported language: auto» → вся Phase 2 падает (реальный случай YTCR03). ⚠️ mlx task=translate ломает пословный синхрон (279 нативных слов → 236 переведённых) — перевод только в отдельное дерево {stem}_en.json.

🗣2.6 · 5Диаризация

  • Штатно: pyannote/speaker-diarization-3.1 поверх full_audio.wav на MPS/CUDA; num_speakers из -n, иначе авто.
  • Диаризация готового транскрипта (без перегона Whisper): ffmpeg → 16k mono WAV → pyannote → сегменту существующего mlx-транскрипта присваивается спикер по max-перекрытию. ~106 мин аудио → ~3.5 мин на MPS. Скрипт-образец: scripts/999_extra/civ_meeting_diarize.py.
  • Диаризация правит только «кто говорит» — текст остаётся с ASR-ошибками исходной расшифровки.
ffmpeg -i in.m4a -ac 1 -ar 16000 -vn out.wav
⚠️ pyannote 4.x: Pipeline.from_pretrained(..., token=tok) — НЕ use_auth_token=; нужен HF-токен с принятыми условиями модели (ищется в ~/.huggingface/token / HF_TOKEN). ⚠️ soundfile не читает m4a — сначала ffmpeg в WAV. ⚠️ Не для multitrack-Zoom — там mix+diar (ниже).

🎭2.6 · 6Роли слов — wordrole_transcribe

  • scripts/999_extra/wordrole_transcribe.py — дословная транскрибация на языке оригинала с пословными таймкодами и ролями: mlx large-v3 + pyannote, каждому слову спикер по max-перекрытию, подряд один спикер → блоки-реплики.
  • Выходы {base}.*: .words.json (мастер), .diarized.txt/.srt (по ролям), .words.srt/.csv (пословно), .review.html (тёмная тема, чипы ролей).
  • Чекпойнты в _wordrole_work/: --rebuild-only пересобирает выходы из кэша за секунды; --speaker-names "A,B" — имена по talk-time; --plain — режим интервью/подкастов.

💻2.6 · 7Zoom и sparse-speech

  • Zoom с раздельными дорожками → transcribe_zoom_multitrack.py --mode mix+diar (дефолт): транскрибируется общий микс, спикер назначается по RMS-огибающим персональных треков.
  • Причина: Whisper на длинных тишинах per-speaker трека сеедит каскад галлюцинаций — реальный кейс: 1602× «Спасибо за внимание!», реальных сегментов 0.2%.
  • Правило для любого sparse-speech (рация, интерком): транскрибировать continuous-speech версию. --mode per-speaker — только когда общего микса не существует.

🩹2.6 · 8Известные артефакты и вычитка

  • Повтор слова на стыке сегментов — регулярный артефакт Whisper (и mlx). Проверка за ~30с: вырезать окно ±6с в mono 16k WAV → mlx_whisper.transcribe(..., word_timestamps=True, temperature=0.0): одно слово в пословном выводе — дефекта нет.
  • subs_wordfix.py — вычитка МЕЖДУ транскрибацией и сборкой субтитров: правит плоский список слов до нарезки на реплики (чинит фразы, разорванные границей реплики); правки — JSON [{from,to,why}].
$PY subs_wordfix.py --transcript in.json --fixes fixes.json --out fixed.json
⚠️ Дефисные слова у mlx — два токена («что-то» = «что»+«-то») → в from писать «что то». ⚠️ Сегмент, из которого правка вынесла все слова, — выбрасывать. ⚠️ В while-read циклах ffmpeg съедает stdin — нужен ffmpeg -nostdin.

📁2.6 · 9Куда кладутся файлы

чтогде
главный транскрипт01_Source/Transcription/{CODE}_transcript.json + transcripts/*.srt + captions/*.srt (пословные) + per-clip по сценам {scene}/
для Assembly brief00_Setup/{CODE}_Claude4_assembly.json (стадия Generate)
для UXP00_Setup/01_Ingest/{CODE}_ingest.json + {CODE}_audio_map.json
per-source (mlx folder)01_Source/Transcription/<folder>/{stem}.words.json|.srt|.txt + сводные _folder_transcript.*
EN-библиотекакамеры → 01_Source/Transcription/{clip}_en.json; лавы → 99_Pipeline/DJI_Audio/transcripts/{tx}_en.json (translate_caption_sources.py)
логи00_Setup/logs/{project}_run_pipeline_{ts}.log
Транскрибация = фундамент: речь — якорь синхрона, слова — валюта монтажа. mlx — минуты вместо часов; один джоб за раз; --language auto не существует.