run_pipeline.py (только с --all или --only transcribe). На Apple Silicon быстрый путь — mlx_whisper (Metal): 42-мин 4K → ~6 мин; офлайн-раннер держит ×11.5 реального времени. Один mlx-джоб за раз, длинное — фоном (nohup+caffeinate, лог в 00_Setup/logs/).{CODE}_Claude4_assembly.json с массивом words[] {w,s,e} на сегмент — из него берутся точные суб-сегменты: tc_in = first_word.s, tc_out = last_word.e + smart padding ≤0.3с.{CODE}_ingest.json в 00_Setup/01_Ingest/ для сборки проекта в Premiere.{stem}_en.json (mlx task=translate по аудио, НЕ LLM-перевод русского ASR) — строительные блоки для сборки.python 03_speaker_id/00_process_all.py --project или Claude-проект.| штатная стадия | 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-секунды) |
.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 скипаются (идемпотентно).# окружение 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
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}, переживает ребут.--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.pyannote/speaker-diarization-3.1 поверх full_audio.wav на MPS/CUDA; num_speakers из -n, иначе авто.scripts/999_extra/civ_meeting_diarize.py.ffmpeg -i in.m4a -ac 1 -ar 16000 -vn out.wav
Pipeline.from_pretrained(..., token=tok) — НЕ use_auth_token=; нужен HF-токен с принятыми условиями модели (ищется в ~/.huggingface/token / HF_TOKEN). ⚠️ soundfile не читает m4a — сначала ffmpeg в WAV. ⚠️ Не для multitrack-Zoom — там mix+diar (ниже).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 — режим интервью/подкастов.transcribe_zoom_multitrack.py --mode mix+diar (дефолт): транскрибируется общий микс, спикер назначается по RMS-огибающим персональных треков.--mode per-speaker — только когда общего микса не существует.mlx_whisper.transcribe(..., word_timestamps=True, temperature=0.0): одно слово в пословном выводе — дефекта нет.[{from,to,why}].$PY subs_wordfix.py --transcript in.json --fixes fixes.json --out fixed.json
from писать «что то». ⚠️ Сегмент, из которого правка вынесла все слова, — выбрасывать. ⚠️ В while-read циклах ffmpeg съедает stdin — нужен ffmpeg -nostdin.| что | где |
|---|---|
| главный транскрипт | 01_Source/Transcription/{CODE}_transcript.json + transcripts/*.srt + captions/*.srt (пословные) + per-clip по сценам {scene}/ |
| для Assembly brief | 00_Setup/{CODE}_Claude4_assembly.json (стадия Generate) |
| для UXP | 00_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 |