~/.cache/ytai/mlx.lock — одна локальная модель за раз (mlx_queue.py: свободной памяти ≥ 30 %, потолок ожидания 3 ч, код 75). ~/.cache/ytai/render.lock = RENDER.lock — на APFS без учёта регистра это один файл — один тяжёлый рендер (render_queue.py / render_gate.py). Рендер запускать системным python3: процесс с .venv_transcribe в командной строке держит mlx_queue часами.Тяжёлое на маке идёт через замки: модели — mlx.lock, рендер — render.lock.
Версии, пути весов и время — в таблицах «Модели» и «Движки» ниже.
| Задача | Модель · версия | Где идёт | Веса, замок, время |
|---|---|---|---|
| Распознавание речи | mlx-community/whisper-large-v3-mlx (mlx_whisper 0.4.3, mlx 0.31.2), word_timestamps, condition_on_previous_text=False | мак, .venv_transcribe; Memex — тот же venv по ssh (align_worker.py, HF_HUB_OFFLINE=1) | HF-кэш ~/YTAI/models/huggingface (HF_HOME) и ~/.cache/huggingface; mlx.lock; DC: 84 куска за 6 мин на Memex |
| Распознавание речи, быстро | mlx-community/whisper-large-v3-turbo | мак | sc_qc asr (приёмка речи YTCR), камеры в разборе дня; через mlx_queue.py |
| Выравнивание слов по звуку | torchaudio MMS_FA (CTC, with_star) | мак, процессор | ~/.cache/torch/hub/checkpoints/model.pt — 1,26 ГБ; ≈ 1 с на край; flock mlx.lock, ждёт до 1800 с |
| Выравнивание, английский | torchaudio WAV2VEC2_ASR_BASE_960H: align = forced align по тексту листа, letters = жадное CTC без языковой модели | мак | wav2vec2_fairseq_base_ls960_asr_ls960.pth; solo.py align · letters |
| Выравнивание, русский | wav2vec2-xlsr-russian (на основе xlsr-53), transformers Wav2Vec2ForCTC; окна ≈ 25 с, слова без кириллицы — «звезда» | мак, .venv_whisperx (torch 2.13, transformers 5.13.1; пакета WhisperX нет — только имя venv) | ~/YTAI/environment/models/wav2vec2-xlsr-russian — вне git |
| Роли по голосам | pyannote/speaker-diarization-3.1 (pyannote.audio 4.0.3) | мак, MPS, иначе процессор | токен ~/.cache/huggingface/token; torchcodec сломан — звук подаётся через soundfile |
| Лица: детекция | YuNet cv2.FaceDetectorYN (score 0,6 · NMS 0,3 · top_k 50) | мак | ~/YTAI/environment/models/face/yunet.onnx, 232 КБ, OpenCV Zoo — вне git |
| Лица: узнавание героя | SFace cv2.FaceRecognizerSF (128-D), HERO_SIM 0,30 | мак | sface.onnx 38 МБ; эталоны 999_extra/face_finder/refs_khalid_ali.npy (69), refs_kamran_sharaf.npy (21) — вне git; ложные 0,42–0,54 на похожих типажах — глазами |
| Что в кадре (VLM) | mlx-community/Qwen2.5-VL-7B-Instruct-4bit (mlx_vlm 0.6.10); запасная Qwen2-VL-2B-Instruct-4bit | Memex (ревью), мак (.venv_vlm, разбор дня) | VLM ≈ 60–70 мин на фильм, пробы ≈ 50 мин; движки фильмов VLM сами не зовут — каталог перебивок готовится выше по течению и путал лица |
| Локальная LLM | mlx-community/Qwen3-8B-4bit (mlx_lm 0.31.3) | мак и Memex, .venv_llm | сцены разбора дня, суждения ревью (≈ 20 мин), сжатие актов; mlx.lock |
| Облачные агенты | rya-draper (отбор шортсов → picks.json), помощники по BRIEF_edl.md и BRIEF_trims_screens.md, rya-murch (сюжет); модель в frontmatter не задана — модель сессии | облако Claude | у помощников общий scratchpad — одноимённые черновики затирают друг друга: писать только в agents/edl/ |
| Облачные проходы Workflow | 0509 cloud/wf_judge.js (судья · факты · кропы · скептик, ≤ 10 агентов), wf_verdict_doc.js, story_map/workflows | облако | один текстовый проход на фильм — четыре круга без системы сожгли ≈ 99 M токенов |
| Движок | Для чего | Параметры | Ключи и грабли |
|---|---|---|---|
| HyperFrames | экраны и выноски: HTML/GSAP → ProRes 4444 с альфой | npx [email protected] (screens2 — 0.8.103), Node 22+, --workers 1; HYPERFRAMES_NO_TELEMETRY=1 HYPERFRAMES_SKIP_SKILLS=1 PRODUCER_BROWSER_GPU_MODE=hardware | две версии в коде — свести; альфа только в mov и в один поток |
| Remotion | второй движок графики: кусок с камерами и экранами за один проход, шаблон из JSON, альфа с метками | 4.0.532 в 999_extra/remotion; npm run film (4K H.264 40M, PNG) · alpha (ProRes 4444); setColorSpace bt709; через очередь рендера | 8 бит sRGB — лог и кубы заранее в ffmpeg; ~4 к/с на 4K; лицензия: бесплатно до 3 сотрудников, ключ не задан; сравнение — Экраны кодом |
| chrome-headless-shell · GUI Chrome | кадры экранов без рендера; плашки шортсов | ~/.cache/puppeteer; GUI Chrome --headless=new, прозрачный фон | GUI Chrome в headless виснет на занятом маке; после --screenshot не выходит сам |
| ffmpeg — промежуточное | кусок = файл | prores_videotoolbox -profile:v standard (autocut); части x264 40 Мбит/с, закрытый GOP 12, затем -c copy | ProRes теги цвета берёт с кадра — ставить setparams |
| ffmpeg — фильм | выдача 4K | libx264 [email protected], 40M (maxrate 80M/60M), GOP 12, bf 2, stitchable; aac_at 320k (паспорт ждёт 384 — жёлтая строка) | M3 Max ≈ 19 кадров/с одной частью, ≈ 21 двумя (--par 2) |
| ffmpeg — шортсы | вертикаль 1080×1920 | libx264 -preset slow -crf 12 -maxrate 40M, yuv420p, AAC 320k 48 кГц, +faststart; склейки читать -fps_mode passthrough | субтитры — поток PNG: libass и drawtext в сборке нет |
| ffmpeg — лёгкие копии | Loom, телефон, Telegram | h264_videotoolbox 8–10M; light.py: 1080p · 4K H.264 ≈ 27 Мбит/с · HEVC libx265 ≈ 12 (hvc1) | -r 25 дублирует хвостовые кадры — -fps_mode passthrough |
| ebur128 · 17_audio/standard.py | громкость | −14 LUFS ±1, пик −1 dBTP, потолок лимитера −1,5, LRA ≤ 8 | autocut без loudnorm: усиление → alimiter → линейная подстройка |
| AUSoundIsolation | изоляция голоса | 999_extra/bin/voice_isolate --wet 100 --quality high (HighQualityVoice, macOS 15+); EQ «рецепт C» из adobe_podcast_enhance | бинарь вне git: swiftc -O voice_isolate.swift -o bin/voice_isolate |
| video_tech_qc.py | паспорт YouTube и VMAF | run F --profile yt_4k25 | yt_1080p25 | yt_short1080; --ref OLD.mp4 → VMAF ok 93 / bad 85 | целиком медленнее реального времени — в приёмке --no-scan; с --ref ни один этап пока не вызывает |
| Epidemic Sound MCP | музыка под длину | JSON-RPC https://www.epidemicsound.com/a/mcp-service/mcp: SearchRecordings, EditRecording (forceDuration ≤ 300 с), Poll, Download | ключ в двух местах: ~/.config/epidemic/api_key (autocut) и ~/.config/ytai/epidemic_sound.env (шортсы); CDN ≈ 18 КБ/с на поток — качать кусками Range; канал в safelist |
| YouTube Data API v3 | заливка, видимость, публикация | 08_youtube/upload_youtube.py --sni-bypass (resumable, куски 8 МиБ, дедуп по названию); scheduled_publish.py → public | токен канала в 08_youtube/channels.json, scope youtube.upload + youtube.force-ssl; лимит ~10 заливок в сутки; Related video в API нет |
| Telethon · бот Telegram | мастера в «Избранное», статусы | tg_send.py: SaveBigFilePart 512 КБ × 8 потоков, до 2 ГБ, /opt/homebrew/bin/python3; статусы ~/bin/tg.py text rya 155880671 | бот шлёт до 50 МБ — поэтому Telethon от своего аккаунта; сессия бывает занята (database is locked) — повторить |
| rclone | Drive: оригиналы вниз, мастера и исходники вверх | remote gdrive_rscore; --bind $(ipconfig getifaddr en0) мимо VPN; --drive-chunk-size 64M; cat --offset для докачки | --include и --exclude вперемешку — правила одним --filter |
| Sheets v4 · Trello REST · Docs | учёт: ContentList, карточка, документы | ledger.py, sheets_chip_links.py --verify, story_to_gdoc.py | ~/.config/rscore/token.json, ~/.config/rya/trello.env |
| qrencode + zbarimg · Natural Earth · OSM | QR на экранах, карты | doc_cut проверяет QR чтением; карты sc_geo.py / ytcg_geo.py prep | ytcg QR без проверки |
Две части дают ≈ +2 к/с, а своп 38 ГБ увёл мак в панику ядра — в «Граблях»: --par 1.
mlx_queue.py <who> -- cmd: ждёт чужие процессы с моделями (шаблон PAT) и свободную память ≥ 30 %render_queue.py <who> [--max-wait] [--idle-pass 240] -- cmd: чужой рендер = ffmpeg > 150 % CPU, x264, AME, Premiere > 300 %, chrome-headless-shell/hyperframes > 100 %, aerenderrender_gate.py --label --max-wait 30 (autocut): через 30 мин идёт дальше под nice~/.cache/ytai/stage_snapshots/, а не из живого этапаПорядок проверок render_queue.py (999_extra): одна команда — один захват замка.
Модели — так же через mlx_queue.py: чужие mlx-процессы → mlx.lock → память ≥ 30 % → потолок 3 ч, код 75. autocut — render_gate.py: замок RENDER.lock, через 30 мин идёт дальше под nice.
| Файл YTs/{CH}/ | Кто читает | Важные ключи | Кто и когда пишет |
|---|---|---|---|
| shorts_profile.json (YTTRBM, YTFP, YTEVO) | 07_shorts job.py: сливается с DEFAULTS, ключи задания перекрывают | gfx · accent · brand · captions · plate · hosts.<Имя>.seat · youtube.slug · cadence_hours · hashtags · rules · forbid · sheet · trello · edges.strict · broll.from | копия у YTTRBM при новом канале; решения Романа с *_note (YTFP: broll 2,5, edges.strict, plate 3,6 с) |
| shorts_gfx.html | gfx.py шортсов (поле профиля gfx) | #brand, .plate(.lead), <!--PLATES--> | руками, по бренду канала |
| color_profile.json (YTEVO, YTUVIE), color-profile-v1 | autocut/color.py (путь YTEVO зашит), 15_color, препрод, project_check | develop{гамма → lut, cameras, decided_by} · look.id · exposure.target_face_luma (YTEVO 134, YTUVIE 149,3) | 15_color/1502_lut_pick/color_plan.py save_choice по выбору Романа в витрине, с бэкапом |
| review_profile.json (YTCH, YTCR, YTEVO, YTUVI, YTUVIE) | 0509_review_cycle; doc_cut/story.py → structure_rules | structure_rules: fund_block_gap_sec 30, fund_piece_max_sec 90, fund_entry_min 34, fund_rx, money_rx · rules_text · tz_classes · style · verdict | руками после решения Романа, с пометкой («Роман, 26.09.2026 (YTCH11 v5)») |
| preprod_profile.json (YTEVO, YTUVIE) | 13_preprod → lesson_plan, который нужен autocut | vocabulary · mech_allow · design · people · links · legal_rf | руками или агентом; рядом .bak_* |
| {CH}_voices.json + {CODE}_cast.json | разбор дня: s13–s16 | groups A/B/C · people[id, name, aliases, voiceprints] | voice_registry.py --enroll — только после того, как человек подтвердил имя |
| {CH}.md | ревью (раздел Story-arc template); подсказка Draper | правила канала текстом | руками |
| brand_profile.json + brand/ (YTCH) · gfx/ (YTCG) · BRAND.md (YTCR, на T9) | bdd_plates, doc_cut/gfx.py (шрифты, логотип), ytcg.py, sc_gfx | palette · fonts · rules · logo · maps | по брендбуку; палитры движков пока зашиты в коде |
| Движок | Пишет человек или агент | Пишет код |
|---|---|---|
| Шортсы · 00_Setup/07_Shorts/ | {CODE}_shorts_job.json (мастер, cues, people, keep_out, masters, drive); picks.json — Draper, broll — человек; frame_legend.json | picks_prompt.md, transcript_roles.txt, edges.json, out/manifest.json, master_ref.m4a, viz/S{NN}/brief.json, music/S{NN}.json, broll/cuts.json |
| autocut · 02_Assembly/autocut_v4/ | directives_v4.json (edges · trims · framing · choice · screens_off · screens_time · facts, поля _why); notes_text.json | cut_v4.json, screens_final.json, faces_v4.json, color_v4.json, qc/, PROGRESS.md, design/*.md |
| headless мультикам · 08_Cut/ | {CODE}_cut_job.json; помощники — {CODE}_trims_v1.json, {CODE}_screens_v1.json (гейт brief.py lint); ТЗ 02_Assembly/{CODE}_Assembly_v{N}_in.json | sync_model.json, words_aligned.json, edl_audio_<tag>.json, edl_<tag>.json, verify_<tag>.json, qc_<tag>.json, status.json |
| headless solo | {CODE}_cut_job.json (mode solo, cta.qr_url, gfx.theme); {CODE}_takes_v1.json; {CODE}_screens_v1.json | edges_v1, listen_v1, letters_v1, words_v1, edl_v1 |
| doc_cut | {CODE}_montage_v1.json — единственное, что правится руками; {CODE}_gfx_v1.json; {CODE}_music_v1.json; {CODE}_preview_notes.json (ask, fund) | edl_audio_v1, paper_v1.md, words_local_v1, check/verify_v1, edl_v1, color.json, conform_v1, PROGRESS.md |
| story_cut | {CODE}_storycut_job.json (tag, look, target_face, gamma_override, dedup.pools); agents/edl/B<N>.json — помощники (гейт sc_edl check); {CODE}_gfx_overrides.json; EDL_NOTES.md; карта сцен scene_maps/ | agents/{blocks/, broll_catalog.md, speech_angles.md}, align_v1.json, media_index.json, {CODE}_cut_<tag>.json, {CODE}_color_<tag>.json, {CODE}_music_plan.json, dedup_log.md |
| story_map · ревью | edge_overrides_vN.json — края, выверенные по звуку (берётся последний N); review_card.json — создаёт review.py init, дальше человек | story_vN.json, _analysis/* |
| Проверка | Как | Норма | Откуда взялась |
|---|---|---|---|
| Веса на месте | ls model.pt · yunet.onnx · sface.onnx · wav2vec2-xlsr-russian; HF-кэш | каждый файл есть; нет — отказ с именем | новый мак или чистый venv: ничего из этого не в git |
| Офлайн-модели | HF_HOME и HF_HUB_OFFLINE=1 на Memex | модель грузится без сети | Memex без доступа к HF |
| Токены и ключи | channels.json (scope upload + force-ssl), tg_user.session, epidemic key, token.json, trello.env | все есть, права 600 | заливка падала на неаудированном scope; ключ Epidemic — в двух местах |
| Задачи launchd | launchctl list | grep ytai | обе задачи загружены | schedule пишет ⛔, если публикатор не загружен |
| Память перед моделью | mlx_queue.py | свободно ≥ 30 % | kernel panic при свопе 38 ГБ и «36 % свободно» — ещё и RENDERQ_MAX_SWAP_GB |
| Замок рендера свободен | render_queue.py / render_gate.py | один тяжёлый процесс | замок не FIFO — зависимые шаги по очереди |
| Memex доступен | ssh memex … | Whisper и VLM отвечают | PATH без brew; VLM 60–70 мин на фильм |
| Версии движков | hyperframes 0.8.103 vs 0.8.106; mlx_whisper 0.4.3; pyannote 4.0.3 | одна версия на трек | две версии HyperFrames в коде одновременно |
| Файл | Что хранит | Кто и когда пишет |
|---|---|---|
| YTs/{CH}/*_profile.json | решения Романа по каналу с причинами в *_note | сессия сразу после решения; без причины правило откатят |
| {CH}_voices.json · refs_*.npy | голоса и лица, которым машина верит | voice_registry --enroll и face_finder — только после подтверждения человеком |
| color_profile.json | гамма → куб, look, цель экспозиции по лицу | color_plan.py save_choice по выбору Романа в витрине |
| 08_youtube/channels.json | токен и флаги канала YouTube | при запуске канала; scope проверять до первой заливки |
| ~/.config/ytai/publish_schedule.json · shorts_pending.json | график выхода и очередь доливки | shorts.py schedule, pending.py add; читают задачи launchd |
| README этапов · CLAUDE.md «Shorts» | каноны и грабли; у фильмов кодом раздела в CLAUDE.md ещё нет | сессия после ошибки, тем же коммитом |
| память: reference_memex_mlx_stack · reference_hub_auto_montage | где стоят модели, как к ним ходить | сессия в конце работы |
X=~/YTAI/scripts/999_extra; V=~/YTAI/environment/.venv_transcribe/bin/python python3 $X/mlx_queue.py <who> -- $V script.py … # модель под замком mlx.lock python3 $X/render_queue.py <who> --idle-pass 240 -- ffmpeg … # рендер под замком render.lock python3 ~/YTAI/scripts/05_editing/0510_autocut/render_gate.py --label <tag> --max-wait 30 -- … # то же для autocut ls -la ~/.cache/torch/hub/checkpoints/model.pt ~/YTAI/environment/models/face/ ~/YTAI/environment/models/ # веса на месте launchctl list | grep ytai # публикатор и доливка загружены ssh memex 'ls ~/YTAI/models/huggingface' # Memex и офлайн-кэш python3 $X/video_tech_qc.py run FILM.mp4 --profile yt_4k25 --no-scan # паспорт YouTube