<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Minimax on Блог Сергея Клюкина</title><link>https://sklukin.ru/tags/minimax/</link><description>Recent content in Minimax on Блог Сергея Клюкина</description><generator>Hugo</generator><language>ru-RU</language><lastBuildDate>Tue, 18 Aug 2026 08:45:13 +0000</lastBuildDate><atom:link href="https://sklukin.ru/tags/minimax/index.xml" rel="self" type="application/rss+xml"/><item><title>Локальная генерация видео из фото: MiniMax H3, ComfyUI и RTX 4090</title><link>https://sklukin.ru/posts/local-ai-video-minimax-h3/</link><pubDate>Tue, 18 Aug 2026 12:41:39 +0500</pubDate><guid>https://sklukin.ru/posts/local-ai-video-minimax-h3/</guid><description>Как я собрал локальный image-to-video пайплайн на MiniMax H3 и ComfyUI, подключил его к AI-агенту и превратил обычные фотографии в короткие ролики со звуком.</description><content:encoded><![CDATA[<p>Сегодня я попросил агента оживить две обычные фотографии. На первой двое мужчин должны были взлететь из двора в позе супергероев. На второй пара должна была превратиться в Бэтмена и Женщину-кошку. Через несколько минут агент вернул готовые MP4 со звуком.</p>
<p>Весь inference прошёл локально на моей RTX 4090. Агент самостоятельно выбрал video workflow, загрузил исходный кадр, составил подробный prompt, отправил задачу в очередь, дождался завершения и проверил финальный файл через <code>ffprobe</code>.</p>
<p>В этой статье разберу, как устроен пайплайн и что получилось на практике.</p>
<h2 id="первый-эксперимент-совместный-взлёт">Первый эксперимент: совместный взлёт</h2>
<p>Исходная фотография снята во дворе: два человека стоят рядом и смотрят в камеру. Задача звучала коротко: «Оба человека улетают как Супермены».</p>
<p>Для модели агент развернул её в подробное описание движения:</p>
<blockquote>
<p>Оба человека одновременно отталкиваются от земли, взлетают вверх и принимают классическую супергеройскую позу. Камера плавно поднимается вслед за ними. Лица, одежда, пропорции и окружение сохраняются. Под ногами поднимаются пыль и листья.</p>
</blockquote>
<p>Такой prompt фиксирует три важных свойства сцены:</p>
<ul>
<li>оба человека участвуют в действии одновременно;</li>
<li>внешность и одежда должны сохраниться;</li>
<li>камера получает понятную траекторию движения.</li>
</ul>
<p>Результат занял около <strong>220 секунд</strong> генерации. Получился ролик продолжительностью 5,17 секунды, с частотой 24 кадра в секунду и разрешением 608×800.</p>
<video controls playsinline preload="metadata" style="width: 100%; max-width: 760px; border-radius: 12px; margin: 1rem auto; display: block;">
  <source src="gallery/video/supermen-takeoff.mp4" type="video/mp4">
</video>
<h2 id="второй-эксперимент-превращение-в-бэтмена-и-женщину-кошку">Второй эксперимент: превращение в Бэтмена и Женщину-кошку</h2>
<p>Во втором тесте исходником стало зеркальное фото пары. Здесь движение сложнее: модель должна удержать двух людей, постепенно заменить одежду, сформировать маски, изменить освещение и сохранить композицию кадра.</p>
<p>В prompt я заложил последовательную трансформацию:</p>
<ul>
<li>броня и плащ собираются поверх костюма мужчины;</li>
<li>чёрный кожаный костюм и маска появляются на женщине;</li>
<li>лица, возраст, позы и положение людей остаются стабильными;</li>
<li>интерьер постепенно получает холодное синее освещение в духе Готэма;</li>
<li>финал заканчивается общей уверенной позой перед зеркалом.</li>
</ul>
<p>Отдельная часть prompt описывала типовые дефекты: лишних людей, дублирование конечностей, слияние тел, замену лиц и искажение рук. Это не гарантирует идеальную анатомию, но заметно сужает пространство для случайных решений модели.</p>
<p>Генерация заняла около <strong>240 секунд</strong> с теми же параметрами: 608×800, 20 шагов и 5 секунд целевой продолжительности.</p>
<video controls playsinline preload="metadata" style="width: 100%; max-width: 760px; border-radius: 12px; margin: 1rem auto; display: block;">
  <source src="gallery/video/batman-catwoman-transformation.mp4" type="video/mp4">
</video>
<h2 id="что-работает-под-капотом">Что работает под капотом</h2>
<p>Снаружи весь сценарий выглядит как одна просьба в Telegram. Внутри запрос проходит через несколько компонентов:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Telegram
</span></span><span class="line"><span class="cl">   ↓
</span></span><span class="line"><span class="cl">Hermes Agent
</span></span><span class="line"><span class="cl">   ↓
</span></span><span class="line"><span class="cl">Python wrapper
</span></span><span class="line"><span class="cl">   ↓
</span></span><span class="line"><span class="cl">ComfyUI :8188
</span></span><span class="line"><span class="cl">   ↓
</span></span><span class="line"><span class="cl">MiniMax H3 на RTX 4090
</span></span></code></pre></div><p>Hermes получает фотографию и определяет, что задаче нужен image-to-video workflow. Wrapper работает напрямую с нативным API ComfyUI:</p>
<ol>
<li>загружает исходник через <code>POST /upload/image</code>;</li>
<li>подставляет prompt, размеры, duration и seed в API-format workflow;</li>
<li>отправляет workflow через <code>POST /prompt</code>;</li>
<li>опрашивает <code>GET /history/{prompt_id}</code>;</li>
<li>скачивает MP4 через <code>GET /view</code>;</li>
<li>проверяет контейнер, кодеки, разрешение и продолжительность.</li>
</ol>
<p>ComfyUI самостоятельно ведёт очередь выполнения. Одна генерация занимает несколько минут и полностью загружает GPU. Wrapper получает <code>prompt_id</code>, ждёт завершения workflow и забирает файл из output history.</p>
<p>Минимальный вызов wrapper выглядит так:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 generate_image_video_job.py <span class="se">\
</span></span></span><span class="line"><span class="cl">  --model minimax-h3 <span class="se">\
</span></span></span><span class="line"><span class="cl">  --input photo.jpg <span class="se">\
</span></span></span><span class="line"><span class="cl">  --prompt <span class="s2">&#34;Both people transform into cinematic superheroes...&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --width <span class="m">608</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --height <span class="m">800</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --duration <span class="m">5</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --steps <span class="m">20</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">  --output result.mp4
</span></span></code></pre></div><p>Wrapper написан на стандартной библиотеке Python: <code>argparse</code>, <code>urllib</code>, <code>json</code>, <code>time</code> и <code>pathlib</code>. Для одной загрузки, трёх HTTP-операций и polling loop отдельный SDK ничего полезного не добавляет.</p>
<h2 id="контрольный-прогон-пайплайна">Контрольный прогон пайплайна</h2>
<p>Для контрольного прогона я запустил полный smoke test через установленный skill. Весь путь прошёл напрямую через ComfyUI на порту 8188.</p>
<p>Сначала FLUX Schnell сгенерировал стартовый кадр размером 512×512 за <strong>5,14 секунды</strong>: дружелюбный ретро-робот в цветочном поле.</p>
<p><picture>
      <source type="image/webp" srcset="/posts/local-ai-video-minimax-h3/gallery/test/direct-comfyui-test-image_hu_89c5a040adf36b68.webp 480w, /posts/local-ai-video-minimax-h3/gallery/test/direct-comfyui-test-image_hu_ca7053418d7e1ae.webp 512w" sizes="(max-width: 768px) 100vw, 768px">
      <source srcset="/posts/local-ai-video-minimax-h3/gallery/test/direct-comfyui-test-image_hu_93b54812c84cc87e.png 480w, /posts/local-ai-video-minimax-h3/gallery/test/direct-comfyui-test-image.png 512w" sizes="(max-width: 768px) 100vw, 768px">
      <img src="/posts/local-ai-video-minimax-h3/gallery/test/direct-comfyui-test-image.png" alt="Тестовый кадр FLUX Schnell для последующей генерации видео"  width="512" height="512" loading="lazy" decoding="async">
    </picture></p>
<p>Затем этот кадр стал <code>first_frame</code> для MiniMax H3. Робот должен был поднять руку, один раз помахать и опустить её, пока цветы двигаются от ветра, а камера медленно приближается.</p>
<video controls playsinline preload="metadata" style="width: 100%; max-width: 760px; border-radius: 12px; margin: 1rem auto; display: block;">
  <source src="gallery/video/direct-comfyui-test-video.mp4" type="video/mp4">
</video>
<p>Генерация заняла <strong>150,52 секунды</strong>. При целевой длине четыре секунды итоговый MP4 получился продолжительностью 4,458 секунды: H.264, 512×512, 24 FPS, стереозвук AAC 32 кГц. Разница связана с внутренним выравниванием последовательности кадров MiniMax H3.</p>
<p>На контрольных кадрах робот сохранил корпус, голову и пропорции, выполнил заметный взмах рукой, а сцена осталась стабильной. В аудиодорожке присутствует реальный сигнал: средний уровень составил −16,1 dB, пиковый — −1,7 dB.</p>
<p>Этот прогон подтвердил рабочую схему <code>wrapper → ComfyUI</code>: нативной очереди и history ComfyUI достаточно для последовательной генерации изображений и видео.</p>
<h2 id="из-чего-состоит-workflow-minimax-h3">Из чего состоит workflow MiniMax H3</h2>
<p>ComfyUI загружает несколько частей модели:</p>
<ul>
<li>diffusion model <code>MiniMax H3</code> в FP8;</li>
<li>мультимодальный text encoder на базе Qwen3-VL 32B в NVFP4/AWQ;</li>
<li>отдельный video VAE в FP16;</li>
<li>отдельный audio VAE в FP32;</li>
<li>sampler <code>res_multistep</code>;</li>
<li>узел <code>MiniMaxH3ImageToVideo</code> для prompt, размеров и первого кадра.</li>
</ul>
<p>Исходная фотография подключается как <code>first_frame</code>. Поэтому композиция стартового кадра сохраняется намного лучше, чем при чистом text-to-video. В этом же workflow декодируются видео и стереозвук, после чего ComfyUI сразу сохраняет результат в MP4 с H.264 и AAC.</p>
<p>MiniMax H3 выравнивает длину последовательности по внутреннему шагу в 17 кадров. Для целевых пяти секунд при 24 FPS workflow формирует 124 кадра. На выходе получается фактическая продолжительность около <strong>5,17 секунды</strong>.</p>
<h2 id="почему-я-выбрал-608800">Почему я выбрал 608×800</h2>
<p>Обе исходные фотографии вертикальные. Я сохранил близкое соотношение сторон и взял размеры, кратные 32. Это уменьшает лишний crop и удерживает обоих людей в кадре.</p>
<p>Разрешение напрямую влияет на время и потребление памяти. Для короткого эксперимента 608×800 даёт разумный баланс:</p>
<ul>
<li>лица остаются различимыми;</li>
<li>вертикальная композиция фотографии сохраняется;</li>
<li>результат удобно отправлять в Telegram;</li>
<li>одна генерация укладывается примерно в четыре минуты на RTX 4090.</li>
</ul>
<p>Для горизонтального ролика я бы начал с 864×480. Увеличивать разрешение стоит после проверки движения на более дешёвом прогоне.</p>
<h2 id="что-пришлось-настроить-на-gpu-узле">Что пришлось настроить на GPU-узле</h2>
<p>MiniMax H3 оказался требовательным к окружению. Рабочая конфигурация использует современную сборку PyTorch с CUDA 13, режим DynamicVRAM и параметры запуска ComfyUI <code>--fast-disk --disable-pinned-memory</code>.</p>
<p>Старая сборка PyTorch с CUDA 12.6 упиралась в память ещё при загрузке text encoder и diffusion model. После обновления весь workflow стал стабильно помещаться на RTX 4090 и выдавать пятисекундный ролик за несколько минут.</p>
<p>Параллельные video jobs я сознательно не запускаю. Одна задача насыщает GPU, а конкуренция за VRAM добавляет риск выгрузки моделей и падения процесса. Очередь последовательно обрабатывает тяжёлые генерации, сохраняя предсказуемое время выполнения.</p>
<h2 id="prompt-для-видео-описывает-движение">Prompt для видео описывает движение</h2>
<p>При генерации картинки prompt в основном отвечает за содержимое кадра. В image-to-video исходник уже задаёт сцену, людей и композицию. Текст должен подробно описывать изменение во времени.</p>
<p>Полезная структура prompt выглядит так:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">1. Кто и когда начинает двигаться.
</span></span><span class="line"><span class="cl">2. Как развивается действие.
</span></span><span class="line"><span class="cl">3. Как движется камера.
</span></span><span class="line"><span class="cl">4. Что требуется сохранить из исходника.
</span></span><span class="line"><span class="cl">5. Каким должен быть финальный кадр.
</span></span><span class="line"><span class="cl">6. Какие артефакты следует исключить.
</span></span></code></pre></div><p>Для нескольких людей особенно полезны формулировки <code>both people</code>, <code>simultaneously</code>, <code>remain in their original positions</code> и <code>preserve facial identity</code>. Для трансформаций стоит описывать порядок появления деталей от начала до финальной позы.</p>
<h2 id="ограничения-которые-уже-видны">Ограничения, которые уже видны</h2>
<p>Локальная генерация коротких роликов стала достаточно быстрой для интерактивных экспериментов, но результат по-прежнему зависит от сложности сцены.</p>
<p>Основные слабые места:</p>
<ul>
<li>руки и предметы в руках могут менять форму;</li>
<li>лица иногда плывут при быстром повороте головы;</li>
<li>два человека повышают вероятность слияния деталей;</li>
<li>сложное превращение может закончиться лишь визуально похожим костюмом;</li>
<li>модель иногда предпочитает эффектный кадр точному выполнению траектории;</li>
<li>пяти секунд мало для нескольких последовательных действий.</li>
</ul>
<p>Поэтому после генерации агент извлекает контрольный кадр ближе к концу ролика и проверяет наличие обоих персонажей, общий смысл действия и критические анатомические дефекты. Финальную оценку всё равно лучше делать просмотром полного видео.</p>
<h2 id="зачем-запускать-это-локально">Зачем запускать это локально</h2>
<p>Локальный пайплайн даёт несколько практических преимуществ:</p>
<ul>
<li>фотографии остаются внутри домашней инфраструктуры;</li>
<li>стоимость эксперимента определяется уже купленным железом и электричеством;</li>
<li>ComfyUI доступен всем моим агентам через один набор wrappers и workflow;</li>
<li>workflow, модели, seed и параметры находятся под моим контролем;</li>
<li>генерацию можно встроить в Telegram, блог и другие автоматизации.</li>
</ul>
<p>Самая удобная часть этой схемы — пользователь не работает с ComfyUI напрямую. Достаточно отправить фотографию и одной фразой описать сцену. Агент переводит намерение в технический prompt, выбирает модель и параметры, следит за очередью и возвращает проверенный MP4.</p>
<h2 id="итог">Итог</h2>
<p>Локальная MiniMax H3 на RTX 4090 уже позволяет превращать обычные фотографии в короткие вертикальные ролики со звуком примерно за четыре минуты. Качество пока требует контроля, особенно в сценах с несколькими людьми, руками и сложной сменой одежды. Для коротких творческих экспериментов текущий результат вполне пригоден.</p>
<p>Пайплайн закрывает полный путь от фотографии в Telegram до готового MP4 прямыми вызовами ComfyUI. Следующий практический шаг — автоматическая проверка нескольких кадров по всей длине ролика, чтобы ловить кратковременные артефакты между началом и финалом.</p>
]]></content:encoded></item></channel></rss>