SoftCache: как ускорить диффузионные модели до 6,9×

SoftCache: как ускорить диффузионные модели до 6,9×

Одна картинка в FLUX.1-dev это 50 последовательных прогонов большого трансформера. Латент между шагами меняется совсем немного, и каждый следующий проход честно пересчитывает почти то же самое, что уже посчитал предыдущий. Кэширование шагов выросло именно из этой избыточности, но до сих пор работало как светофор: обновить или переиспользовать, третьего не дано.

Статья SoftCache (arXiv 2610.22369) предлагает третье. Если сигнал, по которому кэш решает обновляться, ещё далёк от порога, зачем идти шагом сетки? Можно шагнуть дальше, перепрыгнуть несколько запланированных узлов и приземлиться между ними. На FLUX, HunyuanVideo и Wan2.1 такой сэмплер ускоряет генерацию до 6,9× и при этом точнее всех конкурентов воспроизводит некэшированный результат.

Что такое SoftCache

SoftCache это метод ускорения диффузионных и flow-моделей без обучения, который превращает бинарное решение кэша в непрерывное. Сигнал обновления несёт не только ответ «пора или не пора», но и запас до порога, и этот запас задаёт длину следующего шага. Длинные переиспользуемые шаги перепрыгивают узлы сетки сэмплера и экономят прогоны трансформера.

Почему кэш шагов вообще работает

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

Кэш устроен так. У сети есть дорогие части и дешёвые: основная стопка трансформерных блоков съедает почти всё время, а входной слой с патч-эмбеддингами и выходная проекция стоят копейки. Кэш запоминает не результат целиком, а приращение, которое стопка внесла в свой вход на последнем обновлении. Это приращение называют остатком, оно медленно меняется вдоль траектории, поэтому переиспользуемый узел просто добавляет сохранённый остаток к своему входу и пропускает стопку блоков.

Дальше начинается самое интересное. Кэши различаются тем, когда обновляться. У методов с фиксированным расписанием шаблон обновлений задан заранее и одинаков для всех промптов. Динамические кэши (TeaCache, SeaCache) решают это по ходу сэмплирования: на входе в стопку берётся дешёвый зонд, измеряется его относительное изменение между соседними узлами, и когда накопленный сигнал пересекает порог, остаток обновляется. Пока сигнал ниже порога, сэмплер переиспользует старый остаток.

Headroom: запас до порога

Вся хитрость в том, что делается с сигналом. Динамические кэши тратят его на одно бинарное решение: сравнить с порогом и выбрать обновление или переиспользование. Где именно под порогом сидит сигнал, неважно. Узел, где кэш только что обновился, и узел на грани обновления обрабатываются одинаково, и оба шагают на один и тот же интервал сетки.

Авторы измерили, сколько стоит это игнорирование. На некэшированных траекториях FLUX ошибка переиспользования растёт вместе с накопленным сигналом, и разница между узлом сразу после обновления и узлом перед следующим обновлением достигает 2,2× по медианной ошибке. Порог при этом относится к ним как к одинаковым.

Отсюда главная идея метода. Величина, на которую сигнал не дотягивает до порога, названа запасом (headroom) и равна единице минус отношение накопленного сигнала к порогу. Запас большой, значит остаток ещё надёжен, и шаг можно растянуть. Запас маленький, значит обновление близко, и шаг сжимается обратно к сеточному. Формула простая: переиспользуемый узел шагает на интервал сетки плюс добавка, пропорциональная запасу, с потолком в восемь сеточных интервалов на один шаг.

Прыжок отключается в двух случаях: в самом начале траектории и на узле, где изменение зонда само по себе велико. Это единственные страховки, и в обоих случаях узел просто идёт штатным шагом. Никаких отдельных настроек под конкретную модель: одни и те же константы для картинок и видео.

Приземление между узлами

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

Узлы впереди тоже приходится чинить. Прыжок перескочил несколько запланированных точек, и первая непройденная может стоять в доле интервала от места посадки. Если оставить старую сетку, сэмплер потратит целый узел на долю шага. Поэтому хвост расписания переразбивается: оставшиеся узлы равномерно раскладываются от точки посадки до конца, и число прогонов сети падает ровно на число перепрыгнутых узлов.

Коэффициент продолжения остатка равен единице на скоростях ниже 4× и гасится до половины выше этой границы. Всё остальное в методе зафиксировано: и авторы подчёркивают, что в этом и отличие от предиктивных кэшей вроде TaylorSeer, которые предсказывают признаки только в узлах расписания и само расписание не трогают.

Эксперименты: FLUX, HunyuanVideo, Wan2.1

Метод проверили на трёх бэкбонах. FLUX.1-dev генерирует по одной картинке 1024×1024 на каждый из 200 промптов DrawBench, HunyuanVideo делает 65-кадровые видео 640×480 на 946 промптах VBench, а Wan2.1-T2V-1.3B генерирует 81-кадровые видео на 100 промптах. У всех моделей по 50 шагов Эйлера, у всех методов одинаковые промпты, сиды и железо.

Качество измеряли четырьмя метриками сходства с некэшированным результатом той же модели: PSNR и SSIM (чем выше, тем лучше), LPIPS и DreamSim (чем ниже, тем лучше). Сравнение шло при выровненной скорости: для каждого метода подбирали параметр так, чтобы он попадал в ту же полосу ускорения, что и SoftCache.

На FLUX картина такая. В полосе около 5,4× SoftCache выдаёт PSNR 20,05, SSIM 0,770 и LPIPS 0,251 против 18,81, 0,724 и 0,326 у SeaCache. В самой быстрой полосе, около 6,9×, преимущество над SeaCache составляет 1,12 дБ PSNR и 0,082 LPIPS. Причём это не покупка качества за счёт скорости: SoftCache быстрее SeaCache и DPCache во всех трёх полосах, а единственные два прогона, которые обгоняют его по скорости (TeaCache в медленной полосе на 0,23× и TaylorSeer в средней на 0,15×), отстают по PSNR на 7,2 и 8,6 дБ.

На HunyuanVideo SoftCache впереди обеих базовых линий по всем четырём метрикам во всех трёх полосах, с преимуществом от 0,54 до 2,78 дБ PSNR. В полосе около 3,5× у него PSNR 26,48 против 23,63 у SeaCache и 23,70 у DPCache. Показательна динамика при сжатии бюджета: при переходе от средней полосы к самой быстрой SoftCache теряет 0,09 дБ PSNR и 0,021 LPIPS, а SeaCache уже 1,44 дБ и 0,057. На Wan2.1 он тоже впереди на обеих проверенных точках.

Отдельная деталь: на метрике VBench, которая оценивает видео само по себе, методы различает куда слабее, чем метрики сходства. Там SoftCache держится в пределах 0,003 от DPCache и выше SeaCache во всех полосах. А на картинках в глазах начинает рябить раньше, чем в цифрах: в примерах статьи базовые методы на скорости около 5,2× теряют структуру объектов, у зебры из промпта пропадает голова или появляется вторая, у пугала вырастают крылья. SoftCache сохраняет все названные в промпте объекты с целой формой.

Что показали абляции

Авторы разобрали метод по частям на 50 промптах DPG-Bench, отдельно от тестовых. Если убрать прыжки (потолок в один интервал), сэмплер остаётся на сетке и, как SeaCache, может ускоряться только более редкими обновлениями, и тогда он сильнее всех проваливается при сжатии бюджета. Если убрать пропорциональность запасу, каждый прыжок сразу идёт на полную длину вместо адаптивной. Если убрать переразбиение хвоста, дополнительная дистанция не экономит ни одного узла. Если убрать продолжение остатка, узел держит якорное значение и качество падает.

Потолок прыжка проверили отдельно, лестницей значений. В человеческой оценке на 45 разборчивых промптах вариант с потолком 8 не отклонили ни разу (0/45), тогда как потолок 1 отклоняли в 22% случаев, потолок 12 в 53%, а потолок 32 в 91%. Потолки 3 и 5 отклонялись в 2% случаев, но на скорости от 5× уже заметно проигрывают перцептивно, так что восьмёрка оказалась наименьшим значением, которое ничего не отдаёт на практике.

Что это значит на практике

SoftCache не требует обучения и калибровки под конкретную модель: одни и те же настройки работают и на FLUX, и на обоих видео-бэкбонах. Это принципиально для внедрения, потому что конкурирующие методы часто требуют отдельной подгонки порога или расписания под каждый бэкбон. По духу метод ближе всего к SeaCache, у которого он заимствует спектральный зонд, но зонд TeaCache тоже подходит, просто с меньшей точностью.

Экономика вопроса простая. Диффузионные модели упираются в стоимость инференса: каждый прогон это полная стопка трансформера, и на видео с сотнями кадров счёт идёт на тысячи прогонов. Ускорение в 5,4× при лучшем сходстве с некэшированным результатом, чем у конкурентов, напрямую сокращает парк GPU или время ответа продукта. Для видео выигрыш особенно заметен, потому что там больше избыточности между соседними шагами и методу есть что перепрыгивать.

Ограничения тоже стоит держать в голове. Кэш по-прежнему приближает некэшированный сэмплер, и на экстремальных скоростях сходство падает у всех методов, просто у SoftCache медленнее. Порог обновления остаётся настраиваемым параметром. И проверено всё на трёх бэкбонах семейства rectified flow, так что перенос на другие архитектуры это отдельный вопрос.

Часто задаваемые вопросы

SoftCache требует дообучения модели?

Нет. Метод работает поверх готовой модели и не трогает её веса: он только решает, какие прогоны стопки блоков заменить переиспользованием остатка. Единственная дополнительная память это два сохранённых тензора остатка, свежий и предыдущий.

Чем SoftCache отличается от TeaCache и SeaCache?

TeaCache и SeaCache используют сигнал кэша как бинарный переключатель и всегда идут по сетке сэмплера. SoftCache читает запас сигнала до порога и превращает его в длину шага, поэтому переиспользуемые шаги перепрыгивают узлы сетки и приземляются между ними. Зонд берётся у SeaCache, но с зондом TeaCache метод тоже работает, просто чуть менее точно.

Работает ли SoftCache с генерацией видео?

Да, и там выигрыш устойчивее всего. На HunyuanVideo и Wan2.1 метод использует те же константы, что на FLUX, и лидирует по всем метрикам сходства во всех полосах скорости. В видео между шагами больше избыточности, поэтому растянутые шаги окупаются особенно хорошо.

Итог

SoftCache показывает, что адаптивность кэша не обязана заканчиваться на решении «когда обновляться». Запас сигнала до порога измеряет, сколько ещё можно доверять остатку, и если отдать эту величину длине шага, сэмплер уходит с решётки расписания и экономит прогоны, которые раньше тратил впустую. До 6,9× ускорения на FLUX, HunyuanVideo и Wan2.1 при лучшем сходстве с некэшированным результатом, чем у TeaCache, SeaCache, DPCache и TaylorSeer в каждой полосе скорости.

Если вы считаете стоимость инференса диффузионных моделей, статья на arXiv (2610.22369) стоит того, чтобы сравнить её таблицы с вашим пайплайном. Особенно если у вас видео: там разрыв между SoftCache и остальными растёт вместе с бюджетом.

← Все записи