Все записи
6 мин

Нейросеть собрала из кусков франкенштейна: я выкинул сборку шортсов по шаблону

Building in PublicАвтоматизация

Если коротко, то я угробил целый подход к автоматической нарезке коротких видео из длинного ролика и заменил его на прямо противоположный. Раньше SceneX пытался собрать шортс из разных кусков ролика по слотам шаблона, и для каждого слота был свой поиск, своё ранжирование и комбинаторная сборка, как будто из конструктора собираешь. А на реальном материале это дало франкенштейна, где куски врезаны как попало, нет логики начала, нет логики конца, нет осмысленности. Теперь движок ищет в ролике один цельный самодостаточный отрезок на 20-75 секунд и вырезает его целиком, максимум подрезая края, и получается ноль склеек, непрерывный звук и никакого рассинхрона. И это, на минуточку, разворот того самого решения, которое до этого выбирал целый консилиум из ии-экспертов.

Что вообще делает SceneX

SceneX — это мой прототип, который должен сам делать шортсы из длинного видео, тот самый, который я когда-то достал с чердака и спроектировал ещё до первой строчки кода. Скармливаешь ему ролик, а на выходе получаешь готовый вертикальный отрезок под 9:16, который не стыдно выложить. Звучит просто, пока не доходит до главного вопроса, а как именно ии решает, что вырезать из часа болтовни. Вот вокруг этого вопроса всё и крутится, потому что весь смысл продукта спрятан именно тут, а не в кропе и не в субтитрах.

Изначальную архитектуру я не сам придумал на коленке, её выбрал консилиум. Это мой процесс, когда несколько ии-агентов (часть на Claude, часть на GPT) разбирают задачу с разных сторон, спорят, а я уже выбираю победителя. И вот они сошлись на сборке, то есть бьём шаблон на слоты — зацеп, развитие, кульминация — и под каждый слот ищем подходящий кусок в исходнике, ранжируем кандидатов и склеиваем лучшее. На бумаге логично, в спеке красиво. А потом я запустил это на настоящем видео.

Почему сборка по шаблону развалилась

Знаете это ощущение, когда система формально отработала, выдала результат, все галочки зелёные, а смотреть на это невозможно? Вот ровно оно. Работа ради работы была выполнена, каждый слот заполнен, комбинаторика отработала, файл собрался, а ролик при этом мусор. Куски из разных мест ролика, склеенные по логике шаблона, никак не складывались в историю, и звук скакал на каждой склейке, потому что фразы обрывались на полуслове и начинались с середины другой мысли. Нет логики начала, нет логики конца, нет силы в рилсе этом, нет главного смысла.

И тут до меня дошла мысль, которую я сначала даже забраковать не успел, настолько она простая, а именно что может надо вообще не из разных кусков ролика что-то собирать, а просто где-то вырезать что-то со смыслом. То есть не строить пазл из обрезков, а найти в исходнике место, где человек сам, без нашей помощи, сказал что-то цельное и сильное от начала до конца, и вырезать ровно это, одним куском, без всяких склеек.

Звучит как капитуляция перед сложностью, но на самом деле всё наоборот. Сборка из кусков — это попытка быть умнее материала, дорисовать драматургию там, где её в исходнике нет. А экстракция момента — это признание простого факта, что если в часовом ролике есть хоть один сильный самодостаточный отрезок, то его надо просто найти и не трогать. А если такого отрезка нет, значит и шортса хорошего из этого ролика не выйдет, и никакая комбинаторика тут не спасёт, только нарисует красивую обёртку вокруг пустоты.

Как устроена экстракция момента

Теперь логика такая, что LLM читает расшифровку ролика и ищет один связный отрезок на 20-75 секунд, у которого есть своё начало, своя мысль и свой финал, и мы вырезаем его целиком, максимум чуть подрезая края. Всё, никакой пересборки из разных таймкодов, никакого склеивания.

Эффект от смены подхода я почувствовал сразу по нескольким фронтам. Склеек больше нет в принципе, а значит нет и рассинхрона звука с картинкой, который вылезал на каждом стыке, и звук теперь идёт непрерывно, как в исходнике, потому что это и есть кусок исходника один в один. Да и кроп под вертикаль 9:16 стал проще, ведь когда у тебя один монолитный отрезок, а не лоскутное одеяло, кадрировать его под вертикаль — это уже чисто техническая задача, а не творческий ад со скачущими планами.

На первом же реальном видео новый подход выдал два момента, один на 61 секунду, второй на 31. Не десяток мусорных слотов, а два кандидата, и каждый из них можно смотреть как отдельный осмысленный кусок. Вот эта цифра для меня и была проверкой, потому что важно не то, что «система отработала», а то, что из ролика реально вынулось что-то живое.

Где всё равно вылез косяк

Без подводных камней, конечно, не обошлось. Я хотел резать отрезки строго по границам предложений, чтобы кусок начинался с начала фразы и заканчивался на точке, логично же. Но расшифровка идёт через Whisper, а Whisper отвратительно ставит пунктуацию в русской разговорной речи. Там, где человек просто сделал паузу и пошёл дальше, модель лепит точку, а где реально закончил мысль, может вообще ничего не поставить, и в итоге границы предложений, по которым я собирался резать, оказались выдуманными.

Пришлось обрезку по границам предложений просто убрать и резать края по паузам в речи, то есть по тишине, а не по придуманной пунктуации. Получилось честнее, ведь пауза в звуке — это реальный сигнал, что человек закончил мысль или перевёл дыхание, а точка от Whisper в русской разговорке — это гадание на кофейной гуще. Мелочь, а полдня съела, пока я не понял, что воюю не с тем.

Что осталось за качество отвечать

Главное ограничение сейчас честное и упирается в две вещи, в исходный материал и в модель. Если в часовом ролике нет ни одного сильного момента, то экстракция его не родит, потому что выдумывать она не умеет и не должна. А качество самого выбора момента упирается в gpt-4o-mini, на котором это сейчас крутится, и это дешёвая и быстрая модель, она нормально находит связный кусок, но тонкие нюансы, где именно сильнее эмоция, где живее интонация, ловит так себе.

Следующий рычаг тут понятный, подставить модель посильнее через OPENROUTER_MODEL и сравнить, насколько лучше она находит реально цепляющие моменты. Это та история, когда архитектура уже правильная, а дальше ты просто крутишь ручку «модель» и смотришь, где проходит граница цена/качество. По той же логике, что и в других проектах, у меня уже был переезд с OpenAI на OpenRouter, когда я упёрся в деньги, так что инфраструктура под смену модели готова заранее.

И вывод из всей этой истории для меня даже не про видео, а про сам способ принимать решения. Консилиум — штука сильная, но он спорит на бумаге, а ломается всё всегда о реальный материал. Шесть ии-экспертов могут красиво обосновать сборку по шаблону, и аргументы будут логичные, а потом ты запускаешь это на настоящем ролике, смотришь на франкенштейна и понимаешь, что вся стройная архитектура заполняла слоты, но не делала главного, не находила смысл. Иногда самый умный ход в разработке с ии — это не достроить сложную систему, а выкинуть её и спросить себя простую вещь, а что я вообще пытаюсь получить на выходе. Я-то пытался собрать смысл из кусков, а его надо было просто найти и не трогать. Вот и делайте выводы.