Глава 202: Сжатие моделей в финансах
1. Введение
Развёртывание моделей машинного обучения для торговли в продакшн-средах ставит уникальные инженерные задачи. В то время как исследовательские команды обычно обучают большие, выразительные нейронные сети на мощных GPU-кластерах, модели, непосредственно исполняющие сделки, должны работать в условиях жёстких ограничений по задержке, памяти и энергопотреблению. Системы высокочастотной торговли (HFT) требуют времени инференса менее микросекунды. Периферийные развёртывания — такие как колокационные серверы вблизи матчинг-движков бирж — накладывают серьёзные ограничения на объём памяти. Даже облачные платформы алгоритмической торговли выигрывают от меньших моделей, снижающих затраты на инфраструктуру и увеличивающих пропускную способность.
Сжатие моделей — это семейство техник, которые устраняют разрыв между большими моделями, которые мы обучаем, и компактными моделями, которые мы развёртываем. Ключевое наблюдение состоит в том, что обученные нейронные сети, как правило, переопределены: они содержат гораздо больше параметров, чем необходимо для представления выученной функции. Сжатие использует эту избыточность для получения меньших, более быстрых моделей с минимальной потерей точности предсказаний.
Эта глава предоставляет всестороннее рассмотрение техник сжатия моделей применительно к финансовым торговым системам. Мы рассмотрим теоретические основы, обзор основных семейств сжатия и реализуем полный конвейер сжатия на Rust — языке, всё более популярном в количественных финансах благодаря сочетанию производительности и безопасности.
2. Таксономия сжатия
Техники сжатия моделей делятся на пять основных категорий, каждая из которых атакует избыточность с разной стороны:
2.1 Прунинг (обрезка)
Прунинг удаляет ненужные веса или целые нейроны из обученной сети. Фундаментальное наблюдение состоит в том, что многие веса в обученной сети близки к нулю и вносят пренебрежимо малый вклад в выходные данные. Обнуляя эти веса (или удаляя соответствующие связи), мы получаем более разреженную модель, требующую меньше вычислений и памяти.
Неструктурированный прунинг удаляет отдельные веса вне зависимости от их позиции в матрице весов. Это создаёт нерегулярные паттерны разреженности, которые сложно ускорить на стандартном оборудовании, но может достигать очень высоких коэффициентов сжатия (разреженность 90%+ является нормой).
Структурированный прунинг удаляет целые фильтры, каналы или слои. Результирующая модель имеет стандартную плотную архитектуру (просто меньшего размера), что делает её ускорение тривиальным на любом оборудовании. Однако структурированный прунинг обычно достигает более низких коэффициентов сжатия, чем неструктурированный при эквивалентной точности.
2.2 Квантизация
Квантизация снижает числовую точность весов и активаций модели. Стандартная нейронная сеть использует 32-битные числа с плавающей запятой (FP32) для всех вычислений. Квантизация отображает эти значения в представления с меньшей точностью — обычно 8-битные целые числа (INT8), хотя 4-битная и даже бинарная (1-битная) квантизация являются активными направлениями исследований.
Посттренировочная квантизация (PTQ) квантует предварительно обученную FP32-модель без дополнительного обучения. Она проста и быстра, но может приводить к деградации точности, особенно при очень малой разрядности.
Квантизация с учётом обучения (QAT) симулирует квантизацию в процессе обучения, позволяя модели адаптироваться к пониженной точности. QAT обычно восстанавливает большую часть или всю точность, потерянную при PTQ, за счёт полного цикла обучения.
2.3 Дистилляция знаний
Дистилляция знаний обучает маленькую модель-«ученика» имитировать поведение большой модели-«учителя». Вместо обучения на жёстких метках (например, «покупать» или «продавать»), ученик учится на мягких распределениях вероятностей учителя, которые кодируют более богатую информацию о межклассовых отношениях. Для торговых приложений учителем может быть большая ансамблевая модель, улавливающая сложную рыночную динамику, а учеником — компактная модель, подходящая для исполнения в реальном времени.
2.4 Низкоранговая факторизация
Матрицы весов в нейронных сетях часто имеют низкий эффективный ранг — их информационное содержание может быть передано матрицами значительно меньших размерностей. Низкоранговая факторизация разлагает матрицу весов W размера (m x n) в произведение двух меньших матриц: W ≈ U * V, где U имеет размер (m x k) и V — (k x n), при k << min(m, n). Это уменьшает как хранение (с mn до k(m+n) параметров), так и количество вычислений.
Распространённые методы декомпозиции включают:
- SVD (сингулярное разложение): классический подход с усечением малых сингулярных значений.
- Разложение Таккера: обобщает SVD на тензоры, разлагая свёрточные фильтры.
- CP-разложение: представляет тензор как сумму тензоров ранга один.
2.5 Разделение весов
Разделение весов заставляет группы весов принимать одинаковое значение. Классический подход использует кластеризацию k-средних для группировки весов в кластеры, а затем заменяет каждый вес центроидом его кластера. Модель хранит только индексы кластеров (которые требуют значительно меньше бит, чем полноточностные веса) плюс небольшую кодовую книгу значений центроидов.
3. Математические основы
3.1 Коэффициент сжатия
Коэффициент сжатия количественно определяет, насколько меньше сжатая модель по сравнению с оригинальной:
CR = Size(оригинал) / Size(сжатая)Для прунинга с разреженностью s (доля нулевых весов) теоретический коэффициент сжатия при использовании разреженного хранения приблизительно равен 1/(1-s) для больших моделей.
Для квантизации с b_original бит до b_compressed бит:
CR = b_original / b_compressedНапример, квантизация FP32 в INT8 даёт CR = 32/8 = 4x.
3.2 Компромисс точности и эффективности
Каждая техника сжатия обменивает качество модели на эффективность. Зависимость обычно выпукла: начальное сжатие даёт большой прирост эффективности с минимальной потерей точности, но дальнейшее сжатие приводит к убывающей отдаче и в конечном итоге к катастрофической деградации точности.
Мы можем формализовать это как задачу многокритериальной оптимизации:
минимизировать L(θ_c) (функция потерь сжатой модели)при ограничении C(θ_c) ≤ budget (ресурсное ограничение: задержка, память или FLOPs)где θ_c представляет параметры сжатой модели.
3.3 Фронт Парето
Фронт Парето — это множество конфигураций сжатия, при которых никакое улучшение одной цели (например, точности) невозможно без ухудшения другой (например, размера модели). На практике мы строим график точности в зависимости от коэффициента сжатия и выбираем рабочую точку, которая лучше всего соответствует нашим ограничениям развёртывания.
Для торговых приложений фронт Парето особенно важен, поскольку стоимость ошибок асимметрична: модель, пропускающая торговый сигнал, теряет потенциальную прибыль, но модель, генерирующая ложный сигнал, несёт прямые убытки (транзакционные издержки, неблагоприятное движение цены). Оптимальная точка сжатия должна учитывать эту асимметрию.
4. Требования торговых систем
4.1 Бюджеты задержки
Различные торговые стратегии предъявляют кардинально различные требования к задержке:
| Стратегия | Типичный бюджет задержки | Приоритет сжатия |
|---|---|---|
| Высокочастотная торговля | < 1 мкс | Экстремальный: INT4/бинарная квантизация, агрессивный прунинг |
| Маркет-мейкинг | 1-100 мкс | Высокий: INT8 квантизация, структурированный прунинг |
| Статистический арбитраж | 100 мкс - 10 мс | Умеренный: стандартное сжатие достаточно |
| Свинг-трейдинг | > 1 с | Низкий: сжатие в основном для снижения затрат |
4.2 Ограничения памяти
Колокационные торговые серверы вблизи матчинг-движков бирж работают в условиях жёстких аппаратных ограничений. FPGA-системы могут иметь всего несколько мегабайт встроенной памяти. Даже GPU-системы выигрывают от моделей, полностью помещающихся в кэш L2 (обычно 4-40 МБ), чтобы избежать узких мест пропускной способности памяти.
4.3 Требования к пропускной способности
Система маркет-мейкинга, обрабатывающая несколько инструментов, должна оценивать свою модель тысячи раз в секунду по сотням символов. Сжатие моделей напрямую увеличивает количество инструментов, которые можно обработать за заданное временное окно, расширяя вселенную стратегии и потенциал диверсификации.
5. Углублённое изучение техник
5.1 Структурированный и неструктурированный прунинг
Неструктурированный прунинг применяет маску к отдельным весам:
W_pruned = W ⊙ Mгде M — бинарная маска с M_ij = 0, если |W_ij| < порог. Порог обычно устанавливается для достижения целевого уровня разреженности.
Прунинг по магнитуде — самый простой и распространённый критерий: удалить веса с наименьшими абсолютными значениями. Несмотря на свою простоту, прунинг по магнитуде является сильной базовой линией, которая часто соответствует более сложным методам.
Структурированный прунинг удаляет целые строки или столбцы матриц весов (соответствующие нейронам или фильтрам). Для полносвязного слоя с матрицей весов W размера (m x n) удаление нейрона j устраняет столбец j матрицы W и строку j матрицы весов следующего слоя. Это создаёт действительно меньшую плотную модель.
5.2 Посттренировочная квантизация и квантизация с учётом обучения
Посттренировочная квантизация отображает FP32-значения в INT8 с использованием линейного отображения:
x_q = round(x / scale + zero_point)x_dequant = (x_q - zero_point) * scaleгде:
scale = (x_max - x_min) / (2^b - 1)zero_point = round(-x_min / scale)
Квантизация с учётом обучения вставляет узлы «фейковой квантизации» во время обучения, которые симулируют ошибку квантизации в прямом проходе, позволяя градиентам проходить в обратном проходе (используя оценщик прямого прохождения). Это позволяет модели выучить значения весов, устойчивые к шуму квантизации.
Для торговых моделей QAT обычно предпочтительнее, когда это осуществимо, поскольку ошибка квантизации в PTQ может сместить предсказанные вероятности достаточно, чтобы изменить торговые решения на критических порогах.
5.3 Разложение Таккера и CP-разложение
Для свёрточных слоёв (распространённых в моделях, обрабатывающих изображения стакана ордеров или свечные графики) тензорные разложения обеспечивают мощное сжатие.
Разложение Таккера разлагает 4D-свёрточное ядро K размера (C_out x C_in x H x W) на тензор-ядро G, умноженное на факторные матрицы по каждой моде:
K ≈ G ×₁ U₁ ×₂ U₂ ×₃ U₃ ×₄ U₄CP-разложение представляет K как сумму R тензоров ранга один:
K ≈ Σᵣ λᵣ · u₁ᵣ ⊗ u₂ᵣ ⊗ u₃ᵣ ⊗ u₄ᵣОба разложения заменяют одну свёртку последовательностью меньших свёрток, уменьшая как количество параметров, так и FLOPs.
6. Описание реализации
Наша реализация на Rust предоставляет полный инструментарий сжатия моделей для торговых приложений. Кодовая база организована вокруг нескольких основных компонентов:
Представление нейронной сети
Мы представляем нейронную сеть как последовательность плотных слоёв, каждый с матрицей весов и вектором смещений, хранимых как массивы ndarray. Прямой проход применяет активацию ReLU между слоями, а последний слой выдаёт необработанные логиты.
pub struct DenseLayer { pub weights: Array2<f64>, pub biases: Array1<f64>,}
pub struct NeuralNetwork { pub layers: Vec<DenseLayer>,}Прунинг по магнитуде
Наша реализация прунинга по магнитуде вычисляет глобальный порог из всех весов на целевом уровне разреженности, а затем обнуляет каждый вес ниже этого порога.
INT8 квантизация
Модуль квантизации отображает FP32-веса в INT8-значения с использованием покоэффициентной калибровки min/max. Он хранит параметры масштаба и нулевой точки для деквантизации при инференсе. Квантованная модель использует в 4 раза меньше памяти, чем оригинальная.
Низкоранговая факторизация на основе SVD
Для каждого слоя мы вычисляем усечённое SVD матрицы весов и восстанавливаем её, используя только top-k сингулярных значений. Ранг k выбирается на основе целевого коэффициента сжатия, балансируя сохранение точности и уменьшение размера.
Интеграция с Bybit
Реализация включает HTTP-клиент для API биржи Bybit, получающий данные OHLCV в реальном времени и исторические данные для любой торговой пары. Эти данные подаются непосредственно в конвейер обучения и оценки модели.
7. Интеграция данных Bybit
Наша система получает рыночные данные из публичного API Bybit v5:
GET https://api.bybit.com/v5/market/klineПараметры включают торговую пару (например, BTCUSDT), интервал (1m, 5m, 1h и т.д.) и лимит (количество свечей). Ответ включает метку времени, открытие, максимум, минимум, закрытие и объём для каждой свечи.
Конвейер данных:
- Получение: HTTP GET запрос к API Bybit
- Парсинг: десериализация JSON-ответа в структурированные данные свечей
- Инженерия признаков: вычисление доходностей, скользящих средних, оценок волатильности
- Нормализация: масштабирование признаков в диапазон [0, 1] для входа нейронной сети
- Разделение на обучающую/тестовую выборки: хронологическое разделение для избежания смещения заглядывания вперёд
Для оценки сжатия мы обучаем полную модель на исторических данных, применяем каждую технику сжатия и сравниваем точность предсказаний на отложенных тестовых данных. Это даёт нам реалистичную оценку того, как сжатие влияет на качество торговых сигналов.
8. Ключевые выводы
-
Сжатие моделей необходимо для продакшн-торговых систем. Разрыв между размерами исследовательских моделей и ограничениями развёртывания велик и продолжает расти. Сжатие устраняет этот разрыв без необходимости фундаментальных изменений в подходе к моделированию.
-
Разные торговые стратегии требуют разных подходов к сжатию. HFT требует экстремального сжатия (квантизация до INT4/бинарной, агрессивный прунинг). Свинг-трейдинг может потребовать лишь умеренного сжатия для снижения затрат. Подбирайте технику под бюджет задержки и памяти.
-
Комбинируйте несколько техник для максимального сжатия. Прунинг, квантизация и низкоранговая факторизация дополняют друг друга. Типичный продакшн-конвейер сначала применяет структурированный прунинг, затем квантизацию, достигая суммарного сжатия в 10-50 раз.
-
Всегда оценивайте на реалистичных торговых метриках. Одной точности недостаточно. Измеряйте коэффициент Шарпа, максимальную просадку и транзакционные издержки сигналов сжатой модели в сравнении с оригинальной. Малая деградация точности может усилиться до значительных различий в P&L.
-
Фронт Парето направляет решения о развёртывании. Постройте график точности в зависимости от коэффициента сжатия для вашей конкретной модели и данных. Оптимальная рабочая точка зависит от чувствительности вашей стратегии к ошибкам предсказания и ваших инфраструктурных ограничений.
-
Rust — отличный выбор для инференса сжатых моделей. Его абстракции с нулевой стоимостью, отсутствие сборщика мусора и детерминированная производительность делают его идеальным для торговых систем, чувствительных к задержке. Система типов ловит многие ошибки на этапе компиляции, которые стали бы ошибками времени выполнения в Python.
-
Квантизация обеспечивает лучшее соотношение усилий к сжатию. Для большинства торговых моделей квантизация INT8 даёт 4-кратное сжатие с пренебрежимой потерей точности и не требует переобучения (посттренировочная квантизация). Начните с неё, прежде чем исследовать более агрессивные техники.
-
Мониторьте сжатые модели в продакшне. Поведение модели может дрейфовать по-разному после сжатия. Реализуйте постоянный мониторинг распределений предсказаний и торговых результатов для раннего обнаружения деградации.